Repository: CyanogenMod/android_device_oneplus_oneplus2 Branch: cm-14.1 Commit: 04e7a16cf804 Files: 540 Total size: 3.4 MB Directory structure: gitextract_n9ce_52i/ ├── Android.mk ├── BoardConfig.mk ├── android_filesystem_config.h ├── audio/ │ ├── aanc_tuning_mixer.txt │ ├── audio_effects.conf │ ├── audio_output_policy.conf │ ├── audio_platform_info.xml │ ├── audio_policy.conf │ ├── listen_platform_info.xml │ ├── mixer_paths.xml │ ├── sound_trigger_mixer_paths.xml │ └── sound_trigger_platform_info.xml ├── bluetooth/ │ └── bdroid_buildcfg.h ├── board-info.txt ├── camera/ │ ├── Android.mk │ ├── CameraWrapper.cpp │ ├── InputEventReader.cpp │ ├── InputEventReader.h │ ├── ProximitySensor.cpp │ ├── ProximitySensor.h │ ├── SensorBase.cpp │ ├── SensorBase.h │ ├── configuration.h │ ├── sensors.cpp │ └── sensors.h ├── cm.dependencies ├── cm.mk ├── cmhw/ │ └── org/ │ └── cyanogenmod/ │ └── hardware/ │ └── KeyDisabler.java ├── configs/ │ ├── media_codecs.xml │ ├── media_codecs_performance.xml │ ├── media_profiles.xml │ ├── msm_irqbalance.conf │ ├── sec_config │ └── sensors/ │ └── hals.conf ├── data-ipa-cfg-mgr/ │ ├── Android.mk │ ├── Makefile.am │ ├── configure.ac │ ├── ipacm/ │ │ ├── inc/ │ │ │ ├── IPACM_CmdQueue.h │ │ │ ├── IPACM_Config.h │ │ │ ├── IPACM_ConntrackClient.h │ │ │ ├── IPACM_ConntrackListener.h │ │ │ ├── IPACM_Conntrack_NATApp.h │ │ │ ├── IPACM_Defs.h │ │ │ ├── IPACM_EvtDispatcher.h │ │ │ ├── IPACM_Filtering.h │ │ │ ├── IPACM_Header.h │ │ │ ├── IPACM_Iface.h │ │ │ ├── IPACM_IfaceManager.h │ │ │ ├── IPACM_Lan.h │ │ │ ├── IPACM_LanToLan.h │ │ │ ├── IPACM_Listener.h │ │ │ ├── IPACM_Log.h │ │ │ ├── IPACM_Neighbor.h │ │ │ ├── IPACM_Netlink.h │ │ │ ├── IPACM_Routing.h │ │ │ ├── IPACM_Wan.h │ │ │ ├── IPACM_Wlan.h │ │ │ └── IPACM_Xml.h │ │ └── src/ │ │ ├── Android.mk │ │ ├── IPACM_CmdQueue.cpp │ │ ├── IPACM_Config.cpp │ │ ├── IPACM_ConntrackClient.cpp │ │ ├── IPACM_ConntrackListener.cpp │ │ ├── IPACM_Conntrack_NATApp.cpp │ │ ├── IPACM_EvtDispatcher.cpp │ │ ├── IPACM_Filtering.cpp │ │ ├── IPACM_Header.cpp │ │ ├── IPACM_Iface.cpp │ │ ├── IPACM_IfaceManager.cpp │ │ ├── IPACM_Lan.cpp │ │ ├── IPACM_LanToLan.cpp │ │ ├── IPACM_Log.cpp │ │ ├── IPACM_Main.cpp │ │ ├── IPACM_Neighbor.cpp │ │ ├── IPACM_Netlink.cpp │ │ ├── IPACM_Routing.cpp │ │ ├── IPACM_Wan.cpp │ │ ├── IPACM_Wlan.cpp │ │ ├── IPACM_Xml.cpp │ │ ├── IPACM_cfg.xml │ │ ├── Makefile.am │ │ ├── mobileap_firewall.xml │ │ └── start_ipacm_le │ └── ipanat/ │ ├── inc/ │ │ ├── ipa_nat_drv.h │ │ ├── ipa_nat_drvi.h │ │ └── ipa_nat_logi.h │ ├── src/ │ │ ├── Android.mk │ │ ├── Makefile.am │ │ ├── ipa_nat_drv.c │ │ ├── ipa_nat_drvi.c │ │ └── ipa_nat_logi.c │ └── test/ │ ├── Android.mk │ ├── Makefile.am │ ├── README.txt │ ├── ipa_nat_test.h │ ├── ipa_nat_test000.c │ ├── ipa_nat_test001.c │ ├── ipa_nat_test002.c │ ├── ipa_nat_test003.c │ ├── ipa_nat_test004.c │ ├── ipa_nat_test005.c │ ├── ipa_nat_test006.c │ ├── ipa_nat_test007.c │ ├── ipa_nat_test008.c │ ├── ipa_nat_test009.c │ ├── ipa_nat_test010.c │ ├── ipa_nat_test011.c │ ├── ipa_nat_test012.c │ ├── ipa_nat_test013.c │ ├── ipa_nat_test014.c │ ├── ipa_nat_test015.c │ ├── ipa_nat_test016.c │ ├── ipa_nat_test017.c │ ├── ipa_nat_test018.c │ ├── ipa_nat_test019.c │ ├── ipa_nat_test020.c │ ├── ipa_nat_test021.c │ ├── ipa_nat_test022.c │ └── main.c ├── device.mk ├── doze/ │ ├── Android.mk │ ├── AndroidManifest.xml │ ├── proguard.flags │ ├── res/ │ │ ├── drawable/ │ │ │ ├── ic_settings_doze.xml │ │ │ └── switchbar_background.xml │ │ ├── layout/ │ │ │ ├── doze.xml │ │ │ └── switch_bar.xml │ │ ├── values/ │ │ │ ├── colors.xml │ │ │ └── styles.xml │ │ └── xml/ │ │ └── doze_settings.xml │ └── src/ │ └── com/ │ └── cyanogenmod/ │ └── settings/ │ └── doze/ │ ├── BootCompletedReceiver.java │ ├── DozeReceiver.java │ ├── DozeService.java │ ├── DozeSettings.java │ ├── DozeSettingsFragment.java │ ├── ProximitySensor.java │ ├── TiltSensor.java │ └── Utils.java ├── extract-files.sh ├── gps/ │ ├── Android.mk │ ├── CleanSpec.mk │ ├── Makefile.am │ ├── configure.ac │ ├── core/ │ │ ├── Android.mk │ │ ├── ContextBase.cpp │ │ ├── ContextBase.h │ │ ├── LBSProxyBase.h │ │ ├── LocAdapterBase.cpp │ │ ├── LocAdapterBase.h │ │ ├── LocAdapterProxyBase.h │ │ ├── LocApiBase.cpp │ │ ├── LocApiBase.h │ │ ├── LocDualContext.cpp │ │ ├── LocDualContext.h │ │ ├── UlpProxyBase.h │ │ ├── fused_location_extended.h │ │ ├── gps_extended.h │ │ ├── gps_extended_c.h │ │ ├── loc_core_log.cpp │ │ └── loc_core_log.h │ ├── etc/ │ │ ├── Android.mk │ │ ├── flp.conf │ │ ├── gps.conf │ │ ├── izat.conf │ │ ├── lowi.conf │ │ ├── sap.conf │ │ └── xtwifi.conf │ ├── loc-api.pc.in │ ├── loc_api/ │ │ ├── Android.mk │ │ ├── libloc_api-rpc-50001/ │ │ │ ├── Android.mk │ │ │ ├── libloc_api-rpc-glue/ │ │ │ │ ├── Android.mk │ │ │ │ ├── Makefile.am │ │ │ │ ├── rpc_inc/ │ │ │ │ │ ├── LocApiRpc.h │ │ │ │ │ ├── debug.h │ │ │ │ │ ├── loc_api_fixup.h │ │ │ │ │ ├── loc_api_log.h │ │ │ │ │ ├── loc_api_rpc_glue.h │ │ │ │ │ ├── loc_api_sync_call.h │ │ │ │ │ └── loc_apicb_appinit.h │ │ │ │ └── src/ │ │ │ │ ├── LocApiRpc.cpp │ │ │ │ ├── loc_api_fixup.c │ │ │ │ ├── loc_api_log.c │ │ │ │ ├── loc_api_rpc_glue.c │ │ │ │ ├── loc_api_sync_call.c │ │ │ │ └── loc_apicb_appinit.c │ │ │ └── libloc_api-rpc-stub/ │ │ │ ├── Android.mk │ │ │ ├── Makefile.am │ │ │ ├── inc/ │ │ │ │ ├── loc_api_rpcgen_cb_rpc.h │ │ │ │ ├── loc_api_rpcgen_common_rpc.h │ │ │ │ ├── loc_api_rpcgen_rpc.h │ │ │ │ └── loc_apicb_appinit.h │ │ │ ├── src/ │ │ │ │ ├── loc_api_rpcgen_cb_svc.c │ │ │ │ ├── loc_api_rpcgen_cb_xdr.c │ │ │ │ ├── loc_api_rpcgen_clnt.c │ │ │ │ ├── loc_api_rpcgen_common_xdr.c │ │ │ │ ├── loc_api_rpcgen_xdr.c │ │ │ │ └── loc_apicb_appinit.c │ │ │ └── xdr/ │ │ │ ├── loc_api.xdr │ │ │ ├── loc_api_cb.xdr │ │ │ └── loc_api_common.xdr │ │ └── libloc_api_50001/ │ │ ├── Android.mk │ │ ├── LocEngAdapter.cpp │ │ ├── LocEngAdapter.h │ │ ├── Makefile.am │ │ ├── gps.c │ │ ├── loc.cpp │ │ ├── loc.h │ │ ├── loc_eng.cpp │ │ ├── loc_eng.h │ │ ├── loc_eng_agps.cpp │ │ ├── loc_eng_agps.h │ │ ├── loc_eng_dmn_conn.cpp │ │ ├── loc_eng_dmn_conn.h │ │ ├── loc_eng_dmn_conn_glue_msg.c │ │ ├── loc_eng_dmn_conn_glue_msg.h │ │ ├── loc_eng_dmn_conn_glue_pipe.c │ │ ├── loc_eng_dmn_conn_glue_pipe.h │ │ ├── loc_eng_dmn_conn_handler.cpp │ │ ├── loc_eng_dmn_conn_handler.h │ │ ├── loc_eng_dmn_conn_thread_helper.c │ │ ├── loc_eng_dmn_conn_thread_helper.h │ │ ├── loc_eng_log.cpp │ │ ├── loc_eng_log.h │ │ ├── loc_eng_msg.h │ │ ├── loc_eng_ni.cpp │ │ ├── loc_eng_ni.h │ │ ├── loc_eng_nmea.cpp │ │ ├── loc_eng_nmea.h │ │ ├── loc_eng_xtra.cpp │ │ └── loc_eng_xtra.h │ └── utils/ │ ├── Android.mk │ ├── LocHeap.cpp │ ├── LocHeap.h │ ├── LocSharedLock.h │ ├── LocThread.cpp │ ├── LocThread.h │ ├── LocTimer.cpp │ ├── LocTimer.h │ ├── Makefile.am │ ├── MsgTask.cpp │ ├── MsgTask.h │ ├── linked_list.c │ ├── linked_list.h │ ├── loc_cfg.cpp │ ├── loc_cfg.h │ ├── loc_log.cpp │ ├── loc_log.h │ ├── loc_misc_utils.cpp │ ├── loc_misc_utils.h │ ├── loc_target.cpp │ ├── loc_target.h │ ├── loc_timer.h │ ├── log_util.h │ ├── msg_q.c │ ├── msg_q.h │ └── platform_lib_abstractions/ │ ├── elapsed_millis_since_boot.cpp │ ├── platform_lib_includes.h │ ├── platform_lib_macros.h │ └── platform_lib_time.h ├── include/ │ ├── camera/ │ │ └── CameraParametersExtra.h │ └── telephony/ │ └── ril.h ├── init/ │ ├── Android.mk │ └── init_oneplus2.cpp ├── keylayout/ │ ├── fpc1020.kl │ └── synaptics.kl ├── liblight/ │ ├── Android.mk │ ├── NOTICE │ └── lights.c ├── libshims/ │ ├── Android.mk │ ├── Camera.cpp │ ├── CameraBase.cpp │ ├── CameraMetadata.cpp │ ├── CameraParameters.cpp │ ├── CameraParameters2.cpp │ ├── CameraUtils.cpp │ ├── CaptureResult.cpp │ ├── ICamera.cpp │ ├── ICameraClient.cpp │ ├── ICameraRecordingProxy.cpp │ ├── ICameraRecordingProxyListener.cpp │ ├── ICameraService.cpp │ ├── ICameraServiceListener.cpp │ ├── ICameraServiceProxy.cpp │ ├── VendorTagDescriptor.cpp │ ├── camera.cpp │ ├── camera2/ │ │ ├── CaptureRequest.cpp │ │ ├── ICameraDeviceCallbacks.cpp │ │ ├── ICameraDeviceUser.cpp │ │ └── OutputConfiguration.cpp │ └── include/ │ └── camera/ │ ├── Camera.h │ ├── CameraBase.h │ ├── CameraMetadata.h │ ├── CameraParameters.h │ ├── CameraParameters2.h │ ├── CameraParametersExtra.h │ ├── CameraUtils.h │ ├── CaptureResult.h │ ├── ICamera.h │ ├── ICameraClient.h │ ├── ICameraRecordingProxy.h │ ├── ICameraRecordingProxyListener.h │ ├── ICameraService.h │ ├── ICameraServiceListener.h │ ├── ICameraServiceProxy.h │ ├── VendorTagDescriptor.h │ └── camera2/ │ ├── CaptureRequest.h │ ├── ICameraDeviceCallbacks.h │ ├── ICameraDeviceUser.h │ └── OutputConfiguration.h ├── overlay/ │ ├── frameworks/ │ │ ├── base/ │ │ │ ├── core/ │ │ │ │ └── res/ │ │ │ │ └── res/ │ │ │ │ ├── values/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc204-mnc04/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc208-mnc10/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc214-mnc01/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc234-mnc15/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc262-mnc01/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc262-mnc07/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc262-mnc08/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc268-mnc01/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc302-mnc220/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc302-mnc370/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc302-mnc610/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc302-mnc720/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc310-mnc004/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc310-mnc070/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc310-mnc090/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc310-mnc120/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc310-mnc150/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc310-mnc170/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc310-mnc260/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc310-mnc380/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc310-mnc410/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc310-mnc560/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc310-mnc680/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc311-mnc180/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc311-mnc220/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc311-mnc221/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc311-mnc222/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc311-mnc223/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc311-mnc224/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc311-mnc225/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc311-mnc226/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc311-mnc227/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc311-mnc228/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc311-mnc229/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc311-mnc480/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc311-mnc490/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc311-mnc580/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc311-mnc581/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc311-mnc582/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc311-mnc583/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc311-mnc584/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc311-mnc585/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc311-mnc586/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc311-mnc587/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc311-mnc588/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc311-mnc589/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc311-mnc870/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc312-mnc530/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc316-mnc010/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc330-mnc110/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc334-mnc020/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc334-mnc050/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc334-mnc090/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc334-mnc30/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc370-mnc02/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc404-mnc01/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc405-mnc840/ │ │ │ │ │ ├── config.xml │ │ │ │ │ └── strings.xml │ │ │ │ ├── values-mcc405-mnc854/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc405-mnc855/ │ │ │ │ │ ├── config.xml │ │ │ │ │ └── strings.xml │ │ │ │ ├── values-mcc405-mnc856/ │ │ │ │ │ ├── config.xml │ │ │ │ │ └── strings.xml │ │ │ │ ├── values-mcc405-mnc857/ │ │ │ │ │ ├── config.xml │ │ │ │ │ └── strings.xml │ │ │ │ ├── values-mcc405-mnc858/ │ │ │ │ │ ├── config.xml │ │ │ │ │ └── strings.xml │ │ │ │ ├── values-mcc405-mnc859/ │ │ │ │ │ ├── config.xml │ │ │ │ │ └── strings.xml │ │ │ │ ├── values-mcc405-mnc860/ │ │ │ │ │ ├── config.xml │ │ │ │ │ └── strings.xml │ │ │ │ ├── values-mcc405-mnc861/ │ │ │ │ │ ├── config.xml │ │ │ │ │ └── strings.xml │ │ │ │ ├── values-mcc405-mnc862/ │ │ │ │ │ ├── config.xml │ │ │ │ │ └── strings.xml │ │ │ │ ├── values-mcc405-mnc863/ │ │ │ │ │ ├── config.xml │ │ │ │ │ └── strings.xml │ │ │ │ ├── values-mcc405-mnc864/ │ │ │ │ │ ├── config.xml │ │ │ │ │ └── strings.xml │ │ │ │ ├── values-mcc405-mnc865/ │ │ │ │ │ ├── config.xml │ │ │ │ │ └── strings.xml │ │ │ │ ├── values-mcc405-mnc866/ │ │ │ │ │ ├── config.xml │ │ │ │ │ └── strings.xml │ │ │ │ ├── values-mcc405-mnc867/ │ │ │ │ │ ├── config.xml │ │ │ │ │ └── strings.xml │ │ │ │ ├── values-mcc405-mnc868/ │ │ │ │ │ ├── config.xml │ │ │ │ │ └── strings.xml │ │ │ │ ├── values-mcc405-mnc869/ │ │ │ │ │ ├── config.xml │ │ │ │ │ └── strings.xml │ │ │ │ ├── values-mcc405-mnc870/ │ │ │ │ │ ├── config.xml │ │ │ │ │ └── strings.xml │ │ │ │ ├── values-mcc405-mnc871/ │ │ │ │ │ ├── config.xml │ │ │ │ │ └── strings.xml │ │ │ │ ├── values-mcc405-mnc872/ │ │ │ │ │ ├── config.xml │ │ │ │ │ └── strings.xml │ │ │ │ ├── values-mcc405-mnc873/ │ │ │ │ │ ├── config.xml │ │ │ │ │ └── strings.xml │ │ │ │ ├── values-mcc405-mnc874/ │ │ │ │ │ ├── config.xml │ │ │ │ │ └── strings.xml │ │ │ │ ├── values-mcc505-mnc01/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc505-mnc11/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc505-mnc71/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc505-mnc72/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc706-mnc01/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc712-mnc03/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc714-mnc03/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc716-mnc06/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc716-mnc10/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc716-mnc17/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc722-mnc02/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc722-mnc07/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc722-mnc310/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc722-mnc34/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc722-mnc340/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc722-mnc341/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc722-mnc36/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc724-mnc02/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc724-mnc03/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc724-mnc04/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc724-mnc05/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc724-mnc06/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc724-mnc10/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc724-mnc11/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc724-mnc16/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc724-mnc23/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc724-mnc24/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc724-mnc31/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc724-mnc39/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc730-mnc01/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc730-mnc02/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc730-mnc09/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc730-mnc10/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc732-mnc101/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc732-mnc103/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc732-mnc111/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc732-mnc12/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc732-mnc123/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc732-mnc130/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc734-mnc04/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc740-mnc01/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc744-mnc02/ │ │ │ │ │ └── config.xml │ │ │ │ ├── values-mcc748-mnc10/ │ │ │ │ │ └── config.xml │ │ │ │ └── xml/ │ │ │ │ └── power_profile.xml │ │ │ └── packages/ │ │ │ ├── SettingsProvider/ │ │ │ │ └── res/ │ │ │ │ └── values/ │ │ │ │ └── defaults.xml │ │ │ └── SystemUI/ │ │ │ └── res/ │ │ │ └── values/ │ │ │ └── config.xml │ │ └── opt/ │ │ └── telephony/ │ │ └── resources/ │ │ └── res/ │ │ ├── values-mcc310-mnc030/ │ │ │ └── config.xml │ │ ├── values-mcc310-mnc070/ │ │ │ └── config.xml │ │ ├── values-mcc310-mnc080/ │ │ │ └── config.xml │ │ ├── values-mcc310-mnc150/ │ │ │ └── config.xml │ │ ├── values-mcc310-mnc170/ │ │ │ └── config.xml │ │ ├── values-mcc310-mnc280/ │ │ │ └── config.xml │ │ ├── values-mcc310-mnc380/ │ │ │ └── config.xml │ │ ├── values-mcc310-mnc410/ │ │ │ └── config.xml │ │ ├── values-mcc310-mnc560/ │ │ │ └── config.xml │ │ └── values-mcc310-mnc680/ │ │ └── config.xml │ ├── packages/ │ │ ├── apps/ │ │ │ ├── Bluetooth/ │ │ │ │ └── res/ │ │ │ │ └── values/ │ │ │ │ └── config.xml │ │ │ ├── CarrierConfig/ │ │ │ │ └── res/ │ │ │ │ └── xml/ │ │ │ │ └── vendor.xml │ │ │ ├── CellBroadcastReceiver/ │ │ │ │ └── res/ │ │ │ │ └── values/ │ │ │ │ └── config.xml │ │ │ ├── Dialer/ │ │ │ │ └── res/ │ │ │ │ └── values/ │ │ │ │ └── config.xml │ │ │ ├── Mms/ │ │ │ │ └── res/ │ │ │ │ └── values/ │ │ │ │ └── config.xml │ │ │ ├── Settings/ │ │ │ │ └── res/ │ │ │ │ └── values/ │ │ │ │ ├── config.xml │ │ │ │ └── dimens.xml │ │ │ └── Snap/ │ │ │ └── res/ │ │ │ └── values/ │ │ │ ├── arrays.xml │ │ │ ├── cm_strings.xml │ │ │ ├── config.xml │ │ │ └── qcomstrings.xml │ │ └── services/ │ │ ├── Telecomm/ │ │ │ └── res/ │ │ │ └── values/ │ │ │ └── config.xml │ │ └── Telephony/ │ │ └── res/ │ │ └── values/ │ │ └── config.xml │ └── vendor/ │ └── cmsdk/ │ └── cm/ │ └── res/ │ └── res/ │ └── values/ │ └── config.xml ├── proprietary-files.txt ├── rootdir/ │ ├── Android.mk │ └── etc/ │ ├── fstab.qcom │ ├── init.qcom.bt.sh │ ├── init.qcom.power.rc │ ├── init.qcom.rc │ ├── init.qcom.sh │ ├── init.qcom.usb.rc │ ├── init.qcom.usb.sh │ ├── init.zram.sh │ └── ueventd.qcom.rc ├── sensors/ │ ├── Android.mk │ └── SensorsWrapper.c ├── sepolicy/ │ ├── audioserver.te │ ├── cam_sysfs.te │ ├── cameraserver.te │ ├── dpmd.te │ ├── file.te │ ├── file_contexts │ ├── fingerprintd.te │ ├── genfs_contexts │ ├── ims.te │ ├── init.te │ ├── ipacm-diag.te │ ├── kernel.te │ ├── mediacodec.te │ ├── mediadrmserver.te │ ├── mediaserver.te │ ├── mm-pp-daemon.te │ ├── mm-qcamerad.te │ ├── netmgrd.te │ ├── per_mgr.te │ ├── perfd.te │ ├── priv_app.te │ ├── qmuxd.te │ ├── qti_init_shell.te │ ├── radio.te │ ├── rild.te │ ├── sensors.te │ ├── sysinit.te │ ├── system_app.te │ ├── system_server.te │ ├── tee.te │ ├── thermal-engine.te │ ├── time_daemon.te │ ├── ueventd.te │ ├── vold.te │ ├── wcnss_filter.te │ └── wcnss_service.te ├── setup-makefiles.sh ├── system.prop ├── tftp.mk ├── vendorsetup.sh ├── vr/ │ ├── Android.mk │ └── vr.c └── wifi/ ├── WCNSS_qcom_cfg.ini ├── hostapd.accept ├── hostapd.conf ├── hostapd.deny ├── p2p_supplicant_overlay.conf └── wpa_supplicant_overlay.conf ================================================ FILE CONTENTS ================================================ ================================================ FILE: Android.mk ================================================ # # Copyright 2014 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # This contains the module build definitions for the hardware-specific # components for this device. # # As much as possible, those components should be built unconditionally, # with device-specific names to avoid collisions, to avoid device-specific # bitrot and build breakages. Building a component unconditionally does # *not* include it on all devices, so it is safe even with hardware-specific # components. LOCAL_PATH := $(call my-dir) ifeq ($(TARGET_DEVICE),oneplus2) include $(call all-subdir-makefiles,$(LOCAL_PATH)) include $(CLEAR_VARS) LOCAL_MODULE := wifi_symlinks LOCAL_MODULE_TAGS := optional LOCAL_MODULE_CLASS := FAKE LOCAL_MODULE_SUFFIX := -timestamp include $(BUILD_SYSTEM)/base_rules.mk $(LOCAL_BUILT_MODULE): ACTUAL_INI_FILE := /system/etc/wifi/WCNSS_qcom_cfg.ini $(LOCAL_BUILT_MODULE): WCNSS_INI_SYMLINK := $(TARGET_OUT)/etc/firmware/wlan/qca_cld/WCNSS_qcom_cfg.ini $(LOCAL_BUILT_MODULE): ACTUAL_BIN_FILE := /system/etc/wifi/WCNSS_qcom_wlan_nv.bin $(LOCAL_BUILT_MODULE): WCNSS_BIN_SYMLINK := $(TARGET_OUT)/etc/firmware/wlan/qca_cld/WCNSS_qcom_wlan_nv.bin $(LOCAL_BUILT_MODULE): ACTUAL_DAT_FILE := /system/etc/wifi/WCNSS_cfg.dat $(LOCAL_BUILT_MODULE): WCNSS_DAT_SYMLINK := $(TARGET_OUT)/etc/firmware/wlan/qca_cld/WCNSS_cfg.dat $(LOCAL_BUILT_MODULE): ACTUAL_MAC_FILE := /persist/wlan_mac.bin $(LOCAL_BUILT_MODULE): WCNSS_MAC_SYMLINK := $(TARGET_OUT)/etc/firmware/wlan/qca_cld/wlan_mac.bin $(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/Android.mk $(LOCAL_BUILT_MODULE): $(hide) echo "Making symlinks for wifi" $(hide) mkdir -p $(dir $@) $(hide) mkdir -p $(dir $(WCNSS_BIN_SYMLINK)) $(hide) rm -rf $@ $(hide) rm -rf $(WCNSS_INI_SYMLINK) $(hide) ln -sf $(ACTUAL_INI_FILE) $(WCNSS_INI_SYMLINK) $(hide) rm -rf $(WCNSS_BIN_SYMLINK) $(hide) ln -sf $(ACTUAL_BIN_FILE) $(WCNSS_BIN_SYMLINK) $(hide) rm -rf $(WCNSS_DAT_SYMLINK) $(hide) ln -sf $(ACTUAL_DAT_FILE) $(WCNSS_DAT_SYMLINK) $(hide) rm -rf $(WCNSS_MAC_SYMLINK) $(hide) ln -sf $(ACTUAL_MAC_FILE) $(WCNSS_MAC_SYMLINK) $(hide) touch $@ include $(call all-makefiles-under,$(LOCAL_PATH)) IMS_LIBS := libimscamera_jni.so libimsmedia_jni.so IMS_SYMLINKS := $(addprefix $(TARGET_OUT)/app/ims/lib/arm64/,$(notdir $(IMS_LIBS))) $(IMS_SYMLINKS): $(LOCAL_INSTALLED_MODULE) @echo "IMS lib link: $@" @mkdir -p $(dir $@) @rm -rf $@ $(hide) ln -sf /system/vendor/lib64/$(notdir $@) $@ ALL_DEFAULT_INSTALLED_MODULES += $(IMS_SYMLINKS) include device/oneplus/oneplus2/tftp.mk endif ================================================ FILE: BoardConfig.mk ================================================ # Copyright (C) 2015 The CyanogenMod Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # This file sets variables that control the way modules are built # thorughout the system. It should not be used to conditionally # disable makefiles (the proper mechanism to control what gets # included in a build is to use PRODUCT_PACKAGES in a product # definition file). # # Inherit from oppo-common -include device/oppo/common/BoardConfigCommon.mk TARGET_OTA_ASSERT_DEVICE := OnePlus2,oneplus2 PLATFORM_PATH := device/oneplus/oneplus2 BOARD_VENDOR := oneplus # Use Snapdragon LLVM, if available TARGET_USE_SDCLANG := true # Assertions TARGET_BOARD_INFO_FILE ?= $(PLATFORM_PATH)/board-info.txt # Bootloader TARGET_BOOTLOADER_BOARD_NAME := MSM8994 TARGET_NO_BOOTLOADER := true # Platform TARGET_BOARD_PLATFORM := msm8994 TARGET_BOARD_PLATFORM_GPU := qcom-adreno430 # Architecture TARGET_ARCH := arm64 TARGET_ARCH_VARIANT := armv8-a TARGET_CPU_ABI := arm64-v8a TARGET_CPU_ABI2 := TARGET_CPU_VARIANT := generic TARGET_2ND_ARCH := arm TARGET_2ND_ARCH_VARIANT := armv7-a-neon TARGET_2ND_CPU_ABI := armeabi-v7a TARGET_2ND_CPU_ABI2 := armeabi TARGET_2ND_CPU_VARIANT := cortex-a53.a57 TARGET_USES_64_BIT_BINDER := true # Kernel BOARD_KERNEL_CMDLINE := androidboot.hardware=qcom user_debug=31 msm_rtb.filter=0x37 ehci-hcd.park=3 lpm_levels.sleep_disabled=1 boot_cpus=0-3 BOARD_KERNEL_BASE := 0x00000000 BOARD_KERNEL_PAGESIZE := 4096 BOARD_KERNEL_TAGS_OFFSET := 0x00000100 BOARD_RAMDISK_OFFSET := 0x01000000 BOARD_KERNEL_IMAGE_NAME := Image.gz-dtb TARGET_KERNEL_APPEND_DTB := true TARGET_KERNEL_ARCH := arm64 TARGET_KERNEL_HEADER_ARCH := arm64 TARGET_KERNEL_SOURCE := kernel/oneplus/msm8994 TARGET_KERNEL_CONFIG := cm_oneplus2_defconfig TARGET_KERNEL_CROSS_COMPILE_PREFIX := aarch64-linux-android- # QCOM hardware BOARD_USES_QCOM_HARDWARE := true # ANT+ BOARD_ANT_WIRELESS_DEVICE := "qualcomm-uart" # Audio AUDIO_FEATURE_ENABLED_ACDB_LICENSE := true AUDIO_FEATURE_ENABLED_COMPRESS_CAPTURE := true AUDIO_FEATURE_ENABLED_COMPRESS_VOIP := true AUDIO_FEATURE_ENABLED_DS2_DOLBY_DAP := true AUDIO_FEATURE_ENABLED_EXTN_FORMATS := true AUDIO_FEATURE_ENABLED_FLAC_OFFLOAD := true AUDIO_FEATURE_ENABLED_FLUENCE := true AUDIO_FEATURE_ENABLED_HFP := true AUDIO_FEATURE_ENABLED_INCALL_MUSIC := false AUDIO_FEATURE_ENABLED_KPI_OPTIMIZE := true AUDIO_FEATURE_ENABLED_MULTI_VOICE_SESSIONS := true AUDIO_FEATURE_ENABLED_PCM_OFFLOAD := true AUDIO_FEATURE_ENABLED_PCM_OFFLOAD_24 := true AUDIO_FEATURE_ENABLED_PROXY_DEVICE := true AUDIO_USE_LL_AS_PRIMARY_OUTPUT := true BOARD_USES_ALSA_AUDIO := true # Bluetooth BOARD_BLUETOOTH_BDROID_BUILDCFG_INCLUDE_DIR := $(PLATFORM_PATH)/bluetooth BOARD_HAS_QCA_BT_ROME := true BOARD_HAVE_BLUETOOTH := true BOARD_HAVE_BLUETOOTH_QCOM := true QCOM_BT_USE_BTNV := true QCOM_BT_USE_SMD_TTY := true # Camera TARGET_NEEDS_PLATFORM_TEXT_RELOCATIONS := true USE_DEVICE_SPECIFIC_CAMERA := true TARGET_USES_MEDIA_EXTENSIONS := true TARGET_HAS_LEGACY_CAMERA_HAL1 := true # Charger BOARD_CHARGER_DISABLE_INIT_BLANK := true # CNE and DPM TARGET_LDPRELOAD := libNimsWrap.so BOARD_USES_QCNE := true # Cpusets ENABLE_CPUSETS := true # GPS TARGET_NO_RPC := true USE_DEVICE_SPECIFIC_GPS := true # Graphics NUM_FRAMEBUFFER_SURFACE_BUFFERS := 3 TARGET_USES_ION := true TARGET_USES_NEW_ION_API :=true TARGET_USES_C2D_COMPOSITION := true USE_OPENGL_RENDERER := true MAX_EGL_CACHE_KEY_SIZE := 12*1024 MAX_EGL_CACHE_SIZE := 2048*1024 HAVE_ADRENO_SOURCE := false OVERRIDE_RS_DRIVER := libRSDriver_adreno.so VSYNC_EVENT_PHASE_OFFSET_NS := 2000000 SF_VSYNC_EVENT_PHASE_OFFSET_NS := 6000000 # Include path TARGET_SPECIFIC_HEADER_PATH := $(PLATFORM_PATH)/include # Init TARGET_INIT_VENDOR_LIB := libinit_oneplus2 TARGET_PLATFORM_DEVICE_BASE := /devices/soc.0/ # Keystore TARGET_PROVIDES_KEYMASTER := true # Lights TARGET_PROVIDES_LIBLIGHT := true # RIL TARGET_RIL_VARIANT := caf # RPC TARGET_NO_RPC := true # Sensors USE_SENSOR_MULTI_HAL := true # Enable dexpreopt to speed boot time ifeq ($(HOST_OS),linux) ifeq ($(call match-word-in-list,$(TARGET_BUILD_VARIANT),user),true) ifeq ($(WITH_DEXPREOPT),) WITH_DEXPREOPT := true endif endif endif # Wifi BOARD_HAS_QCOM_WLAN := true BOARD_HAS_QCOM_WLAN_SDK := true BOARD_WLAN_DEVICE := qcwcn BOARD_HOSTAPD_DRIVER := NL80211 BOARD_HOSTAPD_PRIVATE_LIB := lib_driver_cmd_$(BOARD_WLAN_DEVICE) BOARD_WPA_SUPPLICANT_DRIVER := NL80211 BOARD_WPA_SUPPLICANT_PRIVATE_LIB := lib_driver_cmd_$(BOARD_WLAN_DEVICE) TARGET_USES_WCNSS_CTRL := true TARGET_USES_QCOM_WCNSS_QMI := true WIFI_DRIVER_FW_PATH_AP := "ap" WIFI_DRIVER_FW_PATH_STA := "sta" WIFI_DRIVER_FW_PATH_P2P := "p2p" WPA_SUPPLICANT_VERSION := VER_0_8_X CONFIG_EAP_PROXY := qmi CONFIG_EAP_PROXY_DUAL_SIM := true CONFIG_EAP_PROXY_AKA_PRIME := true CONFIG_EAP_PROXY_MSM8994_TARGET := true # Partitions BOARD_BOOTIMAGE_PARTITION_SIZE := 67108864 BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := f2fs BOARD_CACHEIMAGE_PARTITION_SIZE := 268435456 BOARD_RECOVERYIMAGE_PARTITION_SIZE := 67108864 BOARD_SYSTEMIMAGE_PARTITION_SIZE := 2684354560 BOARD_USERDATAIMAGE_PARTITION_SIZE := 59047394304 BOARD_FLASH_BLOCK_SIZE := 262144 TARGET_USERIMAGES_USE_EXT4 := true TARGET_USERIMAGES_USE_F2FS := true # Recovery TARGET_RECOVERY_FSTAB := $(PLATFORM_PATH)/rootdir/etc/fstab.qcom # SELinux include device/qcom/sepolicy/sepolicy.mk BOARD_SEPOLICY_DIRS += $(PLATFORM_PATH)/sepolicy # Time services BOARD_USES_QC_TIME_SERVICES := true # CM Hardware BOARD_HARDWARE_CLASS += $(PLATFORM_PATH)/cmhw TARGET_TAP_TO_WAKE_NODE := "/proc/touchpanel/double_tap_enable" # inherit from the proprietary version -include vendor/oneplus/oneplus2/BoardConfigVendor.mk ================================================ FILE: android_filesystem_config.h ================================================ /* # Copyright (c) 2016, The Linux Foundation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of The Linux Foundation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN # IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #define NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS const struct fs_path_config android_device_files[] = { // { 00755, AID_UID, AID_GID, (1ULL << CAPABILITY), "PATH_TO_BINARY" }, { 00755, AID_SYSTEM, AID_SYSTEM, (1ULL << CAP_NET_BIND_SERVICE), "system/bin/pm-service"}, { 00755, AID_SYSTEM, AID_SYSTEM, (1ULL << CAP_NET_BIND_SERVICE), "system/bin/imsdatadaemon" }, { 00755, AID_SYSTEM, AID_SYSTEM, (1ULL << CAP_NET_BIND_SERVICE), "system/bin/cnss-daemon"}, { 00755, AID_SYSTEM, AID_RADIO, (1ULL << CAP_NET_BIND_SERVICE), "system/bin/ims_rtp_daemon" }, }; ================================================ FILE: audio/aanc_tuning_mixer.txt ================================================ #ANC_TEST_P_PATH_MIC_STEREO Capture acdb_dev_id:85 !Capture Txdevice:0 enable TX7 HPF Switch:1 TX8 HPF Switch:1 AIF1_CAP Mixer SLIM TX7:1 AIF1_CAP Mixer SLIM TX8:1 SLIM TX7 MUX:DEC9 DEC9 MUX:DMIC4 SLIM TX8 MUX:DEC10 DEC10 MUX:DMIC3 SLIM_0_TX Channels:Two MultiMedia1 Mixer SLIM_0_TX:1 disable MultiMedia1 Mixer SLIM_0_TX:0 AIF1_CAP Mixer SLIM TX7:0 AIF1_CAP Mixer SLIM TX8:0 SLIM TX7 MUX:ZERO SLIM TX8 MUX:ZERO DEC9 MUX:ZERO DEC10 MUX:ZERO TX7 HPF Switch:0 TX8 HPF Switch:0 #ANC_TEST_S_PATH_MIC_STEREO Capture acdb_dev_id:88 !Capture Txdevice:0 enable TX7 HPF Switch:1 TX8 HPF Switch:1 AIF1_CAP Mixer SLIM TX7:1 AIF1_CAP Mixer SLIM TX8:1 SLIM TX7 MUX:DEC8 DEC7 MUX:ANC2_FB ANC2 MUX:DMIC3 SLIM TX8 MUX:DEC7 DEC8 MUX:ANC1_FB ANC1 MUX:DMIC3 ANC1 FB MUX:EAR_HPH_L SLIM_0_TX Channels:Two MultiMedia1 Mixer SLIM_0_TX:1 disable MultiMedia1 Mixer SLIM_0_TX:0 AIF1_CAP Mixer SLIM TX7:0 AIF1_CAP Mixer SLIM TX8:0 SLIM TX7 MUX:ZERO SLIM TX8 MUX:ZERO DEC7 MUX:ZERO ANC2 MUX:ZERO ANC1 MUX:ZERO DEC8 MUX:ZERO ANC1 FB MUX:ZERO TX7 HPF Switch:0 TX8 HPF Switch:0 #ANC_TEST_E_PATH_MIC_STEREO Capture acdb_dev_id:91 !Capture Txdevice:0 enable TX7 HPF Switch:1 TX8 HPF Switch:1 AIF1_CAP Mixer SLIM TX7:1 AIF1_CAP Mixer SLIM TX8:1 SLIM TX7 MUX:DEC8 DEC7 MUX:ANC2_FB ANC2 MUX:DMIC4 ANC1 MUX:DMIC4 SLIM TX8 MUX:DEC7 DEC8 MUX:ANC1_FB ANC1 FB MUX:EAR_HPH_L SLIM_0_TX Channels:Two MultiMedia1 Mixer SLIM_0_TX:1 disable MultiMedia1 Mixer SLIM_0_TX:0 AIF1_CAP Mixer SLIM TX7:0 AIF1_CAP Mixer SLIM TX8:0 SLIM TX7 MUX:ZERO SLIM TX8 MUX:ZERO DEC7 MUX:ZERO ANC2 MUX:ZERO DEC10 MUX:ZERO ANC1 FB MUX:ZERO TX7 HPF Switch:0 TX8 HPF Switch:0 #ANC_TEST_S_PATH_HANDSET_SPKR_ANC_MONO acdb_dev_id:86 !Playback Rxdevice:0 enable ANC Function:ON SLIM RX1 MUX:AIF1_PB SLIM_0_RX Channels:One RX1 MIX1 INP1:RX1 CLASS_H_DSM MUX:DSM_HPHL_RX1 RX1 Digital Volume:87 DAC1 Switch:1 ANC Slot:7 SLIMBUS_0_RX Audio Mixer MultiMedia1:1 disable SLIMBUS_0_RX Audio Mixer MultiMedia1:0 ANC Slot:0 SLIM RX1 MUX:ZERO RX1 MIX1 INP1:ZERO RX1 Digital Volume:0 DAC1 Switch:0 ANC Function:OFF #ANC_TEST_E_PATH_HANDSET_SPKR_ANC_MONO acdb_dev_id:89 !Playback Rxdevice:0 enable ANC Function:ON SLIM RX1 MUX:AIF1_PB SLIM_0_RX Channels:One RX1 MIX1 INP1:RX1 CLASS_H_DSM MUX:DSM_HPHL_RX1 RX1 Digital Volume:87 DAC1 Switch:1 ANC Slot:8 SLIMBUS_0_RX Audio Mixer MultiMedia1:1 disable SLIMBUS_0_RX Audio Mixer MultiMedia1:0 ANC Slot:0 SLIM RX1 MUX:ZERO RX1 MIX1 INP1:ZERO RX1 Digital Volume:0 DAC1 Switch:0 ANC Function:OFF ================================================ FILE: audio/audio_effects.conf ================================================ # List of effect libraries to load. Each library element must contain a "path" element # giving the full path of the library .so file. # libraries { # { # path # } # } libraries { bundle { path /system/lib/soundfx/libbundlewrapper.so } reverb { path /system/lib/soundfx/libreverbwrapper.so } qcbassboost { path /vendor/lib/soundfx/libqcbassboost.so } qcvirt { path /vendor/lib/soundfx/libqcvirt.so } qcreverb { path /vendor/lib/soundfx/libqcreverb.so } visualizer_sw { path /system/lib/soundfx/libvisualizer.so } visualizer_hw { path /system/lib/soundfx/libqcomvisualizer.so } downmix { path /system/lib/soundfx/libdownmix.so } proxy { path /system/lib/soundfx/libeffectproxy.so } offload_bundle { path /system/lib/soundfx/libqcompostprocbundle.so } qcom_pre_processing { path /system/lib/soundfx/libqcomvoiceprocessing.so } loudness_enhancer { path /system/lib/soundfx/libldnhncr.so } } # Default pre-processing library. Add to audio_effect.conf "libraries" section if # audio HAL implements support for default software audio pre-processing effects # # pre_processing { # path /system/lib/soundfx/libaudiopreprocessing.so # } # list of effects to load. Each effect element must contain a "library" and a "uuid" element. # The value of the "library" element must correspond to the name of one library element in the # "libraries" element. # The name of the effect element is indicative, only the value of the "uuid" element # designates the effect. # The uuid is the implementation specific UUID as specified by the effect vendor. This is not the # generic effect type UUID. # effects { # { # library # uuid # } # ... # } effects { # additions for the proxy implementation # Proxy implementation #effectname { #library proxy #uuid xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx # SW implemetation of the effect. Added as a node under the proxy to # indicate this as a sub effect. #libsw { #library libSW #uuid yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy #} End of SW effect # HW implementation of the effect. Added as a node under the proxy to # indicate this as a sub effect. #libhw { #library libHW #uuid zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz #}End of HW effect #} End of effect proxy bassboost { library proxy uuid 14804144-a5ee-4d24-aa88-0002a5d5c51b libsw { library qcbassboost uuid 23aca180-44bd-11e2-bcfd-0800200c9a66 } libhw { library offload_bundle uuid 2c4a8c24-1581-487f-94f6-0002a5d5c51b } } virtualizer { library proxy uuid d3467faa-acc7-4d34-acaf-0002a5d5c51b libsw { library qcvirt uuid e6c98a16-22a3-11e2-b87b-f23c91aec05e } libhw { library offload_bundle uuid 509a4498-561a-4bea-b3b1-0002a5d5c51b } } equalizer { library proxy uuid c8e70ecd-48ca-456e-8a4f-0002a5d5c51b libsw { library bundle uuid ce772f20-847d-11df-bb17-0002a5d5c51b } libhw { library offload_bundle uuid a0dac280-401c-11e3-9379-0002a5d5c51b } } volume { library bundle uuid 119341a0-8469-11df-81f9-0002a5d5c51b } reverb_env_aux { library proxy uuid 48404ac9-d202-4ccc-bf84-0002a5d5c51b libsw { library qcreverb uuid a8c1e5f3-293d-43cd-95ec-d5e26c02e217 } libhw { library offload_bundle uuid 79a18026-18fd-4185-8233-0002a5d5c51b } } reverb_env_ins { library proxy uuid b707403a-a1c1-4291-9573-0002a5d5c51b libsw { library qcreverb uuid 791fff8b-8129-4655-83a4-59bc61034c3a } libhw { library offload_bundle uuid eb64ea04-973b-43d2-8f5e-0002a5d5c51b } } reverb_pre_aux { library proxy uuid 1b78f587-6d1c-422e-8b84-0002a5d5c51b libsw { library qcreverb uuid 53ef1db5-c0c0-445b-b060-e34d20ebb70a } libhw { library offload_bundle uuid 6987be09-b142-4b41-9056-0002a5d5c51b } } reverb_pre_ins { library proxy uuid f3e178d2-ebcb-408e-8357-0002a5d5c51b libsw { library qcreverb uuid b08a0e38-22a5-11e2-b87b-f23c91aec05e } libhw { library offload_bundle uuid aa2bebf6-47cf-4613-9bca-0002a5d5c51b } } visualizer { library proxy uuid 1d0a1a53-7d5d-48f2-8e71-27fbd10d842c libsw { library visualizer_sw uuid d069d9e0-8329-11df-9168-0002a5d5c51b } libhw { library visualizer_hw uuid 7a8044a0-1a71-11e3-a184-0002a5d5c51b } } downmix { library downmix uuid 93f04452-e4fe-41cc-91f9-e475b6d1d69f } hw_acc { library offload_bundle uuid 7d1580bd-297f-4683-9239-e475b6d1d69f } loudness_enhancer { library loudness_enhancer uuid fa415329-2034-4bea-b5dc-5b381c8d1e2c } aec { library qcom_pre_processing uuid 0f8d0d2a-59e5-45fe-b6e4-248c8a799109 } ns { library qcom_pre_processing uuid 1d97bb0b-9e2f-4403-9ae3-58c2554306f8 } } #ifdef VENDOR_EDIT #lifei@OnePlus.MultiMediaService, 2015/12/31,remove this because no use for skype for slove SNDM-206 #pre_processing { # voice_communication { # aec { # } # ns { # } # } #} #endif/*VENDOR_EDIT*/ # Default pre-processing effects. Add to audio_effect.conf "effects" section if # audio HAL implements support for them. # # agc { # library pre_processing # uuid aa8130e0-66fc-11e0-bad0-0002a5d5c51b # } # aec { # library pre_processing # uuid bb392ec0-8d4d-11e0-a896-0002a5d5c51b # } # ns { # library pre_processing # uuid c06c8400-8e06-11e0-9cb6-0002a5d5c51b # } # Audio preprocessor configurations. # The pre processor configuration consists in a list of elements each describing # pre processor settings for a given input source. Valid input source names are: # "mic", "camcorder", "voice_recognition", "voice_communication" # Each input source element contains a list of effects elements. The name of the effect # element must be the name of one of the effects in the "effects" list of the file. # Each effect element may optionally contain a list of parameters and their # default value to apply when the pre processor effect is created. # A parameter is defined by a "param" element and a "value" element. Each of these elements # consists in one or more elements specifying a type followed by a value. # The types defined are: "int", "short", "float", "bool" and "string" # When both "param" and "value" are a single int, a simple form is allowed where just # the param and value pair is present in the parameter description # pre_processing { # { # { # { # param { # int|short|float|bool|string # [ int|short|float|bool|string ] # ... # } # value { # int|short|float|bool|string # [ int|short|float|bool|string ] # ... # } # } # { } # ... # } # ... # } # ... # } # # TODO: add default audio pre processor configurations after debug and tuning phase # ================================================ FILE: audio/audio_output_policy.conf ================================================ # List of profiles for the output device session where stream is routed. # A stream opened with the inputs attributes which match the "flags" and # "formats" as specified in the profile is routed to a device at # sample rate specified under "sampling_rates" and bit width under # "bit_width" and the topology extracted from the acdb data against # the "app_type". # # the flags and formats are specified using the strings corresponding to # enums in audio.h and audio_policy.h. They are concatenated with "|" # without space or "\n". # the flags and formats should match the ones in "audio_policy.conf" outputs { default { flags AUDIO_OUTPUT_FLAG_PRIMARY formats AUDIO_FORMAT_PCM_16_BIT sampling_rates 48000 bit_width 16 app_type 69937 } deep_buffer { flags AUDIO_OUTPUT_FLAG_DEEP_BUFFER formats AUDIO_FORMAT_PCM_16_BIT sampling_rates 48000 bit_width 16 app_type 69936 } direct { flags AUDIO_OUTPUT_FLAG_DIRECT formats AUDIO_FORMAT_PCM_16_BIT sampling_rates 48000 bit_width 16 app_type 69936 } direct_pcm { flags AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_DIRECT_PCM formats AUDIO_FORMAT_PCM_16_BIT sampling_rates 48000 bit_width 16 app_type 69936 } compress_offload_16 { flags AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING formats AUDIO_FORMAT_MP3|AUDIO_FORMAT_AAC|AUDIO_FORMAT_AC3|AUDIO_FORMAT_EAC3|AUDIO_FORMAT_PCM_16_BIT_OFFLOAD|AUDIO_FORMAT_PCM_24_BIT_OFFLOAD|AUDIO_FORMAT_FLAC sampling_rates 48000 bit_width 16 app_type 69936 } compress_offload_24 { flags AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING formats AUDIO_FORMAT_PCM_24_BIT_OFFLOAD|AUDIO_FORMAT_FLAC sampling_rates 48000|96000|192000 bit_width 24 app_type 69940 } } ================================================ FILE: audio/audio_platform_info.xml ================================================ ================================================ FILE: audio/audio_policy.conf ================================================ # Global configuration section: # - lists input and output devices always present on the device # as well as the output device selected by default. # Devices are designated by a string that corresponds to the enum in audio.h # - defines whether the speaker output path uses DRC # "TRUE" means DRC is enabled, "FALSE" or omission means DRC isn't used. global_configuration { attached_output_devices AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_TELEPHONY_TX default_output_device AUDIO_DEVICE_OUT_SPEAKER attached_input_devices AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_BACK_MIC|AUDIO_DEVICE_IN_REMOTE_SUBMIX|AUDIO_DEVICE_IN_VOICE_CALL|AUDIO_DEVICE_IN_TELEPHONY_RX|AUDIO_DEVICE_IN_FM_TUNER speaker_drc_enabled TRUE } # audio hardware module section: contains descriptors for all audio hw modules present on the # device. Each hw module node is named after the corresponding hw module library base name. # For instance, "primary" corresponds to audio.primary..so. # The "primary" module is mandatory and must include at least one output with # AUDIO_OUTPUT_FLAG_PRIMARY flag. # Each module descriptor contains one or more output profile descriptors and zero or more # input profile descriptors. Each profile lists all the parameters supported by a given output # or input stream category. # The "channel_masks", "formats", "devices" and "flags" are specified using strings corresponding # to enums in audio.h and audio_policy.h. They are concatenated by use of "|" without space or "\n". audio_hw_modules { primary { outputs { primary { sampling_rates 44100|48000 channel_masks AUDIO_CHANNEL_OUT_STEREO formats AUDIO_FORMAT_PCM_16_BIT devices AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_FM flags AUDIO_OUTPUT_FLAG_PRIMARY|AUDIO_OUTPUT_FLAG_FAST } raw { sampling_rates 48000 channel_masks AUDIO_CHANNEL_OUT_STEREO formats AUDIO_FORMAT_PCM_16_BIT devices AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL flags AUDIO_OUTPUT_FLAG_FAST|AUDIO_OUTPUT_FLAG_RAW } deep_buffer { sampling_rates 44100|48000 channel_masks AUDIO_CHANNEL_OUT_STEREO formats AUDIO_FORMAT_PCM_16_BIT devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_FM flags AUDIO_OUTPUT_FLAG_DEEP_BUFFER } multichannel { sampling_rates 8000|11025|16000|22050|32000|44100|48000|64000|88200|96000|128000|176400|192000 channel_masks dynamic formats AUDIO_FORMAT_PCM_16_BIT devices AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_PROXY flags AUDIO_OUTPUT_FLAG_DIRECT } direct_pcm { sampling_rates 8000|11025|16000|22050|32000|44100|48000|64000|88200|96000|176400|192000 channel_masks AUDIO_CHANNEL_OUT_MONO|AUDIO_CHANNEL_OUT_STEREO|AUDIO_CHANNEL_OUT_2POINT1|AUDIO_CHANNEL_OUT_QUAD|AUDIO_CHANNEL_OUT_PENTA|AUDIO_CHANNEL_OUT_5POINT1|AUDIO_CHANNEL_OUT_6POINT1|AUDIO_CHANNEL_OUT_7POINT1 formats AUDIO_FORMAT_PCM_16_BIT devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_ALL_SCO flags AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_DIRECT_PCM } compress_offload { sampling_rates 8000|11025|12000|16000|22050|24000|32000|44100|48000|64000|88200|96000|176400|192000 channel_masks AUDIO_CHANNEL_OUT_MONO|AUDIO_CHANNEL_OUT_STEREO|AUDIO_CHANNEL_OUT_2POINT1|AUDIO_CHANNEL_OUT_QUAD|AUDIO_CHANNEL_OUT_PENTA|AUDIO_CHANNEL_OUT_5POINT1|AUDIO_CHANNEL_OUT_6POINT1|AUDIO_CHANNEL_OUT_7POINT1 #ifndef VENDOR_EDIT #lifei@OnePlus.MultiMediaService, 2015/12/23,add MP2 offload playback #formats AUDIO_FORMAT_MP3|AUDIO_FORMAT_AC3|AUDIO_FORMAT_E_AC3|AUDIO_FORMAT_PCM_24_BIT_OFFLOAD|AUDIO_FORMAT_FLAC|AUDIO_FORMAT_AAC_LC|AUDIO_FORMAT_AAC_HE_V1|AUDIO_FORMAT_AAC_HE_V2 #else formats AUDIO_FORMAT_MP3|AUDIO_FORMAT_AC3|AUDIO_FORMAT_E_AC3|AUDIO_FORMAT_PCM_24_BIT_OFFLOAD|AUDIO_FORMAT_FLAC|AUDIO_FORMAT_AAC_LC|AUDIO_FORMAT_AAC_HE_V1|AUDIO_FORMAT_AAC_HE_V2|AUDIO_FORMAT_MP2|AUDIO_FORMAT_AAC #endif/*VENDOR_EDIT*/ devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_PROXY flags AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING } incall_music { sampling_rates 8000|16000|48000 channel_masks AUDIO_CHANNEL_OUT_MONO formats AUDIO_FORMAT_PCM_16_BIT devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_ALL_SCO flags AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_INCALL_MUSIC } voice_tx { sampling_rates 8000|16000|48000 channel_masks AUDIO_CHANNEL_OUT_STEREO|AUDIO_CHANNEL_OUT_MONO formats AUDIO_FORMAT_PCM_16_BIT devices AUDIO_DEVICE_OUT_TELEPHONY_TX } voip_rx { sampling_rates 8000|16000 channel_masks AUDIO_CHANNEL_OUT_MONO formats AUDIO_FORMAT_PCM_16_BIT|AUDIO_FORMAT_AMR_NB|AUDIO_FORMAT_AMR_WB|AUDIO_FORMAT_QCELP|AUDIO_FORMAT_EVRC|AUDIO_FORMAT_EVRCB|AUDIO_FORMAT_EVRCWB|AUDIO_FORMAT_EVRCNW devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_ALL_SCO flags AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_VOIP_RX } } inputs { primary { sampling_rates 8000|11025|12000|16000|22050|24000|32000|44100|48000 channel_masks AUDIO_CHANNEL_IN_5POINT1|AUDIO_CHANNEL_IN_MONO|AUDIO_CHANNEL_IN_STEREO|AUDIO_CHANNEL_IN_FRONT_BACK formats AUDIO_FORMAT_PCM_16_BIT|AUDIO_FORMAT_AMR_NB|AUDIO_FORMAT_AMR_WB|AUDIO_FORMAT_QCELP|AUDIO_FORMAT_EVRC|AUDIO_FORMAT_EVRCB|AUDIO_FORMAT_EVRCWB|AUDIO_FORMAT_EVRCNW devices AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET|AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET|AUDIO_DEVICE_IN_BACK_MIC|AUDIO_DEVICE_IN_VOICE_CALL|AUDIO_DEVICE_IN_FM_TUNER } voice_rx { sampling_rates 8000|16000|48000 channel_masks AUDIO_CHANNEL_IN_STEREO|AUDIO_CHANNEL_IN_MONO formats AUDIO_FORMAT_PCM_16_BIT devices AUDIO_DEVICE_IN_TELEPHONY_RX } } } a2dp { outputs { a2dp { sampling_rates 44100 channel_masks AUDIO_CHANNEL_OUT_STEREO formats AUDIO_FORMAT_PCM_16_BIT devices AUDIO_DEVICE_OUT_ALL_A2DP } } } usb { outputs { usb_accessory { sampling_rates 44100 channel_masks AUDIO_CHANNEL_OUT_STEREO formats AUDIO_FORMAT_PCM_16_BIT devices AUDIO_DEVICE_OUT_USB_ACCESSORY } usb_device { sampling_rates dynamic channel_masks dynamic formats dynamic devices AUDIO_DEVICE_OUT_USB_DEVICE } } inputs { usb_device { sampling_rates dynamic channel_masks dynamic formats dynamic devices AUDIO_DEVICE_IN_USB_DEVICE } } } r_submix { outputs { submix { sampling_rates 48000 channel_masks AUDIO_CHANNEL_OUT_STEREO formats AUDIO_FORMAT_PCM_16_BIT devices AUDIO_DEVICE_OUT_REMOTE_SUBMIX } } inputs { submix { sampling_rates 48000 channel_masks AUDIO_CHANNEL_IN_STEREO formats AUDIO_FORMAT_PCM_16_BIT devices AUDIO_DEVICE_IN_REMOTE_SUBMIX } } } } ================================================ FILE: audio/listen_platform_info.xml ================================================ ================================================ FILE: audio/mixer_paths.xml ================================================ ================================================ FILE: audio/sound_trigger_mixer_paths.xml ================================================ ================================================ FILE: audio/sound_trigger_platform_info.xml ================================================ ================================================ FILE: bluetooth/bdroid_buildcfg.h ================================================ /* * Copyright (C) 2014 The CyanogenMod Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef _BDROID_BUILDCFG_H #define _BDROID_BUILDCFG_H #define BTM_DEF_LOCAL_NAME "OnePlus 2" // Disables read remote device feature #define BTA_SKIP_BLE_READ_REMOTE_FEAT FALSE #define MAX_ACL_CONNECTIONS 7 #define MAX_L2CAP_CHANNELS 16 #define BLE_VND_INCLUDED TRUE // skips conn update at conn completion #define BTA_BLE_SKIP_CONN_UPD FALSE #define BLE_PERIPHERAL_ADV_NAME FALSE #define BT_CLEAN_TURN_ON_DISABLED 1 #endif ================================================ FILE: board-info.txt ================================================ require version-trustzone=TZ.BF.3.0.R1-00201 ================================================ FILE: camera/Android.mk ================================================ # Copyright (C) 2008 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := sensors.hal.tof LOCAL_C_INCLUDES := kernel/include/linux/input LOCAL_MODULE_RELATIVE_PATH := hw LOCAL_MODULE_TAGS := optional LOCAL_CFLAGS := -DLOG_TAG=\"Sensors\" LOCAL_SRC_FILES := \ sensors.cpp \ SensorBase.cpp \ ProximitySensor.cpp \ InputEventReader.cpp LOCAL_SHARED_LIBRARIES := liblog libcutils LOCAL_PRELINK_MODULE := false include $(BUILD_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_C_INCLUDES := \ system/media/camera/include LOCAL_SRC_FILES := \ CameraWrapper.cpp LOCAL_SHARED_LIBRARIES := \ libhardware liblog libgui libutils LOCAL_MODULE_RELATIVE_PATH := hw LOCAL_MODULE := camera.$(TARGET_BOARD_PLATFORM) LOCAL_MODULE_TAGS := optional include $(BUILD_SHARED_LIBRARY) ================================================ FILE: camera/CameraWrapper.cpp ================================================ /* Copyright (C) 2016, The CyanogenMod Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @file CameraWrapper.cpp * * This file wraps a vendor camera module. * */ //#define LOG_NDEBUG 0 #define LOG_TAG "CameraWrapper" #include #include #include #include #include #include static android::Mutex gCameraWrapperLock; static camera_module_t *gVendorModule = 0; static int camera_device_open(const hw_module_t *module, const char *name, hw_device_t **device); static int camera_get_number_of_cameras(void); static int camera_get_camera_info(int camera_id, struct camera_info *info); static struct hw_module_methods_t camera_module_methods = { .open = camera_device_open }; camera_module_t HAL_MODULE_INFO_SYM = { .common = { .tag = HARDWARE_MODULE_TAG, .module_api_version = CAMERA_MODULE_API_VERSION_1_0, .hal_api_version = HARDWARE_HAL_API_VERSION, .id = CAMERA_HARDWARE_MODULE_ID, .name = "OnePlus 2 Camera Wrapper", .author = "The CyanogenMod Project", .methods = &camera_module_methods, .dso = NULL, /* remove compilation warnings */ .reserved = {0}, /* remove compilation warnings */ }, .get_number_of_cameras = camera_get_number_of_cameras, .get_camera_info = camera_get_camera_info, .set_callbacks = NULL, /* remove compilation warnings */ .get_vendor_tag_ops = NULL, /* remove compilation warnings */ .open_legacy = NULL, /* remove compilation warnings */ .set_torch_mode = NULL, /* remove compilation warnings */ .init = NULL, /* remove compilation warnings */ .reserved = {0}, /* remove compilation warnings */ }; static int load(const char *path, const struct hw_module_t **pHmi) { int status = 0; void *handle = NULL; struct hw_module_t *hmi = NULL; handle = dlopen(path, RTLD_NOW); if (handle == NULL) { status = -EINVAL; goto done; } hmi = (struct hw_module_t *)dlsym(handle, HAL_MODULE_INFO_SYM_AS_STR); if (hmi == NULL) { status = -EINVAL; goto done; } hmi->dso = handle; done: *pHmi = hmi; return status; } static int check_vendor_module() { int rv = 0; ALOGV("%s", __FUNCTION__); if (gVendorModule) return 0; rv = load("/system/lib/hw/camera.vendor.msm8994.so", (const hw_module_t**)&gVendorModule); if (rv) ALOGE("failed to open vendor camera module"); return rv; } static int camera_device_open(const hw_module_t *module __unused, const char *name, hw_device_t **device) { int rv = 0; int num_cameras = 0; int cameraid; int cameraretry; android::Mutex::Autolock lock(gCameraWrapperLock); ALOGV("%s", __FUNCTION__); if (name == NULL || check_vendor_module() != android::NO_ERROR) { return -EINVAL; } for (cameraretry = 0; cameraretry < 2; cameraretry++) { rv = gVendorModule->common.methods->open( (const hw_module_t*)gVendorModule, name, device); if (!rv) break; ALOGV("%s: open failed - retrying attempt %d",__FUNCTION__, cameraretry); } if (rv) ALOGE("vendor camera open fail"); return rv; } static int camera_get_number_of_cameras(void) { ALOGV("%s", __FUNCTION__); if (check_vendor_module()) return 0; return gVendorModule->get_number_of_cameras(); } static int camera_get_camera_info(int camera_id, struct camera_info *info) { ALOGV("%s", __FUNCTION__); if (check_vendor_module()) return 0; return gVendorModule->get_camera_info(camera_id, info); } ================================================ FILE: camera/InputEventReader.cpp ================================================ /* * Copyright (C) 2014 STMicroelectronics, Inc. * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include #include "InputEventReader.h" /*****************************************************************************/ struct input_event; InputEventCircularReader::InputEventCircularReader(size_t numEvents) : mBuffer(new input_event[numEvents * 2]), mBufferEnd(mBuffer + numEvents), mHead(mBuffer), mCurr(mBuffer), mFreeSpace(numEvents) { } InputEventCircularReader::~InputEventCircularReader() { delete [] mBuffer; } ssize_t InputEventCircularReader::fill(int fd) { size_t numEventsRead = 0; if (mFreeSpace) { const ssize_t nread = read(fd, mHead, mFreeSpace * sizeof(input_event)); if (nread<0 || nread % sizeof(input_event)) { // we got a partial event!! return nread<0 ? -errno : -EINVAL; } numEventsRead = nread / sizeof(input_event); if (numEventsRead) { mHead += numEventsRead; mFreeSpace -= numEventsRead; if (mHead > mBufferEnd) { size_t s = mHead - mBufferEnd; memcpy(mBuffer, mBufferEnd, s * sizeof(input_event)); mHead = mBuffer + s; } } } return numEventsRead; } ssize_t InputEventCircularReader::readEvent(input_event const** events) { *events = mCurr; ssize_t available = (mBufferEnd - mBuffer) - mFreeSpace; return available ? 1 : 0; } void InputEventCircularReader::next() { mCurr++; mFreeSpace++; if (mCurr >= mBufferEnd) { mCurr = mBuffer; } } ================================================ FILE: camera/InputEventReader.h ================================================ /* * Copyright (C) 2013 STMicroelectronics, Inc. * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_INPUT_EVENT_READER_H #define ANDROID_INPUT_EVENT_READER_H #include #include #include #include #include /*****************************************************************************/ struct input_event; class InputEventCircularReader { struct input_event* const mBuffer; struct input_event* const mBufferEnd; struct input_event* mHead; struct input_event* mCurr; ssize_t mFreeSpace; public: InputEventCircularReader(size_t numEvents); ~InputEventCircularReader(); ssize_t fill(int fd); ssize_t readEvent(input_event const** events); void next(); }; /*****************************************************************************/ #endif // ANDROID_INPUT_EVENT_READER_H ================================================ FILE: camera/ProximitySensor.cpp ================================================ /* * Copyright (C) 2014 STMicroelectronics, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include #include #include "configuration.h" #include "ProximitySensor.h" //#define FETCH_FULL_EVENT_BEFORE_RETURN 1 /*****************************************************************************/ ProximitySensor::ProximitySensor() : SensorBase(NULL, "STM VL6180 proximity sensor"), mEnabled(0), mBatchEnabled(0), mInputReader(4), mHasPendingEvent(false) { //Added for debug LOGV("ProximitySensor::ProximitySensor gets called!"); mPendingEvent.version = sizeof(sensors_event_t); mPendingEvent.sensor = ID_P; mPendingEvent.type = SENSOR_TYPE_TIME_OF_FLIGHT; memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data)); if (data_fd) { strcpy(input_sysfs_path, "/sys/class/input/"); strcat(input_sysfs_path, "input"); strcat(input_sysfs_path, input_name+5); strcat(input_sysfs_path, "/device/"); input_sysfs_path_len = strlen(input_sysfs_path); LOGV("ProximitySensor: input_name:%s, input_sysfs_path:%s",input_name,input_sysfs_path); enable(0, 1); }else LOGV("%s:%d wrong fd", __func__, __LINE__); } ProximitySensor::~ProximitySensor() { if (mEnabled) { enable(0, 0); } } int ProximitySensor::setInitialState() { struct input_absinfo absinfo; int rc; rc = ioctl(data_fd, EVIOCGABS(EVENT_TYPE_PROXIMITY), &absinfo); if (!rc ) { LOGE("%s:%d Pend event successfully!", __func__, __LINE__); mHasPendingEvent = true; mPendingEvent.distance = absinfo.value; return 0; } else{ LOGV("%s:%d Pend event failed!", __func__, __LINE__); return rc; } } int ProximitySensor::enable(int32_t, int en) { //Added for debug LOGE("ProximitySensor::enable function called for stmvl6180 %d!", en); char buf[2]; int err; int flags = en ? 1 : 0; if (flags != mEnabled) { int fd; //strcpy(&input_sysfs_path[input_sysfs_path_len], "enable"); //fd = open(input_sysfs_path, O_RDWR); fd = open(PROXIMITY_ENABLE_FILENAME_CCI, O_RDWR); if(fd < 0){ LOGE("%s:%d open %s failed(%s), try to open %s", __func__, __LINE__, PROXIMITY_ENABLE_FILENAME_CCI, strerror(errno), PROXIMITY_ENABLE_FILENAME_I2C); fd = open(PROXIMITY_ENABLE_FILENAME_I2C, O_RDWR); } if (fd >= 0) { buf[1] = 0; if (flags) { buf[0] = '1'; } else { buf[0] = '0'; } LOGV("%s:%d fd = %d, flags = %d", __func__, __LINE__, fd, flags); err = write(fd, buf, sizeof(buf)); LOGV("%s:%d after write", __func__, __LINE__, fd, flags); if(err <= 0){ LOGE("%s:%d write %d failed: %s", __func__, __LINE__, fd, strerror(errno)); close(fd); return err; } else LOGV("%s:%d write successfully!", __func__, __LINE__, fd, flags); close(fd); mEnabled = flags; setInitialState(); //Added for debug LOGV("ProximitySensor::enable enabled VL6180! Error code(2 should indicate success): %d", err); return 0; } LOGV("ProximitySensor::enable: Failed to open %s for enabling VL6180 %s", PROXIMITY_ENABLE_FILENAME_I2C, strerror(errno)); LOGV("ProximitySensor::enable: Attempted to open file %s", input_sysfs_path); return -1; } return 0; } bool ProximitySensor::hasPendingEvents() const { return mHasPendingEvent; } int ProximitySensor::batch(int handle, int flags, int64_t period_ns, int64_t timeout) { int err; if (period_ns > 0) { int fd; fd = open(PROXIMITY_SET_DELAY_FILENAME_CCI, O_RDWR); if(fd < 0){ LOGE("%s:%d open %s failed(%s), try to open %s", __func__, __LINE__, PROXIMITY_SET_DELAY_FILENAME_CCI, strerror(errno), PROXIMITY_SET_DELAY_FILENAME_I2C); fd = open(PROXIMITY_SET_DELAY_FILENAME_I2C, O_RDWR); } if (fd >= 0) { char buf[80]; sprintf(buf,"%lld", period_ns / 1000000); err = write(fd, buf, strlen(buf)+1); close(fd); //Added for debug LOGV("ProximitySensor::batch return: %d", err); return 0; } LOGV("ProximitySensor::batch: Failed to open %s for set delay time(%s)", PROXIMITY_SET_DELAY_FILENAME_I2C, strerror(errno)); return -1; } return 0; } int ProximitySensor::setDelay(int32_t handle, int64_t delay_ns) { LOGV("ProximitySensor::setDelay called!"); int fd; strcpy(&input_sysfs_path[input_sysfs_path_len], "pollrate_ms"); fd = open(input_sysfs_path, O_RDWR); if (fd >= 0) { char buf[80]; sprintf(buf, "%lld", delay_ns / 1000000); write(fd, buf, strlen(buf)+1); close(fd); //Added for debug LOGV("ProximitySensor::setDelay is successful!"); return 0; } LOGV("ProximitySensor::setDelay failed!"); return -1; } int ProximitySensor::readEvents(sensors_event_t* data, int count) { //Added for debug if (count < 1) return -EINVAL; if (mHasPendingEvent) { mHasPendingEvent = false; mPendingEvent.timestamp = getTimestamp(); *data = mPendingEvent; return mEnabled ? 1 : 0; } ssize_t n = mInputReader.fill(data_fd); if (n < 0){ LOGE("ProximitySensor::readEvents: Did not successfully read an event, error: %d", n); return n; } int numEventReceived = 0; input_event const* event; #if FETCH_FULL_EVENT_BEFORE_RETURN again: #endif LOGV("ProximitySensor::readEvents: At readEvent loop, probably was able to read at least one event successfully"); while (count && mInputReader.readEvent(&event)) { int type = event->type; if (type == EV_ABS) { if (event->code == EVENT_TYPE_PROXIMITY) { //ABS_DISTANCE if (event->value != -1) { // FIXME: not sure why we're getting -1 sometimes //mPendingEvent.distance = indexToValue(event->value); //mPendingEvent.distance = event->value; mPendingEvent.data[0] = event->value; LOGE("%s:%d mPendingEvent.data[0] = %d",__func__, __LINE__, event->value); } } /* else if (event->code == ABS_X) mPendingEvent.data[1] = event->value; else if (event->code == ABS_HAT0X) mPendingEvent.data[2] = event->value; */ else if (event->code == ABS_HAT0X){ mPendingEvent.data[1] = event->value; LOGV("%s:%d mPendingEvent.data[1] = %d",__func__, __LINE__, event->value); } else if (event->code == ABS_HAT0Y){ mPendingEvent.data[2] = event->value; LOGV("%s:%d mPendingEvent.data[2] = %d",__func__, __LINE__, event->value); } else if (event->code == ABS_HAT1X){ mPendingEvent.data[3] = event->value; LOGV("%s:%d mPendingEvent.data[3] = %d",__func__, __LINE__, event->value); } else if (event->code == ABS_HAT1Y){ mPendingEvent.data[4] = event->value; LOGV("%s:%d mPendingEvent.data[4] = %d",__func__, __LINE__, event->value); } else if (event->code == ABS_HAT2X){ mPendingEvent.data[5] = event->value; LOGV("%s:%d mPendingEvent.data[5] = %d",__func__, __LINE__, event->value); } else if (event->code == ABS_HAT2Y){ mPendingEvent.data[6] = event->value; LOGV("%s:%d mPendingEvent.data[6] = %d",__func__, __LINE__, event->value); } else if (event->code == ABS_HAT3X){ mPendingEvent.data[7] = event->value; LOGV("%s:%d mPendingEvent.data[7] = %d",__func__, __LINE__, event->value); } else if (event->code == ABS_HAT3Y){ mPendingEvent.data[8] = event->value; LOGV("%s:%d mPendingEvent.data[8] = %d",__func__, __LINE__, event->value); } LOGV("ProximitySensor: gets one ps data event!"); } else if (type == EV_SYN) { mPendingEvent.timestamp = timevalToNano(event->time); if (mEnabled) { *data++ = mPendingEvent; numEventReceived++; count--; //Added for debug LOGV("ProximitySensor: gets one ps sync event!"); } } else { LOGV("ProximitySensor: unknown event (type=%d, code=%d)", type, event->code); } mInputReader.next(); } #if 0 LOGV("HAL: distance: %f cm tv_sec: %f tv_usec: %f " "distance: %fmm error_code: %x signalRate_mcps: %f " "rtnAmbRate(kcps): %f rtnConvTime: %f dmax_sq: %f", mPendingEvent.data[0], mPendingEvent.data[1], mPendingEvent.data[2], mPendingEvent.data[3], mPendingEvent.data[4], mPendingEvent.data[5], mPendingEvent.data[6],mPendingEvent.data[7], mPendingEvent.data[8]); #endif #if FETCH_FULL_EVENT_BEFORE_RETURN /* if we didn't read a complete event, see if we can fill and try again instead of returning with nothing and redoing poll. */ if (numEventReceived == 0 && mEnabled == 1) { n = mInputReader.fill(data_fd); if (n) goto again; } #endif return numEventReceived; } ================================================ FILE: camera/ProximitySensor.h ================================================ /* * Copyright (C) 2014 STMicroelectronics, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_PROXIMITY_SENSOR_H #define ANDROID_PROXIMITY_SENSOR_H #include #include #include #include #include "sensors.h" #include "SensorBase.h" #include "InputEventReader.h" /*****************************************************************************/ struct input_event; class ProximitySensor : public SensorBase { int mEnabled; int mBatchEnabled; InputEventCircularReader mInputReader; sensors_event_t mPendingEvent; bool mHasPendingEvent; char input_sysfs_path[PATH_MAX]; int input_sysfs_path_len; int setInitialState(); public: ProximitySensor(); virtual ~ProximitySensor(); virtual int readEvents(sensors_event_t* data, int count); virtual bool hasPendingEvents() const; virtual int setDelay(int32_t handle, int64_t ns); virtual int enable(int32_t handle, int enabled); virtual int batch(int handle, int flags, int64_t period_ns, int64_t timeout); }; /*****************************************************************************/ #endif // ANDROID_PROXIMITY_SENSOR_H ================================================ FILE: camera/SensorBase.cpp ================================================ /* * Copyright (C) 2014 STMicroelectronice, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include #include #include "SensorBase.h" /*****************************************************************************/ SensorBase::SensorBase( const char* dev_name, const char* data_name) : dev_name(dev_name), data_name(data_name), dev_fd(-1), data_fd(-1) { if (data_name) { data_fd = openInput(data_name); } } SensorBase::~SensorBase() { if (data_fd >= 0) { close(data_fd); } if (dev_fd >= 0) { close(dev_fd); } } int SensorBase::open_device() { if (dev_fd<0 && dev_name) { dev_fd = open(dev_name, O_RDONLY); LOGE_IF(dev_fd<0, "Couldn't open %s (%s)", dev_name, strerror(errno)); } return 0; } int SensorBase::close_device() { if (dev_fd >= 0) { close(dev_fd); dev_fd = -1; } return 0; } int SensorBase::getFd() const { if (!data_name) { return dev_fd; } return data_fd; } int SensorBase::setDelay(int32_t handle, int64_t ns) { return 0; } bool SensorBase::hasPendingEvents() const { return false; } int64_t SensorBase::getTimestamp() { struct timespec t; t.tv_sec = t.tv_nsec = 0; clock_gettime(CLOCK_MONOTONIC, &t); return int64_t(t.tv_sec)*1000000000LL + t.tv_nsec; } int SensorBase::openInput(const char* inputName) { int fd = -1; char devname[PATH_MAX] = "/dev/stm_sensor"; char *filename; fd = open(devname, O_RDONLY); if (fd>=0) { char name[80]; if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) { name[0] = '\0'; } if (!strcmp(name, inputName)) { strcpy(input_name, devname); } else { close(fd); fd = -1; } } LOGE_IF(fd<0, "couldn't find '%s' input device", inputName); return fd; } int SensorBase::enable(int32_t handle, int enabled) { return 0; } int SensorBase::query(int what, int* value) { return 0; } int SensorBase::batch(int handle, int flags, int64_t period_ns, int64_t timeout) { return 0; } ================================================ FILE: camera/SensorBase.h ================================================ /* * Copyright (C) 2014 STMicroelectronics, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_SENSOR_BASE_H #define ANDROID_SENSOR_BASE_H #include #include #include #include #include //#if defined ANDROID_JELLYBEAN //build for Jellybean #define LOGV_IF ALOGV_IF #define LOGE_IF ALOGE_IF #define LOGI_IF ALOGI_IF #define LOGI ALOGI #define LOGE ALOGE #define LOGV ALOGV #define LOGW ALOGW //#else //build for ICS or earlier version //#endif /*****************************************************************************/ struct sensors_event_t; class SensorBase { protected: const char* dev_name; const char* data_name; char input_name[PATH_MAX]; int dev_fd; int data_fd; int openInput(const char* inputName); static int64_t getTimestamp(); static int64_t timevalToNano(timeval const& t) { return t.tv_sec*1000000000LL + t.tv_usec*1000; } int open_device(); int close_device(); public: SensorBase(const char* dev_name, const char* data_name); virtual ~SensorBase(); virtual int readEvents(sensors_event_t* data, int count) = 0; virtual bool hasPendingEvents() const; virtual int getFd() const; virtual int setDelay(int32_t handle, int64_t ns); virtual int enable(int32_t handle, int enabled) = 0; virtual int query(int what, int* value); virtual int batch(int handle, int flags, int64_t period_ns, int64_t timeout); }; /*****************************************************************************/ #endif // ANDROID_SENSOR_BASE_H ================================================ FILE: camera/configuration.h ================================================ /* * Copyright (C) 2014 STMicroelectronics, Inc. * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef STM_SENSORS_CONFIGURATION_H #define STM_SENSORS_CONFIGURATION_H #include #include #include #include __BEGIN_DECLS #define SENSOR_PROXIMITY_LABEL "Time of Flight Proximity Sensor" #define SENSOR_PROXIMITY_DATANAME "STM VL6180 proximity sensor" #define PROXIMITY_ENABLE_FILENAME_CCI "/sys/bus/platform/devices/29.qcom,proximity/enable_ps_sensor" #define PROXIMITY_SET_DELAY_FILENAME_CCI "/sys/bus/platform/devices/29.qcom,proximity/set_delay_ms" #define PROXIMITY_ENABLE_FILENAME_I2C "/sys/bus/i2c/devices/i2c-6/6-0029/enable_ps_sensor" #define PROXIMITY_SET_DELAY_FILENAME_I2C "/sys/bus/i2c/devices/i2c-6/6-0029/set_delay_ms" #define PROXIMITY_MAX_RANGE 76 #define PROXIMITY_POWER_CONSUMPTION 0.23f #define PROXIMITY_MIN_DELAY 5000 //in microseconds #define PROXIMITY_FIFO_RESERVED_COUNT 0 #define PROXIMITY_FIFO_MAX_COUNT 0 #define SENSOR_TYPE_TIME_OF_FLIGHT (30) __END_DECLS #endif // ANDROID_SENSORS_H ================================================ FILE: camera/sensors.cpp ================================================ /* * Copyright (C) 2014 STMicroelectronics, Inc. * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "Sensors" #include #include #include #include #include #include #include #include #include #include #include #include "sensors.h" #include "configuration.h" #include "ProximitySensor.h" /*****************************************************************************/ #define DELAY_OUT_TIME 0x7FFFFFFF /* #define SENSORS_ACCELERATION (1<getFd(); mPollFds[proximity].events = POLLIN; mPollFds[proximity].revents = 0; int wakeFds[2]; int result = pipe(wakeFds); LOGE_IF(result<0, "error creating wake pipe (%s)", strerror(errno)); fcntl(wakeFds[0], F_SETFL, O_NONBLOCK); fcntl(wakeFds[1], F_SETFL, O_NONBLOCK); mWritePipeFd = wakeFds[1]; mPollFds[wake].fd = wakeFds[0]; mPollFds[wake].events = POLLIN; mPollFds[wake].revents = 0; } sensors_poll_context_t::~sensors_poll_context_t() { for (int i=0 ; ienable(handle, enabled); LOGV("%s:%d enabled = %d, err = %d", __func__, __LINE__, enabled, err); if (enabled && !err) { const char wakeMessage(WAKE_MESSAGE); int result = write(mWritePipeFd, &wakeMessage, 1); LOGE_IF(result<0, "error sending wake message (%s)", strerror(errno)); } return err; } int sensors_poll_context_t::setDelay(int handle, int64_t ns) { //Added for debug LOGV("sensors_poll_context_t::setDelay gets called!"); int index = handleToDriver(handle); if (index < 0) return index; return 0; } int sensors_poll_context_t::pollEvents(sensors_event_t* data, int count) { int nbEvents = 0; int n = 0; //Added for debug LOGV("sensors_poll_context_t::pollEvents gets called!"); do { // see if we have some leftover from the last poll() for (int i=0 ; count && ihasPendingEvents())) { int nb = sensor->readEvents(data, count); if (nb < count) { // no more data for this sensor mPollFds[i].revents = 0; } count -= nb; nbEvents += nb; data += nb; } } if (count) { // we still have some room, so try to see if we can get // some events immediately or just wait if we don't have // anything to return n = poll(mPollFds, numFds, nbEvents ? 0 : -1); if (n<0) { LOGE("poll() failed (%s)", strerror(errno)); return -errno; } if (mPollFds[wake].revents & POLLIN) { char msg; int result = read(mPollFds[wake].fd, &msg, 1); LOGE_IF(result<0, "error reading from wake pipe (%s)", strerror(errno)); LOGE_IF(msg != WAKE_MESSAGE, "unknown message on wake queue (0x%02x)", int(msg)); mPollFds[wake].revents = 0; } } // if we have events and space, go read them } while (n && count); return nbEvents; } int sensors_poll_context_t::query(int handle, int* value) { //Added for debug LOGV("sensors_poll_context_t::query gets called!"); int index = handleToDriver(handle); if (index < 0) return index; return mSensors[index]->query(handle, value); } int sensors_poll_context_t::batch(int handle, int flags, int64_t period_ns, int64_t timeout) { //Added for debug LOGV("sensors_poll_context_t::batch gets called!"); int index = handleToDriver(handle); if (index < 0) return index; return mSensors[index]->batch(handle, flags, period_ns, timeout); } /*****************************************************************************/ static int poll__close(struct hw_device_t *dev) { sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; if (ctx) { delete ctx; } return 0; } static int poll__activate(struct sensors_poll_device_t *dev, int handle, int enabled) { sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; return ctx->activate(handle, enabled); } static int poll__setDelay(struct sensors_poll_device_t *dev, int handle, int64_t ns) { sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; return ctx->setDelay(handle, ns); } static int poll__poll(struct sensors_poll_device_t *dev, sensors_event_t* data, int count) { sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; return ctx->pollEvents(data, count); } static int poll__query(struct sensors_poll_device_1 *dev, int what, int *value) { sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; return ctx->query(what, value); } static int poll__batch(struct sensors_poll_device_1 *dev, int handle, int flags, int64_t period_ns, int64_t timeout) { sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; return ctx->batch(handle, flags, period_ns, timeout); } /*****************************************************************************/ /** Open a new instance of a sensor device using name */ static int open_sensors(const struct hw_module_t* module, const char* id, struct hw_device_t** device) { int status = -EINVAL; sensors_poll_context_t *dev = new sensors_poll_context_t(); memset(&dev->device, 0, sizeof(sensors_poll_device_1)); dev->device.common.tag = HARDWARE_DEVICE_TAG; dev->device.common.version = SENSORS_DEVICE_API_VERSION_1_0; dev->device.common.module = const_cast(module); dev->device.common.close = poll__close; dev->device.activate = poll__activate; dev->device.setDelay = poll__setDelay; dev->device.poll = poll__poll; /* Batch processing */ dev->device.batch = poll__batch; *device = &dev->device.common; status = 0; //Added for debug LOGV("open_sensors gets called!"); return status; } ================================================ FILE: camera/sensors.h ================================================ /* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_SENSORS_H #define ANDROID_SENSORS_H #include #include #include #include #include #include #include #include __BEGIN_DECLS /*****************************************************************************/ #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) #define ID_A (0) #define ID_M (1) #define ID_O (2) #define ID_L (3) #define ID_P (4) #define ID_GY (5) #define ID_PR (6) #define ID_T (7) /*****************************************************************************/ /* * The SENSORS Module */ /* the GP2A is a binary proximity sensor that triggers around 5 cm on * this hardware */ #define PROXIMITY_THRESHOLD_GP2A 5.0f /*****************************************************************************/ #define EVENT_TYPE_ACCEL_X ABS_X #define EVENT_TYPE_ACCEL_Y ABS_Y #define EVENT_TYPE_ACCEL_Z ABS_Z #define EVENT_TYPE_YAW REL_RX #define EVENT_TYPE_PITCH REL_RY #define EVENT_TYPE_ROLL REL_RZ #define EVENT_TYPE_ORIENT_STATUS REL_WHEEL #define EVENT_TYPE_MAG_X ABS_X #define EVENT_TYPE_MAG_Y ABS_Y #define EVENT_TYPE_MAG_Z ABS_Z #define EVENT_TYPE_PROXIMITY ABS_DISTANCE #define EVENT_TYPE_LIGHT ABS_MISC #define EVENT_TYPE_GYRO_X ABS_X #define EVENT_TYPE_GYRO_Y ABS_Y #define EVENT_TYPE_GYRO_Z ABS_Z #define EVENT_TYPE_PRESS ABS_PRESSURE #define EVENT_TYPE_TEMP ABS_GAS // under default setting in acc driver, Full Scale = 2G, 1000 LSG = 1G #define LSG (1000.0f) // conversion of acceleration data to SI units (m/s^2) #define RANGE_A (2*GRAVITY_EARTH) #define CONVERT_A (GRAVITY_EARTH / LSG) #define CONVERT_A_X (CONVERT_A) #define CONVERT_A_Y (CONVERT_A) #define CONVERT_A_Z (CONVERT_A) // conversion of magnetic data to uT units // conversion of magnetic data to uT units. 1G = 100 uT. #define CONVERT_M (1.0f/10.0f) #define CONVERT_M_X (CONVERT_M) #define CONVERT_M_Y (CONVERT_M) #define CONVERT_M_Z (CONVERT_M) /* conversion of orientation data to degree units */ #define CONVERT_O (1.0f/64.0f) #define CONVERT_O_A (CONVERT_O) #define CONVERT_O_P (CONVERT_O) #define CONVERT_O_R (CONVERT_O) /* Conversion of pressure and temperature */ #define CONVERT_P (1.0f/4096.0f) #define CONVERT_T(x) ((x / 480.0f) + 42.5) // conversion of gyro data to SI units (radian/sec) //#define RANGE_GYRO (2000.0f*(float)M_PI/180.0f) // #define CONVERT_GYRO ((70.0f / 1000.0f) * ((float)M_PI / 180.0f)) // ************************** // under default setting in gyro driver, Full Scale = 250dps, sensitivity = 8.75 mdps/digit #define GYRO_SSTVT (8.75f/1000.0f) #define CONVERT_GYRO (GYRO_SSTVT * ((float)M_PI / 180.0f)) #define CONVERT_GYRO_X (CONVERT_GYRO) #define CONVERT_GYRO_Y (CONVERT_GYRO) #define CONVERT_GYRO_Z (CONVERT_GYRO) #define SENSOR_STATE_MASK (0x7FFF) /*****************************************************************************/ __END_DECLS #endif // ANDROID_SENSORS_H ================================================ FILE: cm.dependencies ================================================ [ { "repository": "android_device_oppo_common", "target_path": "device/oppo/common" }, { "repository": "android_kernel_oneplus_msm8994", "target_path": "kernel/oneplus/msm8994" }, { "repository": "android_packages_resources_devicesettings", "target_path": "packages/resources/devicesettings" } ] ================================================ FILE: cm.mk ================================================ # Copyright (C) 2016 The CyanogenMod Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Inherit from those products. Most specific first. $(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk) $(call inherit-product, $(SRC_TARGET_DIR)/product/full_base_telephony.mk) # Inherit from oneplus2 device $(call inherit-product, device/oneplus/oneplus2/device.mk) # Inherit some common CM stuff. $(call inherit-product, vendor/cm/config/common_full_phone.mk) PRODUCT_NAME := cm_oneplus2 PRODUCT_DEVICE := oneplus2 PRODUCT_MANUFACTURER := OnePlus PRODUCT_BRAND := OnePlus PRODUCT_GMS_CLIENTID_BASE := android-oneplus TARGET_VENDOR_PRODUCT_NAME := OnePlus2 TARGET_VENDOR_DEVICE_NAME := OnePlus2 PRODUCT_BUILD_PROP_OVERRIDES += TARGET_DEVICE=OnePlus2 PRODUCT_NAME=OnePlus2 PRODUCT_BUILD_PROP_OVERRIDES += \ BUILD_FINGERPRINT=OnePlus/OnePlus2/OnePlus2:6.0.1/MMB29M/1447840920:user/release-keys \ PRIVATE_BUILD_DESC="OnePlus2-user 6.0.1 MMB29M 20 dev-keys" PRODUCT_SYSTEM_PROPERTY_BLACKLIST += ro.product.model TARGET_VENDOR := oneplus ================================================ FILE: cmhw/org/cyanogenmod/hardware/KeyDisabler.java ================================================ /* * Copyright (C) 2014 The CyanogenMod Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.cyanogenmod.hardware; import org.cyanogenmod.internal.util.FileUtils; /* * Disable capacitive keys * * This is intended for use on devices in which the capacitive keys * can be fully disabled for replacement with a soft navbar. You * really should not be using this on a device with mechanical or * otherwise visible-when-inactive keys */ public class KeyDisabler { private static String CONTROL_PATH = "/proc/s1302/virtual_key"; public static boolean isSupported() { return FileUtils.isFileWritable(CONTROL_PATH); } public static boolean isActive() { return FileUtils.readOneLine(CONTROL_PATH).contains("enabled"); } public static boolean setActive(boolean state) { return FileUtils.writeLine(CONTROL_PATH, (state ? "1" : "0")); } } ================================================ FILE: configs/media_codecs.xml ================================================ ================================================ FILE: configs/media_codecs_performance.xml ================================================ ================================================ FILE: configs/media_profiles.xml ================================================ ]> ================================================ FILE: configs/msm_irqbalance.conf ================================================ PRIO=1,1,1,1,0,0,0,0 IGNORED_IRQ=20,40,200,203,155,157 ================================================ FILE: configs/sec_config ================================================ /* IPC Security Config */ /* :: */ 16:4294967295:1000:3004 /* Allow SS CTL service to be used by system and net_raw processes */ 43:4294967295:1000:3004 /* :: */ 50:4294967295:1001 /* Allow Sensor services to be used by sensor process */ 256:4294967295:3011 257:4294967295:3011 258:4294967295:3011 259:4294967295:3011 260:4294967295:3011 261:4294967295:3011 262:4294967295:3011 263:4294967295:3011 264:4294967295:3011 265:4294967295:3011 266:4294967295:3011 267:4294967295:3011 268:4294967295:3011 269:4294967295:3011 270:4294967295:3011 271:4294967295:3011 272:4294967295:3011 273:4294967295:3011 274:4294967295:3011 275:4294967295:3011 276:4294967295:3011 277:4294967295:3011 278:4294967295:3011 279:4294967295:3011 280:4294967295:3011 281:4294967295:3011 282:4294967295:3011 283:4294967295:3011 284:4294967295:3011 285:4294967295:3011 286:4294967295:3011 287:4294967295:3011 288:4294967295:3011 289:4294967295:3011 290:4294967295:3011 291:4294967295:3011 292:4294967295:3011 293:4294967295:3011 294:4294967295:3011 295:4294967295:3011 296:4294967295:3011 297:4294967295:3011 298:4294967295:3011 299:4294967295:3011 300:4294967295:3011 301:4294967295:3011 302:4294967295:3011 303:4294967295:3011 304:4294967295:3011 305:4294967295:3011 306:4294967295:3011 307:4294967295:3011 308:4294967295:3011 309:4294967295:3011 310:4294967295:3011 311:4294967295:3011 312:4294967295:3011 313:4294967295:3011 314:4294967295:3011 315:4294967295:3011 316:4294967295:3011 317:4294967295:3011 318:4294967295:3011 319:4294967295:3011 320:4294967295:3011 321:4294967295:3011 322:4294967295:3011 323:4294967295:3011 324:4294967295:3011 325:4294967295:3011 326:4294967295:3011 327:4294967295:3011 328:4294967295:3011 329:4294967295:3011 330:4294967295:3011 331:4294967295:3011 332:4294967295:3011 333:4294967295:3011 334:4294967295:3011 335:4294967295:3011 336:4294967295:3011 337:4294967295:3011 338:4294967295:3011 339:4294967295:3011 340:4294967295:3011 341:4294967295:3011 342:4294967295:3011 343:4294967295:3011 344:4294967295:3011 345:4294967295:3011 346:4294967295:3011 347:4294967295:3011 348:4294967295:3011 349:4294967295:3011 350:4294967295:3011 351:4294967295:3011 352:4294967295:3011 353:4294967295:3011 354:4294967295:3011 355:4294967295:3011 356:4294967295:3011 357:4294967295:3011 358:4294967295:3011 359:4294967295:3011 360:4294967295:3011 361:4294967295:3011 362:4294967295:3011 363:4294967295:3011 364:4294967295:3011 365:4294967295:3011 366:4294967295:3011 367:4294967295:3011 368:4294967295:3011 369:4294967295:3011 370:4294967295:3011 371:4294967295:3011 372:4294967295:3011 373:4294967295:3011 374:4294967295:3011 375:4294967295:3011 376:4294967295:3011 377:4294967295:3011 378:4294967295:3011 379:4294967295:3011 380:4294967295:3011 381:4294967295:3011 382:4294967295:3011 383:4294967295:3011 384:4294967295:3011 385:4294967295:3011 386:4294967295:3011 387:4294967295:3011 388:4294967295:3011 389:4294967295:3011 390:4294967295:3011 391:4294967295:3011 392:4294967295:3011 393:4294967295:3011 394:4294967295:3011 395:4294967295:3011 396:4294967295:3011 397:4294967295:3011 398:4294967295:3011 399:4294967295:3011 400:4294967295:3011 401:4294967295:3011 402:4294967295:3011 403:4294967295:3011 404:4294967295:3011 405:4294967295:3011 406:4294967295:3011 407:4294967295:3011 408:4294967295:3011 409:4294967295:3011 410:4294967295:3011 411:4294967295:3011 412:4294967295:3011 413:4294967295:3011 414:4294967295:3011 415:4294967295:3011 416:4294967295:3011 417:4294967295:3011 418:4294967295:3011 419:4294967295:3011 420:4294967295:3011 421:4294967295:3011 422:4294967295:3011 423:4294967295:3011 424:4294967295:3011 425:4294967295:3011 426:4294967295:3011 427:4294967295:3011 428:4294967295:3011 429:4294967295:3011 430:4294967295:3011 431:4294967295:3011 432:4294967295:3011 433:4294967295:3011 434:4294967295:3011 435:4294967295:3011 436:4294967295:3011 437:4294967295:3011 438:4294967295:3011 439:4294967295:3011 440:4294967295:3011 441:4294967295:3011 442:4294967295:3011 443:4294967295:3011 444:4294967295:3011 445:4294967295:3011 446:4294967295:3011 447:4294967295:3011 448:4294967295:3011 449:4294967295:3011 450:4294967295:3011 451:4294967295:3011 452:4294967295:3011 453:4294967295:3011 454:4294967295:3011 455:4294967295:3011 456:4294967295:3011 457:4294967295:3011 458:4294967295:3011 459:4294967295:3011 460:4294967295:3011 461:4294967295:3011 462:4294967295:3011 463:4294967295:3011 464:4294967295:3011 465:4294967295:3011 466:4294967295:3011 467:4294967295:3011 468:4294967295:3011 469:4294967295:3011 470:4294967295:3011 471:4294967295:3011 472:4294967295:3011 473:4294967295:3011 474:4294967295:3011 475:4294967295:3011 476:4294967295:3011 477:4294967295:3011 478:4294967295:3011 479:4294967295:3011 480:4294967295:3011 481:4294967295:3011 482:4294967295:3011 483:4294967295:3011 484:4294967295:3011 485:4294967295:3011 486:4294967295:3011 487:4294967295:3011 488:4294967295:3011 489:4294967295:3011 490:4294967295:3011 491:4294967295:3011 492:4294967295:3011 493:4294967295:3011 494:4294967295:3011 495:4294967295:3011 496:4294967295:3011 497:4294967295:3011 498:4294967295:3011 499:4294967295:3011 500:4294967295:3011 501:4294967295:3011 502:4294967295:3011 503:4294967295:3011 504:4294967295:3011 505:4294967295:3011 506:4294967295:3011 507:4294967295:3011 508:4294967295:3011 509:4294967295:3011 510:4294967295:3011 511:4294967295:3011 /* Allow RCS service to aquire net_raw permission */ 18:4294967295:1001:3004 /* Allow QMID service to aquire net_raw permission */ 3:4294967295:1001:3004 2:4294967295:1001:3004 42:4294967295:1001:3004 18:4294967295:1001:3004 9:4294967295:1001:3004 1:4294967295:1001:3004:1000 4:4294967295:1001:3004 2797:4294967295:1001:3004 2808:4294967295:1001:3004:1000 /* DPM */ 47:4294967295:1001:3004 /* Allow communication to some QMI services with radio privilages */ /* Format is :: */ /* PBM */ 12:4294967295:1001 /* WMS */ 5:4294967295:1001 /* IMS VT */ 32:4294967295:1001 /* IMSP */ 31:4294967295:1001 /* PDC */ 36:4294967295:1001 /* SAR */ 17:4294967295:1001 /* RFRPE */ 41:4294967295:1001 /*UIM*/ 11:4294967295:1001 /*CAT*/ 10:4294967295:1001 /*IMSA*/ 33:4294967295:1001 /* CSVT */ 29:4294967295:1001 /* Allow Data dpmd to access QMI DFS */ 48:4294967295:1000:3004 /* DIAG */ 4097:4294967295:3009 ================================================ FILE: configs/sensors/hals.conf ================================================ sensors.ssc.wrapper.so ================================================ FILE: data-ipa-cfg-mgr/Android.mk ================================================ # # Copyright (C) 2015 The CyanogenMod Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. LOCAL_PATH := $(call my-dir) include $(call first-makefiles-under,$(LOCAL_PATH)) ================================================ FILE: data-ipa-cfg-mgr/Makefile.am ================================================ ACLOCAL_AMFLAGS = -I m4 AUTOMAKE_OPTIONS = foreign SUBDIRS = ipanat/src ipacm/src/ ================================================ FILE: data-ipa-cfg-mgr/configure.ac ================================================ # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ([2.65]) AC_INIT(data-ipa, 1.0.0) AM_INIT_AUTOMAKE(data-ipa, 1.0.0) AC_OUTPUT(Makefile ipanat/src/Makefile ipacm/src/Makefile) AC_CONFIG_SRCDIR([ipanat/src/ipa_nat_drv.c]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) # Checks for programs. AC_PROG_CC AC_PROG_LIBTOOL AC_PROG_CXX PKG_CHECK_MODULES([LIBXML], [libxml-2.0]) AC_SUBST([LIBXML_CFLAGS]) AC_SUBST([LIBXML_LIBS]) # Checks for libraries. AC_ARG_WITH(sanitized-headers, AS_HELP_STRING([--with-sanitized-headers=DIR], [Specify the location of the sanitized Linux headers]), [CPPFLAGS="$CPPFLAGS -idirafter $withval"]) AC_ARG_WITH([glib], AC_HELP_STRING([--with-glib], [enable glib, building HLOS systems which use glib])) if (test "x${with_glib}" = "xyes"); then AC_DEFINE(ENABLE_USEGLIB, 1, [Define if HLOS systems uses glib]) PKG_CHECK_MODULES(GTHREAD, gthread-2.0 >= 2.16, dummy=yes, AC_MSG_ERROR(GThread >= 2.16 is required)) PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16, dummy=yes, AC_MSG_ERROR(GLib >= 2.16 is required)) GLIB_CFLAGS="$GLIB_CFLAGS $GTHREAD_CFLAGS" GLIB_LIBS="$GLIB_LIBS $GTHREAD_LIBS" AC_SUBST(GLIB_CFLAGS) AC_SUBST(GLIB_LIBS) fi AM_CONDITIONAL(USE_GLIB, test "x${with_glib}" = "xyes") # Checks for header files. AC_CHECK_HEADERS([fcntl.h netinet/in.h sys/ioctl.h unistd.h]) # Checks for typedefs, structures, and compiler characteristics. AC_TYPE_OFF_T # Checks for library functions. AC_FUNC_MALLOC AC_FUNC_MMAP AC_CHECK_FUNCS([memset munmap]) AC_OUTPUT ================================================ FILE: data-ipa-cfg-mgr/ipacm/inc/IPACM_CmdQueue.h ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPACM_CmdQueue.h @brief This file implements the IPAM Comment Queue definitions @Author */ #ifndef IPA_CONNTRACK_MESSAGE_H #define IPA_CONNTRACK_MESSAGE_H #include #include "IPACM_Defs.h" /*--------------------------------------------------------------------------- Event data required by IPA_CM ---------------------------------------------------------------------------*/ typedef struct _ipacm_cmd_q_data { ipa_cm_event_id event; void *evt_data; }ipacm_cmd_q_data; typedef struct cmd_s { void (*callback_ptr)(ipacm_cmd_q_data *); ipacm_cmd_q_data data; }cmd_t; class Message { private: Message *m_next; public: cmd_t evt; Message() { m_next = NULL; evt.callback_ptr = NULL; } ~Message() { } void setnext(Message *item) { m_next = item; } Message* getnext() { return m_next; } }; class MessageQueue { private: Message *Head; Message *Tail; Message* dequeue(void); static MessageQueue *inst; MessageQueue() { Head = NULL; Tail = NULL; } public: ~MessageQueue() { } void enqueue(Message *item); static void* Process(void *); static MessageQueue* getInstance(); }; #endif /* IPA_CONNTRACK_MESSAGE_H */ ================================================ FILE: data-ipa-cfg-mgr/ipacm/inc/IPACM_Config.h ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPACM_Config.h @brief This file implements the IPACM Configuration from XML file @Author Skylar Chang */ #ifndef IPACM_CONFIG_H #define IPACM_CONFIG_H #include "IPACM_Defs.h" #include "IPACM_Xml.h" #include "IPACM_EvtDispatcher.h" typedef struct { char iface_name[IPA_IFACE_NAME_LEN]; }NatIfaces; /* for IPACM rm dependency use*/ typedef struct _ipa_rm_client { ipa_rm_resource_name producer_rm1; ipa_rm_resource_name consumer_rm1; ipa_rm_resource_name producer_rm2; ipa_rm_resource_name consumer_rm2; bool producer1_up; /* only monitor producer_rm1, not monitor producer_rm2 */ bool consumer1_up; /* only monitor consumer_rm1, not monitor consumer_rm2 */ bool rm_set; /* once producer1_up and consumer1_up, will add bi-directional dependency */ bool rx_bypass_ipa; /* support WLAN may not register RX-property, should not add dependency */ }ipa_rm_client; #define MAX_NUM_EXT_PROPS 15 /* used to hold extended properties */ typedef struct { uint8_t num_ext_props; ipa_ioc_ext_intf_prop prop[MAX_NUM_EXT_PROPS]; } ipacm_ext_prop; /* iface */ class IPACM_Config { public: /* IPACM ipa_client map to rm_resource*/ ipa_rm_resource_name ipa_client_rm_map_tbl[IPA_CLIENT_MAX]; /* IPACM monitored rm_depency table */ ipa_rm_client ipa_rm_tbl[IPA_MAX_RM_ENTRY]; /* IPACM rm_depency a2 endpoint check*/ int ipa_rm_a2_check; /* Store interested interface and their configuration from XML file */ ipa_ifi_dev_name_t *iface_table; /* Store interested ALG port from XML file */ ipacm_alg *alg_table; /* Store private subnet configuration from XML file */ ipa_private_subnet private_subnet_table[IPA_MAX_PRIVATE_SUBNET_ENTRIES]; /* Store the non nat iface names */ NatIfaces *pNatIfaces; /* Store the bridge iface names */ char ipa_virtual_iface_name[IPA_IFACE_NAME_LEN]; /* Store the number of interface IPACM read from XML file */ int ipa_num_ipa_interfaces; int ipa_num_private_subnet; int ipa_num_alg_ports; int ipa_nat_max_entries; bool ipacm_odu_router_mode; bool ipacm_odu_enable; int ipa_nat_iface_entries; /* Store SW-enable or not */ bool ipa_sw_rt_enable; /* IPACM routing table name for v4/v6 */ struct ipa_ioc_get_rt_tbl rt_tbl_lan_v4, rt_tbl_wan_v4, rt_tbl_default_v4, rt_tbl_v6, rt_tbl_wan_v6; struct ipa_ioc_get_rt_tbl rt_tbl_wan_dl; struct ipa_ioc_get_rt_tbl rt_tbl_lan2lan_v4, rt_tbl_lan2lan_v6; struct ipa_ioc_get_rt_tbl rt_tbl_odu_v4, rt_tbl_odu_v6; struct ipa_ioc_get_rt_tbl rt_tbl_eth_bridge_usb_wlan_v4, rt_tbl_eth_bridge_wlan_wlan_v4; struct ipa_ioc_get_rt_tbl rt_tbl_eth_bridge_usb_wlan_v6, rt_tbl_eth_bridge_wlan_wlan_v6; /* To return the instance */ static IPACM_Config* GetInstance(); inline int GetAlgPortCnt() { return ipa_num_alg_ports; } int GetAlgPorts(int nPorts, ipacm_alg *pAlgPorts); inline int GetNatMaxEntries(void) { return ipa_nat_max_entries; } inline int GetNatIfacesCnt() { return ipa_nat_iface_entries; } int GetNatIfaces(int nPorts, NatIfaces *ifaces); /* for IPACM resource manager dependency usage */ void AddRmDepend(ipa_rm_resource_name rm1,bool rx_bypass_ipa); void DelRmDepend(ipa_rm_resource_name rm1); int AddNatIfaces(char *dev_name); int DelNatIfaces(char *dev_name); inline void SetQmapId(uint8_t id) { qmap_id = id; } inline uint8_t GetQmapId() { return qmap_id; } int SetExtProp(ipa_ioc_query_intf_ext_props *prop); ipacm_ext_prop* GetExtProp(ipa_ip_type ip_type); int DelExtProp(ipa_ip_type ip_type); int Init(void); inline bool isPrivateSubnet(uint32_t ip_addr) { for(int cnt=0; cnt> 8) << 8; ipa_num_private_subnet++; /* IPACM private subnet set changes */ data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid)); if(data_fid == NULL) { IPACMERR("unable to allocate memory for event data_fid\n"); return IPACM_FAILURE; } data_fid->if_index = ipa_if_index; // already ipa index, not fid index evt_data.event = IPA_PRIVATE_SUBNET_CHANGE_EVENT; evt_data.evt_data = data_fid; /* Insert IPA_PRIVATE_SUBNET_CHANGE_EVENT to command queue */ IPACM_EvtDispatcher::PostEvt(&evt_data); return true; } IPACMERR("IPACM private subnet_addr overflow, total entry(%d)\n", ipa_num_private_subnet); return false; } inline bool DelPrivateSubnet(uint32_t ip_addr, int ipa_if_index) { ipacm_cmd_q_data evt_data; ipacm_event_data_fid *data_fid; for(int cnt=0; cntif_index = ipa_if_index; // already ipa index, not fid index evt_data.event = IPA_PRIVATE_SUBNET_CHANGE_EVENT; evt_data.evt_data = data_fid; /* Insert IPA_PRIVATE_SUBNET_CHANGE_EVENT to command queue */ IPACM_EvtDispatcher::PostEvt(&evt_data); return true; } } IPACMDBG("can't find private subnet_addr as: 0x%x \n", ip_addr); return false; } #endif /* defined(FEATURE_IPA_ANDROID)*/ static const char *DEVICE_NAME_ODU; private: static IPACM_Config *pInstance; static const char *DEVICE_NAME; IPACM_Config(void); int m_fd; /* File descriptor of the IPA device node /dev/ipa */ uint8_t qmap_id; ipacm_ext_prop ext_prop_v4; ipacm_ext_prop ext_prop_v6; }; #endif /* IPACM_CONFIG */ ================================================ FILE: data-ipa-cfg-mgr/ipacm/inc/IPACM_ConntrackClient.h ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef IPACM_CONNTRACK_FILTER_H #define IPACM_CONNTRACK_FILTER_H #include #include #include #include #include #include #include "IPACM_ConntrackClient.h" #include "IPACM_CmdQueue.h" #include "IPACM_Conntrack_NATApp.h" #include "IPACM_EvtDispatcher.h" #include "IPACM_Defs.h" #ifndef IPACM_DEBUG #define IPACM_DEBUG #endif extern "C" { #include #include #include } using namespace std; #define UDP_TIMEOUT_UPDATE 20 #define BROADCAST_IPV4_ADDR 0xFFFFFFFF #define IPACM_TCP_UDP_DIR_NAME "/proc/sys/net/ipv4/netfilter" #define IPACM_TCP_FILE_NAME "ip_conntrack_tcp_timeout_established" #define IPACM_UDP_FILE_NAME "ip_conntrack_udp_timeout_stream" #define IPACM_TCP_FULL_FILE_NAME "/proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_timeout_established" #define IPACM_UDP_FULL_FILE_NAME "/proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout_stream" #define INOTIFY_EVT_SIZE (sizeof(struct inotify_event)) #define INOTIFY_BUFFER_LEN (INOTIFY_EVT_SIZE + 2*sizeof(IPACM_TCP_FILE_NAME)) class IPACM_ConntrackClient { private: static IPACM_ConntrackClient *pInstance; struct nfct_handle *tcp_hdl; struct nfct_handle *udp_hdl; struct nfct_filter *tcp_filter; struct nfct_filter *udp_filter; static int IPA_Conntrack_Filters_Ignore_Local_Addrs(struct nfct_filter *filter); static int IPA_Conntrack_Filters_Ignore_Bridge_Addrs(struct nfct_filter *filter); static int IPA_Conntrack_Filters_Ignore_Local_Iface(struct nfct_filter *, ipacm_event_iface_up *); IPACM_ConntrackClient(); public: static int IPAConntrackEventCB(enum nf_conntrack_msg_type type, struct nf_conntrack *ct, void *data); static int IPA_Conntrack_UDP_Filter_Init(void); static int IPA_Conntrack_TCP_Filter_Init(void); static void* TCPRegisterWithConnTrack(void *); static void* UDPRegisterWithConnTrack(void *); static void* UDPConnTimeoutUpdate(void *); static void* TCPUDP_Timeout_monitor(void *); static void UpdateUDPFilters(void *, bool); static void UpdateTCPFilters(void *, bool); static void Read_TcpUdp_Timeout(char *in, int len); static IPACM_ConntrackClient* GetInstance(); #ifdef IPACM_DEBUG #define iptodot(X,Y) \ IPACMLOG(" %s(0x%x): %d.%d.%d.%d\n", X, Y, ((Y>>24) & 0xFF), ((Y>>16) & 0xFF), ((Y>>8) & 0xFF), (Y & 0xFF)); #endif }; #endif /* IPACM_CONNTRACK_FILTER_H */ ================================================ FILE: data-ipa-cfg-mgr/ipacm/inc/IPACM_ConntrackListener.h ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef IPACM_CONNTRACK_LISTENER #define IPACM_CONNTRACK_LISTENER #include #include #include #include #include #include #include #include "IPACM_CmdQueue.h" #include "IPACM_Conntrack_NATApp.h" #include "IPACM_Listener.h" #ifdef CT_OPT #include "IPACM_LanToLan.h" #endif #define MAX_NAT_IFACES 50 #define MAX_STA_CLNT_IFACES 10 using namespace std; class IPACM_ConntrackListener : public IPACM_Listener { private: bool isCTReg; bool isNatThreadStart; bool WanUp; NatApp *nat_inst; int NatIfaceCnt; int StaClntCnt; NatIfaces *pNatIfaces; uint32_t nat_iface_ipv4_addr[MAX_NAT_IFACES]; uint32_t nonnat_iface_ipv4_addr[MAX_NAT_IFACES]; uint32_t sta_clnt_ipv4_addr[MAX_STA_CLNT_IFACES]; IPACM_Config *pConfig; #ifdef CT_OPT IPACM_LanToLan *p_lan2lan; #endif void ProcessCTMessage(void *); void ProcessTCPorUDPMsg(struct nf_conntrack *, enum nf_conntrack_msg_type, u_int8_t); void TriggerWANUp(void *); void TriggerWANDown(uint32_t); int CreateNatThreads(void); int CreateConnTrackThreads(void); #ifdef CT_OPT void ProcessCTV6Message(void *); #endif public: char wan_ifname[IPA_IFACE_NAME_LEN]; uint32_t wan_ipaddr; bool isStaMode; IPACM_ConntrackListener(); void event_callback(ipa_cm_event_id, void *data); inline bool isWanUp() { return WanUp; } void HandleNeighIpAddrAddEvt(ipacm_event_data_all *); void HandleNeighIpAddrDelEvt(uint32_t); void HandleSTAClientAddEvt(uint32_t); void HandleSTAClientDelEvt(uint32_t); }; extern IPACM_ConntrackListener *CtList; #endif /* IPACM_CONNTRACK_LISTENER */ ================================================ FILE: data-ipa-cfg-mgr/ipacm/inc/IPACM_Conntrack_NATApp.h ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef IPACM_CONNTRACK_NATAPP_H #define IPACM_CONNTRACK_NATAPP_H #include /* for stderror */ #include #include /* for perror */ #include "IPACM_Config.h" #include "IPACM_Xml.h" extern "C" { #include #include } #define MAX_TEMP_ENTRIES 25 typedef struct _nat_table_entry { uint32_t private_ip; uint16_t private_port; uint32_t target_ip; uint16_t target_port; uint16_t public_ip; uint16_t public_port; u_int8_t protocol; uint32_t timestamp; bool dst_nat; bool enabled; uint32_t rule_hdl; }nat_table_entry; #define CHK_TBL_HDL() if(nat_table_hdl == 0){ return -1; } class NatApp { private: static NatApp *pInstance; nat_table_entry *cache; nat_table_entry temp[MAX_TEMP_ENTRIES]; uint32_t pub_ip_addr; uint32_t pub_ip_addr_pre; uint32_t nat_table_hdl; int curCnt, max_entries; ipacm_alg *pALGPorts; uint16_t nALGPort; uint32_t tcp_timeout; uint32_t udp_timeout; uint32_t PwrSaveIfs[IPA_MAX_NUM_WIFI_CLIENTS]; struct nf_conntrack *ct; struct nfct_handle *ct_hdl; NatApp(); int Init(); void UpdateCTUdpTs(nat_table_entry *, uint32_t); bool ChkForDup(const nat_table_entry *); bool isAlgPort(uint8_t, uint16_t); void Reset(); bool isPwrSaveIf(uint32_t); public: static NatApp* GetInstance(); int AddTable(uint32_t); uint32_t GetTableHdl(uint32_t); int DeleteTable(uint32_t); int AddEntry(const nat_table_entry *); int DeleteEntry(const nat_table_entry *); void UpdateUDPTimeStamp(); int UpdatePwrSaveIf(uint32_t); int ResetPwrSaveIf(uint32_t); int DelEntriesOnClntDiscon(uint32_t); int DelEntriesOnSTAClntDiscon(uint32_t); void UpdateTcpUdpTo(uint32_t, int proto); void AddTempEntry(const nat_table_entry *); void CacheEntry(const nat_table_entry *); void DeleteTempEntry(const nat_table_entry *); void FlushTempEntries(uint32_t, bool); }; #endif /* IPACM_CONNTRACK_NATAPP_H */ ================================================ FILE: data-ipa-cfg-mgr/ipacm/inc/IPACM_Defs.h ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPACM_Defs.h @brief This file implements the common definitions amon all ifaces. @Author Skylar Chang */ #ifndef IPA_CM_DEFS_H #define IPA_CM_DEFS_H #include #include #include #include "IPACM_Log.h" extern "C" { #include #include } #define IF_NAME_LEN 16 #define IPA_MAX_FILE_LEN 64 #define IPA_IFACE_NAME_LEN 16 #define IPA_ALG_PROTOCOL_NAME_LEN 10 #define IPA_WLAN_PARTIAL_HDR_OFFSET 0 // dst mac first then src mac //#define IPA_ETH_PARTIAL_HDR_OFFSET 8 // dst mac first then src mac #define IPA_ODU_PARTIAL_HDR_OFFSET 8 // dst mac first then src mac #define IPA_WLAN_PARTIAL_HDR_NAME_v4 "IEEE802_3_v4" #define IPA_WLAN_PARTIAL_HDR_NAME_v6 "IEEE802_3_v6" #define IPA_WAN_PARTIAL_HDR_NAME_v4 "IEEE802_3_STA_v4" #define IPA_WAN_PARTIAL_HDR_NAME_v6 "IEEE802_3_STA_v6" #define IPA_ETH_HDR_NAME_v4 "IPACM_ETH_v4" #define IPA_ETH_HDR_NAME_v6 "IPACM_ETH_v6" #define IPA_ODU_HDR_NAME_v4 "IPACM_ODU_v4" #define IPA_ODU_HDR_NAME_v6 "IPACM_ODU_v6" #define IPA_MAX_IFACE_ENTRIES 15 #define IPA_MAX_PRIVATE_SUBNET_ENTRIES 3 #define IPA_MAX_ALG_ENTRIES 20 #define IPA_MAX_RM_ENTRY 6 #define V4_DEFAULT_ROUTE_TABLE_NAME "ipa_dflt_rt" #define V4_LAN_ROUTE_TABLE_NAME "COMRTBLLANv4" #define V4_WAN_ROUTE_TABLE_NAME "WANRTBLv4" #define WAN_DL_ROUTE_TABLE_NAME "ipa_dflt_wan_rt" #define V6_COMMON_ROUTE_TABLE_NAME "COMRTBLv6" #define V6_WAN_ROUTE_TABLE_NAME "WANRTBLv6" #define V4_LAN_TO_LAN_ROUTE_TABLE_NAME "LANTOLANRTBLv4" #define V6_LAN_TO_LAN_ROUTE_TABLE_NAME "LANTOLANRTBLv6" #define V4_ODU_ROUTE_TABLE_NAME "ODURTBLv4" #define V6_ODU_ROUTE_TABLE_NAME "ODURTBLv6" #define ETH_BRIDGE_USB_WLAN_ROUTE_TABLE_NAME_V4 "ETH_BRIDGE_USB_WLAN_RTBLv4" #define ETH_BRIDGE_WLAN_WLAN_ROUTE_TABLE_NAME_V4 "ETH_BRIDGE_WLAN_WLAN_RTBLv4" #define ETH_BRIDGE_USB_WLAN_ROUTE_TABLE_NAME_V6 "ETH_BRIDGE_USB_WLAN_RTBLv6" #define ETH_BRIDGE_WLAN_WLAN_ROUTE_TABLE_NAME_V6 "ETH_BRIDGE_WLAN_WLAN_RTBLv6" #define WWAN_QMI_IOCTL_DEVICE_NAME "/dev/wwan_ioctl" #define IPA_DEVICE_NAME "/dev/ipa" #define IPA_MAX_FLT_RULE 50 #define MAX_OFFLOAD_PAIR 3 #define MAX_NUM_PROP 8 #define IPA_LAN_TO_LAN_USB_HDR_NAME_V4 "Lan2Lan_USB_v4" #define IPA_LAN_TO_LAN_USB_HDR_NAME_V6 "Lan2Lan_USB_v6" #define IPA_LAN_TO_LAN_WLAN_HDR_NAME_V4 "Lan2Lan_Wlan_v4" #define IPA_LAN_TO_LAN_WLAN_HDR_NAME_V6 "Lan2Lan_Wlan_v6" #define IPA_LAN_TO_LAN_MAX_WLAN_CLIENT 32 #define IPA_LAN_TO_LAN_MAX_USB_CLIENT 1 #define TCP_FIN_SHIFT 16 #define TCP_SYN_SHIFT 17 #define TCP_RST_SHIFT 18 #define NUM_TCP_CTL_FLT_RULE 3 /*--------------------------------------------------------------------------- Return values indicating error status ---------------------------------------------------------------------------*/ #define IPACM_SUCCESS 0 /* Successful operation */ #define IPACM_FAILURE -1 /* Unsuccessful operation */ #define IPACM_IP_NULL (ipa_ip_type)0xFF #define IPACM_INVALID_INDEX (ipa_ip_type)0xFF #define IPA_MAX_NUM_WIFI_CLIENTS 32 #define IPA_MAX_NUM_WAN_CLIENTS 10 #define IPA_MAX_NUM_ETH_CLIENTS 15 #define IPA_MAX_NUM_AMPDU_RULE 15 #define IPA_MAC_ADDR_SIZE 6 /*=========================================================================== GLOBAL DEFINITIONS AND DECLARATIONS ===========================================================================*/ typedef enum { IPA_CFG_CHANGE_EVENT = 1, /* 1 NULL */ IPA_LINK_UP_EVENT, /* 2 ipacm_event_data_fid */ IPA_LINK_DOWN_EVENT, /* 3 ipacm_event_data_fid */ IPA_ADDR_ADD_EVENT, /* 4 ipacm_event_data_addr */ IPA_ADDR_DEL_EVENT, /* 5 no use */ IPA_ROUTE_ADD_EVENT, /* 6 ipacm_event_data_addr */ IPA_ROUTE_DEL_EVENT, /* 7 ipacm_event_data_addr */ IPA_FIREWALL_CHANGE_EVENT, /* 8 NULL */ IPA_WLAN_AP_LINK_UP_EVENT, /* 9 ipacm_event_data_mac */ IPA_WLAN_STA_LINK_UP_EVENT, /* 10 ipacm_event_data_mac */ IPA_WLAN_CLIENT_ADD_EVENT, /* 11 ipacm_event_data_mac */ IPA_WLAN_CLIENT_DEL_EVENT, /* 12 ipacm_event_data_mac */ IPA_WLAN_CLIENT_POWER_SAVE_EVENT, /* 13 ipacm_event_data_mac */ IPA_WLAN_CLIENT_RECOVER_EVENT, /* 14 ipacm_event_data_mac */ IPA_NEW_NEIGH_EVENT, /* 15 ipacm_event_data_all */ IPA_DEL_NEIGH_EVENT, /* 16 ipacm_event_data_all */ IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, /* 17 ipacm_event_data_all */ IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT, /* 18 ipacm_event_data_all */ IPA_SW_ROUTING_ENABLE, /* 19 NULL */ IPA_SW_ROUTING_DISABLE, /* 20 NULL */ IPA_PROCESS_CT_MESSAGE, /* 21 ipacm_ct_evt_data */ IPA_HANDLE_WAN_UP, /* 22 ipacm_event_iface_up */ IPA_HANDLE_WAN_DOWN, /* 23 ipacm_event_iface_up */ IPA_HANDLE_WLAN_UP, /* 24 ipacm_event_iface_up */ IPA_HANDLE_LAN_UP, /* 25 ipacm_event_iface_up */ IPA_WLAN_CLIENT_ADD_EVENT_EX, /* 26 ipacm_event_data_wlan_ex */ IPA_HANDLE_WAN_UP_V6, /* 27 NULL */ IPA_HANDLE_WAN_DOWN_V6, /* 28 NULL */ IPA_LAN_CLIENT_ACTIVE, /* 29 ipacm_event_lan_client*/ IPA_LAN_CLIENT_INACTIVE, /* 30 ipacm_event_lan_client*/ IPA_LAN_CLIENT_DISCONNECT, /* 31 ipacm_event_lan_client*/ IPA_LAN_CLIENT_POWER_SAVE, /* 32 ipacm_event_lan_client*/ IPA_LAN_CLIENT_POWER_RECOVER, /* 33 ipacm_event_lan_client*/ IPA_LAN_TO_LAN_NEW_CONNECTION, /* 34 ipacm_event_connection */ IPA_LAN_TO_LAN_DEL_CONNECTION, /* 35 ipacm_event_connection */ IPA_LAN_DELETE_SELF, /* 36 ipacm_event_data_fid */ IPA_WLAN_LINK_DOWN_EVENT, /* 37 ipacm_event_data_mac */ IPA_USB_LINK_UP_EVENT, /* 38 ipacm_event_data_fid */ IPA_PROCESS_CT_MESSAGE_V6, /* 39 ipacm_ct_evt_data */ IPA_PRIVATE_SUBNET_CHANGE_EVENT, /* 40 ipacm_event_data_fid */ IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT, /* 41 ipacm_event_data_fid */ IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT, /* 42 ipacm_event_data_fid */ IPA_WAN_EMBMS_LINK_UP_EVENT, /* 43 ipacm_event_data_mac */ IPA_ETH_BRIDGE_USB_CLIENT_ADD_EVENT, /* 44 ipacm_event_data_mac */ IPA_ETH_BRIDGE_WLAN_CLIENT_ADD_EVENT, /* 45 ipacm_event_data_mac */ IPA_ETH_BRIDGE_USB_CLIENT_DEL_EVENT, /* 46 ipacm_event_data_mac */ IPA_ETH_BRIDGE_WLAN_CLIENT_DEL_EVENT, /* 47 ipacm_event_data_mac */ IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT, /* 48 ipacm_event_data_if_cat */ IPA_ETH_BRIDGE_HDR_PROC_CTX_UNSET_EVENT, /* 49 ipacm_event_data_if_cat */ IPA_WLAN_SWITCH_TO_SCC, /* 50 No Data */ IPA_WLAN_SWITCH_TO_MCC, /* 51 No Data */ IPA_CRADLE_WAN_MODE_SWITCH, /* 52 ipacm_event_cradle_wan_mode */ IPA_WAN_XLAT_CONNECT_EVENT, /* 53 ipacm_event_data_fid */ IPA_TETHERING_STATS_UPDATE_EVENT, /* 54 ipacm_event_data_fid */ IPA_NETWORK_STATS_UPDATE_EVENT, /* 55 ipacm_event_data_fid */ IPA_HANDLE_WAN_UP_TETHER, /* 56 ipacm_event_iface_up_tehter */ IPA_HANDLE_WAN_DOWN_TETHER, /* 57 ipacm_event_iface_up_tehter */ IPA_HANDLE_WAN_UP_V6_TETHER, /* 58 ipacm_event_iface_up_tehter */ IPA_HANDLE_WAN_DOWN_V6_TETHER, /* 59 ipacm_event_iface_up_tehter */ IPACM_EVENT_MAX } ipa_cm_event_id; typedef struct { uint8_t num_rule; uint32_t rule_hdl[MAX_NUM_PROP]; } lan_to_lan_rt_rule_hdl; typedef enum { LAN_IF = 0, WLAN_IF, WAN_IF, VIRTUAL_IF, ETH_IF, EMBMS_IF, ODU_IF, UNKNOWN_IF } ipacm_iface_type; typedef struct { struct nf_conntrack *ct; enum nf_conntrack_msg_type type; }ipacm_ct_evt_data; typedef struct { char iface_name[IPA_IFACE_NAME_LEN]; ipacm_iface_type if_cat; int netlink_interface_index; } ipa_ifi_dev_name_t; typedef struct { uint32_t subnet_addr; uint32_t subnet_mask; } ipa_private_subnet; typedef struct _ipacm_event_data_all { enum ipa_ip_type iptype; int if_index; uint32_t ipv4_addr; uint32_t ipv6_addr[4]; uint8_t mac_addr[IPA_MAC_ADDR_SIZE]; } ipacm_event_data_all; class IPACM_Lan; typedef struct { enum ipa_ip_type iptype; uint32_t ipv4_addr; uint32_t ipv6_addr[4]; uint8_t mac_addr[6]; IPACM_Lan* p_iface; } ipacm_event_lan_client; typedef struct { enum ipa_ip_type iptype; uint32_t src_ipv4_addr; uint32_t dst_ipv4_addr; uint32_t src_ipv6_addr[4]; uint32_t dst_ipv6_addr[4]; } ipacm_event_connection; typedef struct _ipacm_event_data_fid { int if_index; } ipacm_event_data_fid; typedef struct _ipacm_event_data_iptype { int if_index; int if_index_tether; enum ipa_ip_type iptype; } ipacm_event_data_iptype; typedef struct _ipacm_event_data_addr { enum ipa_ip_type iptype; int if_index; uint32_t ipv4_addr; uint32_t ipv4_addr_mask; uint32_t ipv6_addr[4]; uint32_t ipv6_addr_mask[4]; } ipacm_event_data_addr; typedef struct _ipacm_event_data_mac { int if_index; uint8_t mac_addr[IPA_MAC_ADDR_SIZE]; } ipacm_event_data_mac; typedef struct { int if_index; uint8_t num_of_attribs; struct ipa_wlan_hdr_attrib_val attribs[0]; } ipacm_event_data_wlan_ex; typedef struct _ipacm_event_iface_up { char ifname[IPA_IFACE_NAME_LEN]; uint32_t ipv4_addr; uint32_t addr_mask; uint32_t ipv6_prefix[2]; bool is_sta; }ipacm_event_iface_up; typedef struct _ipacm_event_iface_up_tether { uint32_t if_index_tether; uint32_t ipv6_prefix[2]; bool is_sta; }ipacm_event_iface_up_tehter; typedef enum { Q6_WAN = 0, WLAN_WAN, ECM_WAN } ipacm_wan_iface_type; typedef struct _ipacm_ifacemgr_data { int if_index; ipacm_wan_iface_type if_type; uint8_t mac_addr[IPA_MAC_ADDR_SIZE]; }ipacm_ifacemgr_data; #endif /* IPA_CM_DEFS_H */ ================================================ FILE: data-ipa-cfg-mgr/ipacm/inc/IPACM_EvtDispatcher.h ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPACM_EvtDispatcher.h @brief This file implements the IPAM event dispatcher definitions @Author */ #ifndef IPACM_EvtDispatcher_H #define IPACM_EvtDispatcher_H #include #include #include "IPACM_Defs.h" #include "IPACM_Listener.h" /* queue */ typedef struct _cmd_evts { ipa_cm_event_id event; IPACM_Listener *obj; //int ipa_interface_index; _cmd_evts *next; } cmd_evts; class IPACM_EvtDispatcher { public: /* api for all iface instances to register events */ static int registr(ipa_cm_event_id event, IPACM_Listener *obj); /* api for all iface instances to de-register events */ static int deregistr(IPACM_Listener *obj); static int PostEvt(ipacm_cmd_q_data *); static void ProcessEvt(ipacm_cmd_q_data *); private: static cmd_evts *head; }; #endif /* IPACM_EvtDispatcher_H */ ================================================ FILE: data-ipa-cfg-mgr/ipacm/inc/IPACM_Filtering.h ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPACM_Filtering.h @brief This file implements the IPACM filtering definitions @Author Skylar Chang */ #ifndef IPACM_FILTERING_H #define IPACM_FILTERING_H #include #include #include #include class IPACM_Filtering { public: IPACM_Filtering(); ~IPACM_Filtering(); bool AddFilteringRule(struct ipa_ioc_add_flt_rule const *ruleTable); bool DeleteFilteringRule(struct ipa_ioc_del_flt_rule *ruleTable); bool Commit(enum ipa_ip_type ip); bool Reset(enum ipa_ip_type ip); bool DeviceNodeIsOpened(); bool DeleteFilteringHdls(uint32_t *flt_rule_hdls, ipa_ip_type ip, uint8_t num_rules); bool AddWanDLFilteringRule(struct ipa_ioc_add_flt_rule const *rule_table_v4, struct ipa_ioc_add_flt_rule const * rule_table_v6, uint8_t mux_id); bool SendFilteringRuleIndex(struct ipa_fltr_installed_notif_req_msg_v01* table); bool ModifyFilteringRule(struct ipa_ioc_mdfy_flt_rule* ruleTable); ipa_filter_action_enum_v01 GetQmiFilterAction(ipa_flt_action action); private: static const char *DEVICE_NAME; int fd; /* File descriptor of the IPA device node /dev/ipa */ }; #endif //IPACM_FILTERING_H ================================================ FILE: data-ipa-cfg-mgr/ipacm/inc/IPACM_Header.h ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * IPACM_Header.h * * Created on: Jun 20, 2012 * Author: tatias */ ////////////////////////////////////////////////////////////////////////////////// #ifndef IPACM_HEADER_H #define IPACM_HEADER_H #include #include "linux/msm_ipa.h" ////////////////////////////////////////////////////////////////////////////////// class IPACM_Header { private: int m_fd; public: bool AddHeader(struct ipa_ioc_add_hdr *pHeaderTable); bool DeleteHeader(struct ipa_ioc_del_hdr *pHeaderTable); bool GetHeaderHandle(struct ipa_ioc_get_hdr *pHeaderStruct); bool CopyHeader(struct ipa_ioc_copy_hdr *pCopyHeaderStruct); bool Commit(); bool Reset(); bool DeleteHeaderHdl(uint32_t hdr_hdl); bool AddHeaderProcCtx(struct ipa_ioc_add_hdr_proc_ctx* pHeader); bool DeleteHeaderProcCtx(uint32_t hdl); IPACM_Header(); ~IPACM_Header(); bool DeviceNodeIsOpened(); }; #endif ================================================ FILE: data-ipa-cfg-mgr/ipacm/inc/IPACM_Iface.h ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPACM_iface.h @brief This file implements the basis Iface definitions. @Author Skylar Chang */ #ifndef IPACM_IFACE_H #define IPACM_IFACE_H #include #include #include #include "IPACM_Routing.h" #include "IPACM_Filtering.h" #include "IPACM_Header.h" #include "IPACM_EvtDispatcher.h" #include "IPACM_Xml.h" #include "IPACM_Log.h" #include "IPACM_Config.h" #include "IPACM_Defs.h" #include /* current support 2 ipv6-address*/ #define MAX_DEFAULT_v4_ROUTE_RULES 1 #define MAX_DEFAULT_v6_ROUTE_RULES 2 #define IPV4_DEFAULT_FILTERTING_RULES 3 #ifdef FEATURE_IPA_ANDROID #define IPV6_DEFAULT_FILTERTING_RULES 6 #else #define IPV6_DEFAULT_FILTERTING_RULES 3 #endif #define IPV6_DEFAULT_LAN_FILTERTING_RULES 1 #define IPV6_NUM_ADDR 3 #define MAX_SOFTWAREROUTING_FILTERTING_RULES 2 #define INVALID_IFACE -1 /* iface */ class IPACM_Iface :public IPACM_Listener { public: /* Static class for reading IPACM configuration from XML file*/ static IPACM_Config *ipacmcfg; /* IPACM interface id */ int ipa_if_num; /* IPACM interface category */ int ipa_if_cate; /* IPACM interface name */ char dev_name[IF_NAME_LEN]; /* IPACM interface iptype v4, v6 or both */ ipa_ip_type ip_type; /* IPACM interface v6 ip-address*/ uint32_t ipv6_addr[MAX_DEFAULT_v6_ROUTE_RULES][4]; uint32_t header_hdl; uint32_t software_routing_fl_rule_hdl[MAX_SOFTWAREROUTING_FILTERTING_RULES]; bool softwarerouting_act; /* IPACM number of default route rules for ipv6*/ int num_dft_rt_v6; uint32_t dft_v4fl_rule_hdl[IPV4_DEFAULT_FILTERTING_RULES]; uint32_t dft_v6fl_rule_hdl[IPV6_DEFAULT_FILTERTING_RULES + IPV6_DEFAULT_LAN_FILTERTING_RULES]; /* create additional set of v6 RT-rules in Wanv6RT table*/ uint32_t dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+2*MAX_DEFAULT_v6_ROUTE_RULES]; ipa_ioc_query_intf *iface_query; ipa_ioc_query_intf_tx_props *tx_prop; ipa_ioc_query_intf_rx_props *rx_prop; virtual int handle_down_evt() = 0; virtual int handle_addr_evt(ipacm_event_data_addr *data) = 0; IPACM_Iface(int iface_index); virtual void event_callback(ipa_cm_event_id event, void *data) = 0; /* Query ipa_interface_index by given linux interface_index */ static int iface_ipa_index_query(int interface_index); /* Query ipa_interface ipv4_addr by given linux interface_index */ static void iface_addr_query(int interface_index); /*Query the IPA endpoint property */ int query_iface_property(void); /*implement IPACM strlcpy */ size_t strlcpy(char *dest, const char *src, size_t size); /*implement IPACM strlcat */ size_t strlcat(char *dest, const char *src, size_t n); /*Configure the initial filter rules */ virtual int init_fl_rule(ipa_ip_type iptype); /* Get interface index */ virtual int ipa_get_if_index(char * if_name, int * if_index); static IPACM_Routing m_routing; static IPACM_Filtering m_filtering; static IPACM_Header m_header; /* software routing enable */ virtual int handle_software_routing_enable(void); /* software routing disable */ virtual int handle_software_routing_disable(void); /* used to get filtering rule index in table */ int flt_rule_count_v4; int flt_rule_count_v6; private: static const char *DEVICE_NAME; }; #endif /* IPACM_IFACE_H */ ================================================ FILE: data-ipa-cfg-mgr/ipacm/inc/IPACM_IfaceManager.h ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPACM_IfaceManager.h @brief This file implements the IPAM iface_manager definitions @Author Skylar Chang */ #ifndef IPACM_IFACEMANAGER_H #define IPACM_IFACEMANAGER_H #include #include #include "IPACM_Routing.h" #include "IPACM_Filtering.h" #include "IPACM_Listener.h" #include "IPACM_Iface.h" #define IPA_MAX_NUM_NEIGHBOR_CLIENTS 17 #define IPA_INSTANCE_NOT_FOUND 0 #define IPA_INSTANCE_FOUND 1 /* queue */ typedef struct _iface_instances { /* Linux interface id */ int ipa_if_index; IPACM_Listener *obj; _iface_instances *next; } iface_instances; class IPACM_IfaceManager : public IPACM_Listener { public: IPACM_IfaceManager(); void event_callback(ipa_cm_event_id event, void *data); /* api for all iface instances to de-register instances */ static int deregistr(IPACM_Listener *param); private: int create_iface_instance(ipacm_ifacemgr_data *); /* api to register instances */ int registr(int ipa_if_index, IPACM_Listener *obj); int SearchInstance(int ipa_if_index); static iface_instances *head; }; #endif /* IPACM_IFACEMANAGER_H */ ================================================ FILE: data-ipa-cfg-mgr/ipacm/inc/IPACM_Lan.h ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPACM_Lan.h @brief This file implements the LAN iface definitions @Author Skylar Chang */ #ifndef IPACM_LAN_H #define IPACM_LAN_H #include #include #include "IPACM_CmdQueue.h" #include "IPACM_Iface.h" #include "IPACM_Routing.h" #include "IPACM_Filtering.h" #include "IPACM_Config.h" #include "IPACM_Conntrack_NATApp.h" #define IPA_WAN_DEFAULT_FILTER_RULE_HANDLES 1 #define IPA_PRIV_SUBNET_FILTER_RULE_HANDLES 3 #define IPA_NUM_ODU_ROUTE_RULES 2 #define MAX_WAN_UL_FILTER_RULES 20 #define NUM_IPV6_PREFIX_FLT_RULE 1 #define NUM_IPV6_ICMP_FLT_RULE 1 /* echo ipatetherstats */ /* out_bytes> out_pkts> in_bytes> in_pkts */ #define PIPE_STATS "%s %s %lu %lu %lu %lu" #define IPA_PIPE_STATS_FILE_NAME "/data/misc/ipa/tether_stats" /* store each lan-iface unicast routing rule and its handler*/ struct ipa_lan_rt_rule { ipa_ip_type ip; uint32_t v4_addr; uint32_t v4_addr_mask; uint32_t v6_addr[4]; uint32_t rt_rule_hdl[0]; }; /* Support multiple eth client */ typedef struct _eth_client_rt_hdl { uint32_t eth_rt_rule_hdl_v4; uint32_t eth_rt_rule_hdl_v6[IPV6_NUM_ADDR]; uint32_t eth_rt_rule_hdl_v6_wan[IPV6_NUM_ADDR]; }eth_client_rt_hdl; typedef struct _ipa_eth_client { uint8_t mac[IPA_MAC_ADDR_SIZE]; uint32_t v4_addr; uint32_t v6_addr[IPV6_NUM_ADDR][4]; uint32_t hdr_hdl_v4; uint32_t hdr_hdl_v6; bool route_rule_set_v4; int route_rule_set_v6; bool ipv4_set; int ipv6_set; bool ipv4_header_set; bool ipv6_header_set; eth_client_rt_hdl eth_rt_hdl[0]; /* depends on number of tx properties */ }ipa_eth_client; struct lan2lan_flt_rule_hdl { uint32_t rule_hdl; bool valid; }; struct lan2lan_hdr_hdl { uint32_t hdr_hdl; bool valid; }; struct eth_bridge_client_flt_info { uint8_t mac[IPA_MAC_ADDR_SIZE]; uint32_t flt_rule_hdl_v4; bool flt_rule_set_v4; uint32_t flt_rule_hdl_v6; bool flt_rule_set_v6; }; struct eth_bridge_client_rt_info { uint8_t mac[IPA_MAC_ADDR_SIZE]; uint32_t rt_rule_hdl[0]; }; struct hdr_proc_ctx_info { uint32_t proc_ctx_hdl; bool valid; }; struct eth_bridge_subnet_client_info { uint8_t mac[IPA_MAC_ADDR_SIZE]; int ipa_if_num; }; /* lan iface */ class IPACM_Lan : public IPACM_Iface { public: IPACM_Lan(int iface_index); ~IPACM_Lan(); /* store lan's wan-up filter rule handlers */ uint32_t lan_wan_fl_rule_hdl[IPA_WAN_DEFAULT_FILTER_RULE_HANDLES]; /* store private-subnet filter rule handlers */ uint32_t private_fl_rule_hdl[IPA_MAX_PRIVATE_SUBNET_ENTRIES]; /* LAN-iface's callback function */ void event_callback(ipa_cm_event_id event, void *data); virtual int handle_wan_up(ipa_ip_type ip_type); /* configure filter rule for wan_up event*/ virtual int handle_wan_up_ex(ipacm_ext_prop* ext_prop, ipa_ip_type iptype); /* delete filter rule for wan_down event*/ virtual int handle_wan_down(bool is_sta_mode); /* delete filter rule for wan_down event*/ virtual int handle_wan_down_v6(bool is_sta_mode); /* configure private subnet filter rules*/ virtual int handle_private_subnet(ipa_ip_type iptype); /* handle new_address event*/ int handle_addr_evt(ipacm_event_data_addr *data); int handle_addr_evt_odu_bridge(ipacm_event_data_addr* data); static bool odu_up; /* install UL filter rule from Q6 */ virtual int handle_uplink_filter_rule(ipacm_ext_prop* prop, ipa_ip_type iptype); int add_lan2lan_flt_rule(ipa_ip_type iptype, uint32_t src_v4_addr, uint32_t dst_v4_addr, uint32_t* src_v6_addr, uint32_t* dst_v6_addr, uint32_t* rule_hdl); int del_lan2lan_flt_rule(ipa_ip_type iptype, uint32_t rule_hdl); virtual int add_lan2lan_hdr(ipa_ip_type iptype, uint8_t* src_mac, uint8_t* dst_mac, uint32_t* hdr_hdl); int add_lan2lan_rt_rule(ipa_ip_type iptype, uint32_t src_v4_addr, uint32_t dst_v4_addr, uint32_t* src_v6_addr, uint32_t* dst_v6_addr, uint32_t hdr_hdl, lan_to_lan_rt_rule_hdl* rule_hdl); int del_lan2lan_rt_rule(ipa_ip_type iptype, lan_to_lan_rt_rule_hdl); int del_lan2lan_hdr(ipa_ip_type iptype, uint32_t hdr_hdl); static ipa_hdr_l2_type usb_hdr_type; static ipa_hdr_l2_type wlan_hdr_type; static uint32_t usb_hdr_template_hdl; static uint32_t wlan_hdr_template_hdl; static hdr_proc_ctx_info usb_to_wlan_hdr_proc_ctx, wlan_to_usb_hdr_proc_ctx; static hdr_proc_ctx_info wlan_to_wlan_hdr_proc_ctx; static eth_bridge_subnet_client_info eth_bridge_wlan_client[IPA_LAN_TO_LAN_MAX_WLAN_CLIENT]; static eth_bridge_subnet_client_info eth_bridge_usb_client[IPA_LAN_TO_LAN_MAX_USB_CLIENT]; static int num_wlan_client; static int num_usb_client; protected: lan2lan_flt_rule_hdl wlan_client_flt_rule_hdl_v4[IPA_LAN_TO_LAN_MAX_WLAN_CLIENT]; lan2lan_flt_rule_hdl wlan_client_flt_rule_hdl_v6[IPA_LAN_TO_LAN_MAX_WLAN_CLIENT]; eth_bridge_client_flt_info eth_bridge_wlan_client_flt_info[IPA_LAN_TO_LAN_MAX_WLAN_CLIENT]; int wlan_client_flt_info_count; eth_bridge_client_rt_info* eth_bridge_usb_client_rt_info_v4; eth_bridge_client_rt_info* eth_bridge_usb_client_rt_info_v6; int usb_client_rt_info_count_v4; int usb_client_rt_info_count_v6; int client_rt_info_size_v4; int client_rt_info_size_v6; int each_client_rt_rule_count_v4; int each_client_rt_rule_count_v6; virtual int eth_bridge_handle_dummy_wlan_client_flt_rule(ipa_ip_type iptype); virtual int eth_bridge_add_wlan_guest_ap_flt_rule(ipa_ip_type iptype); virtual int eth_bridge_handle_dummy_usb_client_flt_rule(ipa_ip_type iptype); int eth_bridge_add_wlan_client_flt_rule(uint8_t* mac, ipa_ip_type iptype); int eth_bridge_del_wlan_client_flt_rule(uint8_t* mac); int eth_bridge_post_lan_client_event(uint8_t* mac_addr, ipa_cm_event_id evt); int add_hdr_proc_ctx(); int del_hdr_proc_ctx(); ipa_hdr_proc_type get_hdr_proc_type(ipa_hdr_l2_type t1, ipa_hdr_l2_type t2); virtual int eth_bridge_install_cache_wlan_client_flt_rule(ipa_ip_type iptype); virtual int eth_bridge_install_cache_usb_client_flt_rule(ipa_ip_type iptype); int eth_bridge_add_usb_client_rt_rule(uint8_t* mac, ipa_ip_type iptype); int eth_bridge_del_usb_client_rt_rule(uint8_t* mac); eth_bridge_client_rt_info* eth_bridge_get_client_rt_info_ptr(uint8_t index, ipa_ip_type iptype); void eth_bridge_add_usb_client(uint8_t* mac); void eth_bridge_del_usb_client(uint8_t* mac); int eth_bridge_get_hdr_template_hdl(uint32_t* hdr_hdl); virtual int add_dummy_lan2lan_flt_rule(ipa_ip_type iptype); virtual int add_dummy_private_subnet_flt_rule(ipa_ip_type iptype); int handle_private_subnet_android(ipa_ip_type iptype); int reset_to_dummy_flt_rule(ipa_ip_type iptype, uint32_t rule_hdl); /*handle lan2lan client active*/ int handle_lan2lan_client_active(ipacm_event_data_all *data, ipa_cm_event_id event); int install_ipv6_prefix_flt_rule(uint32_t* prefix); int install_ipv6_icmp_flt_rule(); void post_del_self_evt(); /* handle tethering stats */ int handle_tethering_stats_event(ipa_get_data_stats_resp_msg_v01 *data); /* handle tethering client */ int handle_tethering_client(bool reset, ipacm_client_enum ipa_client); lan2lan_flt_rule_hdl lan2lan_flt_rule_hdl_v4[MAX_OFFLOAD_PAIR]; lan2lan_flt_rule_hdl lan2lan_flt_rule_hdl_v6[MAX_OFFLOAD_PAIR]; uint8_t num_lan2lan_flt_rule_v4; uint8_t num_lan2lan_flt_rule_v6; lan2lan_hdr_hdl lan2lan_hdr_hdl_v4[MAX_OFFLOAD_PAIR]; lan2lan_hdr_hdl lan2lan_hdr_hdl_v6[MAX_OFFLOAD_PAIR]; /* store ipv4 UL filter rule handlers from Q6*/ uint32_t wan_ul_fl_rule_hdl_v4[MAX_WAN_UL_FILTER_RULES]; /* store ipv6 UL filter rule handlers from Q6*/ uint32_t wan_ul_fl_rule_hdl_v6[MAX_WAN_UL_FILTER_RULES]; virtual void install_tcp_ctl_flt_rule(ipa_ip_type iptype); uint32_t tcp_ctl_flt_rule_hdl_v4[NUM_TCP_CTL_FLT_RULE]; uint32_t tcp_ctl_flt_rule_hdl_v6[NUM_TCP_CTL_FLT_RULE]; uint32_t ipv6_prefix_flt_rule_hdl[NUM_IPV6_PREFIX_FLT_RULE]; uint32_t ipv6_icmp_flt_rule_hdl[NUM_IPV6_ICMP_FLT_RULE]; int num_wan_ul_fl_rule_v4; int num_wan_ul_fl_rule_v6; bool is_active; bool modem_ul_v4_set; bool modem_ul_v6_set; uint32_t if_ipv4_subnet; private: /* dynamically allocate lan iface's unicast routing rule structure */ bool is_mode_switch; /* indicate mode switch, need post internal up event */ int eth_client_len; ipa_eth_client *eth_client; int header_name_count; int num_eth_client; NatApp *Nat_App; int ipv6_set; uint32_t ODU_hdr_hdl_v4, ODU_hdr_hdl_v6; uint32_t *odu_route_rule_v4_hdl; uint32_t *odu_route_rule_v6_hdl; bool ipv4_header_set; bool ipv6_header_set; inline ipa_eth_client* get_client_memptr(ipa_eth_client *param, int cnt) { char *ret = ((char *)param) + (eth_client_len * cnt); return (ipa_eth_client *)ret; } inline int get_eth_client_index(uint8_t *mac_addr) { int cnt; int num_eth_client_tmp = num_eth_client; IPACMDBG_H("Passed MAC %02x:%02x:%02x:%02x:%02x:%02x\n", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); for(cnt = 0; cnt < num_eth_client_tmp; cnt++) { IPACMDBG_H("stored MAC %02x:%02x:%02x:%02x:%02x:%02x\n", get_client_memptr(eth_client, cnt)->mac[0], get_client_memptr(eth_client, cnt)->mac[1], get_client_memptr(eth_client, cnt)->mac[2], get_client_memptr(eth_client, cnt)->mac[3], get_client_memptr(eth_client, cnt)->mac[4], get_client_memptr(eth_client, cnt)->mac[5]); if(memcmp(get_client_memptr(eth_client, cnt)->mac, mac_addr, sizeof(get_client_memptr(eth_client, cnt)->mac)) == 0) { IPACMDBG_H("Matched client index: %d\n", cnt); return cnt; } } return IPACM_INVALID_INDEX; } inline int delete_eth_rtrules(int clt_indx, ipa_ip_type iptype) { uint32_t tx_index; uint32_t rt_hdl; int num_v6; if(iptype == IPA_IP_v4) { for(tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) { if((tx_prop->tx[tx_index].ip == IPA_IP_v4) && (get_client_memptr(eth_client, clt_indx)->route_rule_set_v4==true)) /* for ipv4 */ { IPACMDBG_H("Delete client index %d ipv4 RT-rules for tx:%d\n",clt_indx,tx_index); rt_hdl = get_client_memptr(eth_client, clt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v4; if(m_routing.DeleteRoutingHdl(rt_hdl, IPA_IP_v4) == false) { return IPACM_FAILURE; } } } /* end of for loop */ /* clean the ipv4 RT rules for eth-client:clt_indx */ if(get_client_memptr(eth_client, clt_indx)->route_rule_set_v4==true) /* for ipv4 */ { get_client_memptr(eth_client, clt_indx)->route_rule_set_v4 = false; } } if(iptype == IPA_IP_v6) { for(tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) { if((tx_prop->tx[tx_index].ip == IPA_IP_v6) && (get_client_memptr(eth_client, clt_indx)->route_rule_set_v6 != 0)) /* for ipv6 */ { for(num_v6 =0;num_v6 < get_client_memptr(eth_client, clt_indx)->route_rule_set_v6;num_v6++) { IPACMDBG_H("Delete client index %d ipv6 RT-rules for %d-st ipv6 for tx:%d\n", clt_indx,num_v6,tx_index); rt_hdl = get_client_memptr(eth_client, clt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[num_v6]; if(m_routing.DeleteRoutingHdl(rt_hdl, IPA_IP_v6) == false) { return IPACM_FAILURE; } rt_hdl = get_client_memptr(eth_client, clt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[num_v6]; if(m_routing.DeleteRoutingHdl(rt_hdl, IPA_IP_v6) == false) { return IPACM_FAILURE; } } } } /* end of for loop */ /* clean the ipv6 RT rules for eth-client:clt_indx */ if(get_client_memptr(eth_client, clt_indx)->route_rule_set_v6 != 0) /* for ipv6 */ { get_client_memptr(eth_client, clt_indx)->route_rule_set_v6 = 0; } } return IPACM_SUCCESS; } /* handle eth client initial, construct full headers (tx property) */ int handle_eth_hdr_init(uint8_t *mac_addr); /* handle eth client ip-address */ int handle_eth_client_ipaddr(ipacm_event_data_all *data); /* handle eth client routing rule*/ int handle_eth_client_route_rule(uint8_t *mac_addr, ipa_ip_type iptype); /*handle eth client del mode*/ int handle_eth_client_down_evt(uint8_t *mac_addr); /* handle odu client initial, construct full headers (tx property) */ int handle_odu_hdr_init(uint8_t *mac_addr); /* handle odu default route rule configuration */ int handle_odu_route_add(); /* handle odu default route rule deletion */ int handle_odu_route_del(); /*handle lan iface down event*/ int handle_down_evt(); /*handle lan2lan internal mesg posting*/ int post_lan2lan_client_disconnect_msg(ipa_ip_type iptype); /*handle reset usb-client rt-rules */ int handle_lan_client_reset_rt(ipa_ip_type iptype); }; #endif /* IPACM_LAN_H */ ================================================ FILE: data-ipa-cfg-mgr/ipacm/inc/IPACM_LanToLan.h ================================================ /* Copyright (c) 2014, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * IPACM_LanToLan.h * * Created on: Mar 4th, 2014 * Author: Shihuan Liu */ #ifndef IPACM_LANTOLAN_H #define IPACM_LANTOLAN_H #include #include "linux/msm_ipa.h" #include "IPACM_Iface.h" #include "IPACM_Defs.h" #include "IPACM_Lan.h" #include #ifdef FEATURE_IPA_ANDROID #include #else/* defined(FEATURE_IPA_ANDROID) */ #include #endif /* ndefined(FEATURE_IPA_ANDROID)*/ struct client_info; struct peer_info { struct client_info* peer_pointer; int num_connection; }; //used to store rule handles for offload link (one direction) struct offload_link_info { struct client_info* peer_pointer; uint32_t flt_rule_hdl; lan_to_lan_rt_rule_hdl rt_rule_hdl; uint32_t hdr_hdl; }; typedef list peer_info_list; typedef list offload_link_info_list; typedef list connection_list; struct client_info { union { uint32_t ipv4_addr; uint32_t ipv6_addr[4]; } ip; uint8_t mac_addr[6]; bool is_active; bool is_powersave; IPACM_Lan* p_iface; peer_info_list peer; offload_link_info_list link; }; struct v6_addr { uint32_t ipv6_addr[4]; }; typedef unordered_map client_table_v4; typedef unordered_map client_table_v6; class IPACM_LanToLan : public IPACM_Listener { public: IPACM_LanToLan(); ~IPACM_LanToLan(); void handle_new_connection(ipacm_event_connection* new_conn); void handle_del_connection(ipacm_event_connection* del_conn); static IPACM_LanToLan* getLan2LanInstance(); private: uint8_t num_offload_pair_v4_; uint8_t num_offload_pair_v6_; client_table_v4 client_info_v4_; client_table_v6 client_info_v6_; connection_list connection_v4_; connection_list connection_v6_; static IPACM_LanToLan* p_instance; void event_callback(ipa_cm_event_id event, void* param); void handle_client_active(ipacm_event_lan_client* data); void check_potential_link(ipa_ip_type iptype, client_info* client); int add_offload_link(ipa_ip_type iptype, client_info* client, client_info* peer); void handle_client_inactive(ipacm_event_lan_client* data); int turnoff_offload_links(ipa_ip_type iptype, client_info* client); int del_offload_link(ipa_ip_type iptype, IPACM_Lan* client, IPACM_Lan* peer, offload_link_info* link); void handle_client_disconnect(ipacm_event_lan_client* data); int clear_peer_list(client_info* client); void handle_client_power_save(ipacm_event_lan_client* data); void handle_client_power_recover(ipacm_event_lan_client* data); int remove_flt_rules(ipa_ip_type iptype, client_info* client); int add_flt_rules(ipa_ip_type iptype, client_info* client); //the following are for connections void handle_new_lan2lan_connection(ipacm_event_connection* data); bool add_connection(client_info* src_client, client_info* dst_client); void handle_del_lan2lan_connection(ipacm_event_connection* data); bool remove_connection(client_info* src_client, client_info* dst_client); void erase_offload_link(ipa_ip_type iptype, client_info* src_client, client_info* dst_client); void generate_new_connection(ipa_ip_type iptype, client_info* client); bool is_lan2lan_connection(ipacm_event_connection* data); bool is_potential_lan2lan_connection(ipacm_event_connection* new_conn); void cache_new_connection(ipacm_event_connection* new_conn); void remove_cache_connection(ipacm_event_connection* del_conn); void check_cache_connection(ipa_ip_type iptype, client_info* client); }; #endif ================================================ FILE: data-ipa-cfg-mgr/ipacm/inc/IPACM_Listener.h ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPACM_Listener.h @brief This file implements the abstract class notifier. @Author Skylar Chang */ #ifndef IPACM_LISTENER_H #define IPACM_LISTENER_H #include "IPACM_Defs.h" #include "IPACM_CmdQueue.h" /* abstract class notifier */ class IPACM_Listener { public: virtual void event_callback(ipa_cm_event_id event, void *data) = 0; virtual ~IPACM_Listener(void) {}; }; #endif /* IPACM_LISTENER_H */ ================================================ FILE: data-ipa-cfg-mgr/ipacm/inc/IPACM_Log.h ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPACM_log.h @brief This file implements the IPAM log functionality. @Author Skylar Chang */ #ifndef IPACM_LOG_H #define IPACM_LOG_H #ifdef __cplusplus extern "C" { #endif #include #include #include #define MAX_BUF_LEN 256 #ifdef FEATURE_IPA_ANDROID #define IPACMLOG_FILE "/dev/socket/ipacm_log_file" #else/* defined(FEATURE_IPA_ANDROID) */ #define IPACMLOG_FILE "/etc/ipacm_log_file" #endif /* defined(NOT FEATURE_IPA_ANDROID)*/ typedef struct ipacm_log_buffer_s { char user_data[MAX_BUF_LEN]; } ipacm_log_buffer_t; void ipacm_log_send( void * user_data); static char buffer_send[MAX_BUF_LEN]; #define PERROR(fmt) memset(buffer_send, 0, MAX_BUF_LEN);\ snprintf(buffer_send,MAX_BUF_LEN,"%s:%d %s()", __FILE__, __LINE__, __FUNCTION__);\ ipacm_log_send (buffer_send); \ perror(fmt); #define IPACMERR(fmt, ...) memset(buffer_send, 0, MAX_BUF_LEN);\ snprintf(buffer_send,MAX_BUF_LEN,"ERR: %s:%d %s() " fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__);\ ipacm_log_send (buffer_send);\ printf("ERR: %s:%d %s() " fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); #define IPACMDBG_H(fmt, ...) memset(buffer_send, 0, MAX_BUF_LEN);\ snprintf(buffer_send,MAX_BUF_LEN,"%s:%d %s() " fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__);\ ipacm_log_send (buffer_send);\ printf("%s:%d %s() " fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); #define IPACMDBG(fmt, ...) printf("%s:%d %s() " fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); #define IPACMLOG(fmt, ...) printf(fmt, ##__VA_ARGS__); #ifdef __cplusplus } #endif #endif /* IPACM_LOG_H */ ================================================ FILE: data-ipa-cfg-mgr/ipacm/inc/IPACM_Neighbor.h ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPACM_Neighbor.h @brief This file implements the functionality of handling IPACM Neighbor events. @Author Skylar Chang */ #ifndef IPACM_NEIGHBOR_H #define IPACM_NEIGHBOR_H #include #include #include #include "IPACM_Routing.h" #include "IPACM_Filtering.h" #include "IPACM_Listener.h" #include "IPACM_Iface.h" #define IPA_MAX_NUM_NEIGHBOR_CLIENTS 17 struct ipa_neighbor_client { uint8_t mac_addr[6]; int iface_index; uint32_t v4_addr; int ipa_if_num; }; class IPACM_Neighbor : public IPACM_Listener { public: IPACM_Neighbor(); void event_callback(ipa_cm_event_id event, void *data); private: int num_neighbor_client; ipa_neighbor_client neighbor_client[IPA_MAX_NUM_NEIGHBOR_CLIENTS]; }; #endif /* IPACM_NEIGHBOR_H */ ================================================ FILE: data-ipa-cfg-mgr/ipacm/inc/IPACM_Netlink.h ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPA_Netlink.h @brief IPACM Netlink Messaging Implementation File @Author Skylar Chang */ #ifndef IPACM_NETLINK_H #define IPACM_NETLINK_H #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #include #include #include #include #include #include #include "IPACM_Defs.h" #define MAX_NUM_OF_FD 10 #define IPA_NL_MSG_MAX_LEN (2048) /*--------------------------------------------------------------------------- Type representing enumeration of NetLink event indication messages ---------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------- Types representing parsed NetLink message ---------------------------------------------------------------------------*/ #define IPA_NLA_PARAM_NONE (0x0000) #define IPA_NLA_PARAM_PREFIXADDR (0x0001) #define IPA_NLA_PARAM_LOCALADDR (0x0002) #define IPA_NLA_PARAM_LABELNAME (0x0004) #define IPA_NLA_PARAM_BCASTADDR (0x0008) #define IPA_NLA_PARAM_ACASTADDR (0x0010) #define IPA_NLA_PARAM_MCASTADDR (0x0020) #define IPA_NLA_PARAM_CACHEINFO (0x0080) #define IPA_NLA_PARAM_PROTOINFO (0x0100) #define IPA_NLA_PARAM_FLAGS (0x0200) #define IPA_RTA_PARAM_NONE (0x0000) #define IPA_RTA_PARAM_DST (0x0001) #define IPA_RTA_PARAM_SRC (0x0002) #define IPA_RTA_PARAM_GATEWAY (0x0004) #define IPA_RTA_PARAM_IIF (0x0008) #define IPA_RTA_PARAM_OIF (0x0010) #define IPA_RTA_PARAM_CACHEINFO (0x0020) #define IPA_RTA_PARAM_PRIORITY (0x0080) #define IPA_RTA_PARAM_METRICS (0x0100) /*--------------------------------------------------------------------------- Type representing function callback registered with a socket listener thread for reading from a socket on receipt of an incoming message ---------------------------------------------------------------------------*/ typedef int (*ipa_sock_thrd_fd_read_f)(int fd); typedef enum { IPA_INIT = 0, IPA_LINK_UP_WAIT, IPA_LINK_UP, IPA_LINK_DOWN_WAIT, IPA_LINK_DOWN } ipa_nl_state_e; typedef struct { int sk_fd; ipa_sock_thrd_fd_read_f read_func; } ipa_nl_sk_fd_map_info_t; typedef struct { ipa_nl_sk_fd_map_info_t sk_fds[MAX_NUM_OF_FD]; fd_set fdset; int num_fd; int max_fd; } ipa_nl_sk_fd_set_info_t; typedef struct { int sk_fd; /* socket descriptor */ struct sockaddr_nl sk_addr_loc; /* local address of socket */ } ipa_nl_sk_info_t; typedef struct ipa_nl_addr_s { struct sockaddr_storage ip_addr; unsigned int mask; } ipa_nl_addr_t; typedef struct ipa_nl_proto_info_s { unsigned int param_mask; unsigned int flags; struct ifla_cacheinfo cache_info; } ipa_nl_proto_info_t; typedef struct { struct ifinfomsg metainfo; /* from header */ } ipa_nl_link_info_t; typedef struct ipa_nl_addr_info_s { struct ifaddrmsg metainfo; /* from header */ struct /* attributes */ { unsigned int param_mask; unsigned char label_name[IF_NAME_LEN]; struct sockaddr_storage prefix_addr; struct sockaddr_storage local_addr; struct sockaddr_storage bcast_addr; struct sockaddr_storage acast_addr; struct sockaddr_storage mcast_addr; } attr_info; } ipa_nl_addr_info_t; typedef struct ipa_nl_neigh_info_s { struct ndmsg metainfo; /* from header */ struct /* attributes */ { unsigned int param_mask; struct sockaddr_storage local_addr; struct sockaddr lladdr_hwaddr; } attr_info; } ipa_nl_neigh_info_t; typedef struct ipa_nl_route_info_s { struct rtmsg metainfo; /* from header */ struct /* attributes */ { unsigned int param_mask; struct sockaddr_storage dst_addr; struct sockaddr_storage src_addr; struct sockaddr_storage gateway_addr; struct sockaddr_storage mark_addr; struct rta_cacheinfo cache_info; __u32 iif_index; /* Link index */ __u32 oif_index; /* Link index */ __u32 priority; __u32 metrics; ipa_nl_proto_info_t proto_info; } attr_info; } ipa_nl_route_info_t; #define IPA_FLOW_TYPE_INVALID (-1) typedef struct { unsigned int type; bool link_event; /* Optional parameters */ ipa_nl_link_info_t nl_link_info; ipa_nl_addr_info_t nl_addr_info; ipa_nl_neigh_info_t nl_neigh_info; ipa_nl_route_info_t nl_route_info; } ipa_nl_msg_t; /* Initialization routine for listener on NetLink sockets interface */ int ipa_nl_listener_init ( unsigned int nl_type, unsigned int nl_groups, ipa_nl_sk_fd_set_info_t *sk_fdset, ipa_sock_thrd_fd_read_f read_f ); /* Virtual function registered to receive incoming messages over the NETLINK routing socket*/ int ipa_nl_recv_msg(int fd); /* map mask value for ipv6 */ int mask_v6(int index, uint32_t *mask); #ifdef __cplusplus } #endif #endif /* IPACM_NETLINK_H */ ================================================ FILE: data-ipa-cfg-mgr/ipacm/inc/IPACM_Routing.h ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPACM_Routing.cpp @brief This file implements the IPACM routing functionality. @Author Skylar Chang */ #ifndef IPACM_ROUTING_H #define IPACM_ROUTING_H #include #include #include using namespace std; class IPACM_Routing { public: IPACM_Routing(); ~IPACM_Routing(); bool AddRoutingRule(struct ipa_ioc_add_rt_rule *ruleTable); bool DeleteRoutingRule(struct ipa_ioc_del_rt_rule *ruleTable); bool Commit(enum ipa_ip_type ip); bool Reset(enum ipa_ip_type ip); bool GetRoutingTable(struct ipa_ioc_get_rt_tbl *routingTable); bool PutRoutingTable(uint32_t routingTableHandle); bool DeviceNodeIsOpened(); bool DeleteRoutingHdl(uint32_t rt_rule_hdl, ipa_ip_type ip); private: static const char *DEVICE_NAME; int m_fd; /* File descriptor of the IPA device node /dev/ipa */ }; #endif //IPACM_ROUTING_H ================================================ FILE: data-ipa-cfg-mgr/ipacm/inc/IPACM_Wan.h ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPACM_Wan.cpp @brief This file implements the WAN iface functionality. @Author Skylar Chang */ #ifndef IPACM_WAN_H #define IPACM_WAN_H #include #include #include #include "IPACM_Routing.h" #include "IPACM_Filtering.h" #include #include #include #define IPA_NUM_DEFAULT_WAN_FILTER_RULES 3 /*1 for v4, 2 for v6*/ #define IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV4 2 #ifdef FEATURE_IPA_ANDROID #define IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV6 6 #else #define IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV6 3 #endif #define NETWORK_STATS "%s %lu %lu %lu %lu" #define IPA_NETWORK_STATS_FILE_NAME "/data/misc/ipa/network_stats" typedef struct _wan_client_rt_hdl { uint32_t wan_rt_rule_hdl_v4; uint32_t wan_rt_rule_hdl_v6[IPV6_NUM_ADDR]; uint32_t wan_rt_rule_hdl_v6_wan[IPV6_NUM_ADDR]; }wan_client_rt_hdl; typedef struct _ipa_wan_client { ipacm_event_data_wlan_ex* p_hdr_info; uint8_t mac[IPA_MAC_ADDR_SIZE]; uint32_t v4_addr; uint32_t v6_addr[IPV6_NUM_ADDR][4]; uint32_t hdr_hdl_v4; uint32_t hdr_hdl_v6; bool route_rule_set_v4; int route_rule_set_v6; bool ipv4_set; int ipv6_set; bool ipv4_header_set; bool ipv6_header_set; bool power_save_set; wan_client_rt_hdl wan_rt_hdl[0]; /* depends on number of tx properties */ }ipa_wan_client; /* wan iface */ class IPACM_Wan : public IPACM_Iface { public: static bool wan_up; static bool wan_up_v6; /* IPACM interface name */ static char wan_up_dev_name[IF_NAME_LEN]; IPACM_Wan(int, ipacm_wan_iface_type, uint8_t *); virtual ~IPACM_Wan(); static bool isWanUP(int ipa_if_num_tether) { #ifdef FEATURE_IPA_ANDROID int i; for (i=0; i < ipa_if_num_tether_v4_total;i++) { if (ipa_if_num_tether_v4[i] == ipa_if_num_tether) { IPACMDBG_H("support ipv4 tether_iface(%s)\n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether].iface_name); return wan_up; break; } } return false; #else return wan_up; #endif } static bool isWanUP_V6(int ipa_if_num_tether) { #ifdef FEATURE_IPA_ANDROID int i; for (i=0; i < ipa_if_num_tether_v6_total;i++) { if (ipa_if_num_tether_v6[i] == ipa_if_num_tether) { IPACMDBG_H("support ipv6 tether_iface(%s)\n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether].iface_name); return wan_up_v6; break; } } return false; #else return wan_up_v6; #endif } void event_callback(ipa_cm_event_id event, void *data); static struct ipa_flt_rule_add flt_rule_v4[IPA_MAX_FLT_RULE]; static struct ipa_flt_rule_add flt_rule_v6[IPA_MAX_FLT_RULE]; static int num_v4_flt_rule; static int num_v6_flt_rule; ipacm_wan_iface_type m_is_sta_mode; static bool backhaul_is_sta_mode; static bool is_ext_prop_set; static uint32_t backhaul_ipv6_prefix[2]; static bool embms_is_on; #ifdef FEATURE_IPA_ANDROID /* IPACM interface id */ static int ipa_if_num_tether_v4_total; static int ipa_if_num_tether_v4[IPA_MAX_IFACE_ENTRIES]; static int ipa_if_num_tether_v6_total; static int ipa_if_num_tether_v6[IPA_MAX_IFACE_ENTRIES]; #endif private: uint32_t ipv6_frag_firewall_flt_rule_hdl; uint32_t *wan_route_rule_v4_hdl; uint32_t *wan_route_rule_v6_hdl; uint32_t *wan_route_rule_v6_hdl_a5; uint32_t hdr_hdl_sta_v4; uint32_t hdr_hdl_sta_v6; uint32_t firewall_hdl_v4[IPACM_MAX_FIREWALL_ENTRIES]; uint32_t firewall_hdl_v6[IPACM_MAX_FIREWALL_ENTRIES]; uint32_t dft_wan_fl_hdl[IPA_NUM_DEFAULT_WAN_FILTER_RULES]; uint32_t ipv6_dest_flt_rule_hdl[MAX_DEFAULT_v6_ROUTE_RULES]; int num_ipv6_dest_flt_rule; uint32_t ODU_fl_hdl[IPA_NUM_DEFAULT_WAN_FILTER_RULES]; int num_firewall_v4,num_firewall_v6; uint32_t wan_v4_addr; bool active_v4; bool active_v6; bool header_set_v4; bool header_set_v6; bool header_partial_default_wan_v4; bool header_partial_default_wan_v6; uint8_t ext_router_mac_addr[IPA_MAC_ADDR_SIZE]; uint16_t eth2_ofst_v4; uint16_t eth2_ofst_v6; static int num_ipv4_modem_pdn; static int num_ipv6_modem_pdn; int modem_ipv4_pdn_index; int modem_ipv6_pdn_index; bool is_default_gateway; uint32_t ipv6_prefix[2]; /* IPACM firewall Configuration file*/ IPACM_firewall_conf_t firewall_config; /* STA mode wan-client*/ int wan_client_len; ipa_wan_client *wan_client; int header_name_count; int num_wan_client; uint8_t invalid_mac[IPA_MAC_ADDR_SIZE]; /* update network stats for CNE */ int ipa_network_stats_fd; inline ipa_wan_client* get_client_memptr(ipa_wan_client *param, int cnt) { char *ret = ((char *)param) + (wan_client_len * cnt); return (ipa_wan_client *)ret; } inline int get_wan_client_index(uint8_t *mac_addr) { int cnt; int num_wan_client_tmp = num_wan_client; IPACMDBG_H("Passed MAC %02x:%02x:%02x:%02x:%02x:%02x\n", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); for(cnt = 0; cnt < num_wan_client_tmp; cnt++) { IPACMDBG_H("stored MAC %02x:%02x:%02x:%02x:%02x:%02x\n", get_client_memptr(wan_client, cnt)->mac[0], get_client_memptr(wan_client, cnt)->mac[1], get_client_memptr(wan_client, cnt)->mac[2], get_client_memptr(wan_client, cnt)->mac[3], get_client_memptr(wan_client, cnt)->mac[4], get_client_memptr(wan_client, cnt)->mac[5]); if(memcmp(get_client_memptr(wan_client, cnt)->mac, mac_addr, sizeof(get_client_memptr(wan_client, cnt)->mac)) == 0) { IPACMDBG_H("Matched client index: %d\n", cnt); return cnt; } } return IPACM_INVALID_INDEX; } inline int delete_wan_rtrules(int clt_indx, ipa_ip_type iptype) { uint32_t tx_index; uint32_t rt_hdl; int num_v6; if(iptype == IPA_IP_v4) { for(tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) { if((tx_prop->tx[tx_index].ip == IPA_IP_v4) && (get_client_memptr(wan_client, clt_indx)->route_rule_set_v4==true)) /* for ipv4 */ { IPACMDBG_H("Delete client index %d ipv4 Qos rules for tx:%d \n",clt_indx,tx_index); rt_hdl = get_client_memptr(wan_client, clt_indx)->wan_rt_hdl[tx_index].wan_rt_rule_hdl_v4; if(m_routing.DeleteRoutingHdl(rt_hdl, IPA_IP_v4) == false) { return IPACM_FAILURE; } } } /* end of for loop */ /* clean the 4 Qos ipv4 RT rules for client:clt_indx */ if(get_client_memptr(wan_client, clt_indx)->route_rule_set_v4==true) /* for ipv4 */ { get_client_memptr(wan_client, clt_indx)->route_rule_set_v4 = false; } } if(iptype == IPA_IP_v6) { for(tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) { if((tx_prop->tx[tx_index].ip == IPA_IP_v6) && (get_client_memptr(wan_client, clt_indx)->route_rule_set_v6 != 0)) /* for ipv6 */ { for(num_v6 =0;num_v6 < get_client_memptr(wan_client, clt_indx)->route_rule_set_v6;num_v6++) { IPACMDBG_H("Delete client index %d ipv6 Qos rules for %d-st ipv6 for tx:%d\n", clt_indx,num_v6,tx_index); rt_hdl = get_client_memptr(wan_client, clt_indx)->wan_rt_hdl[tx_index].wan_rt_rule_hdl_v6[num_v6]; if(m_routing.DeleteRoutingHdl(rt_hdl, IPA_IP_v6) == false) { return IPACM_FAILURE; } rt_hdl = get_client_memptr(wan_client, clt_indx)->wan_rt_hdl[tx_index].wan_rt_rule_hdl_v6_wan[num_v6]; if(m_routing.DeleteRoutingHdl(rt_hdl, IPA_IP_v6) == false) { return IPACM_FAILURE; } } } } /* end of for loop */ /* clean the 4 Qos ipv6 RT rules for client:clt_indx */ if(get_client_memptr(wan_client, clt_indx)->route_rule_set_v6 != 0) /* for ipv6 */ { get_client_memptr(wan_client, clt_indx)->route_rule_set_v6 = 0; } } return IPACM_SUCCESS; } int handle_wan_hdr_init(uint8_t *mac_addr); int handle_wan_client_ipaddr(ipacm_event_data_all *data); int handle_wan_client_route_rule(uint8_t *mac_addr, ipa_ip_type iptype); /* handle new_address event */ int handle_addr_evt(ipacm_event_data_addr *data); /* wan default route/filter rule configuration */ int handle_route_add_evt(ipa_ip_type iptype); /* construct complete ethernet header */ int handle_header_add_evt(uint8_t *mac_addr); /* wan posting supported tether_iface */ int post_wan_up_tether_evt(ipa_ip_type iptype, int ipa_if_num_tether); int config_dft_firewall_rules(ipa_ip_type iptype); /* configure the initial firewall filter rules */ int config_dft_embms_rules(ipa_ioc_add_flt_rule *pFilteringTable_v4, ipa_ioc_add_flt_rule *pFilteringTable_v6); int handle_route_del_evt(ipa_ip_type iptype); int post_wan_down_tether_evt(ipa_ip_type iptype, int ipa_if_num_tether); int del_dft_firewall_rules(ipa_ip_type iptype); int handle_down_evt(); /*handle wan-iface down event */ int handle_down_evt_ex(); /* wan default route/filter rule delete */ int handle_route_del_evt_ex(ipa_ip_type iptype); /* configure the initial firewall filter rules */ int config_dft_firewall_rules_ex(struct ipa_flt_rule_add* rules, int rule_offset, ipa_ip_type iptype); /* init filtering rule in wan dl filtering table */ int init_fl_rule_ex(ipa_ip_type iptype); /* add ICMP and ALG rules in wan dl filtering table */ int add_icmp_alg_rules(struct ipa_flt_rule_add* rules, int rule_offset, ipa_ip_type iptype); /* query extended property */ int query_ext_prop(); ipa_ioc_query_intf_ext_props *ext_prop; int config_wan_firewall_rule(ipa_ip_type iptype); int del_wan_firewall_rule(ipa_ip_type iptype); int add_dft_filtering_rule(struct ipa_flt_rule_add* rules, int rule_offset, ipa_ip_type iptype); int install_wan_filtering_rule(bool is_sw_routing); void change_to_network_order(ipa_ip_type iptype, ipa_rule_attrib* attrib); bool is_global_ipv6_addr(uint32_t* ipv6_addr); int handle_network_stats_evt(); int m_fd_ipa; int handle_network_stats_update(ipa_get_apn_data_stats_resp_msg_v01 *data); }; #endif /* IPACM_WAN_H */ ================================================ FILE: data-ipa-cfg-mgr/ipacm/inc/IPACM_Wlan.h ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPACM_Wlan.h @brief This file implements the WLAN iface functionality. @Author Skylar Chang */ #ifndef IPACM_WLAN_H #define IPACM_WLAN_H #include #include #include #include "IPACM_Routing.h" #include "IPACM_Filtering.h" #include "IPACM_Lan.h" #include "IPACM_Iface.h" #include "IPACM_Conntrack_NATApp.h" typedef struct _wlan_client_rt_hdl { uint32_t wifi_rt_rule_hdl_v4; uint32_t wifi_rt_rule_hdl_v6[IPV6_NUM_ADDR]; uint32_t wifi_rt_rule_hdl_v6_wan[IPV6_NUM_ADDR]; }wlan_client_rt_hdl; typedef struct _ipa_wlan_client { ipacm_event_data_wlan_ex* p_hdr_info; uint8_t mac[IPA_MAC_ADDR_SIZE]; uint32_t v4_addr; uint32_t v6_addr[IPV6_NUM_ADDR][4]; uint32_t hdr_hdl_v4; uint32_t hdr_hdl_v6; bool route_rule_set_v4; int route_rule_set_v6; bool ipv4_set; int ipv6_set; bool ipv4_header_set; bool ipv6_header_set; bool power_save_set; wlan_client_rt_hdl wifi_rt_hdl[0]; /* depends on number of tx properties */ }ipa_wlan_client; typedef enum { SRC_WLAN, SRC_USB } eth_bridge_src_iface; /* wlan iface */ class IPACM_Wlan : public IPACM_Lan { public: IPACM_Wlan(int iface_index); virtual ~IPACM_Wlan(void); static int total_num_wifi_clients; void event_callback(ipa_cm_event_id event, void *data); virtual int add_lan2lan_hdr(ipa_ip_type iptype, uint8_t* src_mac, uint8_t* dst_mac, uint32_t* hdr_hdl); private: eth_bridge_client_flt_info eth_bridge_usb_client_flt_info[IPA_LAN_TO_LAN_MAX_USB_CLIENT]; int num_usb_client; uint32_t wlan_guest_ap_flt_rule_hdl_v4[IPA_MAX_PRIVATE_SUBNET_ENTRIES]; uint32_t wlan_guest_ap_flt_rule_hdl_v6; static lan2lan_flt_rule_hdl self_client_flt_rule_hdl_v4[IPA_LAN_TO_LAN_MAX_WLAN_CLIENT]; static lan2lan_flt_rule_hdl self_client_flt_rule_hdl_v6[IPA_LAN_TO_LAN_MAX_WLAN_CLIENT]; static lan2lan_flt_rule_hdl usb_client_flt_rule_hdl_v4[IPA_LAN_TO_LAN_MAX_USB_CLIENT]; static lan2lan_flt_rule_hdl usb_client_flt_rule_hdl_v6[IPA_LAN_TO_LAN_MAX_USB_CLIENT]; bool is_guest_ap; eth_bridge_client_rt_info* eth_bridge_wlan_client_rt_from_usb_info_v4; int wlan_client_rt_from_usb_info_count_v4; eth_bridge_client_rt_info* eth_bridge_wlan_client_rt_from_usb_info_v6; int wlan_client_rt_from_usb_info_count_v6; eth_bridge_client_rt_info* eth_bridge_wlan_client_rt_from_wlan_info_v4; int wlan_client_rt_from_wlan_info_count_v4; eth_bridge_client_rt_info* eth_bridge_wlan_client_rt_from_wlan_info_v6; int wlan_client_rt_from_wlan_info_count_v6; virtual int eth_bridge_add_wlan_guest_ap_flt_rule(ipa_ip_type iptype); int eth_bridge_install_wlan_guest_ap_ipv6_flt_rule(); virtual int eth_bridge_handle_dummy_wlan_client_flt_rule(ipa_ip_type iptype); virtual int eth_bridge_handle_dummy_usb_client_flt_rule(ipa_ip_type iptype); int eth_bridge_add_usb_client_flt_rule(uint8_t* mac, ipa_ip_type iptype); int eth_bridge_del_usb_client_flt_rule(uint8_t* mac); int eth_bridge_add_self_client_flt_rule(uint8_t* mac, ipa_ip_type iptype); int eth_bridge_del_self_client_flt_rule(uint8_t* mac); virtual int eth_bridge_install_cache_wlan_client_flt_rule(ipa_ip_type iptype); virtual int eth_bridge_install_cache_usb_client_flt_rule(ipa_ip_type iptype); int eth_bridge_add_wlan_client_rt_rule(uint8_t* mac, eth_bridge_src_iface src, ipa_ip_type iptype); int eth_bridge_del_wlan_client_rt_rule(uint8_t* mac, eth_bridge_src_iface src); eth_bridge_client_rt_info* eth_bridge_get_client_rt_info_ptr(uint8_t index, eth_bridge_src_iface src, ipa_ip_type iptype); void eth_bridge_add_wlan_client(uint8_t* mac, int if_num); void eth_bridge_del_wlan_client(uint8_t* mac); int wlan_client_len; ipa_wlan_client *wlan_client; int header_name_count; int num_wifi_client; int wlan_ap_index; static uint32_t* dummy_flt_rule_hdl_v4; static uint32_t* dummy_flt_rule_hdl_v6; static int num_wlan_ap_iface; NatApp *Nat_App; inline ipa_wlan_client* get_client_memptr(ipa_wlan_client *param, int cnt) { char *ret = ((char *)param) + (wlan_client_len * cnt); return (ipa_wlan_client *)ret; } inline int get_wlan_client_index(uint8_t *mac_addr) { int cnt; int num_wifi_client_tmp = num_wifi_client; IPACMDBG_H("Passed MAC %02x:%02x:%02x:%02x:%02x:%02x\n", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); for(cnt = 0; cnt < num_wifi_client_tmp; cnt++) { IPACMDBG_H("stored MAC %02x:%02x:%02x:%02x:%02x:%02x\n", get_client_memptr(wlan_client, cnt)->mac[0], get_client_memptr(wlan_client, cnt)->mac[1], get_client_memptr(wlan_client, cnt)->mac[2], get_client_memptr(wlan_client, cnt)->mac[3], get_client_memptr(wlan_client, cnt)->mac[4], get_client_memptr(wlan_client, cnt)->mac[5]); if(memcmp(get_client_memptr(wlan_client, cnt)->mac, mac_addr, sizeof(get_client_memptr(wlan_client, cnt)->mac)) == 0) { IPACMDBG_H("Matched client index: %d\n", cnt); return cnt; } } return IPACM_INVALID_INDEX; } inline int delete_default_qos_rtrules(int clt_indx, ipa_ip_type iptype) { uint32_t tx_index; uint32_t rt_hdl; int num_v6; if(iptype == IPA_IP_v4) { for(tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) { if((tx_prop->tx[tx_index].ip == IPA_IP_v4) && (get_client_memptr(wlan_client, clt_indx)->route_rule_set_v4==true)) /* for ipv4 */ { IPACMDBG_H("Delete client index %d ipv4 Qos rules for tx:%d \n",clt_indx,tx_index); rt_hdl = get_client_memptr(wlan_client, clt_indx)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v4; if(m_routing.DeleteRoutingHdl(rt_hdl, IPA_IP_v4) == false) { return IPACM_FAILURE; } } } /* end of for loop */ /* clean the 4 Qos ipv4 RT rules for client:clt_indx */ if(get_client_memptr(wlan_client, clt_indx)->route_rule_set_v4==true) /* for ipv4 */ { get_client_memptr(wlan_client, clt_indx)->route_rule_set_v4 = false; } } if(iptype == IPA_IP_v6) { for(tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) { if((tx_prop->tx[tx_index].ip == IPA_IP_v6) && (get_client_memptr(wlan_client, clt_indx)->route_rule_set_v6 != 0)) /* for ipv6 */ { for(num_v6 =0;num_v6 < get_client_memptr(wlan_client, clt_indx)->route_rule_set_v6;num_v6++) { IPACMDBG_H("Delete client index %d ipv6 Qos rules for %d-st ipv6 for tx:%d\n", clt_indx,num_v6,tx_index); rt_hdl = get_client_memptr(wlan_client, clt_indx)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6[num_v6]; if(m_routing.DeleteRoutingHdl(rt_hdl, IPA_IP_v6) == false) { return IPACM_FAILURE; } rt_hdl = get_client_memptr(wlan_client, clt_indx)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6_wan[num_v6]; if(m_routing.DeleteRoutingHdl(rt_hdl, IPA_IP_v6) == false) { return IPACM_FAILURE; } } } } /* end of for loop */ /* clean the 4 Qos ipv6 RT rules for client:clt_indx */ if(get_client_memptr(wlan_client, clt_indx)->route_rule_set_v6 != 0) /* for ipv6 */ { get_client_memptr(wlan_client, clt_indx)->route_rule_set_v6 = 0; } } return IPACM_SUCCESS; } /* for handle wifi client initial,copy all partial headers (tx property) */ int handle_wlan_client_init_ex(ipacm_event_data_wlan_ex *data); /*handle lan2lan internal mesg posting*/ int handle_lan2lan_msg_post(uint8_t *mac_addr, ipa_cm_event_id event, ipa_ip_type iptype); /*handle wifi client */ int handle_wlan_client_ipaddr(ipacm_event_data_all *data); /*handle wifi client routing rule*/ int handle_wlan_client_route_rule(uint8_t *mac_addr, ipa_ip_type iptype); /*handle wifi client power-save mode*/ int handle_wlan_client_pwrsave(uint8_t *mac_addr); /*handle wifi client del mode*/ int handle_wlan_client_down_evt(uint8_t *mac_addr); /*handle wlan iface down event*/ int handle_down_evt(); /* add dummy filtering rules for WLAN AP-AP mode support */ void add_dummy_flt_rule(); /* install dummy filtering rules for WLAN AP-AP mode support */ int install_dummy_flt_rule(ipa_ip_type iptype, int num_rule); /* delete dummy flt rule for WLAN AP-AP mode support*/ void del_dummy_flt_rule(); /*Configure the initial filter rules */ virtual int init_fl_rule(ipa_ip_type iptype); virtual int add_dummy_lan2lan_flt_rule(ipa_ip_type iptype); virtual int add_dummy_private_subnet_flt_rule(ipa_ip_type iptype); /*configure private subnet filter rules*/ virtual int handle_private_subnet(ipa_ip_type iptype); /* install UL filter rule from Q6 */ virtual int handle_uplink_filter_rule(ipacm_ext_prop* prop, ipa_ip_type iptype); /* install TCP control filter rules */ virtual void install_tcp_ctl_flt_rule(ipa_ip_type iptype); /*handle reset wifi-client rt-rules */ int handle_wlan_client_reset_rt(ipa_ip_type iptype); }; #endif /* IPACM_WLAN_H */ ================================================ FILE: data-ipa-cfg-mgr/ipacm/inc/IPACM_Xml.h ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPACM_Xml.h @brief This file implements the XML specific parsing functionality. @Author Skylar Chang/Shihuan Liu */ #ifndef IPACM_XML_H #define IPACM_XML_H #include #include "IPACM_Defs.h" #include #include #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif #define IPACM_ASSERT(a) \ if (!(a)) { \ fprintf(stderr, "%s, %d: assertion (a) failed!", \ __FILE__, \ __LINE__); \ abort(); \ } /* Max allowed size of the XML file (2 MB) */ #define IPACM_XML_MAX_FILESIZE (2 << 20) #define IPACM_MAX_FIREWALL_ENTRIES 50 #define IPACM_IPV6_ADDR_LEN 16 /* Defines for clipping space or space & quotes (single, double) */ #define IPACM_XML_CLIP_SPACE " " #define IPACM_XML_CLIP_SPACE_QUOTES " '\"" #define MAX_XML_STR_LEN 120 /* IPA Config Entries */ #define system_TAG "system" #define ODU_TAG "ODUCFG" #define ODUMODE_TAG "Mode" #define ODU_ROUTER_TAG "router" #define ODU_BRIDGE_TAG "bridge" #define IPACMCFG_TAG "IPACM" #define IPACMIFACECFG_TAG "IPACMIface" #define IFACE_TAG "Iface" #define NAME_TAG "Name" #define CATEGORY_TAG "Category" #define IPACMPRIVATESUBNETCFG_TAG "IPACMPrivateSubnet" #define SUBNET_TAG "Subnet" #define SUBNETADDRESS_TAG "SubnetAddress" #define SUBNETMASK_TAG "SubnetMask" #define WANIF_TAG "WAN" #define LANIF_TAG "LAN" #define WLANIF_TAG "WLAN" #define VIRTUALIF_TAG "VIRTUAL" #define UNKNOWNIF_TAG "UNKNOWN" #define ODUIF_TAG "ODU" #define EMBMSIF_TAG "EMBMS" #define ETHIF_TAG "ETH" #define IPACMALG_TAG "IPACMALG" #define ALG_TAG "ALG" #define Protocol_TAG "Protocol" #define Port_TAG "Port" #define TCP_PROTOCOL_TAG "TCP" #define UDP_PROTOCOL_TAG "UDP" /* FIREWALL Config Entries */ #define Firewall_TAG "Firewall" #define MobileAPFirewallCfg_TAG "MobileAPFirewallCfg" #define FirewallEnabled_TAG "FirewallEnabled" #define FirewallPktsAllowed_TAG "FirewallPktsAllowed" #define IPFamily_TAG "IPFamily" #define IPV4SourceAddress_TAG "IPV4SourceAddress" #define IPV4SourceIPAddress_TAG "IPV4SourceIPAddress" #define IPV4SourceSubnetMask_TAG "IPV4SourceSubnetMask" #define IPV4DestinationAddress_TAG "IPV4DestinationAddress" #define IPV4DestinationIPAddress_TAG "IPV4DestinationIPAddress" #define IPV4DestinationSubnetMask_TAG "IPV4DestinationSubnetMask" #define IPV4TypeOfService_TAG "IPV4TypeOfService" #define TOSValue_TAG "TOSValue" #define TOSMask_TAG "TOSMask" #define IPV4NextHeaderProtocol_TAG "IPV4NextHeaderProtocol" #define IPV6SourceAddress_TAG "IPV6SourceAddress" #define IPV6SourceIPAddress_TAG "IPV6SourceIPAddress" #define IPV6SourcePrefix_TAG "IPV6SourcePrefix" #define IPV6DestinationAddress_TAG "IPV6DestinationAddress" #define IPV6DestinationIPAddress_TAG "IPV6DestinationIPAddress" #define IPV6DestinationPrefix_TAG "IPV6DestinationPrefix" #define IPV6TrafficClass_TAG "IPV6TrafficClass" #define TrfClsValue_TAG "TrfClsValue" #define TrfClsMask_TAG "TrfClsMask" #define IPV6NextHeaderProtocol_TAG "IPV6NextHeaderProtocol" #define TCPSource_TAG "TCPSource" #define TCPSourcePort_TAG "TCPSourcePort" #define TCPSourceRange_TAG "TCPSourceRange" #define TCPDestination_TAG "TCPDestination" #define TCPDestinationPort_TAG "TCPDestinationPort" #define TCPDestinationRange_TAG "TCPDestinationRange" #define UDPSource_TAG "UDPSource" #define UDPSourcePort_TAG "UDPSourcePort" #define UDPSourceRange_TAG "UDPSourceRange" #define UDPDestination_TAG "UDPDestination" #define UDPDestinationPort_TAG "UDPDestinationPort" #define UDPDestinationRange_TAG "UDPDestinationRange" #define ICMPType_TAG "ICMPType" #define ICMPCode_TAG "ICMPCode" #define ESP_TAG "ESP" #define ESPSPI_TAG "ESPSPI" #define TCP_UDPSource_TAG "TCP_UDPSource" #define TCP_UDPSourcePort_TAG "TCP_UDPSourcePort" #define TCP_UDPSourceRange_TAG "TCP_UDPSourceRange" #define TCP_UDPDestination_TAG "TCP_UDPDestination" #define TCP_UDPDestinationPort_TAG "TCP_UDPDestinationPort" #define TCP_UDPDestinationRange_TAG "TCP_UDPDestinationRange" #define IPACMNat_TAG "IPACMNAT" #define NAT_MaxEntries_TAG "MaxNatEntries" /*--------------------------------------------------------------------------- IP protocol numbers - use in dss_socket() to identify protocols. Also contains the extension header types for IPv6. ---------------------------------------------------------------------------*/ typedef enum { IPACM_FIREWALL_IPV6_BASE_HDR = 4, /* IPv6 Base Header */ IPACM_FIREWALL_IPPROTO_HOP_BY_HOP_OPT_HDR = 0, /* Hop-by-hop Option Header */ IPACM_FIREWALL_IPPROTO_ICMP = 1, /* ICMP protocol */ IPACM_FIREWALL_IPPROTO_IGMP = 2, /* IGMP protocol */ IPACM_FIREWALL_IPPROTO_IP = IPACM_FIREWALL_IPV6_BASE_HDR, /* IPv4 */ IPACM_FIREWALL_IPPROTO_TCP = 6, /* TCP Protocol */ IPACM_FIREWALL_IPPROTO_UDP = 17, /* UDP Protocol */ IPACM_FIREWALL_IPPROTO_IPV6 = 41, /* IPv6 */ IPACM_FIREWALL_IPPROTO_ROUTING_HDR = 43, /* Routing Header */ IPACM_FIREWALL_IPPROTO_FRAG_HDR = 44, /* Fragmentation Header */ IPACM_FIREWALL_IPPROTO_GRE = 47, /* GRE Protocol */ IPACM_FIREWALL_IPPROTO_ESP = 50, /* ESP Protocol */ IPACM_FIREWALL_IPPROTO_AH = 51, /* Authentication Header */ IPACM_FIREWALL_IPPROTO_ICMP6 = 58, /* ICMPv6 */ IPACM_FIREWALL_NO_NEXT_HDR = 59, /* No Next Header for IPv6 */ IPACM_FIREWALL_IPPROTO_DEST_OPT_HDR = 60, /* Destination Options Header */ IPACM_FIREWALL_IPPROTO_MOBILITY_HDR = 135, /* Mobility Header */ IPACM_FIREWALL_IPPROTO_TCP_UDP = 253 /* Unspecified protocol used for IPACM */ } ipacm_firewall_ip_protocol_enum_type; /* define as mobileap firewall rule format*/ typedef enum { IP_V4 = 4, IP_V6 = 6 } firewall_ip_version_enum; /*--------------------------------------------------------------------------- Extended FireWall Entry Configuration. ---------------------------------------------------------------------------*/ typedef struct { struct ipa_rule_attrib attrib; firewall_ip_version_enum ip_vsn; } IPACM_extd_firewall_entry_conf_t; /*--------------------------------------------------------------------------- Extended FireWall configuration. ---------------------------------------------------------------------------*/ typedef union { IPACM_extd_firewall_entry_conf_t extd_firewall_entry; } IPACM_extd_firewall_conf_t; typedef struct { char firewall_config_file[IPA_MAX_FILE_LEN]; uint8_t num_extd_firewall_entries; IPACM_extd_firewall_entry_conf_t extd_firewall_entries[IPACM_MAX_FIREWALL_ENTRIES]; bool rule_action_accept; bool firewall_enable; } IPACM_firewall_conf_t; typedef struct { uint8_t num_iface_entries; ipa_ifi_dev_name_t iface_entries[IPA_MAX_IFACE_ENTRIES]; } ipacm_iface_conf_t; typedef struct { uint8_t num_subnet_entries; ipa_private_subnet private_subnet_entries[IPA_MAX_PRIVATE_SUBNET_ENTRIES]; } ipacm_private_subnet_conf_t; typedef struct { uint8_t protocol; uint16_t port; } ipacm_alg; typedef struct { uint8_t num_alg_entries; ipacm_alg alg_entries[IPA_MAX_ALG_ENTRIES]; } ipacm_alg_conf_t; typedef struct _IPACM_conf_t { ipacm_iface_conf_t iface_config; ipacm_private_subnet_conf_t private_subnet_config; ipacm_alg_conf_t alg_config; int nat_max_entries; bool odu_enable; bool router_mode_enable; } IPACM_conf_t; /* This function read IPACM XML configuration*/ int ipacm_read_cfg_xml ( char *xml_file, /* Filename and path */ IPACM_conf_t *config /* Mobile AP config data */ ); /* This function reads QCMAP Firewall XML and store in IPACM Firewall stucture */ int IPACM_read_firewall_xml ( char *xml_file, /* Filename and path */ IPACM_firewall_conf_t *config /* Mobile AP config data */ ); #ifdef __cplusplus } #endif #endif //IPACM_XML ================================================ FILE: data-ipa-cfg-mgr/ipacm/src/Android.mk ================================================ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src LOCAL_C_INCLUDES += $(LOCAL_PATH)/../inc LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../ipanat/inc ifeq ($(call is-platform-sdk-version-at-least,20),true) LOCAL_C_INCLUDES += external/icu/icu4c/source/common else LOCAL_C_INCLUDES += external/icu4c/common endif LOCAL_C_INCLUDES += external/libxml2/include LOCAL_C_INCLUDES += external/libnetfilter_conntrack/include LOCAL_C_INCLUDES += external/libnfnetlink/include LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr LOCAL_CFLAGS := -v LOCAL_CFLAGS += -DFEATURE_IPA_ANDROID LOCAL_CFLAGS += -DDEBUG ifeq ($(TARGET_ARCH),arm) LOCAL_CFLAGS += -include bionic/libc/kernel/arch-arm/asm/posix_types.h LOCAL_CFLAGS += -include bionic/libc/kernel/arch-arm/asm/byteorder.h endif LOCAL_SRC_FILES := IPACM_Main.cpp \ IPACM_EvtDispatcher.cpp \ IPACM_Config.cpp \ IPACM_CmdQueue.cpp \ IPACM_Filtering.cpp \ IPACM_Routing.cpp \ IPACM_Header.cpp \ IPACM_Lan.cpp \ IPACM_Iface.cpp \ IPACM_Wlan.cpp \ IPACM_Wan.cpp \ IPACM_IfaceManager.cpp \ IPACM_Neighbor.cpp \ IPACM_Netlink.cpp \ IPACM_Xml.cpp \ IPACM_Conntrack_NATApp.cpp\ IPACM_ConntrackClient.cpp \ IPACM_ConntrackListener.cpp \ IPACM_Log.cpp LOCAL_MODULE := ipacm LOCAL_MODULE_TAGS := optional LOCAL_SHARED_LIBRARIES := libipanat LOCAL_SHARED_LIBRARIES += libxml2 LOCAL_SHARED_LIBRARIES += libnfnetlink LOCAL_SHARED_LIBRARIES += libnetfilter_conntrack include $(BUILD_EXECUTABLE) ################################################################################ define ADD_TEST include $(CLEAR_VARS) LOCAL_MODULE := $1 LOCAL_SRC_FILES := $1 LOCAL_MODULE_CLASS := ipacm LOCAL_MODULE_TAGS := debug LOCAL_MODULE_PATH := $(TARGET_OUT_ETC) include $(BUILD_PREBUILT) endef include $(CLEAR_VARS) LOCAL_MODULE := IPACM_cfg.xml LOCAL_MODULE_CLASS := ETC LOCAL_MODULE_PATH := $(TARGET_OUT_ETC) LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(LOCAL_MODULE) LOCAL_MODULE_OWNER := ipacm include $(BUILD_PREBUILT) ================================================ FILE: data-ipa-cfg-mgr/ipacm/src/IPACM_CmdQueue.cpp ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPACM_CmdQueue.cpp @brief This file implements the IPAM Comment Queue functionality @Author Sunil */ #include #include "IPACM_CmdQueue.h" #include "IPACM_Log.h" pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond_var = PTHREAD_COND_INITIALIZER; MessageQueue* MessageQueue::inst = NULL; MessageQueue* MessageQueue::getInstance() { if(inst == NULL) { inst = new MessageQueue(); if(inst == NULL) { IPACMERR("unable to create Message Queue instance\n"); return NULL; } } return inst; } void MessageQueue::enqueue(Message *item) { if(!Head) { Tail = item; Head = item; } else { if(Tail == NULL) { IPACMDBG("Tail is null\n"); Head->setnext(item); } else { Tail->setnext(item); } Tail = item; } } Message* MessageQueue::dequeue(void) { if(Head == NULL) { return NULL; } else { Message *tmp = Head; Head = Head->getnext(); return tmp; } } void* MessageQueue::Process(void *param) { MessageQueue *MsgQueue = NULL; Message *item = NULL; IPACMDBG("MessageQueue::Process()\n"); MsgQueue = MessageQueue::getInstance(); if(MsgQueue == NULL) { IPACMERR("unable to start cmd queue process\n"); return NULL; } while(1) { if(pthread_mutex_lock(&mutex) != 0) { IPACMERR("unable to lock the mutex\n"); return NULL; } item = MsgQueue->dequeue(); if(item == NULL) { IPACMDBG("Waiting for Message\n"); if(pthread_cond_wait(&cond_var, &mutex) != 0) { IPACMERR("unable to lock the mutex\n"); if(pthread_mutex_unlock(&mutex) != 0) { IPACMERR("unable to unlock the mutex\n"); return NULL; } return NULL; } if(pthread_mutex_unlock(&mutex) != 0) { IPACMERR("unable to unlock the mutex\n"); return NULL; } } else { if(pthread_mutex_unlock(&mutex) != 0) { IPACMERR("unable to unlock the mutex\n"); return NULL; } IPACMDBG("Processing item %p event ID: %d\n",item,item->evt.data.event); item->evt.callback_ptr(&item->evt.data); delete item; item = NULL; } } /* Go forever until a termination indication is received */ } ================================================ FILE: data-ipa-cfg-mgr/ipacm/src/IPACM_Config.cpp ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPACM_Config.cpp @brief This file implements the IPACM Configuration from XML file @Author Skylar Chang */ #include #include #include #include #include IPACM_Config *IPACM_Config::pInstance = NULL; const char *IPACM_Config::DEVICE_NAME = "/dev/ipa"; const char *IPACM_Config::DEVICE_NAME_ODU = "/dev/odu_ipa_bridge"; IPACM_Config::IPACM_Config() { iface_table = NULL; alg_table = NULL; memset(&ipa_client_rm_map_tbl, 0, sizeof(ipa_client_rm_map_tbl)); memset(&ipa_rm_tbl, 0, sizeof(ipa_rm_tbl)); ipa_rm_a2_check=0; ipacm_odu_enable = false; ipacm_odu_router_mode = false; ipa_num_ipa_interfaces = 0; ipa_num_private_subnet = 0; ipa_num_alg_ports = 0; ipa_nat_max_entries = 0; ipa_nat_iface_entries = 0; ipa_sw_rt_enable = false; memset(&rt_tbl_default_v4, 0, sizeof(rt_tbl_default_v4)); memset(&rt_tbl_lan_v4, 0, sizeof(rt_tbl_lan_v4)); memset(&rt_tbl_wan_v4, 0, sizeof(rt_tbl_wan_v4)); memset(&rt_tbl_v6, 0, sizeof(rt_tbl_v6)); memset(&rt_tbl_wan_v6, 0, sizeof(rt_tbl_wan_v6)); memset(&rt_tbl_wan_dl, 0, sizeof(rt_tbl_wan_dl)); memset(&rt_tbl_odu_v4, 0, sizeof(rt_tbl_odu_v4)); memset(&rt_tbl_odu_v6, 0, sizeof(rt_tbl_odu_v6)); memset(&ext_prop_v4, 0, sizeof(ext_prop_v4)); memset(&ext_prop_v6, 0, sizeof(ext_prop_v6)); memset(&rt_tbl_eth_bridge_usb_wlan_v4, 0, sizeof(rt_tbl_eth_bridge_usb_wlan_v4)); memset(&rt_tbl_eth_bridge_wlan_wlan_v4, 0, sizeof(rt_tbl_eth_bridge_wlan_wlan_v4)); memset(&rt_tbl_eth_bridge_usb_wlan_v6, 0, sizeof(rt_tbl_eth_bridge_usb_wlan_v6)); memset(&rt_tbl_eth_bridge_wlan_wlan_v6, 0, sizeof(rt_tbl_eth_bridge_wlan_wlan_v6)); qmap_id = ~0; IPACMDBG_H(" create IPACM_Config constructor\n"); return; } int IPACM_Config::Init(void) { /* Read IPACM Config file */ char IPACM_config_file[IPA_MAX_FILE_LEN]; IPACM_conf_t *cfg; cfg = (IPACM_conf_t *)malloc(sizeof(IPACM_conf_t)); if(cfg == NULL) { IPACMERR("Unable to allocate cfg memory.\n"); return IPACM_FAILURE; } uint32_t subnet_addr; uint32_t subnet_mask; int i, ret = IPACM_SUCCESS; struct in_addr in_addr_print; m_fd = open(DEVICE_NAME, O_RDWR); if (0 > m_fd) { IPACMERR("Failed opening %s.\n", DEVICE_NAME); } strncpy(IPACM_config_file, "/etc/IPACM_cfg.xml", sizeof(IPACM_config_file)); IPACMDBG_H("\n IPACM XML file is %s \n", IPACM_config_file); if (IPACM_SUCCESS == ipacm_read_cfg_xml(IPACM_config_file, cfg)) { IPACMDBG_H("\n IPACM XML read OK \n"); } else { IPACMERR("\n IPACM XML read failed \n"); ret = IPACM_FAILURE; goto fail; } /* Construct IPACM Iface table */ ipa_num_ipa_interfaces = cfg->iface_config.num_iface_entries; if (iface_table != NULL) { free(iface_table); iface_table = NULL; IPACMDBG_H("RESET IPACM_Config::iface_table\n"); } iface_table = (ipa_ifi_dev_name_t *)calloc(ipa_num_ipa_interfaces, sizeof(ipa_ifi_dev_name_t)); if(iface_table == NULL) { IPACMERR("Unable to allocate iface_table memory.\n"); ret = IPACM_FAILURE; goto fail; } for (i = 0; i < cfg->iface_config.num_iface_entries; i++) { strncpy(iface_table[i].iface_name, cfg->iface_config.iface_entries[i].iface_name, sizeof(iface_table[i].iface_name)); iface_table[i].if_cat = cfg->iface_config.iface_entries[i].if_cat; IPACMDBG_H("IPACM_Config::iface_table[%d] = %s, cat=%d\n", i, iface_table[i].iface_name, iface_table[i].if_cat); /* copy bridge interface name to ipacmcfg */ if( iface_table[i].if_cat == VIRTUAL_IF) { memcpy(ipa_virtual_iface_name, iface_table[i].iface_name, sizeof(ipa_virtual_iface_name)); IPACMDBG_H("ipa_virtual_iface_name(%s) \n", ipa_virtual_iface_name); } } /* Construct IPACM Private_Subnet table */ memset(&private_subnet_table, 0, sizeof(private_subnet_table)); ipa_num_private_subnet = cfg->private_subnet_config.num_subnet_entries; for (i = 0; i < cfg->private_subnet_config.num_subnet_entries; i++) { memcpy(&private_subnet_table[i].subnet_addr, &cfg->private_subnet_config.private_subnet_entries[i].subnet_addr, sizeof(cfg->private_subnet_config.private_subnet_entries[i].subnet_addr)); memcpy(&private_subnet_table[i].subnet_mask, &cfg->private_subnet_config.private_subnet_entries[i].subnet_mask, sizeof(cfg->private_subnet_config.private_subnet_entries[i].subnet_mask)); subnet_addr = htonl(private_subnet_table[i].subnet_addr); memcpy(&in_addr_print,&subnet_addr,sizeof(in_addr_print)); IPACMDBG_H("%dst::private_subnet_table= %s \n ", i, inet_ntoa(in_addr_print)); subnet_mask = htonl(private_subnet_table[i].subnet_mask); memcpy(&in_addr_print,&subnet_mask,sizeof(in_addr_print)); IPACMDBG_H("%dst::private_subnet_table= %s \n ", i, inet_ntoa(in_addr_print)); } /* Construct IPACM ALG table */ ipa_num_alg_ports = cfg->alg_config.num_alg_entries; if (alg_table != NULL) { free(alg_table); alg_table = NULL; IPACMDBG_H("RESET IPACM_Config::alg_table \n"); } alg_table = (ipacm_alg *)calloc(ipa_num_alg_ports, sizeof(ipacm_alg)); if(alg_table == NULL) { IPACMERR("Unable to allocate alg_table memory.\n"); ret = IPACM_FAILURE; free(iface_table); goto fail;; } for (i = 0; i < cfg->alg_config.num_alg_entries; i++) { alg_table[i].protocol = cfg->alg_config.alg_entries[i].protocol; alg_table[i].port = cfg->alg_config.alg_entries[i].port; IPACMDBG_H("IPACM_Config::ipacm_alg[%d] = %d, port=%d\n", i, alg_table[i].protocol, alg_table[i].port); } ipa_nat_max_entries = cfg->nat_max_entries; IPACMDBG_H("Nat Maximum Entries %d\n", ipa_nat_max_entries); /* Find ODU is either router mode or bridge mode*/ ipacm_odu_enable = cfg->odu_enable; ipacm_odu_router_mode = cfg->router_mode_enable; IPACMDBG_H("ipacm_odu_enable %d\n", ipacm_odu_enable); IPACMDBG_H("ipacm_odu_mode %d\n", ipacm_odu_router_mode); /* Allocate more non-nat entries if the monitored iface dun have Tx/Rx properties */ if (pNatIfaces != NULL) { free(pNatIfaces); pNatIfaces = NULL; IPACMDBG_H("RESET IPACM_Config::pNatIfaces \n"); } pNatIfaces = (NatIfaces *)calloc(ipa_num_ipa_interfaces, sizeof(NatIfaces)); if (pNatIfaces == NULL) { IPACMERR("unable to allocate nat ifaces\n"); ret = IPACM_FAILURE; free(iface_table); free(alg_table); goto fail; } /* Construct the routing table ictol name in iface static member*/ rt_tbl_default_v4.ip = IPA_IP_v4; strncpy(rt_tbl_default_v4.name, V4_DEFAULT_ROUTE_TABLE_NAME, sizeof(rt_tbl_default_v4.name)); rt_tbl_lan_v4.ip = IPA_IP_v4; strncpy(rt_tbl_lan_v4.name, V4_LAN_ROUTE_TABLE_NAME, sizeof(rt_tbl_lan_v4.name)); rt_tbl_wan_v4.ip = IPA_IP_v4; strncpy(rt_tbl_wan_v4.name, V4_WAN_ROUTE_TABLE_NAME, sizeof(rt_tbl_wan_v4.name)); rt_tbl_v6.ip = IPA_IP_v6; strncpy(rt_tbl_v6.name, V6_COMMON_ROUTE_TABLE_NAME, sizeof(rt_tbl_v6.name)); rt_tbl_wan_v6.ip = IPA_IP_v6; strncpy(rt_tbl_wan_v6.name, V6_WAN_ROUTE_TABLE_NAME, sizeof(rt_tbl_wan_v6.name)); rt_tbl_odu_v4.ip = IPA_IP_v4; strncpy(rt_tbl_odu_v4.name, V4_ODU_ROUTE_TABLE_NAME, sizeof(rt_tbl_odu_v4.name)); rt_tbl_odu_v6.ip = IPA_IP_v6; strncpy(rt_tbl_odu_v6.name, V6_ODU_ROUTE_TABLE_NAME, sizeof(rt_tbl_odu_v6.name)); rt_tbl_wan_dl.ip = IPA_IP_MAX; strncpy(rt_tbl_wan_dl.name, WAN_DL_ROUTE_TABLE_NAME, sizeof(rt_tbl_wan_dl.name)); rt_tbl_lan2lan_v4.ip = IPA_IP_v4; strncpy(rt_tbl_lan2lan_v4.name, V4_LAN_TO_LAN_ROUTE_TABLE_NAME, sizeof(rt_tbl_lan2lan_v4.name)); rt_tbl_lan2lan_v6.ip = IPA_IP_v6; strncpy(rt_tbl_lan2lan_v6.name, V6_LAN_TO_LAN_ROUTE_TABLE_NAME, sizeof(rt_tbl_lan2lan_v6.name)); rt_tbl_eth_bridge_usb_wlan_v4.ip = IPA_IP_v4; strncpy(rt_tbl_eth_bridge_usb_wlan_v4.name, ETH_BRIDGE_USB_WLAN_ROUTE_TABLE_NAME_V4, sizeof(rt_tbl_eth_bridge_usb_wlan_v4.name)); rt_tbl_eth_bridge_wlan_wlan_v4.ip = IPA_IP_v4; strncpy(rt_tbl_eth_bridge_wlan_wlan_v4.name, ETH_BRIDGE_WLAN_WLAN_ROUTE_TABLE_NAME_V4, sizeof(rt_tbl_eth_bridge_wlan_wlan_v4.name)); rt_tbl_eth_bridge_usb_wlan_v6.ip = IPA_IP_v6; strncpy(rt_tbl_eth_bridge_usb_wlan_v6.name, ETH_BRIDGE_USB_WLAN_ROUTE_TABLE_NAME_V6, sizeof(rt_tbl_eth_bridge_usb_wlan_v6.name)); rt_tbl_eth_bridge_wlan_wlan_v6.ip = IPA_IP_v6; strncpy(rt_tbl_eth_bridge_wlan_wlan_v6.name, ETH_BRIDGE_WLAN_WLAN_ROUTE_TABLE_NAME_V6, sizeof(rt_tbl_eth_bridge_wlan_wlan_v6.name)); /* Construct IPACM ipa_client map to rm_resource table */ ipa_client_rm_map_tbl[IPA_CLIENT_WLAN1_PROD]= IPA_RM_RESOURCE_WLAN_PROD; ipa_client_rm_map_tbl[IPA_CLIENT_USB_PROD]= IPA_RM_RESOURCE_USB_PROD; ipa_client_rm_map_tbl[IPA_CLIENT_A5_WLAN_AMPDU_PROD]= IPA_RM_RESOURCE_HSIC_PROD; ipa_client_rm_map_tbl[IPA_CLIENT_A2_EMBEDDED_PROD]= IPA_RM_RESOURCE_Q6_PROD; ipa_client_rm_map_tbl[IPA_CLIENT_A2_TETHERED_PROD]= IPA_RM_RESOURCE_Q6_PROD; ipa_client_rm_map_tbl[IPA_CLIENT_APPS_LAN_WAN_PROD]= IPA_RM_RESOURCE_Q6_PROD; ipa_client_rm_map_tbl[IPA_CLIENT_WLAN1_CONS]= IPA_RM_RESOURCE_WLAN_CONS; ipa_client_rm_map_tbl[IPA_CLIENT_WLAN2_CONS]= IPA_RM_RESOURCE_WLAN_CONS; ipa_client_rm_map_tbl[IPA_CLIENT_WLAN3_CONS]= IPA_RM_RESOURCE_WLAN_CONS; ipa_client_rm_map_tbl[IPA_CLIENT_WLAN4_CONS]= IPA_RM_RESOURCE_WLAN_CONS; ipa_client_rm_map_tbl[IPA_CLIENT_USB_CONS]= IPA_RM_RESOURCE_USB_CONS; ipa_client_rm_map_tbl[IPA_CLIENT_A2_EMBEDDED_CONS]= IPA_RM_RESOURCE_Q6_CONS; ipa_client_rm_map_tbl[IPA_CLIENT_A2_TETHERED_CONS]= IPA_RM_RESOURCE_Q6_CONS; ipa_client_rm_map_tbl[IPA_CLIENT_APPS_WAN_CONS]= IPA_RM_RESOURCE_Q6_CONS; /* Create the entries which IPACM wants to add dependencies on */ ipa_rm_tbl[0].producer_rm1 = IPA_RM_RESOURCE_WLAN_PROD; ipa_rm_tbl[0].consumer_rm1 = IPA_RM_RESOURCE_Q6_CONS; ipa_rm_tbl[0].producer_rm2 = IPA_RM_RESOURCE_Q6_PROD; ipa_rm_tbl[0].consumer_rm2 = IPA_RM_RESOURCE_WLAN_CONS; ipa_rm_tbl[1].producer_rm1 = IPA_RM_RESOURCE_USB_PROD; ipa_rm_tbl[1].consumer_rm1 = IPA_RM_RESOURCE_Q6_CONS; ipa_rm_tbl[1].producer_rm2 = IPA_RM_RESOURCE_Q6_PROD; ipa_rm_tbl[1].consumer_rm2 = IPA_RM_RESOURCE_USB_CONS; ipa_rm_tbl[2].producer_rm1 = IPA_RM_RESOURCE_WLAN_PROD; ipa_rm_tbl[2].consumer_rm1 = IPA_RM_RESOURCE_USB_CONS; ipa_rm_tbl[2].producer_rm2 = IPA_RM_RESOURCE_USB_PROD; ipa_rm_tbl[2].consumer_rm2 = IPA_RM_RESOURCE_WLAN_CONS; IPACMDBG_H(" depend MAP-0 rm index %d to rm index: %d \n", IPA_RM_RESOURCE_WLAN_PROD, IPA_RM_RESOURCE_Q6_CONS); IPACMDBG_H(" depend MAP-1 rm index %d to rm index: %d \n", IPA_RM_RESOURCE_USB_PROD, IPA_RM_RESOURCE_Q6_CONS); IPACMDBG_H(" depend MAP-2 rm index %d to rm index: %d \n", IPA_RM_RESOURCE_WLAN_PROD, IPA_RM_RESOURCE_USB_CONS); fail: if (cfg != NULL) { free(cfg); cfg = NULL; } return ret; } IPACM_Config* IPACM_Config::GetInstance() { int res = IPACM_SUCCESS; if (pInstance == NULL) { pInstance = new IPACM_Config(); res = pInstance->Init(); if (res != IPACM_SUCCESS) { delete pInstance; IPACMERR("unable to initialize config instance\n"); return NULL; } } return pInstance; } int IPACM_Config::GetAlgPorts(int nPorts, ipacm_alg *pAlgPorts) { if (nPorts <= 0 || pAlgPorts == NULL) { IPACMERR("Invalid input\n"); return -1; } for (int cnt = 0; cnt < nPorts; cnt++) { pAlgPorts[cnt].protocol = alg_table[cnt].protocol; pAlgPorts[cnt].port = alg_table[cnt].port; } return 0; } int IPACM_Config::GetNatIfaces(int nIfaces, NatIfaces *pIfaces) { if (nIfaces <= 0 || pIfaces == NULL) { IPACMERR("Invalid input\n"); return -1; } for (int cnt=0; cntnum_ext_props <= 0) { IPACMERR("There is no extended property!\n"); return IPACM_FAILURE; } num = prop->num_ext_props; for(i=0; iext[i].ip == IPA_IP_v4) { if(ext_prop_v4.num_ext_props >= MAX_NUM_EXT_PROPS) { IPACMDBG_H("IPv4 extended property table is full!\n"); continue; } memcpy(&ext_prop_v4.prop[ext_prop_v4.num_ext_props], &prop->ext[i], sizeof(struct ipa_ioc_ext_intf_prop)); ext_prop_v4.num_ext_props++; } else if(prop->ext[i].ip == IPA_IP_v6) { if(ext_prop_v6.num_ext_props >= MAX_NUM_EXT_PROPS) { IPACMDBG_H("IPv6 extended property table is full!\n"); continue; } memcpy(&ext_prop_v6.prop[ext_prop_v6.num_ext_props], &prop->ext[i], sizeof(struct ipa_ioc_ext_intf_prop)); ext_prop_v6.num_ext_props++; } else { IPACMERR("The IP type is not expected!\n"); return IPACM_FAILURE; } } IPACMDBG_H("Set extended property succeeded.\n"); return IPACM_SUCCESS; } ipacm_ext_prop* IPACM_Config::GetExtProp(ipa_ip_type ip_type) { if(ip_type == IPA_IP_v4) return &ext_prop_v4; else if(ip_type == IPA_IP_v6) return &ext_prop_v6; else { IPACMERR("Failed to get extended property: the IP version is neither IPv4 nor IPv6!\n"); return NULL; } } int IPACM_Config::DelExtProp(ipa_ip_type ip_type) { if(ip_type != IPA_IP_v6) { memset(&ext_prop_v4, 0, sizeof(ext_prop_v4)); } if(ip_type != IPA_IP_v4) { memset(&ext_prop_v6, 0, sizeof(ext_prop_v6)); } return IPACM_SUCCESS; } ================================================ FILE: data-ipa-cfg-mgr/ipacm/src/IPACM_ConntrackClient.cpp ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include "IPACM_Iface.h" #include "IPACM_ConntrackListener.h" #include "IPACM_ConntrackClient.h" #include "IPACM_Log.h" #define LO_NAME "lo" extern IPACM_EvtDispatcher cm_dis; extern void ParseCTMessage(struct nf_conntrack *ct); IPACM_ConntrackClient *IPACM_ConntrackClient::pInstance = NULL; IPACM_ConntrackListener *CtList = NULL; /* ================================ Local Function Definitions ================================= */ IPACM_ConntrackClient::IPACM_ConntrackClient() { IPACMDBG("\n"); tcp_hdl = NULL; udp_hdl = NULL; tcp_filter = NULL; udp_filter = NULL; } IPACM_ConntrackClient* IPACM_ConntrackClient::GetInstance() { if(pInstance == NULL) { pInstance = new IPACM_ConntrackClient(); pInstance->udp_filter = nfct_filter_create(); if(pInstance->udp_filter == NULL) { IPACMERR("unable to create UDP filter\n"); delete pInstance; return NULL; } IPACMDBG("Created UDP filter\n"); pInstance->tcp_filter = nfct_filter_create(); if(pInstance->tcp_filter == NULL) { IPACMERR("unable to create TCP filter\n"); delete pInstance; return NULL; } IPACMDBG("Created TCP filter\n"); } return pInstance; } int IPACM_ConntrackClient::IPAConntrackEventCB ( enum nf_conntrack_msg_type type, struct nf_conntrack *ct, void *data ) { ipacm_cmd_q_data evt_data; ipacm_ct_evt_data *ct_data; uint8_t ip_type = 0; IPACMDBG("Event callback called with msgtype: %d\n",type); /* Retrieve ip type */ ip_type = nfct_get_attr_u8(ct, ATTR_REPL_L3PROTO); #ifndef CT_OPT if(AF_INET6 == ip_type) { IPACMDBG("Ignoring ipv6(%d) connections\n", ip_type); goto IGNORE; } #endif ct_data = (ipacm_ct_evt_data *)malloc(sizeof(ipacm_ct_evt_data)); if(ct_data == NULL) { IPACMERR("unable to allocate memory \n"); goto IGNORE; } ct_data->ct = ct; ct_data->type = type; evt_data.event = IPA_PROCESS_CT_MESSAGE; evt_data.evt_data = (void *)ct_data; #ifdef CT_OPT if(AF_INET6 == ip_type) { evt_data.event = IPA_PROCESS_CT_MESSAGE_V6; } #endif if(0 != IPACM_EvtDispatcher::PostEvt(&evt_data)) { IPACMERR("Error sending Conntrack message to processing thread!\n"); free(ct_data); goto IGNORE; } /* NFCT_CB_STOLEN means that the conntrack object is not released after the callback That must be manually done later when the object is no longer needed. */ return NFCT_CB_STOLEN; IGNORE: nfct_destroy(ct); return NFCT_CB_STOLEN; } int IPACM_ConntrackClient::IPA_Conntrack_Filters_Ignore_Bridge_Addrs ( struct nfct_filter *filter ) { int fd; fd = socket(AF_INET, SOCK_DGRAM, 0); if(fd < 0) { PERROR("unable to open socket"); return -1; } int ret; uint32_t ipv4_addr; struct ifreq ifr; /* retrieve bridge interface ipv4 address */ memset(&ifr, 0, sizeof(struct ifreq)); ifr.ifr_addr.sa_family = AF_INET; (void)strncpy(ifr.ifr_name, IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, sizeof(ifr.ifr_name)); IPACMDBG("bridge interface name (%s)\n", ifr.ifr_name); ret = ioctl(fd, SIOCGIFADDR, &ifr); if (ret < 0) { IPACMERR("unable to retrieve (%s) interface address\n",ifr.ifr_name); close(fd); return -1; } IPACMDBG("Interface (%s) address %s\n", ifr.ifr_name, inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr)); ipv4_addr = ntohl(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr); close(fd); /* ignore whatever is destined to or originates from broadcast ip address */ struct nfct_filter_ipv4 filter_ipv4; filter_ipv4.addr = ipv4_addr; filter_ipv4.mask = 0xffffffff; nfct_filter_set_logic(filter, NFCT_FILTER_DST_IPV4, NFCT_FILTER_LOGIC_NEGATIVE); nfct_filter_add_attr(filter, NFCT_FILTER_DST_IPV4, &filter_ipv4); nfct_filter_set_logic(filter, NFCT_FILTER_SRC_IPV4, NFCT_FILTER_LOGIC_NEGATIVE); nfct_filter_add_attr(filter, NFCT_FILTER_SRC_IPV4, &filter_ipv4); return 0; } int IPACM_ConntrackClient::IPA_Conntrack_Filters_Ignore_Local_Iface ( struct nfct_filter *filter, ipacm_event_iface_up *param ) { struct nfct_filter_ipv4 filter_ipv4; filter_ipv4.addr = param->ipv4_addr; filter_ipv4.mask = 0xffffffff; /* ignore whatever is destined to local interfaces */ IPACMDBG("Ignore connections destinated to interface %s", param->ifname); iptodot("with ipv4 address", param->ipv4_addr); nfct_filter_set_logic(filter, NFCT_FILTER_DST_IPV4, NFCT_FILTER_LOGIC_NEGATIVE); nfct_filter_add_attr(filter, NFCT_FILTER_DST_IPV4, &filter_ipv4); IPACMDBG("Ignore connections orignated from interface %s", param->ifname); iptodot("with ipv4 address", filter_ipv4.addr); nfct_filter_set_logic(filter, NFCT_FILTER_SRC_IPV4, NFCT_FILTER_LOGIC_NEGATIVE); nfct_filter_add_attr(filter, NFCT_FILTER_SRC_IPV4, &filter_ipv4); /* Retrieve broadcast address */ /* Intialize with 255.255.255.255 */ uint32_t bc_ip_addr = 0xFFFFFFFF; /* calculate broadcast address from addr and addr_mask */ bc_ip_addr = (bc_ip_addr & (~param->addr_mask)); bc_ip_addr = (bc_ip_addr | (param->ipv4_addr & param->addr_mask)); /* netfitler expecting in host-byte order */ filter_ipv4.addr = bc_ip_addr; filter_ipv4.mask = 0xffffffff; iptodot("with broadcast address", filter_ipv4.addr); nfct_filter_set_logic(filter, NFCT_FILTER_DST_IPV4, NFCT_FILTER_LOGIC_NEGATIVE); nfct_filter_add_attr(filter, NFCT_FILTER_DST_IPV4, &filter_ipv4); return 0; } /* Function which sets up filters to ignore connections to and from local interfaces */ int IPACM_ConntrackClient::IPA_Conntrack_Filters_Ignore_Local_Addrs ( struct nfct_filter *filter ) { struct nfct_filter_ipv4 filter_ipv4; /* ignore whatever is destined to or originates from broadcast ip address */ filter_ipv4.addr = 0xffffffff; filter_ipv4.mask = 0xffffffff; nfct_filter_set_logic(filter, NFCT_FILTER_DST_IPV4, NFCT_FILTER_LOGIC_NEGATIVE); nfct_filter_add_attr(filter, NFCT_FILTER_DST_IPV4, &filter_ipv4); nfct_filter_set_logic(filter, NFCT_FILTER_SRC_IPV4, NFCT_FILTER_LOGIC_NEGATIVE); nfct_filter_add_attr(filter, NFCT_FILTER_SRC_IPV4, &filter_ipv4); return 0; } /* IPA_Conntrack_Filters_Ignore_Local_Addrs() */ /* Initialize TCP Filter */ int IPACM_ConntrackClient::IPA_Conntrack_TCP_Filter_Init(void) { int ret = 0; IPACM_ConntrackClient *pClient; IPACMDBG("\n"); pClient = IPACM_ConntrackClient::GetInstance(); if(pClient == NULL) { IPACMERR("unable to get conntrack client instance\n"); return -1; } ret = nfct_filter_set_logic(pClient->tcp_filter, NFCT_FILTER_L4PROTO, NFCT_FILTER_LOGIC_POSITIVE); if(ret == -1) { IPACMERR("Unable to set filter logic\n"); return -1; } /* set protocol filters as tcp and udp */ nfct_filter_add_attr_u32(pClient->tcp_filter, NFCT_FILTER_L4PROTO, IPPROTO_TCP); struct nfct_filter_proto tcp_proto_state; tcp_proto_state.proto = IPPROTO_TCP; tcp_proto_state.state = TCP_CONNTRACK_ESTABLISHED; ret = nfct_filter_set_logic(pClient->tcp_filter, NFCT_FILTER_L4PROTO_STATE, NFCT_FILTER_LOGIC_POSITIVE); if(ret == -1) { IPACMERR("unable to set filter logic\n"); return -1; } nfct_filter_add_attr(pClient->tcp_filter, NFCT_FILTER_L4PROTO_STATE, &tcp_proto_state); tcp_proto_state.proto = IPPROTO_TCP; tcp_proto_state.state = TCP_CONNTRACK_FIN_WAIT; ret = nfct_filter_set_logic(pClient->tcp_filter, NFCT_FILTER_L4PROTO_STATE, NFCT_FILTER_LOGIC_POSITIVE); if(ret == -1) { IPACMERR("unable to set filter logic\n"); return -1; } nfct_filter_add_attr(pClient->tcp_filter, NFCT_FILTER_L4PROTO_STATE, &tcp_proto_state); return 0; } /* Initialize UDP Filter */ int IPACM_ConntrackClient::IPA_Conntrack_UDP_Filter_Init(void) { int ret = 0; IPACM_ConntrackClient *pClient = IPACM_ConntrackClient::GetInstance(); if(pClient == NULL) { IPACMERR("unable to get conntrack client instance\n"); return -1; } ret = nfct_filter_set_logic(pClient->udp_filter, NFCT_FILTER_L4PROTO, NFCT_FILTER_LOGIC_POSITIVE); if(ret == -1) { IPACMERR("unable to set filter logic\n"); } /* set protocol filters as tcp and udp */ nfct_filter_add_attr_u32(pClient->udp_filter, NFCT_FILTER_L4PROTO, IPPROTO_UDP); return 0; } void* IPACM_ConntrackClient::UDPConnTimeoutUpdate(void *ptr) { NatApp *nat_inst = NULL; #ifdef IPACM_DEBUG IPACMDBG("\n"); #endif nat_inst = NatApp::GetInstance(); if(nat_inst == NULL) { IPACMERR("unable to create nat instance\n"); return NULL; } while(1) { nat_inst->UpdateUDPTimeStamp(); sleep(UDP_TIMEOUT_UPDATE); } /* end of while(1) loop */ #ifdef IPACM_DEBUG IPACMDBG("Returning from %s() %d\n", __FUNCTION__, __LINE__); #endif return NULL; } /* Thread to initialize TCP Conntrack Filters*/ void* IPACM_ConntrackClient::TCPRegisterWithConnTrack(void *) { int ret; IPACM_ConntrackClient *pClient; unsigned subscrips = 0; IPACMDBG("\n"); pClient = IPACM_ConntrackClient::GetInstance(); if(pClient == NULL) { IPACMERR("unable to get conntrack client instance\n"); return NULL; } subscrips = (NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY); #ifdef CT_OPT subscrips |= NF_NETLINK_CONNTRACK_NEW; #endif pClient->tcp_hdl = nfct_open(CONNTRACK, subscrips); if(pClient->tcp_hdl == NULL) { PERROR("nfct_open\n"); return NULL; } /* Initialize the filter */ ret = IPA_Conntrack_TCP_Filter_Init(); if(ret == -1) { IPACMERR("Unable to initliaze TCP Filter\n"); return NULL; } /* Attach the filter to net filter handler */ ret = nfct_filter_attach(nfct_fd(pClient->tcp_hdl), pClient->tcp_filter); if(ret == -1) { IPACMDBG("unable to attach TCP filter\n"); return NULL; } /* Register callback with netfilter handler */ IPACMDBG("tcp handle:%p, fd:%d\n", pClient->tcp_hdl, nfct_fd(pClient->tcp_hdl)); #ifndef CT_OPT nfct_callback_register(pClient->tcp_hdl, (nf_conntrack_msg_type) (NFCT_T_UPDATE | NFCT_T_DESTROY | NFCT_T_NEW), IPAConntrackEventCB, NULL); #else nfct_callback_register(pClient->tcp_hdl, (nf_conntrack_msg_type) NFCT_T_ALL, IPAConntrackEventCB, NULL); #endif /* Block to catch events from net filter connection track */ /* nfct_catch() receives conntrack events from kernel-space, by default it blocks waiting for events. */ IPACMDBG("Waiting for events\n"); ret = nfct_catch(pClient->tcp_hdl); if(ret == -1) { IPACMERR("(%d)(%s)\n", ret, strerror(errno)); return NULL; } IPACMDBG("Exit from tcp thread\n"); /* destroy the filter.. this will not detach the filter */ nfct_filter_destroy(pClient->tcp_filter); pClient->tcp_filter = NULL; /* de-register the callback */ nfct_callback_unregister(pClient->tcp_hdl); /* close the handle */ nfct_close(pClient->tcp_hdl); pClient->tcp_hdl = NULL; pthread_exit(NULL); return NULL; } /* Thread to initialize UDP Conntrack Filters*/ void* IPACM_ConntrackClient::UDPRegisterWithConnTrack(void *) { int ret; IPACM_ConntrackClient *pClient = NULL; IPACMDBG("\n"); pClient = IPACM_ConntrackClient::GetInstance(); if(pClient == NULL) { IPACMERR("unable to retrieve instance of conntrack client\n"); return NULL; } pClient->udp_hdl = nfct_open(CONNTRACK, (NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY)); if(pClient->udp_hdl == NULL) { PERROR("nfct_open\n"); return NULL; } /* Initialize Filter */ ret = IPA_Conntrack_UDP_Filter_Init(); if(-1 == ret) { IPACMDBG("Unable to initalize udp filters\n"); return NULL; } /* Attach the filter to net filter handler */ ret = nfct_filter_attach(nfct_fd(pClient->udp_hdl), pClient->udp_filter); if(ret == -1) { IPACMDBG("unable to attach the filter\n"); return NULL; } /* Register callback with netfilter handler */ IPACMDBG("udp handle:%p, fd:%d\n", pClient->udp_hdl, nfct_fd(pClient->udp_hdl)); nfct_callback_register(pClient->udp_hdl, (nf_conntrack_msg_type)(NFCT_T_NEW | NFCT_T_DESTROY), IPAConntrackEventCB, NULL); /* Block to catch events from net filter connection track */ ctcatch: ret = nfct_catch(pClient->udp_hdl); if(ret == -1) { IPACMDBG("(%d)(%s)\n", ret, strerror(errno)); return NULL; } else { IPACMDBG("ctcatch ret:%d\n", ret); goto ctcatch; } IPACMDBG("Exit from udp thread with ret: %d\n", ret); /* destroy the filter.. this will not detach the filter */ nfct_filter_destroy(pClient->udp_filter); pClient->udp_filter = NULL; /* de-register the callback */ nfct_callback_unregister(pClient->udp_hdl); /* close the handle */ nfct_close(pClient->udp_hdl); pClient->udp_hdl = NULL; pthread_exit(NULL); return NULL; } void IPACM_ConntrackClient::UpdateUDPFilters(void *param, bool isWan) { static bool isIgnore = false; int ret = 0; IPACM_ConntrackClient *pClient = NULL; pClient = IPACM_ConntrackClient::GetInstance(); if(pClient == NULL) { IPACMERR("unable to retrieve conntrack client instance\n"); return; } if(pClient->udp_filter == NULL) { return; } if(!isWan) { IPA_Conntrack_Filters_Ignore_Local_Iface(pClient->udp_filter, (ipacm_event_iface_up *)param); if(!isIgnore) { IPA_Conntrack_Filters_Ignore_Bridge_Addrs(pClient->udp_filter); IPA_Conntrack_Filters_Ignore_Local_Addrs(pClient->udp_filter); isIgnore = true; } } /* Attach the filter to udp handle */ if(pClient->udp_hdl != NULL) { IPACMDBG("attaching the filter to udp handle\n"); ret = nfct_filter_attach(nfct_fd(pClient->udp_hdl), pClient->udp_filter); if(ret == -1) { PERROR("unable to attach the filter to udp handle\n"); IPACMERR("udp handle:%p, fd:%d Error: %d\n",pClient->udp_hdl, nfct_fd(pClient->udp_hdl), ret); return; } } return; } void IPACM_ConntrackClient::UpdateTCPFilters(void *param, bool isWan) { static bool isIgnore = false; int ret = 0; IPACM_ConntrackClient *pClient = NULL; pClient = IPACM_ConntrackClient::GetInstance(); if(pClient == NULL) { IPACMERR("unable to retrieve conntrack client instance\n"); return; } if(pClient->tcp_filter == NULL) return; if(!isWan) { IPA_Conntrack_Filters_Ignore_Local_Iface(pClient->tcp_filter, (ipacm_event_iface_up *)param); if(!isIgnore) { IPA_Conntrack_Filters_Ignore_Bridge_Addrs(pClient->udp_filter); IPA_Conntrack_Filters_Ignore_Local_Addrs(pClient->udp_filter); isIgnore = true; } } /* Attach the filter to tcp handle */ if(pClient->tcp_hdl != NULL) { IPACMDBG("attaching the filter to tcp handle\n"); ret = nfct_filter_attach(nfct_fd(pClient->tcp_hdl), pClient->tcp_filter); if(ret == -1) { PERROR("unable to attach the filter to tcp handle\n"); IPACMERR("tcp handle:%p, fd:%d Error: %d\n",pClient->tcp_hdl, nfct_fd(pClient->tcp_hdl), ret); return; } } return; } void IPACM_ConntrackClient::Read_TcpUdp_Timeout(char *in, int len) { int proto; FILE *fd = NULL; char to_str[10]; uint32_t value; NatApp *nat_inst = NULL; nat_inst = NatApp::GetInstance(); if(nat_inst == NULL) { IPACMERR("unable to create nat instance\n"); return; } if(!strncmp(in, IPACM_TCP_FILE_NAME, len)) { proto = IPPROTO_TCP; } else if(!strncmp(in, IPACM_UDP_FILE_NAME, len)) { proto = IPPROTO_UDP; } else { return; } if(proto == IPPROTO_TCP) { fd = fopen(IPACM_TCP_FULL_FILE_NAME, "r"); } else { fd = fopen(IPACM_UDP_FULL_FILE_NAME, "r"); } if(fd == NULL) { PERROR("unable to open file"); return; } fgets(to_str, sizeof(to_str), fd); value = atoi(to_str); IPACMDBG("Protocol %d file \"%s\" value: %d\n", proto, in, value); nat_inst->UpdateTcpUdpTo(value, proto); fclose(fd); return; } void *IPACM_ConntrackClient::TCPUDP_Timeout_monitor(void *) { int length; int wd; char buffer[INOTIFY_BUFFER_LEN]; int inotify_fd; uint32_t mask = IN_MODIFY; FILE *to_fd = NULL; char to_str[10]; uint32_t value=0; NatApp *nat_inst = NULL; nat_inst = NatApp::GetInstance(); if(nat_inst == NULL) { IPACMERR("unable to create nat instance\n"); return NULL; } to_fd = fopen(IPACM_TCP_FULL_FILE_NAME, "r"); if(to_fd == NULL) { PERROR("unable to open file \"ip_conntrack_tcp_timeout_established\" "); return NULL; } memset(to_str, 0, sizeof(to_str)); fgets(to_str, sizeof(to_str), to_fd); value = atoi(to_str); IPACMDBG("ip conntrack tcp timeout initial value:%d\n", value); nat_inst->UpdateTcpUdpTo(value, IPPROTO_TCP); fclose(to_fd); to_fd = fopen(IPACM_UDP_FULL_FILE_NAME, "r"); if(to_fd == NULL) { PERROR("unable to open file \"ip_conntrack_udp_timeout_stream\" "); return NULL; } memset(to_str, 0, sizeof(to_str)); fgets(to_str, sizeof(to_str), to_fd); value = atoi(to_str); IPACMDBG("ip conntrack udp timeout:%d\n", value); nat_inst->UpdateTcpUdpTo(value, IPPROTO_UDP); fclose(to_fd); inotify_fd = inotify_init(); if (inotify_fd < 0) { PERROR("inotify_init"); return NULL; } IPACMDBG("Waiting for nofications in dir %s with mask: 0x%x\n", IPACM_TCP_UDP_DIR_NAME, mask); wd = inotify_add_watch(inotify_fd, IPACM_TCP_UDP_DIR_NAME, mask); while (1) { length = read(inotify_fd, buffer, INOTIFY_BUFFER_LEN); struct inotify_event *event = (struct inotify_event *)buffer; if (length < 0) { IPACMERR("inotify read() error return length: %d and mask: 0x%x 0x%x\n", length, event->mask, mask); return NULL; } if( (event->len > 0) && (event->mask & IN_MODIFY) ) { if(!(event->mask & IN_ISDIR)) { IPACMDBG("Received inotify event for file %s with mask %x value", event->name, event->mask); Read_TcpUdp_Timeout(event->name, event->len); } } } (void)inotify_rm_watch(inotify_fd, wd); (void)close(inotify_fd); return NULL; } ================================================ FILE: data-ipa-cfg-mgr/ipacm/src/IPACM_ConntrackListener.cpp ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include "IPACM_ConntrackListener.h" #include "IPACM_ConntrackClient.h" #include "IPACM_EvtDispatcher.h" IPACM_ConntrackListener::IPACM_ConntrackListener() { IPACMDBG("\n"); isNatThreadStart = false; isCTReg = false; WanUp = false; nat_inst = NatApp::GetInstance(); NatIfaceCnt = 0; StaClntCnt = 0; pNatIfaces = NULL; pConfig = NULL; memset(nat_iface_ipv4_addr, 0, sizeof(nat_iface_ipv4_addr)); memset(nonnat_iface_ipv4_addr, 0, sizeof(nonnat_iface_ipv4_addr)); memset(sta_clnt_ipv4_addr, 0, sizeof(sta_clnt_ipv4_addr)); IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP, this); IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN, this); IPACM_EvtDispatcher::registr(IPA_PROCESS_CT_MESSAGE, this); IPACM_EvtDispatcher::registr(IPA_PROCESS_CT_MESSAGE_V6, this); IPACM_EvtDispatcher::registr(IPA_HANDLE_WLAN_UP, this); IPACM_EvtDispatcher::registr(IPA_HANDLE_LAN_UP, this); #ifdef CT_OPT p_lan2lan = IPACM_LanToLan::getLan2LanInstance(); #endif } void IPACM_ConntrackListener::event_callback(ipa_cm_event_id evt, void *data) { ipacm_event_iface_up *wan_down = NULL; if(data == NULL) { IPACMERR("Invalid Data\n"); return; } switch(evt) { case IPA_PROCESS_CT_MESSAGE: IPACMDBG("Received IPA_PROCESS_CT_MESSAGE event\n"); ProcessCTMessage(data); break; #ifdef CT_OPT case IPA_PROCESS_CT_MESSAGE_V6: IPACMDBG("Received IPA_PROCESS_CT_MESSAGE_V6 event\n"); ProcessCTV6Message(data); break; #endif case IPA_HANDLE_WAN_UP: IPACMDBG("Received IPA_HANDLE_WAN_UP event\n"); CreateConnTrackThreads(); if(!isWanUp()) { TriggerWANUp(data); } break; case IPA_HANDLE_WAN_DOWN: IPACMDBG("Received IPA_HANDLE_WAN_DOWN event\n"); wan_down = (ipacm_event_iface_up *)data; if(isWanUp()) { TriggerWANDown(wan_down->ipv4_addr); } break; /* if wlan or lan comes up after wan interface, modify tcp/udp filters to ignore local wlan or lan connections */ case IPA_HANDLE_WLAN_UP: case IPA_HANDLE_LAN_UP: IPACMDBG("Received event: %d with ifname: %s and address: 0x%x\n", evt, ((ipacm_event_iface_up *)data)->ifname, ((ipacm_event_iface_up *)data)->ipv4_addr); CreateConnTrackThreads(); IPACM_ConntrackClient::UpdateUDPFilters(data, false); IPACM_ConntrackClient::UpdateTCPFilters(data, false); break; default: IPACMDBG("Ignore cmd %d\n", evt); break; } } void IPACM_ConntrackListener::HandleNeighIpAddrAddEvt(ipacm_event_data_all *data) { int fd = 0, len = 0, cnt, i, j; struct ifreq ifr; bool isNatIface = false; if(data->ipv4_addr == 0 || data->iptype != IPA_IP_v4) { IPACMDBG("Ignoring IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT EVENT\n"); return; } IPACMDBG("\n"); IPACMDBG("Received interface index %d with ip type: %d", data->if_index, data->iptype); iptodot(" and ipv4 address", data->ipv4_addr); if(pConfig == NULL) { pConfig = IPACM_Config::GetInstance(); if(pConfig == NULL) { IPACMERR("Unable to get Config instance\n"); return; } } cnt = pConfig->GetNatIfacesCnt(); NatIfaceCnt = cnt; if(pNatIfaces != NULL) { free(pNatIfaces); pNatIfaces = NULL; } len = (sizeof(NatIfaces) * NatIfaceCnt); pNatIfaces = (NatIfaces *)malloc(len); if(pNatIfaces == NULL) { IPACMERR("Unable to allocate memory for non nat ifaces\n"); return; } memset(pNatIfaces, 0, len); if(pConfig->GetNatIfaces(NatIfaceCnt, pNatIfaces) != 0) { IPACMERR("Unable to retrieve non nat ifaces\n"); return; } IPACMDBG("Update %d Nat ifaces\n", NatIfaceCnt); /* Search/Configure linux interface-index and map it to IPA interface-index */ if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { PERROR("get interface name socket create failed"); return; } memset(&ifr, 0, sizeof(struct ifreq)); ifr.ifr_ifindex = data->if_index; if(ioctl(fd, SIOCGIFNAME, &ifr) < 0) { PERROR("call_ioctl_on_dev: ioctl failed:"); close(fd); return; } close(fd); for(i = 0; i < NatIfaceCnt; i++) { if(strncmp(ifr.ifr_name, pNatIfaces[i].iface_name, sizeof(pNatIfaces[i].iface_name)) == 0) { /* copy the ipv4 address to filter out downlink connections ignore downlink after listening connection event from conntrack as it is not destinated to private ip address */ IPACMDBG("Interface (%s) is nat\n", ifr.ifr_name); for(j = 0; j < MAX_NAT_IFACES; j++) { /* check if duplicate NAT ip */ if(nat_iface_ipv4_addr[j] == data->ipv4_addr) break; if(nat_iface_ipv4_addr[j] == 0) { nat_iface_ipv4_addr[j] = data->ipv4_addr; nat_inst->ResetPwrSaveIf(data->ipv4_addr); nat_inst->FlushTempEntries(data->ipv4_addr, true); break; } } if(j == MAX_NAT_IFACES) { IPACMERR("Nat ifaces(%d) exceed maximum\n", j); break; } isNatIface = true; IPACMDBG("Nating connections of Interface (%s), entry (%d) ", pNatIfaces[i].iface_name, j); iptodot("with ipv4 address", nat_iface_ipv4_addr[j]); break; } } /* Cache the non nat iface ip address */ if(isNatIface != true) { for(i = 0; i < MAX_NAT_IFACES; i++) { if(nonnat_iface_ipv4_addr[i] == 0) { nonnat_iface_ipv4_addr[i] = data->ipv4_addr; nat_inst->FlushTempEntries(data->ipv4_addr, false); break; } } } } void IPACM_ConntrackListener::HandleNeighIpAddrDelEvt(uint32_t ipv4_addr) { int cnt; if(ipv4_addr == 0) { IPACMDBG("Ignoring IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT EVENT\n"); return; } IPACMDBG("\n"); iptodot("Received ip addr", ipv4_addr); IPACMDBG("Entering NAT entry deletion checking\n"); for(cnt = 0; cntFlushTempEntries(ipv4_addr, false); nat_inst->DelEntriesOnClntDiscon(ipv4_addr); return; } void IPACM_ConntrackListener::TriggerWANUp(void *in_param) { ipacm_event_iface_up *wanup_data = (ipacm_event_iface_up *)in_param; IPACMDBG("Recevied below information during wanup,\n"); IPACMDBG("if_name:%s, ipv4_address:0x%x\n", wanup_data->ifname, wanup_data->ipv4_addr); if(wanup_data->ipv4_addr == 0) { IPACMERR("Invalid ipv4 address,ignoring IPA_HANDLE_WAN_UP event\n"); return; } WanUp = true; isStaMode = wanup_data->is_sta; IPACMDBG("isStaMode: %d\n", isStaMode); wan_ipaddr = wanup_data->ipv4_addr; memcpy(wan_ifname, wanup_data->ifname, sizeof(wan_ifname)); if(nat_inst != NULL) { nat_inst->AddTable(wanup_data->ipv4_addr); } IPACMDBG("creating nat threads\n"); CreateNatThreads(); } int IPACM_ConntrackListener::CreateConnTrackThreads(void) { int ret; pthread_t tcp_thread = 0, udp_thread = 0; if(isCTReg == false) { if(!tcp_thread) { ret = pthread_create(&tcp_thread, NULL, IPACM_ConntrackClient::TCPRegisterWithConnTrack, NULL); if(0 != ret) { IPACMERR("unable to create TCP conntrack event listner thread\n"); PERROR("unable to create TCP conntrack\n"); return -1; } IPACMDBG("created TCP conntrack event listner thread\n"); } if(!udp_thread) { ret = pthread_create(&udp_thread, NULL, IPACM_ConntrackClient::UDPRegisterWithConnTrack, NULL); if(0 != ret) { IPACMERR("unable to create UDP conntrack event listner thread\n"); PERROR("unable to create UDP conntrack\n"); goto error; } IPACMDBG("created UDP conntrack event listner thread\n"); } isCTReg = true; } return 0; error: return -1; } int IPACM_ConntrackListener::CreateNatThreads(void) { int ret; pthread_t udpcto_thread = 0, to_monitor_thread = 0; if(isNatThreadStart == false) { if(!udpcto_thread) { ret = pthread_create(&udpcto_thread, NULL, IPACM_ConntrackClient::UDPConnTimeoutUpdate, NULL); if(0 != ret) { IPACMERR("unable to create udp conn timeout thread\n"); PERROR("unable to create udp conn timeout\n"); goto error; } IPACMDBG("created upd conn timeout thread\n"); } if(!to_monitor_thread) { ret = pthread_create(&to_monitor_thread, NULL, IPACM_ConntrackClient::TCPUDP_Timeout_monitor, NULL); if(0 != ret) { IPACMERR("unable to create tcp/udp timeout monitor thread\n"); PERROR("unable to create tcp/udp timeout monitor\n"); goto error; } IPACMDBG("created tcp/udp timeout monitor thread\n"); } isNatThreadStart = true; } return 0; error: return -1; } void IPACM_ConntrackListener::TriggerWANDown(uint32_t wan_addr) { IPACMDBG("Deleting ipv4 nat table with"); iptodot("public ip address", wan_addr); WanUp = false; if(nat_inst != NULL) { nat_inst->DeleteTable(wan_addr); } } void ParseCTMessage(struct nf_conntrack *ct) { uint32_t status, timeout; IPACMDBG("Printing conntrack parameters\n"); iptodot("ATTR_IPV4_SRC = ATTR_ORIG_IPV4_SRC:", nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_SRC)); iptodot("ATTR_IPV4_DST = ATTR_ORIG_IPV4_DST:", nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_DST)); IPACMDBG("ATTR_PORT_SRC = ATTR_ORIG_PORT_SRC: 0x%x\n", nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC)); IPACMDBG("ATTR_PORT_DST = ATTR_ORIG_PORT_DST: 0x%x\n", nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST)); iptodot("ATTR_REPL_IPV4_SRC:", nfct_get_attr_u32(ct, ATTR_REPL_IPV4_SRC)); iptodot("ATTR_REPL_IPV4_DST:", nfct_get_attr_u32(ct, ATTR_REPL_IPV4_DST)); IPACMDBG("ATTR_REPL_PORT_SRC: 0x%x\n", nfct_get_attr_u16(ct, ATTR_REPL_PORT_SRC)); IPACMDBG("ATTR_REPL_PORT_DST: 0x%x\n", nfct_get_attr_u16(ct, ATTR_REPL_PORT_DST)); iptodot("ATTR_SNAT_IPV4:", nfct_get_attr_u32(ct, ATTR_SNAT_IPV4)); iptodot("ATTR_DNAT_IPV4:", nfct_get_attr_u32(ct, ATTR_DNAT_IPV4)); IPACMDBG("ATTR_SNAT_PORT: 0x%x\n", nfct_get_attr_u16(ct, ATTR_SNAT_PORT)); IPACMDBG("ATTR_DNAT_PORT: 0x%x\n", nfct_get_attr_u16(ct, ATTR_DNAT_PORT)); IPACMDBG("ATTR_MARK: 0x%x\n", nfct_get_attr_u32(ct, ATTR_MARK)); IPACMDBG("ATTR_USE: 0x%x\n", nfct_get_attr_u32(ct, ATTR_USE)); IPACMDBG("ATTR_ID: 0x%x\n", nfct_get_attr_u32(ct, ATTR_ID)); status = nfct_get_attr_u32(ct, ATTR_STATUS); IPACMDBG("ATTR_STATUS: 0x%x\n", status); timeout = nfct_get_attr_u32(ct, ATTR_TIMEOUT); IPACMDBG("ATTR_TIMEOUT: 0x%x\n", timeout); if(IPS_SRC_NAT & status) { IPACMDBG("IPS_SRC_NAT set\n"); } if(IPS_DST_NAT & status) { IPACMDBG("IPS_DST_NAT set\n"); } if(IPS_SRC_NAT_DONE & status) { IPACMDBG("IPS_SRC_NAT_DONE set\n"); } if(IPS_DST_NAT_DONE & status) { IPACMDBG(" IPS_DST_NAT_DONE set\n"); } IPACMDBG("\n"); return; } void ParseCTV6Message(struct nf_conntrack *ct) { uint32_t status, timeout, secmark; struct nfct_attr_grp_ipv6 orig_params; uint8_t l4proto, tcp_flags, tcp_state; IPACMDBG("Printing conntrack parameters\n"); nfct_get_attr_grp(ct, ATTR_GRP_ORIG_IPV6, (void *)&orig_params); IPACMDBG("Orig src_v6_addr: 0x%08x%08x%08x%08x\n", orig_params.src[0], orig_params.src[1], orig_params.src[2], orig_params.src[3]); IPACMDBG("Orig dst_v6_addr: 0x%08x%08x%08x%08x\n", orig_params.dst[0], orig_params.dst[1], orig_params.dst[2], orig_params.dst[3]); IPACMDBG("ATTR_PORT_SRC = ATTR_ORIG_PORT_SRC: 0x%x\n", nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC)); IPACMDBG("ATTR_PORT_DST = ATTR_ORIG_PORT_DST: 0x%x\n", nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST)); IPACMDBG("ATTR_MARK: 0x%x\n", nfct_get_attr_u32(ct, ATTR_MARK)); IPACMDBG("ATTR_USE: 0x%x\n", nfct_get_attr_u32(ct, ATTR_USE)); IPACMDBG("ATTR_ID: 0x%x\n", nfct_get_attr_u32(ct, ATTR_ID)); timeout = nfct_get_attr_u32(ct, ATTR_TIMEOUT); IPACMDBG("ATTR_TIMEOUT: 0x%x\n", timeout); status = nfct_get_attr_u32(ct, ATTR_STATUS); IPACMDBG("ATTR_STATUS: 0x%x\n", status); l4proto = nfct_get_attr_u8(ct, ATTR_ORIG_L4PROTO); IPACMDBG("ATTR_ORIG_L4PROTO: 0x%x\n", l4proto); if(l4proto == IPPROTO_TCP) { tcp_state = nfct_get_attr_u8(ct, ATTR_TCP_STATE); IPACMDBG("ATTR_TCP_STATE: 0x%x\n", tcp_state); tcp_flags = nfct_get_attr_u8(ct, ATTR_TCP_FLAGS_ORIG); IPACMDBG("ATTR_TCP_FLAGS_ORIG: 0x%x\n", tcp_flags); } IPACMDBG("\n"); return; } #ifdef CT_OPT void IPACM_ConntrackListener::ProcessCTV6Message(void *param) { ipacm_ct_evt_data *evt_data = (ipacm_ct_evt_data *)param; u_int8_t l4proto = 0; uint32_t status = 0; struct nf_conntrack *ct = evt_data->ct; #ifdef IPACM_DEBUG char buf[1024]; /* Process message and generate ioctl call to kernel thread */ nfct_snprintf(buf, sizeof(buf), evt_data->ct, evt_data->type, NFCT_O_PLAIN, NFCT_OF_TIME); IPACMDBG("%s\n", buf); IPACMDBG("\n"); ParseCTV6Message(ct); #endif if(p_lan2lan == NULL) { IPACMERR("Lan2Lan Instance is null\n"); goto IGNORE; } status = nfct_get_attr_u32(ct, ATTR_STATUS); if((IPS_DST_NAT & status) || (IPS_SRC_NAT & status)) { IPACMDBG("Either Destination or Source nat flag Set\n"); goto IGNORE; } l4proto = nfct_get_attr_u8(ct, ATTR_ORIG_L4PROTO); if(IPPROTO_UDP != l4proto && IPPROTO_TCP != l4proto) { IPACMDBG("Received unexpected protocl %d conntrack message\n", l4proto); goto IGNORE; } IPACMDBG("Neither Destination nor Source nat flag Set\n"); struct nfct_attr_grp_ipv6 orig_params; nfct_get_attr_grp(ct, ATTR_GRP_ORIG_IPV6, (void *)&orig_params); ipacm_event_connection lan2lan_conn; lan2lan_conn.iptype = IPA_IP_v6; memcpy(lan2lan_conn.src_ipv6_addr, orig_params.src, sizeof(lan2lan_conn.src_ipv6_addr)); IPACMDBG("Before convert, src_v6_addr: 0x%08x%08x%08x%08x\n", lan2lan_conn.src_ipv6_addr[0], lan2lan_conn.src_ipv6_addr[1], lan2lan_conn.src_ipv6_addr[2], lan2lan_conn.src_ipv6_addr[3]); for(int cnt=0; cnt<4; cnt++) { lan2lan_conn.src_ipv6_addr[cnt] = ntohl(lan2lan_conn.src_ipv6_addr[cnt]); } IPACMDBG("After convert src_v6_addr: 0x%08x%08x%08x%08x\n", lan2lan_conn.src_ipv6_addr[0], lan2lan_conn.src_ipv6_addr[1], lan2lan_conn.src_ipv6_addr[2], lan2lan_conn.src_ipv6_addr[3]); memcpy(lan2lan_conn.dst_ipv6_addr, orig_params.dst, sizeof(lan2lan_conn.dst_ipv6_addr)); IPACMDBG("Before convert, dst_ipv6_addr: 0x%08x%08x%08x%08x\n", lan2lan_conn.dst_ipv6_addr[0], lan2lan_conn.dst_ipv6_addr[1], lan2lan_conn.dst_ipv6_addr[2], lan2lan_conn.dst_ipv6_addr[3]); for(int cnt=0; cnt<4; cnt++) { lan2lan_conn.dst_ipv6_addr[cnt] = ntohl(lan2lan_conn.dst_ipv6_addr[cnt]); } IPACMDBG("After convert, dst_ipv6_addr: 0x%08x%08x%08x%08x\n", lan2lan_conn.dst_ipv6_addr[0], lan2lan_conn.dst_ipv6_addr[1], lan2lan_conn.dst_ipv6_addr[2], lan2lan_conn.dst_ipv6_addr[3]); if(((IPPROTO_UDP == l4proto) && (NFCT_T_NEW == evt_data->type)) || ((IPPROTO_TCP == l4proto) && (nfct_get_attr_u8(ct, ATTR_TCP_STATE) == TCP_CONNTRACK_ESTABLISHED)) ) { p_lan2lan->handle_new_connection(&lan2lan_conn); } else if((IPPROTO_UDP == l4proto && NFCT_T_DESTROY == evt_data->type) || (IPPROTO_TCP == l4proto && nfct_get_attr_u8(ct, ATTR_TCP_STATE) == TCP_CONNTRACK_FIN_WAIT)) { p_lan2lan->handle_del_connection(&lan2lan_conn); } IGNORE: /* Cleanup item that was allocated during the original CT callback */ nfct_destroy(ct); return; } #endif void IPACM_ConntrackListener::ProcessCTMessage(void *param) { ipacm_ct_evt_data *evt_data = (ipacm_ct_evt_data *)param; u_int8_t l4proto = 0; #ifdef IPACM_DEBUG char buf[1024]; unsigned int out_flags; /* Process message and generate ioctl call to kernel thread */ out_flags = (NFCT_OF_SHOW_LAYER3 | NFCT_OF_TIME | NFCT_OF_ID); nfct_snprintf(buf, sizeof(buf), evt_data->ct, evt_data->type, NFCT_O_PLAIN, out_flags); IPACMDBG("%s\n", buf); IPACMDBG("\n"); ParseCTMessage(evt_data->ct); #endif l4proto = nfct_get_attr_u8(evt_data->ct, ATTR_ORIG_L4PROTO); if(IPPROTO_UDP != l4proto && IPPROTO_TCP != l4proto) { IPACMDBG("Received unexpected protocl %d conntrack message\n", l4proto); } else { ProcessTCPorUDPMsg(evt_data->ct, evt_data->type, l4proto); } /* Cleanup item that was allocated during the original CT callback */ nfct_destroy(evt_data->ct); return; } /* conntrack send in host order and ipa expects in host order */ void IPACM_ConntrackListener::ProcessTCPorUDPMsg( struct nf_conntrack *ct, enum nf_conntrack_msg_type type, u_int8_t l4proto) { nat_table_entry rule; u_int8_t tcp_state; uint32_t status = 0; IPACM_Config *pConfig; uint32_t orig_src_ip, orig_dst_ip; bool isTempEntry = false; memset(&rule, 0, sizeof(rule)); pConfig = IPACM_Config::GetInstance(); if(pConfig == NULL) { IPACMERR("Unable to get Config instance\n"); } IPACMDBG("Received type:%d with proto:%d\n", type, l4proto); status = nfct_get_attr_u32(ct, ATTR_STATUS); /* Retrieve Protocol */ rule.protocol = nfct_get_attr_u8(ct, ATTR_REPL_L4PROTO); if(IPS_DST_NAT & status) { status = IPS_DST_NAT; } else if(IPS_SRC_NAT & status) { status = IPS_SRC_NAT; } else { IPACMDBG("Neither Destination nor Source nat flag Set\n"); orig_src_ip = nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_SRC); orig_src_ip = ntohl(orig_src_ip); if(orig_src_ip == 0) { IPACMERR("unable to retrieve orig src ip address\n"); return; } orig_dst_ip = nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_DST); orig_dst_ip = ntohl(orig_dst_ip); if(orig_dst_ip == 0) { IPACMERR("unable to retrieve orig dst ip address\n"); return; } if(orig_src_ip == wan_ipaddr) { IPACMDBG("orig src ip:0x%x equal to wan ip\n",orig_src_ip); status = IPS_SRC_NAT; rule.public_ip = wan_ipaddr; } else if(orig_dst_ip == wan_ipaddr) { IPACMDBG("orig Dst IP:0x%x equal to wan ip\n",orig_dst_ip); status = IPS_DST_NAT; rule.public_ip = wan_ipaddr; } else { IPACMDBG("Neither orig src ip:0x%x Nor orig Dst IP:0x%x equal to wan ip:0x%x\n", orig_src_ip, orig_dst_ip, wan_ipaddr); #ifdef CT_OPT if(p_lan2lan == NULL) { IPACMERR("Lan2Lan Instance is null\n"); goto IGNORE; } ipacm_event_connection lan2lan_conn = { 0 }; lan2lan_conn.iptype = IPA_IP_v4; lan2lan_conn.src_ipv4_addr = orig_src_ip; lan2lan_conn.dst_ipv4_addr = orig_dst_ip; if(((IPPROTO_UDP == rule.protocol) && (NFCT_T_NEW == type)) || ((IPPROTO_TCP == rule.protocol) && (nfct_get_attr_u8(ct, ATTR_TCP_STATE) == TCP_CONNTRACK_ESTABLISHED))) { p_lan2lan->handle_new_connection(&lan2lan_conn); } else if((IPPROTO_UDP == rule.protocol && NFCT_T_DESTROY == type) || (IPPROTO_TCP == rule.protocol && nfct_get_attr_u8(ct, ATTR_TCP_STATE) == TCP_CONNTRACK_FIN_WAIT)) { p_lan2lan->handle_del_connection(&lan2lan_conn); } #endif return; } } if(IPS_DST_NAT == status) { IPACMDBG("Destination NAT\n"); rule.dst_nat = true; IPACMDBG("Parse reply tuple\n"); rule.target_ip = nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_SRC); rule.target_ip = ntohl(rule.target_ip); /* Retriev target/dst port */ rule.target_port = nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC); rule.target_port = ntohs(rule.target_port); if(0 == rule.target_port) { IPACMDBG("unable to retrieve target port\n"); } rule.public_port = nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST); rule.public_port = ntohs(rule.public_port); /* Retriev src/private ip address */ rule.private_ip = nfct_get_attr_u32(ct, ATTR_REPL_IPV4_SRC); rule.private_ip = ntohl(rule.private_ip); if(0 == rule.private_ip) { IPACMDBG("unable to retrieve private ip address\n"); } /* Retriev src/private port */ rule.private_port = nfct_get_attr_u16(ct, ATTR_REPL_PORT_SRC); rule.private_port = ntohs(rule.private_port); if(0 == rule.private_port) { IPACMDBG("unable to retrieve private port\n"); } } else if(IPS_SRC_NAT == status) { IPACMDBG("Source NAT\n"); rule.dst_nat = false; /* Retriev target/dst ip address */ IPACMDBG("Parse source tuple\n"); rule.target_ip = nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_DST); rule.target_ip = ntohl(rule.target_ip); if(0 == rule.target_ip) { IPACMDBG("unable to retrieve target ip address\n"); } /* Retriev target/dst port */ rule.target_port = nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST); rule.target_port = ntohs(rule.target_port); if(0 == rule.target_port) { IPACMDBG("unable to retrieve target port\n"); } /* Retriev public port */ rule.public_port = nfct_get_attr_u16(ct, ATTR_REPL_PORT_DST); rule.public_port = ntohs(rule.public_port); if(0 == rule.public_port) { IPACMDBG("unable to retrieve public port\n"); } /* Retriev src/private ip address */ rule.private_ip = nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_SRC); rule.private_ip = ntohl(rule.private_ip); if(0 == rule.private_ip) { IPACMDBG("unable to retrieve private ip address\n"); } /* Retriev src/private port */ rule.private_port = nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC); rule.private_port = ntohs(rule.private_port); if(0 == rule.private_port) { IPACMDBG("unable to retrieve private port\n"); } } else { IPACMDBG("Neither source Nor destination nat\n"); goto IGNORE; } if(rule.private_ip != wan_ipaddr) { int cnt; for(cnt = 0; cnt < MAX_NAT_IFACES; cnt++) { if(nat_iface_ipv4_addr[cnt] != 0) { if(rule.private_ip == nat_iface_ipv4_addr[cnt] || rule.target_ip == nat_iface_ipv4_addr[cnt]) { IPACMDBG("matched nat_iface_ipv4_addr entry(%d)\n", cnt); iptodot("ProcessTCPorUDPMsg(): Nat entry match with ip addr", nat_iface_ipv4_addr[cnt]); break; } } } if(cnt == MAX_NAT_IFACES) { IPACMDBG("Not mtaching with nat ifaces\n") if(pConfig == NULL) { goto IGNORE; } if(pConfig->isPrivateSubnet(rule.private_ip) || pConfig->isPrivateSubnet(rule.target_ip)) { IPACMDBG("Matching with Private subnet\n"); isTempEntry = true; } else { goto IGNORE; } } } else { if(isStaMode) { IPACMDBG("In STA mode, ignore connections destinated to STA interface\n"); goto IGNORE; } IPACMDBG("For embedded connections add dummy nat rule\n"); IPACMDBG("Change private port %d to %d\n", rule.private_port, rule.public_port); rule.private_port = rule.public_port; } /* Check whether target is in STA client list or not if not ignore the connection */ int nCnt; if(!isStaMode || (StaClntCnt == 0)) { goto ADD; } if((sta_clnt_ipv4_addr[0] & 0xFFFFFF00) != (rule.target_ip & 0xFFFFFF00)) { IPACMDBG("STA client subnet mask not matching\n"); goto ADD; } IPACMDBG("StaClntCnt %d\n", StaClntCnt); for(nCnt = 0; nCnt < StaClntCnt; nCnt++) { IPACMDBG("Comparing trgt_ip 0x%x with sta clnt ip: 0x%x\n", rule.target_ip, sta_clnt_ipv4_addr[nCnt]); if(rule.target_ip == sta_clnt_ipv4_addr[nCnt]) { IPACMDBG("Match index %d\n", nCnt); goto ADD; } } IPACMDBG("Not matching with STA Clnt Ip Addrs 0x%x\n", rule.target_ip); goto IGNORE; ADD: IPACMDBG("Nat Entry with below information will either be added or deleted\n"); iptodot("target ip or dst ip", rule.target_ip); IPACMDBG("target port or dst port: 0x%x Decimal:%d\n", rule.target_port, rule.target_port); iptodot("private ip or src ip", rule.private_ip); IPACMDBG("private port or src port: 0x%x, Decimal:%d\n", rule.private_port, rule.private_port); IPACMDBG("public port or reply dst port: 0x%x, Decimal:%d\n", rule.public_port, rule.public_port); IPACMDBG("Protocol: %d, destination nat flag: %d\n", rule.protocol, rule.dst_nat); if(IPPROTO_TCP == rule.protocol) { if(nat_inst == NULL) { return; } tcp_state = nfct_get_attr_u8(ct, ATTR_TCP_STATE); if(TCP_CONNTRACK_ESTABLISHED == tcp_state) { IPACMDBG("TCP state TCP_CONNTRACK_ESTABLISHED(%d)\n", tcp_state); if(!CtList->isWanUp()) { IPACMDBG("Wan is not up, cache connections\n"); nat_inst->CacheEntry(&rule); } else if(isTempEntry) { nat_inst->AddTempEntry(&rule); } else { nat_inst->AddEntry(&rule); } } else if(TCP_CONNTRACK_FIN_WAIT == tcp_state || type == NFCT_T_DESTROY) { IPACMDBG("TCP state TCP_CONNTRACK_FIN_WAIT(%d) " "or type NFCT_T_DESTROY(%d)\n", tcp_state, type); if(isTempEntry) { nat_inst->DeleteTempEntry(&rule); } else { nat_inst->DeleteEntry(&rule); } } else { IPACMDBG("Ignore tcp state: %d and type: %d\n", tcp_state, type); } } else if(IPPROTO_UDP == rule.protocol) { if(nat_inst == NULL) { return; } if(NFCT_T_NEW == type) { IPACMDBG("New UDP connection at time %ld\n", time(NULL)); if(!CtList->isWanUp()) { IPACMDBG("Wan is not up, cache connections\n"); nat_inst->CacheEntry(&rule); } else if(isTempEntry) { nat_inst->AddTempEntry(&rule); } else { nat_inst->AddEntry(&rule); } } else if(NFCT_T_DESTROY == type) { IPACMDBG("UDP connection close at time %ld\n", time(NULL)); if(isTempEntry) { nat_inst->DeleteTempEntry(&rule); } else { nat_inst->DeleteEntry(&rule); } } } else { IPACMDBG("Ignore protocol: %d and type: %d\n", rule.protocol, type); } return; IGNORE: IPACMDBG("ignoring below Nat Entry\n"); iptodot("target ip or dst ip", rule.target_ip); IPACMDBG("target port or dst port: 0x%x Decimal:%d\n", rule.target_port, rule.target_port); iptodot("private ip or src ip", rule.private_ip); IPACMDBG("private port or src port: 0x%x, Decimal:%d\n", rule.private_port, rule.private_port); IPACMDBG("public port or reply dst port: 0x%x, Decimal:%d\n", rule.public_port, rule.public_port); IPACMDBG("Protocol: %d, destination nat flag: %d\n", rule.protocol, rule.dst_nat); return; } void IPACM_ConntrackListener::HandleSTAClientAddEvt(uint32_t clnt_ip_addr) { int cnt; IPACMDBG("Received STA client 0x%x\n", clnt_ip_addr); if(StaClntCnt >= MAX_STA_CLNT_IFACES) { IPACMDBG("Max STA client reached, ignore 0x%x\n", clnt_ip_addr); return; } for(cnt=0; cntDelEntriesOnSTAClntDiscon(clnt_ip_addr); StaClntCnt--; IPACMDBG("STA client cnt %d\n", StaClntCnt); break; } } return; } ================================================ FILE: data-ipa-cfg-mgr/ipacm/src/IPACM_Conntrack_NATApp.cpp ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "IPACM_Conntrack_NATApp.h" #include "IPACM_ConntrackClient.h" #define INVALID_IP_ADDR 0x0 /* NatApp class Implementation */ NatApp *NatApp::pInstance = NULL; NatApp::NatApp() { max_entries = 0; cache = NULL; nat_table_hdl = 0; pub_ip_addr = 0; curCnt = 0; pALGPorts = NULL; nALGPort = 0; ct = NULL; ct_hdl = NULL; memset(temp, 0, sizeof(temp)); } int NatApp::Init(void) { IPACM_Config *pConfig; int size = 0; pConfig = IPACM_Config::GetInstance(); if(pConfig == NULL) { IPACMERR("Unable to get Config instance\n"); return -1; } max_entries = pConfig->GetNatMaxEntries(); size = (sizeof(nat_table_entry) * max_entries); cache = (nat_table_entry *)malloc(size); if(cache == NULL) { IPACMERR("Unable to allocate memory for cache\n"); goto fail; } IPACMDBG("Allocated %d bytes for config manager nat cache\n", size); memset(cache, 0, size); nALGPort = pConfig->GetAlgPortCnt(); pALGPorts = (ipacm_alg *)malloc(sizeof(ipacm_alg) * nALGPort); if(pALGPorts == NULL) { IPACMERR("Unable to allocate memory for alg prots\n"); goto fail; } memset(pALGPorts, 0, sizeof(ipacm_alg) * nALGPort); if(pConfig->GetAlgPorts(nALGPort, pALGPorts) != 0) { IPACMERR("Unable to retrieve ALG prots\n"); goto fail; } IPACMDBG("Printing %d alg ports information\n", nALGPort); for(int cnt=0; cntInit()) { delete pInstance; return NULL; } } return pInstance; } /* NAT APP related object function definitions */ int NatApp::AddTable(uint32_t pub_ip) { int ret; int cnt = 0; ipa_nat_ipv4_rule nat_rule; IPACMDBG("%s() %d\n", __FUNCTION__, __LINE__); /* Not reset the cache wait it timeout by destroy event */ #if 0 if (pub_ip != pub_ip_addr_pre) { IPACMDBG("Reset the cache because NAT-ipv4 different\n"); memset(cache, 0, sizeof(nat_table_entry) * max_entries); curCnt = 0; } #endif ret = ipa_nat_add_ipv4_tbl(pub_ip, max_entries, &nat_table_hdl); if(ret) { IPACMERR("unable to create nat table Error:%d\n", ret); return ret; } /* Add back the cashed NAT-entry */ if (pub_ip == pub_ip_addr_pre) { IPACMDBG("Restore the cache to ipa NAT-table\n"); for(cnt = 0; cnt < max_entries; cnt++) { if(cache[cnt].private_ip !=0) { memset(&nat_rule, 0 , sizeof(nat_rule)); nat_rule.private_ip = cache[cnt].private_ip; nat_rule.target_ip = cache[cnt].target_ip; nat_rule.target_port = cache[cnt].target_port; nat_rule.private_port = cache[cnt].private_port; nat_rule.public_port = cache[cnt].public_port; nat_rule.protocol = cache[cnt].protocol; if(ipa_nat_add_ipv4_rule(nat_table_hdl, &nat_rule, &cache[cnt].rule_hdl) < 0) { IPACMERR("unable to add the rule delete from cache\n"); memset(&cache[cnt], 0, sizeof(cache[cnt])); curCnt--; continue; } cache[cnt].enabled = true; IPACMDBG("On wan-iface reset added below rule successfully\n"); iptodot("Private IP", nat_rule.private_ip); iptodot("Target IP", nat_rule.target_ip); IPACMDBG("Private Port:%d \t Target Port: %d\t", nat_rule.private_port, nat_rule.target_port); IPACMDBG("Public Port:%d\n", nat_rule.public_port); IPACMDBG("protocol: %d\n", nat_rule.protocol); } } } pub_ip_addr = pub_ip; return 0; } void NatApp::Reset() { int cnt = 0; nat_table_hdl = 0; pub_ip_addr = 0; /* NAT tbl deleted, reset enabled bit */ for(cnt = 0; cnt < max_entries; cnt++) { cache[cnt].enabled ==false; } } int NatApp::DeleteTable(uint32_t pub_ip) { int ret; IPACMDBG("%s() %d\n", __FUNCTION__, __LINE__); CHK_TBL_HDL(); if(pub_ip_addr != pub_ip) { IPACMDBG("Public ip address is not matching\n"); IPACMERR("unable to delete the nat table\n"); return -1; } ret = ipa_nat_del_ipv4_tbl(nat_table_hdl); if(ret) { IPACMERR("unable to delete nat table Error: %d\n", ret);; return ret; } pub_ip_addr_pre = pub_ip_addr; Reset(); return 0; } /* Check for duplicate entries */ bool NatApp::ChkForDup(const nat_table_entry *rule) { int cnt = 0; IPACMDBG("%s() %d\n", __FUNCTION__, __LINE__); for(; cnt < max_entries; cnt++) { if(cache[cnt].private_ip == rule->private_ip && cache[cnt].target_ip == rule->target_ip && cache[cnt].private_port == rule->private_port && cache[cnt].target_port == rule->target_port && cache[cnt].protocol == rule->protocol) { IPACMDBG("Duplicate Rule\n"); iptodot("Private IP", rule->private_ip); iptodot("Target IP", rule->target_ip); IPACMDBG("Private Port: %d\t Target Port: %d\t", rule->private_port, rule->target_port); IPACMDBG("protocolcol: %d\n", rule->protocol); return true; } } return false; } /* Delete the entry from Nat table on connection close */ int NatApp::DeleteEntry(const nat_table_entry *rule) { int cnt = 0; IPACMDBG("%s() %d\n", __FUNCTION__, __LINE__); IPACMDBG("Received below nat entry for deletion\n"); iptodot("Private IP", rule->private_ip); iptodot("Target IP", rule->target_ip); IPACMDBG("Private Port: %d\t Target Port: %d\t", rule->private_port, rule->target_port); IPACMDBG("protocolcol: %d\n", rule->protocol); for(; cnt < max_entries; cnt++) { if(cache[cnt].private_ip == rule->private_ip && cache[cnt].target_ip == rule->target_ip && cache[cnt].private_port == rule->private_port && cache[cnt].target_port == rule->target_port && cache[cnt].protocol == rule->protocol) { if(cache[cnt].enabled == true) { if(ipa_nat_del_ipv4_rule(nat_table_hdl, cache[cnt].rule_hdl) < 0) { IPACMERR("%s() %d deletion failed\n", __FUNCTION__, __LINE__); } IPACMDBG("Deleted Nat entry(%d) Successfully\n", cnt); } else { IPACMDBG("Deleted Nat entry(%d) only from cache\n", cnt); } memset(&cache[cnt], 0, sizeof(cache[cnt])); curCnt--; break; } } return 0; } /* Add new entry to the nat table on new connection */ int NatApp::AddEntry(const nat_table_entry *rule) { int cnt = 0; ipa_nat_ipv4_rule nat_rule; IPACMDBG("%s() %d\n", __FUNCTION__, __LINE__); CHK_TBL_HDL(); IPACMDBG("Received below nat entry for addition\n"); iptodot("Private IP", rule->private_ip); iptodot("Target IP", rule->target_ip); IPACMDBG("Private Port: %d\t Target Port: %d\t", rule->private_port, rule->target_port); IPACMDBG("protocolcol: %d\n", rule->protocol); if(isAlgPort(rule->protocol, rule->private_port) || isAlgPort(rule->protocol, rule->target_port)) { IPACMERR("connection using ALG Port. Dont insert into nat table\n"); return -1; } if(rule->private_ip == 0 || rule->target_ip == 0 || rule->private_port == 0 || rule->target_port == 0 || rule->protocol == 0) { IPACMERR("Invalid Connection, ignoring it\n"); return 0; } if(!ChkForDup(rule)) { for(; cnt < max_entries; cnt++) { if(cache[cnt].private_ip == 0 && cache[cnt].target_ip == 0 && cache[cnt].private_port == 0 && cache[cnt].target_port == 0 && cache[cnt].protocol == 0) { break; } } if(max_entries == cnt) { IPACMERR("Error: Unable to add, reached maximum rules\n"); return -1; } else { nat_rule.private_ip = rule->private_ip; nat_rule.target_ip = rule->target_ip; nat_rule.target_port = rule->target_port; nat_rule.private_port = rule->private_port; nat_rule.public_port = rule->public_port; nat_rule.protocol = rule->protocol; if(isPwrSaveIf(rule->private_ip) || isPwrSaveIf(rule->target_ip)) { IPACMDBG("Device is Power Save mode: Dont insert into nat table but cache\n"); cache[cnt].enabled = false; cache[cnt].rule_hdl = 0; } else { if(ipa_nat_add_ipv4_rule(nat_table_hdl, &nat_rule, &cache[cnt].rule_hdl) < 0) { IPACMERR("unable to add the rule\n"); return -1; } cache[cnt].enabled = true; } cache[cnt].private_ip = rule->private_ip; cache[cnt].target_ip = rule->target_ip; cache[cnt].target_port = rule->target_port; cache[cnt].private_port = rule->private_port; cache[cnt].protocol = rule->protocol; cache[cnt].timestamp = 0; cache[cnt].public_port = rule->public_port; cache[cnt].dst_nat = rule->dst_nat; curCnt++; } } else { IPACMERR("Duplicate rule. Ignore it\n"); return -1; } if(cache[cnt].enabled == true) { IPACMDBG("Added rule(%d) successfully\n", cnt); } else { IPACMDBG("Cached rule(%d) successfully\n", cnt); } return 0; } void NatApp::UpdateCTUdpTs(nat_table_entry *rule, uint32_t new_ts) { int ret; iptodot("Private IP:", rule->private_ip); iptodot("Target IP:", rule->target_ip); IPACMDBG("Private Port: %d, Target Port: %d\n", rule->private_port, rule->target_port); if(!ct_hdl) { ct_hdl = nfct_open(CONNTRACK, 0); if(!ct_hdl) { PERROR("nfct_open"); return; } } if(!ct) { ct = nfct_new(); if(!ct) { PERROR("nfct_new"); return; } } nfct_set_attr_u8(ct, ATTR_L3PROTO, AF_INET); if(rule->protocol == IPPROTO_UDP) { nfct_set_attr_u8(ct, ATTR_L4PROTO, rule->protocol); nfct_set_attr_u32(ct, ATTR_TIMEOUT, udp_timeout); } else { nfct_set_attr_u8(ct, ATTR_L4PROTO, rule->protocol); nfct_set_attr_u32(ct, ATTR_TIMEOUT, tcp_timeout); } if(rule->dst_nat == false) { nfct_set_attr_u32(ct, ATTR_IPV4_SRC, htonl(rule->private_ip)); nfct_set_attr_u16(ct, ATTR_PORT_SRC, htons(rule->private_port)); nfct_set_attr_u32(ct, ATTR_IPV4_DST, htonl(rule->target_ip)); nfct_set_attr_u16(ct, ATTR_PORT_DST, htons(rule->target_port)); IPACMDBG("dst nat is not set\n"); } else { nfct_set_attr_u32(ct, ATTR_IPV4_SRC, htonl(rule->target_ip)); nfct_set_attr_u16(ct, ATTR_PORT_SRC, htons(rule->target_port)); nfct_set_attr_u32(ct, ATTR_IPV4_DST, htonl(pub_ip_addr)); nfct_set_attr_u16(ct, ATTR_PORT_DST, htons(rule->public_port)); IPACMDBG("dst nat is set\n"); } iptodot("Source IP:", nfct_get_attr_u32(ct, ATTR_IPV4_SRC)); iptodot("Destination IP:", nfct_get_attr_u32(ct, ATTR_IPV4_DST)); IPACMDBG("Source Port: %d, Destination Port: %d\n", nfct_get_attr_u16(ct, ATTR_PORT_SRC), nfct_get_attr_u16(ct, ATTR_PORT_DST)); IPACMDBG("updating %d connection with time: %d\n", rule->protocol, nfct_get_attr_u32(ct, ATTR_TIMEOUT)); ret = nfct_query(ct_hdl, NFCT_Q_UPDATE, ct); if(ret == -1) { PERROR("unable to update time stamp"); } else { rule->timestamp = new_ts; IPACMDBG("Updated time stamp successfully\n"); } return; } void NatApp::UpdateUDPTimeStamp() { int cnt; uint32_t ts; for(cnt = 0; cnt < max_entries; cnt++) { ts = 0; if(cache[cnt].enabled == true) { IPACMDBG("\n"); if(ipa_nat_query_timestamp(nat_table_hdl, cache[cnt].rule_hdl, &ts) < 0) { IPACMERR("unable to retrieve timeout for rule hanle: %d\n", cache[cnt].rule_hdl); continue; } if(cache[cnt].timestamp == ts) { IPACMDBG("No Change in Time Stamp: cahce:%d, ipahw:%d\n", cache[cnt].timestamp, ts); continue; } UpdateCTUdpTs(&cache[cnt], ts); } /* end of outer if */ } /* end of for loop */ } bool NatApp::isAlgPort(uint8_t proto, uint16_t port) { int cnt; for(cnt = 0; cnt < nALGPort; cnt++) { if(proto == pALGPorts[cnt].protocol && port == pALGPorts[cnt].port) { return true; } } return false; } bool NatApp::isPwrSaveIf(uint32_t ip_addr) { int cnt; for(cnt = 0; cnt < IPA_MAX_NUM_WIFI_CLIENTS; cnt++) { if(0 != PwrSaveIfs[cnt] && ip_addr == PwrSaveIfs[cnt]) { return true; } } return false; } int NatApp::UpdatePwrSaveIf(uint32_t client_lan_ip) { int cnt; IPACMDBG("Received IP address: 0x%x\n", client_lan_ip); if(client_lan_ip == INVALID_IP_ADDR) { IPACMERR("Invalid ip address received\n"); return -1; } /* check for duplicate events */ for(cnt = 0; cnt < IPA_MAX_NUM_WIFI_CLIENTS; cnt++) { if(PwrSaveIfs[cnt] == client_lan_ip) { IPACMDBG("The client 0x%x is already in power save\n", client_lan_ip); return 0; } } for(cnt = 0; cnt < IPA_MAX_NUM_WIFI_CLIENTS; cnt++) { if(PwrSaveIfs[cnt] == 0) { PwrSaveIfs[cnt] = client_lan_ip; break; } } for(cnt = 0; cnt < max_entries; cnt++) { if(cache[cnt].private_ip == client_lan_ip && cache[cnt].enabled == true) { if(ipa_nat_del_ipv4_rule(nat_table_hdl, cache[cnt].rule_hdl) < 0) { IPACMERR("unable to delete the rule\n"); continue; } cache[cnt].enabled = false; cache[cnt].rule_hdl = 0; } } return 0; } int NatApp::ResetPwrSaveIf(uint32_t client_lan_ip) { int cnt; ipa_nat_ipv4_rule nat_rule; IPACMDBG("Received ip address: 0x%x\n", client_lan_ip); if(client_lan_ip == INVALID_IP_ADDR) { IPACMERR("Invalid ip address received\n"); return -1; } for(cnt = 0; cnt < IPA_MAX_NUM_WIFI_CLIENTS; cnt++) { if(PwrSaveIfs[cnt] == client_lan_ip) { PwrSaveIfs[cnt] = 0; break; } } for(cnt = 0; cnt < max_entries; cnt++) { IPACMDBG("cache (%d): enable %d, ip 0x%x\n", cnt, cache[cnt].enabled, cache[cnt].private_ip); if(cache[cnt].private_ip == client_lan_ip && cache[cnt].enabled == false) { memset(&nat_rule, 0 , sizeof(nat_rule)); nat_rule.private_ip = cache[cnt].private_ip; nat_rule.target_ip = cache[cnt].target_ip; nat_rule.target_port = cache[cnt].target_port; nat_rule.private_port = cache[cnt].private_port; nat_rule.public_port = cache[cnt].public_port; nat_rule.protocol = cache[cnt].protocol; if(ipa_nat_add_ipv4_rule(nat_table_hdl, &nat_rule, &cache[cnt].rule_hdl) < 0) { IPACMERR("unable to add the rule delete from cache\n"); memset(&cache[cnt], 0, sizeof(cache[cnt])); curCnt--; continue; } cache[cnt].enabled = true; IPACMDBG("On power reset added below rule successfully\n"); iptodot("Private IP", nat_rule.private_ip); iptodot("Target IP", nat_rule.target_ip); IPACMDBG("Private Port:%d \t Target Port: %d\t", nat_rule.private_port, nat_rule.target_port); IPACMDBG("Public Port:%d\n", nat_rule.public_port); IPACMDBG("protocol: %d\n", nat_rule.protocol); } } return -1; } void NatApp::UpdateTcpUdpTo(uint32_t new_value, int proto) { if(proto == IPPROTO_TCP) { tcp_timeout = new_value; IPACMDBG("new nat tcp timeout value: %d\n", tcp_timeout); } else if(proto == IPPROTO_UDP) { udp_timeout = new_value; IPACMDBG("new nat udp timeout value: %d\n", udp_timeout); } } uint32_t NatApp::GetTableHdl(uint32_t in_ip_addr) { if(in_ip_addr == pub_ip_addr) { return nat_table_hdl; } return -1; } void NatApp::AddTempEntry(const nat_table_entry *new_entry) { int cnt; IPACMDBG("Received below nat entry\n"); iptodot("Private IP", new_entry->private_ip); iptodot("Target IP", new_entry->target_ip); IPACMDBG("Private Port: %d\t Target Port: %d\t", new_entry->private_port, new_entry->target_port); IPACMDBG("protocolcol: %d\n", new_entry->protocol); for(cnt=0; cntprivate_ip); iptodot("Target IP", entry->target_ip); IPACMDBG("Private Port: %d\t Target Port: %d\t", entry->private_port, entry->target_port); IPACMDBG("protocolcol: %d\n", entry->protocol); for(cnt=0; cntprivate_ip && temp[cnt].target_ip == entry->target_ip && temp[cnt].private_port == entry->private_port && temp[cnt].target_port == entry->target_port && temp[cnt].protocol == entry->protocol) { memset(&temp[cnt], 0, sizeof(nat_table_entry)); IPACMDBG("Delete Temp Entry\n"); return; } } IPACMDBG("No Such Entry exists\n"); return; } void NatApp::FlushTempEntries(uint32_t ip_addr, bool isAdd) { int cnt; int ret; IPACMDBG("Received below with isAdd:%d\n", isAdd); iptodot("IP Address:", ip_addr); for(cnt=0; cntprivate_ip == 0 || rule->target_ip == 0 || rule->private_port == 0 || rule->target_port == 0 || rule->protocol == 0) { IPACMERR("Invalid Connection, ignoring it\n"); return; } if(!ChkForDup(rule)) { for(; cnt < max_entries; cnt++) { if(cache[cnt].private_ip == 0 && cache[cnt].target_ip == 0 && cache[cnt].private_port == 0 && cache[cnt].target_port == 0 && cache[cnt].protocol == 0) { break; } } if(max_entries == cnt) { IPACMERR("Error: Unable to add, reached maximum rules\n"); return; } else { cache[cnt].enabled = false; cache[cnt].rule_hdl = 0; cache[cnt].private_ip = rule->private_ip; cache[cnt].target_ip = rule->target_ip; cache[cnt].target_port = rule->target_port; cache[cnt].private_port = rule->private_port; cache[cnt].protocol = rule->protocol; cache[cnt].timestamp = 0; cache[cnt].public_port = rule->public_port; cache[cnt].dst_nat = rule->dst_nat; curCnt++; } } else { IPACMERR("Duplicate rule. Ignore it\n"); return; } IPACMDBG("Cached rule(%d) successfully\n", cnt); return; } ================================================ FILE: data-ipa-cfg-mgr/ipacm/src/IPACM_EvtDispatcher.cpp ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPACM_EvtDispatcher.cpp @brief This file implements the IPAM event dispatcher functionality @Author */ #include #include #include #include #include "IPACM_CmdQueue.h" #include "IPACM_Defs.h" extern pthread_mutex_t mutex; extern pthread_cond_t cond_var; cmd_evts *IPACM_EvtDispatcher::head = NULL; extern uint32_t ipacm_event_stats[IPACM_EVENT_MAX]; int IPACM_EvtDispatcher::PostEvt ( ipacm_cmd_q_data *data ) { Message *item = NULL; MessageQueue *MsgQueue = NULL; MsgQueue = MessageQueue::getInstance(); if(MsgQueue == NULL) { IPACMERR("unable to retrieve MsgQueue instance\n"); return IPACM_FAILURE; } item = new Message(); if(item == NULL) { IPACMERR("unable to create new message item\n"); return IPACM_FAILURE; } IPACMDBG("Populating item to post to queue\n"); item->evt.callback_ptr = IPACM_EvtDispatcher::ProcessEvt; memcpy(&item->evt.data, data, sizeof(ipacm_cmd_q_data)); if(pthread_mutex_lock(&mutex) != 0) { IPACMERR("unable to lock the mutex\n"); return IPACM_FAILURE; } IPACMDBG("Enqueing item\n"); MsgQueue->enqueue(item); IPACMDBG("Enqueued item %p\n", item); if(pthread_cond_signal(&cond_var) != 0) { IPACMDBG("unable to lock the mutex\n"); /* Release the mutex before you return failure */ if(pthread_mutex_unlock(&mutex) != 0) { IPACMERR("unable to unlock the mutex\n"); return IPACM_FAILURE; } return IPACM_FAILURE; } if(pthread_mutex_unlock(&mutex) != 0) { IPACMERR("unable to unlock the mutex\n"); return IPACM_FAILURE; } return IPACM_SUCCESS; } void IPACM_EvtDispatcher::ProcessEvt(ipacm_cmd_q_data *data) { cmd_evts *tmp = head, tmp1; if(head == NULL) { IPACMDBG("Queue is empty\n"); } while(tmp != NULL) { memcpy(&tmp1, tmp, sizeof(tmp1)); if(data->event == tmp1.event) { ipacm_event_stats[data->event]++; tmp1.obj->event_callback(data->event, data->evt_data); IPACMDBG(" Find matched registered events\n"); } tmp = tmp1.next; } IPACMDBG(" Finished process events\n"); if(data->evt_data != NULL) { IPACMDBG("free the event:%d data: %p\n", data->event, data->evt_data); free(data->evt_data); } return; } int IPACM_EvtDispatcher::registr(ipa_cm_event_id event, IPACM_Listener *obj) { cmd_evts *tmp = head,*nw; nw = (cmd_evts *)malloc(sizeof(cmd_evts)); if(nw != NULL) { nw->event = event; nw->obj = obj; nw->next = NULL; } else { return IPACM_FAILURE; } if(head == NULL) { head = nw; } else { while(tmp->next) { tmp = tmp->next; } tmp->next = nw; } return IPACM_SUCCESS; } int IPACM_EvtDispatcher::deregistr(IPACM_Listener *param) { cmd_evts *tmp = head,*tmp1,*prev = head; while(tmp != NULL) { if(tmp->obj == param) { tmp1 = tmp; if(tmp == head) { head = head->next; } else if(tmp->next == NULL) { prev->next = NULL; } else { prev->next = tmp->next; } tmp = tmp->next; free(tmp1); } else { prev = tmp; tmp = tmp->next; } } return IPACM_SUCCESS; } ================================================ FILE: data-ipa-cfg-mgr/ipacm/src/IPACM_Filtering.cpp ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPACM_Filtering.cpp @brief This file implements the IPACM filtering functionality. @Author Skylar Chang */ #include #include #include #include #include #include "IPACM_Filtering.h" #include #include "IPACM_Defs.h" const char *IPACM_Filtering::DEVICE_NAME = "/dev/ipa"; IPACM_Filtering::IPACM_Filtering() { fd = open(DEVICE_NAME, O_RDWR); if (fd < 0) { IPACMERR("Failed opening %s.\n", DEVICE_NAME); } } IPACM_Filtering::~IPACM_Filtering() { close(fd); } bool IPACM_Filtering::DeviceNodeIsOpened() { return fd; } bool IPACM_Filtering::AddFilteringRule(struct ipa_ioc_add_flt_rule const *ruleTable) { int retval = 0; IPACMDBG("Printing filter add attributes\n"); IPACMDBG("ip type: %d\n", ruleTable->ip); IPACMDBG("Number of rules: %d\n", ruleTable->num_rules); IPACMDBG("End point: %d and global value: %d\n", ruleTable->ep, ruleTable->global); IPACMDBG("commit value: %d\n", ruleTable->commit); for (int cnt=0; cntnum_rules; cnt++) { IPACMDBG("Filter rule:%d attrib mask: 0x%x\n", cnt, ruleTable->rules[cnt].rule.attrib.attrib_mask); } retval = ioctl(fd, IPA_IOC_ADD_FLT_RULE, ruleTable); if (retval != 0) { IPACMERR("Failed adding Filtering rule %p\n", ruleTable); PERROR("unable to add filter rule:"); for (int cnt = 0; cnt < ruleTable->num_rules; cnt++) { if (ruleTable->rules[cnt].status != 0) { IPACMERR("Adding Filter rule:%d failed with status:%d\n", cnt, ruleTable->rules[cnt].status); } } return false; } for (int cnt = 0; cntnum_rules; cnt++) { if(ruleTable->rules[cnt].status != 0) { IPACMERR("Adding Filter rule:%d failed with status:%d\n", cnt, ruleTable->rules[cnt].status); } } IPACMDBG("Added Filtering rule %p\n", ruleTable); return true; } bool IPACM_Filtering::DeleteFilteringRule(struct ipa_ioc_del_flt_rule *ruleTable) { int retval = 0; retval = ioctl(fd, IPA_IOC_DEL_FLT_RULE, ruleTable); if (retval != 0) { IPACMERR("Failed deleting Filtering rule %p\n", ruleTable); return false; } IPACMDBG("Deleted Filtering rule %p\n", ruleTable); return true; } bool IPACM_Filtering::Commit(enum ipa_ip_type ip) { int retval = 0; retval = ioctl(fd, IPA_IOC_COMMIT_FLT, ip); if (retval != 0) { IPACMERR("failed committing Filtering rules.\n"); return false; } IPACMDBG("Committed Filtering rules to IPA HW.\n"); return true; } bool IPACM_Filtering::Reset(enum ipa_ip_type ip) { int retval = 0; retval = ioctl(fd, IPA_IOC_RESET_FLT, ip); retval |= ioctl(fd, IPA_IOC_COMMIT_FLT, ip); if (retval) { IPACMERR("failed resetting Filtering block.\n"); return false; } IPACMDBG("Reset command issued to IPA Filtering block.\n"); return true; } bool IPACM_Filtering::DeleteFilteringHdls ( uint32_t *flt_rule_hdls, ipa_ip_type ip, uint8_t num_rules ) { struct ipa_ioc_del_flt_rule *flt_rule; bool res = true; int len = 0, cnt = 0; const uint8_t UNIT_RULES = 1; len = (sizeof(struct ipa_ioc_del_flt_rule)) + (UNIT_RULES * sizeof(struct ipa_flt_rule_del)); flt_rule = (struct ipa_ioc_del_flt_rule *)malloc(len); if (flt_rule == NULL) { IPACMERR("unable to allocate memory for del filter rule\n"); return false; } for (cnt = 0; cnt < num_rules; cnt++) { memset(flt_rule, 0, len); flt_rule->commit = 1; flt_rule->num_hdls = UNIT_RULES; flt_rule->ip = ip; if (flt_rule_hdls[cnt] == 0) { IPACMERR("invalid filter handle passed, ignoring it: %d\n", cnt) } else { flt_rule->hdl[0].status = -1; flt_rule->hdl[0].hdl = flt_rule_hdls[cnt]; IPACMDBG("Deleting filter hdl:(0x%x) with ip type: %d\n", flt_rule_hdls[cnt], ip); if (DeleteFilteringRule(flt_rule) == false) { PERROR("Filter rule deletion failed!\n"); res = false; goto fail; } else { if (flt_rule->hdl[0].status != 0) { IPACMERR("Filter rule hdl 0x%x deletion failed with error:%d\n", flt_rule->hdl[0].hdl, flt_rule->hdl[0].status); res = false; goto fail; } } } } fail: free(flt_rule); return res; } bool IPACM_Filtering::AddWanDLFilteringRule(struct ipa_ioc_add_flt_rule const *rule_table_v4, struct ipa_ioc_add_flt_rule const * rule_table_v6, uint8_t mux_id) { int ret = 0, cnt, num_rules = 0, pos = 0; ipa_install_fltr_rule_req_msg_v01 qmi_rule_msg; int fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR); if(fd_wwan_ioctl < 0) { IPACMERR("Failed to open %s.\n",WWAN_QMI_IOCTL_DEVICE_NAME); return false; } if(rule_table_v4 != NULL) { num_rules += rule_table_v4->num_rules; IPACMDBG_H("Get %d WAN DL IPv4 filtering rules.\n", rule_table_v4->num_rules); } if(rule_table_v6 != NULL) { num_rules += rule_table_v6->num_rules; IPACMDBG_H("Get %d WAN DL IPv6 filtering rules.\n", rule_table_v6->num_rules); } if(num_rules > QMI_IPA_MAX_FILTERS_V01) { IPACMERR("The number of filtering rules exceed limit.\n"); close(fd_wwan_ioctl); return false; } else { memset(&qmi_rule_msg, 0, sizeof(qmi_rule_msg)); if (num_rules > 0) { qmi_rule_msg.filter_spec_list_valid = true; } else { qmi_rule_msg.filter_spec_list_valid = false; } qmi_rule_msg.filter_spec_list_len = num_rules; qmi_rule_msg.source_pipe_index_valid = 0; IPACMDBG_H("Get %d WAN DL filtering rules in total.\n", num_rules); if(rule_table_v4 != NULL) { for(cnt = rule_table_v4->num_rules - 1; cnt >= 0; cnt--) { if (pos < QMI_IPA_MAX_FILTERS_V01) { qmi_rule_msg.filter_spec_list[pos].filter_spec_identifier = pos; qmi_rule_msg.filter_spec_list[pos].ip_type = QMI_IPA_IP_TYPE_V4_V01; qmi_rule_msg.filter_spec_list[pos].filter_action = GetQmiFilterAction(rule_table_v4->rules[cnt].rule.action); qmi_rule_msg.filter_spec_list[pos].is_routing_table_index_valid = 1; qmi_rule_msg.filter_spec_list[pos].route_table_index = rule_table_v4->rules[cnt].rule.rt_tbl_idx; qmi_rule_msg.filter_spec_list[pos].is_mux_id_valid = 1; qmi_rule_msg.filter_spec_list[pos].mux_id = mux_id; memcpy(&qmi_rule_msg.filter_spec_list[pos].filter_rule, &rule_table_v4->rules[cnt].rule.eq_attrib, sizeof(struct ipa_filter_rule_type_v01)); pos++; } else { IPACMERR(" QMI only support max %d rules, current (%d)\n ",QMI_IPA_MAX_FILTERS_V01, pos); } } } if(rule_table_v6 != NULL) { for(cnt = rule_table_v6->num_rules - 1; cnt >= 0; cnt--) { if (pos < QMI_IPA_MAX_FILTERS_V01) { qmi_rule_msg.filter_spec_list[pos].filter_spec_identifier = pos; qmi_rule_msg.filter_spec_list[pos].ip_type = QMI_IPA_IP_TYPE_V6_V01; qmi_rule_msg.filter_spec_list[pos].filter_action = GetQmiFilterAction(rule_table_v6->rules[cnt].rule.action); qmi_rule_msg.filter_spec_list[pos].is_routing_table_index_valid = 1; qmi_rule_msg.filter_spec_list[pos].route_table_index = rule_table_v6->rules[cnt].rule.rt_tbl_idx; qmi_rule_msg.filter_spec_list[pos].is_mux_id_valid = 1; qmi_rule_msg.filter_spec_list[pos].mux_id = mux_id; memcpy(&qmi_rule_msg.filter_spec_list[pos].filter_rule, &rule_table_v6->rules[cnt].rule.eq_attrib, sizeof(struct ipa_filter_rule_type_v01)); pos++; } else { IPACMERR(" QMI only support max %d rules, current (%d)\n ",QMI_IPA_MAX_FILTERS_V01, pos); } } } ret = ioctl(fd_wwan_ioctl, WAN_IOC_ADD_FLT_RULE, &qmi_rule_msg); if (ret != 0) { IPACMERR("Failed adding Filtering rule %p with ret %d\n ", &qmi_rule_msg, ret); close(fd_wwan_ioctl); return false; } } IPACMDBG("Added Filtering rule %p\n", &qmi_rule_msg); close(fd_wwan_ioctl); return true; } bool IPACM_Filtering::SendFilteringRuleIndex(struct ipa_fltr_installed_notif_req_msg_v01* table) { int ret = 0; int fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR); if(fd_wwan_ioctl < 0) { IPACMERR("Failed to open %s.\n",WWAN_QMI_IOCTL_DEVICE_NAME); return false; } ret = ioctl(fd_wwan_ioctl, WAN_IOC_ADD_FLT_RULE_INDEX, table); if (ret != 0) { IPACMERR("Failed adding filtering rule index %p with ret %d\n", table, ret); close(fd_wwan_ioctl); return false; } IPACMDBG("Added Filtering rule index %p\n", table); close(fd_wwan_ioctl); return true; } ipa_filter_action_enum_v01 IPACM_Filtering::GetQmiFilterAction(ipa_flt_action action) { switch(action) { case IPA_PASS_TO_ROUTING: return QMI_IPA_FILTER_ACTION_ROUTING_V01; case IPA_PASS_TO_SRC_NAT: return QMI_IPA_FILTER_ACTION_SRC_NAT_V01; case IPA_PASS_TO_DST_NAT: return QMI_IPA_FILTER_ACTION_DST_NAT_V01; case IPA_PASS_TO_EXCEPTION: return QMI_IPA_FILTER_ACTION_EXCEPTION_V01; default: return IPA_FILTER_ACTION_ENUM_MAX_ENUM_VAL_V01; } } bool IPACM_Filtering::ModifyFilteringRule(struct ipa_ioc_mdfy_flt_rule* ruleTable) { int i, ret = 0; IPACMDBG("Printing filtering add attributes\n"); IPACMDBG("IP type: %d Number of rules: %d commit value: %d\n", ruleTable->ip, ruleTable->num_rules, ruleTable->commit); for (i=0; inum_rules; i++) { IPACMDBG("Filter rule:%d attrib mask: 0x%x\n", i, ruleTable->rules[i].rule.attrib.attrib_mask); } ret = ioctl(fd, IPA_IOC_MDFY_FLT_RULE, ruleTable); if (ret != 0) { IPACMERR("Failed modifying filtering rule %p\n", ruleTable); for (i = 0; i < ruleTable->num_rules; i++) { if (ruleTable->rules[i].status != 0) { IPACMERR("Modifying filter rule %d failed\n", i); } } return false; } IPACMDBG("Modified filtering rule %p\n", ruleTable); return true; } ================================================ FILE: data-ipa-cfg-mgr/ipacm/src/IPACM_Header.cpp ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include "IPACM_Header.h" #include "IPACM_Log.h" ///////////////////////////////////////////////////////////////////////////////////////////////////////// //All interaction through the driver are made through this inode. static const char *DEVICE_NAME = "/dev/ipa"; ///////////////////////////////////////////////////////////////////////////////////////////////////////// IPACM_Header::IPACM_Header() { m_fd = open(DEVICE_NAME, O_RDWR); if (-1 == m_fd) { IPACMERR("Failed to open %s in IPACM_Header test application constructor.\n", DEVICE_NAME); } } ///////////////////////////////////////////////////////////////////////////////////////////////////////// IPACM_Header::~IPACM_Header() { if (-1 != m_fd) { close(m_fd); } } ///////////////////////////////////////////////////////////////////////////////////////////////////////// bool IPACM_Header::DeviceNodeIsOpened() { return (-1 != m_fd); } ///////////////////////////////////////////////////////////////////////////////////////////////////////// bool IPACM_Header::AddHeader(struct ipa_ioc_add_hdr *pHeaderTableToAdd) { int nRetVal = 0; //call the Driver ioctl in order to add header nRetVal = ioctl(m_fd, IPA_IOC_ADD_HDR, pHeaderTableToAdd); IPACMDBG("return value: %d\n", nRetVal); return (-1 != nRetVal); } ///////////////////////////////////////////////////////////////////////////////////////////////////////// bool IPACM_Header::DeleteHeader(struct ipa_ioc_del_hdr *pHeaderTableToDelete) { int nRetVal = 0; //call the Driver ioctl in order to remove header nRetVal = ioctl(m_fd, IPA_IOC_DEL_HDR, pHeaderTableToDelete); IPACMDBG("return value: %d\n", nRetVal); return (-1 != nRetVal); } ///////////////////////////////////////////////////////////////////////////////////////////////////////// bool IPACM_Header::Commit() { int nRetVal = 0; nRetVal = ioctl(m_fd, IPA_IOC_COMMIT_HDR); IPACMDBG("return value: %d\n", nRetVal); return true; } ///////////////////////////////////////////////////////////////////////////////////////////////////////// bool IPACM_Header::Reset() { int nRetVal = 0; nRetVal = ioctl(m_fd, IPA_IOC_RESET_HDR); nRetVal |= ioctl(m_fd, IPA_IOC_COMMIT_HDR); IPACMDBG("return value: %d\n", nRetVal); return true; } ///////////////////////////////////////////////////////////////////////////////////////////////////////// bool IPACM_Header::GetHeaderHandle(struct ipa_ioc_get_hdr *pHeaderStruct) { int retval = 0; if (!DeviceNodeIsOpened()) return false; retval = ioctl(m_fd, IPA_IOC_GET_HDR, pHeaderStruct); if (retval) { IPACMERR("IPA_IOC_GET_HDR ioctl failed, routingTable =0x%p, retval=0x%x.\n", pHeaderStruct, retval); return false; } IPACMDBG("IPA_IOC_GET_HDR ioctl issued to IPA header insertion block.\n"); return true; } ///////////////////////////////////////////////////////////////////////////////////////////////////////// bool IPACM_Header::CopyHeader(struct ipa_ioc_copy_hdr *pCopyHeaderStruct) { int retval = 0; if (!DeviceNodeIsOpened()) return false; retval = ioctl(m_fd, IPA_IOC_COPY_HDR, pCopyHeaderStruct); if (retval) { IPACMERR("IPA_IOC_COPY_HDR ioctl failed, retval=0x%x.\n", retval); return false; } IPACMDBG("IPA_IOC_COPY_HDR ioctl issued to IPA header insertion block.\n"); return true; } bool IPACM_Header::DeleteHeaderHdl(uint32_t hdr_hdl) { const uint8_t NUM_HDLS = 1; struct ipa_ioc_del_hdr *pHeaderDescriptor = NULL; struct ipa_hdr_del *hd_rule_entry; int len = 0; bool res = true; if (hdr_hdl == 0) { IPACMERR("Invalid header handle passed. Ignoring it\n"); return false; } len = (sizeof(struct ipa_ioc_del_hdr)) + (NUM_HDLS * sizeof(struct ipa_hdr_del)); pHeaderDescriptor = (struct ipa_ioc_del_hdr *)malloc(len); if (pHeaderDescriptor == NULL) { IPACMERR("Unable to allocate memory for del header\n"); return false; } memset(pHeaderDescriptor, 0, len); pHeaderDescriptor->commit = true; pHeaderDescriptor->num_hdls = NUM_HDLS; hd_rule_entry = &pHeaderDescriptor->hdl[0]; hd_rule_entry->hdl = hdr_hdl; hd_rule_entry->status = -1; IPACMDBG("Deleting Header hdl:(%x)\n", hd_rule_entry->hdl); if ((false == DeleteHeader(pHeaderDescriptor)) || (hd_rule_entry->status)) { IPACMERR("Header hdl:(%x) deletion failed! status: %d\n", hd_rule_entry->hdl,hd_rule_entry->status); res = false; goto fail; } IPACMDBG_H("Deleted Header hdl:(%x) successfully\n", hd_rule_entry->hdl); fail: free(pHeaderDescriptor); return res; } bool IPACM_Header::AddHeaderProcCtx(struct ipa_ioc_add_hdr_proc_ctx* pHeader) { int ret = 0; //call the Driver ioctl to add header processing context ret = ioctl(m_fd, IPA_IOC_ADD_HDR_PROC_CTX, pHeader); return (ret != -1); } bool IPACM_Header::DeleteHeaderProcCtx(uint32_t hdl) { int len, ret; struct ipa_ioc_del_hdr_proc_ctx* pHeaderTable = NULL; len = sizeof(struct ipa_ioc_del_hdr_proc_ctx) + sizeof(struct ipa_hdr_proc_ctx_del); pHeaderTable = (struct ipa_ioc_del_hdr_proc_ctx*)malloc(len); if(pHeaderTable == NULL) { IPACMERR("Failed to allocate buffer.\n"); return false; } memset(pHeaderTable, 0, len); pHeaderTable->commit = 1; pHeaderTable->num_hdls = 1; pHeaderTable->hdl[0].hdl = hdl; ret = ioctl(m_fd, IPA_IOC_DEL_HDR_PROC_CTX, pHeaderTable); free(pHeaderTable); return (ret != -1); } ================================================ FILE: data-ipa-cfg-mgr/ipacm/src/IPACM_Iface.cpp ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.Z */ /*! @file IPACM_Iface.cpp @brief This file implements the basis Iface functionality. @Author Skylar Chang */ #include #include #include #include #include #include #include #include extern "C" { #include } const char *IPACM_Iface::DEVICE_NAME = "/dev/ipa"; IPACM_Routing IPACM_Iface::m_routing; IPACM_Filtering IPACM_Iface::m_filtering; IPACM_Header IPACM_Iface::m_header; IPACM_Config *IPACM_Iface::ipacmcfg = IPACM_Config::GetInstance(); IPACM_Iface::IPACM_Iface(int iface_index) { ip_type = IPACM_IP_NULL; /* initially set invalid */ num_dft_rt_v6 = 0; softwarerouting_act = false; ipa_if_num = iface_index; ipa_if_cate = IPACM_Iface::ipacmcfg->iface_table[iface_index].if_cat; iface_query = NULL; tx_prop = NULL; rx_prop = NULL; memcpy(dev_name, IPACM_Iface::ipacmcfg->iface_table[iface_index].iface_name, sizeof(IPACM_Iface::ipacmcfg->iface_table[iface_index].iface_name)); memset(dft_v4fl_rule_hdl, 0, sizeof(dft_v4fl_rule_hdl)); memset(dft_v6fl_rule_hdl, 0, sizeof(dft_v6fl_rule_hdl)); memset(dft_rt_rule_hdl, 0, sizeof(dft_rt_rule_hdl)); memset(software_routing_fl_rule_hdl, 0, sizeof(software_routing_fl_rule_hdl)); memset(ipv6_addr, 0, sizeof(ipv6_addr)); flt_rule_count_v4 = 0; flt_rule_count_v6 = 0; query_iface_property(); IPACMDBG_H(" create iface-index(%d) constructor\n", ipa_if_num); return; } /* software routing enable */ int IPACM_Iface::handle_software_routing_enable(void) { int res = IPACM_SUCCESS; struct ipa_flt_rule_add flt_rule_entry; ipa_ioc_add_flt_rule *m_pFilteringTable; IPACMDBG("\n"); if (softwarerouting_act == true) { IPACMDBG("already setup software_routing rule for (%s)iface ip-family %d\n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, ip_type); return IPACM_SUCCESS; } if(rx_prop == NULL) { IPACMDBG("No rx properties registered for iface %s\n", dev_name); return IPACM_SUCCESS; } m_pFilteringTable = (struct ipa_ioc_add_flt_rule *) calloc(1, sizeof(struct ipa_ioc_add_flt_rule) + 1 * sizeof(struct ipa_flt_rule_add) ); if (!m_pFilteringTable) { IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); return IPACM_FAILURE; } m_pFilteringTable->commit = 1; m_pFilteringTable->ep = rx_prop->rx[0].src_pipe; m_pFilteringTable->global = false; m_pFilteringTable->num_rules = (uint8_t)1; /* Configuring Software-Routing Filtering Rule */ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); flt_rule_entry.at_rear = false; flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); /* check iface is v4 or v6 or both*/ // if (ip_type == IPA_IP_MAX) // { /* handle v4 */ m_pFilteringTable->ip = IPA_IP_v4; if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) { IPACMERR("Error Adding Filtering rule, aborting...\n"); res = IPACM_FAILURE; goto fail; } else if (m_pFilteringTable->rules[0].status) { IPACMERR("adding flt rule failed status=0x%x\n", m_pFilteringTable->rules[0].status); res = IPACM_FAILURE; goto fail; } IPACMDBG("soft-routing flt rule hdl0=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl); /* copy filter hdls */ software_routing_fl_rule_hdl[0] = m_pFilteringTable->rules[0].flt_rule_hdl; /* handle v6*/ m_pFilteringTable->ip = IPA_IP_v6; if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) { IPACMERR("Error Adding Filtering rule, aborting...\n"); res = IPACM_FAILURE; goto fail; } else if (m_pFilteringTable->rules[0].status) { IPACMDBG("adding flt rule failed status=0x%x\n", m_pFilteringTable->rules[0].status); res = IPACM_FAILURE; goto fail; } IPACMDBG("soft-routing flt rule hdl0=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl); /* copy filter hdls */ software_routing_fl_rule_hdl[1] = m_pFilteringTable->rules[0].flt_rule_hdl; softwarerouting_act = true; #if 0 } else { if (ip_type == IPA_IP_v4) { m_pFilteringTable->ip = IPA_IP_v4; } else { m_pFilteringTable->ip = IPA_IP_v6; } if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) { IPACMERR("Error Adding Filtering rule, aborting...\n"); res = IPACM_FAILURE; goto fail; } else if (m_pFilteringTable->rules[0].status) { IPACMERR("adding flt rule failed status=0x%x\n", m_pFilteringTable->rules[0].status); res = IPACM_FAILURE; goto fail; } IPACMDBG("soft-routing flt rule hdl0=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl); /* copy filter hdls */ if (ip_type == IPA_IP_v4) { software_routing_fl_rule_hdl[0] = m_pFilteringTable->rules[0].flt_rule_hdl; } else { software_routing_fl_rule_hdl[1] = m_pFilteringTable->rules[0].flt_rule_hdl; } softwarerouting_act = true; } #endif fail: free(m_pFilteringTable); return res; } /* software routing disable */ int IPACM_Iface::handle_software_routing_disable(void) { int res = IPACM_SUCCESS; ipa_ip_type ip; uint32_t flt_hdl; if (rx_prop == NULL) { IPACMDBG("No rx properties registered for iface %s\n", dev_name); return IPACM_SUCCESS; } if (softwarerouting_act == false) { IPACMDBG("already delete software_routing rule for (%s)iface ip-family %d\n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, ip_type); return IPACM_SUCCESS; } // if (ip_type == IPA_IP_MAX) // { /* ipv4 case */ if (m_filtering.DeleteFilteringHdls(&software_routing_fl_rule_hdl[0], IPA_IP_v4, 1) == false) { IPACMERR("Error Adding Filtering rule, aborting...\n"); res = IPACM_FAILURE; goto fail; } /* ipv6 case */ if (m_filtering.DeleteFilteringHdls(&software_routing_fl_rule_hdl[1], IPA_IP_v6, 1) == false) { IPACMERR("Error Adding Filtering rule, aborting...\n"); res = IPACM_FAILURE; goto fail; } softwarerouting_act = false; #if 0 } else { if (ip_type == IPA_IP_v4) { ip = IPA_IP_v4; } else { ip = IPA_IP_v6; } if (ip_type == IPA_IP_v4) { flt_hdl = software_routing_fl_rule_hdl[0]; } else { flt_hdl = software_routing_fl_rule_hdl[1]; } if (m_filtering.DeleteFilteringHdls(&flt_hdl, ip, 1) == false) { IPACMERR("Error Adding Filtering rule, aborting...\n"); res = IPACM_FAILURE; goto fail; } softwarerouting_act = false; } #endif fail: return res; } /* Query ipa_interface_index by given linux interface_index */ int IPACM_Iface::iface_ipa_index_query ( int interface_index ) { int fd; int link = INVALID_IFACE; int i = 0; struct ifreq ifr; if(IPACM_Iface::ipacmcfg->iface_table == NULL) { IPACMERR("Iface table in IPACM_Config is not available.\n"); return link; } /* Search known linux interface-index and map to IPA interface-index*/ for (i = 0; i < IPACM_Iface::ipacmcfg->ipa_num_ipa_interfaces; i++) { if (interface_index == IPACM_Iface::ipacmcfg->iface_table[i].netlink_interface_index) { link = i; IPACMDBG("Interface (%s) found: linux(%d) ipa(%d) \n", IPACM_Iface::ipacmcfg->iface_table[i].iface_name, IPACM_Iface::ipacmcfg->iface_table[i].netlink_interface_index, link); return link; break; } } /* Search/Configure linux interface-index and map it to IPA interface-index */ if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { PERROR("get interface name socket create failed"); return IPACM_FAILURE; } memset(&ifr, 0, sizeof(struct ifreq)); ifr.ifr_ifindex = interface_index; IPACMDBG_H("Interface index %d\n", interface_index); if (ioctl(fd, SIOCGIFNAME, &ifr) < 0) { PERROR("call_ioctl_on_dev: ioctl failed:"); close(fd); return IPACM_FAILURE; } close(fd); IPACMDBG_H("Received interface name %s\n", ifr.ifr_name); for (i = 0; i < IPACM_Iface::ipacmcfg->ipa_num_ipa_interfaces; i++) { if (strncmp(ifr.ifr_name, IPACM_Iface::ipacmcfg->iface_table[i].iface_name, sizeof(IPACM_Iface::ipacmcfg->iface_table[i].iface_name)) == 0) { IPACMDBG_H("Interface (%s) linux(%d) mapped to ipa(%d) \n", ifr.ifr_name, IPACM_Iface::ipacmcfg->iface_table[i].netlink_interface_index, i); link = i; IPACM_Iface::ipacmcfg->iface_table[i].netlink_interface_index = interface_index; break; } } return link; } /* Query ipa_interface ipv4_addr by given linux interface_index */ void IPACM_Iface::iface_addr_query ( int interface_index ) { int fd; struct ifreq ifr; struct ifaddrs *myaddrs, *ifa; ipacm_cmd_q_data evt_data; ipacm_event_data_addr *data_addr; struct in_addr iface_ipv4; /* use linux interface-index to find interface name */ if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { PERROR("get interface name socket create failed"); return ; } memset(&ifr, 0, sizeof(struct ifreq)); ifr.ifr_ifindex = interface_index; IPACMDBG_H("Interface index %d\n", interface_index); if (ioctl(fd, SIOCGIFNAME, &ifr) < 0) { PERROR("call_ioctl_on_dev: ioctl failed:"); close(fd); return ; } IPACMDBG_H("Interface index %d name: %s\n", interface_index,ifr.ifr_name); close(fd); /* query ipv4/v6 address */ if(getifaddrs(&myaddrs) != 0) { IPACMERR("getifaddrs"); return ; } for (ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next) { if (ifa->ifa_addr == NULL) continue; if (!(ifa->ifa_flags & IFF_UP)) continue; if(strcmp(ifr.ifr_name,ifa->ifa_name) == 0) // find current iface { IPACMDBG_H("Internal post new_addr event for iface %s\n", ifa->ifa_name); switch (ifa->ifa_addr->sa_family) { case AF_INET: { struct sockaddr_in *s4 = (struct sockaddr_in *)ifa->ifa_addr; IPACMDBG_H("ipv4 address %s\n",inet_ntoa(s4->sin_addr)); iface_ipv4 = s4->sin_addr; /* post new_addr event to command queue */ data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr)); if(data_addr == NULL) { IPACMERR("unable to allocate memory for event data_addr\n"); freeifaddrs(myaddrs); return ; } data_addr->iptype = IPA_IP_v4; data_addr->if_index = interface_index; data_addr->ipv4_addr = iface_ipv4.s_addr; data_addr->ipv4_addr = ntohl(data_addr->ipv4_addr); IPACMDBG_H("Posting IPA_ADDR_ADD_EVENT with if index:%d, ipv4 addr:0x%x\n", data_addr->if_index, data_addr->ipv4_addr); evt_data.event = IPA_ADDR_ADD_EVENT; evt_data.evt_data = data_addr; IPACM_EvtDispatcher::PostEvt(&evt_data); break; } case AF_INET6: { struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)ifa->ifa_addr; /* post new_addr event to command queue */ data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr)); if(data_addr == NULL) { IPACMERR("unable to allocate memory for event data_addr\n"); freeifaddrs(myaddrs); return ; } data_addr->iptype = IPA_IP_v6; data_addr->if_index = interface_index; memcpy(data_addr->ipv6_addr, &s6->sin6_addr, sizeof(data_addr->ipv6_addr)); data_addr->ipv6_addr[0] = ntohl(data_addr->ipv6_addr[0]); data_addr->ipv6_addr[1] = ntohl(data_addr->ipv6_addr[1]); data_addr->ipv6_addr[2] = ntohl(data_addr->ipv6_addr[2]); data_addr->ipv6_addr[3] = ntohl(data_addr->ipv6_addr[3]); IPACMDBG_H("Posting IPA_ADDR_ADD_EVENT with if index:%d, ipv6 addr:0x%x:%x:%x:%x\n", data_addr->if_index, data_addr->ipv6_addr[0], data_addr->ipv6_addr[1], data_addr->ipv6_addr[2], data_addr->ipv6_addr[3]); evt_data.event = IPA_ADDR_ADD_EVENT; evt_data.evt_data = data_addr; IPACM_EvtDispatcher::PostEvt(&evt_data); break; } default: continue; } } } freeifaddrs(myaddrs); return ; } /*Query the IPA endpoint property */ int IPACM_Iface::query_iface_property(void) { int res = IPACM_SUCCESS, fd = 0; uint32_t cnt=0; fd = open(DEVICE_NAME, O_RDWR); IPACMDBG("iface query-property \n"); if (0 == fd) { IPACMERR("Failed opening %s.\n", DEVICE_NAME); return IPACM_FAILURE; } iface_query = (struct ipa_ioc_query_intf *) calloc(1, sizeof(struct ipa_ioc_query_intf)); if(iface_query == NULL) { IPACMERR("Unable to allocate iface_query memory.\n"); close(fd); return IPACM_FAILURE; } IPACMDBG_H("iface name %s\n", dev_name); memcpy(iface_query->name, dev_name, sizeof(dev_name)); if (ioctl(fd, IPA_IOC_QUERY_INTF, iface_query) < 0) { PERROR("ioctl IPA_IOC_QUERY_INTF failed\n"); /* iface_query memory will free when iface-down*/ res = IPACM_FAILURE; } if(iface_query->num_tx_props > 0) { tx_prop = (struct ipa_ioc_query_intf_tx_props *) calloc(1, sizeof(struct ipa_ioc_query_intf_tx_props) + iface_query->num_tx_props * sizeof(struct ipa_ioc_tx_intf_prop)); if(tx_prop == NULL) { IPACMERR("Unable to allocate tx_prop memory.\n"); close(fd); return IPACM_FAILURE; } memcpy(tx_prop->name, dev_name, sizeof(tx_prop->name)); tx_prop->num_tx_props = iface_query->num_tx_props; if (ioctl(fd, IPA_IOC_QUERY_INTF_TX_PROPS, tx_prop) < 0) { PERROR("ioctl IPA_IOC_QUERY_INTF_TX_PROPS failed\n"); /* tx_prop memory will free when iface-down*/ res = IPACM_FAILURE; } if (res != IPACM_FAILURE) { for (cnt = 0; cnt < tx_prop->num_tx_props; cnt++) { IPACMDBG_H("Tx(%d):attrib-mask:0x%x, ip-type: %d, dst_pipe: %d, header: %s\n", cnt, tx_prop->tx[cnt].attrib.attrib_mask, tx_prop->tx[cnt].ip, tx_prop->tx[cnt].dst_pipe, tx_prop->tx[cnt].hdr_name); } } } if (iface_query->num_rx_props > 0) { rx_prop = (struct ipa_ioc_query_intf_rx_props *) calloc(1, sizeof(struct ipa_ioc_query_intf_rx_props) + iface_query->num_rx_props * sizeof(struct ipa_ioc_rx_intf_prop)); if(rx_prop == NULL) { IPACMERR("Unable to allocate rx_prop memory.\n"); close(fd); return IPACM_FAILURE; } memcpy(rx_prop->name, dev_name, sizeof(rx_prop->name)); rx_prop->num_rx_props = iface_query->num_rx_props; if (ioctl(fd, IPA_IOC_QUERY_INTF_RX_PROPS, rx_prop) < 0) { PERROR("ioctl IPA_IOC_QUERY_INTF_RX_PROPS failed\n"); /* rx_prop memory will free when iface-down*/ res = IPACM_FAILURE; } if (res != IPACM_FAILURE) { for (cnt = 0; cnt < rx_prop->num_rx_props; cnt++) { IPACMDBG_H("Rx(%d):attrib-mask:0x%x, ip-type: %d, src_pipe: %d\n", cnt, rx_prop->rx[cnt].attrib.attrib_mask, rx_prop->rx[cnt].ip, rx_prop->rx[cnt].src_pipe); } } } /* Add Natting iface to IPACM_Config if there is Rx/Tx property */ if (rx_prop != NULL || tx_prop != NULL) { IPACMDBG_H(" Has rx/tx properties registered for iface %s, add for NATTING \n", dev_name); IPACM_Iface::ipacmcfg->AddNatIfaces(dev_name); } close(fd); return res; } /*Configure the initial filter rules */ int IPACM_Iface::init_fl_rule(ipa_ip_type iptype) { int res = IPACM_SUCCESS, len = 0; struct ipa_flt_rule_add flt_rule_entry; ipa_ioc_add_flt_rule *m_pFilteringTable; /* Adding this hack because WLAN may not registered for Rx-endpoint, other ifaces will always have*/ const char *dev_wlan0="wlan0"; const char *dev_wlan1="wlan1"; const char *dev_ecm0="ecm0"; /* update the iface ip-type to be IPA_IP_v4, IPA_IP_v6 or both*/ if (iptype == IPA_IP_v4) { if ((ip_type == IPA_IP_v4) || (ip_type == IPA_IP_MAX)) { IPACMDBG_H(" interface(%s:%d) already in ip-type %d\n", dev_name, ipa_if_num, ip_type); return res; } if (ip_type == IPA_IP_v6) { ip_type = IPA_IP_MAX; } else { ip_type = IPA_IP_v4; } IPACMDBG_H(" interface(%s:%d) now ip-type is %d\n", dev_name, ipa_if_num, ip_type); } else { if ((ip_type == IPA_IP_v6) || (ip_type == IPA_IP_MAX)) { IPACMDBG_H(" interface(%s:%d) already in ip-type %d\n", dev_name, ipa_if_num, ip_type); return res; } if (ip_type == IPA_IP_v4) { ip_type = IPA_IP_MAX; } else { ip_type = IPA_IP_v6; } IPACMDBG_H(" interface(%s:%d) now ip-type is %d\n", dev_name, ipa_if_num, ip_type); } /* ADD corresponding ipa_rm_resource_name of RX-endpoint before adding all IPV4V6 FT-rules */ if((IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat== WAN_IF) || (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat== EMBMS_IF)) { IPACMDBG_H(" NOT add producer dependency on dev %s with registered rx-prop cat:%d \n", dev_name, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat); } else { if(rx_prop != NULL) { IPACMDBG_H("dev %s add producer dependency\n", dev_name); IPACMDBG_H("depend Got pipe %d rm index : %d \n", rx_prop->rx[0].src_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe]); IPACM_Iface::ipacmcfg->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe],false); } else { /* only wlan may take software-path, not register Rx-property*/ if(strcmp(dev_name,dev_wlan0) == 0 || strcmp(dev_name,dev_wlan1) == 0) { IPACMDBG_H("dev %s add producer dependency\n", dev_name); IPACMDBG_H("depend Got piperm index : %d \n", IPA_RM_RESOURCE_HSIC_PROD); IPACM_Iface::ipacmcfg->AddRmDepend(IPA_RM_RESOURCE_HSIC_PROD,true); } if(strcmp(dev_name,dev_ecm0) == 0) { IPACMDBG_H("dev %s add producer dependency\n", dev_name); IPACMDBG_H("depend Got piperm index : %d \n", IPA_RM_RESOURCE_USB_PROD); IPACM_Iface::ipacmcfg->AddRmDepend(IPA_RM_RESOURCE_USB_PROD,true); } } } if (rx_prop == NULL) { IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); return IPACM_SUCCESS; } /* construct ipa_ioc_add_flt_rule with default filter rules */ if (iptype == IPA_IP_v4) { len = sizeof(struct ipa_ioc_add_flt_rule) + (IPV4_DEFAULT_FILTERTING_RULES * sizeof(struct ipa_flt_rule_add)); m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)calloc(1, len); if (!m_pFilteringTable) { IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); return IPACM_FAILURE; } m_pFilteringTable->commit = 1; m_pFilteringTable->ep = rx_prop->rx[0].src_pipe; m_pFilteringTable->global = false; m_pFilteringTable->ip = iptype; m_pFilteringTable->num_rules = (uint8_t)IPV4_DEFAULT_FILTERTING_RULES; /* Configuring Fragment Filtering Rule */ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); flt_rule_entry.rule.retain_hdr = 1; flt_rule_entry.at_rear = true; flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; IPACMDBG_H("rx property attrib mask:0x%x\n", rx_prop->rx[0].attrib.attrib_mask); memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_FRAGMENT; memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); /* Configuring Multicast Filtering Rule */ memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0xF0000000; flt_rule_entry.rule.attrib.u.v4.dst_addr = 0xE0000000; memcpy(&(m_pFilteringTable->rules[1]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); /* Configuring Broadcast Filtering Rule */ flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF; flt_rule_entry.rule.attrib.u.v4.dst_addr = 0xFFFFFFFF; memcpy(&(m_pFilteringTable->rules[2]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) { IPACMERR("Error Adding Filtering rule, aborting...\n"); res = IPACM_FAILURE; goto fail; } else { flt_rule_count_v4 += IPV4_DEFAULT_FILTERTING_RULES; /* copy filter hdls */ for (int i = 0; i < IPV4_DEFAULT_FILTERTING_RULES; i++) { if (m_pFilteringTable->rules[i].status == 0) { dft_v4fl_rule_hdl[i] = m_pFilteringTable->rules[i].flt_rule_hdl; IPACMDBG_H("Default v4 filter Rule %d HDL:0x%x\n", i, dft_v4fl_rule_hdl[i]); } else { IPACMERR("Failed adding default v4 Filtering rule %d\n", i); } } } } else { len = sizeof(struct ipa_ioc_add_flt_rule) + (IPV6_DEFAULT_FILTERTING_RULES * sizeof(struct ipa_flt_rule_add)); m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)calloc(1, len); if (!m_pFilteringTable) { IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); return IPACM_FAILURE; } m_pFilteringTable->commit = 1; m_pFilteringTable->ep = rx_prop->rx[0].src_pipe; m_pFilteringTable->global = false; m_pFilteringTable->ip = iptype; m_pFilteringTable->num_rules = (uint8_t)IPV6_DEFAULT_FILTERTING_RULES; memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); flt_rule_entry.rule.retain_hdr = 1; flt_rule_entry.at_rear = true; flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; /* Configuring Multicast Filtering Rule */ memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0xFF000000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0XFF000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000; memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); /* Configuring fe80::/10 Link-Scoped Unicast Filtering Rule */ flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0XFFC00000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0xFE800000; flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000; memcpy(&(m_pFilteringTable->rules[1]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); /* Configuring fec0::/10 Reserved by IETF Filtering Rule */ flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0XFFC00000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0xFEC00000; flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000; memcpy(&(m_pFilteringTable->rules[2]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); #ifdef FEATURE_IPA_ANDROID IPACMDBG_H("Add TCP ctrl rules: total num %d\n", IPV6_DEFAULT_FILTERTING_RULES); memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); flt_rule_entry.at_rear = true; flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.retain_hdr = 1; flt_rule_entry.rule.to_uc = 0; flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; flt_rule_entry.rule.eq_attrib_type = 1; flt_rule_entry.rule.eq_attrib.rule_eq_bitmap = 0; if(rx_prop->rx[0].attrib.attrib_mask & IPA_FLT_META_DATA) { flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<14); flt_rule_entry.rule.eq_attrib.metadata_meq32_present = 1; flt_rule_entry.rule.eq_attrib.metadata_meq32.offset = 0; flt_rule_entry.rule.eq_attrib.metadata_meq32.value = rx_prop->rx[0].attrib.meta_data; flt_rule_entry.rule.eq_attrib.metadata_meq32.mask = rx_prop->rx[0].attrib.meta_data_mask; } flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<1); flt_rule_entry.rule.eq_attrib.protocol_eq_present = 1; flt_rule_entry.rule.eq_attrib.protocol_eq = IPACM_FIREWALL_IPPROTO_TCP; flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<8); flt_rule_entry.rule.eq_attrib.num_ihl_offset_meq_32 = 1; flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].offset = 12; /* add TCP FIN rule*/ flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<rules[3]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); /* add TCP SYN rule*/ flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<rules[4]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); /* add TCP RST rule*/ flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<rules[5]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); #endif if (m_filtering.AddFilteringRule(m_pFilteringTable) == false) { IPACMERR("Error Adding Filtering rule, aborting...\n"); res = IPACM_FAILURE; goto fail; } else { flt_rule_count_v6 += IPV6_DEFAULT_FILTERTING_RULES; /* copy filter hdls */ for (int i = 0; i < IPV6_DEFAULT_FILTERTING_RULES; i++) { if (m_pFilteringTable->rules[i].status == 0) { dft_v6fl_rule_hdl[i] = m_pFilteringTable->rules[i].flt_rule_hdl; IPACMDBG_H("Default v6 Filter Rule %d HDL:0x%x\n", i, dft_v6fl_rule_hdl[i]); } else { IPACMERR("Failing adding v6 default IPV6 rule %d\n", i); } } } } fail: free(m_pFilteringTable); return res; } /* get ipa interface name */ int IPACM_Iface::ipa_get_if_index ( char * if_name, int * if_index ) { int fd; struct ifreq ifr; if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { IPACMERR("get interface index socket create failed \n"); return IPACM_FAILURE; } memset(&ifr, 0, sizeof(struct ifreq)); (void)strncpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name)); IPACMDBG_H("interface name (%s)\n", if_name); if (ioctl(fd,SIOCGIFINDEX , &ifr) < 0) { IPACMERR("call_ioctl_on_dev: ioctl failed, interface name (%s):\n", ifr.ifr_name); close(fd); return IPACM_FAILURE; } *if_index = ifr.ifr_ifindex; IPACMDBG_H("Interface index %d\n", *if_index); close(fd); return IPACM_SUCCESS; } size_t IPACM_Iface::strlcpy(char *dest, const char *src, size_t n) { size_t ret = strlen(src); size_t len = 0; if (n > 0) { if(ret >= n) { len = n-1; IPACMERR(" overflow detected \n"); } else { len = ret; } dest[len] = '\0'; memcpy(dest, src, len); } return ret; } size_t IPACM_Iface::strlcat(char *dest, const char *src, size_t n) { size_t dsize = strlen(dest); size_t len = strlen(src); size_t ret = dsize + len; if (dsize < n) { dest += dsize; n -= dsize; if (len >= n) { len = n - 1; IPACMERR(" overflow detected \n"); } dest[len] = '\0'; memcpy(dest, src, len); } else { IPACMERR(" dest buffer full\n"); } return ret; } ================================================ FILE: data-ipa-cfg-mgr/ipacm/src/IPACM_IfaceManager.cpp ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPACM_IfaceManager.cpp @brief This file implements the IPAM iface_manager functionality. @Author Skylar Chang */ #include #include #include #include #include #include #include #include #include #include iface_instances *IPACM_IfaceManager::head = NULL; IPACM_IfaceManager::IPACM_IfaceManager() { IPACM_EvtDispatcher::registr(IPA_CFG_CHANGE_EVENT, this); // register for IPA_CFG_CHANGE event IPACM_EvtDispatcher::registr(IPA_LINK_UP_EVENT, this); IPACM_EvtDispatcher::registr(IPA_WLAN_AP_LINK_UP_EVENT, this); // register for wlan AP-iface #ifndef FEATURE_IPA_ANDROID IPACM_EvtDispatcher::registr(IPA_WLAN_STA_LINK_UP_EVENT, this); // register for wlan STA-iface #endif /* not defined(FEATURE_IPA_ANDROID)*/ IPACM_EvtDispatcher::registr(IPA_USB_LINK_UP_EVENT, this); // register for wlan STA-iface IPACM_EvtDispatcher::registr(IPA_WAN_EMBMS_LINK_UP_EVENT, this); // register for wan eMBMS-iface return; } void IPACM_IfaceManager::event_callback(ipa_cm_event_id event, void *param) { int ipa_interface_index; ipacm_event_data_fid *evt_data = (ipacm_event_data_fid *)param; ipacm_event_data_mac *StaData = (ipacm_event_data_mac *)param; ipacm_ifacemgr_data ifmgr_data = {0}; switch(event) { case IPA_CFG_CHANGE_EVENT: IPACMDBG_H(" RESET IPACM_cfg \n"); IPACM_Iface::ipacmcfg->Init(); break; case IPA_LINK_UP_EVENT: IPACMDBG_H("link up %d: \n", evt_data->if_index); ipa_interface_index = IPACM_Iface::iface_ipa_index_query(evt_data->if_index); /* LTE-backhaul */ if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == EMBMS_IF) { IPACMDBG("WAN-EMBMS (%s) link already up, iface: %d: \n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,evt_data->if_index); } else if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == WAN_IF) { IPACMDBG_H("WAN-LTE (%s) link up, iface: %d: \n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,evt_data->if_index); ifmgr_data.if_index = evt_data->if_index; ifmgr_data.if_type = Q6_WAN; create_iface_instance(&ifmgr_data); } break; case IPA_USB_LINK_UP_EVENT: ipa_interface_index = IPACM_Iface::iface_ipa_index_query(evt_data->if_index); /* check if it's WAN_IF */ if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == WAN_IF) { /* usb-backhaul using sta_mode ECM_WAN*/ IPACMDBG_H("WAN-usb (%s) link up, iface: %d: \n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name, evt_data->if_index); ifmgr_data.if_index = evt_data->if_index; ifmgr_data.if_type = ECM_WAN; create_iface_instance(&ifmgr_data); } else { ifmgr_data.if_index = evt_data->if_index; ifmgr_data.if_type = Q6_WAN; create_iface_instance(&ifmgr_data); } break; case IPA_WLAN_AP_LINK_UP_EVENT: ipa_interface_index = IPACM_Iface::iface_ipa_index_query(evt_data->if_index); /* change iface category from unknown to WLAN_IF */ if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == UNKNOWN_IF) { IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat = WLAN_IF; IPACMDBG_H("WLAN AP (%s) link up, iface: %d: \n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,evt_data->if_index); ifmgr_data.if_index = evt_data->if_index; ifmgr_data.if_type = Q6_WAN; create_iface_instance(&ifmgr_data); } else { IPACMDBG_H("iface %s already up and act as %d mode: \n",IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat); } break; case IPA_WLAN_STA_LINK_UP_EVENT: ipa_interface_index = IPACM_Iface::iface_ipa_index_query(StaData->if_index); /* change iface category from unknown to WAN_IF */ if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == UNKNOWN_IF) { /* wlan-backhaul using sta_mode WLAN_WAN */ IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat = WAN_IF; IPACMDBG_H("WLAN STA (%s) link up, iface: %d: \n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name, StaData->if_index); ifmgr_data.if_index = StaData->if_index; ifmgr_data.if_type = WLAN_WAN; memcpy(ifmgr_data.mac_addr, StaData->mac_addr, sizeof(ifmgr_data.mac_addr)); create_iface_instance(&ifmgr_data); } else { IPACMDBG_H("iface %s already up and act as %d mode: \n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat); } break; /* Add new instance open for eMBMS iface and wan iface */ case IPA_WAN_EMBMS_LINK_UP_EVENT: ipa_interface_index = IPACM_Iface::iface_ipa_index_query(evt_data->if_index); /* change iface category from unknown to EMBMS_IF */ if (IPACM_Iface::ipacmcfg->ipacm_odu_enable == true) { IPACMDBG(" ODU-mode enable or not (%d) \n",IPACM_Iface::ipacmcfg->ipacm_odu_enable); if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == WAN_IF) { IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat=EMBMS_IF; IPACMDBG("WAN eMBMS (%s) link up, iface: %d: \n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,evt_data->if_index); ifmgr_data.if_index = StaData->if_index; ifmgr_data.if_type = Q6_WAN; create_iface_instance(&ifmgr_data); } else { IPACMDBG("iface %s already up and act as %d mode: \n",IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat); } } break; default: break; } return; } int IPACM_IfaceManager::create_iface_instance(ipacm_ifacemgr_data *param) { int if_index = param->if_index; ipacm_wan_iface_type is_sta_mode = param->if_type; int ipa_interface_index; ipa_interface_index = IPACM_Iface::iface_ipa_index_query(if_index); if(ipa_interface_index == INVALID_IFACE) { IPACMDBG_H("Unhandled interface received, fid: %d\n",if_index); return IPACM_SUCCESS; } /* check if duplicate instance*/ if(SearchInstance(ipa_interface_index) == IPA_INSTANCE_NOT_FOUND) { /* IPA_INSTANCE_NOT_FOUND */ switch(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat) { case LAN_IF: { IPACMDBG_H("Creating Lan interface\n"); IPACM_Lan *lan = new IPACM_Lan(ipa_interface_index); IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, lan); //IPACM_EvtDispatcher::registr(IPA_ROUTE_ADD_EVENT, lan); //IPACM_EvtDispatcher::registr(IPA_ROUTE_DEL_EVENT, lan); IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, lan); //IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT, lan); IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, lan); IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, lan); #ifdef FEATURE_IPA_ANDROID IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_TETHER, lan); IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6_TETHER, lan); IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_TETHER, lan); IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6_TETHER, lan); #else IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP, lan); IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6, lan); IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN, lan); IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6, lan); #endif IPACM_EvtDispatcher::registr(IPA_CFG_CHANGE_EVENT, lan); // register for IPA_CFG_CHANGE event IPACM_EvtDispatcher::registr(IPA_PRIVATE_SUBNET_CHANGE_EVENT, lan); // register for IPA_PRIVATE_SUBNET_CHANGE_EVENT event #ifdef FEATURE_ETH_BRIDGE_LE IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_WLAN_CLIENT_ADD_EVENT, lan); IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_WLAN_CLIENT_DEL_EVENT, lan); IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT, lan); IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_HDR_PROC_CTX_UNSET_EVENT, lan); #endif #ifdef FEATURE_IPA_ANDROID IPACM_EvtDispatcher::registr(IPA_TETHERING_STATS_UPDATE_EVENT, lan); #endif IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, lan); IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, lan); IPACMDBG_H("ipa_LAN (%s):ipa_index (%d) instance open/registr ok\n", lan->dev_name, lan->ipa_if_num); registr(ipa_interface_index, lan); /* solve the new_addr comes earlier issue */ IPACM_Iface::iface_addr_query(if_index); } break; case ETH_IF: { IPACMDBG_H("Creating ETH interface in router mode\n"); IPACM_Lan *ETH = new IPACM_Lan(ipa_interface_index); IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, ETH); IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, ETH); IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, ETH); IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, ETH); IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP, ETH); IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6, ETH); IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN, ETH); IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6, ETH); IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, ETH); IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, ETH); IPACMDBG_H("ipa_LAN (%s):ipa_index (%d) instance open/registr ok\n", ETH->dev_name, ETH->ipa_if_num); registr(ipa_interface_index, ETH); /* solve the new_addr comes earlier issue */ IPACM_Iface::iface_addr_query(if_index); } break; case ODU_IF: { if(IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == true) { IPACMDBG("Creating ODU interface in router mode\n"); IPACM_Lan *odu = new IPACM_Lan(ipa_interface_index); IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, odu); IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, odu); IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, odu); IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, odu); IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP, odu); IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6, odu); IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN, odu); IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6, odu); IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, odu); IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, odu); IPACMDBG("ipa_LAN (%s):ipa_index (%d) instance open/registr ok\n", odu->dev_name, odu->ipa_if_num); registr(ipa_interface_index, odu); /* solve the new_addr comes earlier issue */ IPACM_Iface::iface_addr_query(if_index); } else { IPACMDBG("Creating ODU interface in bridge mode\n"); IPACM_Lan *odu = new IPACM_Lan(ipa_interface_index); IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, odu); IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, odu); IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, odu); IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, odu); IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, odu); IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, odu); IPACMDBG("ipa_LAN (%s):ipa_index (%d) instance open/registr ok\n", odu->dev_name, odu->ipa_if_num); registr(ipa_interface_index, odu); /* solve the new_addr comes earlier issue */ IPACM_Iface::iface_addr_query(if_index); } } break; case WLAN_IF: { IPACMDBG_H("Creating WLan interface\n"); IPACM_Wlan *wl = new IPACM_Wlan(ipa_interface_index); IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, wl); IPACM_EvtDispatcher::registr(IPA_ROUTE_DEL_EVENT, wl); IPACM_EvtDispatcher::registr(IPA_WLAN_CLIENT_ADD_EVENT, wl); IPACM_EvtDispatcher::registr(IPA_WLAN_CLIENT_ADD_EVENT_EX, wl); IPACM_EvtDispatcher::registr(IPA_WLAN_CLIENT_DEL_EVENT, wl); IPACM_EvtDispatcher::registr(IPA_WLAN_CLIENT_POWER_SAVE_EVENT, wl); IPACM_EvtDispatcher::registr(IPA_WLAN_CLIENT_RECOVER_EVENT, wl); IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, wl); IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, wl); IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, wl); #ifdef FEATURE_IPA_ANDROID IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_TETHER, wl); IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6_TETHER, wl); IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_TETHER, wl); IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6_TETHER, wl); #else IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP, wl); IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6, wl); IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN, wl); IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6, wl); #endif IPACM_EvtDispatcher::registr(IPA_PRIVATE_SUBNET_CHANGE_EVENT, wl); // register for IPA_PRIVATE_SUBNET_CHANGE_EVENT event #ifdef FEATURE_ETH_BRIDGE_LE IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_USB_CLIENT_ADD_EVENT, wl); IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_USB_CLIENT_DEL_EVENT, wl); IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT, wl); IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_HDR_PROC_CTX_UNSET_EVENT, wl); #endif IPACM_EvtDispatcher::registr(IPA_WLAN_LINK_DOWN_EVENT, wl); IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, wl); #ifdef FEATURE_IPA_ANDROID IPACM_EvtDispatcher::registr(IPA_TETHERING_STATS_UPDATE_EVENT, wl); #endif IPACMDBG_H("ipa_WLAN (%s):ipa_index (%d) instance open/registr ok\n", wl->dev_name, wl->ipa_if_num); registr(ipa_interface_index, wl); /* solve the new_addr comes earlier issue */ IPACM_Iface::iface_addr_query(if_index); } break; case WAN_IF: { if((IPACM_Iface::ipacmcfg->ipacm_odu_enable == false) || (IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == true)) { IPACMDBG_H("Creating Wan interface\n"); IPACM_Wan *w; if(is_sta_mode == WLAN_WAN) { w = new IPACM_Wan(ipa_interface_index, is_sta_mode, param->mac_addr); } else { w = new IPACM_Wan(ipa_interface_index, is_sta_mode, NULL); } IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, w); #ifdef FEATURE_IPA_ANDROID IPACM_EvtDispatcher::registr(IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT, w); IPACM_EvtDispatcher::registr(IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT, w); if(is_sta_mode == Q6_WAN) { IPACM_EvtDispatcher::registr(IPA_NETWORK_STATS_UPDATE_EVENT, w); }; #else/* defined(FEATURE_IPA_ANDROID) */ IPACM_EvtDispatcher::registr(IPA_ROUTE_ADD_EVENT, w); IPACM_EvtDispatcher::registr(IPA_ROUTE_DEL_EVENT, w); #endif /* not defined(FEATURE_IPA_ANDROID)*/ IPACM_EvtDispatcher::registr(IPA_FIREWALL_CHANGE_EVENT, w); IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, w); IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, w); IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, w); IPACM_EvtDispatcher::registr(IPA_CFG_CHANGE_EVENT, w); // register for IPA_CFG_CHANGE event if(is_sta_mode == WLAN_WAN) { IPACM_EvtDispatcher::registr(IPA_WLAN_LINK_DOWN_EVENT, w); // for STA mode } else { IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, w); } IPACMDBG_H("ipa_WAN (%s):ipa_index (%d) instance open/registr ok\n", w->dev_name, w->ipa_if_num); registr(ipa_interface_index, w); /* solve the new_addr comes earlier issue */ IPACM_Iface::iface_addr_query(if_index); } } break; /* WAN-eMBMS instance */ case EMBMS_IF: { IPACMDBG("Creating Wan-eMBSM interface\n"); IPACM_Wan *embms = new IPACM_Wan(ipa_interface_index, is_sta_mode, NULL); IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, embms); IPACMDBG("ipa_WAN (%s):ipa_index (%d) instance open/registr ok\n", embms->dev_name, embms->ipa_if_num); registr(ipa_interface_index, embms); } break; default: IPACMDBG_H("Unhandled interface category received iface name: %s, category: %d\n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat); return IPACM_SUCCESS; } } return IPACM_SUCCESS; } int IPACM_IfaceManager::registr(int ipa_if_index, IPACM_Listener *obj) { iface_instances *tmp = head,*nw; nw = (iface_instances *)malloc(sizeof(iface_instances)); if(nw != NULL) { nw->ipa_if_index = ipa_if_index; nw->obj = obj; nw->next = NULL; } else { return IPACM_FAILURE; } if(head == NULL) { head = nw; } else { while(tmp->next) { tmp = tmp->next; } tmp->next = nw; } return IPACM_SUCCESS; } int IPACM_IfaceManager::deregistr(IPACM_Listener *param) { iface_instances *tmp = head,*tmp1,*prev = head; while(tmp != NULL) { if(tmp->obj == param) { tmp1 = tmp; if(tmp == head) { head = head->next; } else if(tmp->next == NULL) { prev->next = NULL; } else { prev->next = tmp->next; } tmp = tmp->next; free(tmp1); } else { prev = tmp; tmp = tmp->next; } } return IPACM_SUCCESS; } int IPACM_IfaceManager::SearchInstance(int ipa_if_index) { iface_instances *tmp = head; while(tmp != NULL) { if(ipa_if_index == tmp->ipa_if_index) { IPACMDBG_H("Find existed iface-instance name: %s\n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_index].iface_name); return IPA_INSTANCE_FOUND; } tmp = tmp->next; } IPACMDBG_H("No existed iface-instance name: %s,\n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_index].iface_name); return IPA_INSTANCE_NOT_FOUND; } ================================================ FILE: data-ipa-cfg-mgr/ipacm/src/IPACM_Lan.cpp ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPACM_Lan.cpp @brief This file implements the LAN iface functionality. @Author Skylar Chang */ #include #include #include #include "IPACM_Netlink.h" #include "IPACM_Lan.h" #include "IPACM_Wan.h" #include "IPACM_IfaceManager.h" #include "linux/rmnet_ipa_fd_ioctl.h" #include "linux/ipa_qmi_service_v01.h" #include "linux/msm_ipa.h" #include "IPACM_ConntrackListener.h" #include #include bool IPACM_Lan::odu_up = false; ipa_hdr_l2_type IPACM_Lan::usb_hdr_type = IPA_HDR_L2_NONE; ipa_hdr_l2_type IPACM_Lan::wlan_hdr_type = IPA_HDR_L2_NONE; uint32_t IPACM_Lan::usb_hdr_template_hdl = 0; uint32_t IPACM_Lan::wlan_hdr_template_hdl = 0; hdr_proc_ctx_info IPACM_Lan::usb_to_wlan_hdr_proc_ctx; hdr_proc_ctx_info IPACM_Lan::wlan_to_usb_hdr_proc_ctx; hdr_proc_ctx_info IPACM_Lan::wlan_to_wlan_hdr_proc_ctx; eth_bridge_subnet_client_info IPACM_Lan::eth_bridge_wlan_client[IPA_LAN_TO_LAN_MAX_WLAN_CLIENT]; eth_bridge_subnet_client_info IPACM_Lan::eth_bridge_usb_client[IPA_LAN_TO_LAN_MAX_USB_CLIENT]; int IPACM_Lan::num_wlan_client = 0; int IPACM_Lan::num_usb_client = 0; IPACM_Lan::IPACM_Lan(int iface_index) : IPACM_Iface(iface_index) { num_eth_client = 0; header_name_count = 0; ipv6_set = 0; ipv4_header_set = false; ipv6_header_set = false; odu_route_rule_v4_hdl = NULL; odu_route_rule_v6_hdl = NULL; eth_client = NULL; int m_fd_odu, ret = IPACM_SUCCESS; Nat_App = NatApp::GetInstance(); if (Nat_App == NULL) { IPACMERR("unable to get Nat App instance \n"); return; } /* support eth multiple clients */ if(iface_query != NULL) { if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat != WLAN_IF) { eth_client_len = (sizeof(ipa_eth_client)) + (iface_query->num_tx_props * sizeof(eth_client_rt_hdl)); eth_client = (ipa_eth_client *)calloc(IPA_MAX_NUM_ETH_CLIENTS, eth_client_len); if (eth_client == NULL) { IPACMERR("unable to allocate memory\n"); return; } } IPACMDBG_H(" IPACM->IPACM_Lan(%d) constructor: Tx:%d Rx:%d\n", ipa_if_num, iface_query->num_tx_props, iface_query->num_rx_props); #ifdef FEATURE_ETH_BRIDGE_LE if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == LAN_IF && tx_prop != NULL) { if(IPACM_Lan::usb_hdr_type != IPA_HDR_L2_NONE && tx_prop->tx[0].hdr_l2_type != IPACM_Lan::usb_hdr_type) { IPACMERR("The USB header format is not consistent! Now header format is %d.\n", tx_prop->tx[0].hdr_l2_type); } else { if(eth_bridge_get_hdr_template_hdl(&IPACM_Lan::usb_hdr_template_hdl) == IPACM_FAILURE) { IPACMERR("Failed to setup usb hdr template.\n"); } else { IPACM_Lan::usb_hdr_type = tx_prop->tx[0].hdr_l2_type; add_hdr_proc_ctx(); } } } #endif /* ODU routing table initilization */ if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF) { odu_route_rule_v4_hdl = (uint32_t *)calloc(iface_query->num_tx_props, sizeof(uint32_t)); odu_route_rule_v6_hdl = (uint32_t *)calloc(iface_query->num_tx_props, sizeof(uint32_t)); if ((odu_route_rule_v4_hdl == NULL) || (odu_route_rule_v6_hdl == NULL)) { IPACMERR("unable to allocate memory\n"); return; } } } num_wan_ul_fl_rule_v4 = 0; num_wan_ul_fl_rule_v6 = 0; memset(wan_ul_fl_rule_hdl_v4, 0, MAX_WAN_UL_FILTER_RULES * sizeof(uint32_t)); memset(wan_ul_fl_rule_hdl_v6, 0, MAX_WAN_UL_FILTER_RULES * sizeof(uint32_t)); memset(lan2lan_flt_rule_hdl_v4, 0, MAX_OFFLOAD_PAIR * sizeof(lan2lan_flt_rule_hdl)); num_lan2lan_flt_rule_v4 = 0; memset(lan2lan_flt_rule_hdl_v6, 0, MAX_OFFLOAD_PAIR * sizeof(lan2lan_flt_rule_hdl)); num_lan2lan_flt_rule_v6 = 0; memset(lan2lan_hdr_hdl_v4, 0, MAX_OFFLOAD_PAIR*sizeof(lan2lan_hdr_hdl)); memset(lan2lan_hdr_hdl_v6, 0, MAX_OFFLOAD_PAIR*sizeof(lan2lan_hdr_hdl)); memset(wlan_client_flt_rule_hdl_v4, 0, IPA_LAN_TO_LAN_MAX_WLAN_CLIENT * sizeof(lan2lan_flt_rule_hdl)); memset(wlan_client_flt_rule_hdl_v6, 0, IPA_LAN_TO_LAN_MAX_WLAN_CLIENT * sizeof(lan2lan_flt_rule_hdl)); is_active = true; memset(tcp_ctl_flt_rule_hdl_v4, 0, NUM_TCP_CTL_FLT_RULE*sizeof(uint32_t)); memset(tcp_ctl_flt_rule_hdl_v6, 0, NUM_TCP_CTL_FLT_RULE*sizeof(uint32_t)); is_mode_switch = false; if_ipv4_subnet =0; memset(private_fl_rule_hdl, 0, IPA_MAX_PRIVATE_SUBNET_ENTRIES * sizeof(uint32_t)); memset(ipv6_prefix_flt_rule_hdl, 0, NUM_IPV6_PREFIX_FLT_RULE * sizeof(uint32_t)); memset(ipv6_icmp_flt_rule_hdl, 0, NUM_IPV6_ICMP_FLT_RULE * sizeof(uint32_t)); modem_ul_v4_set = false; modem_ul_v6_set = false; /* ODU routing table initilization */ if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF) { /* only do one time ioctl to odu-driver to infrom in router or bridge mode*/ if (IPACM_Lan::odu_up != true) { m_fd_odu = open(IPACM_Iface::ipacmcfg->DEVICE_NAME_ODU, O_RDWR); if (0 == m_fd_odu) { IPACMERR("Failed opening %s.\n", IPACM_Iface::ipacmcfg->DEVICE_NAME_ODU); return ; } if(IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == true) { ret = ioctl(m_fd_odu, ODU_BRIDGE_IOC_SET_MODE, ODU_BRIDGE_MODE_ROUTER); IPACM_Iface::ipacmcfg->ipacm_odu_enable = true; } else { ret = ioctl(m_fd_odu, ODU_BRIDGE_IOC_SET_MODE, ODU_BRIDGE_MODE_BRIDGE); IPACM_Iface::ipacmcfg->ipacm_odu_enable = true; } if (ret) { IPACMERR("Failed tell odu-driver the mode\n"); } IPACMDBG("Tell odu-driver in router-mode(%d)\n", IPACM_Iface::ipacmcfg->ipacm_odu_router_mode); close(m_fd_odu); IPACM_Lan::odu_up = true; } } int i; each_client_rt_rule_count_v4 = 0; each_client_rt_rule_count_v6 = 0; if(iface_query != NULL && tx_prop != NULL) { for(i=0; inum_tx_props; i++) { if(tx_prop->tx[i].ip == IPA_IP_v4) { each_client_rt_rule_count_v4++; } else { each_client_rt_rule_count_v6++; } } } IPACMDBG_H("Need to add %d IPv4 and %d IPv6 routing rules for eth bridge for each client.\n", each_client_rt_rule_count_v4, each_client_rt_rule_count_v6); memset(eth_bridge_wlan_client_flt_info, 0, IPA_LAN_TO_LAN_MAX_WLAN_CLIENT * sizeof(eth_bridge_client_flt_info)); wlan_client_flt_info_count = 0; eth_bridge_usb_client_rt_info_v4 = NULL; eth_bridge_usb_client_rt_info_v6 = NULL; #ifdef FEATURE_ETH_BRIDGE_LE if(tx_prop != NULL) { client_rt_info_size_v4 = sizeof(eth_bridge_client_rt_info) + each_client_rt_rule_count_v4 * sizeof(uint32_t); eth_bridge_usb_client_rt_info_v4 = (eth_bridge_client_rt_info*)calloc(IPA_LAN_TO_LAN_MAX_USB_CLIENT, client_rt_info_size_v4); client_rt_info_size_v6 = sizeof(eth_bridge_client_rt_info) + each_client_rt_rule_count_v6 * sizeof(uint32_t); eth_bridge_usb_client_rt_info_v6 = (eth_bridge_client_rt_info*)calloc(IPA_LAN_TO_LAN_MAX_USB_CLIENT, client_rt_info_size_v6); } #endif usb_client_rt_info_count_v4 = 0; usb_client_rt_info_count_v6 = 0; #ifdef FEATURE_IPA_ANDROID /* set the IPA-client pipe enum */ if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == LAN_IF) { handle_tethering_client(false, IPACM_CLIENT_USB); } #endif return; } IPACM_Lan::~IPACM_Lan() { IPACM_EvtDispatcher::deregistr(this); IPACM_IfaceManager::deregistr(this); return; } /* LAN-iface's callback function */ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param) { if(is_active == false && event != IPA_LAN_DELETE_SELF) { IPACMDBG_H("The interface is no longer active, return.\n"); return; } int ipa_interface_index; ipacm_ext_prop* ext_prop; ipacm_event_iface_up* data_wan; ipacm_event_iface_up_tehter* data_wan_tether; switch (event) { case IPA_LINK_DOWN_EVENT: { ipacm_event_data_fid *data = (ipacm_event_data_fid *)param; ipa_interface_index = iface_ipa_index_query(data->if_index); if (ipa_interface_index == ipa_if_num) { IPACMDBG_H("Received IPA_LINK_DOWN_EVENT\n"); handle_down_evt(); IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface return; } } break; case IPA_CFG_CHANGE_EVENT: { if ( IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat != ipa_if_cate) { IPACMDBG_H("Received IPA_CFG_CHANGE_EVENT and category changed\n"); /* delete previous instance */ handle_down_evt(); IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface is_mode_switch = true; // need post internal usb-link up event return; } } break; case IPA_PRIVATE_SUBNET_CHANGE_EVENT: { ipacm_event_data_fid *data = (ipacm_event_data_fid *)param; /* internel event: data->if_index is ipa_if_index */ if (data->if_index == ipa_if_num) { IPACMDBG_H("Received IPA_PRIVATE_SUBNET_CHANGE_EVENT from itself posting, ignore\n"); return; } else { IPACMDBG_H("Received IPA_PRIVATE_SUBNET_CHANGE_EVENT from other LAN iface \n"); #ifdef FEATURE_IPA_ANDROID handle_private_subnet_android(IPA_IP_v4); #endif IPACMDBG_H(" delete old private subnet rules, use new sets \n"); return; } } break; case IPA_LAN_DELETE_SELF: { ipacm_event_data_fid *data = (ipacm_event_data_fid *)param; if(data->if_index == ipa_if_num) { IPACMDBG_H("Received IPA_LAN_DELETE_SELF event.\n"); IPACMDBG_H("ipa_LAN (%s):ipa_index (%d) instance close \n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, ipa_if_num); /* posting link-up event for cradle use-case */ if(is_mode_switch) { IPACMDBG_H("Posting IPA_USB_LINK_UP_EVENT event for (%s)\n", dev_name); ipacm_cmd_q_data evt_data; memset(&evt_data, 0, sizeof(evt_data)); ipacm_event_data_fid *data_fid = NULL; data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid)); if(data_fid == NULL) { IPACMERR("unable to allocate memory for IPA_USB_LINK_UP_EVENT data_fid\n"); return; } if(IPACM_Iface::ipa_get_if_index(dev_name, &(data_fid->if_index))) { IPACMERR("Error while getting interface index for %s device", dev_name); } evt_data.event = IPA_USB_LINK_UP_EVENT; evt_data.evt_data = data_fid; //IPACMDBG_H("Posting event:%d\n", evt_data.event); IPACM_EvtDispatcher::PostEvt(&evt_data); } delete this; } break; } case IPA_ADDR_ADD_EVENT: { ipacm_event_data_addr *data = (ipacm_event_data_addr *)param; ipa_interface_index = iface_ipa_index_query(data->if_index); if ( (data->iptype == IPA_IP_v4 && data->ipv4_addr == 0) || (data->iptype == IPA_IP_v6 && data->ipv6_addr[0] == 0 && data->ipv6_addr[1] == 0 && data->ipv6_addr[2] == 0 && data->ipv6_addr[3] == 0) ) { IPACMDBG_H("Invalid address, ignore IPA_ADDR_ADD_EVENT event\n"); return; } if (ipa_interface_index == ipa_if_num) { IPACMDBG_H("Received IPA_ADDR_ADD_EVENT\n"); /* only call ioctl for ODU iface with bridge mode */ if((IPACM_Iface::ipacmcfg->ipacm_odu_enable == true) && (IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == false) && (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF)) { if((data->iptype == IPA_IP_v6) && (num_dft_rt_v6 == 0)) { handle_addr_evt_odu_bridge(data); } #ifdef FEATURE_IPA_ANDROID add_dummy_private_subnet_flt_rule(data->iptype); handle_private_subnet_android(data->iptype); #else handle_private_subnet(data->iptype); #endif } else { /* check v4 not setup before, v6 can have 2 iface ip */ if( ((data->iptype != ip_type) && (ip_type != IPA_IP_MAX)) || ((data->iptype==IPA_IP_v6) && (num_dft_rt_v6!=MAX_DEFAULT_v6_ROUTE_RULES))) { IPACMDBG_H("Got IPA_ADDR_ADD_EVENT ip-family:%d, v6 num %d: \n",data->iptype,num_dft_rt_v6); /* ADD ipv6 icmp rule */ if ((num_dft_rt_v6 == 0) && (data->iptype == IPA_IP_v6)) { install_ipv6_icmp_flt_rule(); } if(handle_addr_evt(data) == IPACM_FAILURE) { return; } handle_private_subnet(data->iptype); if (IPACM_Wan::isWanUP(ipa_if_num)) { if(data->iptype == IPA_IP_v4 || data->iptype == IPA_IP_MAX) { if(IPACM_Wan::backhaul_is_sta_mode == false) { ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4); handle_wan_up_ex(ext_prop, IPA_IP_v4); } else { handle_wan_up(IPA_IP_v4); } } } if(IPACM_Wan::isWanUP_V6(ipa_if_num)) { if((data->iptype == IPA_IP_v6 || data->iptype == IPA_IP_MAX) && num_dft_rt_v6 == 1) { install_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix); if(IPACM_Wan::backhaul_is_sta_mode == false) { ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6); handle_wan_up_ex(ext_prop, IPA_IP_v6); } else { handle_wan_up(IPA_IP_v6); } } } /* Post event to NAT */ if (data->iptype == IPA_IP_v4) { ipacm_cmd_q_data evt_data; ipacm_event_iface_up *info; info = (ipacm_event_iface_up *) malloc(sizeof(ipacm_event_iface_up)); if (info == NULL) { IPACMERR("Unable to allocate memory\n"); return; } memcpy(info->ifname, dev_name, IF_NAME_LEN); info->ipv4_addr = data->ipv4_addr; info->addr_mask = IPACM_Iface::ipacmcfg->private_subnet_table[0].subnet_mask; evt_data.event = IPA_HANDLE_LAN_UP; evt_data.evt_data = (void *)info; /* Insert IPA_HANDLE_LAN_UP to command queue */ IPACMDBG_H("posting IPA_HANDLE_LAN_UP for IPv4 with below information\n"); IPACMDBG_H("IPv4 address:0x%x, IPv4 address mask:0x%x\n", info->ipv4_addr, info->addr_mask); IPACM_EvtDispatcher::PostEvt(&evt_data); } IPACMDBG_H("Finish handling IPA_ADDR_ADD_EVENT for ip-family(%d)\n", data->iptype); } IPACMDBG_H("Finish handling IPA_ADDR_ADD_EVENT for ip-family(%d)\n", data->iptype); /* checking if SW-RT_enable */ if (IPACM_Iface::ipacmcfg->ipa_sw_rt_enable == true) { /* handle software routing enable event*/ IPACMDBG_H("IPA_SW_ROUTING_ENABLE for iface: %s \n",IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name); handle_software_routing_enable(); } } } } break; #ifdef FEATURE_IPA_ANDROID case IPA_HANDLE_WAN_UP_TETHER: IPACMDBG_H("Received IPA_HANDLE_WAN_UP_TETHER event\n"); data_wan_tether = (ipacm_event_iface_up_tehter*)param; if(data_wan_tether == NULL) { IPACMERR("No event data is found.\n"); return; } IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->is_sta, data_wan_tether->if_index_tether, IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name); if (data_wan_tether->if_index_tether == ipa_if_num) { if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX) { if(data_wan_tether->is_sta == false) { ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4); handle_wan_up_ex(ext_prop, IPA_IP_v4); } else { handle_wan_up(IPA_IP_v4); } } } break; case IPA_HANDLE_WAN_UP_V6_TETHER: IPACMDBG_H("Received IPA_HANDLE_WAN_UP_V6_TETHER event\n"); data_wan_tether = (ipacm_event_iface_up_tehter*)param; if(data_wan_tether == NULL) { IPACMERR("No event data is found.\n"); return; } IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->is_sta, data_wan_tether->if_index_tether, IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name); if (data_wan_tether->if_index_tether == ipa_if_num) { if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX) { install_ipv6_prefix_flt_rule(data_wan_tether->ipv6_prefix); if(data_wan_tether->is_sta == false) { ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6); handle_wan_up_ex(ext_prop, IPA_IP_v6); } else { handle_wan_up(IPA_IP_v6); } } } break; case IPA_HANDLE_WAN_DOWN_TETHER: IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_TETHER event\n"); data_wan_tether = (ipacm_event_iface_up_tehter*)param; if(data_wan_tether == NULL) { IPACMERR("No event data is found.\n"); return; } IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->is_sta, data_wan_tether->if_index_tether, IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name); if (data_wan_tether->if_index_tether == ipa_if_num) { if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX) { handle_wan_down(data_wan_tether->is_sta); } } break; case IPA_HANDLE_WAN_DOWN_V6_TETHER: IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_V6_TETHER event\n"); data_wan_tether = (ipacm_event_iface_up_tehter*)param; if(data_wan_tether == NULL) { IPACMERR("No event data is found.\n"); return; } IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->is_sta, data_wan_tether->if_index_tether, IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name); if (data_wan_tether->if_index_tether == ipa_if_num) { /* clean up v6 RT rules*/ IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_V6_TETHER in LAN-instance and need clean up client IPv6 address \n"); /* reset usb-client ipv6 rt-rules */ handle_lan_client_reset_rt(IPA_IP_v6); if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX) { handle_wan_down_v6(data_wan_tether->is_sta); } } break; #else case IPA_HANDLE_WAN_UP: IPACMDBG_H("Received IPA_HANDLE_WAN_UP event\n"); data_wan = (ipacm_event_iface_up*)param; if(data_wan == NULL) { IPACMERR("No event data is found.\n"); return; } IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta); if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX) { if(data_wan->is_sta == false) { ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4); handle_wan_up_ex(ext_prop, IPA_IP_v4); } else { handle_wan_up(IPA_IP_v4); } } break; case IPA_HANDLE_WAN_UP_V6: IPACMDBG_H("Received IPA_HANDLE_WAN_UP_V6 event\n"); data_wan = (ipacm_event_iface_up*)param; if(data_wan == NULL) { IPACMERR("No event data is found.\n"); return; } IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta); if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX) { install_ipv6_prefix_flt_rule(data_wan->ipv6_prefix); if(data_wan->is_sta == false) { ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6); handle_wan_up_ex(ext_prop, IPA_IP_v6); } else { handle_wan_up(IPA_IP_v6); } } break; case IPA_HANDLE_WAN_DOWN: IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN event\n"); data_wan = (ipacm_event_iface_up*)param; if(data_wan == NULL) { IPACMERR("No event data is found.\n"); return; } IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta); if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX) { handle_wan_down(data_wan->is_sta); } break; case IPA_HANDLE_WAN_DOWN_V6: IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_V6 event\n"); data_wan = (ipacm_event_iface_up*)param; if(data_wan == NULL) { IPACMERR("No event data is found.\n"); return; } /* clean up v6 RT rules*/ IPACMDBG_H("Received IPA_WAN_V6_DOWN in LAN-instance and need clean up client IPv6 address \n"); /* reset usb-client ipv6 rt-rules */ handle_lan_client_reset_rt(IPA_IP_v6); IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta); if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX) { handle_wan_down_v6(data_wan->is_sta); } break; #endif case IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT: { ipacm_event_data_all *data = (ipacm_event_data_all *)param; ipa_interface_index = iface_ipa_index_query(data->if_index); IPACMDBG_H("check iface %s category: %d\n",IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat); if ((ipa_interface_index == ipa_if_num) && (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF)) { IPACMDBG("ODU iface got v4-ip \n"); /* first construc ODU full header */ if ((ipv4_header_set == false) && (ipv6_header_set == false)) { handle_odu_hdr_init(data->mac_addr); handle_odu_route_add(); /* construct ODU RT tbl*/ IPACMDBG("construct ODU header and route rules \n"); } /* if ODU in bridge mode, directly return */ if(IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == false) { return; } } if (ipa_interface_index == ipa_if_num) { IPACMDBG_H("ETH iface got client \n"); /* first construc ETH full header */ handle_eth_hdr_init(data->mac_addr); handle_lan2lan_client_active(data, IPA_LAN_CLIENT_ACTIVE); IPACMDBG_H("construct ETH header and route rules \n"); /* Associate with IP and construct RT-rule */ if (handle_eth_client_ipaddr(data) == IPACM_FAILURE) { return; } handle_eth_client_route_rule(data->mac_addr, data->iptype); if (data->iptype == IPA_IP_v4) { /* Add NAT rules after ipv4 RT rules are set */ CtList->HandleNeighIpAddrAddEvt(data); } #ifdef FEATURE_ETH_BRIDGE_LE if(IPACM_Lan::wlan_to_usb_hdr_proc_ctx.valid == true) { eth_bridge_add_usb_client_rt_rule(data->mac_addr, IPA_IP_v4); eth_bridge_add_usb_client_rt_rule(data->mac_addr, IPA_IP_v6); } eth_bridge_post_lan_client_event(data->mac_addr, IPA_ETH_BRIDGE_USB_CLIENT_ADD_EVENT); eth_bridge_add_usb_client(data->mac_addr); #endif return; } } break; case IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT: { ipacm_event_data_all *data = (ipacm_event_data_all *)param; ipa_interface_index = iface_ipa_index_query(data->if_index); IPACMDBG_H("check iface %s category: %d\n",IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat); if (ipa_interface_index == ipa_if_num) { IPACMDBG_H("ETH iface delete client \n"); handle_eth_client_down_evt(data->mac_addr); handle_lan2lan_client_active(data, IPA_LAN_CLIENT_INACTIVE); return; } } break; case IPA_SW_ROUTING_ENABLE: IPACMDBG_H("Received IPA_SW_ROUTING_ENABLE\n"); /* handle software routing enable event*/ handle_software_routing_enable(); break; case IPA_SW_ROUTING_DISABLE: IPACMDBG_H("Received IPA_SW_ROUTING_DISABLE\n"); /* handle software routing disable event*/ handle_software_routing_disable(); break; case IPA_ETH_BRIDGE_WLAN_CLIENT_ADD_EVENT: { IPACMDBG_H("Received IPA_ETH_BRIDGE_WLAN_CLIENT_ADD_EVENT event.\n"); ipacm_event_data_mac* mac = (ipacm_event_data_mac*)param; if(mac != NULL) { if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX) { eth_bridge_add_wlan_client_flt_rule(mac->mac_addr, IPA_IP_v4); } if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX) { eth_bridge_add_wlan_client_flt_rule(mac->mac_addr, IPA_IP_v6); } } else { IPACMERR("Event MAC is empty.\n"); } } break; case IPA_ETH_BRIDGE_WLAN_CLIENT_DEL_EVENT: { IPACMDBG_H("Received IPA_ETH_BRIDGE_WLAN_CLIENT_DEL_EVENT event.\n"); ipacm_event_data_mac* mac = (ipacm_event_data_mac*)param; if(mac != NULL) { if(eth_bridge_del_wlan_client_flt_rule(mac->mac_addr) == IPACM_FAILURE) { IPACMDBG_H("Failed to delete wlan client MAC based flt rule.\n"); } } else { IPACMERR("Event MAC is empty.\n"); } } break; case IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT: { IPACMDBG_H("Received IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT event.\n"); int i; ipacm_event_data_fid* fid = (ipacm_event_data_fid*)param; if(fid == NULL) { IPACMERR("Event data is empty.\n"); return; } if(fid->if_index == ipa_if_num) { IPACMDBG_H("The event was sent by the same interface, ignore.\n"); return; } for(i=0; iif_index == ipa_if_num) { IPACMDBG_H("The event was sent by the same interface, ignore.\n"); return; } for(i=0; iipa_stats_type); IPACMDBG("Received %d UL, %d DL pipe stats\n",data->ul_src_pipe_stats_list_len, data->dl_dst_pipe_stats_list_len); if (data->ipa_stats_type != QMI_IPA_STATS_TYPE_PIPE_V01) { IPACMERR("not valid pipe stats enum(%d)\n", data->ipa_stats_type); return; } handle_tethering_stats_event(data); } } } break; default: break; } return; } /* delete filter rule for wan_down event for IPv4*/ int IPACM_Lan::handle_wan_down(bool is_sta_mode) { ipa_fltr_installed_notif_req_msg_v01 flt_index; int fd; fd = open(IPA_DEVICE_NAME, O_RDWR); if (0 == fd) { IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME); return IPACM_FAILURE; } #ifdef FEATURE_ETH_BRIDGE_LE flt_rule_count_v4 = IPV4_DEFAULT_FILTERTING_RULES + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPACM_Iface::ipacmcfg->ipa_num_private_subnet; #else #ifdef CT_OPT flt_rule_count_v4 = IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + NUM_TCP_CTL_FLT_RULE + IPACM_Iface::ipacmcfg->ipa_num_private_subnet; #else flt_rule_count_v4 = IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet; #endif #ifdef FEATURE_IPA_ANDROID flt_rule_count_v4 = flt_rule_count_v4 - IPACM_Iface::ipacmcfg->ipa_num_private_subnet + IPA_MAX_PRIVATE_SUBNET_ENTRIES; #endif #endif if(is_sta_mode == false) { if (num_wan_ul_fl_rule_v4 > MAX_WAN_UL_FILTER_RULES) { IPACMERR("number of wan_ul_fl_rule_v4 (%d) > MAX_WAN_UL_FILTER_RULES (%d), aborting...\n", num_wan_ul_fl_rule_v4, MAX_WAN_UL_FILTER_RULES); close(fd); return IPACM_FAILURE; } if (m_filtering.DeleteFilteringHdls(wan_ul_fl_rule_hdl_v4, IPA_IP_v4, num_wan_ul_fl_rule_v4) == false) { IPACMERR("Error Deleting RuleTable(1) to Filtering, aborting...\n"); close(fd); return IPACM_FAILURE; } memset(wan_ul_fl_rule_hdl_v4, 0, MAX_WAN_UL_FILTER_RULES * sizeof(uint32_t)); num_wan_ul_fl_rule_v4 = 0; modem_ul_v4_set = false; memset(&flt_index, 0, sizeof(flt_index)); flt_index.source_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[0].src_pipe); flt_index.install_status = IPA_QMI_RESULT_SUCCESS_V01; flt_index.filter_index_list_len = 0; flt_index.embedded_pipe_index_valid = 1; flt_index.embedded_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, IPA_CLIENT_APPS_LAN_WAN_PROD); flt_index.retain_header_valid = 1; flt_index.retain_header = 0; flt_index.embedded_call_mux_id_valid = 1; flt_index.embedded_call_mux_id = IPACM_Iface::ipacmcfg->GetQmapId(); if(false == m_filtering.SendFilteringRuleIndex(&flt_index)) { IPACMERR("Error sending filtering rule index, aborting...\n"); close(fd); return IPACM_FAILURE; } } else { if (m_filtering.DeleteFilteringHdls(&lan_wan_fl_rule_hdl[0], IPA_IP_v4, 1) == false) { IPACMERR("Error Adding RuleTable(1) to Filtering, aborting...\n"); close(fd); return IPACM_FAILURE; } } close(fd); return IPACM_SUCCESS; } /* handle new_address event*/ int IPACM_Lan::handle_addr_evt(ipacm_event_data_addr *data) { struct ipa_ioc_add_rt_rule *rt_rule; struct ipa_rt_rule_add *rt_rule_entry; const int NUM_RULES = 1; int num_ipv6_addr; int res = IPACM_SUCCESS; IPACMDBG_H("set route/filter rule ip-type: %d \n", data->iptype); /* Add private subnet*/ #ifdef FEATURE_IPA_ANDROID if (data->iptype == IPA_IP_v4) { IPACMDBG_H("current IPACM private subnet_addr number(%d)\n", IPACM_Iface::ipacmcfg->ipa_num_private_subnet); if_ipv4_subnet = (data->ipv4_addr >> 8) << 8; IPACMDBG_H(" Add IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet); if(IPACM_Iface::ipacmcfg->AddPrivateSubnet(if_ipv4_subnet, ipa_if_num) == false) { IPACMERR(" can't Add IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet); } } #endif /* defined(FEATURE_IPA_ANDROID)*/ if (data->iptype == IPA_IP_v4) { rt_rule = (struct ipa_ioc_add_rt_rule *) calloc(1, sizeof(struct ipa_ioc_add_rt_rule) + NUM_RULES * sizeof(struct ipa_rt_rule_add)); if (!rt_rule) { IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n"); return IPACM_FAILURE; } rt_rule->commit = 1; rt_rule->num_rules = NUM_RULES; rt_rule->ip = data->iptype; rt_rule_entry = &rt_rule->rules[0]; rt_rule_entry->at_rear = false; rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS; //go to A5 rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name); rt_rule_entry->rule.attrib.u.v4.dst_addr = data->ipv4_addr; rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF; if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); res = IPACM_FAILURE; goto fail; } else if (rt_rule_entry->status) { IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status); res = rt_rule_entry->status; goto fail; } dft_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl; IPACMDBG_H("ipv4 iface rt-rule hdl1=0x%x\n", dft_rt_rule_hdl[0]); /* initial multicast/broadcast/fragment filter rule */ #ifdef FEATURE_ETH_BRIDGE_LE init_fl_rule(data->iptype); eth_bridge_add_wlan_guest_ap_flt_rule(data->iptype); eth_bridge_handle_dummy_wlan_client_flt_rule(data->iptype); eth_bridge_handle_dummy_usb_client_flt_rule(data->iptype); eth_bridge_install_cache_wlan_client_flt_rule(data->iptype); eth_bridge_install_cache_usb_client_flt_rule(data->iptype); #else #ifdef CT_OPT install_tcp_ctl_flt_rule(IPA_IP_v4); #endif init_fl_rule(data->iptype); add_dummy_lan2lan_flt_rule(data->iptype); #endif } else { /* check if see that v6-addr already or not*/ for(num_ipv6_addr=0;num_ipv6_addripv6_addr[0]) && (ipv6_addr[num_ipv6_addr][1] == data->ipv6_addr[1]) && (ipv6_addr[num_ipv6_addr][2] == data->ipv6_addr[2]) && (ipv6_addr[num_ipv6_addr][3] == data->ipv6_addr[3])) { return IPACM_FAILURE; break; } } rt_rule = (struct ipa_ioc_add_rt_rule *) calloc(1, sizeof(struct ipa_ioc_add_rt_rule) + NUM_RULES * sizeof(struct ipa_rt_rule_add)); if (!rt_rule) { IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n"); return IPACM_FAILURE; } rt_rule->commit = 1; rt_rule->num_rules = NUM_RULES; rt_rule->ip = data->iptype; strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_v6.name); rt_rule_entry = &rt_rule->rules[0]; rt_rule_entry->at_rear = false; rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS; //go to A5 rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = data->ipv6_addr[0]; rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = data->ipv6_addr[1]; rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = data->ipv6_addr[2]; rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = data->ipv6_addr[3]; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF; ipv6_addr[num_dft_rt_v6][0] = data->ipv6_addr[0]; ipv6_addr[num_dft_rt_v6][1] = data->ipv6_addr[1]; ipv6_addr[num_dft_rt_v6][2] = data->ipv6_addr[2]; ipv6_addr[num_dft_rt_v6][3] = data->ipv6_addr[3]; if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); res = IPACM_FAILURE; goto fail; } else if (rt_rule_entry->status) { IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status); res = rt_rule_entry->status; goto fail; } dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6] = rt_rule_entry->rt_rule_hdl; /* setup same rule for v6_wan table*/ strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name); if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); res = IPACM_FAILURE; goto fail; } else if (rt_rule_entry->status) { IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status); res = rt_rule_entry->status; goto fail; } dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1] = rt_rule_entry->rt_rule_hdl; IPACMDBG_H("ipv6 wan iface rt-rule hdl=0x%x hdl=0x%x, num_dft_rt_v6: %d \n", dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6], dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1],num_dft_rt_v6); if (num_dft_rt_v6 == 0) { /* initial multicast/broadcast/fragment filter rule */ #ifdef FEATURE_ETH_BRIDGE_LE eth_bridge_add_wlan_guest_ap_flt_rule(data->iptype); eth_bridge_handle_dummy_wlan_client_flt_rule(data->iptype); eth_bridge_handle_dummy_usb_client_flt_rule(data->iptype); eth_bridge_install_cache_wlan_client_flt_rule(data->iptype); eth_bridge_install_cache_usb_client_flt_rule(data->iptype); init_fl_rule(data->iptype); #else #ifdef CT_OPT install_tcp_ctl_flt_rule(IPA_IP_v6); #endif add_dummy_lan2lan_flt_rule(data->iptype); init_fl_rule(data->iptype); #endif } num_dft_rt_v6++; IPACMDBG_H("number of default route rules %d\n", num_dft_rt_v6); } IPACMDBG_H("finish route/filter rule ip-type: %d, res(%d)\n", data->iptype, res); fail: free(rt_rule); return res; } /* configure private subnet filter rules*/ int IPACM_Lan::handle_private_subnet(ipa_ip_type iptype) { struct ipa_flt_rule_add flt_rule_entry; int i; ipa_ioc_add_flt_rule *m_pFilteringTable; IPACMDBG_H("lan->handle_private_subnet(); set route/filter rule \n"); if (rx_prop == NULL) { IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); return IPACM_SUCCESS; } if (iptype == IPA_IP_v4) { m_pFilteringTable = (struct ipa_ioc_add_flt_rule *) calloc(1, sizeof(struct ipa_ioc_add_flt_rule) + (IPACM_Iface::ipacmcfg->ipa_num_private_subnet) * sizeof(struct ipa_flt_rule_add) ); if (!m_pFilteringTable) { PERROR("Error Locate ipa_flt_rule_add memory...\n"); return IPACM_FAILURE; } m_pFilteringTable->commit = 1; m_pFilteringTable->ep = rx_prop->rx[0].src_pipe; m_pFilteringTable->global = false; m_pFilteringTable->ip = IPA_IP_v4; m_pFilteringTable->num_rules = (uint8_t)IPACM_Iface::ipacmcfg->ipa_num_private_subnet; if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_lan_v4)) { IPACMERR("LAN m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_lan_v4=0x%p) Failed.\n", &IPACM_Iface::ipacmcfg->rt_tbl_lan_v4); free(m_pFilteringTable); return IPACM_FAILURE; } /* Make LAN-traffic always go A5, use default IPA-RT table */ if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_default_v4)) { IPACMERR("LAN m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_default_v4=0x%p) Failed.\n", &IPACM_Iface::ipacmcfg->rt_tbl_default_v4); free(m_pFilteringTable); return IPACM_FAILURE; } for (i = 0; i < (IPACM_Iface::ipacmcfg->ipa_num_private_subnet); i++) { memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); flt_rule_entry.at_rear = true; flt_rule_entry.rule.retain_hdr = 1; flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; /* Support priave subnet feature including guest-AP can't talk to primary AP etc */ flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_default_v4.hdl; IPACMDBG_H(" private filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_default_v4.name); memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask; flt_rule_entry.rule.attrib.u.v4.dst_addr = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_addr; memcpy(&(m_pFilteringTable->rules[i]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); IPACMDBG_H("Loop %d 5\n", i); } if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) { IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n"); free(m_pFilteringTable); return IPACM_FAILURE; } flt_rule_count_v4 += IPACM_Iface::ipacmcfg->ipa_num_private_subnet; /* copy filter rule hdls */ for (i = 0; i < IPACM_Iface::ipacmcfg->ipa_num_private_subnet; i++) { private_fl_rule_hdl[i] = m_pFilteringTable->rules[i].flt_rule_hdl; } free(m_pFilteringTable); } else { IPACMDBG_H("No private subnet rules for ipv6 iface %s\n", dev_name); } return IPACM_SUCCESS; } /* for STA mode wan up: configure filter rule for wan_up event*/ int IPACM_Lan::handle_wan_up(ipa_ip_type ip_type) { struct ipa_flt_rule_add flt_rule_entry; int len = 0; ipa_ioc_add_flt_rule *m_pFilteringTable; IPACMDBG_H("set WAN interface as default filter rule\n"); if (rx_prop == NULL) { IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); return IPACM_SUCCESS; } if(ip_type == IPA_IP_v4) { len = sizeof(struct ipa_ioc_add_flt_rule) + (1 * sizeof(struct ipa_flt_rule_add)); m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)calloc(1, len); if (m_pFilteringTable == NULL) { PERROR("Error Locate ipa_flt_rule_add memory...\n"); return IPACM_FAILURE; } m_pFilteringTable->commit = 1; m_pFilteringTable->ep = rx_prop->rx[0].src_pipe; m_pFilteringTable->global = false; m_pFilteringTable->ip = IPA_IP_v4; m_pFilteringTable->num_rules = (uint8_t)1; IPACMDBG_H("Retrieving routing hanle for table: %s\n", IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.name); if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_wan_v4)) { IPACMERR("m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_wan_v4=0x%p) Failed.\n", &IPACM_Iface::ipacmcfg->rt_tbl_wan_v4); free(m_pFilteringTable); return IPACM_FAILURE; } IPACMDBG_H("Routing hanle for table: %d\n", IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.hdl); memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); // Zero All Fields flt_rule_entry.at_rear = true; flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.action = IPA_PASS_TO_SRC_NAT; //IPA_PASS_TO_ROUTING flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.hdl; memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x0; flt_rule_entry.rule.attrib.u.v4.dst_addr = 0x0; memcpy(&m_pFilteringTable->rules[0], &flt_rule_entry, sizeof(flt_rule_entry)); if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) { IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n"); free(m_pFilteringTable); return IPACM_FAILURE; } else { IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status); } /* copy filter hdls */ lan_wan_fl_rule_hdl[0] = m_pFilteringTable->rules[0].flt_rule_hdl; free(m_pFilteringTable); } else if(ip_type == IPA_IP_v6) { /* add default v6 filter rule */ m_pFilteringTable = (struct ipa_ioc_add_flt_rule *) calloc(1, sizeof(struct ipa_ioc_add_flt_rule) + 1 * sizeof(struct ipa_flt_rule_add)); if (!m_pFilteringTable) { PERROR("Error Locate ipa_flt_rule_add memory...\n"); return IPACM_FAILURE; } m_pFilteringTable->commit = 1; m_pFilteringTable->ep = rx_prop->rx[0].src_pipe; m_pFilteringTable->global = false; m_pFilteringTable->ip = IPA_IP_v6; m_pFilteringTable->num_rules = (uint8_t)1; if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_v6)) { IPACMERR("m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_v6=0x%p) Failed.\n", &IPACM_Iface::ipacmcfg->rt_tbl_v6); free(m_pFilteringTable); return IPACM_FAILURE; } memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); flt_rule_entry.at_rear = true; flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_v6.hdl; memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0X00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000; memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) { IPACMERR("Error Adding Filtering rule, aborting...\n"); free(m_pFilteringTable); return IPACM_FAILURE; } else { IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status); } /* copy filter hdls */ dft_v6fl_rule_hdl[IPV6_DEFAULT_FILTERTING_RULES] = m_pFilteringTable->rules[0].flt_rule_hdl; free(m_pFilteringTable); } return IPACM_SUCCESS; } int IPACM_Lan::handle_wan_up_ex(ipacm_ext_prop* ext_prop, ipa_ip_type iptype) { int fd, ret = IPACM_SUCCESS, cnt; IPACM_Config* ipacm_config = IPACM_Iface::ipacmcfg; struct ipa_ioc_write_qmapid mux; if(rx_prop != NULL) { /* give mud ID to IPA-driver for WLAN/LAN pkts */ fd = open(IPA_DEVICE_NAME, O_RDWR); if (0 == fd) { IPACMDBG_H("Failed opening %s.\n", IPA_DEVICE_NAME); return IPACM_FAILURE; } mux.qmap_id = ipacm_config->GetQmapId(); for(cnt=0; cntnum_rx_props; cnt++) { mux.client = rx_prop->rx[cnt].src_pipe; ret = ioctl(fd, IPA_IOC_WRITE_QMAPID, &mux); if (ret) { IPACMERR("Failed to write mux id %d\n", mux.qmap_id); close(fd); return IPACM_FAILURE; } } close(fd); } /* check only add static UL filter rule once */ if (num_dft_rt_v6 ==1 && iptype ==IPA_IP_v6 && modem_ul_v6_set == false) { IPACMDBG_H("IPA_IP_v6 num_dft_rt_v6 %d modem_ul_v6_set: %d\n", num_dft_rt_v6, modem_ul_v6_set); ret = handle_uplink_filter_rule(ext_prop, iptype); modem_ul_v6_set = true; } else if (iptype ==IPA_IP_v4 && modem_ul_v4_set == false) { IPACMDBG_H("IPA_IP_v4 modem_ul_v4_set %d\n", modem_ul_v4_set); ret = handle_uplink_filter_rule(ext_prop, iptype); modem_ul_v4_set = true; } else { IPACMDBG_H("ip-type: %d modem_ul_v4_set: %d, modem_ul_v6_set %d\n", iptype, modem_ul_v4_set, modem_ul_v6_set); } return ret; } /* handle ETH client initial, construct full headers (tx property) */ int IPACM_Lan::handle_eth_hdr_init(uint8_t *mac_addr) { #define ETH_IFACE_INDEX_LEN 2 int res = IPACM_SUCCESS, len = 0; char index[ETH_IFACE_INDEX_LEN]; struct ipa_ioc_copy_hdr sCopyHeader; struct ipa_ioc_add_hdr *pHeaderDescriptor = NULL; uint32_t cnt; int clnt_indx; clnt_indx = get_eth_client_index(mac_addr); if (clnt_indx != IPACM_INVALID_INDEX) { IPACMERR("eth client is found/attached already with index %d \n", clnt_indx); return IPACM_FAILURE; } /* add header to IPA */ if (num_eth_client >= IPA_MAX_NUM_ETH_CLIENTS) { IPACMERR("Reached maximum number(%d) of eth clients\n", IPA_MAX_NUM_ETH_CLIENTS); return IPACM_FAILURE; } IPACMDBG_H("ETH client number: %d\n", num_eth_client); memcpy(get_client_memptr(eth_client, num_eth_client)->mac, mac_addr, sizeof(get_client_memptr(eth_client, num_eth_client)->mac)); IPACMDBG_H("Received Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); IPACMDBG_H("stored MAC %02x:%02x:%02x:%02x:%02x:%02x\n", get_client_memptr(eth_client, num_eth_client)->mac[0], get_client_memptr(eth_client, num_eth_client)->mac[1], get_client_memptr(eth_client, num_eth_client)->mac[2], get_client_memptr(eth_client, num_eth_client)->mac[3], get_client_memptr(eth_client, num_eth_client)->mac[4], get_client_memptr(eth_client, num_eth_client)->mac[5]); /* add header to IPA */ if(tx_prop != NULL) { len = sizeof(struct ipa_ioc_add_hdr) + (1 * sizeof(struct ipa_hdr_add)); pHeaderDescriptor = (struct ipa_ioc_add_hdr *)calloc(1, len); if (pHeaderDescriptor == NULL) { IPACMERR("calloc failed to allocate pHeaderDescriptor\n"); return IPACM_FAILURE; } /* copy partial header for v4*/ for (cnt=0; cntnum_tx_props; cnt++) { if(tx_prop->tx[cnt].ip==IPA_IP_v4) { IPACMDBG_H("Got partial v4-header name from %d tx props\n", cnt); memset(&sCopyHeader, 0, sizeof(sCopyHeader)); memcpy(sCopyHeader.name, tx_prop->tx[cnt].hdr_name, sizeof(sCopyHeader.name)); IPACMDBG_H("header name: %s in tx:%d\n", sCopyHeader.name,cnt); if (m_header.CopyHeader(&sCopyHeader) == false) { PERROR("ioctl copy header failed"); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial); IPACMDBG_H("header eth2_ofst_valid: %d, eth2_ofst: %d\n", sCopyHeader.is_eth2_ofst_valid, sCopyHeader.eth2_ofst); if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE) { IPACMERR("header oversize\n"); res = IPACM_FAILURE; goto fail; } else { memcpy(pHeaderDescriptor->hdr[0].hdr, sCopyHeader.hdr, sCopyHeader.hdr_len); } /* copy client mac_addr to partial header */ if (sCopyHeader.is_eth2_ofst_valid) { memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst], mac_addr, IPA_MAC_ADDR_SIZE); } pHeaderDescriptor->commit = true; pHeaderDescriptor->num_hdrs = 1; memset(pHeaderDescriptor->hdr[0].name, 0, sizeof(pHeaderDescriptor->hdr[0].name)); snprintf(index,sizeof(index), "%d", ipa_if_num); strlcpy(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)); if (strlcat(pHeaderDescriptor->hdr[0].name, IPA_ETH_HDR_NAME_v4, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX) { IPACMERR(" header name construction failed exceed length (%d)\n", strlen(pHeaderDescriptor->hdr[0].name)); res = IPACM_FAILURE; goto fail; } snprintf(index,sizeof(index), "%d", header_name_count); if (strlcat(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX) { IPACMERR(" header name construction failed exceed length (%d)\n", strlen(pHeaderDescriptor->hdr[0].name)); res = IPACM_FAILURE; goto fail; } pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len; pHeaderDescriptor->hdr[0].hdr_hdl = -1; pHeaderDescriptor->hdr[0].is_partial = 0; pHeaderDescriptor->hdr[0].status = -1; if (m_header.AddHeader(pHeaderDescriptor) == false || pHeaderDescriptor->hdr[0].status != 0) { IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status); res = IPACM_FAILURE; goto fail; } get_client_memptr(eth_client, num_eth_client)->hdr_hdl_v4 = pHeaderDescriptor->hdr[0].hdr_hdl; IPACMDBG_H("eth-client(%d) v4 full header name:%s header handle:(0x%x)\n", num_eth_client, pHeaderDescriptor->hdr[0].name, get_client_memptr(eth_client, num_eth_client)->hdr_hdl_v4); get_client_memptr(eth_client, num_eth_client)->ipv4_header_set=true; break; } } /* copy partial header for v6*/ for (cnt=0; cntnum_tx_props; cnt++) { if(tx_prop->tx[cnt].ip==IPA_IP_v6) { IPACMDBG_H("Got partial v6-header name from %d tx props\n", cnt); memset(&sCopyHeader, 0, sizeof(sCopyHeader)); memcpy(sCopyHeader.name, tx_prop->tx[cnt].hdr_name, sizeof(sCopyHeader.name)); IPACMDBG_H("header name: %s in tx:%d\n", sCopyHeader.name,cnt); if (m_header.CopyHeader(&sCopyHeader) == false) { PERROR("ioctl copy header failed"); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial); IPACMDBG_H("header eth2_ofst_valid: %d, eth2_ofst: %d\n", sCopyHeader.is_eth2_ofst_valid, sCopyHeader.eth2_ofst); if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE) { IPACMERR("header oversize\n"); res = IPACM_FAILURE; goto fail; } else { memcpy(pHeaderDescriptor->hdr[0].hdr, sCopyHeader.hdr, sCopyHeader.hdr_len); } /* copy client mac_addr to partial header */ if (sCopyHeader.is_eth2_ofst_valid) { memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst], mac_addr, IPA_MAC_ADDR_SIZE); } pHeaderDescriptor->commit = true; pHeaderDescriptor->num_hdrs = 1; memset(pHeaderDescriptor->hdr[0].name, 0, sizeof(pHeaderDescriptor->hdr[0].name)); snprintf(index,sizeof(index), "%d", ipa_if_num); strlcpy(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)); if (strlcat(pHeaderDescriptor->hdr[0].name, IPA_ETH_HDR_NAME_v6, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX) { IPACMERR(" header name construction failed exceed length (%d)\n", strlen(pHeaderDescriptor->hdr[0].name)); res = IPACM_FAILURE; goto fail; } snprintf(index,sizeof(index), "%d", header_name_count); if (strlcat(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX) { IPACMERR(" header name construction failed exceed length (%d)\n", strlen(pHeaderDescriptor->hdr[0].name)); res = IPACM_FAILURE; goto fail; } pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len; pHeaderDescriptor->hdr[0].hdr_hdl = -1; pHeaderDescriptor->hdr[0].is_partial = 0; pHeaderDescriptor->hdr[0].status = -1; if (m_header.AddHeader(pHeaderDescriptor) == false || pHeaderDescriptor->hdr[0].status != 0) { IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status); res = IPACM_FAILURE; goto fail; } get_client_memptr(eth_client, num_eth_client)->hdr_hdl_v6 = pHeaderDescriptor->hdr[0].hdr_hdl; IPACMDBG_H("eth-client(%d) v6 full header name:%s header handle:(0x%x)\n", num_eth_client, pHeaderDescriptor->hdr[0].name, get_client_memptr(eth_client, num_eth_client)->hdr_hdl_v6); get_client_memptr(eth_client, num_eth_client)->ipv6_header_set=true; break; } } /* initialize wifi client*/ get_client_memptr(eth_client, num_eth_client)->route_rule_set_v4 = false; get_client_memptr(eth_client, num_eth_client)->route_rule_set_v6 = 0; get_client_memptr(eth_client, num_eth_client)->ipv4_set = false; get_client_memptr(eth_client, num_eth_client)->ipv6_set = 0; num_eth_client++; header_name_count++; //keep increasing header_name_count res = IPACM_SUCCESS; IPACMDBG_H("eth client number: %d\n", num_eth_client); } else { return res; } fail: free(pHeaderDescriptor); return res; } /*handle eth client */ int IPACM_Lan::handle_eth_client_ipaddr(ipacm_event_data_all *data) { int clnt_indx; int v6_num; IPACMDBG_H("number of eth clients: %d\n", num_eth_client); IPACMDBG_H(" event MAC %02x:%02x:%02x:%02x:%02x:%02x\n", data->mac_addr[0], data->mac_addr[1], data->mac_addr[2], data->mac_addr[3], data->mac_addr[4], data->mac_addr[5]); clnt_indx = get_eth_client_index(data->mac_addr); if (clnt_indx == IPACM_INVALID_INDEX) { IPACMERR("eth client not found/attached \n"); return IPACM_FAILURE; } IPACMDBG_H("Ip-type received %d\n", data->iptype); if (data->iptype == IPA_IP_v4) { IPACMDBG_H("ipv4 address: 0x%x\n", data->ipv4_addr); if (data->ipv4_addr != 0) /* not 0.0.0.0 */ { if (get_client_memptr(eth_client, clnt_indx)->ipv4_set == false) { get_client_memptr(eth_client, clnt_indx)->v4_addr = data->ipv4_addr; get_client_memptr(eth_client, clnt_indx)->ipv4_set = true; } else { /* check if client got new IPv4 address*/ if(data->ipv4_addr == get_client_memptr(eth_client, clnt_indx)->v4_addr) { IPACMDBG_H("Already setup ipv4 addr for client:%d, ipv4 address didn't change\n", clnt_indx); return IPACM_FAILURE; } else { IPACMDBG_H("ipv4 addr for client:%d is changed \n", clnt_indx); /* delete NAT rules first */ CtList->HandleNeighIpAddrDelEvt(get_client_memptr(eth_client, clnt_indx)->v4_addr); delete_eth_rtrules(clnt_indx,IPA_IP_v4); get_client_memptr(eth_client, clnt_indx)->route_rule_set_v4 = false; get_client_memptr(eth_client, clnt_indx)->v4_addr = data->ipv4_addr; } } } else { IPACMDBG_H("Invalid client IPv4 address \n"); return IPACM_FAILURE; } } else { if ((data->ipv6_addr[0] != 0) || (data->ipv6_addr[1] != 0) || (data->ipv6_addr[2] != 0) || (data->ipv6_addr[3] || 0)) /* check if all 0 not valid ipv6 address */ { IPACMDBG_H("ipv6 address: 0x%x:%x:%x:%x\n", data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]); if(get_client_memptr(eth_client, clnt_indx)->ipv6_set < IPV6_NUM_ADDR) { for(v6_num=0;v6_num < get_client_memptr(eth_client, clnt_indx)->ipv6_set;v6_num++) { if( data->ipv6_addr[0] == get_client_memptr(eth_client, clnt_indx)->v6_addr[v6_num][0] && data->ipv6_addr[1] == get_client_memptr(eth_client, clnt_indx)->v6_addr[v6_num][1] && data->ipv6_addr[2]== get_client_memptr(eth_client, clnt_indx)->v6_addr[v6_num][2] && data->ipv6_addr[3] == get_client_memptr(eth_client, clnt_indx)->v6_addr[v6_num][3]) { IPACMDBG_H("Already see this ipv6 addr for client:%d\n", clnt_indx); return IPACM_FAILURE; /* not setup the RT rules*/ break; } } /* not see this ipv6 before for wifi client*/ get_client_memptr(eth_client, clnt_indx)->v6_addr[get_client_memptr(eth_client, clnt_indx)->ipv6_set][0] = data->ipv6_addr[0]; get_client_memptr(eth_client, clnt_indx)->v6_addr[get_client_memptr(eth_client, clnt_indx)->ipv6_set][1] = data->ipv6_addr[1]; get_client_memptr(eth_client, clnt_indx)->v6_addr[get_client_memptr(eth_client, clnt_indx)->ipv6_set][2] = data->ipv6_addr[2]; get_client_memptr(eth_client, clnt_indx)->v6_addr[get_client_memptr(eth_client, clnt_indx)->ipv6_set][3] = data->ipv6_addr[3]; get_client_memptr(eth_client, clnt_indx)->ipv6_set++; } else { IPACMDBG_H("Already got 3 ipv6 addr for client:%d\n", clnt_indx); return IPACM_FAILURE; /* not setup the RT rules*/ } } } return IPACM_SUCCESS; } /*handle eth client routing rule*/ int IPACM_Lan::handle_eth_client_route_rule(uint8_t *mac_addr, ipa_ip_type iptype) { struct ipa_ioc_add_rt_rule *rt_rule; struct ipa_rt_rule_add *rt_rule_entry; uint32_t tx_index; int eth_index,v6_num; const int NUM = 1; if(tx_prop == NULL) { IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); return IPACM_SUCCESS; } IPACMDBG_H("Received mac_addr MAC %02x:%02x:%02x:%02x:%02x:%02x\n", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); eth_index = get_eth_client_index(mac_addr); if (eth_index == IPACM_INVALID_INDEX) { IPACMDBG_H("eth client not found/attached \n"); return IPACM_SUCCESS; } if (iptype==IPA_IP_v4) { IPACMDBG_H("eth client index: %d, ip-type: %d, ipv4_set:%d, ipv4_rule_set:%d \n", eth_index, iptype, get_client_memptr(eth_client, eth_index)->ipv4_set, get_client_memptr(eth_client, eth_index)->route_rule_set_v4); } else { IPACMDBG_H("eth client index: %d, ip-type: %d, ipv6_set:%d, ipv6_rule_num:%d \n", eth_index, iptype, get_client_memptr(eth_client, eth_index)->ipv6_set, get_client_memptr(eth_client, eth_index)->route_rule_set_v6); } /* Add default routing rules if not set yet */ if ((iptype == IPA_IP_v4 && get_client_memptr(eth_client, eth_index)->route_rule_set_v4 == false && get_client_memptr(eth_client, eth_index)->ipv4_set == true) || (iptype == IPA_IP_v6 && get_client_memptr(eth_client, eth_index)->route_rule_set_v6 < get_client_memptr(eth_client, eth_index)->ipv6_set )) { /* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */ IPACMDBG_H("dev %s add producer dependency\n", dev_name); if (tx_prop != NULL) { IPACMDBG_H("depend Got pipe %d rm index : %d \n", tx_prop->tx[0].dst_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]); IPACM_Iface::ipacmcfg->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false); } rt_rule = (struct ipa_ioc_add_rt_rule *) calloc(1, sizeof(struct ipa_ioc_add_rt_rule) + NUM * sizeof(struct ipa_rt_rule_add)); if (rt_rule == NULL) { PERROR("Error Locate ipa_ioc_add_rt_rule memory...\n"); return IPACM_FAILURE; } rt_rule->commit = 1; rt_rule->num_rules = (uint8_t)NUM; rt_rule->ip = iptype; for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) { if(iptype != tx_prop->tx[tx_index].ip) { IPACMDBG_H("Tx:%d, ip-type: %d conflict ip-type: %d no RT-rule added\n", tx_index, tx_prop->tx[tx_index].ip,iptype); continue; } rt_rule_entry = &rt_rule->rules[0]; rt_rule_entry->at_rear = 0; if (iptype == IPA_IP_v4) { IPACMDBG_H("client index(%d):ipv4 address: 0x%x\n", eth_index, get_client_memptr(eth_client, eth_index)->v4_addr); IPACMDBG_H("client(%d): v4 header handle:(0x%x)\n", eth_index, get_client_memptr(eth_client, eth_index)->hdr_hdl_v4); strncpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name, sizeof(rt_rule->rt_tbl_name)); rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe; memcpy(&rt_rule_entry->rule.attrib, &tx_prop->tx[tx_index].attrib, sizeof(rt_rule_entry->rule.attrib)); rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; rt_rule_entry->rule.hdr_hdl = get_client_memptr(eth_client, eth_index)->hdr_hdl_v4; rt_rule_entry->rule.attrib.u.v4.dst_addr = get_client_memptr(eth_client, eth_index)->v4_addr; rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF; /* Replace the v4 header in ODU interface */ if (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF) rt_rule_entry->rule.hdr_hdl = ODU_hdr_hdl_v4; if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); free(rt_rule); return IPACM_FAILURE; } /* copy ipv4 RT hdl */ get_client_memptr(eth_client, eth_index)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v4 = rt_rule->rules[0].rt_rule_hdl; IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index, get_client_memptr(eth_client, eth_index)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v4, iptype); } else { for(v6_num = get_client_memptr(eth_client, eth_index)->route_rule_set_v6;v6_num < get_client_memptr(eth_client, eth_index)->ipv6_set;v6_num++) { IPACMDBG_H("client(%d): v6 header handle:(0x%x)\n", eth_index, get_client_memptr(eth_client, eth_index)->hdr_hdl_v6); /* v6 LAN_RT_TBL */ strncpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_v6.name, sizeof(rt_rule->rt_tbl_name)); /* Replace v6 header in ODU interface */ if (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF) rt_rule_entry->rule.hdr_hdl = ODU_hdr_hdl_v6; /* Support QCMAP LAN traffic feature, send to A5 */ rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS; memset(&rt_rule_entry->rule.attrib, 0, sizeof(rt_rule_entry->rule.attrib)); rt_rule_entry->rule.hdr_hdl = 0; rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][0]; rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][1]; rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][2]; rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][3]; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF; if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); free(rt_rule); return IPACM_FAILURE; } get_client_memptr(eth_client, eth_index)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[v6_num] = rt_rule->rules[0].rt_rule_hdl; IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index, get_client_memptr(eth_client, eth_index)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[v6_num], iptype); /*Copy same rule to v6 WAN RT TBL*/ strncpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name)); /* Downlink traffic from Wan iface, directly through IPA */ rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe; memcpy(&rt_rule_entry->rule.attrib, &tx_prop->tx[tx_index].attrib, sizeof(rt_rule_entry->rule.attrib)); rt_rule_entry->rule.hdr_hdl = get_client_memptr(eth_client, eth_index)->hdr_hdl_v6; rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][0]; rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][1]; rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][2]; rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][3]; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF; if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); free(rt_rule); return IPACM_FAILURE; } get_client_memptr(eth_client, eth_index)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[v6_num] = rt_rule->rules[0].rt_rule_hdl; IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index, get_client_memptr(eth_client, eth_index)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[v6_num], iptype); } } } /* end of for loop */ free(rt_rule); if (iptype == IPA_IP_v4) { get_client_memptr(eth_client, eth_index)->route_rule_set_v4 = true; } else { get_client_memptr(eth_client, eth_index)->route_rule_set_v6 = get_client_memptr(eth_client, eth_index)->ipv6_set; } } return IPACM_SUCCESS; } /* handle odu client initial, construct full headers (tx property) */ int IPACM_Lan::handle_odu_hdr_init(uint8_t *mac_addr) { int res = IPACM_SUCCESS, len = 0; struct ipa_ioc_copy_hdr sCopyHeader; struct ipa_ioc_add_hdr *pHeaderDescriptor = NULL; uint32_t cnt; IPACMDBG("Received Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); /* add header to IPA */ if(tx_prop != NULL) { len = sizeof(struct ipa_ioc_add_hdr) + (1 * sizeof(struct ipa_hdr_add)); pHeaderDescriptor = (struct ipa_ioc_add_hdr *)calloc(1, len); if (pHeaderDescriptor == NULL) { IPACMERR("calloc failed to allocate pHeaderDescriptor\n"); return IPACM_FAILURE; } /* copy partial header for v4*/ for (cnt=0; cntnum_tx_props; cnt++) { if(tx_prop->tx[cnt].ip==IPA_IP_v4) { IPACMDBG("Got partial v4-header name from %d tx props\n", cnt); memset(&sCopyHeader, 0, sizeof(sCopyHeader)); memcpy(sCopyHeader.name, tx_prop->tx[cnt].hdr_name, sizeof(sCopyHeader.name)); IPACMDBG("header name: %s in tx:%d\n", sCopyHeader.name,cnt); if (m_header.CopyHeader(&sCopyHeader) == false) { PERROR("ioctl copy header failed"); res = IPACM_FAILURE; goto fail; } IPACMDBG("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial); if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE) { IPACMERR("header oversize\n"); res = IPACM_FAILURE; goto fail; } else { memcpy(pHeaderDescriptor->hdr[0].hdr, sCopyHeader.hdr, sCopyHeader.hdr_len); } /* copy client mac_addr to partial header */ if (sCopyHeader.is_eth2_ofst_valid) { memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst], mac_addr, IPA_MAC_ADDR_SIZE); } pHeaderDescriptor->commit = true; pHeaderDescriptor->num_hdrs = 1; memset(pHeaderDescriptor->hdr[0].name, 0, sizeof(pHeaderDescriptor->hdr[0].name)); strcpy(pHeaderDescriptor->hdr[0].name, IPA_ODU_HDR_NAME_v4); pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len; pHeaderDescriptor->hdr[0].hdr_hdl = -1; pHeaderDescriptor->hdr[0].is_partial = 0; pHeaderDescriptor->hdr[0].status = -1; if (m_header.AddHeader(pHeaderDescriptor) == false || pHeaderDescriptor->hdr[0].status != 0) { IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status); res = IPACM_FAILURE; goto fail; } ODU_hdr_hdl_v4 = pHeaderDescriptor->hdr[0].hdr_hdl; ipv4_header_set = true ; IPACMDBG(" ODU v4 full header name:%s header handle:(0x%x)\n", pHeaderDescriptor->hdr[0].name, ODU_hdr_hdl_v4); break; } } /* copy partial header for v6*/ for (cnt=0; cntnum_tx_props; cnt++) { if(tx_prop->tx[cnt].ip==IPA_IP_v6) { IPACMDBG("Got partial v6-header name from %d tx props\n", cnt); memset(&sCopyHeader, 0, sizeof(sCopyHeader)); memcpy(sCopyHeader.name, tx_prop->tx[cnt].hdr_name, sizeof(sCopyHeader.name)); IPACMDBG("header name: %s in tx:%d\n", sCopyHeader.name,cnt); if (m_header.CopyHeader(&sCopyHeader) == false) { PERROR("ioctl copy header failed"); res = IPACM_FAILURE; goto fail; } IPACMDBG("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial); if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE) { IPACMERR("header oversize\n"); res = IPACM_FAILURE; goto fail; } else { memcpy(pHeaderDescriptor->hdr[0].hdr, sCopyHeader.hdr, sCopyHeader.hdr_len); } /* copy client mac_addr to partial header */ if (sCopyHeader.is_eth2_ofst_valid) { memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst], mac_addr, IPA_MAC_ADDR_SIZE); } pHeaderDescriptor->commit = true; pHeaderDescriptor->num_hdrs = 1; memset(pHeaderDescriptor->hdr[0].name, 0, sizeof(pHeaderDescriptor->hdr[0].name)); strcpy(pHeaderDescriptor->hdr[0].name, IPA_ODU_HDR_NAME_v6); pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len; pHeaderDescriptor->hdr[0].hdr_hdl = -1; pHeaderDescriptor->hdr[0].is_partial = 0; pHeaderDescriptor->hdr[0].status = -1; if (m_header.AddHeader(pHeaderDescriptor) == false || pHeaderDescriptor->hdr[0].status != 0) { IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status); res = IPACM_FAILURE; goto fail; } ODU_hdr_hdl_v6 = pHeaderDescriptor->hdr[0].hdr_hdl; ipv6_header_set = true ; IPACMDBG(" ODU v4 full header name:%s header handle:(0x%x)\n", pHeaderDescriptor->hdr[0].name, ODU_hdr_hdl_v6); break; } } } fail: free(pHeaderDescriptor); return res; } /* handle odu default route rule configuration */ int IPACM_Lan::handle_odu_route_add() { /* add default WAN route */ struct ipa_ioc_add_rt_rule *rt_rule; struct ipa_rt_rule_add *rt_rule_entry; uint32_t tx_index; const int NUM = 1; if(tx_prop == NULL) { IPACMDBG("No tx properties, ignore default route setting\n"); return IPACM_SUCCESS; } rt_rule = (struct ipa_ioc_add_rt_rule *) calloc(1, sizeof(struct ipa_ioc_add_rt_rule) + NUM * sizeof(struct ipa_rt_rule_add)); if (!rt_rule) { IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n"); return IPACM_FAILURE; } rt_rule->commit = 1; rt_rule->num_rules = (uint8_t)NUM; IPACMDBG(" WAN table created %s \n", rt_rule->rt_tbl_name); rt_rule_entry = &rt_rule->rules[0]; rt_rule_entry->at_rear = true; for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) { if (IPA_IP_v4 == tx_prop->tx[tx_index].ip) { strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v4.name); rt_rule_entry->rule.hdr_hdl = ODU_hdr_hdl_v4; rt_rule->ip = IPA_IP_v4; } else { strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v6.name); rt_rule_entry->rule.hdr_hdl = ODU_hdr_hdl_v6; rt_rule->ip = IPA_IP_v6; } rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe; memcpy(&rt_rule_entry->rule.attrib, &tx_prop->tx[tx_index].attrib, sizeof(rt_rule_entry->rule.attrib)); rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; if (IPA_IP_v4 == tx_prop->tx[tx_index].ip) { rt_rule_entry->rule.attrib.u.v4.dst_addr = 0; rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0; if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); free(rt_rule); return IPACM_FAILURE; } odu_route_rule_v4_hdl[tx_index] = rt_rule_entry->rt_rule_hdl; IPACMDBG("Got ipv4 ODU-route rule hdl:0x%x,tx:%d,ip-type: %d \n", odu_route_rule_v4_hdl[tx_index], tx_index, IPA_IP_v4); } else { rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = 0; rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = 0; rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = 0; rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = 0; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0; if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); free(rt_rule); return IPACM_FAILURE; } odu_route_rule_v6_hdl[tx_index] = rt_rule_entry->rt_rule_hdl; IPACMDBG("Set ipv6 ODU-route rule hdl for v6_lan_table:0x%x,tx:%d,ip-type: %d \n", odu_route_rule_v6_hdl[tx_index], tx_index, IPA_IP_v6); } } free(rt_rule); return IPACM_SUCCESS; } /* handle odu default route rule deletion */ int IPACM_Lan::handle_odu_route_del() { uint32_t tx_index; if(tx_prop == NULL) { IPACMDBG("No tx properties, ignore delete default route setting\n"); return IPACM_SUCCESS; } for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) { if (tx_prop->tx[tx_index].ip == IPA_IP_v4) { IPACMDBG("Tx:%d, ip-type: %d match ip-type: %d, RT-rule deleted\n", tx_index, tx_prop->tx[tx_index].ip,IPA_IP_v4); if (m_routing.DeleteRoutingHdl(odu_route_rule_v4_hdl[tx_index], IPA_IP_v4) == false) { IPACMDBG("IP-family:%d, Routing rule(hdl:0x%x) deletion failed with tx_index %d!\n", IPA_IP_v4, odu_route_rule_v4_hdl[tx_index], tx_index); return IPACM_FAILURE; } } else { IPACMDBG("Tx:%d, ip-type: %d match ip-type: %d, RT-rule deleted\n", tx_index, tx_prop->tx[tx_index].ip,IPA_IP_v6); if (m_routing.DeleteRoutingHdl(odu_route_rule_v6_hdl[tx_index], IPA_IP_v6) == false) { IPACMDBG("IP-family:%d, Routing rule(hdl:0x%x) deletion failed with tx_index %d!\n", IPA_IP_v6, odu_route_rule_v6_hdl[tx_index], tx_index); return IPACM_FAILURE; } } } return IPACM_SUCCESS; } /*handle eth client del mode*/ int IPACM_Lan::handle_eth_client_down_evt(uint8_t *mac_addr) { int clt_indx; uint32_t tx_index; int num_eth_client_tmp = num_eth_client; int num_v6; IPACMDBG_H("total client: %d\n", num_eth_client_tmp); clt_indx = get_eth_client_index(mac_addr); if (clt_indx == IPACM_INVALID_INDEX) { IPACMDBG_H("eth client not attached\n"); return IPACM_SUCCESS; } /* First reset nat rules and then route rules */ if(get_client_memptr(eth_client, clt_indx)->ipv4_set == true) { IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(eth_client, clt_indx)->v4_addr); CtList->HandleNeighIpAddrDelEvt(get_client_memptr(eth_client, clt_indx)->v4_addr); } if (delete_eth_rtrules(clt_indx, IPA_IP_v4)) { IPACMERR("unbale to delete ecm-client v4 route rules for index: %d\n", clt_indx); return IPACM_FAILURE; } if (delete_eth_rtrules(clt_indx, IPA_IP_v6)) { IPACMERR("unbale to delete ecm-client v6 route rules for index: %d\n", clt_indx); return IPACM_FAILURE; } /* Delete eth client header */ if(get_client_memptr(eth_client, clt_indx)->ipv4_header_set == true) { if (m_header.DeleteHeaderHdl(get_client_memptr(eth_client, clt_indx)->hdr_hdl_v4) == false) { return IPACM_FAILURE; } get_client_memptr(eth_client, clt_indx)->ipv4_header_set = false; } if(get_client_memptr(eth_client, clt_indx)->ipv6_header_set == true) { if (m_header.DeleteHeaderHdl(get_client_memptr(eth_client, clt_indx)->hdr_hdl_v6) == false) { return IPACM_FAILURE; } get_client_memptr(eth_client, clt_indx)->ipv6_header_set = false; } /* Reset ip_set to 0*/ get_client_memptr(eth_client, clt_indx)->ipv4_set = false; get_client_memptr(eth_client, clt_indx)->ipv6_set = 0; get_client_memptr(eth_client, clt_indx)->ipv4_header_set = false; get_client_memptr(eth_client, clt_indx)->ipv6_header_set = false; get_client_memptr(eth_client, clt_indx)->route_rule_set_v4 = false; get_client_memptr(eth_client, clt_indx)->route_rule_set_v6 = 0; for (; clt_indx < num_eth_client_tmp - 1; clt_indx++) { memcpy(get_client_memptr(eth_client, clt_indx)->mac, get_client_memptr(eth_client, (clt_indx + 1))->mac, sizeof(get_client_memptr(eth_client, clt_indx)->mac)); get_client_memptr(eth_client, clt_indx)->hdr_hdl_v4 = get_client_memptr(eth_client, (clt_indx + 1))->hdr_hdl_v4; get_client_memptr(eth_client, clt_indx)->hdr_hdl_v6 = get_client_memptr(eth_client, (clt_indx + 1))->hdr_hdl_v6; get_client_memptr(eth_client, clt_indx)->v4_addr = get_client_memptr(eth_client, (clt_indx + 1))->v4_addr; get_client_memptr(eth_client, clt_indx)->ipv4_set = get_client_memptr(eth_client, (clt_indx + 1))->ipv4_set; get_client_memptr(eth_client, clt_indx)->ipv6_set = get_client_memptr(eth_client, (clt_indx + 1))->ipv6_set; get_client_memptr(eth_client, clt_indx)->ipv4_header_set = get_client_memptr(eth_client, (clt_indx + 1))->ipv4_header_set; get_client_memptr(eth_client, clt_indx)->ipv6_header_set = get_client_memptr(eth_client, (clt_indx + 1))->ipv6_header_set; get_client_memptr(eth_client, clt_indx)->route_rule_set_v4 = get_client_memptr(eth_client, (clt_indx + 1))->route_rule_set_v4; get_client_memptr(eth_client, clt_indx)->route_rule_set_v6 = get_client_memptr(eth_client, (clt_indx + 1))->route_rule_set_v6; for (num_v6=0;num_v6< get_client_memptr(eth_client, clt_indx)->ipv6_set;num_v6++) { get_client_memptr(eth_client, clt_indx)->v6_addr[num_v6][0] = get_client_memptr(eth_client, (clt_indx + 1))->v6_addr[num_v6][0]; get_client_memptr(eth_client, clt_indx)->v6_addr[num_v6][1] = get_client_memptr(eth_client, (clt_indx + 1))->v6_addr[num_v6][1]; get_client_memptr(eth_client, clt_indx)->v6_addr[num_v6][2] = get_client_memptr(eth_client, (clt_indx + 1))->v6_addr[num_v6][2]; get_client_memptr(eth_client, clt_indx)->v6_addr[num_v6][3] = get_client_memptr(eth_client, (clt_indx + 1))->v6_addr[num_v6][3]; } for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) { get_client_memptr(eth_client, clt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v4 = get_client_memptr(eth_client, (clt_indx + 1))->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v4; for(num_v6=0;num_v6< get_client_memptr(eth_client, clt_indx)->route_rule_set_v6;num_v6++) { get_client_memptr(eth_client, clt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[num_v6] = get_client_memptr(eth_client, (clt_indx + 1))->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[num_v6]; get_client_memptr(eth_client, clt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[num_v6] = get_client_memptr(eth_client, (clt_indx + 1))->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[num_v6]; } } } IPACMDBG_H(" %d eth client deleted successfully \n", num_eth_client); num_eth_client = num_eth_client - 1; IPACMDBG_H(" Number of eth client: %d\n", num_eth_client); /* Del RM dependency */ if(num_eth_client == 0) { /* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete all IPV4V6 RT-rule*/ IPACMDBG_H("dev %s add producer dependency\n", dev_name); if (tx_prop != NULL) { IPACMDBG_H("depend Got pipe %d rm index : %d \n", tx_prop->tx[0].dst_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]); IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]); } } return IPACM_SUCCESS; } /*handle LAN iface down event*/ int IPACM_Lan::handle_down_evt() { int i; int res = IPACM_SUCCESS; uint32_t temp_eth_bridge_flt_rule[IPA_LAN_TO_LAN_MAX_WLAN_CLIENT]; if (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF) { /* delete ODU default RT rules */ handle_odu_route_del(); /* delete full header */ if (ipv4_header_set) { if (m_header.DeleteHeaderHdl(ODU_hdr_hdl_v4) == false) { IPACMDBG("ODU ipv4 header delete fail\n"); res = IPACM_FAILURE; goto fail; } IPACMDBG("ODU ipv4 header delete success\n"); } if (ipv6_header_set) { if (m_header.DeleteHeaderHdl(ODU_hdr_hdl_v6) == false) { IPACMDBG("ODU ipv6 header delete fail\n"); res = IPACM_FAILURE; goto fail; } IPACMDBG("ODU ipv6 header delete success\n"); } } /* no iface address up, directly close iface*/ if (ip_type == IPACM_IP_NULL) { goto fail; } IPACMDBG_H("lan handle_down_evt\n "); #ifdef FEATURE_ETH_BRIDGE_LE IPACM_Lan::usb_hdr_type = IPA_HDR_L2_NONE; IPACM_Lan::usb_hdr_template_hdl = 0; del_hdr_proc_ctx(); #endif /* delete wan filter rule */ if (IPACM_Wan::isWanUP(ipa_if_num) && rx_prop != NULL) { IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_is_sta_mode); handle_wan_down(IPACM_Wan::backhaul_is_sta_mode); } if (IPACM_Wan::isWanUP_V6(ipa_if_num) && rx_prop != NULL) { IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_is_sta_mode); handle_wan_down_v6(IPACM_Wan::backhaul_is_sta_mode); } /* delete default filter rules */ if (ip_type != IPA_IP_v6 && rx_prop != NULL) { if (m_filtering.DeleteFilteringHdls(dft_v4fl_rule_hdl, IPA_IP_v4, IPV4_DEFAULT_FILTERTING_RULES) == false) { IPACMERR("Error Deleting Filtering Rule, aborting...\n"); res = IPACM_FAILURE; goto fail; } #ifdef FEATURE_ETH_BRIDGE_LE for(i=0; iipa_num_private_subnet > IPA_PRIV_SUBNET_FILTER_RULE_HANDLES) { IPACMERR(" the number of rules are bigger than array, aborting...\n"); res = IPACM_FAILURE; goto fail; } #ifdef FEATURE_IPA_ANDROID if(m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES) == false) { IPACMERR("Error deleting private subnet IPv4 flt rules.\n"); res = IPACM_FAILURE; goto fail; } #else if (m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, IPACM_Iface::ipacmcfg->ipa_num_private_subnet) == false) { IPACMERR("Error Deleting RuleTable(1) to Filtering, aborting...\n"); res = IPACM_FAILURE; goto fail; } #endif } IPACMDBG_H("Finished delete default iface ipv4 filtering rules \n "); if (ip_type != IPA_IP_v4 && rx_prop != NULL) { if (m_filtering.DeleteFilteringHdls(dft_v6fl_rule_hdl, IPA_IP_v6, (IPV6_DEFAULT_FILTERTING_RULES + IPV6_DEFAULT_LAN_FILTERTING_RULES)) == false) { IPACMERR("Error Adding RuleTable(1) to Filtering, aborting...\n"); res = IPACM_FAILURE; goto fail; } #ifdef FEATURE_ETH_BRIDGE_LE for(i=0; imac); eth_bridge_post_lan_client_event(get_client_memptr(eth_client, i)->mac, IPA_ETH_BRIDGE_USB_CLIENT_DEL_EVENT); eth_bridge_del_usb_client(get_client_memptr(eth_client, i)->mac); #endif /* First reset nat rules and then route rules */ if(get_client_memptr(eth_client, i)->ipv4_set == true) { IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(eth_client, i)->v4_addr); CtList->HandleNeighIpAddrDelEvt(get_client_memptr(eth_client, i)->v4_addr); } if (delete_eth_rtrules(i, IPA_IP_v4)) { IPACMERR("unbale to delete ecm-client v4 route rules for index %d\n", i); res = IPACM_FAILURE; goto fail; } if (delete_eth_rtrules(i, IPA_IP_v6)) { IPACMERR("unbale to delete ecm-client v6 route rules for index %d\n", i); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("Delete %d client header\n", num_eth_client); if(get_client_memptr(eth_client, i)->ipv4_header_set == true) { if (m_header.DeleteHeaderHdl(get_client_memptr(eth_client, i)->hdr_hdl_v4) == false) { res = IPACM_FAILURE; goto fail; } } if(get_client_memptr(eth_client, i)->ipv6_header_set == true) { if (m_header.DeleteHeaderHdl(get_client_memptr(eth_client, i)->hdr_hdl_v6) == false) { res = IPACM_FAILURE; goto fail; } } } /* end of for loop */ /* free the edm clients cache */ IPACMDBG_H("Free ecm clients cache\n"); /* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete all IPV4V6 RT-rule */ IPACMDBG_H("dev %s delete producer dependency\n", dev_name); if (tx_prop != NULL) { IPACMDBG_H("depend Got pipe %d rm index : %d \n", tx_prop->tx[0].dst_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]); IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]); } /* check software routing fl rule hdl */ if (softwarerouting_act == true && rx_prop != NULL) { handle_software_routing_disable(); } /* posting ip to lan2lan module to delete RT/FILTER rules*/ post_lan2lan_client_disconnect_msg(IPA_IP_v4); post_lan2lan_client_disconnect_msg(IPA_IP_v6); /* Delete private subnet*/ #ifdef FEATURE_IPA_ANDROID if (ip_type != IPA_IP_v6) { IPACMDBG_H("current IPACM private subnet_addr number(%d)\n", IPACM_Iface::ipacmcfg->ipa_num_private_subnet); IPACMDBG_H(" Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet); if(IPACM_Iface::ipacmcfg->DelPrivateSubnet(if_ipv4_subnet, ipa_if_num) == false) { IPACMERR(" can't Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet); } } /* reset the IPA-client pipe enum */ if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat != WAN_IF) { handle_tethering_client(true, IPACM_CLIENT_USB); } #endif /* defined(FEATURE_IPA_ANDROID)*/ fail: if (odu_route_rule_v4_hdl != NULL) { free(odu_route_rule_v4_hdl); } if (odu_route_rule_v6_hdl != NULL) { free(odu_route_rule_v6_hdl); } /* Delete corresponding ipa_rm_resource_name of RX-endpoint after delete all IPV4V6 FT-rule */ if (rx_prop != NULL) { IPACMDBG_H("dev %s add producer dependency\n", dev_name); IPACMDBG_H("depend Got pipe %d rm index : %d \n", rx_prop->rx[0].src_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe]); IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe]); IPACMDBG_H("Finished delete dependency \n "); free(rx_prop); } if (eth_client != NULL) { free(eth_client); } if (tx_prop != NULL) { free(tx_prop); } if (iface_query != NULL) { free(iface_query); } #ifdef FEATURE_ETH_BRIDGE_LE if(eth_bridge_usb_client_rt_info_v4 != NULL) { free(eth_bridge_usb_client_rt_info_v4); } if(eth_bridge_usb_client_rt_info_v6 != NULL) { free(eth_bridge_usb_client_rt_info_v6); } #endif is_active = false; post_del_self_evt(); return res; } /* install UL filter rule from Q6 */ int IPACM_Lan::handle_uplink_filter_rule(ipacm_ext_prop* prop, ipa_ip_type iptype) { ipa_flt_rule_add flt_rule_entry; int len = 0, cnt, ret = IPACM_SUCCESS; ipa_ioc_add_flt_rule *pFilteringTable; ipa_fltr_installed_notif_req_msg_v01 flt_index; int fd; int i; IPACMDBG_H("Set extended property rules in LAN\n"); if (rx_prop == NULL) { IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); return IPACM_SUCCESS; } if(prop == NULL || prop->num_ext_props <= 0) { IPACMDBG_H("No extended property.\n"); return IPACM_SUCCESS; } fd = open(IPA_DEVICE_NAME, O_RDWR); if (0 == fd) { IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME); } memset(&flt_index, 0, sizeof(flt_index)); flt_index.source_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[0].src_pipe); flt_index.install_status = IPA_QMI_RESULT_SUCCESS_V01; flt_index.filter_index_list_len = prop->num_ext_props; flt_index.embedded_pipe_index_valid = 1; flt_index.embedded_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, IPA_CLIENT_APPS_LAN_WAN_PROD); flt_index.retain_header_valid = 1; flt_index.retain_header = 0; flt_index.embedded_call_mux_id_valid = 1; flt_index.embedded_call_mux_id = IPACM_Iface::ipacmcfg->GetQmapId(); IPACMDBG_H("flt_index: src pipe: %d, num of rules: %d, ebd pipe: %d, mux id: %d\n", flt_index.source_pipe_index, flt_index.filter_index_list_len, flt_index.embedded_pipe_index, flt_index.embedded_call_mux_id); len = sizeof(struct ipa_ioc_add_flt_rule) + prop->num_ext_props * sizeof(struct ipa_flt_rule_add); pFilteringTable = (struct ipa_ioc_add_flt_rule*)malloc(len); if (pFilteringTable == NULL) { IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); close(fd); return IPACM_FAILURE; } memset(pFilteringTable, 0, len); pFilteringTable->commit = 1; pFilteringTable->ep = rx_prop->rx[0].src_pipe; pFilteringTable->global = false; pFilteringTable->ip = iptype; pFilteringTable->num_rules = prop->num_ext_props; memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); // Zero All Fields flt_rule_entry.at_rear = 1; flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.retain_hdr = 0; flt_rule_entry.rule.to_uc = 0; flt_rule_entry.rule.eq_attrib_type = 1; if(iptype == IPA_IP_v4) flt_rule_entry.rule.action = IPA_PASS_TO_SRC_NAT; else if(iptype == IPA_IP_v6) flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; else { IPACMERR("IP type is not expected.\n"); ret = IPACM_FAILURE; goto fail; } for(cnt=0; cntnum_ext_props; cnt++) { memcpy(&flt_rule_entry.rule.eq_attrib, &prop->prop[cnt].eq_attrib, sizeof(prop->prop[cnt].eq_attrib)); flt_rule_entry.rule.rt_tbl_idx = prop->prop[cnt].rt_tbl_idx; memcpy(&pFilteringTable->rules[cnt], &flt_rule_entry, sizeof(flt_rule_entry)); if(iptype == IPA_IP_v4) { IPACMDBG_H("Filtering rule %d has index %d\n", cnt, flt_rule_count_v4); flt_index.filter_index_list[cnt].filter_index = flt_rule_count_v4; flt_rule_count_v4++; } if(iptype == IPA_IP_v6) { IPACMDBG_H("Filtering rule %d has index %d\n", cnt, flt_rule_count_v6); flt_index.filter_index_list[cnt].filter_index = flt_rule_count_v6; flt_rule_count_v6++; } flt_index.filter_index_list[cnt].filter_handle = prop->prop[cnt].filter_hdl; } if(false == m_filtering.SendFilteringRuleIndex(&flt_index)) { IPACMERR("Error sending filtering rule index, aborting...\n"); ret = IPACM_FAILURE; goto fail; } if(false == m_filtering.AddFilteringRule(pFilteringTable)) { IPACMERR("Error Adding RuleTable to Filtering, aborting...\n"); ret = IPACM_FAILURE; goto fail; } else { if(iptype == IPA_IP_v4) { for(i=0; inum_rules; i++) { wan_ul_fl_rule_hdl_v4[num_wan_ul_fl_rule_v4] = pFilteringTable->rules[i].flt_rule_hdl; num_wan_ul_fl_rule_v4++; } } else if(iptype == IPA_IP_v6) { for(i=0; inum_rules; i++) { wan_ul_fl_rule_hdl_v6[num_wan_ul_fl_rule_v6] = pFilteringTable->rules[i].flt_rule_hdl; num_wan_ul_fl_rule_v6++; } } else { IPACMERR("IP type is not expected.\n"); goto fail; } } fail: free(pFilteringTable); close(fd); return ret; } int IPACM_Lan::handle_wan_down_v6(bool is_sta_mode) { ipa_fltr_installed_notif_req_msg_v01 flt_index; int fd; fd = open(IPA_DEVICE_NAME, O_RDWR); if (0 == fd) { IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME); return IPACM_FAILURE; } #ifdef FEATURE_ETH_BRIDGE_LE flt_rule_count_v6 = IPV6_DEFAULT_FILTERTING_RULES + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + NUM_IPV6_ICMP_FLT_RULE; #else #ifdef CT_OPT flt_rule_count_v6 = IPV6_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + NUM_IPV6_ICMP_FLT_RULE; #else flt_rule_count_v6 = IPV6_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + NUM_IPV6_ICMP_FLT_RULE; #endif #endif if(m_filtering.DeleteFilteringHdls(ipv6_prefix_flt_rule_hdl, IPA_IP_v6, NUM_IPV6_PREFIX_FLT_RULE) == false) { close(fd); return IPACM_FAILURE; } if(is_sta_mode == false) { if (num_wan_ul_fl_rule_v6 > MAX_WAN_UL_FILTER_RULES) { IPACMERR(" the number of rules (%d) are bigger than array (%d), aborting...\n", num_wan_ul_fl_rule_v6, MAX_WAN_UL_FILTER_RULES); close(fd); return IPACM_FAILURE; } if (m_filtering.DeleteFilteringHdls(wan_ul_fl_rule_hdl_v6, IPA_IP_v6, num_wan_ul_fl_rule_v6) == false) { IPACMERR("Error Deleting RuleTable(1) to Filtering, aborting...\n"); close(fd); return IPACM_FAILURE; } memset(wan_ul_fl_rule_hdl_v6, 0, MAX_WAN_UL_FILTER_RULES * sizeof(uint32_t)); num_wan_ul_fl_rule_v6 = 0; modem_ul_v6_set = false; memset(&flt_index, 0, sizeof(flt_index)); flt_index.source_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[0].src_pipe); flt_index.install_status = IPA_QMI_RESULT_SUCCESS_V01; flt_index.filter_index_list_len = 0; flt_index.embedded_pipe_index_valid = 1; flt_index.embedded_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, IPA_CLIENT_APPS_LAN_WAN_PROD); flt_index.retain_header_valid = 1; flt_index.retain_header = 0; flt_index.embedded_call_mux_id_valid = 1; flt_index.embedded_call_mux_id = IPACM_Iface::ipacmcfg->GetQmapId(); if(false == m_filtering.SendFilteringRuleIndex(&flt_index)) { IPACMERR("Error sending filtering rule index, aborting...\n"); close(fd); return IPACM_FAILURE; } } else { if (m_filtering.DeleteFilteringHdls(&dft_v6fl_rule_hdl[IPV6_DEFAULT_FILTERTING_RULES], IPA_IP_v6, 1) == false) { IPACMERR("Error Adding RuleTable(1) to Filtering, aborting...\n"); close(fd); return IPACM_FAILURE; } } close(fd); return IPACM_SUCCESS; } /*handle lan2lan client active*/ int IPACM_Lan::handle_lan2lan_client_active(ipacm_event_data_all *data, ipa_cm_event_id event) { if(data == NULL) { IPACMERR("Event data is empty.\n"); return IPACM_FAILURE; } if(data->iptype == IPA_IP_v4 && ip_type != IPA_IP_v4 && ip_type != IPA_IP_MAX) { IPACMERR("Client has IPv4 addr but iface does not have IPv4 up.\n"); return IPACM_FAILURE; } if(data->iptype == IPA_IP_v6 && ip_type != IPA_IP_v6 && ip_type != IPA_IP_MAX) { IPACMERR("Client has IPv6 addr but iface does not have IPv6 up.\n"); return IPACM_FAILURE; } ipacm_cmd_q_data evt_data; memset(&evt_data, 0, sizeof(evt_data)); ipacm_event_lan_client* lan_client; lan_client = (ipacm_event_lan_client*)malloc(sizeof(ipacm_event_lan_client)); if(lan_client == NULL) { IPACMERR("Unable to allocate memory.\n"); return IPACM_FAILURE; } memset(lan_client, 0, sizeof(ipacm_event_lan_client)); lan_client->iptype = data->iptype; lan_client->ipv4_addr = data->ipv4_addr; memcpy(lan_client->ipv6_addr, data->ipv6_addr, 4 * sizeof(uint32_t)); memcpy(lan_client->mac_addr, data->mac_addr, 6 * sizeof(uint8_t)); lan_client->p_iface = this; evt_data.event = event; evt_data.evt_data = (void*)lan_client; IPACMDBG_H("Posting event: %d\n", event); IPACM_EvtDispatcher::PostEvt(&evt_data); return IPACM_SUCCESS; } int IPACM_Lan::add_lan2lan_flt_rule(ipa_ip_type iptype, uint32_t src_v4_addr, uint32_t dst_v4_addr, uint32_t* src_v6_addr, uint32_t* dst_v6_addr, uint32_t* rule_hdl) { if(rx_prop == NULL) { IPACMERR("There is no rx_prop for iface %s, not able to add lan2lan filtering rule.\n", dev_name); return IPACM_FAILURE; } if(rule_hdl == NULL) { IPACMERR("Filteing rule handle is empty.\n"); return IPACM_FAILURE; } IPACMDBG_H("Got a new lan2lan flt rule with IP type: %d\n", iptype); int i, len, res = IPACM_SUCCESS; struct ipa_flt_rule_mdfy flt_rule; struct ipa_ioc_mdfy_flt_rule* pFilteringTable; len = sizeof(struct ipa_ioc_mdfy_flt_rule) + sizeof(struct ipa_flt_rule_mdfy); pFilteringTable = (struct ipa_ioc_mdfy_flt_rule*)malloc(len); if (pFilteringTable == NULL) { IPACMERR("Error allocate lan2lan flt rule memory...\n"); return IPACM_FAILURE; } memset(pFilteringTable, 0, len); pFilteringTable->commit = 1; pFilteringTable->ip = iptype; pFilteringTable->num_rules = 1; memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy)); if(iptype == IPA_IP_v4) { IPACMDBG_H("src_v4_addr: %d dst_v4_addr: %d\n", src_v4_addr, dst_v4_addr); if(num_lan2lan_flt_rule_v4 >= MAX_OFFLOAD_PAIR) { IPACMERR("Lan2lan flt rule table is full, not able to add.\n"); res = IPACM_FAILURE; goto fail; } if(false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_lan2lan_v4)) { IPACMERR("Failed to get routing table %s handle.\n", IPACM_Iface::ipacmcfg->rt_tbl_lan2lan_v4.name); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("Routing handle for table %s: %d\n", IPACM_Iface::ipacmcfg->rt_tbl_lan2lan_v4.name, IPACM_Iface::ipacmcfg->rt_tbl_lan2lan_v4.hdl); flt_rule.status = -1; for(i=0; irt_tbl_lan2lan_v4.hdl; memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib)); IPACMDBG_H("Rx property attrib mask:0x%x\n", rx_prop->rx[0].attrib.attrib_mask); flt_rule.rule.attrib.attrib_mask |= IPA_FLT_SRC_ADDR; flt_rule.rule.attrib.u.v4.src_addr = src_v4_addr; flt_rule.rule.attrib.u.v4.src_addr_mask = 0xFFFFFFFF; flt_rule.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; flt_rule.rule.attrib.u.v4.dst_addr = dst_v4_addr; flt_rule.rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF; memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) { IPACMERR("Error modifying filtering rule.\n"); res = IPACM_FAILURE; goto fail; } else { lan2lan_flt_rule_hdl_v4[i].valid = true; *rule_hdl = lan2lan_flt_rule_hdl_v4[i].rule_hdl; num_lan2lan_flt_rule_v4++; IPACMDBG_H("Flt rule modified, hdl: 0x%x, status: %d\n", pFilteringTable->rules[0].rule_hdl, pFilteringTable->rules[0].status); } } else if(iptype == IPA_IP_v6) { if(num_lan2lan_flt_rule_v6 >= MAX_OFFLOAD_PAIR) { IPACMERR("Lan2lan flt rule table is full, not able to add.\n"); res = IPACM_FAILURE; goto fail; } if(src_v6_addr == NULL || dst_v6_addr == NULL) { IPACMERR("Got IPv6 flt rule but without IPv6 src/dst addr.\n"); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("src_v6_addr: 0x%08x%08x%08x%08x, dst_v6_addr: 0x%08x%08x%08x%08x\n", src_v6_addr[0], src_v6_addr[1], src_v6_addr[2], src_v6_addr[3], dst_v6_addr[0], dst_v6_addr[1], dst_v6_addr[2], dst_v6_addr[3]); if(false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_lan2lan_v6)) { IPACMERR("Failed to get routing table %s handle.\n", IPACM_Iface::ipacmcfg->rt_tbl_lan2lan_v6.name); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("Routing handle for table %s: %d\n", IPACM_Iface::ipacmcfg->rt_tbl_lan2lan_v6.name, IPACM_Iface::ipacmcfg->rt_tbl_lan2lan_v6.hdl); flt_rule.status = -1; for(i=0; irt_tbl_lan2lan_v6.hdl; memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib)); IPACMDBG_H("Rx property attrib mask:0x%x\n", rx_prop->rx[0].attrib.attrib_mask); flt_rule.rule.attrib.attrib_mask |= IPA_FLT_SRC_ADDR; flt_rule.rule.attrib.u.v6.src_addr[0] = src_v6_addr[0]; flt_rule.rule.attrib.u.v6.src_addr[1] = src_v6_addr[1]; flt_rule.rule.attrib.u.v6.src_addr[2] = src_v6_addr[2]; flt_rule.rule.attrib.u.v6.src_addr[3] = src_v6_addr[3]; flt_rule.rule.attrib.u.v6.src_addr_mask[0] = 0xFFFFFFFF; flt_rule.rule.attrib.u.v6.src_addr_mask[1] = 0xFFFFFFFF; flt_rule.rule.attrib.u.v6.src_addr_mask[2] = 0xFFFFFFFF; flt_rule.rule.attrib.u.v6.src_addr_mask[3] = 0xFFFFFFFF; flt_rule.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; flt_rule.rule.attrib.u.v6.dst_addr[0] = dst_v6_addr[0]; flt_rule.rule.attrib.u.v6.dst_addr[1] = dst_v6_addr[1]; flt_rule.rule.attrib.u.v6.dst_addr[2] = dst_v6_addr[2]; flt_rule.rule.attrib.u.v6.dst_addr[3] = dst_v6_addr[3]; flt_rule.rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF; flt_rule.rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; flt_rule.rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF; flt_rule.rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF; memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) { IPACMERR("Error modifying filtering rule.\n"); res = IPACM_FAILURE; goto fail; } else { lan2lan_flt_rule_hdl_v6[i].valid = true; *rule_hdl = lan2lan_flt_rule_hdl_v6[i].rule_hdl; num_lan2lan_flt_rule_v6++; IPACMDBG_H("Flt rule modified, hdl: 0x%x, status: %d\n", pFilteringTable->rules[0].rule_hdl, pFilteringTable->rules[0].status); } } else { IPACMERR("IP type is not expected.\n"); res = IPACM_FAILURE; goto fail; } fail: free(pFilteringTable); return res; } int IPACM_Lan::add_dummy_lan2lan_flt_rule(ipa_ip_type iptype) { if(rx_prop == NULL) { IPACMDBG_H("There is no rx_prop for iface %s, not able to add dummy lan2lan filtering rule.\n", dev_name); return 0; } int i, len, res = IPACM_SUCCESS; struct ipa_flt_rule_add flt_rule; ipa_ioc_add_flt_rule* pFilteringTable; len = sizeof(struct ipa_ioc_add_flt_rule) + MAX_OFFLOAD_PAIR * sizeof(struct ipa_flt_rule_add); pFilteringTable = (struct ipa_ioc_add_flt_rule *)malloc(len); if (pFilteringTable == NULL) { IPACMERR("Error allocate flt table memory...\n"); return IPACM_FAILURE; } memset(pFilteringTable, 0, len); pFilteringTable->commit = 1; pFilteringTable->ep = rx_prop->rx[0].src_pipe; pFilteringTable->global = false; pFilteringTable->ip = iptype; pFilteringTable->num_rules = MAX_OFFLOAD_PAIR; memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_add)); flt_rule.rule.retain_hdr = 0; flt_rule.at_rear = true; flt_rule.flt_rule_hdl = -1; flt_rule.status = -1; flt_rule.rule.action = IPA_PASS_TO_EXCEPTION; memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib)); if(iptype == IPA_IP_v4) { flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR; flt_rule.rule.attrib.u.v4.src_addr_mask = ~0; flt_rule.rule.attrib.u.v4.src_addr = ~0; flt_rule.rule.attrib.u.v4.dst_addr_mask = ~0; flt_rule.rule.attrib.u.v4.dst_addr = ~0; for(i=0; irules[i]), &flt_rule, sizeof(struct ipa_flt_rule_add)); } if (false == m_filtering.AddFilteringRule(pFilteringTable)) { IPACMERR("Error adding dummy lan2lan v4 flt rule\n"); res = IPACM_FAILURE; goto fail; } else { flt_rule_count_v4 += MAX_OFFLOAD_PAIR; /* copy filter rule hdls */ for (int i = 0; i < MAX_OFFLOAD_PAIR; i++) { if (pFilteringTable->rules[i].status == 0) { lan2lan_flt_rule_hdl_v4[i].rule_hdl = pFilteringTable->rules[i].flt_rule_hdl; IPACMDBG_H("Lan2lan v4 flt rule %d hdl:0x%x\n", i, lan2lan_flt_rule_hdl_v4[i].rule_hdl); } else { IPACMERR("Failed adding lan2lan v4 flt rule %d\n", i); res = IPACM_FAILURE; goto fail; } } } } else if(iptype == IPA_IP_v6) { flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR; flt_rule.rule.attrib.u.v6.src_addr_mask[0] = ~0; flt_rule.rule.attrib.u.v6.src_addr_mask[1] = ~0; flt_rule.rule.attrib.u.v6.src_addr_mask[2] = ~0; flt_rule.rule.attrib.u.v6.src_addr_mask[3] = ~0; flt_rule.rule.attrib.u.v6.src_addr[0] = ~0; flt_rule.rule.attrib.u.v6.src_addr[1] = ~0; flt_rule.rule.attrib.u.v6.src_addr[2] = ~0; flt_rule.rule.attrib.u.v6.src_addr[3] = ~0; flt_rule.rule.attrib.u.v6.dst_addr_mask[0] = ~0; flt_rule.rule.attrib.u.v6.dst_addr_mask[1] = ~0; flt_rule.rule.attrib.u.v6.dst_addr_mask[2] = ~0; flt_rule.rule.attrib.u.v6.dst_addr_mask[3] = ~0; flt_rule.rule.attrib.u.v6.dst_addr[0] = ~0; flt_rule.rule.attrib.u.v6.dst_addr[1] = ~0; flt_rule.rule.attrib.u.v6.dst_addr[2] = ~0; flt_rule.rule.attrib.u.v6.dst_addr[3] = ~0; for(i=0; irules[i]), &flt_rule, sizeof(struct ipa_flt_rule_add)); } if (false == m_filtering.AddFilteringRule(pFilteringTable)) { IPACMERR("Error adding dummy lan2lan v6 flt rule\n"); res = IPACM_FAILURE; goto fail; } else { flt_rule_count_v6 += MAX_OFFLOAD_PAIR; /* copy filter rule hdls */ for (int i = 0; i < MAX_OFFLOAD_PAIR; i++) { if (pFilteringTable->rules[i].status == 0) { lan2lan_flt_rule_hdl_v6[i].rule_hdl = pFilteringTable->rules[i].flt_rule_hdl; IPACMDBG_H("Lan2lan v6 flt rule %d hdl:0x%x\n", i, lan2lan_flt_rule_hdl_v6[i].rule_hdl); } else { IPACMERR("Failed adding lan2lan v6 flt rule %d\n", i); res = IPACM_FAILURE; goto fail; } } } } else { IPACMERR("IP type is not expected.\n"); goto fail; } fail: free(pFilteringTable); return res; } int IPACM_Lan::del_lan2lan_flt_rule(ipa_ip_type iptype, uint32_t rule_hdl) { int i; IPACMDBG_H("Del lan2lan flt rule with IP type: %d hdl: %d\n", iptype, rule_hdl); if(iptype == IPA_IP_v4) { for(i=0; icommit = 1; pFilteringTable->ip = iptype; pFilteringTable->num_rules = 1; memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy)); flt_rule.status = -1; flt_rule.rule_hdl = rule_hdl; flt_rule.rule.retain_hdr = 0; flt_rule.rule.action = IPA_PASS_TO_EXCEPTION; if(iptype == IPA_IP_v4) { IPACMDBG_H("Reset IPv4 flt rule to dummy\n"); flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR; flt_rule.rule.attrib.u.v4.dst_addr = ~0; flt_rule.rule.attrib.u.v4.dst_addr_mask = ~0; flt_rule.rule.attrib.u.v4.src_addr = ~0; flt_rule.rule.attrib.u.v4.src_addr_mask = ~0; memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) { IPACMERR("Error modifying filtering rule.\n"); res = IPACM_FAILURE; goto fail; } else { IPACMDBG_H("Flt rule reset to dummy, hdl: 0x%x, status: %d\n", pFilteringTable->rules[0].rule_hdl, pFilteringTable->rules[0].status); } } else if(iptype == IPA_IP_v6) { IPACMDBG_H("Reset IPv6 flt rule to dummy\n"); flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR; flt_rule.rule.attrib.u.v6.src_addr[0] = ~0; flt_rule.rule.attrib.u.v6.src_addr[1] = ~0; flt_rule.rule.attrib.u.v6.src_addr[2] = ~0; flt_rule.rule.attrib.u.v6.src_addr[3] = ~0; flt_rule.rule.attrib.u.v6.src_addr_mask[0] = ~0; flt_rule.rule.attrib.u.v6.src_addr_mask[1] = ~0; flt_rule.rule.attrib.u.v6.src_addr_mask[2] = ~0; flt_rule.rule.attrib.u.v6.src_addr_mask[3] = ~0; flt_rule.rule.attrib.u.v6.dst_addr[0] = ~0; flt_rule.rule.attrib.u.v6.dst_addr[1] = ~0; flt_rule.rule.attrib.u.v6.dst_addr[2] = ~0; flt_rule.rule.attrib.u.v6.dst_addr[3] = ~0; flt_rule.rule.attrib.u.v6.dst_addr_mask[0] = ~0; flt_rule.rule.attrib.u.v6.dst_addr_mask[1] = ~0; flt_rule.rule.attrib.u.v6.dst_addr_mask[2] = ~0; flt_rule.rule.attrib.u.v6.dst_addr_mask[3] = ~0; memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) { IPACMERR("Error modifying filtering rule.\n"); res = IPACM_FAILURE; goto fail; } else { IPACMDBG_H("Flt rule reset to dummy, hdl: 0x%x, status: %d\n", pFilteringTable->rules[0].rule_hdl, pFilteringTable->rules[0].status); } } else { IPACMERR("IP type is not expected.\n"); res = IPACM_FAILURE; goto fail; } fail: free(pFilteringTable); return res; } int IPACM_Lan::add_lan2lan_hdr(ipa_ip_type iptype, uint8_t* src_mac, uint8_t* dst_mac, uint32_t* hdr_hdl) { if(tx_prop == NULL) { IPACMERR("There is no tx_prop, cannot add header.\n"); return IPACM_FAILURE; } if(src_mac == NULL || dst_mac == NULL) { IPACMERR("Either src_mac or dst_mac is null, cannot add header.\n"); return IPACM_FAILURE; } if(hdr_hdl == NULL) { IPACMERR("Header handle is empty.\n"); return IPACM_FAILURE; } int i, j, len; int res = IPACM_SUCCESS; char index[4]; struct ipa_ioc_copy_hdr sCopyHeader; struct ipa_ioc_add_hdr *pHeader; IPACMDBG_H("Get lan2lan header request, src_mac: 0x%02x%02x%02x%02x%02x%02x dst_mac: 0x%02x%02x%02x%02x%02x%02x\n", src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5], dst_mac[0], dst_mac[1], dst_mac[2], dst_mac[3], dst_mac[4], dst_mac[5]); len = sizeof(struct ipa_ioc_add_hdr) + sizeof(struct ipa_hdr_add); pHeader = (struct ipa_ioc_add_hdr *)malloc(len); if (pHeader == NULL) { IPACMERR("Failed to allocate header\n"); return IPACM_FAILURE; } memset(pHeader, 0, len); if(iptype == IPA_IP_v4) { /* copy partial header for v4*/ for(i=0; inum_tx_props; i++) { if(tx_prop->tx[i].ip == IPA_IP_v4) { IPACMDBG_H("Got v4-header name from %d tx props\n", i); memset(&sCopyHeader, 0, sizeof(sCopyHeader)); memcpy(sCopyHeader.name, tx_prop->tx[i].hdr_name, sizeof(sCopyHeader.name)); IPACMDBG_H("Header name: %s\n", sCopyHeader.name); if(m_header.CopyHeader(&sCopyHeader) == false) { IPACMERR("Copy header failed\n"); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("Header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial); if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE) { IPACMERR("Header oversize\n"); res = IPACM_FAILURE; goto fail; } else { memcpy(pHeader->hdr[0].hdr, sCopyHeader.hdr, sCopyHeader.hdr_len); } if(sCopyHeader.is_eth2_ofst_valid) { memcpy(&pHeader->hdr[0].hdr[sCopyHeader.eth2_ofst], dst_mac, IPA_MAC_ADDR_SIZE); memcpy(&pHeader->hdr[0].hdr[sCopyHeader.eth2_ofst+IPA_MAC_ADDR_SIZE], src_mac, IPA_MAC_ADDR_SIZE); } else { IPACMERR("Ethernet 2 header offset is invalid.\n"); } pHeader->commit = true; pHeader->num_hdrs = 1; memset(pHeader->hdr[0].name, 0, sizeof(pHeader->hdr[0].name)); strlcpy(pHeader->hdr[0].name, IPA_LAN_TO_LAN_USB_HDR_NAME_V4, sizeof(pHeader->hdr[0].name)); for(j=0; jhdr[0].name, index, sizeof(pHeader->hdr[0].name)) > IPA_RESOURCE_NAME_MAX) { IPACMERR(" header name construction failed exceed length (%d)\n", strlen(pHeader->hdr[0].name)); res = IPACM_FAILURE; goto fail; } pHeader->hdr[0].hdr_len = sCopyHeader.hdr_len; pHeader->hdr[0].is_partial = 0; pHeader->hdr[0].hdr_hdl = -1; pHeader->hdr[0].status = -1; if (m_header.AddHeader(pHeader) == false || pHeader->hdr[0].status != 0) { IPACMERR("Ioctl IPA_IOC_ADD_HDR failed with status: %d\n", pHeader->hdr[0].status); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("Installed v4 full header %s header handle 0x%08x\n", pHeader->hdr[0].name, pHeader->hdr[0].hdr_hdl); *hdr_hdl = pHeader->hdr[0].hdr_hdl; lan2lan_hdr_hdl_v4[j].hdr_hdl = pHeader->hdr[0].hdr_hdl; break; } } } else if(iptype == IPA_IP_v6) { /* copy partial header for v6*/ for(i=0; inum_tx_props; i++) { if(tx_prop->tx[i].ip == IPA_IP_v6) { IPACMDBG_H("Got v6-header name from %d tx props\n", i); memset(&sCopyHeader, 0, sizeof(sCopyHeader)); memcpy(sCopyHeader.name, tx_prop->tx[i].hdr_name, sizeof(sCopyHeader.name)); IPACMDBG_H("Header name: %s\n", sCopyHeader.name); if(m_header.CopyHeader(&sCopyHeader) == false) { IPACMERR("Copy header failed\n"); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("Header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial); if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE) { IPACMERR("Header oversize\n"); res = IPACM_FAILURE; goto fail; } else { memcpy(pHeader->hdr[0].hdr, sCopyHeader.hdr, sCopyHeader.hdr_len); } if(sCopyHeader.is_eth2_ofst_valid) { memcpy(&pHeader->hdr[0].hdr[sCopyHeader.eth2_ofst], dst_mac, IPA_MAC_ADDR_SIZE); memcpy(&pHeader->hdr[0].hdr[sCopyHeader.eth2_ofst+IPA_MAC_ADDR_SIZE], src_mac, IPA_MAC_ADDR_SIZE); } else { IPACMERR("Ethernet 2 header offset is invalid.\n"); } pHeader->commit = true; pHeader->num_hdrs = 1; memset(pHeader->hdr[0].name, 0, sizeof(pHeader->hdr[0].name)); strlcpy(pHeader->hdr[0].name, IPA_LAN_TO_LAN_USB_HDR_NAME_V6, sizeof(pHeader->hdr[0].name)); for(j=0; jhdr[0].name, index, sizeof(pHeader->hdr[0].name)) > IPA_RESOURCE_NAME_MAX) { IPACMERR(" header name construction failed exceed length (%d)\n", strlen(pHeader->hdr[0].name)); res = IPACM_FAILURE; goto fail; } pHeader->hdr[0].hdr_len = sCopyHeader.hdr_len; pHeader->hdr[0].is_partial = 0; pHeader->hdr[0].hdr_hdl = -1; pHeader->hdr[0].status = -1; if (m_header.AddHeader(pHeader) == false || pHeader->hdr[0].status != 0) { IPACMERR("Ioctl IPA_IOC_ADD_HDR failed with status: %d\n", pHeader->hdr[0].status); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("Installed v6 full header %s header handle 0x%08x\n", pHeader->hdr[0].name, pHeader->hdr[0].hdr_hdl); *hdr_hdl = pHeader->hdr[0].hdr_hdl; lan2lan_hdr_hdl_v6[j].hdr_hdl = pHeader->hdr[0].hdr_hdl; break; } } } else { IPACMERR("IP type is not expected.\n"); } fail: free(pHeader); return res; } int IPACM_Lan::del_lan2lan_hdr(ipa_ip_type iptype, uint32_t hdr_hdl) { int i; if (m_header.DeleteHeaderHdl(hdr_hdl) == false) { IPACMERR("Failed to delete header %d\n", hdr_hdl); return IPACM_FAILURE; } IPACMDBG_H("Deleted header %d\n", hdr_hdl); if(iptype == IPA_IP_v4) { for(i=0; icommit = 1; rt_rule->num_rules = 1; rt_rule->ip = iptype; if(iptype == IPA_IP_v4) { IPACMDBG_H("src_v4_addr: 0x%08x dst_v4_addr: 0x%08x\n", src_v4_addr, dst_v4_addr); strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan2lan_v4.name); rt_rule_entry = &rt_rule->rules[0]; rt_rule_entry->at_rear = false; rt_rule_entry->rt_rule_hdl = 0; rt_rule_entry->status = -1; for (tx_index = 0; tx_indexnum_tx_props; tx_index++) { if(tx_prop->tx[tx_index].ip != IPA_IP_v4) { IPACMDBG_H("Tx:%d, iptype: %d conflict ip-type: %d bypass\n", tx_index, tx_prop->tx[tx_index].ip, IPA_IP_v4); continue; } rt_rule_entry->rule.hdr_hdl = hdr_hdl; rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe; memcpy(&rt_rule_entry->rule.attrib, &tx_prop->tx[tx_index].attrib, sizeof(rt_rule_entry->rule.attrib)); rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_SRC_ADDR; rt_rule_entry->rule.attrib.u.v4.src_addr = src_v4_addr; rt_rule_entry->rule.attrib.u.v4.src_addr_mask = 0xFFFFFFFF; rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; rt_rule_entry->rule.attrib.u.v4.dst_addr = dst_v4_addr; rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF; if(m_routing.AddRoutingRule(rt_rule) == false) { IPACMERR("Routing rule addition failed\n"); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("Added rt rule hdl: 0x%08x\n", rt_rule_entry->rt_rule_hdl); rule_hdl->rule_hdl[rule_hdl->num_rule] = rt_rule_entry->rt_rule_hdl; rule_hdl->num_rule++; } } else if(iptype == IPA_IP_v6) { if(src_v6_addr == NULL || dst_v6_addr == NULL) { IPACMERR("Got IPv6 rt rule but without IPv6 src/dst addr.\n"); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("src_v6_addr: 0x%08x%08x%08x%08x, dst_v6_addr: 0x%08x%08x%08x%08x\n", src_v6_addr[0], src_v6_addr[1], src_v6_addr[2], src_v6_addr[3], dst_v6_addr[0], dst_v6_addr[1], dst_v6_addr[2], dst_v6_addr[3]); strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan2lan_v6.name); rt_rule_entry = &rt_rule->rules[0]; rt_rule_entry->at_rear = false; rt_rule_entry->rt_rule_hdl = 0; rt_rule_entry->status = -1; for (tx_index = 0; tx_indexnum_tx_props; tx_index++) { if(tx_prop->tx[tx_index].ip != IPA_IP_v6) { IPACMDBG_H("Tx:%d, iptype: %d conflict ip-type: %d bypass\n", tx_index, tx_prop->tx[tx_index].ip, IPA_IP_v6); continue; } rt_rule_entry->rule.hdr_hdl = hdr_hdl; rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe; memcpy(&rt_rule_entry->rule.attrib, &tx_prop->tx[tx_index].attrib, sizeof(rt_rule_entry->rule.attrib)); rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_SRC_ADDR; rt_rule_entry->rule.attrib.u.v6.src_addr[0] = src_v6_addr[0]; rt_rule_entry->rule.attrib.u.v6.src_addr[1] = src_v6_addr[1]; rt_rule_entry->rule.attrib.u.v6.src_addr[2] = src_v6_addr[2]; rt_rule_entry->rule.attrib.u.v6.src_addr[3] = src_v6_addr[3]; rt_rule_entry->rule.attrib.u.v6.src_addr_mask[0] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.src_addr_mask[1] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.src_addr_mask[2] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.src_addr_mask[3] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = dst_v6_addr[0]; rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = dst_v6_addr[1]; rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = dst_v6_addr[2]; rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = dst_v6_addr[3]; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF; if(m_routing.AddRoutingRule(rt_rule) == false) { IPACMERR("Routing rule addition failed\n"); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("Added rt rule hdl: 0x%08x\n", rt_rule_entry->rt_rule_hdl); rule_hdl->rule_hdl[rule_hdl->num_rule] = rt_rule_entry->rt_rule_hdl; rule_hdl->num_rule++; } } else { IPACMERR("IP type is not expected.\n"); } fail: free(rt_rule); return res; } int IPACM_Lan::del_lan2lan_rt_rule(ipa_ip_type iptype, lan_to_lan_rt_rule_hdl rule_hdl) { if(rule_hdl.num_rule <= 0 || rule_hdl.num_rule > MAX_NUM_PROP) { IPACMERR("The number of rule handles are not correct.\n"); return IPACM_FAILURE; } int i, res = IPACM_SUCCESS; IPACMDBG_H("Get %d rule handles with IP type %d\n", rule_hdl.num_rule, iptype); for(i=0; iif_index = ipa_if_num; evt.evt_data = (void*)fid; evt.event = IPA_LAN_DELETE_SELF; IPACMDBG_H("Posting event IPA_LAN_DELETE_SELF\n"); IPACM_EvtDispatcher::PostEvt(&evt); } /*handle reset usb-client rt-rules */ int IPACM_Lan::handle_lan_client_reset_rt(ipa_ip_type iptype) { int i, res = IPACM_SUCCESS; /* clean eth-client routing rules */ IPACMDBG_H("left %d eth clients need to be deleted \n ", num_eth_client); for (i = 0; i < num_eth_client; i++) { res = delete_eth_rtrules(i, iptype); if (res != IPACM_SUCCESS) { IPACMERR("Failed to delete old iptype(%d) rules.\n", iptype); return res; } } /* end of for loop */ /* Pass info to LAN2LAN module */ res = post_lan2lan_client_disconnect_msg(iptype); if (res != IPACM_SUCCESS) { IPACMERR("Failed to posting delete old iptype(%d) address.\n", iptype); return res; } /* Reset ip-address */ for (i = 0; i < num_eth_client; i++) { if(iptype == IPA_IP_v4) { get_client_memptr(eth_client, i)->ipv4_set = false; } else { get_client_memptr(eth_client, i)->ipv6_set = 0; } } /* end of for loop */ return res; } /*handle lan2lan internal mesg posting*/ int IPACM_Lan::post_lan2lan_client_disconnect_msg(ipa_ip_type iptype) { int i, j; ipacm_cmd_q_data evt_data; ipacm_event_lan_client* lan_client; for (i = 0; i < num_eth_client; i++) { if((get_client_memptr(eth_client, i)->ipv4_set == true) && (iptype == IPA_IP_v4)) { lan_client = (ipacm_event_lan_client*)malloc(sizeof(ipacm_event_lan_client)); if(lan_client == NULL) { IPACMERR("Failed to allocate memory.\n"); return IPACM_FAILURE; } memset(lan_client, 0, sizeof(ipacm_event_lan_client)); lan_client->iptype = IPA_IP_v4; lan_client->ipv4_addr = get_client_memptr(eth_client, i)->v4_addr; lan_client->p_iface = this; memset(&evt_data, 0, sizeof(ipacm_cmd_q_data)); evt_data.evt_data = (void*)lan_client; evt_data.event = IPA_LAN_CLIENT_DISCONNECT; IPACMDBG_H("Posting event IPA_LAN_CLIENT_DISCONNECT\n"); IPACM_EvtDispatcher::PostEvt(&evt_data); } if((get_client_memptr(eth_client, i)->ipv6_set > 0) && (iptype == IPA_IP_v6)) { for (j = 0; j < get_client_memptr(eth_client, i)->ipv6_set; j++) { lan_client = (ipacm_event_lan_client*)malloc(sizeof(ipacm_event_lan_client)); if(lan_client == NULL) { IPACMERR("Failed to allocate memory.\n"); return IPACM_FAILURE; } memset(lan_client, 0, sizeof(ipacm_event_lan_client)); lan_client->iptype = IPA_IP_v6; lan_client->ipv6_addr[0] = get_client_memptr(eth_client, i)->v6_addr[j][0]; lan_client->ipv6_addr[0] = get_client_memptr(eth_client, i)->v6_addr[j][0]; lan_client->ipv6_addr[0] = get_client_memptr(eth_client, i)->v6_addr[j][0]; lan_client->ipv6_addr[0] = get_client_memptr(eth_client, i)->v6_addr[j][0]; lan_client->p_iface = this; memset(&evt_data, 0, sizeof(ipacm_cmd_q_data)); evt_data.evt_data = (void*)lan_client; evt_data.event = IPA_LAN_CLIENT_DISCONNECT; IPACMDBG_H("Posting event IPA_LAN_CLIENT_DISCONNECT\n"); IPACM_EvtDispatcher::PostEvt(&evt_data); } } } /* end of for loop */ return IPACM_SUCCESS; } void IPACM_Lan::install_tcp_ctl_flt_rule(ipa_ip_type iptype) { if (rx_prop == NULL) { IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); return; } int len, i; struct ipa_flt_rule_add flt_rule; ipa_ioc_add_flt_rule* pFilteringTable; len = sizeof(struct ipa_ioc_add_flt_rule) + NUM_TCP_CTL_FLT_RULE * sizeof(struct ipa_flt_rule_add); pFilteringTable = (struct ipa_ioc_add_flt_rule *)malloc(len); if (pFilteringTable == NULL) { IPACMERR("Error allocate flt table memory...\n"); return; } memset(pFilteringTable, 0, len); pFilteringTable->commit = 1; pFilteringTable->ip = iptype; pFilteringTable->ep = rx_prop->rx[0].src_pipe; pFilteringTable->global = false; pFilteringTable->num_rules = NUM_TCP_CTL_FLT_RULE; memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_add)); flt_rule.at_rear = true; flt_rule.flt_rule_hdl = -1; flt_rule.status = -1; flt_rule.rule.retain_hdr = 1; flt_rule.rule.to_uc = 0; flt_rule.rule.action = IPA_PASS_TO_EXCEPTION; flt_rule.rule.eq_attrib_type = 1; flt_rule.rule.eq_attrib.rule_eq_bitmap = 0; flt_rule.rule.eq_attrib.rule_eq_bitmap |= (1<<14); flt_rule.rule.eq_attrib.metadata_meq32_present = 1; flt_rule.rule.eq_attrib.metadata_meq32.offset = 0; flt_rule.rule.eq_attrib.metadata_meq32.value = rx_prop->rx[0].attrib.meta_data; flt_rule.rule.eq_attrib.metadata_meq32.mask = rx_prop->rx[0].attrib.meta_data_mask; flt_rule.rule.eq_attrib.rule_eq_bitmap |= (1<<1); flt_rule.rule.eq_attrib.protocol_eq_present = 1; flt_rule.rule.eq_attrib.protocol_eq = IPACM_FIREWALL_IPPROTO_TCP; flt_rule.rule.eq_attrib.rule_eq_bitmap |= (1<<8); flt_rule.rule.eq_attrib.num_ihl_offset_meq_32 = 1; flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].offset = 12; /* add TCP FIN rule*/ flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_add)); /* add TCP SYN rule*/ flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<rules[1]), &flt_rule, sizeof(struct ipa_flt_rule_add)); /* add TCP RST rule*/ flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<rules[2]), &flt_rule, sizeof(struct ipa_flt_rule_add)); if (false == m_filtering.AddFilteringRule(pFilteringTable)) { IPACMERR("Error adding tcp control flt rule\n"); goto fail; } else { if(iptype == IPA_IP_v4) { for(i=0; irules[i].flt_rule_hdl; } } else { for(i=0; irules[i].flt_rule_hdl; } } } fail: free(pFilteringTable); return; } int IPACM_Lan::add_dummy_private_subnet_flt_rule(ipa_ip_type iptype) { if(rx_prop == NULL) { IPACMDBG_H("There is no rx_prop for iface %s, not able to add dummy private subnet filtering rule.\n", dev_name); return 0; } if(iptype == IPA_IP_v6) { IPACMDBG_H("There is no ipv6 dummy filter rules needed for iface %s\n", dev_name); return 0; } int i, len, res = IPACM_SUCCESS; struct ipa_flt_rule_add flt_rule; ipa_ioc_add_flt_rule* pFilteringTable; len = sizeof(struct ipa_ioc_add_flt_rule) + IPA_MAX_PRIVATE_SUBNET_ENTRIES * sizeof(struct ipa_flt_rule_add); pFilteringTable = (struct ipa_ioc_add_flt_rule *)malloc(len); if (pFilteringTable == NULL) { IPACMERR("Error allocate flt table memory...\n"); return IPACM_FAILURE; } memset(pFilteringTable, 0, len); pFilteringTable->commit = 1; pFilteringTable->ep = rx_prop->rx[0].src_pipe; pFilteringTable->global = false; pFilteringTable->ip = iptype; pFilteringTable->num_rules = IPA_MAX_PRIVATE_SUBNET_ENTRIES; memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_add)); flt_rule.rule.retain_hdr = 0; flt_rule.at_rear = true; flt_rule.flt_rule_hdl = -1; flt_rule.status = -1; flt_rule.rule.action = IPA_PASS_TO_EXCEPTION; memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib)); if(iptype == IPA_IP_v4) { flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR; flt_rule.rule.attrib.u.v4.src_addr_mask = ~0; flt_rule.rule.attrib.u.v4.src_addr = ~0; flt_rule.rule.attrib.u.v4.dst_addr_mask = ~0; flt_rule.rule.attrib.u.v4.dst_addr = ~0; for(i=0; irules[i]), &flt_rule, sizeof(struct ipa_flt_rule_add)); } if (false == m_filtering.AddFilteringRule(pFilteringTable)) { IPACMERR("Error adding dummy private subnet v4 flt rule\n"); res = IPACM_FAILURE; goto fail; } else { flt_rule_count_v4 += IPA_MAX_PRIVATE_SUBNET_ENTRIES; /* copy filter rule hdls */ for (int i = 0; i < IPA_MAX_PRIVATE_SUBNET_ENTRIES; i++) { if (pFilteringTable->rules[i].status == 0) { private_fl_rule_hdl[i] = pFilteringTable->rules[i].flt_rule_hdl; IPACMDBG_H("Private subnet v4 flt rule %d hdl:0x%x\n", i, private_fl_rule_hdl[i]); } else { IPACMERR("Failed adding lan2lan v4 flt rule %d\n", i); res = IPACM_FAILURE; goto fail; } } } } fail: free(pFilteringTable); return res; } int IPACM_Lan::handle_private_subnet_android(ipa_ip_type iptype) { int i, len, res = IPACM_SUCCESS; struct ipa_flt_rule_mdfy flt_rule; struct ipa_ioc_mdfy_flt_rule* pFilteringTable; if (rx_prop == NULL) { IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); return IPACM_SUCCESS; } if(iptype == IPA_IP_v6) { IPACMDBG_H("There is no ipv6 dummy filter rules needed for iface %s\n", dev_name); return 0; } else { for(i=0; iipa_num_private_subnet) * sizeof(struct ipa_flt_rule_mdfy); pFilteringTable = (struct ipa_ioc_mdfy_flt_rule*)malloc(len); if (!pFilteringTable) { IPACMERR("Failed to allocate ipa_ioc_mdfy_flt_rule memory...\n"); return IPACM_FAILURE; } memset(pFilteringTable, 0, len); pFilteringTable->commit = 1; pFilteringTable->ip = iptype; pFilteringTable->num_rules = (uint8_t)IPACM_Iface::ipacmcfg->ipa_num_private_subnet; /* Make LAN-traffic always go A5, use default IPA-RT table */ if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_default_v4)) { IPACMERR("Failed to get routing table handle.\n"); res = IPACM_FAILURE; goto fail; } memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy)); flt_rule.status = -1; flt_rule.rule.retain_hdr = 1; flt_rule.rule.to_uc = 0; flt_rule.rule.action = IPA_PASS_TO_ROUTING; flt_rule.rule.eq_attrib_type = 0; flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_default_v4.hdl; IPACMDBG_H("Private filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_default_v4.name); memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib)); flt_rule.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; for (i = 0; i < (IPACM_Iface::ipacmcfg->ipa_num_private_subnet); i++) { flt_rule.rule_hdl = private_fl_rule_hdl[i]; flt_rule.rule.attrib.u.v4.dst_addr_mask = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask; flt_rule.rule.attrib.u.v4.dst_addr = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_addr; memcpy(&(pFilteringTable->rules[i]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); IPACMDBG_H(" IPACM private subnet_addr as: 0x%x entry(%d)\n", flt_rule.rule.attrib.u.v4.dst_addr, i); } if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) { IPACMERR("Failed to modify private subnet filtering rules.\n"); res = IPACM_FAILURE; goto fail; } } fail: if(pFilteringTable != NULL) { free(pFilteringTable); } return res; } int IPACM_Lan::install_ipv6_prefix_flt_rule(uint32_t* prefix) { if(prefix == NULL) { IPACMERR("IPv6 prefix is empty.\n"); return IPACM_FAILURE; } IPACMDBG_H("Receive IPv6 prefix: 0x%08x%08x.\n", prefix[0], prefix[1]); int len; struct ipa_ioc_add_flt_rule* flt_rule; struct ipa_flt_rule_add flt_rule_entry; if(rx_prop != NULL) { len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add); flt_rule = (struct ipa_ioc_add_flt_rule *)calloc(1, len); if (!flt_rule) { IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); return IPACM_FAILURE; } flt_rule->commit = 1; flt_rule->ep = rx_prop->rx[0].src_pipe; flt_rule->global = false; flt_rule->ip = IPA_IP_v6; flt_rule->num_rules = 1; memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); flt_rule_entry.rule.retain_hdr = 1; flt_rule_entry.rule.to_uc = 0; flt_rule_entry.rule.eq_attrib_type = 0; flt_rule_entry.at_rear = true; flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); flt_rule_entry.rule.attrib.attrib_mask = flt_rule_entry.rule.attrib.attrib_mask & ~((uint32_t)IPA_FLT_META_DATA); flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = prefix[0]; flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = prefix[1]; flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x0; flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0x0; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x0; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x0; memcpy(&(flt_rule->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); if (m_filtering.AddFilteringRule(flt_rule) == false) { IPACMERR("Error Adding Filtering rule, aborting...\n"); free(flt_rule); return IPACM_FAILURE; } else { ipv6_prefix_flt_rule_hdl[0] = flt_rule->rules[0].flt_rule_hdl; IPACMDBG_H("IPv6 prefix filter rule HDL:0x%x\n", ipv6_prefix_flt_rule_hdl[0]); flt_rule_count_v6++; free(flt_rule); } } return IPACM_SUCCESS; } int IPACM_Lan::install_ipv6_icmp_flt_rule() { int len; struct ipa_ioc_add_flt_rule* flt_rule; struct ipa_flt_rule_add flt_rule_entry; if(rx_prop != NULL) { len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add); flt_rule = (struct ipa_ioc_add_flt_rule *)calloc(1, len); if (!flt_rule) { IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); return IPACM_FAILURE; } flt_rule->commit = 1; flt_rule->ep = rx_prop->rx[0].src_pipe; flt_rule->global = false; flt_rule->ip = IPA_IP_v6; flt_rule->num_rules = 1; memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); flt_rule_entry.rule.retain_hdr = 1; flt_rule_entry.rule.to_uc = 0; flt_rule_entry.rule.eq_attrib_type = 0; flt_rule_entry.at_rear = true; flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); flt_rule_entry.rule.attrib.attrib_mask = flt_rule_entry.rule.attrib.attrib_mask & ~((uint32_t)IPA_FLT_META_DATA); flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR; flt_rule_entry.rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_ICMP6; memcpy(&(flt_rule->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); if (m_filtering.AddFilteringRule(flt_rule) == false) { IPACMERR("Error Adding Filtering rule, aborting...\n"); free(flt_rule); return IPACM_FAILURE; } else { ipv6_icmp_flt_rule_hdl[0] = flt_rule->rules[0].flt_rule_hdl; IPACMDBG_H("IPv6 icmp filter rule HDL:0x%x\n", ipv6_icmp_flt_rule_hdl[0]); flt_rule_count_v6++; free(flt_rule); } } return IPACM_SUCCESS; } int IPACM_Lan::handle_addr_evt_odu_bridge(ipacm_event_data_addr* data) { int fd, res = IPACM_SUCCESS; struct in6_addr ipv6_addr; if(data == NULL) { IPACMERR("Failed to get interface IP address.\n"); return IPACM_FAILURE; } if(data->iptype == IPA_IP_v6) { fd = open(IPACM_Iface::ipacmcfg->DEVICE_NAME_ODU, O_RDWR); if(fd == 0) { IPACMERR("Failed to open %s.\n", IPACM_Iface::ipacmcfg->DEVICE_NAME_ODU); return IPACM_FAILURE; } memcpy(&ipv6_addr, data->ipv6_addr, sizeof(struct in6_addr)); if( ioctl(fd, ODU_BRIDGE_IOC_SET_LLV6_ADDR, &ipv6_addr) ) { IPACMERR("Failed to write IPv6 address to odu driver.\n"); res = IPACM_FAILURE; } num_dft_rt_v6++; close(fd); } return res; } int IPACM_Lan::eth_bridge_handle_dummy_wlan_client_flt_rule(ipa_ip_type iptype) { if(rx_prop == NULL) { IPACMDBG_H("There is no rx_prop for iface %s, not able to add dummy wlan client specific filtering rule.\n", dev_name); return 0; } int i, len, res = IPACM_SUCCESS; struct ipa_flt_rule_add flt_rule; ipa_ioc_add_flt_rule* pFilteringTable; len = sizeof(struct ipa_ioc_add_flt_rule) + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT * sizeof(struct ipa_flt_rule_add); pFilteringTable = (struct ipa_ioc_add_flt_rule *)malloc(len); if (pFilteringTable == NULL) { IPACMERR("Error allocate flt table memory...\n"); return IPACM_FAILURE; } memset(pFilteringTable, 0, len); pFilteringTable->commit = 1; pFilteringTable->ep = rx_prop->rx[0].src_pipe; pFilteringTable->global = false; pFilteringTable->ip = iptype; pFilteringTable->num_rules = IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_add)); flt_rule.rule.retain_hdr = 0; flt_rule.at_rear = true; flt_rule.flt_rule_hdl = -1; flt_rule.status = -1; flt_rule.rule.action = IPA_PASS_TO_EXCEPTION; memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib)); if(iptype == IPA_IP_v4) { flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR; flt_rule.rule.attrib.u.v4.src_addr_mask = ~0; flt_rule.rule.attrib.u.v4.src_addr = ~0; flt_rule.rule.attrib.u.v4.dst_addr_mask = ~0; flt_rule.rule.attrib.u.v4.dst_addr = ~0; for(i=0; irules[i]), &flt_rule, sizeof(struct ipa_flt_rule_add)); } if (false == m_filtering.AddFilteringRule(pFilteringTable)) { IPACMERR("Error adding dummy lan2lan v4 flt rule\n"); res = IPACM_FAILURE; goto fail; } else { flt_rule_count_v4 += IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; /* copy filter rule hdls */ for (int i = 0; i < IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; i++) { if (pFilteringTable->rules[i].status == 0) { wlan_client_flt_rule_hdl_v4[i].rule_hdl = pFilteringTable->rules[i].flt_rule_hdl; wlan_client_flt_rule_hdl_v4[i].valid = true; IPACMDBG_H("Wlan client v4 flt rule %d hdl:0x%x\n", i, wlan_client_flt_rule_hdl_v4[i].rule_hdl); } else { IPACMERR("Failed adding wlan client v4 flt rule %d\n", i); res = IPACM_FAILURE; goto fail; } } } } else if(iptype == IPA_IP_v6) { flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR; flt_rule.rule.attrib.u.v6.src_addr_mask[0] = ~0; flt_rule.rule.attrib.u.v6.src_addr_mask[1] = ~0; flt_rule.rule.attrib.u.v6.src_addr_mask[2] = ~0; flt_rule.rule.attrib.u.v6.src_addr_mask[3] = ~0; flt_rule.rule.attrib.u.v6.src_addr[0] = ~0; flt_rule.rule.attrib.u.v6.src_addr[1] = ~0; flt_rule.rule.attrib.u.v6.src_addr[2] = ~0; flt_rule.rule.attrib.u.v6.src_addr[3] = ~0; flt_rule.rule.attrib.u.v6.dst_addr_mask[0] = ~0; flt_rule.rule.attrib.u.v6.dst_addr_mask[1] = ~0; flt_rule.rule.attrib.u.v6.dst_addr_mask[2] = ~0; flt_rule.rule.attrib.u.v6.dst_addr_mask[3] = ~0; flt_rule.rule.attrib.u.v6.dst_addr[0] = ~0; flt_rule.rule.attrib.u.v6.dst_addr[1] = ~0; flt_rule.rule.attrib.u.v6.dst_addr[2] = ~0; flt_rule.rule.attrib.u.v6.dst_addr[3] = ~0; for(i=0; irules[i]), &flt_rule, sizeof(struct ipa_flt_rule_add)); } if (false == m_filtering.AddFilteringRule(pFilteringTable)) { IPACMERR("Error adding dummy lan2lan v6 flt rule\n"); res = IPACM_FAILURE; goto fail; } else { flt_rule_count_v6 += IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; /* copy filter rule hdls */ for (int i = 0; i < IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; i++) { if (pFilteringTable->rules[i].status == 0) { wlan_client_flt_rule_hdl_v6[i].rule_hdl = pFilteringTable->rules[i].flt_rule_hdl; wlan_client_flt_rule_hdl_v6[i].valid = true; IPACMDBG_H("Wlan client v6 flt rule %d hdl:0x%x\n", i, wlan_client_flt_rule_hdl_v6[i].rule_hdl); } else { IPACMERR("Failed adding wlan client v6 flt rule %d\n", i); res = IPACM_FAILURE; goto fail; } } } } else { IPACMERR("IP type is not expected.\n"); goto fail; } fail: free(pFilteringTable); return res; } int IPACM_Lan::eth_bridge_add_wlan_guest_ap_flt_rule(ipa_ip_type iptype) { IPACMDBG_H("No need to add WLAN guest AP flt rule on USB pipe.\n"); return IPACM_SUCCESS; } int IPACM_Lan::eth_bridge_handle_dummy_usb_client_flt_rule(ipa_ip_type iptype) { IPACMDBG_H("No need to add USB client specific flt rule on USB pipe.\n"); return IPACM_SUCCESS; } int IPACM_Lan::eth_bridge_post_lan_client_event(uint8_t* mac_addr, ipa_cm_event_id evt) { if(mac_addr == NULL) { IPACMERR("Event mac is empty.\n"); return IPACM_FAILURE; } ipacm_cmd_q_data evt_data; memset(&evt_data, 0, sizeof(evt_data)); ipacm_event_data_mac* mac; mac = (ipacm_event_data_mac*)malloc(sizeof(ipacm_event_data_mac)); if(mac == NULL) { IPACMERR("Unable to allocate memory.\n"); return IPACM_FAILURE; } memset(mac, 0, sizeof(ipacm_event_data_mac)); memcpy(mac->mac_addr, mac_addr, 6 * sizeof(uint8_t)); evt_data.event = evt; evt_data.evt_data = (void*)mac; IPACMDBG_H("Posting event: %d\n", evt); IPACM_EvtDispatcher::PostEvt(&evt_data); return IPACM_SUCCESS; } int IPACM_Lan::eth_bridge_add_wlan_client_flt_rule(uint8_t* mac, ipa_ip_type iptype) { int i, len, res = IPACM_SUCCESS, client_position; struct ipa_flt_rule_mdfy flt_rule; struct ipa_ioc_mdfy_flt_rule* pFilteringTable = NULL; bool client_is_found = false; if (rx_prop == NULL) { IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); return IPACM_FAILURE; } if(mac == NULL) { IPACMERR("MAC address is empty.\n"); return IPACM_FAILURE; } if(IPACM_Lan::usb_to_wlan_hdr_proc_ctx.valid == false) { IPACMDBG_H("USB to WLAN hdr proc ctx has not been set, don't add client specific flt rule.\n"); return IPACM_FAILURE; } for(i=0; icommit = 1; pFilteringTable->ip = iptype; pFilteringTable->num_rules = 1; memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy)); flt_rule.status = -1; flt_rule.rule.retain_hdr = 0; flt_rule.rule.to_uc = 0; flt_rule.rule.action = IPA_PASS_TO_ROUTING; flt_rule.rule.eq_attrib_type = 0; /* point to USB-WLAN routing table */ if(iptype == IPA_IP_v4) { if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_usb_wlan_v4)) { IPACMERR("Failed to get routing table handle.\n"); res = IPACM_FAILURE; goto fail; } flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_usb_wlan_v4.hdl; IPACMDBG_H("USB->WLAN filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_usb_wlan_v4.name); } else { if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_usb_wlan_v6)) { IPACMERR("Failed to get routing table handle.\n"); res = IPACM_FAILURE; goto fail; } flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_usb_wlan_v6.hdl; IPACMDBG_H("USB->WLAN filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_usb_wlan_v6.name); } memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib)); if(IPACM_Lan::usb_hdr_type == IPA_HDR_L2_ETHERNET_II) { flt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II; } else if(IPACM_Lan::usb_hdr_type == IPA_HDR_L2_802_3) { flt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3; } else { IPACMERR("USB hdr type is not expected.\n"); res = IPACM_FAILURE; goto fail; } memcpy(flt_rule.rule.attrib.dst_mac_addr, mac, sizeof(flt_rule.rule.attrib.dst_mac_addr)); memset(flt_rule.rule.attrib.dst_mac_addr_mask, 0xFF, sizeof(flt_rule.rule.attrib.dst_mac_addr_mask)); if(iptype == IPA_IP_v4) { for(i=0; irules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) { IPACMERR("Failed to add wlan client filtering rules.\n"); res = IPACM_FAILURE; goto fail; } if(client_is_found == false) { client_position = wlan_client_flt_info_count; wlan_client_flt_info_count++; } memcpy(eth_bridge_wlan_client_flt_info[client_position].mac, mac, sizeof(eth_bridge_wlan_client_flt_info[client_position].mac)); if(iptype == IPA_IP_v4) { eth_bridge_wlan_client_flt_info[client_position].flt_rule_set_v4 = true; eth_bridge_wlan_client_flt_info[client_position].flt_rule_hdl_v4 = wlan_client_flt_rule_hdl_v4[i].rule_hdl; } else { eth_bridge_wlan_client_flt_info[client_position].flt_rule_set_v6 = true; eth_bridge_wlan_client_flt_info[client_position].flt_rule_hdl_v6 = wlan_client_flt_rule_hdl_v6[i].rule_hdl; } fail: if(pFilteringTable == NULL) { free(pFilteringTable); } return res; } int IPACM_Lan::eth_bridge_del_wlan_client_flt_rule(uint8_t* mac) { if(mac == NULL) { IPACMERR("Client MAC address is empty.\n"); return IPACM_FAILURE; } IPACMDBG_H("Receive WLAN client MAC 0x%02x%02x%02x%02x%02x%02x.\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); int i, j, res = IPACM_SUCCESS; for(i=0; iiface_table[ipa_if_num].if_cat == WLAN_IF) { if(IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.valid == false) { memset(pHeaderProcTable, 0, len); pHeaderProcTable->commit = 1; pHeaderProcTable->num_proc_ctxs = 1; pHeaderProcTable->proc_ctx[0].type = get_hdr_proc_type(IPACM_Lan::wlan_hdr_type, IPACM_Lan::wlan_hdr_type); pHeaderProcTable->proc_ctx[0].hdr_hdl = IPACM_Lan::wlan_hdr_template_hdl; if (m_header.AddHeaderProcCtx(pHeaderProcTable) == false) { IPACMERR("Adding WLAN to WLAN hdr proc ctx failed with status: %d\n", pHeaderProcTable->proc_ctx[0].status); res = IPACM_FAILURE; } else { IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.proc_ctx_hdl = pHeaderProcTable->proc_ctx[0].proc_ctx_hdl; IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.valid = true; } } } if(IPACM_Lan::usb_hdr_type != IPA_HDR_L2_NONE) { if(IPACM_Lan::usb_to_wlan_hdr_proc_ctx.valid == false) { memset(pHeaderProcTable, 0, len); pHeaderProcTable->commit = 1; pHeaderProcTable->num_proc_ctxs = 1; pHeaderProcTable->proc_ctx[0].type = get_hdr_proc_type(IPACM_Lan::usb_hdr_type, IPACM_Lan::wlan_hdr_type); pHeaderProcTable->proc_ctx[0].hdr_hdl = IPACM_Lan::wlan_hdr_template_hdl; if (m_header.AddHeaderProcCtx(pHeaderProcTable) == false) { IPACMERR("Adding USB to WLAN hdr proc ctx failed with status: %d\n", pHeaderProcTable->proc_ctx[0].status); res = IPACM_FAILURE; goto fail; } else { IPACM_Lan::usb_to_wlan_hdr_proc_ctx.proc_ctx_hdl = pHeaderProcTable->proc_ctx[0].proc_ctx_hdl; IPACM_Lan::usb_to_wlan_hdr_proc_ctx.valid = true; } ipacm_cmd_q_data evt_data; memset(&evt_data, 0, sizeof(ipacm_cmd_q_data)); ipacm_event_data_fid* fid; fid = (ipacm_event_data_fid*)malloc(sizeof(ipacm_event_data_fid)); if(fid == NULL) { IPACMERR("Unable to allocate memory.\n"); return IPACM_FAILURE; } memset(fid, 0, sizeof(ipacm_event_data_fid)); fid->if_index = ipa_if_num; evt_data.evt_data = fid; evt_data.event = IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT; IPACMDBG_H("Posting event IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT\n"); IPACM_EvtDispatcher::PostEvt(&evt_data); } if(IPACM_Lan::wlan_to_usb_hdr_proc_ctx.valid == false) { memset(pHeaderProcTable, 0, len); pHeaderProcTable->commit = 1; pHeaderProcTable->num_proc_ctxs = 1; pHeaderProcTable->proc_ctx[0].type = get_hdr_proc_type(IPACM_Lan::wlan_hdr_type, IPACM_Lan::usb_hdr_type); pHeaderProcTable->proc_ctx[0].hdr_hdl = IPACM_Lan::usb_hdr_template_hdl; if (m_header.AddHeaderProcCtx(pHeaderProcTable) == false) { IPACMERR("Adding WLAN to USB hdr proc ctx failed with status: %d\n", pHeaderProcTable->proc_ctx[0].status); m_header.DeleteHeaderProcCtx(IPACM_Lan::usb_to_wlan_hdr_proc_ctx.proc_ctx_hdl); IPACM_Lan::usb_to_wlan_hdr_proc_ctx.valid = false; res = IPACM_FAILURE; goto fail; } else { IPACM_Lan::wlan_to_usb_hdr_proc_ctx.proc_ctx_hdl = pHeaderProcTable->proc_ctx[0].proc_ctx_hdl; IPACM_Lan::wlan_to_usb_hdr_proc_ctx.valid = true; } } } } else { IPACMDBG_H("Not adding header processing context.\n"); } fail: free(pHeaderProcTable); return res; } ipa_hdr_proc_type IPACM_Lan::get_hdr_proc_type(ipa_hdr_l2_type t1, ipa_hdr_l2_type t2) { if(t1 == IPA_HDR_L2_ETHERNET_II) { if(t2 == IPA_HDR_L2_ETHERNET_II) { return IPA_HDR_PROC_ETHII_TO_ETHII; } if(t2 == IPA_HDR_L2_802_3) { return IPA_HDR_PROC_ETHII_TO_802_3; } } if(t1 == IPA_HDR_L2_802_3) { if(t2 == IPA_HDR_L2_ETHERNET_II) { return IPA_HDR_PROC_802_3_TO_ETHII; } if(t2 == IPA_HDR_L2_802_3) { return IPA_HDR_PROC_802_3_TO_802_3; } } return IPA_HDR_PROC_NONE; } int IPACM_Lan::eth_bridge_install_cache_wlan_client_flt_rule(ipa_ip_type iptype) { int i; IPACMDBG_H("There are %d wlan clients cached.\n",IPACM_Lan::num_wlan_client); for(i=0; imac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, iptype)->mac)) == 0) { IPACMDBG_H("The client's routing rule was added before.\n"); return IPACM_SUCCESS; } } memcpy(eth_bridge_get_client_rt_info_ptr(usb_client_rt_info_count_v4, iptype)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(usb_client_rt_info_count_v4, iptype)->mac)); } else { for(i=0; imac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, iptype)->mac)) == 0) { IPACMDBG_H("The client's routing rule was added before.\n"); return IPACM_SUCCESS; } } memcpy(eth_bridge_get_client_rt_info_ptr(usb_client_rt_info_count_v6, iptype)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(usb_client_rt_info_count_v6, iptype)->mac)); } if(iptype == IPA_IP_v4) { num_rt_rule = each_client_rt_rule_count_v4; } else { num_rt_rule = each_client_rt_rule_count_v6; } len = sizeof(ipa_ioc_add_rt_rule) + num_rt_rule * sizeof(ipa_rt_rule_add); rt_rule_table = (ipa_ioc_add_rt_rule*)malloc(len); if(rt_rule_table == NULL) { IPACMERR("Failed to allocate memory.\n"); return IPACM_FAILURE; } memset(rt_rule_table, 0, len); rt_rule_table->commit = 1; rt_rule_table->ip = iptype; rt_rule_table->num_rules = num_rt_rule; if(iptype == IPA_IP_v4) { strncpy(rt_rule_table->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_usb_wlan_v4.name, sizeof(rt_rule_table->rt_tbl_name)); } else { strncpy(rt_rule_table->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_usb_wlan_v6.name, sizeof(rt_rule_table->rt_tbl_name)); } memset(&rt_rule, 0, sizeof(ipa_rt_rule_add)); rt_rule.at_rear = false; rt_rule.status = -1; rt_rule.rt_rule_hdl = -1; rt_rule.rule.hdr_hdl = 0; rt_rule.rule.hdr_proc_ctx_hdl = IPACM_Lan::wlan_to_usb_hdr_proc_ctx.proc_ctx_hdl; position = 0; for(i=0; inum_tx_props; i++) { if(tx_prop->tx[i].ip == iptype) { if(position >= num_rt_rule) { IPACMERR("Number of routing rules already exceeds limit for iptype %d.\n", iptype); res = IPACM_FAILURE; goto fail; } rt_rule.rule.dst = tx_prop->tx[i].dst_pipe; memcpy(&rt_rule.rule.attrib, &tx_prop->tx[i].attrib, sizeof(rt_rule.rule.attrib)); if(IPACM_Lan::wlan_hdr_type == IPA_HDR_L2_ETHERNET_II) { rt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II; } else if(IPACM_Lan::wlan_hdr_type == IPA_HDR_L2_802_3) { rt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3; } else { IPACMERR("WLAN header type is not expected.\n"); res = IPACM_FAILURE; goto fail; } memcpy(rt_rule.rule.attrib.dst_mac_addr, mac, sizeof(rt_rule.rule.attrib.dst_mac_addr)); memset(rt_rule.rule.attrib.dst_mac_addr_mask, 0xFF, sizeof(rt_rule.rule.attrib.dst_mac_addr_mask)); memcpy(&(rt_rule_table->rules[position]), &rt_rule, sizeof(rt_rule_table->rules[position])); position++; } } if(false == m_routing.AddRoutingRule(rt_rule_table)) { IPACMERR("Routing rule addition failed!\n"); res = IPACM_FAILURE; goto fail; } else { for(i=0; irt_rule_hdl[i] = rt_rule_table->rules[i].rt_rule_hdl; } else { eth_bridge_get_client_rt_info_ptr(usb_client_rt_info_count_v6, iptype)->rt_rule_hdl[i] = rt_rule_table->rules[i].rt_rule_hdl; } } } if(iptype == IPA_IP_v4) { usb_client_rt_info_count_v4++; IPACMDBG_H("Now the number of IPv4 rt rule info is %d.\n", usb_client_rt_info_count_v4); } else { usb_client_rt_info_count_v6++; IPACMDBG_H("Now the number of IPv6 rt rule info is %d.\n", usb_client_rt_info_count_v6); } fail: if(rt_rule_table != NULL) { free(rt_rule_table); } return res; } int IPACM_Lan::eth_bridge_del_usb_client_rt_rule(uint8_t* mac) { if(tx_prop == NULL) { IPACMDBG_H("Tx prop is empty, not deleting routing rule.\n"); return IPACM_SUCCESS; } if(mac == NULL) { IPACMERR("Client MAC address is empty.\n"); return IPACM_FAILURE; } IPACMDBG_H("Receive USB client MAC 0x%02x%02x%02x%02x%02x%02x.\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); int i, position; /* delete rule from IPv4 rt table first */ for(i=0; imac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, IPA_IP_v4)->mac)) == 0) { position = i; IPACMDBG_H("The client is found at position %d.\n", position); break; } } if(i == usb_client_rt_info_count_v4) { IPACMERR("The client is not found.\n"); return IPACM_FAILURE; } for(i=0; irt_rule_hdl[i], IPA_IP_v4) == false) { IPACMERR("Failed to delete routing rule %d.\n", i); return IPACM_FAILURE; } } for(i=position+1; imac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, IPA_IP_v6)->mac)) == 0) { position = i; IPACMDBG_H("The client is found at position %d.\n", position); break; } } if(i == usb_client_rt_info_count_v6) { IPACMERR("The client is not found.\n"); return IPACM_FAILURE; } for(i=0; irt_rule_hdl[i], IPA_IP_v6) == false) { IPACMERR("Failed to delete routing rule %d.\n", i); return IPACM_FAILURE; } } for(i=position+1; itx[0].hdr_name, sizeof(hdr.name)); if(m_header.GetHeaderHandle(&hdr) == false) { IPACMERR("Failed to get template hdr hdl.\n"); return IPACM_FAILURE; } *hdr_hdl = hdr.hdl; return IPACM_SUCCESS; } int IPACM_Lan::del_hdr_proc_ctx() { if(IPACM_Lan::usb_to_wlan_hdr_proc_ctx.valid == true) { if(m_header.DeleteHeaderProcCtx(IPACM_Lan::usb_to_wlan_hdr_proc_ctx.proc_ctx_hdl) == false) { IPACMERR("Failed to delete usb to wlan hdr proc ctx.\n"); return IPACM_FAILURE; } IPACM_Lan::usb_to_wlan_hdr_proc_ctx.valid = false; ipacm_cmd_q_data evt_data; memset(&evt_data, 0, sizeof(ipacm_cmd_q_data)); ipacm_event_data_fid* fid; fid = (ipacm_event_data_fid*)malloc(sizeof(ipacm_event_data_fid)); if(fid == NULL) { IPACMERR("Unable to allocate memory.\n"); return IPACM_FAILURE; } memset(fid, 0, sizeof(ipacm_event_data_fid)); fid->if_index = ipa_if_num; evt_data.evt_data = fid; evt_data.event = IPA_ETH_BRIDGE_HDR_PROC_CTX_UNSET_EVENT; IPACMDBG_H("Posting event IPA_ETH_BRIDGE_HDR_PROC_CTX_UNSET_EVENT\n"); IPACM_EvtDispatcher::PostEvt(&evt_data); } if(IPACM_Lan::wlan_to_usb_hdr_proc_ctx.valid == true) { if(m_header.DeleteHeaderProcCtx(IPACM_Lan::wlan_to_usb_hdr_proc_ctx.proc_ctx_hdl) == false) { IPACMERR("Failed to delete wlan to usb hdr proc ctx.\n"); return IPACM_FAILURE; } IPACM_Lan::wlan_to_usb_hdr_proc_ctx.valid = false; } if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == WLAN_IF) { if(IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.valid == true) { if(m_header.DeleteHeaderProcCtx(IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.proc_ctx_hdl) == false) { IPACMERR("Failed to delete wlan to wlan hdr proc ctx.\n"); return IPACM_FAILURE; } IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.valid = false; } } return IPACM_SUCCESS; } /*handle reset usb-client rt-rules */ int IPACM_Lan::handle_tethering_stats_event(ipa_get_data_stats_resp_msg_v01 *data) { int cnt, pipe_len, fd; uint64_t num_ul_packets, num_ul_bytes; uint64_t num_dl_packets, num_dl_bytes; bool ul_pipe_found, dl_pipe_found; FILE *fp = NULL; fd = open(IPA_DEVICE_NAME, O_RDWR); if (fd < 0) { IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME); return IPACM_FAILURE; } ul_pipe_found = false; dl_pipe_found = false; num_ul_packets = 0; num_dl_packets = 0; num_ul_bytes = 0; num_dl_bytes = 0; if (data->dl_dst_pipe_stats_list_valid) { if(tx_prop != NULL) { for (pipe_len = 0; pipe_len < data->dl_dst_pipe_stats_list_len; pipe_len++) { IPACMDBG_H("Check entry(%d) dl_dst_pipe(%d)\n", pipe_len, data->dl_dst_pipe_stats_list[pipe_len].pipe_index); for (cnt=0; cntnum_tx_props; cnt++) { IPACMDBG_H("Check Tx_prop_entry(%d) pipe(%d)\n", cnt, ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, tx_prop->tx[cnt].dst_pipe)); if(ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, tx_prop->tx[cnt].dst_pipe) == data->dl_dst_pipe_stats_list[pipe_len].pipe_index) { /* update the DL stats */ dl_pipe_found = true; num_dl_packets += data->dl_dst_pipe_stats_list[pipe_len].num_ipv4_packets; num_dl_packets += data->dl_dst_pipe_stats_list[pipe_len].num_ipv6_packets; num_dl_bytes += data->dl_dst_pipe_stats_list[pipe_len].num_ipv4_bytes; num_dl_bytes += data->dl_dst_pipe_stats_list[pipe_len].num_ipv6_bytes; IPACMDBG_H("Got matched dst-pipe (%d) from %d tx props\n", data->dl_dst_pipe_stats_list[pipe_len].pipe_index, cnt); IPACMDBG_H("DL_packets:(%lu) DL_bytes:(%lu) \n", num_dl_packets, num_dl_bytes); break; } } } } } if (data->ul_src_pipe_stats_list_valid) { if(rx_prop != NULL) { for (pipe_len = 0; pipe_len < data->ul_src_pipe_stats_list_len; pipe_len++) { IPACMDBG_H("Check entry(%d) dl_dst_pipe(%d)\n", pipe_len, data->ul_src_pipe_stats_list[pipe_len].pipe_index); for (cnt=0; cnt < rx_prop->num_rx_props; cnt++) { IPACMDBG_H("Check Rx_prop_entry(%d) pipe(%d)\n", cnt, ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[cnt].src_pipe)); if(ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[cnt].src_pipe) == data->ul_src_pipe_stats_list[pipe_len].pipe_index) { /* update the UL stats */ ul_pipe_found = true; num_ul_packets += data->ul_src_pipe_stats_list[pipe_len].num_ipv4_packets; num_ul_packets += data->ul_src_pipe_stats_list[pipe_len].num_ipv6_packets; num_ul_bytes += data->ul_src_pipe_stats_list[pipe_len].num_ipv4_bytes; num_ul_bytes += data->ul_src_pipe_stats_list[pipe_len].num_ipv6_bytes; IPACMDBG_H("Got matched dst-pipe (%d) from %d tx props\n", data->ul_src_pipe_stats_list[pipe_len].pipe_index, cnt); IPACMDBG_H("UL_packets:(%lu) UL_bytes:(%lu) \n", num_ul_packets, num_ul_bytes); break; } } } } } close(fd); if (ul_pipe_found || dl_pipe_found) { IPACMDBG_H("Update IPA_TETHERING_STATS_UPDATE_EVENT, TX(P%lu/B%lu) RX(P%lu/B%lu) DEV(%s) to LTE(%s) \n", num_ul_packets, num_ul_bytes, num_dl_packets, num_dl_bytes, dev_name, IPACM_Wan::wan_up_dev_name); fp = fopen(IPA_PIPE_STATS_FILE_NAME, "w"); if ( fp == NULL ) { IPACMERR("Failed to write pipe stats to %s, error is %d - %s\n", IPA_PIPE_STATS_FILE_NAME, errno, strerror(errno)); return IPACM_FAILURE; } fprintf(fp, PIPE_STATS, dev_name, IPACM_Wan::wan_up_dev_name, num_ul_bytes, num_ul_packets, num_dl_bytes, num_dl_packets); fclose(fp); } return IPACM_SUCCESS; } /*handle tether client */ int IPACM_Lan::handle_tethering_client(bool reset, ipacm_client_enum ipa_client) { int cnt, fd, ret = IPACM_SUCCESS; int fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR); wan_ioctl_set_tether_client_pipe tether_client; if(fd_wwan_ioctl < 0) { IPACMERR("Failed to open %s.\n",WWAN_QMI_IOCTL_DEVICE_NAME); return IPACM_FAILURE; } fd = open(IPA_DEVICE_NAME, O_RDWR); if (fd < 0) { IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME); close(fd_wwan_ioctl); return IPACM_FAILURE; } memset(&tether_client, 0, sizeof(tether_client)); tether_client.reset_client = reset; tether_client.ipa_client = ipa_client; if(tx_prop != NULL) { tether_client.dl_dst_pipe_len = tx_prop->num_tx_props; for (cnt = 0; cnt < tx_prop->num_tx_props; cnt++) { IPACMDBG_H("Tx(%d), dst_pipe: %d, ipa_pipe: %d\n", cnt, tx_prop->tx[cnt].dst_pipe, ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, tx_prop->tx[cnt].dst_pipe)); tether_client.dl_dst_pipe_list[cnt] = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, tx_prop->tx[cnt].dst_pipe); } } if(rx_prop != NULL) { tether_client.ul_src_pipe_len = rx_prop->num_rx_props; for (cnt = 0; cnt < rx_prop->num_rx_props; cnt++) { IPACMDBG_H("Rx(%d), src_pipe: %d, ipa_pipe: %d\n", cnt, rx_prop->rx[cnt].src_pipe, ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[cnt].src_pipe)); tether_client.ul_src_pipe_list[cnt] = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[cnt].src_pipe); } } ret = ioctl(fd_wwan_ioctl, WAN_IOC_SET_TETHER_CLIENT_PIPE, &tether_client); if (ret != 0) { IPACMERR("Failed set tether-client-pipe %p with ret %d\n ", &tether_client, ret); } IPACMDBG("Set tether-client-pipe %p\n", &tether_client); close(fd); close(fd_wwan_ioctl); return ret; } ================================================ FILE: data-ipa-cfg-mgr/ipacm/src/IPACM_LanToLan.cpp ================================================ /* Copyright (c) 2014, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPACM_LanToLan.cpp @brief This file implements the functionality of offloading LAN to LAN traffic. @Author Shihuan Liu */ #include #include #include "IPACM_LanToLan.h" #include "IPACM_Wlan.h" #define ipv6_multicast_addr 0xff000000 #define ipv6_multicast_mask 0xff000000 #define max_cache_connection 20 IPACM_LanToLan* IPACM_LanToLan::p_instance = NULL; IPACM_LanToLan::IPACM_LanToLan() { num_offload_pair_v4_ = 0; num_offload_pair_v6_ = 0; client_info_v4_.reserve(IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_USB_CLIENT); client_info_v6_.reserve(3*(IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_USB_CLIENT)); p_instance = this; IPACM_EvtDispatcher::registr(IPA_LAN_CLIENT_ACTIVE, this); IPACM_EvtDispatcher::registr(IPA_LAN_CLIENT_INACTIVE, this); IPACM_EvtDispatcher::registr(IPA_LAN_CLIENT_DISCONNECT, this); IPACM_EvtDispatcher::registr(IPA_LAN_CLIENT_POWER_SAVE, this); IPACM_EvtDispatcher::registr(IPA_LAN_CLIENT_POWER_RECOVER, this); IPACM_EvtDispatcher::registr(IPA_LAN_TO_LAN_NEW_CONNECTION, this); IPACM_EvtDispatcher::registr(IPA_LAN_TO_LAN_DEL_CONNECTION, this); return; } IPACM_LanToLan::~IPACM_LanToLan() { client_table_v4::iterator it_v4; for(it_v4 = client_info_v4_.begin(); it_v4 != client_info_v4_.end(); it_v4++) { turnoff_offload_links(IPA_IP_v4, &(it_v4->second)); clear_peer_list(&(it_v4->second)); } client_info_v4_.clear(); IPACMDBG("Clear IPv4 hash table in Lan2Lan distructor.\n"); client_table_v6::iterator it_v6; for(it_v6 = client_info_v6_.begin(); it_v6 != client_info_v6_.end(); it_v6++) { turnoff_offload_links(IPA_IP_v6, &(it_v6->second)); clear_peer_list(&(it_v6->second)); } client_info_v6_.clear(); IPACMDBG("Clear IPv6 hash table in Lan2Lan distructor.\n"); return; } void IPACM_LanToLan::event_callback(ipa_cm_event_id event, void* param) { switch(event) { case IPA_LAN_CLIENT_ACTIVE: { IPACMDBG_H("Get IPA_LAN_CLIENT_ACTIVE event.\n"); ipacm_event_lan_client* data = (ipacm_event_lan_client*)param; handle_client_active(data); break; } case IPA_LAN_CLIENT_INACTIVE: { IPACMDBG_H("Get IPA_LAN_CLIENT_INACTIVE event.\n"); ipacm_event_lan_client* data = (ipacm_event_lan_client*)param; handle_client_inactive(data); break; } case IPA_LAN_CLIENT_DISCONNECT: { IPACMDBG_H("Get IPA_LAN_CLIENT_DISCONNECT event.\n"); ipacm_event_lan_client* data = (ipacm_event_lan_client*)param; handle_client_disconnect(data); break; } case IPA_LAN_TO_LAN_NEW_CONNECTION: { IPACMDBG_H("Get IPA_LAN_TO_LAN_NEW_CONNECTION event.\n"); ipacm_event_connection* data = (ipacm_event_connection*)param; handle_new_lan2lan_connection(data); break; } case IPA_LAN_TO_LAN_DEL_CONNECTION: { IPACMDBG_H("Get IPA_LAN_TO_LAN_DEL_CONNECTION event.\n"); ipacm_event_connection* data = (ipacm_event_connection*)param; handle_del_lan2lan_connection(data); break; } case IPA_LAN_CLIENT_POWER_SAVE: { IPACMDBG_H("Get IPA_LAN_CLIENT_POWER_SAVE event.\n"); ipacm_event_lan_client* data = (ipacm_event_lan_client*)param; handle_client_power_save(data); break; } case IPA_LAN_CLIENT_POWER_RECOVER: { IPACMDBG_H("Get IPA_LAN_CLIENT_POWER_RECOVER event.\n"); ipacm_event_lan_client* data = (ipacm_event_lan_client*)param; handle_client_power_recover(data); break; } default: break; } return; } void IPACM_LanToLan::handle_client_active(ipacm_event_lan_client* data) { if(data == NULL) { IPACMERR("No client info is found.\n"); return; } if(data->mac_addr == NULL || data->ipv6_addr == NULL || data->p_iface == NULL) { IPACMERR("Event data is not populated properly.\n"); return; } if(data->iptype != IPA_IP_v4 && data->iptype != IPA_IP_v6) { IPACMERR("IP type is not expected.\n"); return; } IPACMDBG_H("New client info: iface %s, iptype: %d, mac: 0x%02x%02x%02x%02x%02x%02x, v4_addr: 0x%08x, v6_addr: 0x%08x%08x%08x%08x \n", data->p_iface->dev_name, data->iptype, data->mac_addr[0], data->mac_addr[1], data->mac_addr[2], data->mac_addr[3], data->mac_addr[4], data->mac_addr[5], data->ipv4_addr, data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]); bool client_not_found; client_info* client_ptr; if(data->iptype == IPA_IP_v4) { client_not_found = (client_info_v4_.count(data->ipv4_addr) == 0); IPACMDBG_H("Is the client not found? %d\n", client_not_found); client_info& client = client_info_v4_[data->ipv4_addr]; client_ptr = &client; } else { uint64_t v6_addr; memcpy(&v6_addr, &(data->ipv6_addr[2]), sizeof(uint64_t)); client_not_found = (client_info_v6_.count(v6_addr) == 0); IPACMDBG_H("Is the client not found? %d\n", client_not_found); client_info& client = client_info_v6_[v6_addr]; client_ptr = &client; } if(client_not_found == true) { if(data->iptype == IPA_IP_v4) { client_ptr->ip.ipv4_addr = data->ipv4_addr; } else { memcpy(client_ptr->ip.ipv6_addr, data->ipv6_addr, sizeof(client_ptr->ip.ipv6_addr)); } memcpy(client_ptr->mac_addr, data->mac_addr, sizeof(client_ptr->mac_addr)); client_ptr->is_active = true; client_ptr->is_powersave = false; client_ptr->p_iface = data->p_iface; generate_new_connection(data->iptype, client_ptr); check_cache_connection(data->iptype, client_ptr); } else //the client is found { if(client_ptr->is_active == true) //the client is active { IPACMDBG_H("The client is active.\n"); if(memcmp(client_ptr->mac_addr, data->mac_addr, sizeof(client_ptr->mac_addr)) == 0) { IPACMDBG_H("Mac addr is the same, do nothing.\n"); } else { IPACMERR("The new client has same IP but differenc mac.\n"); turnoff_offload_links(data->iptype, client_ptr); clear_peer_list(client_ptr); if(data->iptype == IPA_IP_v4) { client_ptr->ip.ipv4_addr = data->ipv4_addr; } else { memcpy(client_ptr->ip.ipv6_addr, data->ipv6_addr, sizeof(client_ptr->ip.ipv6_addr)); } memcpy(client_ptr->mac_addr, data->mac_addr, sizeof(client_ptr->mac_addr)); client_ptr->is_active = true; client_ptr->is_powersave = false; client_ptr->p_iface = data->p_iface; generate_new_connection(data->iptype, client_ptr); check_cache_connection(data->iptype, client_ptr); } } else //the client is inactive { IPACMDBG_H("The client is inactive.\n"); if(data->iptype == IPA_IP_v4) { client_ptr->ip.ipv4_addr = data->ipv4_addr; } else { memcpy(client_ptr->ip.ipv6_addr, data->ipv6_addr, sizeof(client_ptr->ip.ipv6_addr)); } memcpy(client_ptr->mac_addr, data->mac_addr, sizeof(client_ptr->mac_addr)); client_ptr->is_active = true; client_ptr->is_powersave = false; client_ptr->p_iface = data->p_iface; check_potential_link(data->iptype, client_ptr); generate_new_connection(data->iptype, client_ptr); check_cache_connection(data->iptype, client_ptr); } } IPACMDBG_H("There are %d clients in v4 table and %d clients in v6 table.\n", client_info_v4_.size(), client_info_v6_.size()); return; } void IPACM_LanToLan::check_potential_link(ipa_ip_type iptype, client_info* client) { if(client == NULL) { IPACMERR("Client is NULL.\n"); return; } IPACMDBG_H("Check client's peer list.\n"); IPACMDBG_H("Client: IP type: %d, IPv4 addr: 0x%08x, IPv6 addr: 0x%08x%08x%08x%08x\n", iptype, client->ip.ipv4_addr, client->ip.ipv6_addr[0], client->ip.ipv6_addr[1], client->ip.ipv6_addr[2], client->ip.ipv6_addr[3]); peer_info_list::iterator peer_it; int res, num = 0; for(peer_it = client->peer.begin(); peer_it != client->peer.end(); peer_it++) { if(peer_it->peer_pointer->is_active == true && peer_it->num_connection > 0) { res = IPACM_SUCCESS; res = add_offload_link(iptype, client, peer_it->peer_pointer); res = add_offload_link(iptype, peer_it->peer_pointer, client); if(res == IPACM_SUCCESS) { if(iptype == IPA_IP_v4) { num_offload_pair_v4_ ++; IPACMDBG_H("Now the number of v4 offload links is %d.\n", num_offload_pair_v4_); } else { num_offload_pair_v6_ ++; IPACMDBG_H("Now the number of v6 offload links is %d.\n", num_offload_pair_v6_); } num++; } } } IPACMDBG_H("Added %d offload links in total.\n", num); return; } int IPACM_LanToLan::add_offload_link(ipa_ip_type iptype, client_info* client, client_info* peer) { if( (iptype == IPA_IP_v4 && num_offload_pair_v4_ >= MAX_OFFLOAD_PAIR) || (iptype == IPA_IP_v6 && num_offload_pair_v6_ >= MAX_OFFLOAD_PAIR) ) { IPACMDBG_H("The number of offload pairs already reaches maximum.\n"); return IPACM_FAILURE; } if(client == NULL || peer == NULL) { IPACMERR("Either client or peer is NULL.\n"); return IPACM_FAILURE; } uint32_t hdr_hdl, flt_hdl; lan_to_lan_rt_rule_hdl rt_rule_hdl; offload_link_info link_info; if(iptype == IPA_IP_v4) { IPACMDBG_H("Add offload link for IPv4, client IP: 0x%08x, peer IP: 0x%08x \n", client->ip.ipv4_addr, peer->ip.ipv4_addr); } else if(iptype == IPA_IP_v6) { IPACMDBG_H("Add offload link for IPv6, client IP: 0x%08x%08x%08x%08x, peer IP: 0x%08x%08x%08x%08x \n", client->ip.ipv6_addr[0], client->ip.ipv6_addr[1], client->ip.ipv6_addr[2], client->ip.ipv6_addr[3], peer->ip.ipv6_addr[0], peer->ip.ipv6_addr[1], peer->ip.ipv6_addr[2], peer->ip.ipv6_addr[3]); } else { IPACMERR("IP type is not expected.\n"); return IPACM_FAILURE; } //add lan2lan header if(peer->p_iface->add_lan2lan_hdr(iptype, client->mac_addr, peer->mac_addr, &hdr_hdl) == IPACM_FAILURE) { IPACMERR("Failed to create lan2lan header.\n"); return IPACM_FAILURE; } IPACMDBG_H("Created lan2lan hdr with hdl %d.\n", hdr_hdl); //add lan2lan routing/filtering rules if(peer->p_iface->add_lan2lan_rt_rule(iptype, client->ip.ipv4_addr, peer->ip.ipv4_addr, client->ip.ipv6_addr, peer->ip.ipv6_addr, hdr_hdl, &rt_rule_hdl) == IPACM_FAILURE) { IPACMERR("Failed to create lan2lan rt rule.\n"); goto rt_fail; } IPACMDBG_H("Created %d lan2lan rt rules.\n", rt_rule_hdl.num_rule); IPACMDBG_H("Created lan2lan rt rules with hdl: %d.\n", rt_rule_hdl.rule_hdl[0]); if(client->p_iface->add_lan2lan_flt_rule(iptype, client->ip.ipv4_addr, peer->ip.ipv4_addr, client->ip.ipv6_addr, peer->ip.ipv6_addr, &flt_hdl) == IPACM_FAILURE) { IPACMERR("Failed to create lan2lan flt rule.\n"); goto flt_fail; } IPACMDBG_H("Created lan2lan flt rule with hdl %d.\n", flt_hdl); link_info.peer_pointer = peer; link_info.flt_rule_hdl = flt_hdl; link_info.hdr_hdl = hdr_hdl; memcpy(&link_info.rt_rule_hdl, &rt_rule_hdl, sizeof(lan_to_lan_rt_rule_hdl)); client->link.push_back(link_info); return IPACM_SUCCESS; flt_fail: peer->p_iface->del_lan2lan_rt_rule(iptype, rt_rule_hdl); rt_fail: peer->p_iface->del_lan2lan_hdr(iptype, hdr_hdl); return IPACM_FAILURE; } void IPACM_LanToLan::handle_client_inactive(ipacm_event_lan_client* data) { if(data == NULL) { IPACMERR("No client info is found.\n"); return; } if(data->mac_addr == NULL || data->ipv6_addr == NULL || data->p_iface == NULL) { IPACMERR("Event data is not populated properly.\n"); return; } if(data->iptype != IPA_IP_v4 && data->iptype != IPA_IP_v6) { IPACMERR("IP type is not expected: %d.\n", data->iptype); return; } IPACMDBG_H("Del client info: iface %s, iptype: %d, mac: 0x%02x%02x%02x%02x%02x%02x, v4_addr: 0x%08x, v6_addr: 0x%08x%08x%08x%08x \n", data->p_iface->dev_name, data->iptype, data->mac_addr[0], data->mac_addr[1], data->mac_addr[2], data->mac_addr[3], data->mac_addr[4], data->mac_addr[5], data->ipv4_addr, data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]); client_info* client_ptr; uint64_t v6_addr; if(data->iptype == IPA_IP_v4) { if(client_info_v4_.count(data->ipv4_addr) == 0)//if not found the client, return { IPACMERR("The client is not found the client, return.\n"); return; } IPACMDBG_H("The client is found.\n"); client_info& client = client_info_v4_[data->ipv4_addr]; client_ptr = &client; } else { memcpy(&v6_addr, &(data->ipv6_addr[2]), sizeof(uint64_t)); if(client_info_v6_.count(v6_addr) == 0) //if not found the client, insert it in table { IPACMERR("The client is not found the client, return.\n"); return; } IPACMDBG_H("The client is found.\n"); client_info& client = client_info_v6_[v6_addr]; client_ptr = &client; } turnoff_offload_links(data->iptype, client_ptr); client_ptr->is_active = false; if(client_ptr->peer.size() == 0) { IPACMDBG_H("Peer list is empty, remove client entry.\n"); if(data->iptype == IPA_IP_v4) { client_info_v4_.erase(data->ipv4_addr); } else { client_info_v6_.erase(v6_addr); } } return; } int IPACM_LanToLan::turnoff_offload_links(ipa_ip_type iptype, client_info* client) { if(client == NULL) { IPACMERR("Client is NULL.\n"); return IPACM_FAILURE; } bool err_flag; offload_link_info_list::iterator client_it; offload_link_info_list::iterator peer_it; client_info* peer; for(client_it = client->link.begin(); client_it != client->link.end(); client_it++) { peer = client_it->peer_pointer; if(del_offload_link(iptype, client->p_iface, peer->p_iface, &(*client_it)) == IPACM_FAILURE) { IPACMERR("Failed to delete client's offload link.\n"); return IPACM_FAILURE; } err_flag = true; for(peer_it = peer->link.begin(); peer_it != peer->link.end(); peer_it++) { if(peer_it->peer_pointer == client) { if(del_offload_link(iptype, peer->p_iface, client->p_iface, &(*peer_it)) == IPACM_FAILURE) { IPACMERR("Failed to delete peer's offload link.\n"); return IPACM_FAILURE; } peer->link.erase(peer_it); err_flag = false; break; } } if(err_flag) { IPACMERR("Unable to find corresponding offload link in peer's entry.\n"); return IPACM_FAILURE; } if(iptype == IPA_IP_v4) { num_offload_pair_v4_ --; IPACMDBG_H("Now the number of v4 offload pair is %d\n", num_offload_pair_v4_); } else { num_offload_pair_v6_ --; IPACMDBG_H("Now the number of v6 offload pair is %d\n", num_offload_pair_v6_); } } client->link.clear(); return IPACM_SUCCESS; } int IPACM_LanToLan::del_offload_link(ipa_ip_type iptype, IPACM_Lan* client, IPACM_Lan* peer, offload_link_info* link) { if(client == NULL || peer == NULL || link == NULL) { IPACMERR("Either iface or link is NULL.\n"); return IPACM_FAILURE; } IPACMDBG_H("Delete an offload link for IP type: %d\n", iptype); int res = IPACM_SUCCESS; if(client->del_lan2lan_flt_rule(iptype, link->flt_rule_hdl) == IPACM_FAILURE) { IPACMERR("Failed to delete flt rule.\n"); res = IPACM_FAILURE; } if(peer->del_lan2lan_rt_rule(iptype, link->rt_rule_hdl) == IPACM_FAILURE) { IPACMERR("Failed to delete rt rules.\n"); res = IPACM_FAILURE; } if(peer->del_lan2lan_hdr(iptype, link->hdr_hdl) == IPACM_FAILURE) { IPACMERR("Failed to delete header.\n"); res = IPACM_FAILURE; } return res; } void IPACM_LanToLan::handle_client_disconnect(ipacm_event_lan_client* data) { if(data == NULL) { IPACMERR("No client info is found.\n"); return; } if(data->mac_addr == NULL || data->ipv6_addr == NULL || data->p_iface == NULL) { IPACMERR("Event data is not populated properly.\n"); return; } if(data->iptype != IPA_IP_v4 && data->iptype != IPA_IP_v6) { IPACMERR("IP type is not expected: %d.\n", data->iptype); return; } IPACMDBG_H("Del client info: iface %s, iptype: %d, mac: 0x%02x%02x%02x%02x%02x%02x, v4_addr: 0x%08x, v6_addr: 0x%08x%08x%08x%08x \n", data->p_iface->dev_name, data->iptype, data->mac_addr[0], data->mac_addr[1], data->mac_addr[2], data->mac_addr[3], data->mac_addr[4], data->mac_addr[5], data->ipv4_addr, data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]); client_info* client_ptr; uint64_t v6_addr; if(data->iptype == IPA_IP_v4) { if(client_info_v4_.count(data->ipv4_addr) == 0) //if not found the client, return { IPACMERR("The client is not found the client, return.\n"); return; } IPACMDBG_H("The client is found.\n"); client_info& client = client_info_v4_[data->ipv4_addr]; client_ptr = &client; } else { memcpy(&v6_addr, &(data->ipv6_addr[2]), sizeof(uint64_t)); if(client_info_v6_.count(v6_addr) == 0) //if not found the client, insert it in table { IPACMERR("The client is not found the client, return.\n"); return; } IPACMDBG_H("The client is found.\n"); client_info& client = client_info_v6_[v6_addr]; client_ptr = &client; } turnoff_offload_links(data->iptype, client_ptr); clear_peer_list(client_ptr); if(data->iptype == IPA_IP_v4) { client_info_v4_.erase(data->ipv4_addr); } else { client_info_v6_.erase(v6_addr); } return; } int IPACM_LanToLan::clear_peer_list(client_info* client) { if(client == NULL) { IPACMERR("Client is NULL.\n"); return IPACM_FAILURE; } bool err_flag; peer_info_list::iterator client_it; peer_info_list::iterator peer_it; client_info* peer; for(client_it = client->peer.begin(); client_it != client->peer.end(); client_it++) { err_flag = true; peer = client_it->peer_pointer; for(peer_it = peer->peer.begin(); peer_it != peer->peer.end(); peer_it++) { if(peer_it->peer_pointer == client) { peer->peer.erase(peer_it); err_flag = false; break; } } if(err_flag == true) { IPACMERR("Failed to find peer info.\n"); return IPACM_FAILURE; } } client->peer.clear(); return IPACM_SUCCESS; } void IPACM_LanToLan::handle_client_power_save(ipacm_event_lan_client* data) { if(data == NULL) { IPACMERR("No client info is found.\n"); return; } if(data->mac_addr == NULL || data->ipv6_addr == NULL || data->p_iface == NULL) { IPACMERR("Event data is not populated properly.\n"); return; } if(data->iptype != IPA_IP_v4 && data->iptype != IPA_IP_v6) { IPACMERR("IP type is not expected: %d.\n", data->iptype); return; } IPACMDBG_H("Client power save info: iface %s, iptype: %d, mac: 0x%02x%02x%02x%02x%02x%02x, v4_addr: 0x%08x, v6_addr: 0x%08x%08x%08x%08x \n", data->p_iface->dev_name, data->iptype, data->mac_addr[0], data->mac_addr[1], data->mac_addr[2], data->mac_addr[3], data->mac_addr[4], data->mac_addr[5], data->ipv4_addr, data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]); client_info* client_ptr; uint64_t v6_addr; if(data->iptype == IPA_IP_v4) { if(client_info_v4_.count(data->ipv4_addr) == 0)//if not found the client, return { IPACMERR("The client is not found the client, return.\n"); return; } IPACMDBG_H("The client is found.\n"); client_info& client = client_info_v4_[data->ipv4_addr]; client_ptr = &client; } else { memcpy(&v6_addr, &(data->ipv6_addr[2]), sizeof(uint64_t)); if(client_info_v6_.count(v6_addr) == 0) //if not found the client, insert it in table { IPACMERR("The client is not found the client, return.\n"); return; } IPACMDBG_H("The client is found.\n"); client_info& client = client_info_v6_[v6_addr]; client_ptr = &client; } if(remove_flt_rules(data->iptype, client_ptr) == IPACM_FAILURE) { IPACMERR("Failed to remove flt rules when power save.\n"); return; } client_ptr->is_active = false; client_ptr->is_powersave = true; return; } void IPACM_LanToLan::handle_new_lan2lan_connection(ipacm_event_connection* data) { IPACMDBG_H("New lan2lan connection info: IP type: %d, src_v4_addr: 0x%08x, dst_v4_addr: 0x%08x\n", data->iptype, data->src_ipv4_addr, data->dst_ipv4_addr); IPACMDBG_H("src_v6_addr: 0x%08x%08x%08x%08x, dst_v6_addr: 0x%08x%08x%08x%08x", data->src_ipv6_addr[0], data->src_ipv6_addr[1], data->src_ipv6_addr[2], data->src_ipv6_addr[3], data->dst_ipv6_addr[0], data->dst_ipv6_addr[1], data->dst_ipv6_addr[2], data->dst_ipv6_addr[3]); client_info* src_client_ptr; client_info* dst_client_ptr; if(data->iptype == IPA_IP_v4) { if(client_info_v4_.count(data->src_ipv4_addr) == 0 || client_info_v4_.count(data->dst_ipv4_addr) == 0) { IPACMERR("Either source or destination is not in table.\n"); return; } client_info& src_client = client_info_v4_[data->src_ipv4_addr]; src_client_ptr = &src_client; client_info& dst_client = client_info_v4_[data->dst_ipv4_addr]; dst_client_ptr = &dst_client; } else //ipv6 case { uint64_t src_ipv6_addr; uint64_t dst_ipv6_addr; memcpy(&src_ipv6_addr, &(data->src_ipv6_addr[2]), sizeof(uint64_t)); memcpy(&dst_ipv6_addr, &(data->dst_ipv6_addr[2]), sizeof(uint64_t)); if(client_info_v6_.count(src_ipv6_addr) == 0 || client_info_v6_.count(dst_ipv6_addr) == 0) { IPACMERR("Either source or destination is not in table.\n"); return; } client_info& src_client = client_info_v6_[src_ipv6_addr]; src_client_ptr = &src_client; client_info& dst_client = client_info_v6_[dst_ipv6_addr]; dst_client_ptr = &dst_client; } IPACMDBG_H("Both src and dst are already in table.\n"); bool is_first_connection; is_first_connection = add_connection(src_client_ptr, dst_client_ptr); if(is_first_connection && src_client_ptr->is_active && dst_client_ptr->is_active) { IPACMDBG_H("This is first connection, add offload links.\n"); if(add_offload_link(data->iptype, src_client_ptr, dst_client_ptr) == IPACM_FAILURE) { IPACMERR("Failed to add offload link for src->dst direction.\n"); return; } if(add_offload_link(data->iptype, dst_client_ptr, src_client_ptr) == IPACM_FAILURE) { IPACMERR("Failed to add offload link for dst->src direction.\n"); return; } if(data->iptype == IPA_IP_v4) { num_offload_pair_v4_ ++; IPACMDBG_H("Added offload links, now num_offload_pair_v4_: %d\n", num_offload_pair_v4_); } else { num_offload_pair_v6_ ++; IPACMDBG_H("Added offload links, now num_offload_pair_v6_: %d\n", num_offload_pair_v6_); } } return; } //If need to insert an entry in peer list, return true, otherwise return false bool IPACM_LanToLan::add_connection(client_info* src_client, client_info* dst_client) { if(src_client == NULL || dst_client == NULL) { IPACMERR("Either source or dest client is NULL.\n"); return false; } peer_info_list::iterator it; peer_info new_peer; bool ret = false; for(it = src_client->peer.begin(); it != src_client->peer.end(); it++) { if(it->peer_pointer == dst_client) { it->num_connection++; IPACMDBG_H("Find dst client entry in peer list, connection count: %d\n", it->num_connection); break; } } if(it == src_client->peer.end()) { IPACMDBG_H("Not finding dst client entry, insert a new one in peer list.\n"); new_peer.peer_pointer = dst_client; new_peer.num_connection = 1; src_client->peer.push_back(new_peer); ret = true; } for(it = dst_client->peer.begin(); it != dst_client->peer.end(); it++) { if(it->peer_pointer == src_client) { it->num_connection++; IPACMDBG_H("Find dst client entry in peer list, connection count: %d\n", it->num_connection); break; } } if(it == dst_client->peer.end()) { IPACMDBG_H("Not finding src client entry, insert a new one in peer list.\n"); new_peer.peer_pointer = src_client; new_peer.num_connection = 1; dst_client->peer.push_back(new_peer); ret = true; } return ret; } void IPACM_LanToLan::handle_del_lan2lan_connection(ipacm_event_connection* data) { IPACMDBG_H("Del lan2lan connection info: IP type: %d, src_v4_addr: 0x%08x, dst_v4_addr: 0x%08x\n", data->iptype, data->src_ipv4_addr, data->dst_ipv4_addr); IPACMDBG_H("src_v6_addr: 0x%08x%08x%08x%08x, dst_v6_addr: 0x%08x%08x%08x%08x", data->src_ipv6_addr[0], data->src_ipv6_addr[1], data->src_ipv6_addr[2], data->src_ipv6_addr[3], data->dst_ipv6_addr[0], data->dst_ipv6_addr[1], data->dst_ipv6_addr[2], data->dst_ipv6_addr[3]); bool res; uint64_t src_ipv6_addr, dst_ipv6_addr; client_info* src_client_ptr; client_info* dst_client_ptr; if(data->iptype == IPA_IP_v4) { if(client_info_v4_.count(data->src_ipv4_addr) == 0 || client_info_v4_.count(data->dst_ipv4_addr) == 0) //if not found the client { IPACMDBG_H("Not found either source or dest client, return.\n"); return; } client_info& src_client = client_info_v4_[data->src_ipv4_addr]; client_info& dst_client = client_info_v4_[data->dst_ipv4_addr]; src_client_ptr = &src_client; dst_client_ptr = &dst_client; } else { memcpy(&src_ipv6_addr, &(data->src_ipv6_addr[2]), sizeof(uint64_t)); memcpy(&dst_ipv6_addr, &(data->dst_ipv6_addr[2]), sizeof(uint64_t)); if(client_info_v6_.count(src_ipv6_addr) == 0 || client_info_v6_.count(dst_ipv6_addr) == 0)//if not found the client { IPACMDBG_H("Not found either source or dest client, return.\n"); return; } client_info& src_client = client_info_v6_[src_ipv6_addr]; client_info& dst_client = client_info_v6_[dst_ipv6_addr]; src_client_ptr = &src_client; dst_client_ptr = &dst_client; } res = remove_connection(src_client_ptr, dst_client_ptr); if(res && src_client_ptr->is_active && dst_client_ptr->is_active) { IPACMDBG_H("Erase link info for both src and dst entries.\n"); erase_offload_link(data->iptype, src_client_ptr, dst_client_ptr); } else { if(res && src_client_ptr->is_powersave && (dst_client_ptr->is_active || dst_client_ptr->is_powersave)) { IPACMDBG_H("Erase link info for both src and dst entries due to src powersave.\n"); erase_offload_link(data->iptype, src_client_ptr, dst_client_ptr); } if(res && dst_client_ptr->is_powersave && (src_client_ptr->is_active || src_client_ptr->is_powersave)) { IPACMDBG_H("Erase link info for both src and dst entries due to dst powersave.\n"); erase_offload_link(data->iptype, dst_client_ptr, src_client_ptr); } } //if the src client is not active and not powersave mode, if peer list is empty, remove client entry if(res && src_client_ptr->is_active == false && src_client_ptr->is_powersave == false && src_client_ptr->peer.size() == 0) { IPACMDBG_H("Peer list of src is empty, remove src entry.\n"); if(data->iptype == IPA_IP_v4) { client_info_v4_.erase(data->src_ipv4_addr); } else { client_info_v6_.erase(src_ipv6_addr); } } //if the dst client is not active and not powersave mode, if peer list is empty, remove client entry if(res && dst_client_ptr->is_active == false && dst_client_ptr->is_powersave == false && dst_client_ptr->peer.size() == 0) { IPACMDBG_H("Peer list of dst is empty, remove dst entry.\n"); if(data->iptype == IPA_IP_v4) { client_info_v4_.erase(data->dst_ipv4_addr); } else { client_info_v6_.erase(dst_ipv6_addr); } } return; } //If need to remove an entry in peer list, return true, otherwise return false bool IPACM_LanToLan::remove_connection(client_info* src_client, client_info* dst_client) { if(src_client == NULL || dst_client == NULL) { IPACMERR("Either source or dest client is NULL.\n"); return false; } peer_info_list::iterator it; bool ret = false; for(it = src_client->peer.begin(); it != src_client->peer.end(); it++) { if(it->peer_pointer == dst_client) { it->num_connection--; IPACMDBG_H("Find dst client entry in src peer list, connection count: %d\n", it->num_connection); if(it->num_connection == 0) { IPACMDBG_H("Need to remove dst entry in src peer list.\n"); ret = true; } break; } } if(ret == true) { src_client->peer.erase(it); } ret = false; for(it = dst_client->peer.begin(); it != dst_client->peer.end(); it++) { if(it->peer_pointer == src_client) { it->num_connection--; IPACMDBG_H("Find src client entry in dst peer list, connection count: %d\n", it->num_connection); if(it->num_connection == 0) { IPACMDBG_H("Need to remove src entry in dst peer list.\n"); ret = true; } break; } } if(ret == true) { dst_client->peer.erase(it); } return ret; } void IPACM_LanToLan::erase_offload_link(ipa_ip_type iptype, client_info* src_client, client_info* dst_client) { if(src_client == NULL || dst_client == NULL) { IPACMERR("Either source or dest client is NULL.\n"); return; } offload_link_info_list::iterator it; int res_src = IPACM_FAILURE, res_dst = IPACM_FAILURE; for(it = src_client->link.begin(); it != src_client->link.end(); it++) { if(it->peer_pointer == dst_client) { res_src = IPACM_SUCCESS; IPACMDBG_H("Find dst client entry in src link list\n"); res_src = del_offload_link(iptype, src_client->p_iface, dst_client->p_iface, &(*it)); src_client->link.erase(it); break; } } for(it = dst_client->link.begin(); it != dst_client->link.end(); it++) { if(it->peer_pointer == src_client) { res_dst = IPACM_SUCCESS; IPACMDBG_H("Find src client entry in dst link list\n"); res_dst = del_offload_link(iptype, dst_client->p_iface, src_client->p_iface, &(*it)); dst_client->link.erase(it); break; } } if(res_src == IPACM_SUCCESS && res_dst == IPACM_SUCCESS) { if(iptype == IPA_IP_v4) { num_offload_pair_v4_ --; IPACMDBG_H("Decrease num of v4 offload pairs to %d\n", num_offload_pair_v4_); } else { num_offload_pair_v6_ --; IPACMDBG_H("Decrease num of v6 offload pairs to %d\n", num_offload_pair_v6_); } } return; } void IPACM_LanToLan::generate_new_connection(ipa_ip_type iptype, client_info* client) { #ifndef CT_OPT if(client == NULL) { IPACMERR("Client is NULL.\n"); return; } IPACMDBG_H("Generate new connection events for IP type %d\n", iptype); int num = 0; ipacm_cmd_q_data evt; ipacm_event_connection* new_conn; ipacm_iface_type client_type, peer_type; client_type = IPACM_Iface::ipacmcfg->iface_table[client->p_iface->ipa_if_num].if_cat; IPACMDBG_H("Client's iface type is %d.\n", client_type); if(iptype == IPA_IP_v4) { client_table_v4::iterator it; for(it = client_info_v4_.begin(); it != client_info_v4_.end(); it++) { peer_type = IPACM_Iface::ipacmcfg->iface_table[it->second.p_iface->ipa_if_num].if_cat; if(peer_type != client_type && it->second.is_active == true) { IPACMDBG_H("Find a qualified peer to generate new_conn event.\n"); IPACMDBG_H("Peer's iface type is %d.\n", peer_type); new_conn = (ipacm_event_connection*)malloc(sizeof(ipacm_event_connection)); if(new_conn == NULL) { IPACMERR("Failed to allocate memory for new_connection event.\n"); return; } memset(new_conn, 0, sizeof(ipacm_event_connection)); new_conn->iptype = IPA_IP_v4; new_conn->src_ipv4_addr = client->ip.ipv4_addr; new_conn->dst_ipv4_addr = it->second.ip.ipv4_addr; memset(&evt, 0, sizeof(evt)); evt.event = IPA_LAN_TO_LAN_NEW_CONNECTION; evt.evt_data = (void*)new_conn; IPACM_EvtDispatcher::PostEvt(&evt); num++; } } } else if(iptype == IPA_IP_v6) { client_table_v6::iterator it; for(it = client_info_v6_.begin(); it != client_info_v6_.end(); it++) { peer_type = IPACM_Iface::ipacmcfg->iface_table[it->second.p_iface->ipa_if_num].if_cat; if(peer_type != client_type && it->second.is_active == true) { IPACMDBG_H("Find a qualified peer to generate new_conn event.\n"); IPACMDBG_H("Peer's iface type is %d.\n", peer_type); new_conn = (ipacm_event_connection*)malloc(sizeof(ipacm_event_connection)); if(new_conn == NULL) { IPACMERR("Failed to allocate memory for new_connection event.\n"); return; } memset(new_conn, 0, sizeof(ipacm_event_connection)); new_conn->iptype = IPA_IP_v6; memcpy(new_conn->src_ipv6_addr, client->ip.ipv6_addr, sizeof(new_conn->src_ipv6_addr)); memcpy(new_conn->dst_ipv6_addr, it->second.ip.ipv6_addr, sizeof(new_conn->dst_ipv6_addr)); memset(&evt, 0, sizeof(evt)); evt.event = IPA_LAN_TO_LAN_NEW_CONNECTION; evt.evt_data = (void*)new_conn; IPACM_EvtDispatcher::PostEvt(&evt); num++; } } } else { IPACMERR("IP type is not expected.\n"); } IPACMDBG_H("Generate %d new connection events in total.\n", num); #endif return; } void IPACM_LanToLan::handle_client_power_recover(ipacm_event_lan_client* data) { if(data == NULL) { IPACMERR("No client info is found.\n"); return; } if(data->mac_addr == NULL || data->ipv6_addr == NULL || data->p_iface == NULL) { IPACMERR("Event data is not populated properly.\n"); return; } if(data->iptype != IPA_IP_v4 && data->iptype != IPA_IP_v6) { IPACMERR("IP type is not expected: %d\n", data->iptype); return; } IPACMDBG_H("New client info: iface %s, iptype: %d, mac: 0x%02x%02x%02x%02x%02x%02x, v4_addr: 0x%08x, v6_addr: 0x%08x%08x%08x%08x \n", data->p_iface->dev_name, data->iptype, data->mac_addr[0], data->mac_addr[1], data->mac_addr[2], data->mac_addr[3], data->mac_addr[4], data->mac_addr[5], data->ipv4_addr, data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]); client_info* client_ptr; if(data->iptype == IPA_IP_v4) { if(client_info_v4_.count(data->ipv4_addr) == 0) { IPACMERR("Client is not found.\n"); return; } client_info& client = client_info_v4_[data->ipv4_addr]; client_ptr = &client; } else { uint64_t v6_addr; memcpy(&v6_addr, &(data->ipv6_addr[2]), sizeof(uint64_t)); if(client_info_v6_.count(v6_addr) == 0) { IPACMERR("Client is not found.\n"); return; } client_info& client = client_info_v6_[v6_addr]; client_ptr = &client; } if(client_ptr->is_active == true || client_ptr->is_powersave != true) //the client is in wrong state { IPACMERR("The client is in wrong state: active %d, powersave %d.\n", client_ptr->is_active, client_ptr->is_powersave); return; } else { if(add_flt_rules(data->iptype, client_ptr) == IPACM_FAILURE) { IPACMERR("Failed to add back flt rules when power recovery.\n"); return; } client_ptr->is_active = true; client_ptr->is_powersave = false; check_potential_link(data->iptype, client_ptr); generate_new_connection(data->iptype, client_ptr); } IPACMDBG_H("There are %d clients in v4 table and %d clients in v6 table.\n", client_info_v4_.size(), client_info_v6_.size()); return; } //This function is called when power save: remove filtering rules only int IPACM_LanToLan::remove_flt_rules(ipa_ip_type iptype, client_info* client) { if(client == NULL) { IPACMERR("No client info is found.\n"); return IPACM_FAILURE; } bool err_flag; offload_link_info_list::iterator client_it; offload_link_info_list::iterator peer_it; client_info* peer; for(client_it = client->link.begin(); client_it != client->link.end(); client_it++) { if(client->p_iface->del_lan2lan_flt_rule(iptype, client_it->flt_rule_hdl) == IPACM_FAILURE) { IPACMERR("Failed to delete client's filtering rule.\n"); } err_flag = true; peer = client_it->peer_pointer; for(peer_it = peer->link.begin(); peer_it != peer->link.end(); peer_it++) { if(peer_it->peer_pointer == client) { if(peer->p_iface->del_lan2lan_flt_rule(iptype, peer_it->flt_rule_hdl) == IPACM_FAILURE) { IPACMERR("Failed to delete peer's offload link.\n"); } err_flag = false; break; } } if(err_flag) { IPACMERR("Unable to find corresponding offload link in peer's entry.\n"); return IPACM_FAILURE; } } return IPACM_SUCCESS; } int IPACM_LanToLan::add_flt_rules(ipa_ip_type iptype, client_info* client) { if(client == NULL) { IPACMERR("No client info is found.\n"); return IPACM_FAILURE; } bool err_flag; offload_link_info_list::iterator client_it; offload_link_info_list::iterator peer_it; client_info* peer; for(client_it = client->link.begin(); client_it != client->link.end(); client_it++) { peer = client_it->peer_pointer; if(client->p_iface->add_lan2lan_flt_rule(iptype, client->ip.ipv4_addr, peer->ip.ipv4_addr, client->ip.ipv6_addr, peer->ip.ipv6_addr, &(client_it->flt_rule_hdl)) == IPACM_FAILURE) { IPACMERR("Failed to add client's filtering rule.\n"); return IPACM_FAILURE; } err_flag = true; for(peer_it = peer->link.begin(); peer_it != peer->link.end(); peer_it++) { if(peer_it->peer_pointer == client) { if(peer->p_iface->add_lan2lan_flt_rule(iptype, peer->ip.ipv4_addr, client->ip.ipv4_addr, peer->ip.ipv6_addr, client->ip.ipv6_addr, &(peer_it->flt_rule_hdl)) == IPACM_FAILURE) { IPACMERR("Failed to delete peer's offload link.\n"); return IPACM_FAILURE; } err_flag = false; break; } } if(err_flag) { IPACMERR("Unable to find corresponding offload link in peer's entry.\n"); return IPACM_FAILURE; } } return IPACM_SUCCESS; } void IPACM_LanToLan::handle_new_connection(ipacm_event_connection* new_conn) { #ifdef CT_OPT if(new_conn == NULL) { IPACMERR("No connection info is found.\n"); return; } if(new_conn->iptype != IPA_IP_v4 && new_conn->iptype != IPA_IP_v6) { IPACMERR("IP type is not expected: %d.\n", new_conn->iptype); return; } IPACMDBG_H("New connection info: IP type: %d, src_v4_addr: 0x%08x, dst_v4_addr: 0x%08x\n", new_conn->iptype, new_conn->src_ipv4_addr, new_conn->dst_ipv4_addr); IPACMDBG_H("src_v6_addr: 0x%08x%08x%08x%08x, dst_v6_addr: 0x%08x%08x%08x%08x", new_conn->src_ipv6_addr[0], new_conn->src_ipv6_addr[1], new_conn->src_ipv6_addr[2], new_conn->src_ipv6_addr[3], new_conn->dst_ipv6_addr[0], new_conn->dst_ipv6_addr[1], new_conn->dst_ipv6_addr[2], new_conn->dst_ipv6_addr[3]); if(is_lan2lan_connection(new_conn) == false) { IPACMDBG_H("The connection is not lan2lan connection.\n"); cache_new_connection(new_conn); return; } ipacm_cmd_q_data evt; ipacm_event_connection* conn; conn = (ipacm_event_connection*)malloc(sizeof(ipacm_event_connection)); if(conn == NULL) { IPACMERR("Failed to allocate memory for new_connection event.\n"); return; } memcpy(conn, new_conn, sizeof(ipacm_event_connection)); memset(&evt, 0, sizeof(evt)); evt.event = IPA_LAN_TO_LAN_NEW_CONNECTION; evt.evt_data = (void*)conn; IPACM_EvtDispatcher::PostEvt(&evt); #endif return; } void IPACM_LanToLan::handle_del_connection(ipacm_event_connection* new_conn) { #ifdef CT_OPT if(new_conn == NULL) { IPACMERR("No connection info is found.\n"); return; } if(new_conn->iptype != IPA_IP_v4 && new_conn->iptype != IPA_IP_v6) { IPACMERR("IP type is not expected: %d.\n", new_conn->iptype); return; } IPACMDBG_H("Del connection info: IP type: %d, src_v4_addr: 0x%08x, dst_v4_addr: 0x%08x\n", new_conn->iptype, new_conn->src_ipv4_addr, new_conn->dst_ipv4_addr); IPACMDBG_H("src_v6_addr: 0x%08x%08x%08x%08x, dst_v6_addr: 0x%08x%08x%08x%08x", new_conn->src_ipv6_addr[0], new_conn->src_ipv6_addr[1], new_conn->src_ipv6_addr[2], new_conn->src_ipv6_addr[3], new_conn->dst_ipv6_addr[0], new_conn->dst_ipv6_addr[1], new_conn->dst_ipv6_addr[2], new_conn->dst_ipv6_addr[3]); if(is_lan2lan_connection(new_conn) == false) { IPACMDBG_H("The connection is not lan2lan connection.\n"); remove_cache_connection(new_conn); return; } ipacm_cmd_q_data evt; ipacm_event_connection* conn; conn = (ipacm_event_connection*)malloc(sizeof(ipacm_event_connection)); if(conn == NULL) { IPACMERR("Failed to allocate memory for del_connection event.\n"); return; } memcpy(conn, new_conn, sizeof(ipacm_event_connection)); memset(&evt, 0, sizeof(evt)); evt.event = IPA_LAN_TO_LAN_DEL_CONNECTION; evt.evt_data = (void*)conn; IPACM_EvtDispatcher::PostEvt(&evt); #endif return; } bool IPACM_LanToLan::is_lan2lan_connection(ipacm_event_connection* data) { if(data->iptype == IPA_IP_v4) { if(client_info_v4_.count(data->src_ipv4_addr) == 0 || client_info_v4_.count(data->dst_ipv4_addr) == 0) { IPACMDBG("Either source or destination is not in client table\n"); return false; } ipacm_iface_type src_type, dst_type; src_type = IPACM_Iface::ipacmcfg->iface_table[client_info_v4_[data->src_ipv4_addr].p_iface->ipa_if_num].if_cat; dst_type = IPACM_Iface::ipacmcfg->iface_table[client_info_v4_[data->dst_ipv4_addr].p_iface->ipa_if_num].if_cat; return (src_type != dst_type); } else { uint64_t src_v6_addr, dst_v6_addr; memcpy(&src_v6_addr, &(data->src_ipv6_addr[2]), sizeof(uint64_t)); memcpy(&dst_v6_addr, &(data->dst_ipv6_addr[2]), sizeof(uint64_t)); if(client_info_v6_.count(src_v6_addr) == 0 || client_info_v6_.count(dst_v6_addr) == 0) { IPACMDBG("Either source or destination is not in client table\n"); return false; } ipacm_iface_type src_type, dst_type; src_type = IPACM_Iface::ipacmcfg->iface_table[client_info_v6_[src_v6_addr].p_iface->ipa_if_num].if_cat; dst_type = IPACM_Iface::ipacmcfg->iface_table[client_info_v6_[dst_v6_addr].p_iface->ipa_if_num].if_cat; return (src_type != dst_type); } } IPACM_LanToLan* IPACM_LanToLan::getLan2LanInstance() { return p_instance; } bool IPACM_LanToLan::is_potential_lan2lan_connection(ipacm_event_connection* new_conn) { int i, num_private_subnet; bool src_is_valid = false; bool dst_is_valid = false; if(new_conn->iptype == IPA_IP_v4) { num_private_subnet = IPACM_Iface::ipacmcfg->ipa_num_private_subnet; for(i=0; isrc_ipv4_addr & IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask) == (IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_addr & IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask) ) { src_is_valid = true; } if( (new_conn->dst_ipv4_addr & IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask) == (IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_addr & IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask) ) { dst_is_valid = true; } } if(src_is_valid && dst_is_valid) { IPACMDBG("Both src and dst are potentially in subnet.\n"); return true; } } else { if( (new_conn->src_ipv6_addr[0] & ipv6_multicast_mask) != (ipv6_multicast_addr & ipv6_multicast_mask) ) { src_is_valid = true; } if( (new_conn->dst_ipv6_addr[0] & ipv6_multicast_mask) != (ipv6_multicast_addr & ipv6_multicast_mask) ) { dst_is_valid = true; } if(src_is_valid && dst_is_valid) { IPACMDBG("Both src and dst are potentially in subnet.\n"); return true; } } IPACMDBG("This connection is not a lan2lan connection potentially.\n"); return false; } void IPACM_LanToLan::cache_new_connection(ipacm_event_connection* new_conn) { if(is_potential_lan2lan_connection(new_conn) == true) { if(new_conn->iptype == IPA_IP_v4) { if(connection_v4_.size() == max_cache_connection) { IPACMDBG_H("Cached ipv4 connections already reach maximum, clear up the list.\n"); connection_v4_.clear(); } connection_v4_.push_back(*new_conn); IPACMDBG_H("Cache an ipv4 connection, now the number of ipv4 cache connection is %d.\n", connection_v4_.size()); } else { if(connection_v6_.size() == max_cache_connection) { IPACMDBG_H("Cached ipv6 connections already reach maximum, clear up the list.\n"); connection_v6_.clear(); } connection_v6_.push_back(*new_conn); IPACMDBG_H("Cache an ipv6 connection, now the number of ipv6 cache connection is %d.\n", connection_v6_.size()); } } return; } void IPACM_LanToLan::remove_cache_connection(ipacm_event_connection* del_conn) { connection_list::iterator it; if(is_potential_lan2lan_connection(del_conn) == true) { if(del_conn->iptype == IPA_IP_v4) { for(it = connection_v4_.begin(); it != connection_v4_.end(); it++) { if(it->src_ipv4_addr == del_conn->src_ipv4_addr && it->dst_ipv4_addr == del_conn->dst_ipv4_addr) { IPACMDBG("Find the cached ipv4 connection, remove it from list.\n"); connection_v4_.erase(it); IPACMDBG_H("Now the number of ipv4 cache connection is %d.\n", connection_v4_.size()); return; } } IPACMDBG_H("Do not find the cached ipv4 connection, do nothing.\n"); } else { for(it = connection_v6_.begin(); it != connection_v6_.end(); it++) { if(memcmp(it->src_ipv6_addr, del_conn->src_ipv6_addr, 4*sizeof(uint32_t)) == 0 && memcmp(it->dst_ipv6_addr, del_conn->dst_ipv6_addr, 4*sizeof(uint32_t)) == 0 ) { IPACMDBG("Find the cached ipv6 connection, remove it from list.\n"); connection_v6_.erase(it); IPACMDBG_H("Now the number of ipv6 cache connection is %d.\n", connection_v6_.size()); return; } } IPACMDBG_H("Do not find the cached ipv6 connection, do nothing.\n"); } } return; } void IPACM_LanToLan::check_cache_connection(ipa_ip_type iptype, client_info* client) { #ifdef CT_OPT connection_list::iterator it; if(iptype == IPA_IP_v4) { it = connection_v4_.begin(); while(it != connection_v4_.end()) { if( (it->src_ipv4_addr == client->ip.ipv4_addr && client_info_v4_.count(it->dst_ipv4_addr) > 0) || (it->dst_ipv4_addr == client->ip.ipv4_addr && client_info_v4_.count(it->src_ipv4_addr) > 0) ) { IPACMDBG("Found a cache connection for src client 0x%08x and dst client 0x%08x.\n", it->src_ipv4_addr, it->dst_ipv4_addr); ipacm_cmd_q_data evt; ipacm_event_connection* conn; conn = (ipacm_event_connection*)malloc(sizeof(ipacm_event_connection)); if(conn == NULL) { IPACMERR("Failed to allocate memory for new_connection event.\n"); return; } memcpy(conn, &(*it), sizeof(ipacm_event_connection)); memset(&evt, 0, sizeof(evt)); evt.event = IPA_LAN_TO_LAN_NEW_CONNECTION; evt.evt_data = (void*)conn; IPACM_EvtDispatcher::PostEvt(&evt); it = connection_v4_.erase(it); IPACMDBG_H("Now the number of cache connections is %d.\n", connection_v4_.size()); } else { it++; } } } else { uint64_t src_v6_addr, dst_v6_addr; it = connection_v6_.begin(); while(it != connection_v6_.end()) { memcpy(&src_v6_addr, &(it->src_ipv6_addr[2]), sizeof(uint64_t)); memcpy(&dst_v6_addr, &(it->dst_ipv6_addr[2]), sizeof(uint64_t)); if( (memcmp(it->src_ipv6_addr, client->ip.ipv6_addr, 4*sizeof(uint32_t)) == 0 && client_info_v6_.count(dst_v6_addr) > 0) || (memcmp(it->dst_ipv6_addr, client->ip.ipv6_addr, 4*sizeof(uint32_t)) == 0 && client_info_v6_.count(src_v6_addr) > 0) ) { IPACMDBG("Found a cache connection with src client 0x%08x%08x%08x%08x and dst client 0x%08x%08x%08x%08x.\n", it->src_ipv6_addr[0], it->src_ipv6_addr[1], it->src_ipv6_addr[2], it->src_ipv6_addr[3], it->dst_ipv6_addr[0], it->dst_ipv6_addr[1], it->dst_ipv6_addr[2], it->dst_ipv6_addr[3]); ipacm_cmd_q_data evt; ipacm_event_connection* conn; conn = (ipacm_event_connection*)malloc(sizeof(ipacm_event_connection)); if(conn == NULL) { IPACMERR("Failed to allocate memory for new_connection event.\n"); return; } memcpy(conn, &(*it), sizeof(ipacm_event_connection)); memset(&evt, 0, sizeof(evt)); evt.event = IPA_LAN_TO_LAN_NEW_CONNECTION; evt.evt_data = (void*)conn; IPACM_EvtDispatcher::PostEvt(&evt); it = connection_v6_.erase(it); IPACMDBG_H("Now the number of cache connections is %d.\n", connection_v6_.size()); } else { it++; } } } #endif return; } ================================================ FILE: data-ipa-cfg-mgr/ipacm/src/IPACM_Log.cpp ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPACM_log.cpp @brief This file implements the IPAM log functionality. @Author Skylar Chang */ #include "IPACM_Log.h" #include #include #include #include #include #include #include #include #include #include #include void logmessage(int log_level) { return; } /* start IPACMDIAG socket*/ int create_socket(unsigned int *sockfd) { if ((*sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) == IPACM_FAILURE) { perror("Error creating ipacm_log socket\n"); return IPACM_FAILURE; } if(fcntl(*sockfd, F_SETFD, FD_CLOEXEC) < 0) { perror("Couldn't set ipacm_log Close on Exec\n"); } return IPACM_SUCCESS; } void ipacm_log_send( void * user_data) { ipacm_log_buffer_t ipacm_log_buffer; int numBytes=0, len; struct sockaddr_un ipacmlog_socket; static unsigned int ipacm_log_sockfd = 0; if(ipacm_log_sockfd == 0) { /* start ipacm_log socket */ if(create_socket(&ipacm_log_sockfd) < 0) { printf("unable to create ipacm_log socket\n"); return; } printf("create ipacm_log socket successfully\n"); } ipacmlog_socket.sun_family = AF_UNIX; strcpy(ipacmlog_socket.sun_path, IPACMLOG_FILE); len = strlen(ipacmlog_socket.sun_path) + sizeof(ipacmlog_socket.sun_family); memcpy(ipacm_log_buffer.user_data, user_data, MAX_BUF_LEN); //printf("send : %s\n", ipacm_log_buffer.user_data); if ((numBytes = sendto(ipacm_log_sockfd, (void *)&ipacm_log_buffer, sizeof(ipacm_log_buffer.user_data), 0, (struct sockaddr *)&ipacmlog_socket, len)) == -1) { printf("Send Failed(%d) %s \n",errno,strerror(errno)); return; } return; } ================================================ FILE: data-ipa-cfg-mgr/ipacm/src/IPACM_Main.cpp ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPACM_Main.cpp @brief This file implements the IPAM functionality. @Author Skylar Chang */ /****************************************************************************** IP_MAIN.C ******************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include "linux/ipa_qmi_service_v01.h" #define __stringify_1(x...) #x #define __stringify(x...) __stringify_1(x) #include "IPACM_CmdQueue.h" #include "IPACM_EvtDispatcher.h" #include "IPACM_Defs.h" #include "IPACM_Neighbor.h" #include "IPACM_IfaceManager.h" #include "IPACM_Log.h" #include "IPACM_ConntrackListener.h" #include "IPACM_ConntrackClient.h" #include "IPACM_Netlink.h" /* not defined(FEATURE_IPA_ANDROID)*/ #ifndef FEATURE_IPA_ANDROID #include "IPACM_LanToLan.h" #endif const char *ipacm_event_name[] = { __stringify(IPA_CFG_CHANGE_EVENT), /* 1 NULL */ __stringify(IPA_LINK_UP_EVENT), /* 2 ipacm_event_data_fid */ __stringify(IPA_LINK_DOWN_EVENT), /* 3 ipacm_event_data_fid */ __stringify(IPA_ADDR_ADD_EVENT), /* 4 ipacm_event_data_addr */ __stringify(IPA_ADDR_DEL_EVENT), /* 5 no use */ __stringify(IPA_ROUTE_ADD_EVENT), /* 6 ipacm_event_data_addr */ __stringify(IPA_ROUTE_DEL_EVENT), /* 7 ipacm_event_data_addr */ __stringify(IPA_FIREWALL_CHANGE_EVENT), /* 8 NULL */ __stringify(IPA_WLAN_AP_LINK_UP_EVENT), /* 9 ipacm_event_data_mac */ __stringify(IPA_WLAN_STA_LINK_UP_EVENT), /* 10 ipacm_event_data_mac */ __stringify(IPA_WLAN_CLIENT_ADD_EVENT), /* 11 ipacm_event_data_mac */ __stringify(IPA_WLAN_CLIENT_DEL_EVENT), /* 12 ipacm_event_data_mac */ __stringify(IPA_WLAN_CLIENT_POWER_SAVE_EVENT), /* 13 ipacm_event_data_mac */ __stringify(IPA_WLAN_CLIENT_RECOVER_EVENT), /* 14 ipacm_event_data_mac */ __stringify(IPA_NEW_NEIGH_EVENT), /* 15 ipacm_event_data_all */ __stringify(IPA_DEL_NEIGH_EVENT), /* 16 ipacm_event_data_all */ __stringify(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT), /* 17 ipacm_event_data_all */ __stringify(IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT), /* 18 ipacm_event_data_all */ __stringify(IPA_SW_ROUTING_ENABLE), /* 19 NULL */ __stringify(IPA_SW_ROUTING_DISABLE), /* 20 NULL */ __stringify(IPA_PROCESS_CT_MESSAGE), /* 21 ipacm_ct_evt_data */ __stringify(IPA_HANDLE_WAN_UP), /* 22 ipacm_event_iface_up */ __stringify(IPA_HANDLE_WAN_DOWN), /* 23 ipacm_event_iface_up */ __stringify(IPA_HANDLE_WLAN_UP), /* 24 ipacm_event_iface_up */ __stringify(IPA_HANDLE_LAN_UP), /* 25 ipacm_event_iface_up */ __stringify(IPA_WLAN_CLIENT_ADD_EVENT_EX), /* 26 ipacm_event_data_wlan_ex */ __stringify(IPA_HANDLE_WAN_UP_V6), /* 27 NULL */ __stringify(IPA_HANDLE_WAN_DOWN_V6), /* 28 NULL */ __stringify(IPA_LAN_CLIENT_ACTIVE), /* 29 ipacm_event_lan_client*/ __stringify(IPA_LAN_CLIENT_INACTIVE), /* 30 ipacm_event_lan_client*/ __stringify(IPA_LAN_CLIENT_DISCONNECT), /* 31 ipacm_event_lan_client*/ __stringify(IPA_LAN_CLIENT_POWER_SAVE), /* 32 ipacm_event_lan_client*/ __stringify(IPA_LAN_CLIENT_POWER_RECOVER), /* 33 ipacm_event_lan_client*/ __stringify(IPA_LAN_TO_LAN_NEW_CONNECTION), /* 34 ipacm_event_connection */ __stringify(IPA_LAN_TO_LAN_DEL_CONNECTION), /* 35 ipacm_event_connection */ __stringify(IPA_LAN_DELETE_SELF), /* 36 ipacm_event_data_fid */ __stringify(IPA_WLAN_LINK_DOWN_EVENT), /* 37 ipacm_event_data_mac */ __stringify(IPA_USB_LINK_UP_EVENT), /* 38 ipacm_event_data_fid */ __stringify(IPA_PROCESS_CT_MESSAGE_V6), /* 39 ipacm_ct_evt_data */ __stringify(IPA_PRIVATE_SUBNET_CHANGE_EVENT), /* 40 ipacm_event_data_fid */ __stringify(IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT), /* 41 ipacm_event_data_fid */ __stringify(IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT), /* 42 ipacm_event_data_fid */ }; #define IPA_DRIVER "/dev/ipa" #define IPACM_FIREWALL_FILE_NAME "mobileap_firewall.xml" #define IPACM_CFG_FILE_NAME "IPACM_cfg.xml" #ifdef FEATURE_IPA_ANDROID #define IPACM_PID_FILE "/data/misc/ipa/ipacm.pid" #define IPACM_DIR_NAME "/data" #else/* defined(FEATURE_IPA_ANDROID) */ #define IPACM_PID_FILE "/etc/ipacm.pid" #define IPACM_DIR_NAME "/etc" #endif /* defined(NOT FEATURE_IPA_ANDROID)*/ #define IPACM_NAME "ipacm" #define INOTIFY_EVENT_SIZE (sizeof(struct inotify_event)) #define INOTIFY_BUF_LEN (INOTIFY_EVENT_SIZE + 2*sizeof(IPACM_FIREWALL_FILE_NAME)) #define IPA_DRIVER_WLAN_EVENT_MAX_OF_ATTRIBS 3 #define IPA_DRIVER_WLAN_EVENT_SIZE (sizeof(struct ipa_wlan_msg_ex)+ IPA_DRIVER_WLAN_EVENT_MAX_OF_ATTRIBS*sizeof(ipa_wlan_hdr_attrib_val)) #define IPA_DRIVER_PIPE_STATS_EVENT_SIZE (sizeof(struct ipa_get_data_stats_resp_msg_v01)) #define IPA_DRIVER_WLAN_META_MSG (sizeof(struct ipa_msg_meta)) #define IPA_DRIVER_WLAN_BUF_LEN (IPA_DRIVER_PIPE_STATS_EVENT_SIZE + IPA_DRIVER_WLAN_META_MSG) uint32_t ipacm_event_stats[IPACM_EVENT_MAX]; bool ipacm_logging = true; void ipa_is_ipacm_running(void); int ipa_get_if_index(char *if_name, int *if_index); /* start netlink socket monitor*/ void* netlink_start(void *param) { ipa_nl_sk_fd_set_info_t sk_fdset; int ret_val = 0; memset(&sk_fdset, 0, sizeof(ipa_nl_sk_fd_set_info_t)); IPACMDBG_H("netlink starter memset sk_fdset succeeds\n"); ret_val = ipa_nl_listener_init(NETLINK_ROUTE, (RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE | RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR | RTMGRP_NEIGH | RTNLGRP_IPV6_PREFIX), &sk_fdset, ipa_nl_recv_msg); if (ret_val != IPACM_SUCCESS) { IPACMERR("Failed to initialize IPA netlink event listener\n"); return NULL; } return NULL; } /* start firewall-rule monitor*/ void* firewall_monitor(void *param) { int length; int wd; char buffer[INOTIFY_BUF_LEN]; int inotify_fd; ipacm_cmd_q_data evt_data; uint32_t mask = IN_MODIFY | IN_MOVE; inotify_fd = inotify_init(); if (inotify_fd < 0) { PERROR("inotify_init"); } IPACMDBG_H("Waiting for nofications in dir %s with mask: 0x%x\n", IPACM_DIR_NAME, mask); wd = inotify_add_watch(inotify_fd, IPACM_DIR_NAME, mask); while (1) { length = read(inotify_fd, buffer, INOTIFY_BUF_LEN); if (length < 0) { IPACMERR("inotify read() error return length: %d and mask: 0x%x\n", length, mask); continue; } struct inotify_event* event; event = (struct inotify_event*)malloc(length); if(event == NULL) { IPACMERR("Failed to allocate memory.\n"); return NULL; } memset(event, 0, length); memcpy(event, buffer, length); if (event->len > 0) { if ( (event->mask & IN_MODIFY) || (event->mask & IN_MOVE)) { if (event->mask & IN_ISDIR) { IPACMDBG_H("The directory %s was 0x%x\n", event->name, event->mask); } else if (!strncmp(event->name, IPACM_FIREWALL_FILE_NAME, event->len)) // firewall_rule change { IPACMDBG_H("File \"%s\" was 0x%x\n", event->name, event->mask); IPACMDBG_H("The interested file %s .\n", IPACM_FIREWALL_FILE_NAME); evt_data.event = IPA_FIREWALL_CHANGE_EVENT; evt_data.evt_data = NULL; /* Insert IPA_FIREWALL_CHANGE_EVENT to command queue */ IPACM_EvtDispatcher::PostEvt(&evt_data); } else if (!strncmp(event->name, IPACM_CFG_FILE_NAME, event->len)) // IPACM_configuration change { IPACMDBG_H("File \"%s\" was 0x%x\n", event->name, event->mask); IPACMDBG_H("The interested file %s .\n", IPACM_CFG_FILE_NAME); evt_data.event = IPA_CFG_CHANGE_EVENT; evt_data.evt_data = NULL; /* Insert IPA_FIREWALL_CHANGE_EVENT to command queue */ IPACM_EvtDispatcher::PostEvt(&evt_data); } } IPACMDBG_H("Received monitoring event %s.\n", event->name); } free(event); } (void)inotify_rm_watch(inotify_fd, wd); (void)close(inotify_fd); return NULL; } /* start IPACM WLAN-driver notifier */ void* ipa_driver_wlan_notifier(void *param) { int length, fd, cnt; char buffer[IPA_DRIVER_WLAN_BUF_LEN]; struct ipa_msg_meta event_hdr; struct ipa_ecm_msg event_ecm; struct ipa_wan_msg event_wan; struct ipa_wlan_msg_ex event_ex_o; struct ipa_wlan_msg *event_wlan=NULL; struct ipa_wlan_msg_ex *event_ex= NULL; struct ipa_get_data_stats_resp_msg_v01 event_data_stats; struct ipa_get_apn_data_stats_resp_msg_v01 event_network_stats; ipacm_cmd_q_data evt_data; ipacm_event_data_mac *data = NULL; ipacm_event_data_fid *data_fid = NULL; ipacm_event_data_iptype *data_iptype = NULL; ipacm_event_data_wlan_ex *data_ex; ipa_get_data_stats_resp_msg_v01 *data_tethering_stats = NULL; ipa_get_apn_data_stats_resp_msg_v01 *data_network_stats = NULL; fd = open(IPA_DRIVER, O_RDWR); if (fd == 0) { IPACMERR("Failed opening %s.\n", IPA_DRIVER); return NULL; } while (1) { IPACMDBG_H("Waiting for nofications from IPA driver \n"); memset(buffer, 0, sizeof(buffer)); memset(&evt_data, 0, sizeof(evt_data)); data = NULL; data_fid = NULL; data_tethering_stats = NULL; data_network_stats = NULL; length = read(fd, buffer, IPA_DRIVER_WLAN_BUF_LEN); if (length < 0) { PERROR("didn't read IPA_driver correctly"); continue; } memcpy(&event_hdr, buffer,sizeof(struct ipa_msg_meta)); IPACMDBG_H("Message type: %d\n", event_hdr.msg_type); IPACMDBG_H("Event header length received: %d\n",event_hdr.msg_len); /* Insert WLAN_DRIVER_EVENT to command queue */ switch (event_hdr.msg_type) { case SW_ROUTING_ENABLE: IPACMDBG_H("Received SW_ROUTING_ENABLE\n"); evt_data.event = IPA_SW_ROUTING_ENABLE; IPACMDBG_H("Not supported anymore\n"); continue; case SW_ROUTING_DISABLE: IPACMDBG_H("Received SW_ROUTING_DISABLE\n"); evt_data.event = IPA_SW_ROUTING_DISABLE; IPACMDBG_H("Not supported anymore\n"); continue; case WLAN_AP_CONNECT: event_wlan = (struct ipa_wlan_msg *) (buffer + sizeof(struct ipa_msg_meta)); IPACMDBG_H("Received WLAN_AP_CONNECT name: %s\n",event_wlan->name); IPACMDBG_H("AP Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n", event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2], event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]); data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid)); if(data_fid == NULL) { IPACMERR("unable to allocate memory for event_wlan data_fid\n"); return NULL; } ipa_get_if_index(event_wlan->name, &(data_fid->if_index)); evt_data.event = IPA_WLAN_AP_LINK_UP_EVENT; evt_data.evt_data = data_fid; break; case WLAN_AP_DISCONNECT: event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta)); IPACMDBG_H("Received WLAN_AP_DISCONNECT name: %s\n",event_wlan->name); IPACMDBG_H("AP Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n", event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2], event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]); data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid)); if(data_fid == NULL) { IPACMERR("unable to allocate memory for event_wlan data_fid\n"); return NULL; } ipa_get_if_index(event_wlan->name, &(data_fid->if_index)); evt_data.event = IPA_WLAN_LINK_DOWN_EVENT; evt_data.evt_data = data_fid; break; case WLAN_STA_CONNECT: event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta)); IPACMDBG_H("Received WLAN_STA_CONNECT name: %s\n",event_wlan->name); IPACMDBG_H("STA Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n", event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2], event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]); data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac)); if(data == NULL) { IPACMERR("unable to allocate memory for event_wlan data_fid\n"); return NULL; } memcpy(data->mac_addr, event_wlan->mac_addr, sizeof(event_wlan->mac_addr)); ipa_get_if_index(event_wlan->name, &(data->if_index)); evt_data.event = IPA_WLAN_STA_LINK_UP_EVENT; evt_data.evt_data = data; break; case WLAN_STA_DISCONNECT: event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta)); IPACMDBG_H("Received WLAN_STA_DISCONNECT name: %s\n",event_wlan->name); IPACMDBG_H("STA Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n", event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2], event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]); data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid)); if(data_fid == NULL) { IPACMERR("unable to allocate memory for event_wlan data_fid\n"); return NULL; } ipa_get_if_index(event_wlan->name, &(data_fid->if_index)); evt_data.event = IPA_WLAN_LINK_DOWN_EVENT; evt_data.evt_data = data_fid; break; case WLAN_CLIENT_CONNECT: event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta)); IPACMDBG_H("Received WLAN_CLIENT_CONNECT\n"); IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n", event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2], event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]); data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac)); if (data == NULL) { IPACMERR("unable to allocate memory for event_wlan data\n"); return NULL; } memcpy(data->mac_addr, event_wlan->mac_addr, sizeof(event_wlan->mac_addr)); ipa_get_if_index(event_wlan->name, &(data->if_index)); evt_data.event = IPA_WLAN_CLIENT_ADD_EVENT; evt_data.evt_data = data; break; case WLAN_CLIENT_CONNECT_EX: IPACMDBG_H("Received WLAN_CLIENT_CONNECT_EX\n"); memcpy(&event_ex_o, buffer + sizeof(struct ipa_msg_meta),sizeof(struct ipa_wlan_msg_ex)); if(event_ex_o.num_of_attribs > IPA_DRIVER_WLAN_EVENT_MAX_OF_ATTRIBS) { IPACMERR("buffer size overflow\n"); return NULL; } length = sizeof(ipa_wlan_msg_ex)+ event_ex_o.num_of_attribs * sizeof(ipa_wlan_hdr_attrib_val); IPACMDBG_H("num_of_attribs %d, length %d\n", event_ex_o.num_of_attribs, length); event_ex = (ipa_wlan_msg_ex *)malloc(length); if(event_ex == NULL ) { IPACMERR("Unable to allocate memory\n"); return NULL; } memcpy(event_ex, buffer + sizeof(struct ipa_msg_meta), length); data_ex = (ipacm_event_data_wlan_ex *)malloc(sizeof(ipacm_event_data_wlan_ex) + event_ex_o.num_of_attribs * sizeof(ipa_wlan_hdr_attrib_val)); if (data_ex == NULL) { IPACMERR("unable to allocate memory for event data\n"); return NULL; } data_ex->num_of_attribs = event_ex->num_of_attribs; memcpy(data_ex->attribs, event_ex->attribs, event_ex->num_of_attribs * sizeof(ipa_wlan_hdr_attrib_val)); for(cnt = 0; cnt < event_ex->num_of_attribs; cnt++) { if(event_ex->attribs[cnt].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR) { IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n", event_ex->attribs[cnt].u.mac_addr[0], event_ex->attribs[cnt].u.mac_addr[1], event_ex->attribs[cnt].u.mac_addr[2], event_ex->attribs[cnt].u.mac_addr[3], event_ex->attribs[cnt].u.mac_addr[4], event_ex->attribs[cnt].u.mac_addr[5]); } else if(event_ex->attribs[cnt].attrib_type == WLAN_HDR_ATTRIB_STA_ID) { IPACMDBG_H("Wlan client id %d\n",event_ex->attribs[cnt].u.sta_id); } else { IPACMDBG_H("Wlan message has unexpected type!\n"); } } ipa_get_if_index(event_ex->name, &(data_ex->if_index)); evt_data.event = IPA_WLAN_CLIENT_ADD_EVENT_EX; evt_data.evt_data = data_ex; free(event_ex); break; case WLAN_CLIENT_DISCONNECT: IPACMDBG_H("Received WLAN_CLIENT_DISCONNECT\n"); event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta)); IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n", event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2], event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]); data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac)); if (data == NULL) { IPACMERR("unable to allocate memory for event_wlan data\n"); return NULL; } memcpy(data->mac_addr, event_wlan->mac_addr, sizeof(event_wlan->mac_addr)); ipa_get_if_index(event_wlan->name, &(data->if_index)); evt_data.event = IPA_WLAN_CLIENT_DEL_EVENT; evt_data.evt_data = data; break; case WLAN_CLIENT_POWER_SAVE_MODE: IPACMDBG_H("Received WLAN_CLIENT_POWER_SAVE_MODE\n"); event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta)); IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n", event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2], event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]); data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac)); if (data == NULL) { IPACMERR("unable to allocate memory for event_wlan data\n"); return NULL; } memcpy(data->mac_addr, event_wlan->mac_addr, sizeof(event_wlan->mac_addr)); ipa_get_if_index(event_wlan->name, &(data->if_index)); evt_data.event = IPA_WLAN_CLIENT_POWER_SAVE_EVENT; evt_data.evt_data = data; break; case WLAN_CLIENT_NORMAL_MODE: IPACMDBG_H("Received WLAN_CLIENT_NORMAL_MODE\n"); event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta)); IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n", event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2], event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]); data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac)); if (data == NULL) { IPACMERR("unable to allocate memory for event_wlan data\n"); return NULL; } memcpy(data->mac_addr, event_wlan->mac_addr, sizeof(event_wlan->mac_addr)); ipa_get_if_index(event_wlan->name, &(data->if_index)); evt_data.evt_data = data; evt_data.event = IPA_WLAN_CLIENT_RECOVER_EVENT; break; case ECM_CONNECT: memcpy(&event_ecm, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_ecm_msg)); IPACMDBG_H("Received ECM_CONNECT name: %s\n",event_ecm.name); data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid)); if(data_fid == NULL) { IPACMERR("unable to allocate memory for event_ecm data_fid\n"); return NULL; } data_fid->if_index = event_ecm.ifindex; evt_data.event = IPA_USB_LINK_UP_EVENT; evt_data.evt_data = data_fid; break; case ECM_DISCONNECT: memcpy(&event_ecm, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_ecm_msg)); IPACMDBG_H("Received ECM_DISCONNECT name: %s\n",event_ecm.name); data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid)); if(data_fid == NULL) { IPACMERR("unable to allocate memory for event_ecm data_fid\n"); return NULL; } data_fid->if_index = event_ecm.ifindex; evt_data.event = IPA_LINK_DOWN_EVENT; evt_data.evt_data = data_fid; break; /* Add for 8994 Android case */ case WAN_UPSTREAM_ROUTE_ADD: memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_wan_msg)); IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_ADD name: %s, tethered name: %s\n", event_wan.upstream_ifname, event_wan.tethered_ifname); data_iptype = (ipacm_event_data_iptype *)malloc(sizeof(ipacm_event_data_iptype)); if(data_iptype == NULL) { IPACMERR("unable to allocate memory for event_ecm data_iptype\n"); return NULL; } ipa_get_if_index(event_wan.upstream_ifname, &(data_iptype->if_index)); ipa_get_if_index(event_wan.tethered_ifname, &(data_iptype->if_index_tether)); data_iptype->iptype = event_wan.ip; IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_ADD: fid(%d) tether_fid(%d) ip-type(%d)\n", data_iptype->if_index, data_iptype->if_index_tether, data_iptype->iptype); evt_data.event = IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT; evt_data.evt_data = data_iptype; break; case WAN_UPSTREAM_ROUTE_DEL: memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_wan_msg)); IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_DEL name: %s, tethered name: %s\n", event_wan.upstream_ifname, event_wan.tethered_ifname); data_iptype = (ipacm_event_data_iptype *)malloc(sizeof(ipacm_event_data_iptype)); if(data_iptype == NULL) { IPACMERR("unable to allocate memory for event_ecm data_iptype\n"); return NULL; } ipa_get_if_index(event_wan.upstream_ifname, &(data_iptype->if_index)); ipa_get_if_index(event_wan.tethered_ifname, &(data_iptype->if_index_tether)); data_iptype->iptype = event_wan.ip; IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_DEL: fid(%d) ip-type(%d)\n", data_iptype->if_index, data_iptype->iptype); evt_data.event = IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT; evt_data.evt_data = data_iptype; break; /* End of adding for 8994 Android case */ /* Add for embms case */ case WAN_EMBMS_CONNECT: memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_wan_msg)); IPACMDBG("Received WAN_EMBMS_CONNECT name: %s\n",event_wan.upstream_ifname); data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid)); if(data_fid == NULL) { IPACMERR("unable to allocate memory for event data_fid\n"); return NULL; } ipa_get_if_index(event_wan.upstream_ifname, &(data_fid->if_index)); evt_data.event = IPA_WAN_EMBMS_LINK_UP_EVENT; evt_data.evt_data = data_fid; break; case IPA_TETHERING_STATS_UPDATE_STATS: memcpy(&event_data_stats, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_get_data_stats_resp_msg_v01)); data_tethering_stats = (ipa_get_data_stats_resp_msg_v01 *)malloc(sizeof(struct ipa_get_data_stats_resp_msg_v01)); if(data_tethering_stats == NULL) { IPACMERR("unable to allocate memory for event data_tethering_stats\n"); return NULL; } memcpy(data_tethering_stats, &event_data_stats, sizeof(struct ipa_get_data_stats_resp_msg_v01)); IPACMDBG("Received IPA_TETHERING_STATS_UPDATE_STATS ipa_stats_type: %d\n",data_tethering_stats->ipa_stats_type); IPACMDBG("Received %d UL, %d DL pipe stats\n",data_tethering_stats->ul_src_pipe_stats_list_len, data_tethering_stats->dl_dst_pipe_stats_list_len); evt_data.event = IPA_TETHERING_STATS_UPDATE_EVENT; evt_data.evt_data = data_tethering_stats; break; case IPA_TETHERING_STATS_UPDATE_NETWORK_STATS: memcpy(&event_network_stats, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_get_apn_data_stats_resp_msg_v01)); data_network_stats = (ipa_get_apn_data_stats_resp_msg_v01 *)malloc(sizeof(ipa_get_apn_data_stats_resp_msg_v01)); if(data_network_stats == NULL) { IPACMERR("unable to allocate memory for event data_network_stats\n"); return NULL; } memcpy(data_network_stats, &event_network_stats, sizeof(struct ipa_get_apn_data_stats_resp_msg_v01)); IPACMDBG("Received %d apn network stats \n", data_network_stats->apn_data_stats_list_len); evt_data.event = IPA_NETWORK_STATS_UPDATE_EVENT; evt_data.evt_data = data_network_stats; break; default: IPACMDBG_H("Unhandled message type: %d\n", event_hdr.msg_type); continue; } /* finish command queue */ IPACMDBG_H("Posting event:%d\n", evt_data.event); IPACM_EvtDispatcher::PostEvt(&evt_data); } (void)close(fd); return NULL; } void IPACM_Sig_Handler(int sig) { int cnt; ipacm_cmd_q_data evt_data; printf("Received Signal: %d\n", sig); memset(&evt_data, 0, sizeof(evt_data)); switch(sig) { case SIGUSR1: IPACMDBG_H("Received SW_ROUTING_ENABLE request \n"); evt_data.event = IPA_SW_ROUTING_ENABLE; IPACM_Iface::ipacmcfg->ipa_sw_rt_enable = true; break; case SIGUSR2: IPACMDBG_H("Received SW_ROUTING_DISABLE request \n"); evt_data.event = IPA_SW_ROUTING_DISABLE; IPACM_Iface::ipacmcfg->ipa_sw_rt_enable = false; break; } /* finish command queue */ IPACMDBG_H("Posting event:%d\n", evt_data.event); IPACM_EvtDispatcher::PostEvt(&evt_data); return; } void RegisterForSignals(void) { signal(SIGUSR1, IPACM_Sig_Handler); signal(SIGUSR2, IPACM_Sig_Handler); } int main(int argc, char **argv) { int ret; pthread_t netlink_thread = 0, monitor_thread = 0, ipa_driver_thread = 0; pthread_t cmd_queue_thread = 0; /* check if ipacm is already running or not */ ipa_is_ipacm_running(); IPACMDBG_H("In main()\n"); IPACM_Neighbor *neigh = new IPACM_Neighbor(); IPACM_IfaceManager *ifacemgr = new IPACM_IfaceManager(); #ifndef FEATURE_ETH_BRIDGE_LE #ifndef FEATURE_IPA_ANDROID IPACM_LanToLan* lan2lan = new IPACM_LanToLan(); #endif /* defined(FEATURE_IPA_ANDROID)*/ #endif IPACM_ConntrackClient *cc = IPACM_ConntrackClient::GetInstance(); CtList = new IPACM_ConntrackListener(); IPACMDBG_H("Staring IPA main\n"); IPACMDBG_H("ipa_cmdq_successful\n"); RegisterForSignals(); if (IPACM_SUCCESS == cmd_queue_thread) { ret = pthread_create(&cmd_queue_thread, NULL, MessageQueue::Process, NULL); if (IPACM_SUCCESS != ret) { IPACMERR("unable to command queue thread\n"); return ret; } IPACMDBG_H("created command queue thread\n"); } if (IPACM_SUCCESS == netlink_thread) { ret = pthread_create(&netlink_thread, NULL, netlink_start, NULL); if (IPACM_SUCCESS != ret) { IPACMERR("unable to create netlink thread\n"); return ret; } IPACMDBG_H("created netlink thread\n"); } if (IPACM_SUCCESS == monitor_thread) { ret = pthread_create(&monitor_thread, NULL, firewall_monitor, NULL); if (IPACM_SUCCESS != ret) { IPACMERR("unable to create monitor thread\n"); return ret; } IPACMDBG_H("created firewall monitor thread\n"); } if (IPACM_SUCCESS == ipa_driver_thread) { ret = pthread_create(&ipa_driver_thread, NULL, ipa_driver_wlan_notifier, NULL); if (IPACM_SUCCESS != ret) { IPACMERR("unable to create ipa_driver_wlan thread\n"); return ret; } IPACMDBG_H("created ipa_driver_wlan thread\n"); } pthread_join(cmd_queue_thread, NULL); pthread_join(netlink_thread, NULL); pthread_join(monitor_thread, NULL); pthread_join(ipa_driver_thread, NULL); return IPACM_SUCCESS; } /*=========================================================================== FUNCTION ipa_is_ipacm_running ===========================================================================*/ /*! @brief Determine whether there's already an IPACM process running, if so, terminate the current one @return None @note - Dependencies - None - Side Effects - None */ /*=========================================================================*/ void ipa_is_ipacm_running(void) { int fd; struct flock lock; int retval; fd = open(IPACM_PID_FILE, O_RDWR | O_CREAT, 0600); if ( fd <= 0 ) { IPACMERR("Failed to open %s, error is %d - %s\n", IPACM_PID_FILE, errno, strerror(errno)); exit(0); } /* * Getting an exclusive Write lock on the file, if it fails, * it means that another instance of IPACM is running and it * got the lock before us. */ memset(&lock, 0, sizeof(lock)); lock.l_type = F_WRLCK; retval = fcntl(fd, F_SETLK, &lock); if (retval != 0) { retval = fcntl(fd, F_GETLK, &lock); if (retval == 0) { IPACMERR("Unable to get lock on file %s (my PID %d), PID %d already has it\n", IPACM_PID_FILE, getpid(), lock.l_pid); close(fd); exit(0); } } else { IPACMERR("PID %d is IPACM main process\n", getpid()); } return; } /*=========================================================================== FUNCTION ipa_get_if_index ===========================================================================*/ /*! @brief get ipa interface index by given the interface name @return IPACM_SUCCESS or IPA_FALUIRE @note - Dependencies - None - Side Effects - None */ /*=========================================================================*/ int ipa_get_if_index ( char *if_name, int *if_index ) { int fd; struct ifreq ifr; if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { PERROR("get interface index socket create failed"); return IPACM_FAILURE; } memset(&ifr, 0, sizeof(struct ifreq)); (void)strncpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name)); if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) { IPACMERR("call_ioctl_on_dev: ioctl failed: can't find device %s",if_name); *if_index = -1; close(fd); return IPACM_FAILURE; } *if_index = ifr.ifr_ifindex; close(fd); return IPACM_SUCCESS; } ================================================ FILE: data-ipa-cfg-mgr/ipacm/src/IPACM_Neighbor.cpp ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPACM_Neighbor.cpp @brief This file implements the functionality of handling IPACM Neighbor events. @Author Skylar Chang */ #include #include #include #include "IPACM_Defs.h" #include "IPACM_Log.h" IPACM_Neighbor::IPACM_Neighbor() { num_neighbor_client = 0; IPACM_EvtDispatcher::registr(IPA_WLAN_CLIENT_ADD_EVENT_EX, this); IPACM_EvtDispatcher::registr(IPA_NEW_NEIGH_EVENT, this); IPACM_EvtDispatcher::registr(IPA_DEL_NEIGH_EVENT, this); return; } void IPACM_Neighbor::event_callback(ipa_cm_event_id event, void *param) { ipacm_event_data_all *data_all = NULL; int i, ipa_interface_index; ipacm_cmd_q_data evt_data; int num_neighbor_client_temp = num_neighbor_client; IPACMDBG("Recieved event %d\n", event); switch (event) { case IPA_WLAN_CLIENT_ADD_EVENT_EX: { ipacm_event_data_wlan_ex *data = (ipacm_event_data_wlan_ex *)param; ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data->if_index); uint8_t client_mac_addr[6]; IPACMDBG_H("Received IPA_WLAN_CLIENT_ADD_EVENT\n"); for(i = 0; i < data->num_of_attribs; i++) { if(data->attribs[i].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR) { memcpy(client_mac_addr, data->attribs[i].u.mac_addr, sizeof(client_mac_addr)); IPACMDBG_H("AP Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n", client_mac_addr[0], client_mac_addr[1], client_mac_addr[2], client_mac_addr[3], client_mac_addr[4], client_mac_addr[5]); } else { IPACMDBG_H("The attribute type is not expected!\n"); } } for (i = 0; i < num_neighbor_client_temp; i++) { /* find the client */ if (memcmp(neighbor_client[i].mac_addr, client_mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0) { /* check if iface is not bridge interface*/ if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name) != 0) { /* use previous ipv4 first */ if(data->if_index != neighbor_client[i].iface_index) { IPACMERR("update new kernel iface index \n"); neighbor_client[i].iface_index = data->if_index; } /* check if client associated with previous network interface */ if(ipa_interface_index != neighbor_client[i].ipa_if_num) { IPACMERR("client associate to different AP \n"); return; } if (neighbor_client[i].v4_addr != 0) /* not 0.0.0.0 */ { evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT; data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all)); if (data_all == NULL) { IPACMERR("Unable to allocate memory\n"); return; } data_all->iptype = IPA_IP_v4; data_all->if_index = neighbor_client[i].iface_index; data_all->ipv4_addr = neighbor_client[i].v4_addr; //use previous ipv4 address memcpy(data_all->mac_addr, neighbor_client[i].mac_addr, sizeof(data_all->mac_addr)); evt_data.evt_data = (void *)data_all; IPACM_EvtDispatcher::PostEvt(&evt_data); /* ask for replaced iface name*/ ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data_all->if_index); IPACMDBG_H("Posted event %d, with %s for ipv4 client re-connect\n", evt_data.event, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name); } } break; } } } break; default: { ipacm_event_data_all *data = (ipacm_event_data_all *)param; ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data->if_index); if (data->iptype == IPA_IP_v4) { if (data->ipv4_addr != 0) /* not 0.0.0.0 */ { IPACMDBG(" Got New_Neighbor event with ipv4 address \n"); /* check if iface is bridge interface*/ if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name) == 0) { /* searh if seen this client or not*/ for (i = 0; i < num_neighbor_client_temp; i++) { if (memcmp(neighbor_client[i].mac_addr, data->mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0) { data->if_index = neighbor_client[i].iface_index; neighbor_client[i].v4_addr = data->ipv4_addr; // cache client's previous ipv4 address /* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */ if (event == IPA_NEW_NEIGH_EVENT) evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT; else evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT; data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all)); if (data_all == NULL) { IPACMERR("Unable to allocate memory\n"); return; } memcpy(data_all, data, sizeof(ipacm_event_data_all)); evt_data.evt_data = (void *)data_all; IPACM_EvtDispatcher::PostEvt(&evt_data); /* ask for replaced iface name*/ ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data_all->if_index); IPACMDBG_H("Posted event %d, with %s for ipv4\n", evt_data.event, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name); break; }; } } else { /* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */ if (event == IPA_NEW_NEIGH_EVENT) evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT; else evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT; data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all)); if (data_all == NULL) { IPACMERR("Unable to allocate memory\n"); return; } memcpy(data_all, data, sizeof(ipacm_event_data_all)); evt_data.evt_data = (void *)data_all; IPACM_EvtDispatcher::PostEvt(&evt_data); IPACMDBG_H("Posted event %d with %s for ipv4\n", evt_data.event, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name); /* Also save to cache for ipv4 */ /*searh if seen this client or not*/ for (i = 0; i < num_neighbor_client_temp; i++) { /* find the client */ if (memcmp(neighbor_client[i].mac_addr, data->mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0) { /* update the network interface client associated */ neighbor_client[i].iface_index = data->if_index; neighbor_client[i].ipa_if_num = ipa_interface_index; neighbor_client[i].v4_addr = data->ipv4_addr; // cache client's previous ipv4 address IPACMDBG_H("update cache %d-entry, with %s iface, ipv4 address: 0x%x\n", i, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name, data->ipv4_addr); break; } } /* not find client */ if (i == num_neighbor_client_temp) { if (num_neighbor_client_temp < IPA_MAX_NUM_NEIGHBOR_CLIENTS) { memcpy(neighbor_client[num_neighbor_client_temp].mac_addr, data->mac_addr, sizeof(data->mac_addr)); neighbor_client[num_neighbor_client_temp].iface_index = data->if_index; /* cache the network interface client associated */ neighbor_client[num_neighbor_client_temp].ipa_if_num = ipa_interface_index; neighbor_client[num_neighbor_client_temp].v4_addr = data->ipv4_addr; IPACMDBG_H("Cache wlan-iface client MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d\n", neighbor_client[num_neighbor_client_temp].mac_addr[0], neighbor_client[num_neighbor_client_temp].mac_addr[1], neighbor_client[num_neighbor_client_temp].mac_addr[2], neighbor_client[num_neighbor_client_temp].mac_addr[3], neighbor_client[num_neighbor_client_temp].mac_addr[4], neighbor_client[num_neighbor_client_temp].mac_addr[5], num_neighbor_client); num_neighbor_client++; return; } else { IPACMERR("error: neighbor client oversize!"); return; } } } } } else { //ipv6 starts if ((data->ipv6_addr[0]) || (data->ipv6_addr[1]) || (data->ipv6_addr[2]) || (data->ipv6_addr[3])) { IPACMDBG(" Got New_Neighbor event with ipv6 address \n"); /* check if iface is bridge interface*/ if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name) == 0) { /* searh if seen this client or not*/ for (i = 0; i < num_neighbor_client_temp; i++) { if (memcmp(neighbor_client[i].mac_addr, data->mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0) { data->if_index = neighbor_client[i].iface_index; /* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */ if (event == IPA_NEW_NEIGH_EVENT) evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT; else evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT; data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all)); if (data_all == NULL) { IPACMERR("Unable to allocate memory\n"); return; } memcpy(data_all, data, sizeof(ipacm_event_data_all)); evt_data.evt_data = (void *)data_all; IPACM_EvtDispatcher::PostEvt(&evt_data); /* ask for replaced iface name*/ ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data_all->if_index); IPACMDBG_H("Posted event %d, with %s for ipv6\n", evt_data.event, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name); break; }; } } else { /* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */ if (event == IPA_NEW_NEIGH_EVENT) evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT; else evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT; data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all)); if (data_all == NULL) { IPACMERR("Unable to allocate memory\n"); return; } memcpy(data_all, data, sizeof(ipacm_event_data_all)); evt_data.evt_data = (void *)data_all; IPACM_EvtDispatcher::PostEvt(&evt_data); IPACMDBG_H("Posted event %d with %s for ipv6\n", evt_data.event, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name); } } else { IPACMDBG(" Got New_Neighbor event with no ipv6/ipv4 address \n"); /*no ipv6 in data searh if seen this client or not*/ for (i = 0; i < num_neighbor_client_temp; i++) { /* find the client */ if (memcmp(neighbor_client[i].mac_addr, data->mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0) { /* check if iface is not bridge interface*/ if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name) != 0) { /* use previous ipv4 first */ if(data->if_index != neighbor_client[i].iface_index) { IPACMERR("update new kernel iface index \n"); neighbor_client[i].iface_index = data->if_index; } /* check if client associated with previous network interface */ if(ipa_interface_index != neighbor_client[i].ipa_if_num) { IPACMERR("client associate to different AP \n"); return; } if (neighbor_client[i].v4_addr != 0) /* not 0.0.0.0 */ { evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT; data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all)); if (data_all == NULL) { IPACMERR("Unable to allocate memory\n"); return; } data_all->iptype = IPA_IP_v4; data_all->if_index = neighbor_client[i].iface_index; data_all->ipv4_addr = neighbor_client[i].v4_addr; //use previous ipv4 address memcpy(data_all->mac_addr, neighbor_client[i].mac_addr, sizeof(data_all->mac_addr)); evt_data.evt_data = (void *)data_all; IPACM_EvtDispatcher::PostEvt(&evt_data); /* ask for replaced iface name*/ ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data_all->if_index); IPACMDBG_H("Posted event %d, with %s for ipv4 client re-connect\n", evt_data.event, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name); } } break; } } /* not find client */ if (i == num_neighbor_client_temp) { /* check if iface is not bridge interface*/ if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name) != 0) { if (num_neighbor_client_temp < IPA_MAX_NUM_NEIGHBOR_CLIENTS) { memcpy(neighbor_client[num_neighbor_client_temp].mac_addr, data->mac_addr, sizeof(data->mac_addr)); neighbor_client[num_neighbor_client_temp].iface_index = data->if_index; /* cache the network interface client associated */ neighbor_client[num_neighbor_client_temp].ipa_if_num = ipa_interface_index; neighbor_client[num_neighbor_client_temp].v4_addr = 0; IPACMDBG_H("Copy wlan-iface client MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d\n", neighbor_client[num_neighbor_client_temp].mac_addr[0], neighbor_client[num_neighbor_client_temp].mac_addr[1], neighbor_client[num_neighbor_client_temp].mac_addr[2], neighbor_client[num_neighbor_client_temp].mac_addr[3], neighbor_client[num_neighbor_client_temp].mac_addr[4], neighbor_client[num_neighbor_client_temp].mac_addr[5], num_neighbor_client); num_neighbor_client++; return; } else { IPACMERR("error: neighbor client oversize!"); return; } } } } } //ipv6 ends } break; } return; } ================================================ FILE: data-ipa-cfg-mgr/ipacm/src/IPACM_Netlink.cpp ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPACM_Netlink.cpp @brief This file implements the IPAM Netlink Socket Parer functionality. @Author Skylar Chang */ #include #include #include #include #include "IPACM_CmdQueue.h" #include "IPACM_Defs.h" #include "IPACM_Netlink.h" #include "IPACM_EvtDispatcher.h" #include "IPACM_Log.h" int ipa_get_if_name(char *if_name, int if_index); int find_mask(int ip_v4_last, int *mask_value); #ifdef FEATURE_IPA_ANDROID #define IPACM_NL_COPY_ADDR( event_info, element ) \ memcpy( &event_info->attr_info.element.__data, \ RTA_DATA(rtah), \ sizeof(event_info->attr_info.element.__data) ); #define IPACM_EVENT_COPY_ADDR_v6( event_data, element) \ memcpy( event_data, element.__data, sizeof(event_data)); #define IPACM_EVENT_COPY_ADDR_v4( event_data, element) \ memcpy( &event_data, element.__data, sizeof(event_data)); #define IPACM_NL_REPORT_ADDR( prefix, addr ) \ if( AF_INET6 == (addr).ss_family ) { \ IPACM_LOG_IPV6_ADDR( prefix, addr.__data); \ } else { \ IPACM_LOG_IPV4_ADDR( prefix, (*(unsigned int*)&(addr).__data) ); \ } #else/* defined(FEATURE_IPA_ANDROID) */ #define IPACM_NL_COPY_ADDR( event_info, element ) \ memcpy( &event_info->attr_info.element.__ss_padding, \ RTA_DATA(rtah), \ sizeof(event_info->attr_info.element.__ss_padding) ); #define IPACM_EVENT_COPY_ADDR_v6( event_data, element) \ memcpy( event_data, element.__ss_padding, sizeof(event_data)); #define IPACM_EVENT_COPY_ADDR_v4( event_data, element) \ memcpy( &event_data, element.__ss_padding, sizeof(event_data)); #define IPACM_NL_REPORT_ADDR( prefix, addr ) \ if( AF_INET6 == (addr).ss_family ) { \ IPACM_LOG_IPV6_ADDR( prefix, addr.__ss_padding); \ } else { \ IPACM_LOG_IPV4_ADDR( prefix, (*(unsigned int*)&(addr).__ss_padding) ); \ } #endif /* defined(FEATURE_IPA_ANDROID)*/ #define NDA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg)))) #define IPACM_LOG_IPV6_ADDR(prefix, ip_addr) \ IPACMDBG_H(prefix); \ IPACMDBG_H(" IPV6 Address %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n", \ (int)ip_addr[0], (int)ip_addr[1], \ (int)ip_addr[2], (int)ip_addr[3], \ (int)ip_addr[4], (int)ip_addr[5], \ (int)ip_addr[6], (int)ip_addr[7], \ (int)ip_addr[8], (int)ip_addr[9], \ (int)ip_addr[10], (int)ip_addr[11], \ (int)ip_addr[12], (int)ip_addr[13], \ (int)ip_addr[14], (int)ip_addr[15]); #define IPACM_LOG_IPV4_ADDR(prefix, ip_addr) \ IPACMDBG_H(prefix); \ IPACMDBG_H(" IPV4 Address %d.%d.%d.%d\n", \ (unsigned char)(ip_addr), \ (unsigned char)(ip_addr >> 8), \ (unsigned char)(ip_addr >> 16) , \ (unsigned char)(ip_addr >> 24)); /* Opens a netlink socket*/ static int ipa_nl_open_socket ( ipa_nl_sk_info_t *sk_info, int protocol, unsigned int grps ) { int *p_sk_fd; int buf_size = 6669999, sendbuff=0, res; struct sockaddr_nl *p_sk_addr_loc; socklen_t optlen; p_sk_fd = &(sk_info->sk_fd); p_sk_addr_loc = &(sk_info->sk_addr_loc); /* Open netlink socket for specified protocol */ if((*p_sk_fd = socket(AF_NETLINK, SOCK_RAW, protocol)) < 0) { IPACMERR("cannot open netlink socket\n"); return IPACM_FAILURE; } optlen = sizeof(sendbuff); res = getsockopt(*p_sk_fd, SOL_SOCKET, SO_SNDBUF, &sendbuff, &optlen); if(res == -1) { IPACMDBG("Error getsockopt one"); } else { IPACMDBG("orignal send buffer size = %d\n", sendbuff); } IPACMDBG("sets the send buffer to %d\n", buf_size); if (setsockopt(*p_sk_fd, SOL_SOCKET, SO_RCVBUF, &buf_size, sizeof(int)) == -1) { IPACMERR("Error setting socket opts\n"); } /* Initialize socket addresses to null */ memset(p_sk_addr_loc, 0, sizeof(struct sockaddr_nl)); /* Populate local socket address using specified groups */ p_sk_addr_loc->nl_family = AF_NETLINK; p_sk_addr_loc->nl_pid = getpid(); p_sk_addr_loc->nl_groups = grps; /* Bind socket to the local address, i.e. specified groups. This ensures that multicast messages for these groups are delivered over this socket. */ if(bind(*p_sk_fd, (struct sockaddr *)p_sk_addr_loc, sizeof(struct sockaddr_nl)) < 0) { IPACMERR("Socket bind failed\n"); return IPACM_FAILURE; } return IPACM_SUCCESS; } /* Add fd to fdmap array and store read handler function ptr (up to MAX_NUM_OF_FD).*/ static int ipa_nl_addfd_map ( ipa_nl_sk_fd_set_info_t *info, int fd, ipa_sock_thrd_fd_read_f read_f ) { if(info->num_fd < MAX_NUM_OF_FD) { FD_SET(fd, &info->fdset); /* Add fd to fdmap array and store read handler function ptr */ info->sk_fds[info->num_fd].sk_fd = fd; info->sk_fds[info->num_fd].read_func = read_f; /* Increment number of fds stored in fdmap */ info->num_fd++; if(info->max_fd < fd) info->max_fd = fd; } else { return IPACM_FAILURE; } return IPACM_SUCCESS; } /* start socket listener */ static int ipa_nl_sock_listener_start ( ipa_nl_sk_fd_set_info_t *sk_fd_set ) { int i, ret; while(true) { for(i = 0; i < sk_fd_set->num_fd; i++ ) { FD_SET(sk_fd_set->sk_fds[i].sk_fd, &(sk_fd_set->fdset)); } if((ret = select(sk_fd_set->max_fd + 1, &(sk_fd_set->fdset), NULL, NULL, NULL)) < 0) { IPACMERR("ipa_nl select failed\n"); } else { for(i = 0; i < sk_fd_set->num_fd; i++) { if(FD_ISSET(sk_fd_set->sk_fds[i].sk_fd, &(sk_fd_set->fdset))) { if(sk_fd_set->sk_fds[i].read_func) { if(IPACM_SUCCESS != ((sk_fd_set->sk_fds[i].read_func)(sk_fd_set->sk_fds[i].sk_fd))) { IPACMERR("Error on read callback[%d] fd=%d\n", i, sk_fd_set->sk_fds[i].sk_fd); } FD_CLR(sk_fd_set->sk_fds[i].sk_fd, &(sk_fd_set->fdset)); } else { IPACMERR("No read function\n"); } } } /* end of for loop*/ } /* end of else */ } /* end of while */ return IPACM_SUCCESS; } /* allocate memory for ipa_nl__msg */ static struct msghdr* ipa_nl_alloc_msg ( uint32_t msglen ) { unsigned char *buf = NULL; struct sockaddr_nl *nladdr = NULL; struct iovec *iov = NULL; struct msghdr *msgh = NULL; if(IPA_NL_MSG_MAX_LEN < msglen) { IPACMERR("Netlink message exceeds maximum length\n"); return NULL; } msgh = (struct msghdr *)malloc(sizeof(struct msghdr)); if(msgh == NULL) { IPACMERR("Failed malloc for msghdr\n"); return NULL; } nladdr = (struct sockaddr_nl *)malloc(sizeof(struct sockaddr_nl)); if(nladdr == NULL) { IPACMERR("Failed malloc for sockaddr\n"); free(msgh); return NULL; } iov = (struct iovec *)malloc(sizeof(struct iovec)); if(iov == NULL) { PERROR("Failed malloc for iovec"); free(nladdr); free(msgh); return NULL; } buf = (unsigned char *)malloc(msglen); if(buf == NULL) { IPACMERR("Failed malloc for mglen\n"); free(iov); free(nladdr); free(msgh); return NULL; } memset(nladdr, 0, sizeof(struct sockaddr_nl)); nladdr->nl_family = AF_NETLINK; memset(msgh, 0x0, sizeof(struct msghdr)); msgh->msg_name = nladdr; msgh->msg_namelen = sizeof(struct sockaddr_nl); msgh->msg_iov = iov; msgh->msg_iovlen = 1; memset(iov, 0x0, sizeof(struct iovec)); iov->iov_base = buf; iov->iov_len = msglen; return msgh; } /* release IPA message */ static void ipa_nl_release_msg ( struct msghdr *msgh ) { unsigned char *buf = NULL; struct sockaddr_nl *nladdr = NULL; struct iovec *iov = NULL; if(NULL == msgh) { return; } nladdr = (struct sockaddr_nl *)msgh->msg_name; iov = msgh->msg_iov; if(msgh->msg_iov) { buf = (unsigned char *)msgh->msg_iov->iov_base; } if(buf) { free(buf); } if(iov) { free(iov); } if(nladdr) { free(nladdr); } if(msgh) { free(msgh); } return; } /* receive and process nl message */ static int ipa_nl_recv ( int fd, struct msghdr **msg_pptr, unsigned int *msglen_ptr ) { struct msghdr *msgh = NULL; int rmsgl; msgh = ipa_nl_alloc_msg(IPA_NL_MSG_MAX_LEN); if(NULL == msgh) { IPACMERR("Failed to allocate NL message\n"); goto error; } /* Receive message over the socket */ rmsgl = recvmsg(fd, msgh, 0); /* Verify that something was read */ if(rmsgl <= 0) { PERROR("NL recv error"); goto error; } /* Verify that NL address length in the received message is expected value */ if(sizeof(struct sockaddr_nl) != msgh->msg_namelen) { IPACMERR("rcvd msg with namelen != sizeof sockaddr_nl\n"); goto error; } /* Verify that message was not truncated. This should not occur */ if(msgh->msg_flags & MSG_TRUNC) { IPACMERR("Rcvd msg truncated!\n"); goto error; } *msg_pptr = msgh; *msglen_ptr = rmsgl; return IPACM_SUCCESS; /* An error occurred while receiving the message. Free all memory before returning. */ error: ipa_nl_release_msg(msgh); *msg_pptr = NULL; *msglen_ptr = 0; return IPACM_FAILURE; } /* decode the rtm netlink message */ static int ipa_nl_decode_rtm_link ( const char *buffer, unsigned int buflen, ipa_nl_link_info_t *link_info ) { struct rtattr; /* NL message header */ struct nlmsghdr *nlh = (struct nlmsghdr *)buffer; /* Extract the header data */ link_info->metainfo = *(struct ifinfomsg *)NLMSG_DATA(nlh); buflen -= sizeof(struct nlmsghdr); return IPACM_SUCCESS; } /* Decode kernel address message parameters from Netlink attribute TLVs. */ static int ipa_nl_decode_rtm_addr ( const char *buffer, unsigned int buflen, ipa_nl_addr_info_t *addr_info ) { struct nlmsghdr *nlh = (struct nlmsghdr *)buffer; /* NL message header */ struct rtattr *rtah = NULL; /* Extract the header data */ addr_info->metainfo = *((struct ifaddrmsg *)NLMSG_DATA(nlh)); buflen -= sizeof(struct nlmsghdr); /* Extract the available attributes */ addr_info->attr_info.param_mask = IPA_NLA_PARAM_NONE; rtah = IFA_RTA(NLMSG_DATA(nlh)); while(RTA_OK(rtah, buflen)) { switch(rtah->rta_type) { case IFA_ADDRESS: addr_info->attr_info.prefix_addr.ss_family = addr_info->metainfo.ifa_family; IPACM_NL_COPY_ADDR( addr_info, prefix_addr ); addr_info->attr_info.param_mask |= IPA_NLA_PARAM_PREFIXADDR; break; default: break; } /* Advance to next attribute */ rtah = RTA_NEXT(rtah, buflen); } return IPACM_SUCCESS; } /* Decode kernel neighbor message parameters from Netlink attribute TLVs. */ static int ipa_nl_decode_rtm_neigh ( const char *buffer, unsigned int buflen, ipa_nl_neigh_info_t *neigh_info ) { struct nlmsghdr *nlh = (struct nlmsghdr *)buffer; /* NL message header */ struct rtattr *rtah = NULL; /* Extract the header data */ neigh_info->metainfo = *((struct ndmsg *)NLMSG_DATA(nlh)); buflen -= sizeof(struct nlmsghdr); /* Extract the available attributes */ neigh_info->attr_info.param_mask = IPA_NLA_PARAM_NONE; rtah = NDA_RTA(NLMSG_DATA(nlh)); while(RTA_OK(rtah, buflen)) { switch(rtah->rta_type) { case NDA_DST: neigh_info->attr_info.local_addr.ss_family = neigh_info->metainfo.ndm_family; IPACM_NL_COPY_ADDR( neigh_info, local_addr ); break; case NDA_LLADDR: memcpy(neigh_info->attr_info.lladdr_hwaddr.sa_data, RTA_DATA(rtah), sizeof(neigh_info->attr_info.lladdr_hwaddr.sa_data)); break; default: break; } /* Advance to next attribute */ rtah = RTA_NEXT(rtah, buflen); } return IPACM_SUCCESS; } /* Decode kernel route message parameters from Netlink attribute TLVs. */ static int ipa_nl_decode_rtm_route ( const char *buffer, unsigned int buflen, ipa_nl_route_info_t *route_info ) { struct nlmsghdr *nlh = (struct nlmsghdr *)buffer; /* NL message header */ struct rtattr *rtah = NULL; /* Extract the header data */ route_info->metainfo = *((struct rtmsg *)NLMSG_DATA(nlh)); buflen -= sizeof(struct nlmsghdr); route_info->attr_info.param_mask = IPA_RTA_PARAM_NONE; rtah = RTM_RTA(NLMSG_DATA(nlh)); while(RTA_OK(rtah, buflen)) { switch(rtah->rta_type) { case RTA_DST: route_info->attr_info.dst_addr.ss_family = route_info->metainfo.rtm_family; IPACM_NL_COPY_ADDR( route_info, dst_addr ); route_info->attr_info.param_mask |= IPA_RTA_PARAM_DST; break; case RTA_SRC: route_info->attr_info.src_addr.ss_family = route_info->metainfo.rtm_family; IPACM_NL_COPY_ADDR( route_info, src_addr ); route_info->attr_info.param_mask |= IPA_RTA_PARAM_SRC; break; case RTA_GATEWAY: route_info->attr_info.gateway_addr.ss_family = route_info->metainfo.rtm_family; IPACM_NL_COPY_ADDR( route_info, gateway_addr ); route_info->attr_info.param_mask |= IPA_RTA_PARAM_GATEWAY; break; case RTA_IIF: memcpy(&route_info->attr_info.iif_index, RTA_DATA(rtah), sizeof(route_info->attr_info.iif_index)); route_info->attr_info.param_mask |= IPA_RTA_PARAM_IIF; break; case RTA_OIF: memcpy(&route_info->attr_info.oif_index, RTA_DATA(rtah), sizeof(route_info->attr_info.oif_index)); route_info->attr_info.param_mask |= IPA_RTA_PARAM_OIF; break; case RTA_PRIORITY: memcpy(&route_info->attr_info.priority, RTA_DATA(rtah), sizeof(route_info->attr_info.priority)); route_info->attr_info.param_mask |= IPA_RTA_PARAM_PRIORITY; break; default: break; } /* Advance to next attribute */ rtah = RTA_NEXT(rtah, buflen); } return IPACM_SUCCESS; } /* decode the ipa nl-message */ static int ipa_nl_decode_nlmsg ( const char *buffer, unsigned int buflen, ipa_nl_msg_t *msg_ptr ) { char dev_name[IF_NAME_LEN]={0}; int ret_val, mask_value, mask_index, mask_value_v6; struct nlmsghdr *nlh = (struct nlmsghdr *)buffer; uint32_t if_ipv4_addr =0, if_ipipv4_addr_mask =0, temp =0; ipacm_cmd_q_data evt_data; ipacm_event_data_all *data_all; ipacm_event_data_fid *data_fid; ipacm_event_data_addr *data_addr; while(NLMSG_OK(nlh, buflen)) { memset(dev_name,0,IF_NAME_LEN); IPACMDBG("Received msg:%d from netlink\n", nlh->nlmsg_type) switch(nlh->nlmsg_type) { case RTM_NEWLINK: msg_ptr->type = nlh->nlmsg_type; msg_ptr->link_event = true; if(IPACM_SUCCESS != ipa_nl_decode_rtm_link(buffer, buflen, &(msg_ptr->nl_link_info))) { IPACMERR("Failed to decode rtm link message\n"); return IPACM_FAILURE; } else { IPACMDBG("Got RTM_NEWLINK with below values\n"); IPACMDBG("RTM_NEWLINK, ifi_change:%d\n", msg_ptr->nl_link_info.metainfo.ifi_change); IPACMDBG("RTM_NEWLINK, ifi_flags:%d\n", msg_ptr->nl_link_info.metainfo.ifi_flags); IPACMDBG("RTM_NEWLINK, ifi_index:%d\n", msg_ptr->nl_link_info.metainfo.ifi_index); IPACMDBG("RTM_NEWLINK, family:%d\n", msg_ptr->nl_link_info.metainfo.ifi_family); if (msg_ptr->nl_link_info.metainfo.ifi_family == AF_BRIDGE) { IPACMERR(" ignore this RTM_NEWLINK msg \n"); return IPACM_SUCCESS; } if(IFF_UP & msg_ptr->nl_link_info.metainfo.ifi_change) { IPACMDBG("GOT useful newlink event\n"); ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_link_info.metainfo.ifi_index); if(ret_val != IPACM_SUCCESS) { IPACMERR("Error while getting interface name\n"); return IPACM_FAILURE; } data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid)); if(data_fid == NULL) { IPACMERR("unable to allocate memory for event data_fid\n"); return IPACM_FAILURE; } data_fid->if_index = msg_ptr->nl_link_info.metainfo.ifi_index; if(msg_ptr->nl_link_info.metainfo.ifi_flags & IFF_UP) { IPACMDBG_H("Interface %s bring up with IP-family: %d \n", dev_name, msg_ptr->nl_link_info.metainfo.ifi_family); /* post link up to command queue */ evt_data.event = IPA_LINK_UP_EVENT; IPACMDBG_H("Posting IPA_LINK_UP_EVENT with if index: %d\n", msg_ptr->nl_link_info.metainfo.ifi_index); } else { IPACMDBG_H("Interface %s bring down with IP-family: %d \n", dev_name, msg_ptr->nl_link_info.metainfo.ifi_family); /* post link down to command queue */ evt_data.event = IPA_LINK_DOWN_EVENT; IPACMDBG_H("Posting IPA_LINK_DOWN_EVENT with if index: %d\n", data_fid->if_index); } evt_data.evt_data = data_fid; IPACM_EvtDispatcher::PostEvt(&evt_data); } /* Add IPACM support for ECM plug-in/plug_out */ /*-------------------------------------------------------------------------- Check if the interface is running.If its a RTM_NEWLINK and the interface is running then it means that its a link up event ---------------------------------------------------------------------------*/ if((msg_ptr->nl_link_info.metainfo.ifi_flags & IFF_RUNNING) && (msg_ptr->nl_link_info.metainfo.ifi_flags & IFF_LOWER_UP)) { data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid)); if(data_fid == NULL) { IPACMERR("unable to allocate memory for event data_fid\n"); return IPACM_FAILURE; } data_fid->if_index = msg_ptr->nl_link_info.metainfo.ifi_index; ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_link_info.metainfo.ifi_index); if(ret_val != IPACM_SUCCESS) { IPACMERR("Error while getting interface name\n"); return IPACM_FAILURE; } IPACMDBG("Got a usb link_up event (Interface %s, %d) \n", dev_name, msg_ptr->nl_link_info.metainfo.ifi_index); /*-------------------------------------------------------------------------- Post LAN iface (ECM) link up event ---------------------------------------------------------------------------*/ evt_data.event = IPA_USB_LINK_UP_EVENT; evt_data.evt_data = data_fid; IPACM_EvtDispatcher::PostEvt(&evt_data); IPACMDBG("Posting usb IPA_LINK_UP_EVENT with if index: %d\n", data_fid->if_index); } else if(!(msg_ptr->nl_link_info.metainfo.ifi_flags & IFF_LOWER_UP)) { data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid)); if(data_fid == NULL) { IPACMERR("unable to allocate memory for event data_fid\n"); return IPACM_FAILURE; } data_fid->if_index = msg_ptr->nl_link_info.metainfo.ifi_index; ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_link_info.metainfo.ifi_index); if(ret_val != IPACM_SUCCESS) { IPACMERR("Error while getting interface name\n"); return IPACM_FAILURE; } IPACMDBG_H("Got a usb link_down event (Interface %s) \n", dev_name); /*-------------------------------------------------------------------------- Post LAN iface (ECM) link down event ---------------------------------------------------------------------------*/ evt_data.event = IPA_LINK_DOWN_EVENT; evt_data.evt_data = data_fid; IPACM_EvtDispatcher::PostEvt(&evt_data); IPACMDBG_H("Posting usb IPA_LINK_DOWN_EVENT with if index: %d\n", data_fid->if_index); } } break; case RTM_DELLINK: IPACMDBG("\n GOT dellink event\n"); msg_ptr->type = nlh->nlmsg_type; msg_ptr->link_event = true; IPACMDBG("entering rtm decode\n"); if(IPACM_SUCCESS != ipa_nl_decode_rtm_link(buffer, buflen, &(msg_ptr->nl_link_info))) { IPACMERR("Failed to decode rtm link message\n"); return IPACM_FAILURE; } else { IPACMDBG("Got RTM_DELLINK with below values\n"); IPACMDBG("RTM_DELLINK, ifi_change:%d\n", msg_ptr->nl_link_info.metainfo.ifi_change); IPACMDBG("RTM_DELLINK, ifi_flags:%d\n", msg_ptr->nl_link_info.metainfo.ifi_flags); IPACMDBG("RTM_DELLINK, ifi_index:%d\n", msg_ptr->nl_link_info.metainfo.ifi_index); IPACMDBG("RTM_DELLINK, family:%d\n", msg_ptr->nl_link_info.metainfo.ifi_family); if (msg_ptr->nl_link_info.metainfo.ifi_family == AF_BRIDGE) { IPACMERR(" ignore this RTM_DELLINK msg \n"); return IPACM_SUCCESS; } ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_link_info.metainfo.ifi_index); if(ret_val != IPACM_SUCCESS) { IPACMERR("Error while getting interface name\n"); return IPACM_FAILURE; } IPACMDBG("Interface %s bring down \n", dev_name); /* post link down to command queue */ evt_data.event = IPA_LINK_DOWN_EVENT; data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid)); if(data_fid == NULL) { IPACMERR("unable to allocate memory for event data_fid\n"); return IPACM_FAILURE; } data_fid->if_index = msg_ptr->nl_link_info.metainfo.ifi_index; IPACMDBG_H("posting IPA_LINK_DOWN_EVENT with if idnex:%d\n", data_fid->if_index); evt_data.evt_data = data_fid; IPACM_EvtDispatcher::PostEvt(&evt_data); /* finish command queue */ } break; case RTM_NEWADDR: IPACMDBG("\n GOT RTM_NEWADDR event\n"); if(IPACM_SUCCESS != ipa_nl_decode_rtm_addr(buffer, buflen, &(msg_ptr->nl_addr_info))) { IPACMERR("Failed to decode rtm addr message\n"); return IPACM_FAILURE; } else { ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_addr_info.metainfo.ifa_index); if(ret_val != IPACM_SUCCESS) { IPACMERR("Error while getting interface name\n"); } IPACMDBG("Interface %s \n", dev_name); data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr)); if(data_addr == NULL) { IPACMERR("unable to allocate memory for event data_addr\n"); return IPACM_FAILURE; } if(AF_INET6 == msg_ptr->nl_addr_info.attr_info.prefix_addr.ss_family) { data_addr->iptype = IPA_IP_v6; IPACM_NL_REPORT_ADDR( "IFA_ADDRESS:", msg_ptr->nl_addr_info.attr_info.prefix_addr ); IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr, msg_ptr->nl_addr_info.attr_info.prefix_addr); data_addr->ipv6_addr[0] = ntohl(data_addr->ipv6_addr[0]); data_addr->ipv6_addr[1] = ntohl(data_addr->ipv6_addr[1]); data_addr->ipv6_addr[2] = ntohl(data_addr->ipv6_addr[2]); data_addr->ipv6_addr[3] = ntohl(data_addr->ipv6_addr[3]); } else { data_addr->iptype = IPA_IP_v4; IPACM_NL_REPORT_ADDR( "IFA_ADDRESS:", msg_ptr->nl_addr_info.attr_info.prefix_addr ); IPACM_EVENT_COPY_ADDR_v4( data_addr->ipv4_addr, msg_ptr->nl_addr_info.attr_info.prefix_addr); data_addr->ipv4_addr = ntohl(data_addr->ipv4_addr); } evt_data.event = IPA_ADDR_ADD_EVENT; data_addr->if_index = msg_ptr->nl_addr_info.metainfo.ifa_index; if(AF_INET6 == msg_ptr->nl_addr_info.attr_info.prefix_addr.ss_family) { IPACMDBG("Posting IPA_ADDR_ADD_EVENT with if index:%d, ipv6 addr:0x%x:%x:%x:%x\n", data_addr->if_index, data_addr->ipv6_addr[0], data_addr->ipv6_addr[1], data_addr->ipv6_addr[2], data_addr->ipv6_addr[3]); } else { IPACMDBG("Posting IPA_ADDR_ADD_EVENT with if index:%d, ipv4 addr:0x%x\n", data_addr->if_index, data_addr->ipv4_addr); } evt_data.evt_data = data_addr; IPACM_EvtDispatcher::PostEvt(&evt_data); } break; case RTM_NEWROUTE: if(IPACM_SUCCESS != ipa_nl_decode_rtm_route(buffer, buflen, &(msg_ptr->nl_route_info))) { IPACMERR("Failed to decode rtm route message\n"); return IPACM_FAILURE; } IPACMDBG("In case RTM_NEWROUTE\n"); IPACMDBG("rtm_type: %d\n", msg_ptr->nl_route_info.metainfo.rtm_type); IPACMDBG("rtm_type: %d\n", msg_ptr->nl_route_info.metainfo.rtm_type); IPACMDBG("protocol: %d\n", msg_ptr->nl_route_info.metainfo.rtm_protocol); IPACMDBG("rtm_scope: %d\n", msg_ptr->nl_route_info.metainfo.rtm_scope); IPACMDBG("rtm_table: %d\n", msg_ptr->nl_route_info.metainfo.rtm_table); IPACMDBG("rtm_family: %d\n", msg_ptr->nl_route_info.metainfo.rtm_family); IPACMDBG("param_mask: 0x%x\n", msg_ptr->nl_route_info.attr_info.param_mask); /* take care of route add default route & uniroute */ if((msg_ptr->nl_route_info.metainfo.rtm_type == RTN_UNICAST) && (msg_ptr->nl_route_info.metainfo.rtm_protocol == RTPROT_BOOT) && (msg_ptr->nl_route_info.metainfo.rtm_scope == RT_SCOPE_UNIVERSE) && (msg_ptr->nl_route_info.metainfo.rtm_table == RT_TABLE_MAIN)) { IPACMDBG("\n GOT RTM_NEWROUTE event\n"); if(msg_ptr->nl_route_info.attr_info.param_mask & IPA_RTA_PARAM_DST) { ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_route_info.attr_info.oif_index); if(ret_val != IPACM_SUCCESS) { IPACMERR("Error while getting interface name\n"); return IPACM_FAILURE; } IPACM_NL_REPORT_ADDR( "route add -host", msg_ptr->nl_route_info.attr_info.dst_addr ); IPACM_NL_REPORT_ADDR( "gw", msg_ptr->nl_route_info.attr_info.gateway_addr ); IPACMDBG("dev %s\n",dev_name ); /* insert to command queue */ IPACM_EVENT_COPY_ADDR_v4( if_ipv4_addr, msg_ptr->nl_route_info.attr_info.dst_addr); temp = (-1); evt_data.event = IPA_ROUTE_ADD_EVENT; data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr)); if(data_addr == NULL) { IPACMERR("unable to allocate memory for event data_addr\n"); return IPACM_FAILURE; } data_addr->if_index = msg_ptr->nl_route_info.attr_info.oif_index; data_addr->iptype = IPA_IP_v4; data_addr->ipv4_addr = ntohl(if_ipv4_addr); data_addr->ipv4_addr_mask = ntohl(if_ipipv4_addr_mask); IPACMDBG("Posting IPA_ROUTE_ADD_EVENT with if index:%d, ipv4 address 0x%x, mask:0x%x\n", data_addr->if_index, data_addr->ipv4_addr, data_addr->ipv4_addr_mask); evt_data.evt_data = data_addr; IPACM_EvtDispatcher::PostEvt(&evt_data); /* finish command queue */ } else { ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_route_info.attr_info.oif_index); if(ret_val != IPACM_SUCCESS) { IPACMERR("Error while getting interface name\n"); return IPACM_FAILURE; } if(AF_INET6 == msg_ptr->nl_route_info.metainfo.rtm_family) { /* insert to command queue */ data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr)); if(data_addr == NULL) { IPACMERR("unable to allocate memory for event data_addr\n"); return IPACM_FAILURE; } if(msg_ptr->nl_route_info.attr_info.param_mask & IPA_RTA_PARAM_PRIORITY) { IPACMDBG_H("ip -6 route add default dev %s metric %d\n", dev_name, msg_ptr->nl_route_info.attr_info.priority); } else { IPACMDBG_H("ip -6 route add default dev %s\n", dev_name); } IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr, msg_ptr->nl_route_info.attr_info.dst_addr); data_addr->ipv6_addr[0] = ntohl(data_addr->ipv6_addr[0]); data_addr->ipv6_addr[1] = ntohl(data_addr->ipv6_addr[1]); data_addr->ipv6_addr[2] = ntohl(data_addr->ipv6_addr[2]); data_addr->ipv6_addr[3] = ntohl(data_addr->ipv6_addr[3]); IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr_mask, msg_ptr->nl_route_info.attr_info.dst_addr); data_addr->ipv6_addr_mask[0] = ntohl(data_addr->ipv6_addr_mask[0]); data_addr->ipv6_addr_mask[1] = ntohl(data_addr->ipv6_addr_mask[1]); data_addr->ipv6_addr_mask[2] = ntohl(data_addr->ipv6_addr_mask[2]); data_addr->ipv6_addr_mask[3] = ntohl(data_addr->ipv6_addr_mask[3]); evt_data.event = IPA_ROUTE_ADD_EVENT; data_addr->if_index = msg_ptr->nl_route_info.attr_info.oif_index; data_addr->iptype = IPA_IP_v6; IPACMDBG("Posting IPA_ROUTE_ADD_EVENT with if index:%d, ipv6 address\n", data_addr->if_index); evt_data.evt_data = data_addr; IPACM_EvtDispatcher::PostEvt(&evt_data); /* finish command queue */ } else { IPACM_NL_REPORT_ADDR( "route add default gw \n", msg_ptr->nl_route_info.attr_info.gateway_addr ); IPACMDBG_H("dev %s \n", dev_name); IPACM_NL_REPORT_ADDR( "dstIP:", msg_ptr->nl_route_info.attr_info.dst_addr ); /* insert to command queue */ data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr)); if(data_addr == NULL) { IPACMERR("unable to allocate memory for event data_addr\n"); return IPACM_FAILURE; } IPACM_EVENT_COPY_ADDR_v4( if_ipv4_addr, msg_ptr->nl_route_info.attr_info.dst_addr); IPACM_EVENT_COPY_ADDR_v4( if_ipipv4_addr_mask, msg_ptr->nl_route_info.attr_info.dst_addr); evt_data.event = IPA_ROUTE_ADD_EVENT; data_addr->if_index = msg_ptr->nl_route_info.attr_info.oif_index; data_addr->iptype = IPA_IP_v4; data_addr->ipv4_addr = ntohl(if_ipv4_addr); data_addr->ipv4_addr_mask = ntohl(if_ipipv4_addr_mask); IPACMDBG_H("Posting IPA_ROUTE_ADD_EVENT with if index:%d, ipv4 addr:0x%x and maxk: 0x%x\n", data_addr->if_index, data_addr->ipv4_addr, data_addr->ipv4_addr_mask); evt_data.evt_data = data_addr; IPACM_EvtDispatcher::PostEvt(&evt_data); /* finish command queue */ } } } /* ipv6 routing table */ if((AF_INET6 == msg_ptr->nl_route_info.metainfo.rtm_family) && (msg_ptr->nl_route_info.metainfo.rtm_type == RTN_UNICAST) && (msg_ptr->nl_route_info.metainfo.rtm_protocol == RTPROT_KERNEL) && (msg_ptr->nl_route_info.metainfo.rtm_table == RT_TABLE_MAIN)) { IPACMDBG("\n GOT valid v6-RTM_NEWROUTE event\n"); ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_route_info.attr_info.oif_index); if(ret_val != IPACM_SUCCESS) { IPACMERR("Error while getting interface name\n"); return IPACM_FAILURE; } if(msg_ptr->nl_route_info.attr_info.param_mask & IPA_RTA_PARAM_DST) { IPACM_NL_REPORT_ADDR( "Route ADD DST:", msg_ptr->nl_route_info.attr_info.dst_addr ); IPACMDBG("%d, metric %d, dev %s\n", msg_ptr->nl_route_info.metainfo.rtm_dst_len, msg_ptr->nl_route_info.attr_info.priority, dev_name); /* insert to command queue */ data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr)); if(data_addr == NULL) { IPACMERR("unable to allocate memory for event data_addr\n"); return IPACM_FAILURE; } IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr, msg_ptr->nl_route_info.attr_info.dst_addr); data_addr->ipv6_addr[0] = ntohl(data_addr->ipv6_addr[0]); data_addr->ipv6_addr[1] = ntohl(data_addr->ipv6_addr[1]); data_addr->ipv6_addr[2] = ntohl(data_addr->ipv6_addr[2]); data_addr->ipv6_addr[3] = ntohl(data_addr->ipv6_addr[3]); mask_value_v6 = msg_ptr->nl_route_info.metainfo.rtm_dst_len; for(mask_index = 0; mask_index < 4; mask_index++) { if(mask_value_v6 >= 32) { mask_v6(32, &data_addr->ipv6_addr_mask[mask_index]); mask_value_v6 -= 32; } else { mask_v6(mask_value_v6, &data_addr->ipv6_addr_mask[mask_index]); mask_value_v6 = 0; } } IPACMDBG("ADD IPV6 MASK %d: %08x:%08x:%08x:%08x \n", msg_ptr->nl_route_info.metainfo.rtm_dst_len, data_addr->ipv6_addr_mask[0], data_addr->ipv6_addr_mask[1], data_addr->ipv6_addr_mask[2], data_addr->ipv6_addr_mask[3]); data_addr->ipv6_addr_mask[0] = ntohl(data_addr->ipv6_addr_mask[0]); data_addr->ipv6_addr_mask[1] = ntohl(data_addr->ipv6_addr_mask[1]); data_addr->ipv6_addr_mask[2] = ntohl(data_addr->ipv6_addr_mask[2]); data_addr->ipv6_addr_mask[3] = ntohl(data_addr->ipv6_addr_mask[3]); evt_data.event = IPA_ROUTE_ADD_EVENT; data_addr->if_index = msg_ptr->nl_route_info.attr_info.oif_index; data_addr->iptype = IPA_IP_v6; IPACMDBG("Posting IPA_ROUTE_ADD_EVENT with if index:%d, ipv6 addr\n", data_addr->if_index); evt_data.evt_data = data_addr; IPACM_EvtDispatcher::PostEvt(&evt_data); /* finish command queue */ } if(msg_ptr->nl_route_info.attr_info.param_mask & IPA_RTA_PARAM_GATEWAY) { IPACM_NL_REPORT_ADDR( "Route ADD ::/0 Next Hop:", msg_ptr->nl_route_info.attr_info.gateway_addr ); IPACMDBG(" metric %d, dev %s\n", msg_ptr->nl_route_info.attr_info.priority, dev_name); /* insert to command queue */ data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr)); if(data_addr == NULL) { IPACMERR("unable to allocate memory for event data_addr\n"); return IPACM_FAILURE; } IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr, msg_ptr->nl_route_info.attr_info.dst_addr); data_addr->ipv6_addr[0]=ntohl(data_addr->ipv6_addr[0]); data_addr->ipv6_addr[1]=ntohl(data_addr->ipv6_addr[1]); data_addr->ipv6_addr[2]=ntohl(data_addr->ipv6_addr[2]); data_addr->ipv6_addr[3]=ntohl(data_addr->ipv6_addr[3]); IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr_mask, msg_ptr->nl_route_info.attr_info.dst_addr); data_addr->ipv6_addr_mask[0]=ntohl(data_addr->ipv6_addr_mask[0]); data_addr->ipv6_addr_mask[1]=ntohl(data_addr->ipv6_addr_mask[1]); data_addr->ipv6_addr_mask[2]=ntohl(data_addr->ipv6_addr_mask[2]); data_addr->ipv6_addr_mask[3]=ntohl(data_addr->ipv6_addr_mask[3]); evt_data.event = IPA_ROUTE_ADD_EVENT; data_addr->if_index = msg_ptr->nl_route_info.attr_info.oif_index; data_addr->iptype = IPA_IP_v6; IPACMDBG("posting IPA_ROUTE_ADD_EVENT with if index:%d, ipv6 address\n", data_addr->if_index); evt_data.evt_data = data_addr; IPACM_EvtDispatcher::PostEvt(&evt_data); /* finish command queue */ } } break; case RTM_DELROUTE: if(IPACM_SUCCESS != ipa_nl_decode_rtm_route(buffer, buflen, &(msg_ptr->nl_route_info))) { IPACMERR("Failed to decode rtm route message\n"); return IPACM_FAILURE; } /* take care of route delete of default route & uniroute */ if((msg_ptr->nl_route_info.metainfo.rtm_type == RTN_UNICAST) && (msg_ptr->nl_route_info.metainfo.rtm_protocol == RTPROT_BOOT) && (msg_ptr->nl_route_info.metainfo.rtm_scope == 0) && (msg_ptr->nl_route_info.metainfo.rtm_table == RT_TABLE_MAIN)) { if(msg_ptr->nl_route_info.attr_info.param_mask & IPA_RTA_PARAM_DST) { ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_route_info.attr_info.oif_index); if(ret_val != IPACM_SUCCESS) { IPACMERR("Error while getting interface name\n"); return IPACM_FAILURE; } IPACM_NL_REPORT_ADDR( "route del -host ", msg_ptr->nl_route_info.attr_info.dst_addr); IPACM_NL_REPORT_ADDR( " gw ", msg_ptr->nl_route_info.attr_info.gateway_addr); IPACMDBG("dev %s\n", dev_name); /* insert to command queue */ data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr)); if(data_addr == NULL) { IPACMERR("unable to allocate memory for event data_addr\n"); return IPACM_FAILURE; } IPACM_EVENT_COPY_ADDR_v4( if_ipv4_addr, msg_ptr->nl_route_info.attr_info.dst_addr); temp = (-1); if_ipipv4_addr_mask = ntohl(temp); evt_data.event = IPA_ROUTE_DEL_EVENT; data_addr->if_index = msg_ptr->nl_route_info.attr_info.oif_index; data_addr->iptype = IPA_IP_v4; data_addr->ipv4_addr = ntohl(if_ipv4_addr); data_addr->ipv4_addr_mask = ntohl(if_ipipv4_addr_mask); IPACMDBG_H("Posting event IPA_ROUTE_DEL_EVENT with if index:%d, ipv4 address 0x%x, mask:0x%x\n", data_addr->if_index, data_addr->ipv4_addr, data_addr->ipv4_addr_mask); evt_data.evt_data = data_addr; IPACM_EvtDispatcher::PostEvt(&evt_data); /* finish command queue */ } else { ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_route_info.attr_info.oif_index); if(ret_val != IPACM_SUCCESS) { IPACMERR("Error while getting interface name\n"); return IPACM_FAILURE; } /* insert to command queue */ data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr)); if(data_addr == NULL) { IPACMERR("unable to allocate memory for event data_addr\n"); return IPACM_FAILURE; } if(AF_INET6 == msg_ptr->nl_route_info.metainfo.rtm_family) { if(msg_ptr->nl_route_info.attr_info.param_mask & IPA_RTA_PARAM_PRIORITY) { IPACMDBG("ip -6 route del default dev %s metric %d\n", dev_name, msg_ptr->nl_route_info.attr_info.priority); } else { IPACMDBG("ip -6 route del default dev %s\n", dev_name); } IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr, msg_ptr->nl_route_info.attr_info.dst_addr); data_addr->ipv6_addr[0] = ntohl(data_addr->ipv6_addr[0]); data_addr->ipv6_addr[1] = ntohl(data_addr->ipv6_addr[1]); data_addr->ipv6_addr[2] = ntohl(data_addr->ipv6_addr[2]); data_addr->ipv6_addr[3] = ntohl(data_addr->ipv6_addr[3]); IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr_mask, msg_ptr->nl_route_info.attr_info.dst_addr); data_addr->ipv6_addr_mask[0] = ntohl(data_addr->ipv6_addr_mask[0]); data_addr->ipv6_addr_mask[1] = ntohl(data_addr->ipv6_addr_mask[1]); data_addr->ipv6_addr_mask[2] = ntohl(data_addr->ipv6_addr_mask[2]); data_addr->ipv6_addr_mask[3] = ntohl(data_addr->ipv6_addr_mask[3]); data_addr->iptype = IPA_IP_v6; } else { IPACM_NL_REPORT_ADDR( "route del default gw", msg_ptr->nl_route_info.attr_info.gateway_addr); IPACMDBG("dev %s\n", dev_name); IPACM_EVENT_COPY_ADDR_v4( data_addr->ipv4_addr, msg_ptr->nl_route_info.attr_info.dst_addr); data_addr->ipv4_addr = ntohl(data_addr->ipv4_addr); IPACM_EVENT_COPY_ADDR_v4( data_addr->ipv4_addr_mask, msg_ptr->nl_route_info.attr_info.dst_addr); data_addr->ipv4_addr_mask = ntohl(data_addr->ipv4_addr_mask); data_addr->iptype = IPA_IP_v4; } evt_data.event = IPA_ROUTE_DEL_EVENT; data_addr->if_index = msg_ptr->nl_route_info.attr_info.oif_index; IPACMDBG_H("Posting IPA_ROUTE_DEL_EVENT with if index:%d\n", data_addr->if_index); evt_data.evt_data = data_addr; IPACM_EvtDispatcher::PostEvt(&evt_data); /* finish command queue */ } } /* ipv6 routing table */ if((AF_INET6 == msg_ptr->nl_route_info.metainfo.rtm_family) && (msg_ptr->nl_route_info.metainfo.rtm_type == RTN_UNICAST) && (msg_ptr->nl_route_info.metainfo.rtm_protocol == RTPROT_KERNEL) && (msg_ptr->nl_route_info.metainfo.rtm_table == RT_TABLE_MAIN)) { IPACMDBG("\n GOT valid v6-RTM_DELROUTE event\n"); ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_route_info.attr_info.oif_index); if(ret_val != IPACM_SUCCESS) { IPACMERR("Error while getting interface name"); return IPACM_FAILURE; } if(msg_ptr->nl_route_info.attr_info.param_mask & IPA_RTA_PARAM_DST) { IPACM_NL_REPORT_ADDR( "DEL", msg_ptr->nl_route_info.attr_info.dst_addr); IPACMDBG("/%d, metric %d, dev %s\n", msg_ptr->nl_route_info.metainfo.rtm_dst_len, msg_ptr->nl_route_info.attr_info.priority, dev_name); /* insert to command queue */ data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr)); if(data_addr == NULL) { IPACMERR("unable to allocate memory for event data_addr\n"); return IPACM_FAILURE; } IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr, msg_ptr->nl_route_info.attr_info.dst_addr); data_addr->ipv6_addr[0] = ntohl(data_addr->ipv6_addr[0]); data_addr->ipv6_addr[1] = ntohl(data_addr->ipv6_addr[1]); data_addr->ipv6_addr[2] = ntohl(data_addr->ipv6_addr[2]); data_addr->ipv6_addr[3] = ntohl(data_addr->ipv6_addr[3]); mask_value_v6 = msg_ptr->nl_route_info.metainfo.rtm_dst_len; for(mask_index = 0; mask_index < 4; mask_index++) { IPACMDBG("%dst %d \n", mask_index, mask_value_v6); if(mask_value_v6 >= 32) { mask_v6(32, &data_addr->ipv6_addr_mask[mask_index]); mask_value_v6 -= 32; IPACMDBG("%dst: %08x \n", mask_index, data_addr->ipv6_addr_mask[mask_index]); } else { mask_v6(mask_value_v6, data_addr->ipv6_addr_mask); mask_value_v6 = 0; IPACMDBG("%dst: %08x \n", mask_index, data_addr->ipv6_addr_mask[mask_index]); } } IPACMDBG("DEL IPV6 MASK 0st: %08x ", data_addr->ipv6_addr_mask[0]); IPACMDBG("1st: %08x ", data_addr->ipv6_addr_mask[1]); IPACMDBG("2st: %08x ", data_addr->ipv6_addr_mask[2]); IPACMDBG("3st: %08x \n", data_addr->ipv6_addr_mask[3]); data_addr->ipv6_addr_mask[0] = ntohl(data_addr->ipv6_addr_mask[0]); data_addr->ipv6_addr_mask[1] = ntohl(data_addr->ipv6_addr_mask[1]); data_addr->ipv6_addr_mask[2] = ntohl(data_addr->ipv6_addr_mask[2]); data_addr->ipv6_addr_mask[3] = ntohl(data_addr->ipv6_addr_mask[3]); evt_data.event = IPA_ROUTE_DEL_EVENT; data_addr->if_index = msg_ptr->nl_route_info.attr_info.oif_index; data_addr->iptype = IPA_IP_v6; IPACMDBG_H("posting event IPA_ROUTE_DEL_EVENT with if index:%d, ipv4 address\n", data_addr->if_index); evt_data.evt_data = data_addr; IPACM_EvtDispatcher::PostEvt(&evt_data); /* finish command queue */ } } break; case RTM_NEWNEIGH: if(IPACM_SUCCESS != ipa_nl_decode_rtm_neigh(buffer, buflen, &(msg_ptr->nl_neigh_info))) { IPACMERR("Failed to decode rtm neighbor message\n"); return IPACM_FAILURE; } ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_neigh_info.metainfo.ndm_ifindex); if(ret_val != IPACM_SUCCESS) { IPACMERR("Error while getting interface index\n"); return IPACM_FAILURE; } else { IPACMDBG("\n GOT RTM_NEWNEIGH event (%s) ip %d\n",dev_name,msg_ptr->nl_neigh_info.attr_info.local_addr.ss_family); } /* insert to command queue */ data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all)); if(data_all == NULL) { IPACMERR("unable to allocate memory for event data_all\n"); return IPACM_FAILURE; } memset(data_all, 0, sizeof(ipacm_event_data_all)); if(msg_ptr->nl_neigh_info.attr_info.local_addr.ss_family == AF_INET6) { IPACM_NL_REPORT_ADDR( " ", msg_ptr->nl_neigh_info.attr_info.local_addr); IPACM_EVENT_COPY_ADDR_v6( data_all->ipv6_addr, msg_ptr->nl_neigh_info.attr_info.local_addr); data_all->ipv6_addr[0]=ntohl(data_all->ipv6_addr[0]); data_all->ipv6_addr[1]=ntohl(data_all->ipv6_addr[1]); data_all->ipv6_addr[2]=ntohl(data_all->ipv6_addr[2]); data_all->ipv6_addr[3]=ntohl(data_all->ipv6_addr[3]); data_all->iptype = IPA_IP_v6; } else if (msg_ptr->nl_neigh_info.attr_info.local_addr.ss_family == AF_INET) { IPACM_NL_REPORT_ADDR( " ", msg_ptr->nl_neigh_info.attr_info.local_addr); IPACM_EVENT_COPY_ADDR_v4( data_all->ipv4_addr, msg_ptr->nl_neigh_info.attr_info.local_addr); data_all->ipv4_addr = ntohl(data_all->ipv4_addr); data_all->iptype = IPA_IP_v4; } else { data_all->iptype = IPA_IP_v6; } IPACMDBG("NDA_LLADDR:MAC %02x:%02x:%02x:%02x:%02x:%02x\n", (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[0], (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[1], (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[2], (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[3], (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[4], (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[5]); memcpy(data_all->mac_addr, msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr.sa_data, sizeof(data_all->mac_addr)); evt_data.event = IPA_NEW_NEIGH_EVENT; data_all->if_index = msg_ptr->nl_neigh_info.metainfo.ndm_ifindex; IPACMDBG_H("posting IPA_NEW_NEIGH_EVENT (%s):index:%d ip-family: %d\n", dev_name, data_all->if_index, msg_ptr->nl_neigh_info.attr_info.local_addr.ss_family); evt_data.evt_data = data_all; IPACM_EvtDispatcher::PostEvt(&evt_data); /* finish command queue */ break; case RTM_DELNEIGH: if(IPACM_SUCCESS != ipa_nl_decode_rtm_neigh(buffer, buflen, &(msg_ptr->nl_neigh_info))) { IPACMERR("Failed to decode rtm neighbor message\n"); return IPACM_FAILURE; } ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_neigh_info.metainfo.ndm_ifindex); if(ret_val != IPACM_SUCCESS) { IPACMERR("Error while getting interface index\n"); return IPACM_FAILURE; } else { IPACMDBG("\n GOT RTM_DELNEIGH event (%s) ip %d\n",dev_name,msg_ptr->nl_neigh_info.attr_info.local_addr.ss_family); } /* insert to command queue */ data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all)); if(data_all == NULL) { IPACMERR("unable to allocate memory for event data_all\n"); return IPACM_FAILURE; } memset(data_all, 0, sizeof(ipacm_event_data_all)); if(msg_ptr->nl_neigh_info.attr_info.local_addr.ss_family == AF_INET6) { IPACM_NL_REPORT_ADDR( " ", msg_ptr->nl_neigh_info.attr_info.local_addr); IPACM_EVENT_COPY_ADDR_v6( data_all->ipv6_addr, msg_ptr->nl_neigh_info.attr_info.local_addr); data_all->ipv6_addr[0] = ntohl(data_all->ipv6_addr[0]); data_all->ipv6_addr[1] = ntohl(data_all->ipv6_addr[1]); data_all->ipv6_addr[2] = ntohl(data_all->ipv6_addr[2]); data_all->ipv6_addr[3] = ntohl(data_all->ipv6_addr[3]); data_all->iptype = IPA_IP_v6; } else if (msg_ptr->nl_neigh_info.attr_info.local_addr.ss_family == AF_INET) { IPACM_NL_REPORT_ADDR( " ", msg_ptr->nl_neigh_info.attr_info.local_addr); IPACM_EVENT_COPY_ADDR_v4( data_all->ipv4_addr, msg_ptr->nl_neigh_info.attr_info.local_addr); data_all->ipv4_addr = ntohl(data_all->ipv4_addr); data_all->iptype = IPA_IP_v4; } else { data_all->iptype = IPA_IP_v6; } IPACMDBG("NDA_LLADDR:MAC %02x:%02x:%02x:%02x:%02x:%02x\n", (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[0], (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[1], (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[2], (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[3], (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[4], (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[5]); memcpy(data_all->mac_addr, msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr.sa_data, sizeof(data_all->mac_addr)); evt_data.event = IPA_DEL_NEIGH_EVENT; data_all->if_index = msg_ptr->nl_neigh_info.metainfo.ndm_ifindex; IPACMDBG_H("posting IPA_DEL_NEIGH_EVENT (%s):index:%d ip-family: %d\n", dev_name, data_all->if_index, msg_ptr->nl_neigh_info.attr_info.local_addr.ss_family); evt_data.evt_data = data_all; IPACM_EvtDispatcher::PostEvt(&evt_data); /* finish command queue */ break; default: IPACMDBG(" ignore NL event %d!!!\n ", nlh->nlmsg_type); break; } nlh = NLMSG_NEXT(nlh, buflen); } return IPACM_SUCCESS; } /* Virtual function registered to receive incoming messages over the NETLINK routing socket*/ int ipa_nl_recv_msg(int fd) { struct msghdr *msghdr = NULL; struct iovec *iov = NULL; unsigned int msglen = 0; ipa_nl_msg_t *nlmsg = NULL; nlmsg = (ipa_nl_msg_t *)malloc(sizeof(ipa_nl_msg_t)); if(NULL == nlmsg) { IPACMERR("Failed alloc of nlmsg \n"); goto error; } else { if(IPACM_SUCCESS != ipa_nl_recv(fd, &msghdr, &msglen)) { IPACMERR("Failed to receive nl message \n"); goto error; } if(msghdr== NULL) { IPACMERR(" failed to get msghdr\n"); goto error; } iov = msghdr->msg_iov; memset(nlmsg, 0, sizeof(ipa_nl_msg_t)); if(IPACM_SUCCESS != ipa_nl_decode_nlmsg((char *)iov->iov_base, msglen, nlmsg)) { IPACMERR("Failed to decode nl message \n"); goto error; } /* Release NetLink message buffer */ if(msghdr) { ipa_nl_release_msg(msghdr); } if(nlmsg) { free(nlmsg); } } return IPACM_SUCCESS; error: if(msghdr) { ipa_nl_release_msg(msghdr); } if(nlmsg) { free(nlmsg); } return IPACM_FAILURE; } /* get ipa interface name */ int ipa_get_if_name ( char *if_name, int if_index ) { int fd; struct ifreq ifr; if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { IPACMERR("get interface name socket create failed \n"); return IPACM_FAILURE; } memset(&ifr, 0, sizeof(struct ifreq)); ifr.ifr_ifindex = if_index; IPACMDBG("Interface index %d\n", if_index); if(ioctl(fd, SIOCGIFNAME, &ifr) < 0) { IPACMERR("call_ioctl_on_dev: ioctl failed:\n"); close(fd); return IPACM_FAILURE; } (void)strncpy(if_name, ifr.ifr_name, sizeof(ifr.ifr_name)); IPACMDBG("interface name %s\n", ifr.ifr_name); close(fd); return IPACM_SUCCESS; } /* Initialization routine for listener on NetLink sockets interface */ int ipa_nl_listener_init ( unsigned int nl_type, unsigned int nl_groups, ipa_nl_sk_fd_set_info_t *sk_fdset, ipa_sock_thrd_fd_read_f read_f ) { ipa_nl_sk_info_t sk_info; int ret_val; memset(&sk_info, 0, sizeof(ipa_nl_sk_info_t)); IPACMDBG_H("Entering IPA NL listener init\n"); if(ipa_nl_open_socket(&sk_info, nl_type, nl_groups) == IPACM_SUCCESS) { IPACMDBG_H("IPA Open netlink socket succeeds\n"); } else { IPACMERR("Netlink socket open failed\n"); return IPACM_FAILURE; } /* Add NETLINK socket to the list of sockets that the listener thread should listen on. */ if(ipa_nl_addfd_map(sk_fdset, sk_info.sk_fd, read_f) != IPACM_SUCCESS) { IPACMERR("cannot add nl routing sock for reading\n"); close(sk_info.sk_fd); return IPACM_FAILURE; } /* Start the socket listener thread */ ret_val = ipa_nl_sock_listener_start(sk_fdset); if(ret_val != IPACM_SUCCESS) { IPACMERR("Failed to start NL listener\n"); } return IPACM_SUCCESS; } /* find the newroute subnet mask */ int find_mask(int ip_v4_last, int *mask_value) { switch(ip_v4_last) { case 3: *mask_value = 252; return IPACM_SUCCESS; break; case 7: *mask_value = 248; return IPACM_SUCCESS; break; case 15: *mask_value = 240; return IPACM_SUCCESS; break; case 31: *mask_value = 224; return IPACM_SUCCESS; break; case 63: *mask_value = 192; return IPACM_SUCCESS; break; case 127: *mask_value = 128; return IPACM_SUCCESS; break; case 255: *mask_value = 0; return IPACM_SUCCESS; break; default: return IPACM_FAILURE; break; } } /* map mask value for ipv6 */ int mask_v6(int index, uint32_t *mask) { switch(index) { case 0: *mask = 0x00000000; return IPACM_SUCCESS; break; case 4: *mask = 0xf0000000; return IPACM_SUCCESS; break; case 8: *mask = 0xff000000; return IPACM_SUCCESS; break; case 12: *mask = 0xfff00000; return IPACM_SUCCESS; break; case 16: *mask = 0xffff0000; return IPACM_SUCCESS; break; case 20: *mask = 0xfffff000; return IPACM_SUCCESS; break; case 24: *mask = 0xffffff00; return IPACM_SUCCESS; break; case 28: *mask = 0xfffffff0; return IPACM_SUCCESS; break; case 32: *mask = 0xffffffff; return IPACM_SUCCESS; break; default: return IPACM_FAILURE; break; } } ================================================ FILE: data-ipa-cfg-mgr/ipacm/src/IPACM_Routing.cpp ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPACM_Routing.cpp @brief This file implements the IPACM routing functionality. @Author */ #include #include #include #include #include #include "IPACM_Routing.h" #include const char *IPACM_Routing::DEVICE_NAME = "/dev/ipa"; IPACM_Routing::IPACM_Routing() { m_fd = open(DEVICE_NAME, O_RDWR); if (0 == m_fd) { IPACMERR("Failed opening %s.\n", DEVICE_NAME); } } IPACM_Routing::~IPACM_Routing() { close(m_fd); } bool IPACM_Routing::DeviceNodeIsOpened() { int res = fcntl(m_fd, F_GETFL); if (m_fd > 0 && res >= 0) return true; else return false; } bool IPACM_Routing::AddRoutingRule(struct ipa_ioc_add_rt_rule *ruleTable) { int retval = 0; if (!DeviceNodeIsOpened()) { IPACMERR("Device is not opened\n"); return false; } retval = ioctl(m_fd, IPA_IOC_ADD_RT_RULE, ruleTable); if (retval) { IPACMERR("Failed adding routing rule %p\n", ruleTable); return false; } IPACMDBG_H("Added routing rule %p\n", ruleTable); return true; } bool IPACM_Routing::DeleteRoutingRule(struct ipa_ioc_del_rt_rule *ruleTable) { int retval = 0; if (!DeviceNodeIsOpened()) return false; retval = ioctl(m_fd, IPA_IOC_DEL_RT_RULE, ruleTable); if (retval) { IPACMERR("Failed deleting routing rule table %p\n", ruleTable); return false; } IPACMDBG_H("Deleted routing rule %p\n", ruleTable); return true; } bool IPACM_Routing::Commit(enum ipa_ip_type ip) { int retval = 0; if (!DeviceNodeIsOpened()) return false; retval = ioctl(m_fd, IPA_IOC_COMMIT_RT, ip); if (retval) { IPACMERR("Failed commiting routing rules.\n"); return false; } IPACMDBG_H("Commited routing rules to IPA HW.\n"); return true; } bool IPACM_Routing::Reset(enum ipa_ip_type ip) { int retval = 0; if (!DeviceNodeIsOpened()) return false; retval = ioctl(m_fd, IPA_IOC_RESET_RT, ip); retval |= ioctl(m_fd, IPA_IOC_COMMIT_RT, ip); if (retval) { IPACMERR("Failed resetting routing block.\n"); return false; } IPACMDBG_H("Reset command issued to IPA routing block.\n"); return true; } bool IPACM_Routing::GetRoutingTable(struct ipa_ioc_get_rt_tbl *routingTable) { int retval = 0; if (!DeviceNodeIsOpened()) return false; retval = ioctl(m_fd, IPA_IOC_GET_RT_TBL, routingTable); if (retval) { IPACMERR("IPA_IOCTL_GET_RT_TBL ioctl failed, routingTable =0x%p, retval=0x%x.\n", routingTable, retval); return false; } IPACMDBG_H("IPA_IOCTL_GET_RT_TBL ioctl issued to IPA routing block.\n"); return true; } bool IPACM_Routing::PutRoutingTable(uint32_t routingTableHandle) { int retval = 0; if (!DeviceNodeIsOpened()) return false; retval = ioctl(m_fd, IPA_IOC_PUT_RT_TBL, routingTableHandle); if (retval) { IPACMERR("IPA_IOCTL_PUT_RT_TBL ioctl failed.\n"); return false; } IPACMDBG_H("IPA_IOCTL_PUT_RT_TBL ioctl issued to IPA routing block.\n"); return true; } bool IPACM_Routing::DeleteRoutingHdl(uint32_t rt_rule_hdl, ipa_ip_type ip) { const uint8_t NUM_RULES = 1; struct ipa_ioc_del_rt_rule *rt_rule; struct ipa_rt_rule_del *rt_rule_entry; bool res = true; int len = 0; if (rt_rule_hdl == 0) { IPACMERR(" No route handle passed. Ignoring it\n"); return res; } len = (sizeof(struct ipa_ioc_del_rt_rule)) + (NUM_RULES * sizeof(struct ipa_rt_rule_del)); rt_rule = (struct ipa_ioc_del_rt_rule *)malloc(len); if (rt_rule == NULL) { IPACMERR("unable to allocate memory for del route rule\n"); return false; } memset(rt_rule, 0, len); rt_rule->commit = 1; rt_rule->num_hdls = NUM_RULES; rt_rule->ip = ip; rt_rule_entry = &rt_rule->hdl[0]; rt_rule_entry->status = -1; rt_rule_entry->hdl = rt_rule_hdl; IPACMDBG_H("Deleting Route hdl:(0x%x) with ip type: %d\n", rt_rule_entry->hdl, ip); if ((false == DeleteRoutingRule(rt_rule)) || (rt_rule_entry->status)) { PERROR("Routing rule deletion failed!\n"); goto fail; res = false; } fail: free(rt_rule); return res; } ================================================ FILE: data-ipa-cfg-mgr/ipacm/src/IPACM_Wan.cpp ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPACM_Wan.cpp @brief This file implements the WAN iface functionality. @Author Skylar Chang */ #include #include #include #include #include #include #include "IPACM_EvtDispatcher.h" #include #include "linux/rmnet_ipa_fd_ioctl.h" #include "IPACM_Config.h" #include "IPACM_Defs.h" #include #include "linux/ipa_qmi_service_v01.h" bool IPACM_Wan::wan_up = false; bool IPACM_Wan::wan_up_v6 = false; int IPACM_Wan::num_v4_flt_rule = 0; int IPACM_Wan::num_v6_flt_rule = 0; struct ipa_flt_rule_add IPACM_Wan::flt_rule_v4[IPA_MAX_FLT_RULE]; struct ipa_flt_rule_add IPACM_Wan::flt_rule_v6[IPA_MAX_FLT_RULE]; char IPACM_Wan::wan_up_dev_name[IF_NAME_LEN]; bool IPACM_Wan::backhaul_is_sta_mode = false; bool IPACM_Wan::is_ext_prop_set = false; int IPACM_Wan::num_ipv4_modem_pdn = 0; int IPACM_Wan::num_ipv6_modem_pdn = 0; bool IPACM_Wan::embms_is_on = false; uint32_t IPACM_Wan::backhaul_ipv6_prefix[2]; #ifdef FEATURE_IPA_ANDROID int IPACM_Wan::ipa_if_num_tether_v4_total = 0; int IPACM_Wan::ipa_if_num_tether_v6_total = 0; int IPACM_Wan::ipa_if_num_tether_v4[IPA_MAX_IFACE_ENTRIES]; int IPACM_Wan::ipa_if_num_tether_v6[IPA_MAX_IFACE_ENTRIES]; #endif IPACM_Wan::IPACM_Wan(int iface_index, ipacm_wan_iface_type is_sta_mode, uint8_t *mac_addr) : IPACM_Iface(iface_index) { num_firewall_v4 = 0; num_firewall_v6 = 0; wan_route_rule_v4_hdl = NULL; wan_route_rule_v6_hdl = NULL; wan_route_rule_v6_hdl_a5 = NULL; wan_client = NULL; if(iface_query != NULL) { wan_route_rule_v4_hdl = (uint32_t *)calloc(iface_query->num_tx_props, sizeof(uint32_t)); wan_route_rule_v6_hdl = (uint32_t *)calloc(iface_query->num_tx_props, sizeof(uint32_t)); wan_route_rule_v6_hdl_a5 = (uint32_t *)calloc(iface_query->num_tx_props, sizeof(uint32_t)); IPACMDBG_H("IPACM->IPACM_Wan(%d) constructor: Tx:%d\n", ipa_if_num, iface_query->num_tx_props); } m_is_sta_mode = is_sta_mode; active_v4 = false; active_v6 = false; header_set_v4 = false; header_set_v6 = false; header_partial_default_wan_v4 = false; header_partial_default_wan_v6 = false; hdr_hdl_sta_v4 = 0; hdr_hdl_sta_v6 = 0; num_ipv6_dest_flt_rule = 0; memset(ipv6_dest_flt_rule_hdl, 0, MAX_DEFAULT_v6_ROUTE_RULES*sizeof(uint32_t)); memset(ipv6_prefix, 0, sizeof(ipv6_prefix)); ext_prop = NULL; num_wan_client = 0; header_name_count = 0; memset(invalid_mac, 0, sizeof(invalid_mac)); if(iface_query != NULL) { wan_client_len = (sizeof(ipa_wan_client)) + (iface_query->num_tx_props * sizeof(wan_client_rt_hdl)); wan_client = (ipa_wan_client *)calloc(IPA_MAX_NUM_WAN_CLIENTS, wan_client_len); if (wan_client == NULL) { IPACMERR("unable to allocate memory\n"); return; } IPACMDBG_H("index:%d constructor: Tx properties:%d\n", iface_index, iface_query->num_tx_props); } if(m_is_sta_mode == Q6_WAN) { IPACMDBG_H("The new WAN interface is modem.\n"); is_default_gateway = false; query_ext_prop(); } else { IPACMDBG_H("The new WAN interface is WLAN STA.\n"); } if(m_is_sta_mode == WLAN_WAN) { memcpy(ext_router_mac_addr, mac_addr, sizeof(ext_router_mac_addr)); } m_fd_ipa = open(IPA_DEVICE_NAME, O_RDWR); if(0 == m_fd_ipa) { IPACMERR("Failed to open %s\n",IPA_DEVICE_NAME); } if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == EMBMS_IF) { IPACMDBG(" IPACM->IPACM_Wan_eMBMS(%d)\n", ipa_if_num); embms_is_on = true; install_wan_filtering_rule(false); /* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */ if(tx_prop != NULL) { IPACMDBG_H("dev %s add producer dependency\n", dev_name); IPACMDBG_H("depend Got pipe %d rm index : %d \n", tx_prop->tx[0].dst_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]); IPACM_Iface::ipacmcfg->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false); } } else { IPACMDBG(" IPACM->IPACM_Wan(%d)\n", ipa_if_num); } return; } IPACM_Wan::~IPACM_Wan() { IPACM_EvtDispatcher::deregistr(this); IPACM_IfaceManager::deregistr(this); return; } /* handle new_address event */ int IPACM_Wan::handle_addr_evt(ipacm_event_data_addr *data) { struct ipa_ioc_add_rt_rule *rt_rule; struct ipa_rt_rule_add *rt_rule_entry; struct ipa_ioc_add_flt_rule *flt_rule; struct ipa_flt_rule_add flt_rule_entry; const int NUM_RULES = 1; int num_ipv6_addr, len; int res = IPACM_SUCCESS; if (data->iptype == IPA_IP_v6) { for(num_ipv6_addr=0;num_ipv6_addripv6_addr[0]) && (ipv6_addr[num_ipv6_addr][1] == data->ipv6_addr[1]) && (ipv6_addr[num_ipv6_addr][2] == data->ipv6_addr[2]) && (ipv6_addr[num_ipv6_addr][3] == data->ipv6_addr[3])) { IPACMDBG_H("find matched ipv6 address, index:%d \n", num_ipv6_addr); return IPACM_SUCCESS; break; } } rt_rule = (struct ipa_ioc_add_rt_rule *) calloc(1, sizeof(struct ipa_ioc_add_rt_rule) + NUM_RULES * sizeof(struct ipa_rt_rule_add)); if (!rt_rule) { IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n"); return IPACM_FAILURE; } rt_rule->commit = 1; rt_rule->num_rules = NUM_RULES; rt_rule->ip = data->iptype; strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_v6.name); rt_rule_entry = &rt_rule->rules[0]; rt_rule_entry->at_rear = false; rt_rule_entry->rule.dst = iface_query->excp_pipe; //go to A5 rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = data->ipv6_addr[0]; rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = data->ipv6_addr[1]; rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = data->ipv6_addr[2]; rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = data->ipv6_addr[3]; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF; ipv6_addr[num_dft_rt_v6][0] = data->ipv6_addr[0]; ipv6_addr[num_dft_rt_v6][1] = data->ipv6_addr[1]; ipv6_addr[num_dft_rt_v6][2] = data->ipv6_addr[2]; ipv6_addr[num_dft_rt_v6][3] = data->ipv6_addr[3]; if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); res = IPACM_FAILURE; goto fail; } else if (rt_rule_entry->status) { IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status); res = rt_rule_entry->status; goto fail; } dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6] = rt_rule_entry->rt_rule_hdl; /* setup same rule for v6_wan table*/ strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name); if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); res = IPACM_FAILURE; goto fail; } else if (rt_rule_entry->status) { IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status); res = rt_rule_entry->status; goto fail; } dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1] = rt_rule_entry->rt_rule_hdl; IPACMDBG_H("ipv6 wan iface rt-rule hdl=0x%x hdl=0x%x, num_dft_rt_v6: %d \n", dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6], dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1],num_dft_rt_v6); if (num_dft_rt_v6 == 0) { if(m_is_sta_mode == Q6_WAN) { modem_ipv6_pdn_index = num_ipv6_modem_pdn; num_ipv6_modem_pdn++; IPACMDBG_H("Now the number of modem ipv6 pdn is %d.\n", num_ipv6_modem_pdn); init_fl_rule_ex(data->iptype); } else { init_fl_rule(data->iptype); } } /* add WAN DL interface IP specific flt rule for IPv6 when backhaul is not Q6 */ if(m_is_sta_mode != Q6_WAN) { if(rx_prop != NULL && is_global_ipv6_addr(data->ipv6_addr) && num_ipv6_dest_flt_rule < MAX_DEFAULT_v6_ROUTE_RULES) { len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add); flt_rule = (struct ipa_ioc_add_flt_rule *)calloc(1, len); if (!flt_rule) { IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); return IPACM_FAILURE; } flt_rule->commit = 1; flt_rule->ep = rx_prop->rx[0].src_pipe; flt_rule->global = false; flt_rule->ip = IPA_IP_v6; flt_rule->num_rules = 1; memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); flt_rule_entry.rule.retain_hdr = 1; flt_rule_entry.rule.to_uc = 0; flt_rule_entry.rule.eq_attrib_type = 0; flt_rule_entry.at_rear = true; flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; memcpy(flt_rule_entry.rule.attrib.u.v6.dst_addr, data->ipv6_addr, sizeof(flt_rule_entry.rule.attrib.u.v6.dst_addr)); flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF; memcpy(&(flt_rule->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); if (m_filtering.AddFilteringRule(flt_rule) == false) { IPACMERR("Error Adding Filtering rule, aborting...\n"); free(flt_rule); res = IPACM_FAILURE; goto fail; } else { ipv6_dest_flt_rule_hdl[num_ipv6_dest_flt_rule] = flt_rule->rules[0].flt_rule_hdl; IPACMDBG_H("IPv6 dest filter rule %d HDL:0x%x\n", num_ipv6_dest_flt_rule, ipv6_dest_flt_rule_hdl[num_ipv6_dest_flt_rule]); num_ipv6_dest_flt_rule++; free(flt_rule); } } } /* store ipv6 prefix if the ipv6 address is not link local */ if(is_global_ipv6_addr(data->ipv6_addr)) { memcpy(ipv6_prefix, data->ipv6_addr, sizeof(ipv6_prefix)); } num_dft_rt_v6++; } else { rt_rule = (struct ipa_ioc_add_rt_rule *) calloc(1, sizeof(struct ipa_ioc_add_rt_rule) + NUM_RULES * sizeof(struct ipa_rt_rule_add)); if (!rt_rule) { IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n"); return IPACM_FAILURE; } rt_rule->commit = 1; rt_rule->num_rules = NUM_RULES; rt_rule->ip = data->iptype; rt_rule_entry = &rt_rule->rules[0]; rt_rule_entry->at_rear = false; rt_rule_entry->rule.dst = iface_query->excp_pipe; //go to A5 rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; /* still need setup v4 default routing rule to A5*/ strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name); rt_rule_entry->rule.attrib.u.v4.dst_addr = data->ipv4_addr; rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF; if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); res = IPACM_FAILURE; goto fail; } else if (rt_rule_entry->status) { IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status); res = rt_rule_entry->status; goto fail; } dft_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl; IPACMDBG_H("ipv4 wan iface rt-rule hdll=0x%x\n", dft_rt_rule_hdl[0]); /* initial multicast/broadcast/fragment filter rule */ if(m_is_sta_mode == Q6_WAN) { modem_ipv4_pdn_index = num_ipv4_modem_pdn; num_ipv4_modem_pdn++; IPACMDBG_H("Now the number of modem ipv4 pdn is %d.\n", num_ipv4_modem_pdn); init_fl_rule_ex(data->iptype); } else { init_fl_rule(data->iptype); } wan_v4_addr = data->ipv4_addr; IPACMDBG_H("Receved wan address:0x%x\n",wan_v4_addr); } IPACMDBG_H("number of default route rules %d\n", num_dft_rt_v6); fail: free(rt_rule); return res; } void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param) { int ipa_interface_index; switch (event) { case IPA_WLAN_LINK_DOWN_EVENT: { if(m_is_sta_mode == WLAN_WAN) { ipacm_event_data_fid *data = (ipacm_event_data_fid *)param; ipa_interface_index = iface_ipa_index_query(data->if_index); if (ipa_interface_index == ipa_if_num) { IPACMDBG_H("Received IPA_WLAN_LINK_DOWN_EVENT\n"); handle_down_evt(); /* reset the STA-iface category to unknown */ IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat = UNKNOWN_IF; IPACMDBG_H("IPA_WAN_STA (%s):ipa_index (%d) instance close \n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, ipa_if_num); IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface delete this; return; } } } break; case IPA_CFG_CHANGE_EVENT: { if ( (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat != ipa_if_cate) && (m_is_sta_mode ==ECM_WAN)) { IPACMDBG_H("Received IPA_CFG_CHANGE_EVENT and category changed(wan_mode:%d)\n", m_is_sta_mode); /* posting link-up event for cradle use-case */ ipacm_cmd_q_data evt_data; memset(&evt_data, 0, sizeof(evt_data)); ipacm_event_data_fid *data_fid = NULL; data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid)); if(data_fid == NULL) { IPACMERR("unable to allocate memory for IPA_USB_LINK_UP_EVENT data_fid\n"); return; } if(IPACM_Iface::ipa_get_if_index(dev_name, &(data_fid->if_index))) { IPACMERR("Error while getting interface index for %s device", dev_name); } evt_data.event = IPA_USB_LINK_UP_EVENT; evt_data.evt_data = data_fid; IPACMDBG_H("Posting event:%d\n", evt_data.event); IPACM_EvtDispatcher::PostEvt(&evt_data); /* delete previous instance */ handle_down_evt(); IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface delete this; return; } } break; case IPA_LINK_DOWN_EVENT: { if(m_is_sta_mode == Q6_WAN) { ipacm_event_data_fid *data = (ipacm_event_data_fid *)param; ipa_interface_index = iface_ipa_index_query(data->if_index); if (ipa_interface_index == ipa_if_num) { IPACMDBG_H("Received IPA_LINK_DOWN_EVENT\n"); handle_down_evt_ex(); IPACMDBG_H("IPA_WAN_Q6 (%s):ipa_index (%d) instance close \n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, ipa_if_num); IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface delete this; return; } } else if (m_is_sta_mode == ECM_WAN) { IPACMDBG_H("Received IPA_LINK_DOWN_EVENT(wan_mode:%d)\n", m_is_sta_mode); /* delete previous instance */ handle_down_evt(); IPACMDBG_H("IPA_WAN_CRADLE (%s):ipa_index (%d) instance close \n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, ipa_if_num); IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface delete this; return; } } break; case IPA_ADDR_ADD_EVENT: { ipacm_event_data_addr *data = (ipacm_event_data_addr *)param; ipa_interface_index = iface_ipa_index_query(data->if_index); if ( (data->iptype == IPA_IP_v4 && data->ipv4_addr == 0) || (data->iptype == IPA_IP_v6 && data->ipv6_addr[0] == 0 && data->ipv6_addr[1] == 0 && data->ipv6_addr[2] == 0 && data->ipv6_addr[3] == 0) ) { IPACMDBG_H("Invalid address, ignore IPA_ADDR_ADD_EVENT event\n"); return; } if (ipa_interface_index == ipa_if_num) { IPACMDBG_H("Get IPA_ADDR_ADD_EVENT: IF ip type %d, incoming ip type %d\n", ip_type, data->iptype); /* check v4 not setup before, v6 can have 2 iface ip */ if( ((data->iptype != ip_type) && (ip_type != IPA_IP_MAX)) || ((data->iptype==IPA_IP_v6) && (num_dft_rt_v6!=MAX_DEFAULT_v6_ROUTE_RULES))) { IPACMDBG_H("Got IPA_ADDR_ADD_EVENT ip-family:%d, v6 num %d: \n",data->iptype,num_dft_rt_v6); handle_addr_evt(data); /* checking if SW-RT_enable */ if (IPACM_Iface::ipacmcfg->ipa_sw_rt_enable == true && m_is_sta_mode != Q6_WAN) { /* handle software routing enable event*/ IPACMDBG_H("IPA_SW_ROUTING_ENABLE for iface: %s \n",IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name); handle_software_routing_enable(); } } } } break; case IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT: { ipacm_event_data_iptype *data = (ipacm_event_data_iptype *)param; ipa_interface_index = iface_ipa_index_query(data->if_index); if (ipa_interface_index == ipa_if_num) { IPACMDBG_H("Received IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT (Android) for ip-type (%d)\n", data->iptype); /* The special below condition is to handle default gateway */ if ((data->iptype == IPA_IP_v4) && (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)) { if (active_v4 == false) { IPACMDBG_H("adding routing table(upstream), dev (%s) ip-type(%d)\n", dev_name,data->iptype); handle_route_add_evt(data->iptype); } #ifdef FEATURE_IPA_ANDROID /* using ipa_if_index, not netdev_index */ post_wan_up_tether_evt(data->iptype, iface_ipa_index_query(data->if_index_tether)); #endif } else if ((data->iptype == IPA_IP_v6) && (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)) { if (active_v6 == false) { IPACMDBG_H("\n get default v6 route (dst:00.00.00.00) upstream\n"); handle_route_add_evt(data->iptype); } #ifdef FEATURE_IPA_ANDROID /* using ipa_if_index, not netdev_index */ post_wan_up_tether_evt(data->iptype, iface_ipa_index_query(data->if_index_tether)); #endif } } else /* double check if current default iface is not itself */ { if ((data->iptype == IPA_IP_v4) && (active_v4 == true)) { IPACMDBG_H("Received v4 IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT for other iface (%s)\n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name); IPACMDBG_H("need clean default v4 route (dst:0.0.0.0) for old iface (%s)\n", dev_name); if(m_is_sta_mode == Q6_WAN) { del_wan_firewall_rule(IPA_IP_v4); install_wan_filtering_rule(false); handle_route_del_evt_ex(IPA_IP_v4); } else { del_dft_firewall_rules(IPA_IP_v4); handle_route_del_evt(IPA_IP_v4); } } else if ((data->iptype == IPA_IP_v6) && (active_v6 == true)) { IPACMDBG_H("Received v6 IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT for other iface (%s)\n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name); IPACMDBG_H("need clean default v6 route for old iface (%s)\n", dev_name); if(m_is_sta_mode == Q6_WAN) { del_wan_firewall_rule(IPA_IP_v6); install_wan_filtering_rule(false); handle_route_del_evt_ex(IPA_IP_v6); } else { del_dft_firewall_rules(IPA_IP_v6); handle_route_del_evt(IPA_IP_v6); } } } } break; case IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT: { ipacm_event_data_iptype *data = (ipacm_event_data_iptype *)param; ipa_interface_index = iface_ipa_index_query(data->if_index); if (ipa_interface_index == ipa_if_num) { IPACMDBG_H("Received IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT\n"); if ((data->iptype == IPA_IP_v4) && (active_v4 == true)) { IPACMDBG_H("get del default v4 route (dst:0.0.0.0)\n"); // wan_v4_addr_gw_set = false; /* android requires CnE change too */ #ifdef FEATURE_IPA_ANDROID /* using ipa_if_index, not netdev_index */ post_wan_down_tether_evt(data->iptype, iface_ipa_index_query(data->if_index_tether)); /* no any ipv4 tether iface support*/ if(IPACM_Wan::ipa_if_num_tether_v4_total != 0) { IPACMDBG_H("still have tether ipv4 client on upsteam iface\n"); return; } #endif if(m_is_sta_mode == Q6_WAN) { del_wan_firewall_rule(IPA_IP_v4); install_wan_filtering_rule(false); handle_route_del_evt_ex(IPA_IP_v4); } else { del_dft_firewall_rules(IPA_IP_v4); handle_route_del_evt(IPA_IP_v4); } } else if ((data->iptype == IPA_IP_v6) && (active_v6 == true)) { #ifdef FEATURE_IPA_ANDROID /* using ipa_if_index, not netdev_index */ post_wan_down_tether_evt(data->iptype, iface_ipa_index_query(data->if_index_tether)); /* no any ipv6 tether iface support*/ if(IPACM_Wan::ipa_if_num_tether_v6_total != 0) { IPACMDBG_H("still have tether ipv6 client on upsteam iface\n"); return; } #endif if(m_is_sta_mode == Q6_WAN) { del_wan_firewall_rule(IPA_IP_v6); install_wan_filtering_rule(false); handle_route_del_evt_ex(IPA_IP_v6); } else { del_dft_firewall_rules(IPA_IP_v6); handle_route_del_evt(IPA_IP_v6); } } } } break; case IPA_NETWORK_STATS_UPDATE_EVENT: { ipa_get_apn_data_stats_resp_msg_v01 *data = (ipa_get_apn_data_stats_resp_msg_v01 *)param; if (!data->apn_data_stats_list_valid) { IPACMERR("not valid APN\n"); return; } else { handle_network_stats_update(data); } } break; case IPA_ROUTE_ADD_EVENT: { ipacm_event_data_addr *data = (ipacm_event_data_addr *)param; ipa_interface_index = iface_ipa_index_query(data->if_index); if (ipa_interface_index == ipa_if_num) { IPACMDBG_H("Received IPA_ROUTE_ADD_EVENT\n"); IPACMDBG_H("ipv4 addr 0x%x\n", data->ipv4_addr); IPACMDBG_H("ipv4 addr mask 0x%x\n", data->ipv4_addr_mask); /* The special below condition is to handle default gateway */ if ((data->iptype == IPA_IP_v4) && (!data->ipv4_addr) && (!data->ipv4_addr_mask) && (active_v4 == false) && (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)) { IPACMDBG_H("adding routing table, dev (%s) ip-type(%d)\n", dev_name,data->iptype); handle_route_add_evt(data->iptype); } else if ((data->iptype == IPA_IP_v6) && (!data->ipv6_addr[0]) && (!data->ipv6_addr[1]) && (!data->ipv6_addr[2]) && (!data->ipv6_addr[3]) && (active_v6 == false) && (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)) { IPACMDBG_H("\n get default v6 route (dst:00.00.00.00)\n"); IPACMDBG_H(" IPV6 value: %08x:%08x:%08x:%08x \n", data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]); handle_route_add_evt(data->iptype); } } else /* double check if current default iface is not itself */ { if ((data->iptype == IPA_IP_v4) && (!data->ipv4_addr) && (!data->ipv4_addr_mask) && (active_v4 == true)) { IPACMDBG_H("Received v4 IPA_ROUTE_ADD_EVENT for other iface (%s)\n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name); IPACMDBG_H("ipv4 addr 0x%x\n", data->ipv4_addr); IPACMDBG_H("ipv4 addr mask 0x%x\n", data->ipv4_addr_mask); IPACMDBG_H("need clean default v4 route (dst:0.0.0.0) for old iface (%s)\n", dev_name); if(m_is_sta_mode == Q6_WAN) { del_wan_firewall_rule(IPA_IP_v4); install_wan_filtering_rule(false); handle_route_del_evt_ex(IPA_IP_v4); } else { del_dft_firewall_rules(IPA_IP_v4); handle_route_del_evt(IPA_IP_v4); } } else if ((data->iptype == IPA_IP_v6) && (!data->ipv6_addr[0]) && (!data->ipv6_addr[1]) && (!data->ipv6_addr[2]) && (!data->ipv6_addr[3]) && (active_v6 == true)) { IPACMDBG_H("Received v6 IPA_ROUTE_ADD_EVENT for other iface (%s)\n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name); IPACMDBG_H("need clean default v6 route for old iface (%s)\n", dev_name); if(m_is_sta_mode == Q6_WAN) { del_wan_firewall_rule(IPA_IP_v6); install_wan_filtering_rule(false); handle_route_del_evt_ex(IPA_IP_v6); } else { del_dft_firewall_rules(IPA_IP_v6); handle_route_del_evt(IPA_IP_v6); } } } } break; case IPA_ROUTE_DEL_EVENT: { ipacm_event_data_addr *data = (ipacm_event_data_addr *)param; ipa_interface_index = iface_ipa_index_query(data->if_index); if (ipa_interface_index == ipa_if_num) { IPACMDBG_H("Received IPA_ROUTE_DEL_EVENT\n"); if ((data->iptype == IPA_IP_v4) && (!data->ipv4_addr) && (!data->ipv4_addr_mask) && (active_v4 == true)) { IPACMDBG_H("get del default v4 route (dst:0.0.0.0)\n"); if(m_is_sta_mode == Q6_WAN) { del_wan_firewall_rule(IPA_IP_v4); install_wan_filtering_rule(false); handle_route_del_evt_ex(IPA_IP_v4); } else { del_dft_firewall_rules(IPA_IP_v4); handle_route_del_evt(IPA_IP_v4); } } else if ((data->iptype == IPA_IP_v6) && (!data->ipv6_addr[0]) && (!data->ipv6_addr[1]) && (!data->ipv6_addr[2]) && (!data->ipv6_addr[3]) && (active_v6 == true)) { IPACMDBG_H("get del default v6 route (dst:00.00.00.00)\n"); if(m_is_sta_mode == Q6_WAN) { del_wan_firewall_rule(IPA_IP_v6); install_wan_filtering_rule(false); handle_route_del_evt_ex(IPA_IP_v6); } else { del_dft_firewall_rules(IPA_IP_v6); handle_route_del_evt(IPA_IP_v6); } } } } break; case IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT: { ipacm_event_data_all *data = (ipacm_event_data_all *)param; ipa_interface_index = iface_ipa_index_query(data->if_index); if (ipa_interface_index == ipa_if_num) { IPACMDBG_H("Received IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT in STA mode\n"); if (m_is_sta_mode == WLAN_WAN) { handle_header_add_evt(ext_router_mac_addr); if (data->iptype == IPA_IP_v4 && data->ipv4_addr == wan_v4_addr) { IPACMDBG_H("Ignore IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT in STA mode\n"); IPACMDBG_H("for its own ipv4 address\n"); return; } else if (data->iptype == IPA_IP_v6) { for (int num_ipv6_addr = 0; num_ipv6_addr < num_dft_rt_v6; num_ipv6_addr++) { if ((ipv6_addr[num_ipv6_addr][0] == data->ipv6_addr[0]) && (ipv6_addr[num_ipv6_addr][1] == data->ipv6_addr[1]) && (ipv6_addr[num_ipv6_addr][2] == data->ipv6_addr[2]) && (ipv6_addr[num_ipv6_addr][3] == data->ipv6_addr[3])) { IPACMDBG_H("Ignore IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT in STA mode\n"); IPACMDBG_H("for its own ipv6 address\n"); return; } } } } IPACMDBG_H("wan-iface got client \n"); /* first construc WAN-client full header */ if(memcmp(data->mac_addr, invalid_mac, sizeof(data->mac_addr)) == 0) { IPACMDBG_H("Received invalid Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n", data->mac_addr[0], data->mac_addr[1], data->mac_addr[2], data->mac_addr[3], data->mac_addr[4], data->mac_addr[5]); return; } handle_header_add_evt(data->mac_addr); handle_wan_hdr_init(data->mac_addr); IPACMDBG_H("construct wan header and route rules \n"); /* Associate with IP and construct RT-rule */ if (handle_wan_client_ipaddr(data) == IPACM_FAILURE) { return; } handle_wan_client_route_rule(data->mac_addr, data->iptype); return; } } break; case IPA_SW_ROUTING_ENABLE: IPACMDBG_H("Received IPA_SW_ROUTING_ENABLE\n"); /* handle software routing enable event */ if(m_is_sta_mode == Q6_WAN) { install_wan_filtering_rule(true); } else { handle_software_routing_enable(); } break; case IPA_SW_ROUTING_DISABLE: IPACMDBG_H("Received IPA_SW_ROUTING_DISABLE\n"); /* handle software routing disable event */ if(m_is_sta_mode == Q6_WAN) { /* send current DL rules to modem */ install_wan_filtering_rule(false); softwarerouting_act = false; } else { handle_software_routing_disable(); } break; case IPA_FIREWALL_CHANGE_EVENT: IPACMDBG_H("Received IPA_FIREWALL_CHANGE_EVENT\n"); if(m_is_sta_mode == Q6_WAN) { if(is_default_gateway == false) { IPACMDBG_H("Interface %s is not default gw, return.\n", dev_name); return; } if(ip_type == IPA_IP_v4) { del_wan_firewall_rule(IPA_IP_v4); config_wan_firewall_rule(IPA_IP_v4); install_wan_filtering_rule(false); } else if(ip_type == IPA_IP_v6) { del_wan_firewall_rule(IPA_IP_v6); config_wan_firewall_rule(IPA_IP_v6); install_wan_filtering_rule(false); } else if(ip_type == IPA_IP_MAX) { del_wan_firewall_rule(IPA_IP_v4); config_wan_firewall_rule(IPA_IP_v4); del_wan_firewall_rule(IPA_IP_v6); config_wan_firewall_rule(IPA_IP_v6); install_wan_filtering_rule(false); } else { IPACMERR("IP type is not expected.\n"); } } else { if (active_v4) { del_dft_firewall_rules(IPA_IP_v4); config_dft_firewall_rules(IPA_IP_v4); } if (active_v6) { del_dft_firewall_rules(IPA_IP_v6); config_dft_firewall_rules(IPA_IP_v6); } } break; default: break; } return; } /* wan default route/filter rule configuration */ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype) { /* add default WAN route */ struct ipa_ioc_add_rt_rule *rt_rule; struct ipa_rt_rule_add *rt_rule_entry; struct ipa_ioc_get_hdr sRetHeader; uint32_t cnt, tx_index = 0; const int NUM = 1; ipacm_cmd_q_data evt_data; struct ipa_ioc_copy_hdr sCopyHeader; /* checking if partial header*/ IPACMDBG_H("ip-type:%d\n", iptype); /* copy header from tx-property, see if partial or not */ /* assume all tx-property uses the same header name for v4 or v6*/ if(tx_prop == NULL) { IPACMDBG_H("No tx properties, ignore default route setting\n"); return IPACM_SUCCESS; } is_default_gateway = true; IPACMDBG_H("Default route is added to iface %s.\n", dev_name); memcpy(backhaul_ipv6_prefix, ipv6_prefix, sizeof(backhaul_ipv6_prefix)); IPACMDBG_H("Setup backhaul ipv6 prefix to be 0x%08x%08x.\n", backhaul_ipv6_prefix[0], backhaul_ipv6_prefix[1]); if (m_is_sta_mode !=Q6_WAN) { IPACM_Wan::backhaul_is_sta_mode = true; if((iptype==IPA_IP_v4) && (header_set_v4 != true)) { header_partial_default_wan_v4 = true; IPACMDBG_H("STA ipv4-header haven't constructed \n"); return IPACM_SUCCESS; } else if((iptype==IPA_IP_v6) && (header_set_v6 != true)) { header_partial_default_wan_v6 = true; IPACMDBG_H("STA ipv6-header haven't constructed \n"); return IPACM_SUCCESS; } } else { IPACM_Wan::backhaul_is_sta_mode = false; IPACMDBG_H("reset backhaul to LTE \n"); if (iface_query != NULL && iface_query->num_ext_props > 0) { if(ext_prop == NULL) { IPACMERR("Extended property is empty.\n"); return IPACM_FAILURE; } else { IPACM_Iface::ipacmcfg->SetQmapId(ext_prop->ext[0].mux_id); IPACMDBG_H("Setting up QMAP ID %d.\n", ext_prop->ext[0].mux_id); } } else { IPACMERR("iface_query is empty.\n"); return IPACM_FAILURE; } } for (cnt=0; cntnum_tx_props; cnt++) { if(tx_prop->tx[cnt].ip==iptype) break; } //if(tx_prop->tx[cnt].hdr_name != NULL) { memset(&sCopyHeader, 0, sizeof(sCopyHeader)); memcpy(sCopyHeader.name, tx_prop->tx[cnt].hdr_name, sizeof(sCopyHeader.name)); IPACMDBG_H("header name: %s\n", sCopyHeader.name); if (m_header.CopyHeader(&sCopyHeader) == false) { IPACMERR("ioctl copy header failed"); return IPACM_FAILURE; } IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial); if(sCopyHeader.is_partial) { IPACMDBG_H("Not setup default WAN routing rules cuz the header is not complete\n"); if(iptype==IPA_IP_v4) { header_partial_default_wan_v4 = true; } else { header_partial_default_wan_v6 = true; } return IPACM_SUCCESS; } else { if(iptype==IPA_IP_v4) { header_partial_default_wan_v4 = false; } else { header_partial_default_wan_v6 = false; } } } rt_rule = (struct ipa_ioc_add_rt_rule *) calloc(1, sizeof(struct ipa_ioc_add_rt_rule) + NUM * sizeof(struct ipa_rt_rule_add)); if (!rt_rule) { IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n"); return IPACM_FAILURE; } rt_rule->commit = 1; rt_rule->num_rules = (uint8_t)NUM; rt_rule->ip = iptype; IPACMDBG_H(" WAN table created %s \n", rt_rule->rt_tbl_name); rt_rule_entry = &rt_rule->rules[0]; rt_rule_entry->at_rear = true; if(m_is_sta_mode != Q6_WAN) { IPACMDBG_H(" WAN instance is in STA mode \n"); for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) { if(iptype != tx_prop->tx[tx_index].ip) { IPACMDBG_H("Tx:%d, ip-type: %d conflict ip-type: %d no RT-rule added\n", tx_index, tx_prop->tx[tx_index].ip,iptype); continue; } if (iptype == IPA_IP_v4) { strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.name); } else { strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_v6.name); } //if (tx_prop->tx[tx_index].hdr_name != NULL) { IPACMDBG_H(" TX- header hdl %s \n", tx_prop->tx[tx_index].hdr_name); memset(&sRetHeader, 0, sizeof(sRetHeader)); strncpy(sRetHeader.name, tx_prop->tx[tx_index].hdr_name, sizeof(tx_prop->tx[tx_index].hdr_name)); if (false == m_header.GetHeaderHandle(&sRetHeader)) { IPACMERR("\n ioctl failed\n"); free(rt_rule); return IPACM_FAILURE; } rt_rule_entry->rule.hdr_hdl = sRetHeader.hdl; } rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe; memcpy(&rt_rule_entry->rule.attrib, &tx_prop->tx[tx_index].attrib, sizeof(rt_rule_entry->rule.attrib)); rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; if (iptype == IPA_IP_v4) { rt_rule_entry->rule.attrib.u.v4.dst_addr = 0; rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0; if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); free(rt_rule); return IPACM_FAILURE; } wan_route_rule_v4_hdl[tx_index] = rt_rule_entry->rt_rule_hdl; IPACMDBG_H("Got ipv4 wan-route rule hdl:0x%x,tx:%d,ip-type: %d \n", wan_route_rule_v4_hdl[tx_index], tx_index, iptype); } else { rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = 0; rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = 0; rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = 0; rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = 0; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0; if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); free(rt_rule); return IPACM_FAILURE; } wan_route_rule_v6_hdl[tx_index] = rt_rule_entry->rt_rule_hdl; IPACMDBG_H("Set ipv6 wan-route rule hdl for v6_lan_table:0x%x,tx:%d,ip-type: %d \n", wan_route_rule_v6_hdl[tx_index], tx_index, iptype); } } } /* add a catch-all rule in wan dl routing table */ if (iptype == IPA_IP_v6) { strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name); memset(rt_rule_entry, 0, sizeof(struct ipa_rt_rule_add)); rt_rule_entry->at_rear = true; rt_rule_entry->rule.dst = iface_query->excp_pipe; //go to A5 rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = 0; rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = 0; rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = 0; rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = 0; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0; if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); free(rt_rule); return IPACM_FAILURE; } wan_route_rule_v6_hdl_a5[0] = rt_rule_entry->rt_rule_hdl; IPACMDBG_H("Set ipv6 wan-route rule hdl for v6_wan_table:0x%x,tx:%d,ip-type: %d \n", wan_route_rule_v6_hdl_a5[0], 0, iptype); } ipacm_event_iface_up *wanup_data; wanup_data = (ipacm_event_iface_up *)malloc(sizeof(ipacm_event_iface_up)); if (wanup_data == NULL) { IPACMERR("Unable to allocate memory\n"); return IPACM_FAILURE; } memset(wanup_data, 0, sizeof(ipacm_event_iface_up)); if (iptype == IPA_IP_v4) { IPACM_Wan::wan_up = true; active_v4 = true; memcpy(IPACM_Wan::wan_up_dev_name, dev_name, sizeof(IPACM_Wan::wan_up_dev_name)); if(m_is_sta_mode == Q6_WAN) { config_wan_firewall_rule(IPA_IP_v4); install_wan_filtering_rule(false); } else { config_dft_firewall_rules(IPA_IP_v4); } memcpy(wanup_data->ifname, dev_name, sizeof(wanup_data->ifname)); wanup_data->ipv4_addr = wan_v4_addr; if (m_is_sta_mode!=Q6_WAN) { wanup_data->is_sta = true; } else { wanup_data->is_sta = false; } IPACMDBG_H("Posting IPA_HANDLE_WAN_UP with below information:\n"); IPACMDBG_H("if_name:%s, ipv4_address:0x%x, is sta mode:%d\n", wanup_data->ifname, wanup_data->ipv4_addr, wanup_data->is_sta); memset(&evt_data, 0, sizeof(evt_data)); evt_data.event = IPA_HANDLE_WAN_UP; evt_data.evt_data = (void *)wanup_data; IPACM_EvtDispatcher::PostEvt(&evt_data); } else { IPACM_Wan::wan_up_v6 = true; active_v6 = true; memcpy(IPACM_Wan::wan_up_dev_name, dev_name, sizeof(IPACM_Wan::wan_up_dev_name)); if(m_is_sta_mode == Q6_WAN) { config_wan_firewall_rule(IPA_IP_v6); install_wan_filtering_rule(false); } else { config_dft_firewall_rules(IPA_IP_v6); } memcpy(wanup_data->ifname, dev_name, sizeof(wanup_data->ifname)); if (m_is_sta_mode!=Q6_WAN) { wanup_data->is_sta = true; } else { wanup_data->is_sta = false; } memcpy(wanup_data->ipv6_prefix, ipv6_prefix, sizeof(wanup_data->ipv6_prefix)); IPACMDBG_H("Posting IPA_HANDLE_WAN_UP_V6 with below information:\n"); IPACMDBG_H("if_name:%s, is sta mode: %d\n", wanup_data->ifname, wanup_data->is_sta); IPACMDBG_H("ipv6 prefix: 0x%08x%08x.\n", ipv6_prefix[0], ipv6_prefix[1]); memset(&evt_data, 0, sizeof(evt_data)); evt_data.event = IPA_HANDLE_WAN_UP_V6; evt_data.evt_data = (void *)wanup_data; IPACM_EvtDispatcher::PostEvt(&evt_data); } /* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */ IPACMDBG_H("dev %s add producer dependency\n", dev_name); IPACMDBG_H("depend Got pipe %d rm index : %d \n", tx_prop->tx[0].dst_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]); IPACM_Iface::ipacmcfg->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false); return IPACM_SUCCESS; } /* wan default route/filter rule configuration */ int IPACM_Wan::post_wan_up_tether_evt(ipa_ip_type iptype, int ipa_if_num_tether) { ipacm_cmd_q_data evt_data; ipacm_event_iface_up_tehter *wanup_data; wanup_data = (ipacm_event_iface_up_tehter *)malloc(sizeof(ipacm_event_iface_up_tehter)); if (wanup_data == NULL) { IPACMERR("Unable to allocate memory\n"); return IPACM_FAILURE; } memset(wanup_data, 0, sizeof(ipacm_event_iface_up_tehter)); wanup_data->if_index_tether = ipa_if_num_tether; if (m_is_sta_mode!=Q6_WAN) { wanup_data->is_sta = true; } else { wanup_data->is_sta = false; } IPACMDBG_H("Posting IPA_HANDLE_WAN_UP_TETHER with below information:\n"); IPACMDBG_H("tether_if_name:%s, is sta mode:%d\n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether].iface_name, wanup_data->is_sta); memset(&evt_data, 0, sizeof(evt_data)); if (iptype == IPA_IP_v4) { evt_data.event = IPA_HANDLE_WAN_UP_TETHER; /* Add support tether ifaces to its array*/ IPACM_Wan::ipa_if_num_tether_v4[IPACM_Wan::ipa_if_num_tether_v4_total] = ipa_if_num_tether; IPACMDBG_H("adding tether iface(%s) ipa_if_num_tether_v4_total(%d) on wan_iface(%s)\n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether].iface_name, IPACM_Wan::ipa_if_num_tether_v4_total, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name); IPACM_Wan::ipa_if_num_tether_v4_total++; } else { evt_data.event = IPA_HANDLE_WAN_UP_V6_TETHER; memcpy(wanup_data->ipv6_prefix, ipv6_prefix, sizeof(wanup_data->ipv6_prefix)); /* Add support tether ifaces to its array*/ IPACM_Wan::ipa_if_num_tether_v6[IPACM_Wan::ipa_if_num_tether_v6_total] = ipa_if_num_tether; IPACMDBG_H("adding tether iface(%s) ipa_if_num_tether_v6_total(%d) on wan_iface(%s)\n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether].iface_name, IPACM_Wan::ipa_if_num_tether_v6_total, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name); IPACM_Wan::ipa_if_num_tether_v6_total++; } evt_data.evt_data = (void *)wanup_data; IPACM_EvtDispatcher::PostEvt(&evt_data); return IPACM_SUCCESS; } /* wan default route/filter rule configuration */ int IPACM_Wan::post_wan_down_tether_evt(ipa_ip_type iptype, int ipa_if_num_tether) { ipacm_cmd_q_data evt_data; ipacm_event_iface_up_tehter *wandown_data; int i, j; wandown_data = (ipacm_event_iface_up_tehter *)malloc(sizeof(ipacm_event_iface_up_tehter)); if (wandown_data == NULL) { IPACMERR("Unable to allocate memory\n"); return IPACM_FAILURE; } memset(wandown_data, 0, sizeof(ipacm_event_iface_up_tehter)); wandown_data->if_index_tether = ipa_if_num_tether; if (m_is_sta_mode!=Q6_WAN) { wandown_data->is_sta = true; } else { wandown_data->is_sta = false; } IPACMDBG_H("Posting IPA_HANDLE_WAN_DOWN_TETHER with below information:\n"); IPACMDBG_H("tether_if_name:%s, is sta mode:%d\n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether].iface_name, wandown_data->is_sta); memset(&evt_data, 0, sizeof(evt_data)); if (iptype == IPA_IP_v4) { evt_data.event = IPA_HANDLE_WAN_DOWN_TETHER; /* delete support tether ifaces to its array*/ for (i=0; i < IPACM_Wan::ipa_if_num_tether_v4_total; i++) { if(IPACM_Wan::ipa_if_num_tether_v4[i] == ipa_if_num_tether) { IPACMDBG_H("Found tether client at position %d name(%s)\n", i, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether].iface_name); break; } } if(i == IPACM_Wan::ipa_if_num_tether_v4_total) { IPACMDBG_H("Not finding the tether client.\n"); free(wandown_data); return IPACM_SUCCESS; } for(j = i+1; j < IPACM_Wan::ipa_if_num_tether_v4_total; j++) { IPACM_Wan::ipa_if_num_tether_v4[j-1] = IPACM_Wan::ipa_if_num_tether_v4[j]; } IPACM_Wan::ipa_if_num_tether_v4_total--; IPACMDBG_H("Now the total num of ipa_if_num_tether_v4_total is %d on wan-iface(%s)\n", IPACM_Wan::ipa_if_num_tether_v4_total, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name); } else { evt_data.event = IPA_HANDLE_WAN_DOWN_V6_TETHER; /* delete support tether ifaces to its array*/ for (i=0; i < IPACM_Wan::ipa_if_num_tether_v6_total; i++) { if(IPACM_Wan::ipa_if_num_tether_v6[i] == ipa_if_num_tether) { IPACMDBG_H("Found tether client at position %d name(%s)\n", i, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether].iface_name); break; } } if(i == IPACM_Wan::ipa_if_num_tether_v6_total) { IPACMDBG_H("Not finding the tether client.\n"); free(wandown_data); return IPACM_SUCCESS; } for(j = i+1; j < IPACM_Wan::ipa_if_num_tether_v6_total; j++) { IPACM_Wan::ipa_if_num_tether_v6[j-1] = IPACM_Wan::ipa_if_num_tether_v6[j]; } IPACM_Wan::ipa_if_num_tether_v6_total--; IPACMDBG_H("Now the total num of ipa_if_num_tether_v6_total is %d on wan-iface(%s)\n", IPACM_Wan::ipa_if_num_tether_v6_total, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name); } evt_data.evt_data = (void *)wandown_data; IPACM_EvtDispatcher::PostEvt(&evt_data); return IPACM_SUCCESS; } /* construct complete ethernet header */ int IPACM_Wan::handle_header_add_evt(uint8_t *mac_addr) { #define WAN_IFACE_INDEX_LEN 2 uint32_t tx_index,cnt; int res = IPACM_SUCCESS, len = 0; char index[WAN_IFACE_INDEX_LEN]; struct ipa_ioc_copy_hdr sCopyHeader; struct ipa_ioc_add_hdr *pHeaderDescriptor = NULL; /* start of adding header */ IPACMDBG_H("Received Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); if((header_set_v4 == true) || (header_set_v6 == true)) { IPACMDBG_H("Already add STA full header\n"); return IPACM_SUCCESS; } /* add header to IPA */ len = sizeof(struct ipa_ioc_add_hdr) + (1 * sizeof(struct ipa_hdr_add)); pHeaderDescriptor = (struct ipa_ioc_add_hdr *)calloc(1, len); if (pHeaderDescriptor == NULL) { IPACMERR("calloc failed to allocate pHeaderDescriptor\n"); return IPACM_FAILURE; } /* copy partial header for v4 */ for (cnt=0; cntnum_tx_props; cnt++) { if(tx_prop->tx[cnt].ip==IPA_IP_v4) { memset(&sCopyHeader, 0, sizeof(sCopyHeader)); memcpy(sCopyHeader.name, tx_prop->tx[cnt].hdr_name, sizeof(sCopyHeader.name)); IPACMDBG_H("header name: %s from tx: %d\n", sCopyHeader.name,cnt); if (m_header.CopyHeader(&sCopyHeader) == false) { IPACMERR("ioctl copy header failed"); res = IPACM_FAILURE; goto fail; } if(sCopyHeader.is_eth2_ofst_valid == false) { eth2_ofst_v4 = 0; } else { eth2_ofst_v4 = sCopyHeader.eth2_ofst; } IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial); if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE) { IPACMERR("header oversize\n"); res = IPACM_FAILURE; goto fail; } else { memcpy(pHeaderDescriptor->hdr[0].hdr, sCopyHeader.hdr, sCopyHeader.hdr_len); } /* copy client mac_addr to partial header */ memcpy(&pHeaderDescriptor->hdr[0].hdr[eth2_ofst_v4], mac_addr, IPA_MAC_ADDR_SIZE); /* only copy 6 bytes mac-address */ pHeaderDescriptor->commit = true; pHeaderDescriptor->num_hdrs = 1; memset(pHeaderDescriptor->hdr[0].name, 0, sizeof(pHeaderDescriptor->hdr[0].name)); snprintf(index,sizeof(index), "%d", ipa_if_num); strlcpy(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)); if ( strlcat(pHeaderDescriptor->hdr[0].name, IPA_WAN_PARTIAL_HDR_NAME_v4, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX) { IPACMERR(" header name construction failed exceed length (%d)\n", strlen(pHeaderDescriptor->hdr[0].name)); res = IPACM_FAILURE; goto fail; } pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len; pHeaderDescriptor->hdr[0].hdr_hdl = -1; pHeaderDescriptor->hdr[0].is_partial = 0; pHeaderDescriptor->hdr[0].status = -1; if (m_header.AddHeader(pHeaderDescriptor) == false || pHeaderDescriptor->hdr[0].status != 0) { IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status); res = IPACM_FAILURE; goto fail; } else { hdr_hdl_sta_v4 = pHeaderDescriptor->hdr[0].hdr_hdl; header_set_v4 = true; IPACMDBG_H("add full header name: %s (%x)\n", pHeaderDescriptor->hdr[0].name, pHeaderDescriptor->hdr[0].hdr_hdl); } /* copy ipv4 full header to each TX endpoint property*/ for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) { if(tx_prop->tx[tx_index].ip==IPA_IP_v4) { memcpy(tx_prop->tx[tx_index].hdr_name, pHeaderDescriptor->hdr[0].name, sizeof(tx_prop->tx[tx_index].hdr_name)); IPACMDBG_H("replace full header name: %s (%x) in tx:%d\n", tx_prop->tx[tx_index].hdr_name, pHeaderDescriptor->hdr[0].hdr_hdl,tx_index); } } break; } } /* copy partial header for v6 */ for (cnt=0; cntnum_tx_props; cnt++) { if(tx_prop->tx[cnt].ip == IPA_IP_v6) { IPACMDBG_H("Got partial v6-header name from %d tx props\n", cnt); memset(&sCopyHeader, 0, sizeof(sCopyHeader)); memcpy(sCopyHeader.name, tx_prop->tx[cnt].hdr_name, sizeof(sCopyHeader.name)); IPACMDBG_H("header name: %s from tx: %d\n", sCopyHeader.name,cnt); if (m_header.CopyHeader(&sCopyHeader) == false) { IPACMERR("ioctl copy header failed"); res = IPACM_FAILURE; goto fail; } if(sCopyHeader.is_eth2_ofst_valid == false) { eth2_ofst_v6 = 0; } else { eth2_ofst_v6 = sCopyHeader.eth2_ofst; } IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial); if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE) { IPACMERR("header oversize\n"); res = IPACM_FAILURE; goto fail; } else { memcpy(pHeaderDescriptor->hdr[0].hdr, sCopyHeader.hdr, sCopyHeader.hdr_len); } /* copy client mac_addr to partial header */ memcpy(&pHeaderDescriptor->hdr[0].hdr[eth2_ofst_v6], mac_addr, IPA_MAC_ADDR_SIZE); /* only copy 6 bytes mac-address */ pHeaderDescriptor->commit = true; pHeaderDescriptor->num_hdrs = 1; memset(pHeaderDescriptor->hdr[0].name, 0, sizeof(pHeaderDescriptor->hdr[0].name)); snprintf(index,sizeof(index), "%d", ipa_if_num); strlcpy(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)); if (strlcat(pHeaderDescriptor->hdr[0].name, IPA_WAN_PARTIAL_HDR_NAME_v6, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX) { IPACMERR(" header name construction failed exceed length (%d)\n", strlen(pHeaderDescriptor->hdr[0].name)); res = IPACM_FAILURE; goto fail; } pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len; pHeaderDescriptor->hdr[0].hdr_hdl = -1; pHeaderDescriptor->hdr[0].is_partial = 0; pHeaderDescriptor->hdr[0].status = -1; if (m_header.AddHeader(pHeaderDescriptor) == false || pHeaderDescriptor->hdr[0].status != 0) { IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status); res = IPACM_FAILURE; goto fail; } else { header_set_v6 = true; hdr_hdl_sta_v6 = pHeaderDescriptor->hdr[0].hdr_hdl; IPACMDBG_H("add full header name: %s (%x)\n", pHeaderDescriptor->hdr[0].name, pHeaderDescriptor->hdr[0].hdr_hdl); } /* copy ipv6 full header to each TX endpoint property*/ for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) { if(tx_prop->tx[tx_index].ip==IPA_IP_v6) { memcpy(tx_prop->tx[tx_index].hdr_name, pHeaderDescriptor->hdr[0].name, sizeof(tx_prop->tx[tx_index].hdr_name)); IPACMDBG_H("replace full header name: %s (%x) in tx:%d\n", tx_prop->tx[tx_index].hdr_name, pHeaderDescriptor->hdr[0].hdr_hdl,tx_index); } } break; } } /* see if default routes are setup before constructing full header */ if(header_partial_default_wan_v4 == true) { handle_route_add_evt(IPA_IP_v4); } if(header_partial_default_wan_v6 == true) { handle_route_add_evt(IPA_IP_v6); } fail: free(pHeaderDescriptor); return res; } /* for STA mode: add firewall rules */ int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype) { struct ipa_flt_rule_add flt_rule_entry; int i, rule_v4 = 0, rule_v6 = 0, len; IPACMDBG_H("ip-family: %d; \n", iptype); if (rx_prop == NULL) { IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); return IPACM_SUCCESS; } /* default firewall is disable and the rule action is drop */ memset(&firewall_config, 0, sizeof(firewall_config)); strncpy(firewall_config.firewall_config_file, "/etc/mobileap_firewall.xml", sizeof(firewall_config.firewall_config_file)); //if (firewall_config.firewall_config_file) { IPACMDBG_H("Firewall XML file is %s \n", firewall_config.firewall_config_file); if (IPACM_SUCCESS == IPACM_read_firewall_xml(firewall_config.firewall_config_file, &firewall_config)) { IPACMDBG_H("QCMAP Firewall XML read OK \n"); /* find the number of v4/v6 firewall rules */ for (i = 0; i < firewall_config.num_extd_firewall_entries; i++) { if (firewall_config.extd_firewall_entries[i].ip_vsn == 4) { rule_v4++; } else { rule_v6++; } } IPACMDBG_H("firewall rule v4:%d v6:%d total:%d\n", rule_v4, rule_v6, firewall_config.num_extd_firewall_entries); } else { IPACMERR("QCMAP Firewall XML read failed, no that file, use default configuration \n"); } } /*else { IPACMERR("No firewall xml mentioned \n"); return IPACM_FAILURE; }*/ /* construct ipa_ioc_add_flt_rule with N firewall rules */ ipa_ioc_add_flt_rule *m_pFilteringTable = NULL; len = sizeof(struct ipa_ioc_add_flt_rule) + 1 * sizeof(struct ipa_flt_rule_add); m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)calloc(1, len); if (!m_pFilteringTable) { IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); return IPACM_FAILURE; } if(iptype == IPA_IP_v6 && firewall_config.firewall_enable == true) { m_pFilteringTable->commit = 1; m_pFilteringTable->ep = rx_prop->rx[0].src_pipe; m_pFilteringTable->global = false; m_pFilteringTable->ip = IPA_IP_v6; m_pFilteringTable->num_rules = (uint8_t)1; memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); flt_rule_entry.at_rear = true; flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(struct ipa_rule_attrib)); flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR; flt_rule_entry.rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_FRAG_HDR; memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) { IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n"); free(m_pFilteringTable); return IPACM_FAILURE; } else { ipv6_frag_firewall_flt_rule_hdl = m_pFilteringTable->rules[0].flt_rule_hdl; IPACMDBG_H("Installed IPv6 frag firewall rule, handle %d.\n", ipv6_frag_firewall_flt_rule_hdl); } } if (iptype == IPA_IP_v4) { if (rule_v4 == 0) { memset(m_pFilteringTable, 0, len); m_pFilteringTable->commit = 1; m_pFilteringTable->ep = rx_prop->rx[0].src_pipe; m_pFilteringTable->global = false; m_pFilteringTable->ip = IPA_IP_v4; m_pFilteringTable->num_rules = (uint8_t)1; memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_lan_v4)) { IPACMERR("m_routing.GetRoutingTable(rt_tbl_lan_v4) Failed.\n"); free(m_pFilteringTable); return IPACM_FAILURE; } flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; /* firewall disable, all traffic are allowed */ if(firewall_config.firewall_enable == true) { flt_rule_entry.at_rear = true; /* default action for v4 is go DST_NAT unless user set to exception*/ if(firewall_config.rule_action_accept == true) { flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; } else { flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT; } } else { flt_rule_entry.at_rear = true; flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT; } flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.hdl; memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(struct ipa_rule_attrib)); flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x00000000; flt_rule_entry.rule.attrib.u.v4.dst_addr = 0x00000000; memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) { IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n"); free(m_pFilteringTable); return IPACM_FAILURE; } else { IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status); } /* copy filter hdls */ dft_wan_fl_hdl[0] = m_pFilteringTable->rules[0].flt_rule_hdl; } else { memset(m_pFilteringTable, 0, len); m_pFilteringTable->commit = 1; m_pFilteringTable->ep = rx_prop->rx[0].src_pipe; m_pFilteringTable->global = false; m_pFilteringTable->ip = IPA_IP_v4; m_pFilteringTable->num_rules = (uint8_t)1; IPACMDBG_H("Retreiving Routing handle for routing table name:%s\n", IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name); if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_lan_v4)) { IPACMERR("m_routing.GetRoutingTable(&rt_tbl_lan_v4=0x%p) Failed.\n", &IPACM_Iface::ipacmcfg->rt_tbl_lan_v4); free(m_pFilteringTable); return IPACM_FAILURE; } IPACMDBG_H("Routing handle for wan routing table:0x%x\n", IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.hdl); if(firewall_config.firewall_enable == true) { rule_v4 = 0; for (i = 0; i < firewall_config.num_extd_firewall_entries; i++) { if (firewall_config.extd_firewall_entries[i].ip_vsn == 4) { memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); flt_rule_entry.at_rear = true; flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.hdl; /* Accept v4 matched rules*/ if(firewall_config.rule_action_accept == true) { flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT; } else { flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; } memcpy(&flt_rule_entry.rule.attrib, &firewall_config.extd_firewall_entries[i].attrib, sizeof(struct ipa_rule_attrib)); IPACMDBG_H("rx property attrib mask: 0x%x\n", rx_prop->rx[0].attrib.attrib_mask); flt_rule_entry.rule.attrib.attrib_mask |= rx_prop->rx[0].attrib.attrib_mask; flt_rule_entry.rule.attrib.meta_data_mask = rx_prop->rx[0].attrib.meta_data_mask; flt_rule_entry.rule.attrib.meta_data = rx_prop->rx[0].attrib.meta_data; /* check if the rule is define as TCP_UDP, split into 2 rules, 1 for TCP and 1 UDP */ if (firewall_config.extd_firewall_entries[i].attrib.u.v4.protocol == IPACM_FIREWALL_IPPROTO_TCP_UDP) { /* insert TCP rule*/ flt_rule_entry.rule.attrib.u.v4.protocol = IPACM_FIREWALL_IPPROTO_TCP; memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); IPACMDBG_H("Filter rule attrib mask: 0x%x\n", m_pFilteringTable->rules[0].rule.attrib.attrib_mask); if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) { IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n"); free(m_pFilteringTable); return IPACM_FAILURE; } else { /* save v4 firewall filter rule handler */ IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[rule_v4].flt_rule_hdl, m_pFilteringTable->rules[rule_v4].status); firewall_hdl_v4[rule_v4] = m_pFilteringTable->rules[0].flt_rule_hdl; num_firewall_v4++; rule_v4++; } /* insert UDP rule*/ flt_rule_entry.rule.attrib.u.v4.protocol = IPACM_FIREWALL_IPPROTO_UDP; memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); IPACMDBG_H("Filter rule attrib mask: 0x%x\n", m_pFilteringTable->rules[0].rule.attrib.attrib_mask); if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) { IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n"); free(m_pFilteringTable); return IPACM_FAILURE; } else { /* save v4 firewall filter rule handler */ IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[rule_v4].flt_rule_hdl, m_pFilteringTable->rules[rule_v4].status); firewall_hdl_v4[rule_v4] = m_pFilteringTable->rules[0].flt_rule_hdl; num_firewall_v4++; rule_v4++; } } else { memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); IPACMDBG_H("Filter rule attrib mask: 0x%x\n", m_pFilteringTable->rules[0].rule.attrib.attrib_mask); if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) { IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n"); free(m_pFilteringTable); return IPACM_FAILURE; } else { /* save v4 firewall filter rule handler */ IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[rule_v4].flt_rule_hdl, m_pFilteringTable->rules[rule_v4].status); firewall_hdl_v4[rule_v4] = m_pFilteringTable->rules[0].flt_rule_hdl; num_firewall_v4++; rule_v4++; } } } } /* end of firewall ipv4 filter rule add for loop*/ } /* configure default filter rule */ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; /* firewall disable, all traffic are allowed */ if(firewall_config.firewall_enable == true) { flt_rule_entry.at_rear = true; /* default action for v4 is go DST_NAT unless user set to exception*/ if(firewall_config.rule_action_accept == true) { flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; } else { flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT; } } else { flt_rule_entry.at_rear = true; flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT; } flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.hdl; memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(struct ipa_rule_attrib)); flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x00000000; flt_rule_entry.rule.attrib.u.v4.dst_addr = 0x00000000; memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); IPACMDBG_H("Filter rule attrib mask: 0x%x\n", m_pFilteringTable->rules[0].rule.attrib.attrib_mask); if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) { IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n"); free(m_pFilteringTable); return IPACM_FAILURE; } else { IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status); } /* copy filter hdls */ dft_wan_fl_hdl[0] = m_pFilteringTable->rules[0].flt_rule_hdl; } } else { if (rule_v6 == 0) { memset(m_pFilteringTable, 0, len); m_pFilteringTable->commit = 1; m_pFilteringTable->ep = rx_prop->rx[0].src_pipe; m_pFilteringTable->global = false; m_pFilteringTable->ip = IPA_IP_v6; m_pFilteringTable->num_rules = (uint8_t)1; /* Construct ICMP rule */ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); flt_rule_entry.at_rear = true; flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.retain_hdr = 1; flt_rule_entry.rule.eq_attrib_type = 0; flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(struct ipa_rule_attrib)); flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR; flt_rule_entry.rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_ICMP6; memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) { IPACMERR("Error Adding Filtering rules, aborting...\n"); free(m_pFilteringTable); return IPACM_FAILURE; } else { IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status); } /* copy filter hdls */ dft_wan_fl_hdl[2] = m_pFilteringTable->rules[0].flt_rule_hdl; /* End of construct ICMP rule */ /* v6 default route */ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_wan_v6)) //rt_tbl_wan_v6 rt_tbl_v6 { IPACMERR("m_routing.GetRoutingTable(rt_tbl_wan_v6) Failed.\n"); free(m_pFilteringTable); return IPACM_FAILURE; } flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.hdl; /* firewall disable, all traffic are allowed */ if(firewall_config.firewall_enable == true) { flt_rule_entry.at_rear = true; /* default action for v6 is PASS_TO_ROUTE unless user set to exception*/ if(firewall_config.rule_action_accept == true) { flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; } else { flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; } } else { flt_rule_entry.at_rear = true; flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; } memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(struct ipa_rule_attrib)); flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0X00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000; memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) { IPACMERR("Error Adding Filtering rules, aborting...\n"); free(m_pFilteringTable); return IPACM_FAILURE; } else { IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status); } /* copy filter hdls */ dft_wan_fl_hdl[1] = m_pFilteringTable->rules[0].flt_rule_hdl; } else { memset(m_pFilteringTable, 0, len); m_pFilteringTable->commit = 1; m_pFilteringTable->ep = rx_prop->rx[0].src_pipe; m_pFilteringTable->global = false; m_pFilteringTable->ip = IPA_IP_v6; m_pFilteringTable->num_rules = (uint8_t)1; if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_wan_v6)) { IPACMERR("m_routing.GetRoutingTable(rt_tbl_wan_v6) Failed.\n"); free(m_pFilteringTable); return IPACM_FAILURE; } if(firewall_config.firewall_enable == true) { rule_v6 = 0; for (i = 0; i < firewall_config.num_extd_firewall_entries; i++) { if (firewall_config.extd_firewall_entries[i].ip_vsn == 6) { memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); flt_rule_entry.at_rear = true; flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; /* matched rules for v6 go PASS_TO_ROUTE */ if(firewall_config.rule_action_accept == true) { flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; } else { flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; } flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.hdl; memcpy(&flt_rule_entry.rule.attrib, &firewall_config.extd_firewall_entries[i].attrib, sizeof(struct ipa_rule_attrib)); flt_rule_entry.rule.attrib.attrib_mask |= rx_prop->rx[0].attrib.attrib_mask; flt_rule_entry.rule.attrib.meta_data_mask = rx_prop->rx[0].attrib.meta_data_mask; flt_rule_entry.rule.attrib.meta_data = rx_prop->rx[0].attrib.meta_data; /* check if the rule is define as TCP/UDP */ if (firewall_config.extd_firewall_entries[i].attrib.u.v6.next_hdr == IPACM_FIREWALL_IPPROTO_TCP_UDP) { /* insert TCP rule*/ flt_rule_entry.rule.attrib.u.v6.next_hdr = IPACM_FIREWALL_IPPROTO_TCP; memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) { IPACMERR("Error Adding Filtering rules, aborting...\n"); free(m_pFilteringTable); return IPACM_FAILURE; } else { /* save v4 firewall filter rule handler */ IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status); firewall_hdl_v6[rule_v6] = m_pFilteringTable->rules[0].flt_rule_hdl; num_firewall_v6++; rule_v6++; } /* insert UDP rule*/ flt_rule_entry.rule.attrib.u.v6.next_hdr = IPACM_FIREWALL_IPPROTO_UDP; memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) { IPACMERR("Error Adding Filtering rules, aborting...\n"); free(m_pFilteringTable); return IPACM_FAILURE; } else { /* save v6 firewall filter rule handler */ IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status); firewall_hdl_v6[rule_v6] = m_pFilteringTable->rules[0].flt_rule_hdl; num_firewall_v6++; rule_v6++; } } else { memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) { IPACMERR("Error Adding Filtering rules, aborting...\n"); free(m_pFilteringTable); return IPACM_FAILURE; } else { /* save v6 firewall filter rule handler */ IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status); firewall_hdl_v6[rule_v6] = m_pFilteringTable->rules[0].flt_rule_hdl; num_firewall_v6++; rule_v6++; } } } } /* end of firewall ipv6 filter rule add for loop*/ } /* Construct ICMP rule */ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); flt_rule_entry.at_rear = true; flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.retain_hdr = 1; flt_rule_entry.rule.eq_attrib_type = 0; flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(struct ipa_rule_attrib)); flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR; flt_rule_entry.rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_ICMP6; memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) { IPACMERR("Error Adding Filtering rules, aborting...\n"); free(m_pFilteringTable); return IPACM_FAILURE; } else { IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status); } /* copy filter hdls */ dft_wan_fl_hdl[2] = m_pFilteringTable->rules[0].flt_rule_hdl; /* End of construct ICMP rule */ /* setup default wan filter rule */ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.hdl; /* firewall disable, all traffic are allowed */ if(firewall_config.firewall_enable == true) { flt_rule_entry.at_rear = true; /* default action for v6 is PASS_TO_ROUTE unless user set to exception*/ if(firewall_config.rule_action_accept == true) { flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; } else { flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; } } else { flt_rule_entry.at_rear = true; flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; } memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(struct ipa_rule_attrib)); flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0X00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000; memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) { IPACMERR("Error Adding Filtering rules, aborting...\n"); free(m_pFilteringTable); return IPACM_FAILURE; } else { IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status); } /* copy filter hdls*/ dft_wan_fl_hdl[1] = m_pFilteringTable->rules[0].flt_rule_hdl; } } if(m_pFilteringTable != NULL) { free(m_pFilteringTable); } return IPACM_SUCCESS; } /* configure the initial firewall filter rules */ int IPACM_Wan::config_dft_firewall_rules_ex(struct ipa_flt_rule_add *rules, int rule_offset, ipa_ip_type iptype) { struct ipa_flt_rule_add flt_rule_entry; int i; int num_rules = 0, original_num_rules = 0; ipa_ioc_get_rt_tbl_indx rt_tbl_idx; ipa_ioc_generate_flt_eq flt_eq; int pos = rule_offset; IPACMDBG_H("ip-family: %d; \n", iptype); if (rx_prop == NULL) { IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); return IPACM_SUCCESS; } if(rules == NULL || rule_offset < 0) { IPACMERR("No filtering table is available.\n"); return IPACM_FAILURE; } /* default firewall is disable and the rule action is drop */ memset(&firewall_config, 0, sizeof(firewall_config)); strncpy(firewall_config.firewall_config_file, "/etc/mobileap_firewall.xml", sizeof(firewall_config.firewall_config_file)); //if (firewall_config.firewall_config_file) { IPACMDBG_H("Firewall XML file is %s \n", firewall_config.firewall_config_file); if (IPACM_SUCCESS == IPACM_read_firewall_xml(firewall_config.firewall_config_file, &firewall_config)) { IPACMDBG_H("QCMAP Firewall XML read OK \n"); } else { IPACMERR("QCMAP Firewall XML read failed, no that file, use default configuration \n"); } } /*else //{ IPACMERR("No firewall xml mentioned \n"); return IPACM_FAILURE; }*/ /* add IPv6 frag rule when firewall is enabled*/ if(iptype == IPA_IP_v6 && firewall_config.firewall_enable == true) { memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); flt_rule_entry.at_rear = true; flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.retain_hdr = 1; flt_rule_entry.rule.to_uc = 0; flt_rule_entry.rule.eq_attrib_type = 1; flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); rt_tbl_idx.ip = IPA_IP_v6; strncpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX); if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx)) { IPACMERR("Failed to get routing table index from name\n"); return IPACM_FAILURE; } flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; IPACMDBG_H("IPv6 frag flt rule uses routing table index %d\n", rt_tbl_idx.idx); flt_rule_entry.rule.attrib.attrib_mask |= rx_prop->rx[0].attrib.attrib_mask; flt_rule_entry.rule.attrib.meta_data_mask = rx_prop->rx[0].attrib.meta_data_mask; flt_rule_entry.rule.attrib.meta_data = rx_prop->rx[0].attrib.meta_data; flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR; flt_rule_entry.rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_FRAG_HDR; change_to_network_order(IPA_IP_v6, &flt_rule_entry.rule.attrib); memset(&flt_eq, 0, sizeof(flt_eq)); memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); flt_eq.ip = IPA_IP_v6; if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) { IPACMERR("Failed to get eq_attrib\n"); return IPACM_FAILURE; } memcpy(&flt_rule_entry.rule.eq_attrib, &flt_eq.eq_attrib, sizeof(flt_rule_entry.rule.eq_attrib)); memcpy(&(rules[pos]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); pos++; IPACM_Wan::num_v6_flt_rule++; } if (iptype == IPA_IP_v4) { original_num_rules = IPACM_Wan::num_v4_flt_rule; if(firewall_config.firewall_enable == true) { for (i = 0; i < firewall_config.num_extd_firewall_entries; i++) { if (firewall_config.extd_firewall_entries[i].ip_vsn == 4) { memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); flt_rule_entry.at_rear = true; flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.retain_hdr = 1; flt_rule_entry.rule.to_uc = 0; flt_rule_entry.rule.eq_attrib_type = 1; /* Accept v4 matched rules*/ if(firewall_config.rule_action_accept == true) { flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT; } else { flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; } memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); rt_tbl_idx.ip = iptype; if(flt_rule_entry.rule.action == IPA_PASS_TO_ROUTING) { strncpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX); } else /*pass to dst nat*/ { strncpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name, IPA_RESOURCE_NAME_MAX); } if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx)) { IPACMERR("Failed to get routing table index from name\n"); return IPACM_FAILURE; } flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; IPACMDBG_H("Routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx); memcpy(&flt_rule_entry.rule.attrib, &firewall_config.extd_firewall_entries[i].attrib, sizeof(struct ipa_rule_attrib)); flt_rule_entry.rule.attrib.attrib_mask |= rx_prop->rx[0].attrib.attrib_mask; flt_rule_entry.rule.attrib.meta_data_mask = rx_prop->rx[0].attrib.meta_data_mask; flt_rule_entry.rule.attrib.meta_data = rx_prop->rx[0].attrib.meta_data; change_to_network_order(IPA_IP_v4, &flt_rule_entry.rule.attrib); /* check if the rule is define as TCP_UDP, split into 2 rules, 1 for TCP and 1 UDP */ if (firewall_config.extd_firewall_entries[i].attrib.u.v4.protocol == IPACM_FIREWALL_IPPROTO_TCP_UDP) { /* insert TCP rule*/ flt_rule_entry.rule.attrib.u.v4.protocol = IPACM_FIREWALL_IPPROTO_TCP; memset(&flt_eq, 0, sizeof(flt_eq)); memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); flt_eq.ip = iptype; if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) { IPACMERR("Failed to get eq_attrib\n"); return IPACM_FAILURE; } memcpy(&flt_rule_entry.rule.eq_attrib, &flt_eq.eq_attrib, sizeof(flt_rule_entry.rule.eq_attrib)); memcpy(&(rules[pos]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); IPACMDBG_H("Filter rule attrib mask: 0x%x\n", rules[pos].rule.attrib.attrib_mask); pos++; num_firewall_v4++; IPACM_Wan::num_v4_flt_rule++; /* insert UDP rule*/ flt_rule_entry.rule.attrib.u.v4.protocol = IPACM_FIREWALL_IPPROTO_UDP; memset(&flt_eq, 0, sizeof(flt_eq)); memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); flt_eq.ip = iptype; if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) { IPACMERR("Failed to get eq_attrib\n"); return IPACM_FAILURE; } memcpy(&flt_rule_entry.rule.eq_attrib, &flt_eq.eq_attrib, sizeof(flt_rule_entry.rule.eq_attrib)); memcpy(&(rules[pos]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); IPACMDBG_H("Filter rule attrib mask: 0x%x\n", rules[pos].rule.attrib.attrib_mask); pos++; num_firewall_v4++; IPACM_Wan::num_v4_flt_rule++; } else { memset(&flt_eq, 0, sizeof(flt_eq)); memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); flt_eq.ip = iptype; if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) { IPACMERR("Failed to get eq_attrib\n"); return IPACM_FAILURE; } memcpy(&flt_rule_entry.rule.eq_attrib, &flt_eq.eq_attrib, sizeof(flt_rule_entry.rule.eq_attrib)); memcpy(&(rules[pos]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); IPACMDBG_H("Filter rule attrib mask: 0x%x\n", rules[pos].rule.attrib.attrib_mask); pos++; num_firewall_v4++; IPACM_Wan::num_v4_flt_rule++; } } } /* end of firewall ipv4 filter rule add for loop*/ } /* configure default filter rule */ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); flt_rule_entry.at_rear = true; flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.retain_hdr = 1; flt_rule_entry.rule.to_uc = 0; flt_rule_entry.rule.eq_attrib_type = 1; /* firewall disable, all traffic are allowed */ if(firewall_config.firewall_enable == true) { /* default action for v4 is go DST_NAT unless user set to exception*/ if(firewall_config.rule_action_accept == true) { flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; } else { flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT; } } else { flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT; } memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); rt_tbl_idx.ip = iptype; if(flt_rule_entry.rule.action == IPA_PASS_TO_ROUTING) { strncpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX); } else /*pass to dst nat*/ { strncpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name, IPA_RESOURCE_NAME_MAX); } if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx)) { IPACMERR("Failed to get routing table index from name\n"); return IPACM_FAILURE; } flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; IPACMDBG_H("Routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx); memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(struct ipa_rule_attrib)); flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x00000000; flt_rule_entry.rule.attrib.u.v4.dst_addr = 0x00000000; change_to_network_order(IPA_IP_v4, &flt_rule_entry.rule.attrib); memset(&flt_eq, 0, sizeof(flt_eq)); memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); flt_eq.ip = iptype; if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) { IPACMERR("Failed to get eq_attrib\n"); return IPACM_FAILURE; } memcpy(&flt_rule_entry.rule.eq_attrib, &flt_eq.eq_attrib, sizeof(flt_rule_entry.rule.eq_attrib)); memcpy(&(rules[pos]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); IPACMDBG_H("Filter rule attrib mask: 0x%x\n", rules[pos].rule.attrib.attrib_mask); pos++; num_firewall_v4++; IPACM_Wan::num_v4_flt_rule++; num_rules = IPACM_Wan::num_v4_flt_rule - original_num_rules - 1; } else { original_num_rules = IPACM_Wan::num_v6_flt_rule; if(firewall_config.firewall_enable == true) { for (i = 0; i < firewall_config.num_extd_firewall_entries; i++) { if (firewall_config.extd_firewall_entries[i].ip_vsn == 6) { memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); flt_rule_entry.at_rear = true; flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.retain_hdr = 1; flt_rule_entry.rule.to_uc = 0; flt_rule_entry.rule.eq_attrib_type = 1; flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); rt_tbl_idx.ip = iptype; /* matched rules for v6 go PASS_TO_ROUTE */ if(firewall_config.rule_action_accept == true) { strncpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, IPA_RESOURCE_NAME_MAX); } else { strncpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX); } if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx)) { IPACMERR("Failed to get routing table index from name\n"); return IPACM_FAILURE; } flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; IPACMDBG_H("Routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx); memcpy(&flt_rule_entry.rule.attrib, &firewall_config.extd_firewall_entries[i].attrib, sizeof(struct ipa_rule_attrib)); flt_rule_entry.rule.attrib.attrib_mask |= rx_prop->rx[0].attrib.attrib_mask; flt_rule_entry.rule.attrib.meta_data_mask = rx_prop->rx[0].attrib.meta_data_mask; flt_rule_entry.rule.attrib.meta_data = rx_prop->rx[0].attrib.meta_data; change_to_network_order(IPA_IP_v6, &flt_rule_entry.rule.attrib); /* check if the rule is define as TCP/UDP */ if (firewall_config.extd_firewall_entries[i].attrib.u.v6.next_hdr == IPACM_FIREWALL_IPPROTO_TCP_UDP) { /* insert TCP rule*/ flt_rule_entry.rule.attrib.u.v6.next_hdr = IPACM_FIREWALL_IPPROTO_TCP; memset(&flt_eq, 0, sizeof(flt_eq)); memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); flt_eq.ip = iptype; if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) { IPACMERR("Failed to get eq_attrib\n"); return IPACM_FAILURE; } memcpy(&flt_rule_entry.rule.eq_attrib, &flt_eq.eq_attrib, sizeof(flt_rule_entry.rule.eq_attrib)); memcpy(&(rules[pos]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); pos++; num_firewall_v6++; IPACM_Wan::num_v6_flt_rule++; /* insert UDP rule*/ flt_rule_entry.rule.attrib.u.v6.next_hdr = IPACM_FIREWALL_IPPROTO_UDP; memset(&flt_eq, 0, sizeof(flt_eq)); memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); flt_eq.ip = iptype; if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) { IPACMERR("Failed to get eq_attrib\n"); return IPACM_FAILURE; } memcpy(&flt_rule_entry.rule.eq_attrib, &flt_eq.eq_attrib, sizeof(flt_rule_entry.rule.eq_attrib)); memcpy(&(rules[pos]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); pos++; num_firewall_v6++; IPACM_Wan::num_v6_flt_rule++; } else { memset(&flt_eq, 0, sizeof(flt_eq)); memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); flt_eq.ip = iptype; if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) { IPACMERR("Failed to get eq_attrib\n"); return IPACM_FAILURE; } memcpy(&flt_rule_entry.rule.eq_attrib, &flt_eq.eq_attrib, sizeof(flt_rule_entry.rule.eq_attrib)); memcpy(&(rules[pos]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); pos++; num_firewall_v6++; IPACM_Wan::num_v6_flt_rule++; } } } /* end of firewall ipv6 filter rule add for loop*/ } /* setup default wan filter rule */ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); flt_rule_entry.at_rear = true; flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.retain_hdr = 1; flt_rule_entry.rule.to_uc = 0; flt_rule_entry.rule.eq_attrib_type = 1; flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); rt_tbl_idx.ip = iptype; /* firewall disable, all traffic are allowed */ if(firewall_config.firewall_enable == true) { /* default action for v6 is PASS_TO_ROUTE unless user set to exception*/ if(firewall_config.rule_action_accept == true) { strncpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX); } else { strncpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, IPA_RESOURCE_NAME_MAX); } } else { strncpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, IPA_RESOURCE_NAME_MAX); } if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx)) { IPACMERR("Failed to get routing table index from name\n"); return IPACM_FAILURE; } flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; IPACMDBG_H("Routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx); memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[1].attrib, sizeof(struct ipa_rule_attrib)); flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0X00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000; change_to_network_order(IPA_IP_v6, &flt_rule_entry.rule.attrib); memset(&flt_eq, 0, sizeof(flt_eq)); memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); flt_eq.ip = iptype; if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) { IPACMERR("Failed to get eq_attrib\n"); return IPACM_FAILURE; } memcpy(&flt_rule_entry.rule.eq_attrib, &flt_eq.eq_attrib, sizeof(flt_rule_entry.rule.eq_attrib)); memcpy(&(rules[pos]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); pos++; num_firewall_v6++; IPACM_Wan::num_v6_flt_rule++; num_rules = IPACM_Wan::num_v6_flt_rule - original_num_rules - 1; } IPACMDBG_H("Constructed %d firewall rules for ip type %d\n", num_rules, iptype); return IPACM_SUCCESS; } int IPACM_Wan::init_fl_rule_ex(ipa_ip_type iptype) { int res = IPACM_SUCCESS; char *dev_wlan0="wlan0"; char *dev_wlan1="wlan1"; char *dev_ecm0="ecm0"; /* update the iface ip-type to be IPA_IP_v4, IPA_IP_v6 or both*/ if (iptype == IPA_IP_v4) { if ((ip_type == IPA_IP_v4) || (ip_type == IPA_IP_MAX)) { IPACMDBG_H(" interface(%s:%d) already in ip-type %d\n", dev_name, ipa_if_num, ip_type); return res; } if (ip_type == IPA_IP_v6) { ip_type = IPA_IP_MAX; } else { ip_type = IPA_IP_v4; } IPACMDBG_H(" interface(%s:%d) now ip-type is %d\n", dev_name, ipa_if_num, ip_type); } else { if ((ip_type == IPA_IP_v6) || (ip_type == IPA_IP_MAX)) { IPACMDBG_H(" interface(%s:%d) already in ip-type %d\n", dev_name, ipa_if_num, ip_type); return res; } if (ip_type == IPA_IP_v4) { ip_type = IPA_IP_MAX; } else { ip_type = IPA_IP_v6; } IPACMDBG_H(" interface(%s:%d) now ip-type is %d\n", dev_name, ipa_if_num, ip_type); } /* ADD corresponding ipa_rm_resource_name of RX-endpoint before adding all IPV4V6 FT-rules */ IPACMDBG_H(" dun add producer dependency from %s with registered rx-prop\n", dev_name); if(iptype == IPA_IP_v4) { if(modem_ipv4_pdn_index == 0) //install ipv4 default modem DL filtering rules only once { /* reset the num_v4_flt_rule*/ IPACM_Wan::num_v4_flt_rule = 0; add_dft_filtering_rule(flt_rule_v4, IPACM_Wan::num_v4_flt_rule, IPA_IP_v4); } } else if(iptype == IPA_IP_v6) { if(modem_ipv6_pdn_index == 0) //install ipv6 default modem DL filtering rules only once { /* reset the num_v6_flt_rule*/ IPACM_Wan::num_v6_flt_rule = 0; add_dft_filtering_rule(flt_rule_v6, IPACM_Wan::num_v6_flt_rule, IPA_IP_v6); } } else { IPACMERR("IP type is not expected.\n"); res = IPACM_FAILURE; goto fail; } install_wan_filtering_rule(false); fail: return res; } int IPACM_Wan::add_icmp_alg_rules(struct ipa_flt_rule_add *rules, int rule_offset, ipa_ip_type iptype) { int res = IPACM_SUCCESS, i, original_num_rules = 0, num_rules = 0; struct ipa_flt_rule_add flt_rule_entry; IPACM_Config* ipacm_config = IPACM_Iface::ipacmcfg; ipa_ioc_generate_flt_eq flt_eq; ipa_ioc_get_rt_tbl_indx rt_tbl_idx; if(rules == NULL || rule_offset < 0) { IPACMERR("No filtering table is available.\n"); return IPACM_FAILURE; } if(iptype == IPA_IP_v4) { original_num_rules = IPACM_Wan::num_v4_flt_rule; memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); strncpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX); rt_tbl_idx.ip = iptype; if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx)) { IPACMERR("Failed to get routing table index from name\n"); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("WAN DL routing table %s has index %d\n", IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, rt_tbl_idx.idx); memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); flt_rule_entry.at_rear = true; flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.retain_hdr = 1; flt_rule_entry.rule.to_uc = 0; flt_rule_entry.rule.eq_attrib_type = 1; flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; /* Configuring ICMP filtering rule */ memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); /* remove meta data mask */ flt_rule_entry.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA); flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_PROTOCOL; flt_rule_entry.rule.attrib.u.v4.protocol = (uint8_t)IPACM_FIREWALL_IPPROTO_ICMP; memset(&flt_eq, 0, sizeof(flt_eq)); memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); flt_eq.ip = iptype; if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) { IPACMERR("Failed to get eq_attrib\n"); res = IPACM_FAILURE; goto fail; } memcpy(&flt_rule_entry.rule.eq_attrib, &flt_eq.eq_attrib, sizeof(flt_rule_entry.rule.eq_attrib)); memcpy(&(rules[rule_offset]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); IPACM_Wan::num_v4_flt_rule++; /* Configure ALG filtering rules */ memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); /* remove meta data mask */ flt_rule_entry.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA); flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_SRC_PORT; flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_PROTOCOL; for(i = 0; i < ipacm_config->ipa_num_alg_ports; i++) { flt_rule_entry.rule.attrib.src_port = ipacm_config->alg_table[i].port; flt_rule_entry.rule.attrib.u.v4.protocol = ipacm_config->alg_table[i].protocol; memset(&flt_eq, 0, sizeof(flt_eq)); memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); flt_eq.ip = iptype; if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) { IPACMERR("Failed to get eq_attrib\n"); res = IPACM_FAILURE; goto fail; } memcpy(&flt_rule_entry.rule.eq_attrib, &flt_eq.eq_attrib, sizeof(flt_rule_entry.rule.eq_attrib)); memcpy(&(rules[rule_offset + 1 + i]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); IPACM_Wan::num_v4_flt_rule++; } memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); /* remove meta data mask */ flt_rule_entry.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA); flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_PORT; flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_PROTOCOL; for(i = 0; i < ipacm_config->ipa_num_alg_ports; i++) { flt_rule_entry.rule.attrib.dst_port = ipacm_config->alg_table[i].port; flt_rule_entry.rule.attrib.u.v4.protocol = ipacm_config->alg_table[i].protocol; memset(&flt_eq, 0, sizeof(flt_eq)); memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); flt_eq.ip = iptype; if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) { IPACMERR("Failed to get eq_attrib\n"); res = IPACM_FAILURE; goto fail; } memcpy(&flt_rule_entry.rule.eq_attrib, &flt_eq.eq_attrib, sizeof(flt_rule_entry.rule.eq_attrib)); memcpy(&(rules[rule_offset + ipacm_config->ipa_num_alg_ports + 1 + i]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); IPACM_Wan::num_v4_flt_rule++; } num_rules = IPACM_Wan::num_v4_flt_rule - original_num_rules; } else /* IPv6 case */ { original_num_rules = IPACM_Wan::num_v6_flt_rule; memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); strncpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX); rt_tbl_idx.ip = iptype; if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx)) { IPACMERR("Failed to get routing table index from name\n"); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("WAN DL routing table %s has index %d\n", IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, rt_tbl_idx.idx); memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); flt_rule_entry.at_rear = true; flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.retain_hdr = 1; flt_rule_entry.rule.to_uc = 0; flt_rule_entry.rule.eq_attrib_type = 1; flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; /* Configuring ICMP filtering rule */ memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[1].attrib, sizeof(flt_rule_entry.rule.attrib)); /* remove meta data mask */ flt_rule_entry.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA); flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR; flt_rule_entry.rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_ICMP6; memset(&flt_eq, 0, sizeof(flt_eq)); memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); flt_eq.ip = iptype; if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) { IPACMERR("Failed to get eq_attrib\n"); res = IPACM_FAILURE; goto fail; } memcpy(&flt_rule_entry.rule.eq_attrib, &flt_eq.eq_attrib, sizeof(flt_rule_entry.rule.eq_attrib)); memcpy(&(rules[rule_offset]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); IPACM_Wan::num_v6_flt_rule++; num_rules = IPACM_Wan::num_v6_flt_rule - original_num_rules; } fail: IPACMDBG_H("Constructed %d ICMP/ALG rules for ip type %d\n", num_rules, iptype); return res; } int IPACM_Wan::query_ext_prop() { int fd, ret = IPACM_SUCCESS, cnt; if (iface_query->num_ext_props > 0) { fd = open(IPA_DEVICE_NAME, O_RDWR); IPACMDBG_H("iface query-property \n"); if (0 == fd) { IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME); return IPACM_FAILURE; } ext_prop = (struct ipa_ioc_query_intf_ext_props *) calloc(1, sizeof(struct ipa_ioc_query_intf_ext_props) + iface_query->num_ext_props * sizeof(struct ipa_ioc_ext_intf_prop)); if(ext_prop == NULL) { IPACMERR("Unable to allocate memory.\n"); return IPACM_FAILURE; } memcpy(ext_prop->name, dev_name, sizeof(dev_name)); ext_prop->num_ext_props = iface_query->num_ext_props; IPACMDBG_H("Query extended property for iface %s\n", ext_prop->name); ret = ioctl(fd, IPA_IOC_QUERY_INTF_EXT_PROPS, ext_prop); if (ret < 0) { IPACMERR("ioctl IPA_IOC_QUERY_INTF_EXT_PROPS failed\n"); /* ext_prop memory will free when iface-down*/ free(ext_prop); close(fd); return ret; } IPACMDBG_H("Wan interface has %d tx props, %d rx props and %d ext props\n", iface_query->num_tx_props, iface_query->num_rx_props, iface_query->num_ext_props); for (cnt = 0; cnt < ext_prop->num_ext_props; cnt++) { IPACMDBG_H("Ex(%d): ip-type: %d, mux_id: %d, flt_action: %d\n, rt_tbl_idx: %d, flt_hdr: %d \n", cnt, ext_prop->ext[cnt].ip, ext_prop->ext[cnt].mux_id, ext_prop->ext[cnt].action, ext_prop->ext[cnt].rt_tbl_idx, ext_prop->ext[cnt].filter_hdl); } if(IPACM_Wan::is_ext_prop_set == false) { IPACM_Iface::ipacmcfg->SetExtProp(ext_prop); IPACM_Wan::is_ext_prop_set = true; } close(fd); } return IPACM_SUCCESS; } int IPACM_Wan::config_wan_firewall_rule(ipa_ip_type iptype) { int res = IPACM_SUCCESS; IPACMDBG_H("Configure WAN DL firewall rules.\n"); if(iptype == IPA_IP_v4) { IPACM_Wan::num_v4_flt_rule = IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV4; if(IPACM_FAILURE == add_icmp_alg_rules(flt_rule_v4, IPACM_Wan::num_v4_flt_rule, IPA_IP_v4)) { IPACMERR("Failed to add ICMP and ALG port filtering rules.\n"); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("Succeded in constructing ICMP/ALG rules for ip type %d\n", iptype); if(IPACM_FAILURE == config_dft_firewall_rules_ex(flt_rule_v4, IPACM_Wan::num_v4_flt_rule, IPA_IP_v4)) { IPACMERR("Failed to add firewall filtering rules.\n"); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("Succeded in constructing firewall rules for ip type %d\n", iptype); } else if(iptype == IPA_IP_v6) { IPACM_Wan::num_v6_flt_rule = IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV6; if(IPACM_FAILURE == add_icmp_alg_rules(flt_rule_v6, IPACM_Wan::num_v6_flt_rule, IPA_IP_v6)) { IPACMERR("Failed to add ICMP and ALG port filtering rules.\n"); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("Succeded in constructing ICMP/ALG rules for ip type %d\n", iptype); if(IPACM_FAILURE == config_dft_firewall_rules_ex(flt_rule_v6, IPACM_Wan::num_v6_flt_rule, IPA_IP_v6)) { IPACMERR("Failed to add firewall filtering rules.\n"); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("Succeded in constructing firewall rules for ip type %d\n", iptype); } else { IPACMERR("IP type is not expected.\n"); return IPACM_FAILURE; } fail: return res; } int IPACM_Wan::add_dft_filtering_rule(struct ipa_flt_rule_add *rules, int rule_offset, ipa_ip_type iptype) { struct ipa_ioc_get_rt_tbl_indx rt_tbl_idx; struct ipa_flt_rule_add flt_rule_entry; struct ipa_ioc_generate_flt_eq flt_eq; int res = IPACM_SUCCESS; if(rules == NULL) { IPACMERR("No filtering table available.\n"); return IPACM_FAILURE; } if(rx_prop == NULL) { IPACMERR("No tx property.\n"); return IPACM_FAILURE; } if (iptype == IPA_IP_v4) { memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); strncpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX); rt_tbl_idx.ip = iptype; if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx)) { IPACMERR("Failed to get routing table index from name\n"); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("Routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx); memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); flt_rule_entry.at_rear = true; flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.retain_hdr = 1; flt_rule_entry.rule.to_uc = 0; flt_rule_entry.rule.eq_attrib_type = 1; flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; IPACMDBG_H("rx property attrib mask:0x%x\n", rx_prop->rx[0].attrib.attrib_mask); /* Configuring Multicast Filtering Rule */ memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); /* remove meta data mask since we only install default flt rules once for all modem PDN*/ flt_rule_entry.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA); flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0xF0000000; flt_rule_entry.rule.attrib.u.v4.dst_addr = 0xE0000000; change_to_network_order(IPA_IP_v4, &flt_rule_entry.rule.attrib); memset(&flt_eq, 0, sizeof(flt_eq)); memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); flt_eq.ip = iptype; if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) { IPACMERR("Failed to get eq_attrib\n"); res = IPACM_FAILURE; goto fail; } memcpy(&flt_rule_entry.rule.eq_attrib, &flt_eq.eq_attrib, sizeof(flt_rule_entry.rule.eq_attrib)); memcpy(&(rules[rule_offset]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); /* Configuring Broadcast Filtering Rule */ flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF; flt_rule_entry.rule.attrib.u.v4.dst_addr = 0xFFFFFFFF; change_to_network_order(IPA_IP_v4, &flt_rule_entry.rule.attrib); memset(&flt_eq, 0, sizeof(flt_eq)); memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); flt_eq.ip = iptype; if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) { IPACMERR("Failed to get eq_attrib\n"); res = IPACM_FAILURE; goto fail; } memcpy(&flt_rule_entry.rule.eq_attrib, &flt_eq.eq_attrib, sizeof(flt_rule_entry.rule.eq_attrib)); memcpy(&(rules[rule_offset + 1]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); IPACM_Wan::num_v4_flt_rule += IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV4; IPACMDBG_H("Constructed %d default filtering rules for ip type %d\n", IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV4, iptype); } else /*insert rules for ipv6*/ { memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); strncpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX); rt_tbl_idx.ip = iptype; if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx)) { IPACMERR("Failed to get routing table index from name\n"); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("Routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx); memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); flt_rule_entry.at_rear = true; flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.retain_hdr = 1; flt_rule_entry.rule.to_uc = 0; flt_rule_entry.rule.eq_attrib_type = 1; flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; /* Configuring Multicast Filtering Rule */ memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); /* remove meta data mask since we only install default flt rules once for all modem PDN*/ flt_rule_entry.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA); flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0xFF000000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0xFF000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0x00000000; change_to_network_order(IPA_IP_v6, &flt_rule_entry.rule.attrib); memset(&flt_eq, 0, sizeof(flt_eq)); memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); flt_eq.ip = iptype; if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) { IPACMERR("Failed to get eq_attrib\n"); res = IPACM_FAILURE; goto fail; } memcpy(&flt_rule_entry.rule.eq_attrib, &flt_eq.eq_attrib, sizeof(flt_rule_entry.rule.eq_attrib)); memcpy(&(rules[rule_offset]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); /* Configuring fe80::/10 Link-Scoped Unicast Filtering Rule */ flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0xFFC00000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0xFE800000; flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0x00000000; change_to_network_order(IPA_IP_v6, &flt_rule_entry.rule.attrib); memset(&flt_eq, 0, sizeof(flt_eq)); memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); flt_eq.ip = iptype; if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) { IPACMERR("Failed to get eq_attrib\n"); res = IPACM_FAILURE; goto fail; } memcpy(&flt_rule_entry.rule.eq_attrib, &flt_eq.eq_attrib, sizeof(flt_rule_entry.rule.eq_attrib)); memcpy(&(rules[rule_offset + 1]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); /* Configuring fec0::/10 Reserved by IETF Filtering Rule */ flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0xFFC00000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0xFEC00000; flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0x00000000; change_to_network_order(IPA_IP_v6, &flt_rule_entry.rule.attrib); memset(&flt_eq, 0, sizeof(flt_eq)); memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); flt_eq.ip = iptype; if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) { IPACMERR("Failed to get eq_attrib\n"); res = IPACM_FAILURE; goto fail; } memcpy(&flt_rule_entry.rule.eq_attrib, &flt_eq.eq_attrib, sizeof(flt_rule_entry.rule.eq_attrib)); memcpy(&(rules[rule_offset + 2]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); #ifdef FEATURE_IPA_ANDROID IPACMDBG_H("Add TCP ctrl rules: total num %d\n", IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV6); memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); flt_rule_entry.at_rear = true; flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.retain_hdr = 1; flt_rule_entry.rule.to_uc = 0; flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; flt_rule_entry.rule.eq_attrib_type = 1; flt_rule_entry.rule.eq_attrib.rule_eq_bitmap = 0; flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<1); flt_rule_entry.rule.eq_attrib.protocol_eq_present = 1; flt_rule_entry.rule.eq_attrib.protocol_eq = IPACM_FIREWALL_IPPROTO_TCP; flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<8); flt_rule_entry.rule.eq_attrib.num_ihl_offset_meq_32 = 1; flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].offset = 12; /* add TCP FIN rule*/ flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)< IPACM_MAX_FIREWALL_ENTRIES) { IPACMERR("the number of v4 firewall entries overflow, aborting...\n"); return IPACM_FAILURE; } if (num_firewall_v4 != 0) { if (m_filtering.DeleteFilteringHdls(firewall_hdl_v4, IPA_IP_v4, num_firewall_v4) == false) { IPACMERR("Error Deleting Filtering rules, aborting...\n"); return IPACM_FAILURE; } } else { IPACMDBG_H("No ipv4 firewall rules, no need deleted\n"); } if (m_filtering.DeleteFilteringHdls(dft_wan_fl_hdl, IPA_IP_v4, 1) == false) { IPACMERR("Error Deleting Filtering rules, aborting...\n"); return IPACM_FAILURE; } num_firewall_v4 = 0; } /* free v6 firewall filter rule */ if ((iptype == IPA_IP_v6) && (active_v6 == true)) { if (num_firewall_v6 > IPACM_MAX_FIREWALL_ENTRIES) { IPACMERR("the number of v6 firewall entries overflow, aborting...\n"); return IPACM_FAILURE; } if (num_firewall_v6 != 0) { if (m_filtering.DeleteFilteringHdls(firewall_hdl_v6, IPA_IP_v6, num_firewall_v6) == false) { IPACMERR("Error Deleting Filtering rules, aborting...\n"); return IPACM_FAILURE; } } else { IPACMDBG_H("No ipv6 firewall rules, no need deleted\n"); } if (m_filtering.DeleteFilteringHdls(&dft_wan_fl_hdl[1], IPA_IP_v6, 1) == false) { IPACMERR("Error Deleting Filtering rules, aborting...\n"); return IPACM_FAILURE; } if (m_filtering.DeleteFilteringHdls(&dft_wan_fl_hdl[2], IPA_IP_v6, 1) == false) { IPACMERR("Error Deleting Filtering rules, aborting...\n"); return IPACM_FAILURE; } if (m_filtering.DeleteFilteringHdls(&ipv6_frag_firewall_flt_rule_hdl, IPA_IP_v6, 1) == false) { IPACMERR("Error deleting IPv6 frag filtering rules.\n"); } num_firewall_v6 = 0; } return IPACM_SUCCESS; } /* for STA mode: wan default route/filter rule delete */ int IPACM_Wan::handle_route_del_evt(ipa_ip_type iptype) { uint32_t tx_index; ipacm_cmd_q_data evt_data; IPACMDBG_H("got handle_route_del_evt with ip-family:%d \n", iptype); if(tx_prop == NULL) { IPACMDBG_H("No tx properties, ignore delete default route setting\n"); return IPACM_SUCCESS; } is_default_gateway = false; IPACMDBG_H("Default route is deleted to iface %s.\n", dev_name); if (((iptype == IPA_IP_v4) && (active_v4 == true)) || ((iptype == IPA_IP_v6) && (active_v6 == true))) { /* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete IPV4/V6 RT-rule */ IPACMDBG_H("dev %s add producer dependency\n", dev_name); IPACMDBG_H("depend Got pipe %d rm index : %d \n", tx_prop->tx[0].dst_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]); IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]); for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) { if(iptype != tx_prop->tx[tx_index].ip) { IPACMDBG_H("Tx:%d, ip-type: %d conflict ip-type: %d, no RT-rule deleted\n", tx_index, tx_prop->tx[tx_index].ip,iptype); continue; } if (iptype == IPA_IP_v4) { IPACMDBG_H("Tx:%d, ip-type: %d match ip-type: %d, RT-rule deleted\n", tx_index, tx_prop->tx[tx_index].ip,iptype); if (m_routing.DeleteRoutingHdl(wan_route_rule_v4_hdl[tx_index], IPA_IP_v4) == false) { IPACMDBG_H("IP-family:%d, Routing rule(hdl:0x%x) deletion failed with tx_index %d!\n", IPA_IP_v4, wan_route_rule_v4_hdl[tx_index], tx_index); return IPACM_FAILURE; } } else { IPACMDBG_H("Tx:%d, ip-type: %d match ip-type: %d, RT-rule deleted\n", tx_index, tx_prop->tx[tx_index].ip,iptype); if (m_routing.DeleteRoutingHdl(wan_route_rule_v6_hdl[tx_index], IPA_IP_v6) == false) { IPACMDBG_H("IP-family:%d, Routing rule(hdl:0x%x) deletion failed with tx_index %d!\n", IPA_IP_v6, wan_route_rule_v6_hdl[tx_index], tx_index); return IPACM_FAILURE; } } } /* Delete the default wan route*/ if (iptype == IPA_IP_v6) { IPACMDBG_H("ip-type %d: default v6 wan RT-rule deleted\n",iptype); if (m_routing.DeleteRoutingHdl(wan_route_rule_v6_hdl_a5[0], IPA_IP_v6) == false) { IPACMDBG_H("IP-family:%d, Routing rule(hdl:0x%x) deletion failed!\n",IPA_IP_v6,wan_route_rule_v6_hdl_a5[0]); return IPACM_FAILURE; } } ipacm_event_iface_up *wandown_data; wandown_data = (ipacm_event_iface_up *)malloc(sizeof(ipacm_event_iface_up)); if (wandown_data == NULL) { IPACMERR("Unable to allocate memory\n"); return IPACM_FAILURE; } memset(wandown_data, 0, sizeof(ipacm_event_iface_up)); if (iptype == IPA_IP_v4) { wandown_data->ipv4_addr = wan_v4_addr; if (m_is_sta_mode!=Q6_WAN) { wandown_data->is_sta = true; } else { wandown_data->is_sta = false; } evt_data.event = IPA_HANDLE_WAN_DOWN; evt_data.evt_data = (void *)wandown_data; /* Insert IPA_HANDLE_WAN_DOWN to command queue */ IPACMDBG_H("posting IPA_HANDLE_WAN_DOWN for IPv4 (%d.%d.%d.%d) \n", (unsigned char)(wandown_data->ipv4_addr), (unsigned char)(wandown_data->ipv4_addr >> 8), (unsigned char)(wandown_data->ipv4_addr >> 16), (unsigned char)(wandown_data->ipv4_addr >> 24)); IPACM_EvtDispatcher::PostEvt(&evt_data); IPACMDBG_H("setup wan_up/active_v4= false \n"); IPACM_Wan::wan_up = false; active_v4 = false; if(IPACM_Wan::wan_up_v6) { IPACMDBG_H("modem v6-call still up(%s), not reset\n", IPACM_Wan::wan_up_dev_name); } else { memset(IPACM_Wan::wan_up_dev_name, 0, sizeof(IPACM_Wan::wan_up_dev_name)); } } else { if (m_is_sta_mode!=Q6_WAN) { wandown_data->is_sta = true; } else { wandown_data->is_sta = false; } memcpy(wandown_data->ipv6_prefix, ipv6_prefix, sizeof(wandown_data->ipv6_prefix)); evt_data.event = IPA_HANDLE_WAN_DOWN_V6; evt_data.evt_data = (void *)wandown_data; /* Insert IPA_HANDLE_WAN_DOWN to command queue */ IPACMDBG_H("posting IPA_HANDLE_WAN_DOWN for IPv6 with prefix 0x%08x%08x\n", ipv6_prefix[0], ipv6_prefix[1]); IPACM_EvtDispatcher::PostEvt(&evt_data); IPACMDBG_H("setup wan_up_v6/active_v6= false \n"); IPACM_Wan::wan_up_v6 = false; active_v6 = false; if(IPACM_Wan::wan_up) { IPACMDBG_H("modem v4-call still up(%s), not reset\n", IPACM_Wan::wan_up_dev_name); } else { memset(IPACM_Wan::wan_up_dev_name, 0, sizeof(IPACM_Wan::wan_up_dev_name)); } } } else { IPACMDBG_H(" The default WAN routing rules are deleted already \n"); } return IPACM_SUCCESS; } int IPACM_Wan::handle_route_del_evt_ex(ipa_ip_type iptype) { ipacm_cmd_q_data evt_data; IPACMDBG_H("got handle_route_del_evt_ex with ip-family:%d \n", iptype); if(tx_prop == NULL) { IPACMDBG_H("No tx properties, ignore delete default route setting\n"); return IPACM_SUCCESS; } is_default_gateway = false; IPACMDBG_H("Default route is deleted to iface %s.\n", dev_name); if (((iptype == IPA_IP_v4) && (active_v4 == true)) || ((iptype == IPA_IP_v6) && (active_v6 == true))) { /* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete IPV4/V6 RT-rule */ IPACMDBG_H("dev %s add producer dependency\n", dev_name); IPACMDBG_H("depend Got pipe %d rm index : %d \n", tx_prop->tx[0].dst_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]); IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]); /* Delete the default route*/ if (iptype == IPA_IP_v6) { IPACMDBG_H("ip-type %d: default v6 wan RT-rule deleted\n",iptype); if (m_routing.DeleteRoutingHdl(wan_route_rule_v6_hdl_a5[0], IPA_IP_v6) == false) { IPACMDBG_H("IP-family:%d, Routing rule(hdl:0x%x) deletion failed!\n",IPA_IP_v6,wan_route_rule_v6_hdl_a5[0]); return IPACM_FAILURE; } } ipacm_event_iface_up *wandown_data; wandown_data = (ipacm_event_iface_up *)malloc(sizeof(ipacm_event_iface_up)); if (wandown_data == NULL) { IPACMERR("Unable to allocate memory\n"); return IPACM_FAILURE; } memset(wandown_data, 0, sizeof(ipacm_event_iface_up)); if (iptype == IPA_IP_v4) { wandown_data->ipv4_addr = wan_v4_addr; if (m_is_sta_mode!=Q6_WAN) { wandown_data->is_sta = true; } else { wandown_data->is_sta = false; } evt_data.event = IPA_HANDLE_WAN_DOWN; evt_data.evt_data = (void *)wandown_data; /* Insert IPA_HANDLE_WAN_DOWN to command queue */ IPACMDBG_H("posting IPA_HANDLE_WAN_DOWN for IPv4 with address: 0x%x\n", wan_v4_addr); IPACM_EvtDispatcher::PostEvt(&evt_data); IPACMDBG_H("setup wan_up/active_v4= false \n"); IPACM_Wan::wan_up = false; active_v4 = false; if(IPACM_Wan::wan_up_v6) { IPACMDBG_H("modem v6-call still up(%s), not reset\n", IPACM_Wan::wan_up_dev_name); } else { memset(IPACM_Wan::wan_up_dev_name, 0, sizeof(IPACM_Wan::wan_up_dev_name)); } } else { if (m_is_sta_mode!=Q6_WAN) { wandown_data->is_sta = true; } else { wandown_data->is_sta = false; } memcpy(wandown_data->ipv6_prefix, ipv6_prefix, sizeof(wandown_data->ipv6_prefix)); evt_data.event = IPA_HANDLE_WAN_DOWN_V6; evt_data.evt_data = (void *)wandown_data; IPACMDBG_H("posting IPA_HANDLE_WAN_DOWN_V6 for IPv6 with prefix 0x%08x%08x\n", ipv6_prefix[0], ipv6_prefix[1]); IPACM_EvtDispatcher::PostEvt(&evt_data); IPACMDBG_H("setup wan_up_v6/active_v6= false \n"); IPACM_Wan::wan_up_v6 = false; active_v6 = false; if(IPACM_Wan::wan_up) { IPACMDBG_H("modem v4-call still up(%s), not reset\n", IPACM_Wan::wan_up_dev_name); } else { memset(IPACM_Wan::wan_up_dev_name, 0, sizeof(IPACM_Wan::wan_up_dev_name)); } } } else { IPACMDBG_H(" The default WAN routing rules are deleted already \n"); } return IPACM_SUCCESS; } /* configure the initial embms filter rules */ int IPACM_Wan::config_dft_embms_rules(ipa_ioc_add_flt_rule *pFilteringTable_v4, ipa_ioc_add_flt_rule *pFilteringTable_v6) { struct ipa_flt_rule_add flt_rule_entry; struct ipa_ioc_get_rt_tbl_indx rt_tbl_idx; struct ipa_ioc_generate_flt_eq flt_eq; if (rx_prop == NULL) { IPACMDBG("No rx properties registered for iface %s\n", dev_name); return IPACM_SUCCESS; } if(pFilteringTable_v4 == NULL || pFilteringTable_v6 == NULL) { IPACMERR("Either v4 or v6 filtering table is empty.\n"); return IPACM_FAILURE; } /* set up ipv4 odu rule*/ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); /* get eMBMS ODU tbl index*/ memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); strncpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v4.name, IPA_RESOURCE_NAME_MAX); rt_tbl_idx.ip = IPA_IP_v4; if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx)) { IPACMERR("Failed to get routing table index from name\n"); return IPACM_FAILURE; } IPACMDBG_H("Odu routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx); memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.at_rear = false; flt_rule_entry.rule.retain_hdr = 0; flt_rule_entry.rule.to_uc = 0; flt_rule_entry.rule.eq_attrib_type = 1; flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(struct ipa_rule_attrib)); flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x00000000; flt_rule_entry.rule.attrib.u.v4.dst_addr = 0x00000000; memset(&flt_eq, 0, sizeof(flt_eq)); memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); flt_eq.ip = IPA_IP_v4; if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) { IPACMERR("Failed to get eq_attrib\n"); return IPACM_FAILURE; } memcpy(&flt_rule_entry.rule.eq_attrib, &flt_eq.eq_attrib, sizeof(flt_rule_entry.rule.eq_attrib)); memcpy(&(pFilteringTable_v4->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); /* construc v6 rule */ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); /* get eMBMS ODU tbl*/ memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); strncpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v6.name, IPA_RESOURCE_NAME_MAX); rt_tbl_idx.ip = IPA_IP_v6; if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx)) { IPACMERR("Failed to get routing table index from name\n"); return IPACM_FAILURE; } IPACMDBG_H("Odu routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx); memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.at_rear = false; flt_rule_entry.rule.retain_hdr = 0; flt_rule_entry.rule.to_uc = 0; flt_rule_entry.rule.eq_attrib_type = 1; flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(struct ipa_rule_attrib)); flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0X00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000; memset(&flt_eq, 0, sizeof(flt_eq)); memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); flt_eq.ip = IPA_IP_v6; if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) { IPACMERR("Failed to get eq_attrib\n"); return IPACM_FAILURE; } memcpy(&flt_rule_entry.rule.eq_attrib, &flt_eq.eq_attrib, sizeof(flt_rule_entry.rule.eq_attrib)); memcpy(&(pFilteringTable_v6->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); return IPACM_SUCCESS; } /*for STA mode: handle wan-iface down event */ int IPACM_Wan::handle_down_evt() { int res = IPACM_SUCCESS; int i; IPACMDBG_H(" wan handle_down_evt \n"); /* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete IPV4/V6 RT-rule */ IPACMDBG_H("dev %s add producer dependency\n", dev_name); if (tx_prop != NULL) { IPACMDBG_H("depend Got pipe %d rm index : %d \n", tx_prop->tx[0].dst_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]); IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]); } /* no iface address up, directly close iface*/ if (ip_type == IPACM_IP_NULL) { goto fail; } /* make sure default routing rules and firewall rules are deleted*/ if (active_v4) { if (rx_prop != NULL) { del_dft_firewall_rules(IPA_IP_v4); } handle_route_del_evt(IPA_IP_v4); IPACMDBG_H("Delete default v4 routing rules\n"); } if (active_v6) { if (rx_prop != NULL) { del_dft_firewall_rules(IPA_IP_v6); } handle_route_del_evt(IPA_IP_v6); IPACMDBG_H("Delete default v6 routing rules\n"); } /* Delete default v4 RT rule */ if (ip_type != IPA_IP_v6) { IPACMDBG_H("Delete default v4 routing rules\n"); if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4) == false) { IPACMERR("Routing rule deletion failed!\n"); res = IPACM_FAILURE; goto fail; } } /* delete default v6 RT rule */ if (ip_type != IPA_IP_v4) { IPACMDBG_H("Delete default v6 routing rules\n"); /* May have multiple ipv6 iface-routing rules*/ for (i = 0; i < 2*num_dft_rt_v6; i++) { if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6) == false) { IPACMERR("Routing rule deletion failed!\n"); res = IPACM_FAILURE; goto fail; } } IPACMDBG_H("finished delete default v6 RT rules\n "); } /* clean wan-client header, routing rules */ IPACMDBG_H("left %d wan clients need to be deleted \n ", num_wan_client); for (i = 0; i < num_wan_client; i++) { /* Del NAT rules before ipv4 RT rules are delete */ if(get_client_memptr(wan_client, i)->ipv4_set == true) { IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(wan_client, i)->v4_addr); CtList->HandleSTAClientDelEvt(get_client_memptr(wan_client, i)->v4_addr); } if (delete_wan_rtrules(i, IPA_IP_v4)) { IPACMERR("unbale to delete wan-client v4 route rules for index %d\n", i); res = IPACM_FAILURE; goto fail; } if (delete_wan_rtrules(i, IPA_IP_v6)) { IPACMERR("unbale to delete ecm-client v6 route rules for index %d\n", i); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("Delete %d client header\n", num_wan_client); if(get_client_memptr(wan_client, i)->ipv4_header_set == true) { if (m_header.DeleteHeaderHdl(get_client_memptr(wan_client, i)->hdr_hdl_v4) == false) { res = IPACM_FAILURE; goto fail; } } if(get_client_memptr(wan_client, i)->ipv6_header_set == true) { if (m_header.DeleteHeaderHdl(get_client_memptr(wan_client, i)->hdr_hdl_v6) == false) { res = IPACM_FAILURE; goto fail; } } } /* end of for loop */ /* free the edm clients cache */ IPACMDBG_H("Free wan clients cache\n"); /* check software routing fl rule hdl */ if (softwarerouting_act == true) { handle_software_routing_disable(); } /* free filter rule handlers */ if (ip_type != IPA_IP_v6 && rx_prop != NULL) { if (m_filtering.DeleteFilteringHdls(dft_v4fl_rule_hdl, IPA_IP_v4, IPV4_DEFAULT_FILTERTING_RULES) == false) { IPACMERR("Error Delete Filtering rules, aborting...\n"); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("finished delete default v4 filtering rules\n "); } if (ip_type != IPA_IP_v4 && rx_prop != NULL) { if (m_filtering.DeleteFilteringHdls(dft_v6fl_rule_hdl, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES) == false) { IPACMERR("ErrorDeleting Filtering rule, aborting...\n"); res = IPACM_FAILURE; goto fail; } if(num_ipv6_dest_flt_rule > 0 && num_ipv6_dest_flt_rule <= MAX_DEFAULT_v6_ROUTE_RULES) { if(m_filtering.DeleteFilteringHdls(ipv6_dest_flt_rule_hdl, IPA_IP_v6, num_ipv6_dest_flt_rule) == false) { IPACMERR("Failed to delete ipv6 dest flt rules.\n"); res = IPACM_FAILURE; goto fail; } } IPACMDBG_H("finished delete default v6 filtering rules\n "); } /* delete the complete header for STA mode*/ if((header_set_v4 == true) || (header_set_v6 == true)) { if (m_header.DeleteHeaderHdl(hdr_hdl_sta_v4) == false) { IPACMERR("ErrorDeleting STA header for v4, aborting...\n"); res = IPACM_FAILURE; goto fail; } if (m_header.DeleteHeaderHdl(hdr_hdl_sta_v6) == false) { IPACMERR("ErrorDeleting STA header for v6, aborting...\n"); res = IPACM_FAILURE; goto fail; } } fail: if (tx_prop != NULL) { free(tx_prop); } if (rx_prop != NULL) { free(rx_prop); } if (iface_query != NULL) { free(iface_query); } if (wan_route_rule_v4_hdl != NULL) { free(wan_route_rule_v4_hdl); } if (wan_route_rule_v6_hdl != NULL) { free(wan_route_rule_v6_hdl); } if (wan_route_rule_v6_hdl_a5 != NULL) { free(wan_route_rule_v6_hdl_a5); } if (wan_client != NULL) { free(wan_client); } close(m_fd_ipa); return res; } int IPACM_Wan::handle_down_evt_ex() { int res = IPACM_SUCCESS; int i, tether_total; int ipa_if_num_tether_tmp[IPA_MAX_IFACE_ENTRIES]; IPACMDBG_H(" wan handle_down_evt \n"); /* no iface address up, directly close iface*/ if (ip_type == IPACM_IP_NULL) { goto fail; } /* free ODU filter rule handlers */ if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == EMBMS_IF) { embms_is_on = false; /* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete IPV4/V6 RT-rule */ IPACMDBG_H("dev %s add producer dependency\n", dev_name); if (tx_prop != NULL) { IPACMDBG_H("depend Got pipe %d rm index : %d \n", tx_prop->tx[0].dst_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]); IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]); } if (rx_prop != NULL) { install_wan_filtering_rule(false); IPACMDBG("finished delete embms filtering rule\n "); } goto fail; } if(ip_type == IPA_IP_v4) { num_ipv4_modem_pdn--; IPACMDBG_H("Now the number of ipv4 modem pdn is %d.\n", num_ipv4_modem_pdn); /* only when default gw goes down we post WAN_DOWN event*/ if(is_default_gateway == true) { IPACM_Wan::wan_up = false; del_wan_firewall_rule(IPA_IP_v4); install_wan_filtering_rule(false); handle_route_del_evt_ex(IPA_IP_v4); #ifdef FEATURE_IPA_ANDROID /* posting wan_down_tether for all lan clients */ for (i=0; i < IPACM_Wan::ipa_if_num_tether_v4_total; i++) { ipa_if_num_tether_tmp[i] = IPACM_Wan::ipa_if_num_tether_v4[i]; } tether_total = IPACM_Wan::ipa_if_num_tether_v4_total; for (i=0; i < tether_total; i++) { post_wan_down_tether_evt(IPA_IP_v4, ipa_if_num_tether_tmp[i]); IPACMDBG_H("post_wan_down_tether_v4 iface(%d: %s)\n", i, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether_tmp[i]].iface_name); } #endif if(IPACM_Wan::wan_up_v6) { IPACMDBG_H("modem v6-call still up(%s), not reset\n", IPACM_Wan::wan_up_dev_name); } else { memset(IPACM_Wan::wan_up_dev_name, 0, sizeof(IPACM_Wan::wan_up_dev_name)); } } /* only when the last ipv4 modem interface goes down, delete ipv4 default flt rules*/ if(num_ipv4_modem_pdn == 0) { IPACMDBG_H("Now the number of modem ipv4 interface is 0, delete default flt rules.\n"); IPACM_Wan::num_v4_flt_rule = 0; memset(IPACM_Wan::flt_rule_v4, 0, IPA_MAX_FLT_RULE * sizeof(struct ipa_flt_rule_add)); install_wan_filtering_rule(false); } if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4) == false) { IPACMERR("Routing rule deletion failed!\n"); res = IPACM_FAILURE; goto fail; } } else if(ip_type == IPA_IP_v6) { if (num_dft_rt_v6 > 1) num_ipv6_modem_pdn--; IPACMDBG_H("Now the number of ipv6 modem pdn is %d.\n", num_ipv6_modem_pdn); /* only when default gw goes down we post WAN_DOWN event*/ if(is_default_gateway == true) { IPACM_Wan::wan_up_v6 = false; del_wan_firewall_rule(IPA_IP_v6); install_wan_filtering_rule(false); handle_route_del_evt_ex(IPA_IP_v6); #ifdef FEATURE_IPA_ANDROID //sky /* posting wan_down_tether for all lan clients */ for (i=0; i < IPACM_Wan::ipa_if_num_tether_v6_total; i++) { ipa_if_num_tether_tmp[i] = IPACM_Wan::ipa_if_num_tether_v6[i]; } tether_total = IPACM_Wan::ipa_if_num_tether_v6_total; for (i=0; i < tether_total; i++) { post_wan_down_tether_evt(IPA_IP_v6, ipa_if_num_tether_tmp[i]); IPACMDBG_H("post_wan_down_tether_v6 iface(%d: %s)\n", i, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether_tmp[i]].iface_name); } #endif if(IPACM_Wan::wan_up) { IPACMDBG_H("modem v4-call still up(%s), not reset\n", IPACM_Wan::wan_up_dev_name); } else { memset(IPACM_Wan::wan_up_dev_name, 0, sizeof(IPACM_Wan::wan_up_dev_name)); } } /* only when the last ipv6 modem interface goes down, delete ipv6 default flt rules*/ if(num_ipv6_modem_pdn == 0) { IPACMDBG_H("Now the number of modem ipv6 interface is 0, delete default flt rules.\n"); IPACM_Wan::num_v6_flt_rule = 0; memset(IPACM_Wan::flt_rule_v6, 0, IPA_MAX_FLT_RULE * sizeof(struct ipa_flt_rule_add)); install_wan_filtering_rule(false); } for (i = 0; i < 2*num_dft_rt_v6; i++) { if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6) == false) { IPACMERR("Routing rule deletion failed!\n"); res = IPACM_FAILURE; goto fail; } } } else { num_ipv4_modem_pdn--; IPACMDBG_H("Now the number of ipv4 modem pdn is %d.\n", num_ipv4_modem_pdn); if (num_dft_rt_v6 > 1) num_ipv6_modem_pdn--; IPACMDBG_H("Now the number of ipv6 modem pdn is %d.\n", num_ipv6_modem_pdn); /* only when default gw goes down we post WAN_DOWN event*/ if(is_default_gateway == true) { IPACM_Wan::wan_up = false; del_wan_firewall_rule(IPA_IP_v4); handle_route_del_evt_ex(IPA_IP_v4); #ifdef FEATURE_IPA_ANDROID /* posting wan_down_tether for all lan clients */ for (i=0; i < IPACM_Wan::ipa_if_num_tether_v4_total; i++) { ipa_if_num_tether_tmp[i] = IPACM_Wan::ipa_if_num_tether_v4[i]; } tether_total = IPACM_Wan::ipa_if_num_tether_v4_total; for (i=0; i < tether_total; i++) { post_wan_down_tether_evt(IPA_IP_v4, ipa_if_num_tether_tmp[i]); IPACMDBG_H("post_wan_down_tether_v4 iface(%d: %s)\n", i, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether_tmp[i]].iface_name); } #endif IPACM_Wan::wan_up_v6 = false; del_wan_firewall_rule(IPA_IP_v6); handle_route_del_evt_ex(IPA_IP_v6); #ifdef FEATURE_IPA_ANDROID /* posting wan_down_tether for all lan clients */ for (i=0; i < IPACM_Wan::ipa_if_num_tether_v6_total; i++) { ipa_if_num_tether_tmp[i] = IPACM_Wan::ipa_if_num_tether_v6[i]; } tether_total = IPACM_Wan::ipa_if_num_tether_v6_total; for (i=0; i < tether_total; i++) { post_wan_down_tether_evt(IPA_IP_v6, ipa_if_num_tether_tmp[i]); IPACMDBG_H("post_wan_down_tether_v6 iface(%d: %s)\n", i, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether_tmp[i]].iface_name); } #endif memset(IPACM_Wan::wan_up_dev_name, 0, sizeof(IPACM_Wan::wan_up_dev_name)); install_wan_filtering_rule(false); } /* only when the last ipv4 modem interface goes down, delete ipv4 default flt rules*/ if(num_ipv4_modem_pdn == 0) { IPACMDBG_H("Now the number of modem ipv4 interface is 0, delete default flt rules.\n"); IPACM_Wan::num_v4_flt_rule = 0; memset(IPACM_Wan::flt_rule_v4, 0, IPA_MAX_FLT_RULE * sizeof(struct ipa_flt_rule_add)); install_wan_filtering_rule(false); } /* only when the last ipv6 modem interface goes down, delete ipv6 default flt rules*/ if(num_ipv6_modem_pdn == 0) { IPACMDBG_H("Now the number of modem ipv6 interface is 0, delete default flt rules.\n"); IPACM_Wan::num_v6_flt_rule = 0; memset(IPACM_Wan::flt_rule_v6, 0, IPA_MAX_FLT_RULE * sizeof(struct ipa_flt_rule_add)); install_wan_filtering_rule(false); } if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4) == false) { IPACMERR("Routing rule deletion failed!\n"); res = IPACM_FAILURE; goto fail; } for (i = 0; i < 2*num_dft_rt_v6; i++) { if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6) == false) { IPACMERR("Routing rule deletion failed!\n"); res = IPACM_FAILURE; goto fail; } } } /* check software routing fl rule hdl */ if (softwarerouting_act == true) { handle_software_routing_disable(); } /* delete the complete header for STA mode*/ if((header_set_v4 == true) || (header_set_v6 == true)) { if (m_header.DeleteHeaderHdl(hdr_hdl_sta_v4) == false) { IPACMERR("ErrorDeleting STA header for v4, aborting...\n"); res = IPACM_FAILURE; goto fail; } if (m_header.DeleteHeaderHdl(hdr_hdl_sta_v6) == false) { IPACMERR("ErrorDeleting STA header for v6, aborting...\n"); res = IPACM_FAILURE; goto fail; } } fail: if (tx_prop != NULL) { free(tx_prop); } if (rx_prop != NULL) { free(rx_prop); } if (ext_prop != NULL) { free(ext_prop); } if (iface_query != NULL) { free(iface_query); } if (wan_route_rule_v4_hdl != NULL) { free(wan_route_rule_v4_hdl); } if (wan_route_rule_v6_hdl != NULL) { free(wan_route_rule_v6_hdl); } if (wan_route_rule_v6_hdl_a5 != NULL) { free(wan_route_rule_v6_hdl_a5); } if (wan_client != NULL) { free(wan_client); } close(m_fd_ipa); return res; } int IPACM_Wan::install_wan_filtering_rule(bool is_sw_routing) { int len, res = IPACM_SUCCESS; uint8_t mux_id; ipa_ioc_add_flt_rule *pFilteringTable_v4 = NULL; ipa_ioc_add_flt_rule *pFilteringTable_v6 = NULL; mux_id = IPACM_Iface::ipacmcfg->GetQmapId(); if(rx_prop == NULL) { IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); return IPACM_SUCCESS; } if (is_sw_routing == true || IPACM_Iface::ipacmcfg->ipa_sw_rt_enable == true) { /* contruct SW-RT rules to Q6*/ struct ipa_flt_rule_add flt_rule_entry; struct ipa_ioc_get_rt_tbl_indx rt_tbl_idx; ipa_ioc_generate_flt_eq flt_eq; IPACMDBG("\n"); if (softwarerouting_act == true) { IPACMDBG("already setup software_routing rule for (%s)iface ip-family %d\n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, ip_type); return IPACM_SUCCESS; } len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add); pFilteringTable_v4 = (struct ipa_ioc_add_flt_rule*)malloc(len); if (pFilteringTable_v4 == NULL) { IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); return IPACM_FAILURE; } memset(pFilteringTable_v4, 0, len); IPACMDBG_H("Total number of WAN DL filtering rule for IPv4 is 1\n"); pFilteringTable_v4->commit = 1; pFilteringTable_v4->ep = rx_prop->rx[0].src_pipe; pFilteringTable_v4->global = false; pFilteringTable_v4->ip = IPA_IP_v4; pFilteringTable_v4->num_rules = (uint8_t)1; /* Configuring Software-Routing Filtering Rule */ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); strncpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX); rt_tbl_idx.ip = IPA_IP_v4; if(ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx) < 0) { IPACMERR("Failed to get routing table index from name\n"); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("Routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx); flt_rule_entry.at_rear = false; flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); flt_rule_entry.rule.retain_hdr = 0; flt_rule_entry.rule.to_uc = 0; flt_rule_entry.rule.eq_attrib_type = 1; memset(&flt_eq, 0, sizeof(flt_eq)); memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); flt_eq.ip = IPA_IP_v4; if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) { IPACMERR("Failed to get eq_attrib\n"); return IPACM_FAILURE; } memcpy(&flt_rule_entry.rule.eq_attrib, &flt_eq.eq_attrib, sizeof(flt_rule_entry.rule.eq_attrib)); memcpy(&(pFilteringTable_v4->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add); pFilteringTable_v6 = (struct ipa_ioc_add_flt_rule*)malloc(len); if (pFilteringTable_v6 == NULL) { IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); free(pFilteringTable_v4); return IPACM_FAILURE; } memset(pFilteringTable_v6, 0, len); IPACMDBG_H("Total number of WAN DL filtering rule for IPv6 is 1\n"); pFilteringTable_v6->commit = 1; pFilteringTable_v6->ep = rx_prop->rx[0].src_pipe; pFilteringTable_v6->global = false; pFilteringTable_v6->ip = IPA_IP_v6; pFilteringTable_v6->num_rules = (uint8_t)1; /* Configuring Software-Routing Filtering Rule */ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); strncpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX); rt_tbl_idx.ip = IPA_IP_v6; if(ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx) < 0) { IPACMERR("Failed to get routing table index from name\n"); free(pFilteringTable_v4); return IPACM_FAILURE; } IPACMDBG_H("Routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx); flt_rule_entry.at_rear = false; flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); flt_rule_entry.rule.retain_hdr = 0; flt_rule_entry.rule.to_uc = 0; flt_rule_entry.rule.eq_attrib_type = 1; memset(&flt_eq, 0, sizeof(flt_eq)); memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); flt_eq.ip = IPA_IP_v6; if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) { IPACMERR("Failed to get eq_attrib\n"); return IPACM_FAILURE; } memcpy(&flt_rule_entry.rule.eq_attrib, &flt_eq.eq_attrib, sizeof(flt_rule_entry.rule.eq_attrib)); memcpy(&(pFilteringTable_v6->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); softwarerouting_act = true; /* end of contruct SW-RT rules to Q6*/ } else { if(embms_is_on == false) { if(IPACM_Wan::num_v4_flt_rule > 0) { len = sizeof(struct ipa_ioc_add_flt_rule) + IPACM_Wan::num_v4_flt_rule * sizeof(struct ipa_flt_rule_add); pFilteringTable_v4 = (struct ipa_ioc_add_flt_rule*)malloc(len); IPACMDBG_H("Total number of WAN DL filtering rule for IPv4 is %d\n", IPACM_Wan::num_v4_flt_rule); if (pFilteringTable_v4 == NULL) { IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); return IPACM_FAILURE; } pFilteringTable_v4->commit = 1; pFilteringTable_v4->ep = rx_prop->rx[0].src_pipe; pFilteringTable_v4->global = false; pFilteringTable_v4->ip = IPA_IP_v4; pFilteringTable_v4->num_rules = (uint8_t)IPACM_Wan::num_v4_flt_rule; memcpy(pFilteringTable_v4->rules, IPACM_Wan::flt_rule_v4, IPACM_Wan::num_v4_flt_rule * sizeof(ipa_flt_rule_add)); } if(IPACM_Wan::num_v6_flt_rule > 0) { len = sizeof(struct ipa_ioc_add_flt_rule) + IPACM_Wan::num_v6_flt_rule * sizeof(struct ipa_flt_rule_add); pFilteringTable_v6 = (struct ipa_ioc_add_flt_rule*)malloc(len); IPACMDBG_H("Total number of WAN DL filtering rule for IPv6 is %d\n", IPACM_Wan::num_v6_flt_rule); if (pFilteringTable_v6 == NULL) { IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); free(pFilteringTable_v4); return IPACM_FAILURE; } pFilteringTable_v6->commit = 1; pFilteringTable_v6->ep = rx_prop->rx[0].src_pipe; pFilteringTable_v6->global = false; pFilteringTable_v6->ip = IPA_IP_v6; pFilteringTable_v6->num_rules = (uint8_t)IPACM_Wan::num_v6_flt_rule; memcpy(pFilteringTable_v6->rules, IPACM_Wan::flt_rule_v6, IPACM_Wan::num_v6_flt_rule * sizeof(ipa_flt_rule_add)); } } else //embms is on, always add 1 embms rule on top of WAN DL flt table { /* allocate ipv4 filtering table */ len = sizeof(struct ipa_ioc_add_flt_rule) + (1 + IPACM_Wan::num_v4_flt_rule) * sizeof(struct ipa_flt_rule_add); pFilteringTable_v4 = (struct ipa_ioc_add_flt_rule*)malloc(len); IPACMDBG_H("Total number of WAN DL filtering rule for IPv4 is %d\n", IPACM_Wan::num_v4_flt_rule + 1); if (pFilteringTable_v4 == NULL) { IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); return IPACM_FAILURE; } pFilteringTable_v4->commit = 1; pFilteringTable_v4->ep = rx_prop->rx[0].src_pipe; pFilteringTable_v4->global = false; pFilteringTable_v4->ip = IPA_IP_v4; pFilteringTable_v4->num_rules = (uint8_t)IPACM_Wan::num_v4_flt_rule + 1; /* allocate ipv6 filtering table */ len = sizeof(struct ipa_ioc_add_flt_rule) + (1 + IPACM_Wan::num_v6_flt_rule) * sizeof(struct ipa_flt_rule_add); pFilteringTable_v6 = (struct ipa_ioc_add_flt_rule*)malloc(len); IPACMDBG_H("Total number of WAN DL filtering rule for IPv6 is %d\n", IPACM_Wan::num_v6_flt_rule + 1); if (pFilteringTable_v6 == NULL) { IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); free(pFilteringTable_v4); return IPACM_FAILURE; } pFilteringTable_v6->commit = 1; pFilteringTable_v6->ep = rx_prop->rx[0].src_pipe; pFilteringTable_v6->global = false; pFilteringTable_v6->ip = IPA_IP_v6; pFilteringTable_v6->num_rules = (uint8_t)IPACM_Wan::num_v6_flt_rule + 1; config_dft_embms_rules(pFilteringTable_v4, pFilteringTable_v6); if(IPACM_Wan::num_v4_flt_rule > 0) { memcpy(&(pFilteringTable_v4->rules[1]), IPACM_Wan::flt_rule_v4, IPACM_Wan::num_v4_flt_rule * sizeof(ipa_flt_rule_add)); } if(IPACM_Wan::num_v6_flt_rule > 0) { memcpy(&(pFilteringTable_v6->rules[1]), IPACM_Wan::flt_rule_v6, IPACM_Wan::num_v6_flt_rule * sizeof(ipa_flt_rule_add)); } } } if(false == m_filtering.AddWanDLFilteringRule(pFilteringTable_v4, pFilteringTable_v6, mux_id)) { IPACMERR("Failed to install WAN DL filtering table.\n"); res = IPACM_FAILURE; goto fail; } fail: if(pFilteringTable_v4 != NULL) { free(pFilteringTable_v4); } if(pFilteringTable_v6 != NULL) { free(pFilteringTable_v6); } return res; } void IPACM_Wan::change_to_network_order(ipa_ip_type iptype, ipa_rule_attrib* attrib) { if(attrib == NULL) { IPACMERR("Attribute pointer is NULL.\n"); return; } if(iptype == IPA_IP_v6) { int i; for(i=0; i<4; i++) { attrib->u.v6.src_addr[i] = htonl(attrib->u.v6.src_addr[i]); attrib->u.v6.src_addr_mask[i] = htonl(attrib->u.v6.src_addr_mask[i]); attrib->u.v6.dst_addr[i] = htonl(attrib->u.v6.dst_addr[i]); attrib->u.v6.dst_addr_mask[i] = htonl(attrib->u.v6.dst_addr_mask[i]); } } else { IPACMDBG_H("IP type is not IPv6, do nothing: %d\n", iptype); } return; } bool IPACM_Wan::is_global_ipv6_addr(uint32_t* ipv6_addr) { if(ipv6_addr == NULL) { IPACMERR("IPv6 address is empty.\n"); return false; } IPACMDBG_H("Get ipv6 address with first word 0x%08x.\n", ipv6_addr[0]); uint32_t ipv6_link_local_prefix, ipv6_link_local_prefix_mask; ipv6_link_local_prefix = 0xFE800000; ipv6_link_local_prefix_mask = 0xFFC00000; if((ipv6_addr[0] & ipv6_link_local_prefix_mask) == (ipv6_link_local_prefix & ipv6_link_local_prefix_mask)) { IPACMDBG_H("This IPv6 address is link local.\n"); return false; } else { IPACMDBG_H("This IPv6 address is not link local.\n"); return true; } } /* handle STA WAN-client */ /* handle WAN client initial, construct full headers (tx property) */ int IPACM_Wan::handle_wan_hdr_init(uint8_t *mac_addr) { #define WAN_IFACE_INDEX_LEN 2 int res = IPACM_SUCCESS, len = 0; char index[WAN_IFACE_INDEX_LEN]; struct ipa_ioc_copy_hdr sCopyHeader; struct ipa_ioc_add_hdr *pHeaderDescriptor = NULL; uint32_t cnt; int clnt_indx; clnt_indx = get_wan_client_index(mac_addr); if (clnt_indx != IPACM_INVALID_INDEX) { IPACMERR("eth client is found/attached already with index %d \n", clnt_indx); return IPACM_FAILURE; } /* add header to IPA */ if (num_wan_client >= IPA_MAX_NUM_WAN_CLIENTS) { IPACMERR("Reached maximum number(%d) of eth clients\n", IPA_MAX_NUM_WAN_CLIENTS); return IPACM_FAILURE; } IPACMDBG_H("WAN client number: %d\n", num_wan_client); memcpy(get_client_memptr(wan_client, num_wan_client)->mac, mac_addr, sizeof(get_client_memptr(wan_client, num_wan_client)->mac)); IPACMDBG_H("Received Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); IPACMDBG_H("stored MAC %02x:%02x:%02x:%02x:%02x:%02x\n", get_client_memptr(wan_client, num_wan_client)->mac[0], get_client_memptr(wan_client, num_wan_client)->mac[1], get_client_memptr(wan_client, num_wan_client)->mac[2], get_client_memptr(wan_client, num_wan_client)->mac[3], get_client_memptr(wan_client, num_wan_client)->mac[4], get_client_memptr(wan_client, num_wan_client)->mac[5]); /* add header to IPA */ if(tx_prop != NULL) { len = sizeof(struct ipa_ioc_add_hdr) + (1 * sizeof(struct ipa_hdr_add)); pHeaderDescriptor = (struct ipa_ioc_add_hdr *)calloc(1, len); if (pHeaderDescriptor == NULL) { IPACMERR("calloc failed to allocate pHeaderDescriptor\n"); return IPACM_FAILURE; } /* copy partial header for v4*/ for (cnt=0; cntnum_tx_props; cnt++) { if(tx_prop->tx[cnt].ip==IPA_IP_v4) { IPACMDBG_H("Got partial v4-header name from %d tx props\n", cnt); memset(&sCopyHeader, 0, sizeof(sCopyHeader)); memcpy(sCopyHeader.name, tx_prop->tx[cnt].hdr_name, sizeof(sCopyHeader.name)); IPACMDBG_H("header name: %s in tx:%d\n", sCopyHeader.name,cnt); if (m_header.CopyHeader(&sCopyHeader) == false) { PERROR("ioctl copy header failed"); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial); IPACMDBG_H("header eth2_ofst_valid: %d, eth2_ofst: %d\n", sCopyHeader.is_eth2_ofst_valid, sCopyHeader.eth2_ofst); if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE) { IPACMERR("header oversize\n"); res = IPACM_FAILURE; goto fail; } else { memcpy(pHeaderDescriptor->hdr[0].hdr, sCopyHeader.hdr, sCopyHeader.hdr_len); } /* copy client mac_addr to partial header */ IPACMDBG_H("header eth2_ofst_valid: %d, eth2_ofst: %d\n", sCopyHeader.is_eth2_ofst_valid, sCopyHeader.eth2_ofst); memcpy(&pHeaderDescriptor->hdr[0].hdr[eth2_ofst_v4], mac_addr, IPA_MAC_ADDR_SIZE); /* only copy 6 bytes mac-address */ pHeaderDescriptor->commit = true; pHeaderDescriptor->num_hdrs = 1; memset(pHeaderDescriptor->hdr[0].name, 0, sizeof(pHeaderDescriptor->hdr[0].name)); snprintf(index,sizeof(index), "%d", ipa_if_num); strlcpy(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)); if (strlcat(pHeaderDescriptor->hdr[0].name, IPA_WAN_PARTIAL_HDR_NAME_v4, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX) { IPACMERR(" header name construction failed exceed length (%d)\n", strlen(pHeaderDescriptor->hdr[0].name)); res = IPACM_FAILURE; goto fail; } snprintf(index,sizeof(index), "%d", header_name_count); if (strlcat(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX) { IPACMERR(" header name construction failed exceed length (%d)\n", strlen(pHeaderDescriptor->hdr[0].name)); res = IPACM_FAILURE; goto fail; } pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len; pHeaderDescriptor->hdr[0].hdr_hdl = -1; pHeaderDescriptor->hdr[0].is_partial = 0; pHeaderDescriptor->hdr[0].status = -1; if (m_header.AddHeader(pHeaderDescriptor) == false || pHeaderDescriptor->hdr[0].status != 0) { IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status); res = IPACM_FAILURE; goto fail; } get_client_memptr(wan_client, num_wan_client)->hdr_hdl_v4 = pHeaderDescriptor->hdr[0].hdr_hdl; IPACMDBG_H("eth-client(%d) v4 full header name:%s header handle:(0x%x)\n", num_wan_client, pHeaderDescriptor->hdr[0].name, get_client_memptr(wan_client, num_wan_client)->hdr_hdl_v4); get_client_memptr(wan_client, num_wan_client)->ipv4_header_set=true; break; } } /* copy partial header for v6*/ for (cnt=0; cntnum_tx_props; cnt++) { if(tx_prop->tx[cnt].ip==IPA_IP_v6) { IPACMDBG_H("Got partial v6-header name from %d tx props\n", cnt); memset(&sCopyHeader, 0, sizeof(sCopyHeader)); memcpy(sCopyHeader.name, tx_prop->tx[cnt].hdr_name, sizeof(sCopyHeader.name)); IPACMDBG_H("header name: %s in tx:%d\n", sCopyHeader.name,cnt); if (m_header.CopyHeader(&sCopyHeader) == false) { PERROR("ioctl copy header failed"); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial); IPACMDBG_H("header eth2_ofst_valid: %d, eth2_ofst: %d\n", sCopyHeader.is_eth2_ofst_valid, sCopyHeader.eth2_ofst); if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE) { IPACMERR("header oversize\n"); res = IPACM_FAILURE; goto fail; } else { memcpy(pHeaderDescriptor->hdr[0].hdr, sCopyHeader.hdr, sCopyHeader.hdr_len); } /* copy client mac_addr to partial header */ memcpy(&pHeaderDescriptor->hdr[0].hdr[eth2_ofst_v6], mac_addr, IPA_MAC_ADDR_SIZE); /* only copy 6 bytes mac-address */ pHeaderDescriptor->commit = true; pHeaderDescriptor->num_hdrs = 1; memset(pHeaderDescriptor->hdr[0].name, 0, sizeof(pHeaderDescriptor->hdr[0].name)); snprintf(index,sizeof(index), "%d", ipa_if_num); strlcpy(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)); if (strlcat(pHeaderDescriptor->hdr[0].name, IPA_WAN_PARTIAL_HDR_NAME_v6, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX) { IPACMERR(" header name construction failed exceed length (%d)\n", strlen(pHeaderDescriptor->hdr[0].name)); res = IPACM_FAILURE; goto fail; } snprintf(index,sizeof(index), "%d", header_name_count); if (strlcat(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX) { IPACMERR(" header name construction failed exceed length (%d)\n", strlen(pHeaderDescriptor->hdr[0].name)); res = IPACM_FAILURE; goto fail; } pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len; pHeaderDescriptor->hdr[0].hdr_hdl = -1; pHeaderDescriptor->hdr[0].is_partial = 0; pHeaderDescriptor->hdr[0].status = -1; if (m_header.AddHeader(pHeaderDescriptor) == false || pHeaderDescriptor->hdr[0].status != 0) { IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status); res = IPACM_FAILURE; goto fail; } get_client_memptr(wan_client, num_wan_client)->hdr_hdl_v6 = pHeaderDescriptor->hdr[0].hdr_hdl; IPACMDBG_H("eth-client(%d) v6 full header name:%s header handle:(0x%x)\n", num_wan_client, pHeaderDescriptor->hdr[0].name, get_client_memptr(wan_client, num_wan_client)->hdr_hdl_v6); get_client_memptr(wan_client, num_wan_client)->ipv6_header_set=true; break; } } /* initialize wifi client*/ get_client_memptr(wan_client, num_wan_client)->route_rule_set_v4 = false; get_client_memptr(wan_client, num_wan_client)->route_rule_set_v6 = 0; get_client_memptr(wan_client, num_wan_client)->ipv4_set = false; get_client_memptr(wan_client, num_wan_client)->ipv6_set = 0; num_wan_client++; header_name_count++; //keep increasing header_name_count res = IPACM_SUCCESS; IPACMDBG_H("eth client number: %d\n", num_wan_client); } else { return res; } fail: free(pHeaderDescriptor); return res; } /*handle eth client */ int IPACM_Wan::handle_wan_client_ipaddr(ipacm_event_data_all *data) { int clnt_indx; int v6_num; IPACMDBG_H("number of wan clients: %d\n", num_wan_client); IPACMDBG_H(" event MAC %02x:%02x:%02x:%02x:%02x:%02x\n", data->mac_addr[0], data->mac_addr[1], data->mac_addr[2], data->mac_addr[3], data->mac_addr[4], data->mac_addr[5]); clnt_indx = get_wan_client_index(data->mac_addr); if (clnt_indx == IPACM_INVALID_INDEX) { IPACMERR("wan client not found/attached \n"); return IPACM_FAILURE; } IPACMDBG_H("Ip-type received %d\n", data->iptype); if (data->iptype == IPA_IP_v4) { IPACMDBG_H("ipv4 address: 0x%x\n", data->ipv4_addr); if (data->ipv4_addr != 0) /* not 0.0.0.0 */ { if (get_client_memptr(wan_client, clnt_indx)->ipv4_set == false) { get_client_memptr(wan_client, clnt_indx)->v4_addr = data->ipv4_addr; get_client_memptr(wan_client, clnt_indx)->ipv4_set = true; /* Add NAT rules after ipv4 RT rules are set */ CtList->HandleSTAClientAddEvt(data->ipv4_addr); } else { /* check if client got new IPv4 address*/ if(data->ipv4_addr == get_client_memptr(wan_client, clnt_indx)->v4_addr) { IPACMDBG_H("Already setup ipv4 addr for client:%d, ipv4 address didn't change\n", clnt_indx); return IPACM_FAILURE; } else { IPACMDBG_H("ipv4 addr for client:%d is changed \n", clnt_indx); /* Del NAT rules before ipv4 RT rules are delete */ CtList->HandleSTAClientDelEvt(get_client_memptr(wan_client, clnt_indx)->v4_addr); delete_wan_rtrules(clnt_indx,IPA_IP_v4); get_client_memptr(wan_client, clnt_indx)->route_rule_set_v4 = false; get_client_memptr(wan_client, clnt_indx)->v4_addr = data->ipv4_addr; /* Add NAT rules after ipv4 RT rules are set */ CtList->HandleSTAClientAddEvt(data->ipv4_addr); } } } else { IPACMDBG_H("Invalid client IPv4 address \n"); return IPACM_FAILURE; } } else { if ((data->ipv6_addr[0] != 0) || (data->ipv6_addr[1] != 0) || (data->ipv6_addr[2] != 0) || (data->ipv6_addr[3] || 0)) /* check if all 0 not valid ipv6 address */ { IPACMDBG_H("ipv6 address: 0x%x:%x:%x:%x\n", data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]); if(get_client_memptr(wan_client, clnt_indx)->ipv6_set < IPV6_NUM_ADDR) { for(v6_num=0;v6_num < get_client_memptr(wan_client, clnt_indx)->ipv6_set;v6_num++) { if( data->ipv6_addr[0] == get_client_memptr(wan_client, clnt_indx)->v6_addr[v6_num][0] && data->ipv6_addr[1] == get_client_memptr(wan_client, clnt_indx)->v6_addr[v6_num][1] && data->ipv6_addr[2]== get_client_memptr(wan_client, clnt_indx)->v6_addr[v6_num][2] && data->ipv6_addr[3] == get_client_memptr(wan_client, clnt_indx)->v6_addr[v6_num][3]) { IPACMDBG_H("Already see this ipv6 addr for client:%d\n", clnt_indx); return IPACM_FAILURE; /* not setup the RT rules*/ } } /* not see this ipv6 before for wifi client*/ get_client_memptr(wan_client, clnt_indx)->v6_addr[get_client_memptr(wan_client, clnt_indx)->ipv6_set][0] = data->ipv6_addr[0]; get_client_memptr(wan_client, clnt_indx)->v6_addr[get_client_memptr(wan_client, clnt_indx)->ipv6_set][1] = data->ipv6_addr[1]; get_client_memptr(wan_client, clnt_indx)->v6_addr[get_client_memptr(wan_client, clnt_indx)->ipv6_set][2] = data->ipv6_addr[2]; get_client_memptr(wan_client, clnt_indx)->v6_addr[get_client_memptr(wan_client, clnt_indx)->ipv6_set][3] = data->ipv6_addr[3]; get_client_memptr(wan_client, clnt_indx)->ipv6_set++; } else { IPACMDBG_H("Already got 3 ipv6 addr for client:%d\n", clnt_indx); return IPACM_FAILURE; /* not setup the RT rules*/ } } } return IPACM_SUCCESS; } /*handle wan client routing rule*/ int IPACM_Wan::handle_wan_client_route_rule(uint8_t *mac_addr, ipa_ip_type iptype) { struct ipa_ioc_add_rt_rule *rt_rule; struct ipa_rt_rule_add *rt_rule_entry; uint32_t tx_index; int wan_index,v6_num; const int NUM = 1; if(tx_prop == NULL) { IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); return IPACM_SUCCESS; } IPACMDBG_H("Received mac_addr MAC %02x:%02x:%02x:%02x:%02x:%02x\n", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); wan_index = get_wan_client_index(mac_addr); if (wan_index == IPACM_INVALID_INDEX) { IPACMDBG_H("wan client not found/attached \n"); return IPACM_SUCCESS; } if (iptype==IPA_IP_v4) { IPACMDBG_H("wan client index: %d, ip-type: %d, ipv4_set:%d, ipv4_rule_set:%d \n", wan_index, iptype, get_client_memptr(wan_client, wan_index)->ipv4_set, get_client_memptr(wan_client, wan_index)->route_rule_set_v4); } else { IPACMDBG_H("wan client index: %d, ip-type: %d, ipv6_set:%d, ipv6_rule_num:%d \n", wan_index, iptype, get_client_memptr(wan_client, wan_index)->ipv6_set, get_client_memptr(wan_client, wan_index)->route_rule_set_v6); } /* Add default routing rules if not set yet */ if ((iptype == IPA_IP_v4 && get_client_memptr(wan_client, wan_index)->route_rule_set_v4 == false && get_client_memptr(wan_client, wan_index)->ipv4_set == true) || (iptype == IPA_IP_v6 && get_client_memptr(wan_client, wan_index)->route_rule_set_v6 < get_client_memptr(wan_client, wan_index)->ipv6_set )) { /* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */ IPACMDBG_H("dev %s add producer dependency\n", dev_name); IPACMDBG_H("depend Got pipe %d rm index : %d \n", tx_prop->tx[0].dst_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]); IPACM_Iface::ipacmcfg->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false); rt_rule = (struct ipa_ioc_add_rt_rule *) calloc(1, sizeof(struct ipa_ioc_add_rt_rule) + NUM * sizeof(struct ipa_rt_rule_add)); if (rt_rule == NULL) { PERROR("Error Locate ipa_ioc_add_rt_rule memory...\n"); return IPACM_FAILURE; } rt_rule->commit = 1; rt_rule->num_rules = (uint8_t)NUM; rt_rule->ip = iptype; for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) { if(iptype != tx_prop->tx[tx_index].ip) { IPACMDBG_H("Tx:%d, ip-type: %d conflict ip-type: %d no RT-rule added\n", tx_index, tx_prop->tx[tx_index].ip,iptype); continue; } rt_rule_entry = &rt_rule->rules[0]; rt_rule_entry->at_rear = 0; if (iptype == IPA_IP_v4) { IPACMDBG_H("client index(%d):ipv4 address: 0x%x\n", wan_index, get_client_memptr(wan_client, wan_index)->v4_addr); IPACMDBG_H("client(%d): v4 header handle:(0x%x)\n", wan_index, get_client_memptr(wan_client, wan_index)->hdr_hdl_v4); strncpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.name, sizeof(rt_rule->rt_tbl_name)); rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe; memcpy(&rt_rule_entry->rule.attrib, &tx_prop->tx[tx_index].attrib, sizeof(rt_rule_entry->rule.attrib)); rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; rt_rule_entry->rule.hdr_hdl = get_client_memptr(wan_client, wan_index)->hdr_hdl_v4; rt_rule_entry->rule.attrib.u.v4.dst_addr = get_client_memptr(wan_client, wan_index)->v4_addr; rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF; if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); free(rt_rule); return IPACM_FAILURE; } /* copy ipv4 RT hdl */ get_client_memptr(wan_client, wan_index)->wan_rt_hdl[tx_index].wan_rt_rule_hdl_v4 = rt_rule->rules[0].rt_rule_hdl; IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index, get_client_memptr(wan_client, wan_index)->wan_rt_hdl[tx_index].wan_rt_rule_hdl_v4, iptype); } else { for(v6_num = get_client_memptr(wan_client, wan_index)->route_rule_set_v6;v6_num < get_client_memptr(wan_client, wan_index)->ipv6_set;v6_num++) { IPACMDBG_H("client(%d): v6 header handle:(0x%x)\n", wan_index, get_client_memptr(wan_client, wan_index)->hdr_hdl_v6); /* v6 LAN_RT_TBL */ strncpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_v6.name, sizeof(rt_rule->rt_tbl_name)); /* Support QCMAP LAN traffic feature, send to A5 */ rt_rule_entry->rule.dst = iface_query->excp_pipe; memset(&rt_rule_entry->rule.attrib, 0, sizeof(rt_rule_entry->rule.attrib)); rt_rule_entry->rule.hdr_hdl = 0; rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = get_client_memptr(wan_client, wan_index)->v6_addr[v6_num][0]; rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = get_client_memptr(wan_client, wan_index)->v6_addr[v6_num][1]; rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = get_client_memptr(wan_client, wan_index)->v6_addr[v6_num][2]; rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = get_client_memptr(wan_client, wan_index)->v6_addr[v6_num][3]; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF; if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); free(rt_rule); return IPACM_FAILURE; } get_client_memptr(wan_client, wan_index)->wan_rt_hdl[tx_index].wan_rt_rule_hdl_v6[v6_num] = rt_rule->rules[0].rt_rule_hdl; IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index, get_client_memptr(wan_client, wan_index)->wan_rt_hdl[tx_index].wan_rt_rule_hdl_v6[v6_num], iptype); /*Copy same rule to v6 WAN RT TBL*/ strncpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name)); /* Downlink traffic from Wan iface, directly through IPA */ rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe; memcpy(&rt_rule_entry->rule.attrib, &tx_prop->tx[tx_index].attrib, sizeof(rt_rule_entry->rule.attrib)); rt_rule_entry->rule.hdr_hdl = get_client_memptr(wan_client, wan_index)->hdr_hdl_v6; rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = get_client_memptr(wan_client, wan_index)->v6_addr[v6_num][0]; rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = get_client_memptr(wan_client, wan_index)->v6_addr[v6_num][1]; rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = get_client_memptr(wan_client, wan_index)->v6_addr[v6_num][2]; rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = get_client_memptr(wan_client, wan_index)->v6_addr[v6_num][3]; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF; if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); free(rt_rule); return IPACM_FAILURE; } get_client_memptr(wan_client, wan_index)->wan_rt_hdl[tx_index].wan_rt_rule_hdl_v6_wan[v6_num] = rt_rule->rules[0].rt_rule_hdl; IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index, get_client_memptr(wan_client, wan_index)->wan_rt_hdl[tx_index].wan_rt_rule_hdl_v6_wan[v6_num], iptype); } } } /* end of for loop */ free(rt_rule); if (iptype == IPA_IP_v4) { get_client_memptr(wan_client, wan_index)->route_rule_set_v4 = true; } else { get_client_memptr(wan_client, wan_index)->route_rule_set_v6 = get_client_memptr(wan_client, wan_index)->ipv6_set; } } return IPACM_SUCCESS; } /*handle eth client */ int IPACM_Wan::handle_network_stats_update(ipa_get_apn_data_stats_resp_msg_v01 *data) { FILE *fp = NULL; for (int apn_index =0; apn_index < data->apn_data_stats_list_len; apn_index++) { if(data->apn_data_stats_list[apn_index].mux_id == ext_prop->ext[0].mux_id) { IPACMDBG_H("Received IPA_TETHERING_STATS_UPDATE_NETWORK_STATS, MUX ID %d TX (P%lu/B%lu) RX (P%lu/B%lu)\n", data->apn_data_stats_list[apn_index].mux_id, data->apn_data_stats_list[apn_index].num_ul_packets, data->apn_data_stats_list[apn_index].num_ul_bytes, data->apn_data_stats_list[apn_index].num_dl_packets, data->apn_data_stats_list[apn_index].num_dl_bytes); fp = fopen(IPA_NETWORK_STATS_FILE_NAME, "w"); if ( fp == NULL ) { IPACMERR("Failed to write pipe stats to %s, error is %d - %s\n", IPA_NETWORK_STATS_FILE_NAME, errno, strerror(errno)); return IPACM_FAILURE; } fprintf(fp, NETWORK_STATS, dev_name, data->apn_data_stats_list[apn_index].num_ul_packets, data->apn_data_stats_list[apn_index].num_ul_bytes, data->apn_data_stats_list[apn_index].num_dl_packets, data->apn_data_stats_list[apn_index].num_dl_bytes); fclose(fp); break; }; } return IPACM_SUCCESS; } ================================================ FILE: data-ipa-cfg-mgr/ipacm/src/IPACM_Wlan.cpp ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPACM_Wlan.cpp @brief This file implements the WLAN iface functionality. @Author Skylar Chang */ #include #include #include #include #include #include #include #include #include #include #include /* static member to store the number of total wifi clients within all APs*/ int IPACM_Wlan::total_num_wifi_clients = 0; uint32_t* IPACM_Wlan::dummy_flt_rule_hdl_v4 = NULL; uint32_t* IPACM_Wlan::dummy_flt_rule_hdl_v6 = NULL; int IPACM_Wlan::num_wlan_ap_iface = 0; lan2lan_flt_rule_hdl IPACM_Wlan::self_client_flt_rule_hdl_v4[IPA_LAN_TO_LAN_MAX_WLAN_CLIENT]; lan2lan_flt_rule_hdl IPACM_Wlan::self_client_flt_rule_hdl_v6[IPA_LAN_TO_LAN_MAX_WLAN_CLIENT]; lan2lan_flt_rule_hdl IPACM_Wlan::usb_client_flt_rule_hdl_v4[IPA_LAN_TO_LAN_MAX_USB_CLIENT]; lan2lan_flt_rule_hdl IPACM_Wlan::usb_client_flt_rule_hdl_v6[IPA_LAN_TO_LAN_MAX_USB_CLIENT]; IPACM_Wlan::IPACM_Wlan(int iface_index) : IPACM_Lan(iface_index) { #define WLAN_AMPDU_DEFAULT_FILTER_RULES 3 wlan_ap_index = IPACM_Wlan::num_wlan_ap_iface; if(wlan_ap_index < 0 || wlan_ap_index > 1) { IPACMERR("Wlan_ap_index is not correct: %d, not creating instance.\n", wlan_ap_index); if (tx_prop != NULL) { free(tx_prop); } if (rx_prop != NULL) { free(rx_prop); } if (iface_query != NULL) { free(iface_query); } delete this; return; } num_wifi_client = 0; header_name_count = 0; wlan_client = NULL; if(iface_query != NULL) { wlan_client_len = (sizeof(ipa_wlan_client)) + (iface_query->num_tx_props * sizeof(wlan_client_rt_hdl)); wlan_client = (ipa_wlan_client *)calloc(IPA_MAX_NUM_WIFI_CLIENTS, wlan_client_len); if (wlan_client == NULL) { IPACMERR("unable to allocate memory\n"); return; } IPACMDBG_H("index:%d constructor: Tx properties:%d\n", iface_index, iface_query->num_tx_props); } Nat_App = NatApp::GetInstance(); if (Nat_App == NULL) { IPACMERR("unable to get Nat App instance \n"); return; } IPACM_Wlan::num_wlan_ap_iface++; IPACMDBG_H("Now the number of wlan AP iface is %d\n", IPACM_Wlan::num_wlan_ap_iface); add_dummy_flt_rule(); memset(wlan_guest_ap_flt_rule_hdl_v4, 0, IPA_MAX_PRIVATE_SUBNET_ENTRIES * sizeof(uint32_t)); wlan_guest_ap_flt_rule_hdl_v6 = 0; is_guest_ap = false; num_usb_client = 0; memset(eth_bridge_usb_client_flt_info, 0, IPA_LAN_TO_LAN_MAX_USB_CLIENT * sizeof(eth_bridge_client_flt_info)); num_usb_client = 0; eth_bridge_wlan_client_rt_from_usb_info_v4 = NULL; eth_bridge_wlan_client_rt_from_usb_info_v6 = NULL; eth_bridge_wlan_client_rt_from_wlan_info_v4 = NULL; eth_bridge_wlan_client_rt_from_wlan_info_v6 = NULL; if(tx_prop != NULL) { #ifdef FEATURE_ETH_BRIDGE_LE client_rt_info_size_v4 = sizeof(eth_bridge_client_rt_info) + each_client_rt_rule_count_v4 * sizeof(uint32_t); eth_bridge_wlan_client_rt_from_usb_info_v4 = (eth_bridge_client_rt_info*)calloc(IPA_LAN_TO_LAN_MAX_WLAN_CLIENT, client_rt_info_size_v4); eth_bridge_wlan_client_rt_from_wlan_info_v4 = (eth_bridge_client_rt_info*)calloc(IPA_LAN_TO_LAN_MAX_WLAN_CLIENT, client_rt_info_size_v4); client_rt_info_size_v6 = sizeof(eth_bridge_client_rt_info) + each_client_rt_rule_count_v6 * sizeof(uint32_t); eth_bridge_wlan_client_rt_from_usb_info_v6 = (eth_bridge_client_rt_info*)calloc(IPA_LAN_TO_LAN_MAX_WLAN_CLIENT, client_rt_info_size_v6); eth_bridge_wlan_client_rt_from_wlan_info_v6 = (eth_bridge_client_rt_info*)calloc(IPA_LAN_TO_LAN_MAX_WLAN_CLIENT, client_rt_info_size_v6); #endif } wlan_client_rt_from_usb_info_count_v4 = 0; wlan_client_rt_from_usb_info_count_v6 = 0; wlan_client_rt_from_wlan_info_count_v4 = 0; wlan_client_rt_from_wlan_info_count_v6 = 0; #ifdef FEATURE_ETH_BRIDGE_LE if(iface_query != NULL) { if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == WLAN_IF && tx_prop != NULL) { if(IPACM_Lan::wlan_hdr_type != IPA_HDR_L2_NONE && tx_prop->tx[0].hdr_l2_type != IPACM_Lan::wlan_hdr_type) { IPACMERR("The WLAN header format is not consistent! Now header format is %d.\n", tx_prop->tx[0].hdr_l2_type); } else { if(wlan_ap_index == 0) { if(eth_bridge_get_hdr_template_hdl(&IPACM_Lan::wlan_hdr_template_hdl) == IPACM_FAILURE) { IPACMERR("Failed to setup wlan hdr template.\n"); } else { IPACM_Lan::wlan_hdr_type = tx_prop->tx[0].hdr_l2_type; add_hdr_proc_ctx(); } } } } } #endif #ifdef FEATURE_IPA_ANDROID /* set the IPA-client pipe enum */ if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == WLAN_IF) { handle_tethering_client(false, IPACM_CLIENT_WLAN); } #endif return; } IPACM_Wlan::~IPACM_Wlan() { IPACM_EvtDispatcher::deregistr(this); IPACM_IfaceManager::deregistr(this); return; } void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param) { if(is_active == false && event != IPA_LAN_DELETE_SELF) { IPACMDBG_H("The interface is no longer active, return.\n"); return; } int ipa_interface_index; int wlan_index; ipacm_ext_prop* ext_prop; ipacm_event_iface_up* data_wan; ipacm_event_iface_up_tehter* data_wan_tether; switch (event) { case IPA_WLAN_LINK_DOWN_EVENT: { ipacm_event_data_fid *data = (ipacm_event_data_fid *)param; ipa_interface_index = iface_ipa_index_query(data->if_index); if (ipa_interface_index == ipa_if_num) { IPACMDBG_H("Received IPA_WLAN_LINK_DOWN_EVENT\n"); handle_down_evt(); /* reset the AP-iface category to unknown */ IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat=UNKNOWN_IF; IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface IPACM_Wlan::total_num_wifi_clients = (IPACM_Wlan::total_num_wifi_clients) - \ (num_wifi_client); return; } } break; case IPA_PRIVATE_SUBNET_CHANGE_EVENT: { ipacm_event_data_fid *data = (ipacm_event_data_fid *)param; /* internel event: data->if_index is ipa_if_index */ if (data->if_index == ipa_if_num) { IPACMDBG_H("Received IPA_PRIVATE_SUBNET_CHANGE_EVENT from itself posting, ignore\n"); return; } else { IPACMDBG_H("Received IPA_PRIVATE_SUBNET_CHANGE_EVENT from other LAN iface \n"); #ifdef FEATURE_IPA_ANDROID handle_private_subnet_android(IPA_IP_v4); #endif IPACMDBG_H(" delete old private subnet rules, use new sets \n"); return; } } break; case IPA_LAN_DELETE_SELF: { ipacm_event_data_fid *data = (ipacm_event_data_fid *)param; if(data->if_index == ipa_if_num) { IPACM_Wlan::num_wlan_ap_iface--; IPACMDBG_H("Now the number of wlan AP iface is %d\n", IPACM_Wlan::num_wlan_ap_iface); del_dummy_flt_rule(); IPACMDBG_H("Received IPA_LAN_DELETE_SELF event.\n"); IPACMDBG_H("ipa_WLAN (%s):ipa_index (%d) instance close \n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, ipa_if_num); delete this; } break; } case IPA_ADDR_ADD_EVENT: { ipacm_event_data_addr *data = (ipacm_event_data_addr *)param; ipa_interface_index = iface_ipa_index_query(data->if_index); if ( (data->iptype == IPA_IP_v4 && data->ipv4_addr == 0) || (data->iptype == IPA_IP_v6 && data->ipv6_addr[0] == 0 && data->ipv6_addr[1] == 0 && data->ipv6_addr[2] == 0 && data->ipv6_addr[3] == 0) ) { IPACMDBG_H("Invalid address, ignore IPA_ADDR_ADD_EVENT event\n"); return; } if (ipa_interface_index == ipa_if_num) { /* check v4 not setup before, v6 can have 2 iface ip */ if( ((data->iptype != ip_type) && (ip_type != IPA_IP_MAX)) || ((data->iptype==IPA_IP_v6) && (num_dft_rt_v6!=MAX_DEFAULT_v6_ROUTE_RULES))) { IPACMDBG_H("Got IPA_ADDR_ADD_EVENT ip-family:%d, v6 num %d: \n",data->iptype,num_dft_rt_v6); /* Post event to NAT */ if (data->iptype == IPA_IP_v4) { ipacm_cmd_q_data evt_data; ipacm_event_iface_up *info; info = (ipacm_event_iface_up *) malloc(sizeof(ipacm_event_iface_up)); if (info == NULL) { IPACMERR("Unable to allocate memory\n"); return; } memcpy(info->ifname, dev_name, IF_NAME_LEN); info->ipv4_addr = data->ipv4_addr; info->addr_mask = IPACM_Iface::ipacmcfg->private_subnet_table[0].subnet_mask; evt_data.event = IPA_HANDLE_WLAN_UP; evt_data.evt_data = (void *)info; /* Insert IPA_HANDLE_WLAN_UP to command queue */ IPACMDBG_H("posting IPA_HANDLE_WLAN_UP for IPv4 with below information\n"); IPACMDBG_H("IPv4 address:0x%x, IPv4 address mask:0x%x\n", info->ipv4_addr, info->addr_mask); IPACM_EvtDispatcher::PostEvt(&evt_data); } if ((num_dft_rt_v6 == 0) && (data->iptype == IPA_IP_v6) && (wlan_ap_index == 0)) { install_ipv6_icmp_flt_rule(); } if(handle_addr_evt(data) == IPACM_FAILURE) { return; } #ifdef FEATURE_IPA_ANDROID add_dummy_private_subnet_flt_rule(data->iptype); handle_private_subnet_android(data->iptype); #else if(wlan_ap_index == 0) { handle_private_subnet(data->iptype); } #endif if (IPACM_Wan::isWanUP(ipa_if_num)) { if(data->iptype == IPA_IP_v4 || data->iptype == IPA_IP_MAX) { if(IPACM_Wan::backhaul_is_sta_mode == false) { ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4); IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v4); } else { IPACM_Lan::handle_wan_up(IPA_IP_v4); } } } if(IPACM_Wan::isWanUP_V6(ipa_if_num)) { if((data->iptype == IPA_IP_v6 || data->iptype == IPA_IP_MAX) && num_dft_rt_v6 == 1) { if(wlan_ap_index == 0) //install ipv6 prefix rule only once { install_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix); } if(IPACM_Wan::backhaul_is_sta_mode == false) { ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6); IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v6); } else { IPACM_Lan::handle_wan_up(IPA_IP_v6); } } } IPACMDBG_H("posting IPA_HANDLE_WLAN_UP:Finished checking wan_up\n"); /* checking if SW-RT_enable */ if (IPACM_Iface::ipacmcfg->ipa_sw_rt_enable == true) { /* handle software routing enable event*/ IPACMDBG_H("IPA_SW_ROUTING_ENABLE for iface: %s \n",IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name); handle_software_routing_enable(); } } } } break; #ifdef FEATURE_IPA_ANDROID case IPA_HANDLE_WAN_UP_TETHER: IPACMDBG_H("Received IPA_HANDLE_WAN_UP_TETHER event\n"); data_wan_tether = (ipacm_event_iface_up_tehter*)param; if(data_wan_tether == NULL) { IPACMERR("No event data is found.\n"); return; } IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->is_sta, data_wan_tether->if_index_tether, IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name); if (data_wan_tether->if_index_tether == ipa_if_num) { if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX) { if(data_wan_tether->is_sta == false) { ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4); IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v4); } else { IPACM_Lan::handle_wan_up(IPA_IP_v4); } } } break; case IPA_HANDLE_WAN_UP_V6_TETHER: IPACMDBG_H("Received IPA_HANDLE_WAN_UP_V6_TETHER event\n"); data_wan_tether = (ipacm_event_iface_up_tehter*)param; if(data_wan_tether == NULL) { IPACMERR("No event data is found.\n"); return; } IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->is_sta, data_wan_tether->if_index_tether, IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name); if (data_wan_tether->if_index_tether == ipa_if_num) { if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX) { if(wlan_ap_index == 0) //install ipv6 prefix rule only once { install_ipv6_prefix_flt_rule(data_wan_tether->ipv6_prefix); } if(data_wan_tether->is_sta == false) { ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6); IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v6); } else { IPACM_Lan::handle_wan_up(IPA_IP_v6); } } } break; case IPA_HANDLE_WAN_DOWN_TETHER: IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_TETHER event\n"); data_wan_tether = (ipacm_event_iface_up_tehter*)param; if(data_wan_tether == NULL) { IPACMERR("No event data is found.\n"); return; } IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->is_sta, data_wan_tether->if_index_tether, IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name); if (data_wan_tether->if_index_tether == ipa_if_num) { if(data_wan_tether->is_sta == false && wlan_ap_index > 0) { IPACMDBG_H("This is not the first AP instance and not STA mode, ignore WAN_DOWN event.\n"); return; } if (rx_prop != NULL) { if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX) { handle_wan_down(data_wan_tether->is_sta); } } } break; case IPA_HANDLE_WAN_DOWN_V6_TETHER: IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_V6_TETHER event\n"); data_wan_tether = (ipacm_event_iface_up_tehter*)param; if(data_wan_tether == NULL) { IPACMERR("No event data is found.\n"); return; } IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->is_sta, data_wan_tether->if_index_tether, IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name); if (data_wan_tether->if_index_tether == ipa_if_num) { /* clean up v6 RT rules*/ IPACMDBG_H("Received IPA_WAN_V6_DOWN in WLAN-instance and need clean up client IPv6 address \n"); /* reset wifi-client ipv6 rt-rules */ handle_wlan_client_reset_rt(IPA_IP_v6); if(data_wan_tether->is_sta == false && wlan_ap_index > 0) { IPACMDBG_H("This is not the first AP instance and not STA mode, ignore WAN_DOWN event.\n"); return; } if (rx_prop != NULL) { if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX) { handle_wan_down_v6(data_wan_tether->is_sta); } } } break; #else case IPA_HANDLE_WAN_UP: { IPACMDBG_H("Received IPA_HANDLE_WAN_UP event\n"); data_wan = (ipacm_event_iface_up*)param; if(data_wan == NULL) { IPACMERR("No event data is found.\n"); return; } IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta); if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX) { if(data_wan->is_sta == false) { ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4); IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v4); } else { IPACM_Lan::handle_wan_up(IPA_IP_v4); } } } break; case IPA_HANDLE_WAN_UP_V6: IPACMDBG_H("Received IPA_HANDLE_WAN_UP_V6 event\n"); data_wan = (ipacm_event_iface_up*)param; if(data_wan == NULL) { IPACMERR("No event data is found.\n"); return; } IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta); if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX) { #ifdef FEATURE_ETH_BRIDGE_LE eth_bridge_install_wlan_guest_ap_ipv6_flt_rule(); #endif if(wlan_ap_index == 0) //install ipv6 prefix rule only once { install_ipv6_prefix_flt_rule(data_wan->ipv6_prefix); } if(data_wan->is_sta == false) { ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6); IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v6); } else { IPACM_Lan::handle_wan_up(IPA_IP_v6); } } break; case IPA_HANDLE_WAN_DOWN: IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN event\n"); data_wan = (ipacm_event_iface_up*)param; if(data_wan == NULL) { IPACMERR("No event data is found.\n"); return; } IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta); if(data_wan->is_sta == false && wlan_ap_index > 0) { IPACMDBG_H("This is not the first AP instance and not STA mode, ignore WAN_DOWN event.\n"); return; } if (rx_prop != NULL) { if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX) { handle_wan_down(data_wan->is_sta); } } break; case IPA_HANDLE_WAN_DOWN_V6: IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_V6 event\n"); data_wan = (ipacm_event_iface_up*)param; if(data_wan == NULL) { IPACMERR("No event data is found.\n"); return; } /* clean up v6 RT rules*/ IPACMDBG_H("Received IPA_WAN_V6_DOWN in WLAN-instance and need clean up client IPv6 address \n"); /* reset wifi-client ipv6 rt-rules */ handle_wlan_client_reset_rt(IPA_IP_v6); IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta); if(data_wan->is_sta == false && wlan_ap_index > 0) { IPACMDBG_H("This is not the first AP instance and not STA mode, ignore WAN_DOWN event.\n"); return; } if (rx_prop != NULL) { if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX) { handle_wan_down_v6(data_wan->is_sta); } } break; #endif case IPA_WLAN_CLIENT_ADD_EVENT_EX: { ipacm_event_data_wlan_ex *data = (ipacm_event_data_wlan_ex *)param; ipa_interface_index = iface_ipa_index_query(data->if_index); if (ipa_interface_index == ipa_if_num) { #ifdef FEATURE_ETH_BRIDGE_LE int i; for(i=0; inum_of_attribs; i++) { if(data->attribs[i].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR) { if(IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.valid == true) { eth_bridge_add_wlan_client_rt_rule(data->attribs[i].u.mac_addr, SRC_WLAN, IPA_IP_v4); eth_bridge_add_wlan_client_rt_rule(data->attribs[i].u.mac_addr, SRC_WLAN, IPA_IP_v6); } if(IPACM_Lan::usb_to_wlan_hdr_proc_ctx.valid == true) { eth_bridge_add_wlan_client_rt_rule(data->attribs[i].u.mac_addr, SRC_USB, IPA_IP_v4); eth_bridge_add_wlan_client_rt_rule(data->attribs[i].u.mac_addr, SRC_USB, IPA_IP_v6); } if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX) { eth_bridge_add_self_client_flt_rule(data->attribs[i].u.mac_addr, IPA_IP_v4); } if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX) { eth_bridge_add_self_client_flt_rule(data->attribs[i].u.mac_addr, IPA_IP_v6); } eth_bridge_post_lan_client_event(data->attribs[i].u.mac_addr, IPA_ETH_BRIDGE_WLAN_CLIENT_ADD_EVENT); eth_bridge_add_wlan_client(data->attribs[i].u.mac_addr, ipa_if_num); break; } } #endif IPACMDBG_H("Received IPA_WLAN_CLIENT_ADD_EVENT\n"); handle_wlan_client_init_ex(data); } } break; case IPA_WLAN_CLIENT_DEL_EVENT: { ipacm_event_data_mac *data = (ipacm_event_data_mac *)param; ipa_interface_index = iface_ipa_index_query(data->if_index); if (ipa_interface_index == ipa_if_num) { IPACMDBG_H("Received IPA_WLAN_CLIENT_DEL_EVENT\n"); #ifdef FEATURE_ETH_BRIDGE_LE eth_bridge_del_wlan_client_rt_rule(data->mac_addr, SRC_WLAN); if(IPACM_Lan::usb_to_wlan_hdr_proc_ctx.valid == true) { eth_bridge_del_wlan_client_rt_rule(data->mac_addr, SRC_USB); } eth_bridge_del_self_client_flt_rule(data->mac_addr); eth_bridge_post_lan_client_event(data->mac_addr, IPA_ETH_BRIDGE_WLAN_CLIENT_DEL_EVENT); eth_bridge_del_wlan_client(data->mac_addr); #endif /* support lan2lan ipa-HW feature*/ handle_lan2lan_msg_post(data->mac_addr, IPA_LAN_CLIENT_DISCONNECT, IPA_IP_v4); handle_lan2lan_msg_post(data->mac_addr, IPA_LAN_CLIENT_DISCONNECT, IPA_IP_v6); handle_wlan_client_down_evt(data->mac_addr); } } break; case IPA_WLAN_CLIENT_POWER_SAVE_EVENT: { ipacm_event_data_mac *data = (ipacm_event_data_mac *)param; ipa_interface_index = iface_ipa_index_query(data->if_index); if (ipa_interface_index == ipa_if_num) { IPACMDBG_H("Received IPA_WLAN_CLIENT_POWER_SAVE_EVENT\n"); /* support lan2lan ipa-HW feature*/ handle_lan2lan_msg_post(data->mac_addr, IPA_LAN_CLIENT_POWER_SAVE, IPA_IP_v4); handle_lan2lan_msg_post(data->mac_addr, IPA_LAN_CLIENT_POWER_SAVE, IPA_IP_v6); handle_wlan_client_pwrsave(data->mac_addr); } } break; case IPA_WLAN_CLIENT_RECOVER_EVENT: { ipacm_event_data_mac *data = (ipacm_event_data_mac *)param; ipa_interface_index = iface_ipa_index_query(data->if_index); if (ipa_interface_index == ipa_if_num) { IPACMDBG_H("Received IPA_WLAN_CLIENT_RECOVER_EVENT\n"); /* support lan2lan ipa-HW feature*/ handle_lan2lan_msg_post(data->mac_addr, IPA_LAN_CLIENT_POWER_RECOVER, IPA_IP_v4); handle_lan2lan_msg_post(data->mac_addr, IPA_LAN_CLIENT_POWER_RECOVER, IPA_IP_v6); wlan_index = get_wlan_client_index(data->mac_addr); if ((wlan_index != IPACM_INVALID_INDEX) && (get_client_memptr(wlan_client, wlan_index)->power_save_set == true)) { IPACMDBG_H("change wlan client out of power safe mode \n"); get_client_memptr(wlan_client, wlan_index)->power_save_set = false; /* First add route rules and then nat rules */ if(get_client_memptr(wlan_client, wlan_index)->ipv4_set == true) /* for ipv4 */ { IPACMDBG_H("recover client index(%d):ipv4 address: 0x%x\n", wlan_index, get_client_memptr(wlan_client, wlan_index)->v4_addr); IPACMDBG_H("Adding Route Rules\n"); handle_wlan_client_route_rule(data->mac_addr, IPA_IP_v4); IPACMDBG_H("Adding Nat Rules\n"); Nat_App->ResetPwrSaveIf(get_client_memptr(wlan_client, wlan_index)->v4_addr); } if(get_client_memptr(wlan_client, wlan_index)->ipv6_set != 0) /* for ipv6 */ { handle_wlan_client_route_rule(data->mac_addr, IPA_IP_v6); } } } } break; case IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT: { ipacm_event_data_all *data = (ipacm_event_data_all *)param; ipa_interface_index = iface_ipa_index_query(data->if_index); if (ipa_interface_index == ipa_if_num) { IPACMDBG_H("Received IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT\n"); if (handle_wlan_client_ipaddr(data) == IPACM_FAILURE) { return; } /* support lan2lan ipa-hw feature */ handle_lan2lan_client_active(data, IPA_LAN_CLIENT_ACTIVE); handle_wlan_client_route_rule(data->mac_addr, data->iptype); if (data->iptype == IPA_IP_v4) { /* Add NAT rules after ipv4 RT rules are set */ CtList->HandleNeighIpAddrAddEvt(data); // Nat_App->ResetPwrSaveIf(data->ipv4_addr); } } } break; /* handle software routing enable event, iface will update softwarerouting_act to true*/ case IPA_SW_ROUTING_ENABLE: IPACMDBG_H("Received IPA_SW_ROUTING_ENABLE\n"); IPACM_Iface::handle_software_routing_enable(); break; /* handle software routing disable event, iface will update softwarerouting_act to false*/ case IPA_SW_ROUTING_DISABLE: IPACMDBG_H("Received IPA_SW_ROUTING_DISABLE\n"); IPACM_Iface::handle_software_routing_disable(); break; case IPA_ETH_BRIDGE_USB_CLIENT_ADD_EVENT: { IPACMDBG_H("Received IPA_ETH_BRIDGE_USB_CLIENT_ADD_EVENT event.\n"); ipacm_event_data_mac* mac = (ipacm_event_data_mac*)param; if(mac != NULL) { if(wlan_ap_index == 0) { if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX) { eth_bridge_add_usb_client_flt_rule(mac->mac_addr, IPA_IP_v4); } if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX) { eth_bridge_add_usb_client_flt_rule(mac->mac_addr, IPA_IP_v6); } } } else { IPACMERR("Event MAC is empty.\n"); } } break; case IPA_ETH_BRIDGE_USB_CLIENT_DEL_EVENT: { IPACMDBG_H("Received IPA_ETH_BRIDGE_USB_CLIENT_DEL_EVENT event.\n"); ipacm_event_data_mac* mac = (ipacm_event_data_mac*)param; if(mac != NULL) { if(wlan_ap_index == 0) { if(eth_bridge_del_usb_client_flt_rule(mac->mac_addr) == IPACM_FAILURE) { IPACMDBG_H("Failed to delete usb client MAC based flt rule.\n"); } } } else { IPACMERR("Event MAC is empty.\n"); } } break; case IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT: { IPACMDBG_H("Received IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT event.\n"); int i; ipacm_event_data_fid* fid = (ipacm_event_data_fid*)param; if(fid == NULL) { IPACMERR("Event data is empty.\n"); return; } if(fid->if_index == ipa_if_num) { IPACMDBG_H("The event was sent by the same interface, ignore.\n"); return; } for(i=0; iif_index == ipa_if_num) { IPACMDBG_H("The event was sent by the same interface, ignore.\n"); return; } for(i=0; iipa_stats_type != QMI_IPA_STATS_TYPE_PIPE_V01) { IPACMERR("not valid pipe stats\n"); return; } handle_tethering_stats_event(data); }; } } break; default: break; } return; } /*Configure the initial filter rules */ int IPACM_Wlan::init_fl_rule(ipa_ip_type iptype) { int res = IPACM_SUCCESS, len, offset; struct ipa_flt_rule_mdfy flt_rule; struct ipa_ioc_mdfy_flt_rule* pFilteringTable; /* update the iface ip-type to be IPA_IP_v4, IPA_IP_v6 or both*/ if (iptype == IPA_IP_v4) { if ((ip_type == IPA_IP_v4) || (ip_type == IPA_IP_MAX)) { IPACMDBG_H("Interface(%s:%d) already in ip-type %d\n", dev_name, ipa_if_num, ip_type); return res; } if (ip_type == IPA_IP_v6) { ip_type = IPA_IP_MAX; } else { ip_type = IPA_IP_v4; } IPACMDBG_H("Interface(%s:%d) now ip-type is %d\n", dev_name, ipa_if_num, ip_type); } else { if ((ip_type == IPA_IP_v6) || (ip_type == IPA_IP_MAX)) { IPACMDBG_H("Interface(%s:%d) already in ip-type %d\n", dev_name, ipa_if_num, ip_type); return res; } if (ip_type == IPA_IP_v4) { ip_type = IPA_IP_MAX; } else { ip_type = IPA_IP_v6; } IPACMDBG_H("Interface(%s:%d) now ip-type is %d\n", dev_name, ipa_if_num, ip_type); } /* ADD corresponding ipa_rm_resource_name of RX-endpoint before adding all IPV4V6 FT-rules */ if(rx_prop != NULL) { IPACMDBG_H("dev %s add producer dependency\n", dev_name); IPACMDBG_H("depend Got pipe %d rm index : %d \n", rx_prop->rx[0].src_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe]); IPACM_Iface::ipacmcfg->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe],false); IPACMDBG_H("Add producer dependency from %s with registered rx-prop\n", dev_name); } else { /* Adding the check if no Rx property registered, no filter rules will be added */ IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); return IPACM_SUCCESS; } #ifdef FEATURE_ETH_BRIDGE_LE if(wlan_ap_index != 0) { IPACMDBG_H("Install frag/multicast/broadcast rules only for the first AP.\n"); return IPACM_SUCCESS; } #endif /* construct ipa_ioc_add_flt_rule with default filter rules */ if (iptype == IPA_IP_v4) { if(IPACM_Wlan::dummy_flt_rule_hdl_v4 == NULL) { IPACMERR("Dummy ipv4 flt rule has not been installed.\n"); return IPACM_FAILURE; } #ifdef FEATURE_ETH_BRIDGE_LE offset = 0; #else #ifndef CT_OPT offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet); #else offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet) + NUM_TCP_CTL_FLT_RULE; #endif #endif #ifdef FEATURE_IPA_ANDROID offset = offset + wlan_ap_index * (IPA_MAX_PRIVATE_SUBNET_ENTRIES - IPACM_Iface::ipacmcfg->ipa_num_private_subnet); #endif len = sizeof(struct ipa_ioc_mdfy_flt_rule) + (IPV4_DEFAULT_FILTERTING_RULES * sizeof(struct ipa_flt_rule_mdfy)); pFilteringTable = (struct ipa_ioc_mdfy_flt_rule *)calloc(1, len); if (!pFilteringTable) { IPACMERR("Error Locate ipa_ioc_mdfy_flt_rule memory...\n"); return IPACM_FAILURE; } memset(pFilteringTable, 0, len); pFilteringTable->commit = 1; pFilteringTable->ip = iptype; pFilteringTable->num_rules = (uint8_t)IPV4_DEFAULT_FILTERTING_RULES; memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy)); flt_rule.status = -1; flt_rule.rule.retain_hdr = 1; flt_rule.rule.to_uc = 0; flt_rule.rule.action = IPA_PASS_TO_EXCEPTION; flt_rule.rule.eq_attrib_type = 0; /* Configuring Fragment Filtering Rule */ IPACMDBG_H("rx property attrib mask:0x%x\n", rx_prop->rx[0].attrib.attrib_mask); memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib)); #ifdef FEATURE_ETH_BRIDGE_LE /* remove meta data mask */ flt_rule.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA); #endif flt_rule.rule.attrib.attrib_mask |= IPA_FLT_FRAGMENT; flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset]; memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); /* Configuring Multicast Filtering Rule */ memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib)); #ifdef FEATURE_ETH_BRIDGE_LE /* remove meta data mask */ flt_rule.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA); #endif flt_rule.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; flt_rule.rule.attrib.u.v4.dst_addr_mask = 0xF0000000; flt_rule.rule.attrib.u.v4.dst_addr = 0xE0000000; flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset+1]; memcpy(&(pFilteringTable->rules[1]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); /* Configuring Broadcast Filtering Rule */ flt_rule.rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF; flt_rule.rule.attrib.u.v4.dst_addr = 0xFFFFFFFF; flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset+2]; memcpy(&(pFilteringTable->rules[2]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) { IPACMERR("Failed to modify default ipv4 filtering rules.\n"); res = IPACM_FAILURE; goto fail; } else { /* copy filter hdls */ for (int i = 0; i < IPV4_DEFAULT_FILTERTING_RULES; i++) { if (pFilteringTable->rules[i].status == 0) { dft_v4fl_rule_hdl[i] = pFilteringTable->rules[i].rule_hdl; IPACMDBG_H("Default v4 filter Rule %d HDL:0x%x\n", i, dft_v4fl_rule_hdl[i]); } else { IPACMERR("Failed adding default v4 Filtering rule %d\n", i); } } } } else { if(IPACM_Wlan::dummy_flt_rule_hdl_v6 == NULL) { IPACMERR("Dummy ipv6 flt rule has not been installed.\n"); return IPACM_FAILURE; } #ifdef FEATURE_ETH_BRIDGE_LE offset = 1 + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_USB_CLIENT; #else #ifndef CT_OPT offset = wlan_ap_index * (IPV6_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR) + MAX_OFFLOAD_PAIR; #else offset = wlan_ap_index * (IPV6_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR) + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR; #endif #endif len = sizeof(struct ipa_ioc_mdfy_flt_rule) + (IPV6_DEFAULT_FILTERTING_RULES * sizeof(struct ipa_flt_rule_mdfy)); pFilteringTable = (struct ipa_ioc_mdfy_flt_rule *)calloc(1, len); if (!pFilteringTable) { IPACMERR("Error Locate ipa_ioc_mdfy_flt_rule memory...\n"); return IPACM_FAILURE; } memset(pFilteringTable, 0, len); pFilteringTable->commit = 1; pFilteringTable->ip = iptype; pFilteringTable->num_rules = (uint8_t)IPV6_DEFAULT_FILTERTING_RULES; memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy)); flt_rule.status = -1; flt_rule.rule.retain_hdr = 1; flt_rule.rule.to_uc = 0; flt_rule.rule.action = IPA_PASS_TO_EXCEPTION; flt_rule.rule.eq_attrib_type = 0; /* Configuring Multicast Filtering Rule */ memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib)); #ifdef FEATURE_ETH_BRIDGE_LE /* remove meta data mask */ flt_rule.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA); #endif flt_rule.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; flt_rule.rule.attrib.u.v6.dst_addr_mask[0] = 0xFF000000; flt_rule.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000; flt_rule.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000; flt_rule.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000; flt_rule.rule.attrib.u.v6.dst_addr[0] = 0XFF000000; flt_rule.rule.attrib.u.v6.dst_addr[1] = 0x00000000; flt_rule.rule.attrib.u.v6.dst_addr[2] = 0x00000000; flt_rule.rule.attrib.u.v6.dst_addr[3] = 0X00000000; flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v6[offset]; memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); /* Configuring fe80::/10 Link-Scoped Unicast Filtering Rule */ flt_rule.rule.attrib.u.v6.dst_addr_mask[0] = 0XFFC00000; flt_rule.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000; flt_rule.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000; flt_rule.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000; flt_rule.rule.attrib.u.v6.dst_addr[0] = 0xFE800000; flt_rule.rule.attrib.u.v6.dst_addr[1] = 0x00000000; flt_rule.rule.attrib.u.v6.dst_addr[2] = 0x00000000; flt_rule.rule.attrib.u.v6.dst_addr[3] = 0X00000000; flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v6[offset+1]; memcpy(&(pFilteringTable->rules[1]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); /* Configuring fec0::/10 Reserved by IETF Filtering Rule */ flt_rule.rule.attrib.u.v6.dst_addr_mask[0] = 0XFFC00000; flt_rule.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000; flt_rule.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000; flt_rule.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000; flt_rule.rule.attrib.u.v6.dst_addr[0] = 0xFEC00000; flt_rule.rule.attrib.u.v6.dst_addr[1] = 0x00000000; flt_rule.rule.attrib.u.v6.dst_addr[2] = 0x00000000; flt_rule.rule.attrib.u.v6.dst_addr[3] = 0X00000000; flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v6[offset+2]; memcpy(&(pFilteringTable->rules[2]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); #ifdef FEATURE_IPA_ANDROID memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy)); flt_rule.status = -1; flt_rule.rule.retain_hdr = 1; flt_rule.rule.to_uc = 0; flt_rule.rule.action = IPA_PASS_TO_EXCEPTION; flt_rule.rule.eq_attrib_type = 1; flt_rule.rule.eq_attrib.rule_eq_bitmap = 0; if(rx_prop->rx[0].attrib.attrib_mask & IPA_FLT_META_DATA) { flt_rule.rule.eq_attrib.rule_eq_bitmap |= (1<<14); flt_rule.rule.eq_attrib.metadata_meq32_present = 1; flt_rule.rule.eq_attrib.metadata_meq32.offset = 0; flt_rule.rule.eq_attrib.metadata_meq32.value = rx_prop->rx[0].attrib.meta_data; flt_rule.rule.eq_attrib.metadata_meq32.mask = rx_prop->rx[0].attrib.meta_data_mask; } flt_rule.rule.eq_attrib.rule_eq_bitmap |= (1<<1); flt_rule.rule.eq_attrib.protocol_eq_present = 1; flt_rule.rule.eq_attrib.protocol_eq = IPACM_FIREWALL_IPPROTO_TCP; flt_rule.rule.eq_attrib.rule_eq_bitmap |= (1<<8); flt_rule.rule.eq_attrib.num_ihl_offset_meq_32 = 1; flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].offset = 12; /* add TCP FIN rule*/ flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<rules[3]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); /* add TCP SYN rule*/ flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<rules[4]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); /* add TCP RST rule*/ flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<rules[5]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); #endif if (m_filtering.ModifyFilteringRule(pFilteringTable) == false) { IPACMERR("Failed to modify default ipv6 filtering rules.\n"); res = IPACM_FAILURE; goto fail; } else { for (int i = 0; i < IPV6_DEFAULT_FILTERTING_RULES; i++) { if (pFilteringTable->rules[i].status == 0) { dft_v6fl_rule_hdl[i] = pFilteringTable->rules[i].rule_hdl; IPACMDBG_H("Default v6 Filter Rule %d HDL:0x%x\n", i, dft_v6fl_rule_hdl[i]); } else { IPACMERR("Failing adding v6 default IPV6 rule %d\n", i); } } } } fail: free(pFilteringTable); return res; } int IPACM_Wlan::add_dummy_lan2lan_flt_rule(ipa_ip_type iptype) { if(rx_prop == NULL) { IPACMDBG_H("There is no rx_prop for iface %s, not able to add dummy lan2lan filtering rule.\n", dev_name); return IPACM_FAILURE; } int offset; if(iptype == IPA_IP_v4) { if(IPACM_Wlan::dummy_flt_rule_hdl_v4 == NULL) { IPACMERR("Dummy ipv4 flt rule has not been installed.\n"); return IPACM_FAILURE; } #ifndef CT_OPT offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet) + IPV4_DEFAULT_FILTERTING_RULES; #else offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet) + NUM_TCP_CTL_FLT_RULE + IPV4_DEFAULT_FILTERTING_RULES; #endif #ifdef FEATURE_IPA_ANDROID offset = offset + wlan_ap_index * (IPA_MAX_PRIVATE_SUBNET_ENTRIES - IPACM_Iface::ipacmcfg->ipa_num_private_subnet); #endif for (int i = 0; i < MAX_OFFLOAD_PAIR; i++) { lan2lan_flt_rule_hdl_v4[i].rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset+i]; lan2lan_flt_rule_hdl_v4[i].valid = false; IPACMDBG_H("Lan2lan v4 flt rule %d hdl:0x%x\n", i, lan2lan_flt_rule_hdl_v4[i].rule_hdl); } } else if(iptype == IPA_IP_v6) { if(IPACM_Wlan::dummy_flt_rule_hdl_v6 == NULL) { IPACMERR("Dummy ipv6 flt rule has not been installed.\n"); return IPACM_FAILURE; } #ifndef CT_OPT offset = wlan_ap_index * (IPV6_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR); #else offset = wlan_ap_index * (IPV6_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR) + NUM_TCP_CTL_FLT_RULE; #endif for (int i = 0; i < MAX_OFFLOAD_PAIR; i++) { lan2lan_flt_rule_hdl_v6[i].rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v6[offset+i]; lan2lan_flt_rule_hdl_v6[i].valid = false; IPACMDBG_H("Lan2lan v6 flt rule %d hdl:0x%x\n", i, lan2lan_flt_rule_hdl_v6[i].rule_hdl); } } else { IPACMERR("IP type is not expected.\n"); return IPACM_FAILURE; } return IPACM_SUCCESS; } /* configure private subnet filter rules*/ int IPACM_Wlan::handle_private_subnet(ipa_ip_type iptype) { int i, len, res = IPACM_SUCCESS, offset; struct ipa_flt_rule_mdfy flt_rule; struct ipa_ioc_mdfy_flt_rule* pFilteringTable; if (rx_prop == NULL) { IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); return IPACM_SUCCESS; } if (iptype == IPA_IP_v4) { if(IPACM_Wlan::dummy_flt_rule_hdl_v4 == NULL) { IPACMERR("Dummy ipv4 flt rule has not been installed.\n"); return IPACM_FAILURE; } #ifdef FEATURE_ETH_BRIDGE_LE offset = IPV4_DEFAULT_FILTERTING_RULES + IPACM_Iface::ipacmcfg->ipa_num_private_subnet + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_USB_CLIENT; #else #ifndef CT_OPT offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet) + IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR; #else offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet) + IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR; #endif #endif len = sizeof(struct ipa_ioc_mdfy_flt_rule) + (IPACM_Iface::ipacmcfg->ipa_num_private_subnet) * sizeof(struct ipa_flt_rule_mdfy); pFilteringTable = (struct ipa_ioc_mdfy_flt_rule*)malloc(len); if (!pFilteringTable) { IPACMERR("Failed to allocate ipa_ioc_mdfy_flt_rule memory...\n"); return IPACM_FAILURE; } memset(pFilteringTable, 0, len); pFilteringTable->commit = 1; pFilteringTable->ip = iptype; pFilteringTable->num_rules = (uint8_t)IPACM_Iface::ipacmcfg->ipa_num_private_subnet; /* Make LAN-traffic always go A5, use default IPA-RT table */ if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_default_v4)) { IPACMERR("Failed to get routing table handle.\n"); res = IPACM_FAILURE; goto fail; } memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy)); flt_rule.status = -1; flt_rule.rule.retain_hdr = 1; flt_rule.rule.to_uc = 0; flt_rule.rule.action = IPA_PASS_TO_ROUTING; flt_rule.rule.eq_attrib_type = 0; flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_default_v4.hdl; IPACMDBG_H("Private filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_default_v4.name); memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib)); flt_rule.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; #ifdef FEATURE_ETH_BRIDGE_LE /* remove meta data mask */ flt_rule.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA); #endif for (i = 0; i < (IPACM_Iface::ipacmcfg->ipa_num_private_subnet); i++) { flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset+i]; flt_rule.rule.attrib.u.v4.dst_addr_mask = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask; flt_rule.rule.attrib.u.v4.dst_addr = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_addr; memcpy(&(pFilteringTable->rules[i]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); } if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) { IPACMERR("Failed to modify private subnet filtering rules.\n"); res = IPACM_FAILURE; goto fail; } /* copy filter rule hdls */ for (i = 0; i < IPACM_Iface::ipacmcfg->ipa_num_private_subnet; i++) { private_fl_rule_hdl[i] = pFilteringTable->rules[i].rule_hdl; } } else { return IPACM_SUCCESS; } fail: free(pFilteringTable); return res; } /* install UL filter rule from Q6 */ int IPACM_Wlan::handle_uplink_filter_rule(ipacm_ext_prop* prop, ipa_ip_type iptype) { ipa_flt_rule_add flt_rule_entry; int len = 0, cnt, ret = IPACM_SUCCESS, offset; ipa_ioc_add_flt_rule *pFilteringTable; ipa_fltr_installed_notif_req_msg_v01 flt_index; int fd; int i; IPACMDBG_H("Set extended property rules in LAN\n"); if (rx_prop == NULL) { IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); return IPACM_SUCCESS; } if(prop == NULL || prop->num_ext_props <= 0) { IPACMDBG_H("No extended property.\n"); return IPACM_SUCCESS; } if(wlan_ap_index > 0) { IPACMDBG_H("This is not the first WLAN AP, do not install modem UL rules.\n"); return IPACM_SUCCESS; } fd = open(IPA_DEVICE_NAME, O_RDWR); if (0 == fd) { IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME); } memset(&flt_index, 0, sizeof(flt_index)); flt_index.source_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[0].src_pipe); flt_index.install_status = IPA_QMI_RESULT_SUCCESS_V01; flt_index.filter_index_list_len = prop->num_ext_props; flt_index.embedded_pipe_index_valid = 1; flt_index.embedded_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, IPA_CLIENT_APPS_LAN_WAN_PROD); flt_index.retain_header_valid = 1; flt_index.retain_header = 0; flt_index.embedded_call_mux_id_valid = 1; flt_index.embedded_call_mux_id = IPACM_Iface::ipacmcfg->GetQmapId(); IPACMDBG_H("flt_index: src pipe: %d, num of rules: %d, ebd pipe: %d, mux id: %d\n", flt_index.source_pipe_index, flt_index.filter_index_list_len, flt_index.embedded_pipe_index, flt_index.embedded_call_mux_id); len = sizeof(struct ipa_ioc_add_flt_rule) + prop->num_ext_props * sizeof(struct ipa_flt_rule_add); pFilteringTable = (struct ipa_ioc_add_flt_rule*)malloc(len); if (pFilteringTable == NULL) { IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); close(fd); return IPACM_FAILURE; } memset(pFilteringTable, 0, len); pFilteringTable->commit = 1; pFilteringTable->ep = rx_prop->rx[0].src_pipe; pFilteringTable->global = false; pFilteringTable->ip = iptype; pFilteringTable->num_rules = prop->num_ext_props; memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); // Zero All Fields flt_rule_entry.at_rear = 1; flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.retain_hdr = 0; flt_rule_entry.rule.to_uc = 0; flt_rule_entry.rule.eq_attrib_type = 1; if(iptype == IPA_IP_v4) flt_rule_entry.rule.action = IPA_PASS_TO_SRC_NAT; else if(iptype == IPA_IP_v6) flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; else { IPACMERR("IP type is not expected.\n"); ret = IPACM_FAILURE; goto fail; } if(iptype == IPA_IP_v4) { #ifdef FEATURE_ETH_BRIDGE_LE offset = IPV4_DEFAULT_FILTERTING_RULES + 2 * IPACM_Iface::ipacmcfg->ipa_num_private_subnet + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_USB_CLIENT; #else #ifndef CT_OPT offset = 2*(IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet); #else offset = 2*(IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet); #endif #ifdef FEATURE_IPA_ANDROID offset = offset + 2 * (IPA_MAX_PRIVATE_SUBNET_ENTRIES - IPACM_Iface::ipacmcfg->ipa_num_private_subnet); #endif #endif } else { #ifdef FEATURE_ETH_BRIDGE_LE offset = IPV6_DEFAULT_FILTERTING_RULES + 1 + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_USB_CLIENT + NUM_IPV6_PREFIX_FLT_RULE + NUM_IPV6_ICMP_FLT_RULE; #else #ifndef CT_OPT offset = 2*(IPV6_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR) + NUM_IPV6_PREFIX_FLT_RULE + NUM_IPV6_ICMP_FLT_RULE; #else offset = 2*(IPV6_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR) + NUM_IPV6_PREFIX_FLT_RULE + NUM_IPV6_ICMP_FLT_RULE; #endif #endif } for(cnt=0; cntnum_ext_props; cnt++) { memcpy(&flt_rule_entry.rule.eq_attrib, &prop->prop[cnt].eq_attrib, sizeof(prop->prop[cnt].eq_attrib)); flt_rule_entry.rule.rt_tbl_idx = prop->prop[cnt].rt_tbl_idx; memcpy(&pFilteringTable->rules[cnt], &flt_rule_entry, sizeof(flt_rule_entry)); flt_index.filter_index_list[cnt].filter_index = offset+cnt; IPACMDBG_H("Modem UL filtering rule %d has index %d\n", cnt, offset+cnt); flt_index.filter_index_list[cnt].filter_handle = prop->prop[cnt].filter_hdl; } if(false == m_filtering.SendFilteringRuleIndex(&flt_index)) { IPACMERR("Error sending filtering rule index, aborting...\n"); ret = IPACM_FAILURE; goto fail; } if(false == m_filtering.AddFilteringRule(pFilteringTable)) { IPACMERR("Error Adding RuleTable to Filtering, aborting...\n"); ret = IPACM_FAILURE; goto fail; } else { if(iptype == IPA_IP_v4) { for(i=0; inum_rules; i++) { wan_ul_fl_rule_hdl_v4[num_wan_ul_fl_rule_v4] = pFilteringTable->rules[i].flt_rule_hdl; num_wan_ul_fl_rule_v4++; } } else if(iptype == IPA_IP_v6) { for(i=0; inum_rules; i++) { wan_ul_fl_rule_hdl_v6[num_wan_ul_fl_rule_v6] = pFilteringTable->rules[i].flt_rule_hdl; num_wan_ul_fl_rule_v6++; } } else { IPACMERR("IP type is not expected.\n"); goto fail; } } fail: free(pFilteringTable); close(fd); return ret; } /* handle wifi client initial,copy all partial headers (tx property) */ int IPACM_Wlan::handle_wlan_client_init_ex(ipacm_event_data_wlan_ex *data) { #define WLAN_IFACE_INDEX_LEN 2 int res = IPACM_SUCCESS, len = 0, i, evt_size; char index[WLAN_IFACE_INDEX_LEN]; struct ipa_ioc_copy_hdr sCopyHeader; struct ipa_ioc_add_hdr *pHeaderDescriptor = NULL; uint32_t cnt; /* start of adding header */ IPACMDBG_H("Wifi client number for this iface: %d & total number of wlan clients: %d\n", num_wifi_client,IPACM_Wlan::total_num_wifi_clients); if ((num_wifi_client >= IPA_MAX_NUM_WIFI_CLIENTS) || (IPACM_Wlan::total_num_wifi_clients >= IPA_MAX_NUM_WIFI_CLIENTS)) { IPACMERR("Reached maximum number of wlan clients\n"); return IPACM_FAILURE; } IPACMDBG_H("Wifi client number: %d\n", num_wifi_client); /* add header to IPA */ if(tx_prop != NULL) { len = sizeof(struct ipa_ioc_add_hdr) + (1 * sizeof(struct ipa_hdr_add)); pHeaderDescriptor = (struct ipa_ioc_add_hdr *)calloc(1, len); if (pHeaderDescriptor == NULL) { IPACMERR("calloc failed to allocate pHeaderDescriptor\n"); return IPACM_FAILURE; } evt_size = sizeof(ipacm_event_data_wlan_ex) + data->num_of_attribs * sizeof(struct ipa_wlan_hdr_attrib_val); get_client_memptr(wlan_client, num_wifi_client)->p_hdr_info = (ipacm_event_data_wlan_ex*)malloc(evt_size); memcpy(get_client_memptr(wlan_client, num_wifi_client)->p_hdr_info, data, evt_size); /* copy partial header for v4*/ for (cnt=0; cntnum_tx_props; cnt++) { if(tx_prop->tx[cnt].ip==IPA_IP_v4) { IPACMDBG_H("Got partial v4-header name from %d tx props\n", cnt); memset(&sCopyHeader, 0, sizeof(sCopyHeader)); memcpy(sCopyHeader.name, tx_prop->tx[cnt].hdr_name, sizeof(sCopyHeader.name)); IPACMDBG_H("header name: %s in tx:%d\n", sCopyHeader.name,cnt); if (m_header.CopyHeader(&sCopyHeader) == false) { PERROR("ioctl copy header failed"); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial); if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE) { IPACMERR("header oversize\n"); res = IPACM_FAILURE; goto fail; } else { memcpy(pHeaderDescriptor->hdr[0].hdr, sCopyHeader.hdr, sCopyHeader.hdr_len); } for(i = 0; i < data->num_of_attribs; i++) { if(data->attribs[i].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR) { memcpy(get_client_memptr(wlan_client, num_wifi_client)->mac, data->attribs[i].u.mac_addr, sizeof(get_client_memptr(wlan_client, num_wifi_client)->mac)); /* copy client mac_addr to partial header */ memcpy(&pHeaderDescriptor->hdr[0].hdr[data->attribs[i].offset], get_client_memptr(wlan_client, num_wifi_client)->mac, IPA_MAC_ADDR_SIZE); } else if(data->attribs[i].attrib_type == WLAN_HDR_ATTRIB_STA_ID) { /* copy client id to header */ memcpy(&pHeaderDescriptor->hdr[0].hdr[data->attribs[i].offset], &data->attribs[i].u.sta_id, sizeof(data->attribs[i].u.sta_id)); } else { IPACMDBG_H("The attribute type is not expected!\n"); } } pHeaderDescriptor->commit = true; pHeaderDescriptor->num_hdrs = 1; memset(pHeaderDescriptor->hdr[0].name, 0, sizeof(pHeaderDescriptor->hdr[0].name)); snprintf(index,sizeof(index), "%d", ipa_if_num); strlcpy(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)); if (strlcat(pHeaderDescriptor->hdr[0].name, IPA_WLAN_PARTIAL_HDR_NAME_v4, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX) { IPACMERR(" header name construction failed exceed length (%d)\n", strlen(pHeaderDescriptor->hdr[0].name)); res = IPACM_FAILURE; goto fail; } snprintf(index,sizeof(index), "%d", header_name_count); if (strlcat(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX) { IPACMERR(" header name construction failed exceed length (%d)\n", strlen(pHeaderDescriptor->hdr[0].name)); res = IPACM_FAILURE; goto fail; } pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len; pHeaderDescriptor->hdr[0].hdr_hdl = -1; pHeaderDescriptor->hdr[0].is_partial = 0; pHeaderDescriptor->hdr[0].status = -1; if (m_header.AddHeader(pHeaderDescriptor) == false || pHeaderDescriptor->hdr[0].status != 0) { IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status); res = IPACM_FAILURE; goto fail; } get_client_memptr(wlan_client, num_wifi_client)->hdr_hdl_v4 = pHeaderDescriptor->hdr[0].hdr_hdl; IPACMDBG_H("client(%d) v4 full header name:%s header handle:(0x%x)\n", num_wifi_client, pHeaderDescriptor->hdr[0].name, get_client_memptr(wlan_client, num_wifi_client)->hdr_hdl_v4); get_client_memptr(wlan_client, num_wifi_client)->ipv4_header_set=true; break; } } /* copy partial header for v6*/ for (cnt=0; cntnum_tx_props; cnt++) { if(tx_prop->tx[cnt].ip==IPA_IP_v6) { IPACMDBG_H("Got partial v6-header name from %d tx props\n", cnt); memset(&sCopyHeader, 0, sizeof(sCopyHeader)); memcpy(sCopyHeader.name, tx_prop->tx[cnt].hdr_name, sizeof(sCopyHeader.name)); IPACMDBG_H("header name: %s in tx:%d\n", sCopyHeader.name,cnt); if (m_header.CopyHeader(&sCopyHeader) == false) { PERROR("ioctl copy header failed"); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial); if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE) { IPACMERR("header oversize\n"); res = IPACM_FAILURE; goto fail; } else { memcpy(pHeaderDescriptor->hdr[0].hdr, sCopyHeader.hdr, sCopyHeader.hdr_len); } for(i = 0; i < data->num_of_attribs; i++) { if(data->attribs[i].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR) { memcpy(get_client_memptr(wlan_client, num_wifi_client)->mac, data->attribs[i].u.mac_addr, sizeof(get_client_memptr(wlan_client, num_wifi_client)->mac)); /* copy client mac_addr to partial header */ memcpy(&pHeaderDescriptor->hdr[0].hdr[data->attribs[i].offset], get_client_memptr(wlan_client, num_wifi_client)->mac, IPA_MAC_ADDR_SIZE); } else if (data->attribs[i].attrib_type == WLAN_HDR_ATTRIB_STA_ID) { /* copy client id to header */ memcpy(&pHeaderDescriptor->hdr[0].hdr[data->attribs[i].offset], &data->attribs[i].u.sta_id, sizeof(data->attribs[i].u.sta_id)); } else { IPACMDBG_H("The attribute type is not expected!\n"); } } pHeaderDescriptor->commit = true; pHeaderDescriptor->num_hdrs = 1; memset(pHeaderDescriptor->hdr[0].name, 0, sizeof(pHeaderDescriptor->hdr[0].name)); snprintf(index,sizeof(index), "%d", ipa_if_num); strlcpy(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)); if (strlcat(pHeaderDescriptor->hdr[0].name, IPA_WLAN_PARTIAL_HDR_NAME_v6, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX) { IPACMERR(" header name construction failed exceed length (%d)\n", strlen(pHeaderDescriptor->hdr[0].name)); res = IPACM_FAILURE; goto fail; } snprintf(index,sizeof(index), "%d", header_name_count); if (strlcat(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX) { IPACMERR(" header name construction failed exceed length (%d)\n", strlen(pHeaderDescriptor->hdr[0].name)); res = IPACM_FAILURE; goto fail; } pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len; pHeaderDescriptor->hdr[0].hdr_hdl = -1; pHeaderDescriptor->hdr[0].is_partial = 0; pHeaderDescriptor->hdr[0].status = -1; if (m_header.AddHeader(pHeaderDescriptor) == false || pHeaderDescriptor->hdr[0].status != 0) { IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status); res = IPACM_FAILURE; goto fail; } get_client_memptr(wlan_client, num_wifi_client)->hdr_hdl_v6 = pHeaderDescriptor->hdr[0].hdr_hdl; IPACMDBG_H("client(%d) v6 full header name:%s header handle:(0x%x)\n", num_wifi_client, pHeaderDescriptor->hdr[0].name, get_client_memptr(wlan_client, num_wifi_client)->hdr_hdl_v6); get_client_memptr(wlan_client, num_wifi_client)->ipv6_header_set=true; break; } } /* initialize wifi client*/ get_client_memptr(wlan_client, num_wifi_client)->route_rule_set_v4 = false; get_client_memptr(wlan_client, num_wifi_client)->route_rule_set_v6 = 0; get_client_memptr(wlan_client, num_wifi_client)->ipv4_set = false; get_client_memptr(wlan_client, num_wifi_client)->ipv6_set = 0; get_client_memptr(wlan_client, num_wifi_client)->power_save_set=false; num_wifi_client++; header_name_count++; //keep increasing header_name_count IPACM_Wlan::total_num_wifi_clients++; res = IPACM_SUCCESS; IPACMDBG_H("Wifi client number: %d\n", num_wifi_client); } else { return res; } fail: free(pHeaderDescriptor); return res; } /*handle wifi client */ int IPACM_Wlan::handle_wlan_client_ipaddr(ipacm_event_data_all *data) { int clnt_indx; int v6_num; IPACMDBG_H("number of wifi clients: %d\n", num_wifi_client); IPACMDBG_H(" event MAC %02x:%02x:%02x:%02x:%02x:%02x\n", data->mac_addr[0], data->mac_addr[1], data->mac_addr[2], data->mac_addr[3], data->mac_addr[4], data->mac_addr[5]); clnt_indx = get_wlan_client_index(data->mac_addr); if (clnt_indx == IPACM_INVALID_INDEX) { IPACMERR("wlan client not found/attached \n"); return IPACM_FAILURE; } IPACMDBG_H("Ip-type received %d\n", data->iptype); if (data->iptype == IPA_IP_v4) { IPACMDBG_H("ipv4 address: 0x%x\n", data->ipv4_addr); if (data->ipv4_addr != 0) /* not 0.0.0.0 */ { if (get_client_memptr(wlan_client, clnt_indx)->ipv4_set == false) { get_client_memptr(wlan_client, clnt_indx)->v4_addr = data->ipv4_addr; get_client_memptr(wlan_client, clnt_indx)->ipv4_set = true; } else { /* check if client got new IPv4 address*/ if(data->ipv4_addr == get_client_memptr(wlan_client, clnt_indx)->v4_addr) { IPACMDBG_H("Already setup ipv4 addr for client:%d, ipv4 address didn't change\n", clnt_indx); return IPACM_FAILURE; } else { IPACMDBG_H("ipv4 addr for client:%d is changed \n", clnt_indx); /* delete NAT rules first */ CtList->HandleNeighIpAddrDelEvt(get_client_memptr(wlan_client, clnt_indx)->v4_addr); delete_default_qos_rtrules(clnt_indx,IPA_IP_v4); get_client_memptr(wlan_client, clnt_indx)->route_rule_set_v4 = false; get_client_memptr(wlan_client, clnt_indx)->v4_addr = data->ipv4_addr; } } } else { IPACMDBG_H("Invalid client IPv4 address \n"); return IPACM_FAILURE; } } else { if ((data->ipv6_addr[0] != 0) || (data->ipv6_addr[1] != 0) || (data->ipv6_addr[2] != 0) || (data->ipv6_addr[3] || 0)) /* check if all 0 not valid ipv6 address */ { IPACMDBG_H("ipv6 address: 0x%x:%x:%x:%x\n", data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]); if(get_client_memptr(wlan_client, clnt_indx)->ipv6_set < IPV6_NUM_ADDR) { for(v6_num=0;v6_num < get_client_memptr(wlan_client, clnt_indx)->ipv6_set;v6_num++) { if( data->ipv6_addr[0] == get_client_memptr(wlan_client, clnt_indx)->v6_addr[v6_num][0] && data->ipv6_addr[1] == get_client_memptr(wlan_client, clnt_indx)->v6_addr[v6_num][1] && data->ipv6_addr[2]== get_client_memptr(wlan_client, clnt_indx)->v6_addr[v6_num][2] && data->ipv6_addr[3] == get_client_memptr(wlan_client, clnt_indx)->v6_addr[v6_num][3]) { IPACMDBG_H("Already see this ipv6 addr for client:%d\n", clnt_indx); return IPACM_FAILURE; /* not setup the RT rules*/ break; } } /* not see this ipv6 before for wifi client*/ get_client_memptr(wlan_client, clnt_indx)->v6_addr[get_client_memptr(wlan_client, clnt_indx)->ipv6_set][0] = data->ipv6_addr[0]; get_client_memptr(wlan_client, clnt_indx)->v6_addr[get_client_memptr(wlan_client, clnt_indx)->ipv6_set][1] = data->ipv6_addr[1]; get_client_memptr(wlan_client, clnt_indx)->v6_addr[get_client_memptr(wlan_client, clnt_indx)->ipv6_set][2] = data->ipv6_addr[2]; get_client_memptr(wlan_client, clnt_indx)->v6_addr[get_client_memptr(wlan_client, clnt_indx)->ipv6_set][3] = data->ipv6_addr[3]; get_client_memptr(wlan_client, clnt_indx)->ipv6_set++; } else { IPACMDBG_H("Already got 3 ipv6 addr for client:%d\n", clnt_indx); return IPACM_FAILURE; /* not setup the RT rules*/ } } } return IPACM_SUCCESS; } /*handle wifi client routing rule*/ int IPACM_Wlan::handle_wlan_client_route_rule(uint8_t *mac_addr, ipa_ip_type iptype) { struct ipa_ioc_add_rt_rule *rt_rule; struct ipa_rt_rule_add *rt_rule_entry; uint32_t tx_index; int wlan_index,v6_num; const int NUM = 1; if(tx_prop == NULL) { IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); return IPACM_SUCCESS; } IPACMDBG_H("Received mac_addr MAC %02x:%02x:%02x:%02x:%02x:%02x\n", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); wlan_index = get_wlan_client_index(mac_addr); if (wlan_index == IPACM_INVALID_INDEX) { IPACMDBG_H("wlan client not found/attached \n"); return IPACM_SUCCESS; } /* during power_save mode, even receive IP_ADDR_ADD, not setting RT rules*/ if (get_client_memptr(wlan_client, wlan_index)->power_save_set == true) { IPACMDBG_H("wlan client is in power safe mode \n"); return IPACM_SUCCESS; } if (iptype==IPA_IP_v4) { IPACMDBG_H("wlan client index: %d, ip-type: %d, ipv4_set:%d, ipv4_rule_set:%d \n", wlan_index, iptype, get_client_memptr(wlan_client, wlan_index)->ipv4_set, get_client_memptr(wlan_client, wlan_index)->route_rule_set_v4); } else { IPACMDBG_H("wlan client index: %d, ip-type: %d, ipv6_set:%d, ipv6_rule_num:%d \n", wlan_index, iptype, get_client_memptr(wlan_client, wlan_index)->ipv6_set, get_client_memptr(wlan_client, wlan_index)->route_rule_set_v6); } /* Add default Qos routing rules if not set yet */ if ((iptype == IPA_IP_v4 && get_client_memptr(wlan_client, wlan_index)->route_rule_set_v4 == false && get_client_memptr(wlan_client, wlan_index)->ipv4_set == true) || (iptype == IPA_IP_v6 && get_client_memptr(wlan_client, wlan_index)->route_rule_set_v6 < get_client_memptr(wlan_client, wlan_index)->ipv6_set )) { rt_rule = (struct ipa_ioc_add_rt_rule *) calloc(1, sizeof(struct ipa_ioc_add_rt_rule) + NUM * sizeof(struct ipa_rt_rule_add)); if (rt_rule == NULL) { PERROR("Error Locate ipa_ioc_add_rt_rule memory...\n"); return IPACM_FAILURE; } rt_rule->commit = 1; rt_rule->num_rules = (uint8_t)NUM; rt_rule->ip = iptype; for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) { if(iptype != tx_prop->tx[tx_index].ip) { IPACMDBG_H("Tx:%d, ip-type: %d conflict ip-type: %d no RT-rule added\n", tx_index, tx_prop->tx[tx_index].ip,iptype); continue; } rt_rule_entry = &rt_rule->rules[0]; rt_rule_entry->at_rear = 0; if (iptype == IPA_IP_v4) { IPACMDBG_H("client index(%d):ipv4 address: 0x%x\n", wlan_index, get_client_memptr(wlan_client, wlan_index)->v4_addr); IPACMDBG_H("client(%d): v4 header handle:(0x%x)\n", wlan_index, get_client_memptr(wlan_client, wlan_index)->hdr_hdl_v4); strncpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name, sizeof(rt_rule->rt_tbl_name)); rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe; memcpy(&rt_rule_entry->rule.attrib, &tx_prop->tx[tx_index].attrib, sizeof(rt_rule_entry->rule.attrib)); rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; rt_rule_entry->rule.hdr_hdl = get_client_memptr(wlan_client, wlan_index)->hdr_hdl_v4; rt_rule_entry->rule.attrib.u.v4.dst_addr = get_client_memptr(wlan_client, wlan_index)->v4_addr; rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF; if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); free(rt_rule); return IPACM_FAILURE; } /* copy ipv4 RT hdl */ get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v4 = rt_rule->rules[0].rt_rule_hdl; IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index, get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v4, iptype); } else { for(v6_num = get_client_memptr(wlan_client, wlan_index)->route_rule_set_v6;v6_num < get_client_memptr(wlan_client, wlan_index)->ipv6_set;v6_num++) { IPACMDBG_H("client(%d): v6 header handle:(0x%x)\n", wlan_index, get_client_memptr(wlan_client, wlan_index)->hdr_hdl_v6); /* v6 LAN_RT_TBL */ strncpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_v6.name, sizeof(rt_rule->rt_tbl_name)); /* Support QCMAP LAN traffic feature, send to A5 */ rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS; memset(&rt_rule_entry->rule.attrib, 0, sizeof(rt_rule_entry->rule.attrib)); rt_rule_entry->rule.hdr_hdl = 0; rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][0]; rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][1]; rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][2]; rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][3]; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF; if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); free(rt_rule); return IPACM_FAILURE; } get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6[v6_num] = rt_rule->rules[0].rt_rule_hdl; IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index, get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6[v6_num], iptype); /*Copy same rule to v6 WAN RT TBL*/ strncpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name)); /* Downlink traffic from Wan iface, directly through IPA */ rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe; memcpy(&rt_rule_entry->rule.attrib, &tx_prop->tx[tx_index].attrib, sizeof(rt_rule_entry->rule.attrib)); rt_rule_entry->rule.hdr_hdl = get_client_memptr(wlan_client, wlan_index)->hdr_hdl_v6; rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][0]; rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][1]; rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][2]; rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num][3]; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF; if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); free(rt_rule); return IPACM_FAILURE; } get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6_wan[v6_num] = rt_rule->rules[0].rt_rule_hdl; IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index, get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6_wan[v6_num], iptype); } } } /* end of for loop */ free(rt_rule); if (iptype == IPA_IP_v4) { get_client_memptr(wlan_client, wlan_index)->route_rule_set_v4 = true; } else { get_client_memptr(wlan_client, wlan_index)->route_rule_set_v6 = get_client_memptr(wlan_client, wlan_index)->ipv6_set; } } return IPACM_SUCCESS; } /*handle wifi client power-save mode*/ int IPACM_Wlan::handle_wlan_client_pwrsave(uint8_t *mac_addr) { int clt_indx; IPACMDBG_H("wlan->handle_wlan_client_pwrsave();\n"); clt_indx = get_wlan_client_index(mac_addr); if (clt_indx == IPACM_INVALID_INDEX) { IPACMDBG_H("wlan client not attached\n"); return IPACM_SUCCESS; } if (get_client_memptr(wlan_client, clt_indx)->power_save_set == false) { /* First reset nat rules and then route rules */ if(get_client_memptr(wlan_client, clt_indx)->ipv4_set == true) { IPACMDBG_H("Deleting Nat Rules\n"); Nat_App->UpdatePwrSaveIf(get_client_memptr(wlan_client, clt_indx)->v4_addr); } IPACMDBG_H("Deleting default qos Route Rules\n"); delete_default_qos_rtrules(clt_indx, IPA_IP_v4); delete_default_qos_rtrules(clt_indx, IPA_IP_v6); get_client_memptr(wlan_client, clt_indx)->power_save_set = true; } else { IPACMDBG_H("wlan client already in power-save mode\n"); } return IPACM_SUCCESS; } /*handle wifi client del mode*/ int IPACM_Wlan::handle_wlan_client_down_evt(uint8_t *mac_addr) { int clt_indx; uint32_t tx_index; int num_wifi_client_tmp = num_wifi_client; int num_v6; IPACMDBG_H("total client: %d\n", num_wifi_client_tmp); clt_indx = get_wlan_client_index(mac_addr); if (clt_indx == IPACM_INVALID_INDEX) { IPACMDBG_H("wlan client not attached\n"); return IPACM_SUCCESS; } /* First reset nat rules and then route rules */ if(get_client_memptr(wlan_client, clt_indx)->ipv4_set == true) { IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(wlan_client, clt_indx)->v4_addr); CtList->HandleNeighIpAddrDelEvt(get_client_memptr(wlan_client, clt_indx)->v4_addr); } if (delete_default_qos_rtrules(clt_indx, IPA_IP_v4)) { IPACMERR("unbale to delete v4 default qos route rules for index: %d\n", clt_indx); return IPACM_FAILURE; } if (delete_default_qos_rtrules(clt_indx, IPA_IP_v6)) { IPACMERR("unbale to delete v6 default qos route rules for indexn: %d\n", clt_indx); return IPACM_FAILURE; } /* Delete wlan client header */ if(get_client_memptr(wlan_client, clt_indx)->ipv4_header_set == true) { if (m_header.DeleteHeaderHdl(get_client_memptr(wlan_client, clt_indx)->hdr_hdl_v4) == false) { return IPACM_FAILURE; } get_client_memptr(wlan_client, clt_indx)->ipv4_header_set = false; } if(get_client_memptr(wlan_client, clt_indx)->ipv6_header_set == true) { if (m_header.DeleteHeaderHdl(get_client_memptr(wlan_client, clt_indx)->hdr_hdl_v6) == false) { return IPACM_FAILURE; } get_client_memptr(wlan_client, clt_indx)->ipv6_header_set = false; } /* Reset ip_set to 0*/ get_client_memptr(wlan_client, clt_indx)->ipv4_set = false; get_client_memptr(wlan_client, clt_indx)->ipv6_set = 0; get_client_memptr(wlan_client, clt_indx)->ipv4_header_set = false; get_client_memptr(wlan_client, clt_indx)->ipv6_header_set = false; get_client_memptr(wlan_client, clt_indx)->route_rule_set_v4 = false; get_client_memptr(wlan_client, clt_indx)->route_rule_set_v6 = 0; free(get_client_memptr(wlan_client, clt_indx)->p_hdr_info); for (; clt_indx < num_wifi_client_tmp - 1; clt_indx++) { get_client_memptr(wlan_client, clt_indx)->p_hdr_info = get_client_memptr(wlan_client, (clt_indx + 1))->p_hdr_info; memcpy(get_client_memptr(wlan_client, clt_indx)->mac, get_client_memptr(wlan_client, (clt_indx + 1))->mac, sizeof(get_client_memptr(wlan_client, clt_indx)->mac)); get_client_memptr(wlan_client, clt_indx)->hdr_hdl_v4 = get_client_memptr(wlan_client, (clt_indx + 1))->hdr_hdl_v4; get_client_memptr(wlan_client, clt_indx)->hdr_hdl_v6 = get_client_memptr(wlan_client, (clt_indx + 1))->hdr_hdl_v6; get_client_memptr(wlan_client, clt_indx)->v4_addr = get_client_memptr(wlan_client, (clt_indx + 1))->v4_addr; get_client_memptr(wlan_client, clt_indx)->ipv4_set = get_client_memptr(wlan_client, (clt_indx + 1))->ipv4_set; get_client_memptr(wlan_client, clt_indx)->ipv6_set = get_client_memptr(wlan_client, (clt_indx + 1))->ipv6_set; get_client_memptr(wlan_client, clt_indx)->ipv4_header_set = get_client_memptr(wlan_client, (clt_indx + 1))->ipv4_header_set; get_client_memptr(wlan_client, clt_indx)->ipv6_header_set = get_client_memptr(wlan_client, (clt_indx + 1))->ipv6_header_set; get_client_memptr(wlan_client, clt_indx)->route_rule_set_v4 = get_client_memptr(wlan_client, (clt_indx + 1))->route_rule_set_v4; get_client_memptr(wlan_client, clt_indx)->route_rule_set_v6 = get_client_memptr(wlan_client, (clt_indx + 1))->route_rule_set_v6; for(num_v6=0;num_v6< get_client_memptr(wlan_client, clt_indx)->ipv6_set;num_v6++) { get_client_memptr(wlan_client, clt_indx)->v6_addr[num_v6][0] = get_client_memptr(wlan_client, (clt_indx + 1))->v6_addr[num_v6][0]; get_client_memptr(wlan_client, clt_indx)->v6_addr[num_v6][1] = get_client_memptr(wlan_client, (clt_indx + 1))->v6_addr[num_v6][1]; get_client_memptr(wlan_client, clt_indx)->v6_addr[num_v6][2] = get_client_memptr(wlan_client, (clt_indx + 1))->v6_addr[num_v6][2]; get_client_memptr(wlan_client, clt_indx)->v6_addr[num_v6][3] = get_client_memptr(wlan_client, (clt_indx + 1))->v6_addr[num_v6][3]; } for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) { get_client_memptr(wlan_client, clt_indx)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v4 = get_client_memptr(wlan_client, (clt_indx + 1))->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v4; for(num_v6=0;num_v6< get_client_memptr(wlan_client, clt_indx)->route_rule_set_v6;num_v6++) { get_client_memptr(wlan_client, clt_indx)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6[num_v6] = get_client_memptr(wlan_client, (clt_indx + 1))->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6[num_v6]; get_client_memptr(wlan_client, clt_indx)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6_wan[num_v6] = get_client_memptr(wlan_client, (clt_indx + 1))->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6_wan[num_v6]; } } } IPACMDBG_H(" %d wifi client deleted successfully \n", num_wifi_client); num_wifi_client = num_wifi_client - 1; IPACM_Wlan::total_num_wifi_clients = IPACM_Wlan::total_num_wifi_clients - 1; IPACMDBG_H(" Number of wifi client: %d\n", num_wifi_client); return IPACM_SUCCESS; } /*handle wlan iface down event*/ int IPACM_Wlan::handle_down_evt() { int res = IPACM_SUCCESS, i; IPACMDBG_H("WLAN ip-type: %d \n", ip_type); /* no iface address up, directly close iface*/ if (ip_type == IPACM_IP_NULL) { IPACMERR("Invalid iptype: 0x%x\n", ip_type); goto fail; } #ifdef FEATURE_ETH_BRIDGE_LE if(wlan_ap_index == 0) { IPACM_Lan::wlan_hdr_type = IPA_HDR_L2_NONE; IPACM_Lan::wlan_hdr_template_hdl = 0; del_hdr_proc_ctx(); } #endif /* delete wan filter rule */ if (IPACM_Wan::isWanUP(ipa_if_num) && rx_prop != NULL) { IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_is_sta_mode); IPACM_Lan::handle_wan_down(IPACM_Wan::backhaul_is_sta_mode); } if (IPACM_Wan::isWanUP_V6(ipa_if_num) && rx_prop != NULL) { IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_is_sta_mode); IPACM_Lan::handle_wan_down_v6(IPACM_Wan::backhaul_is_sta_mode); } IPACMDBG_H("finished deleting wan filtering rules\n "); /* Delete v4 filtering rules */ if (ip_type != IPA_IP_v6 && rx_prop != NULL) { #ifdef FEATURE_ETH_BRIDGE_LE if(wlan_ap_index == 0) { /* delete default filter rules */ for(i=0; iipa_num_private_subnet; i++) { if(reset_to_dummy_flt_rule(IPA_IP_v4, wlan_guest_ap_flt_rule_hdl_v4[i]) == IPACM_FAILURE) { IPACMERR("Error deleting wlan guest ap IPv4 flt rules.\n"); res = IPACM_FAILURE; goto fail; } } } IPACMDBG_H("Deleted guest ap v4 filter rules successfully.\n"); #endif /* delete icmp filter rules */ if(wlan_ap_index == 0) { if(m_filtering.DeleteFilteringHdls(ipv6_icmp_flt_rule_hdl, IPA_IP_v6, NUM_IPV6_ICMP_FLT_RULE) == false) { IPACMERR("Error Deleting ICMPv6 Filtering Rule, aborting...\n"); res = IPACM_FAILURE; goto fail; } } #ifndef FEATURE_ETH_BRIDGE_LE #ifdef CT_OPT IPACMDBG_H("Delete tcp control flt rules.\n"); /* Delete tcp control flt rules */ for(i=0; iipa_num_private_subnet; i++) { if(reset_to_dummy_flt_rule(IPA_IP_v4, private_fl_rule_hdl[i]) == IPACM_FAILURE) { IPACMERR("Error deleting private subnet IPv4 flt rules.\n"); res = IPACM_FAILURE; goto fail; } } } IPACMDBG_H("Deleted private subnet v4 filter rules successfully.\n"); #endif } /* Delete v6 filtering rules */ if (ip_type != IPA_IP_v4 && rx_prop != NULL) { IPACMDBG_H("Delete default %d v6 filter rules\n", IPV6_DEFAULT_FILTERTING_RULES); /* delete default filter rules */ #ifdef FEATURE_ETH_BRIDGE_LE if(wlan_ap_index == 0) { for(i=0; imac); eth_bridge_del_self_client_flt_rule(get_client_memptr(wlan_client, i)->mac); eth_bridge_post_lan_client_event(get_client_memptr(wlan_client, i)->mac, IPA_ETH_BRIDGE_WLAN_CLIENT_DEL_EVENT); eth_bridge_del_wlan_client_rt_rule(get_client_memptr(wlan_client, i)->mac, SRC_WLAN); eth_bridge_del_wlan_client_rt_rule(get_client_memptr(wlan_client, i)->mac, SRC_USB); #endif /* First reset nat rules and then route rules */ if(get_client_memptr(wlan_client, i)->ipv4_set == true) { IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(wlan_client, i)->v4_addr); CtList->HandleNeighIpAddrDelEvt(get_client_memptr(wlan_client, i)->v4_addr); } if (delete_default_qos_rtrules(i, IPA_IP_v4)) { IPACMERR("unbale to delete v4 default qos route rules for index: %d\n", i); res = IPACM_FAILURE; goto fail; } if (delete_default_qos_rtrules(i, IPA_IP_v6)) { IPACMERR("unbale to delete v6 default qos route rules for index: %d\n", i); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("Delete %d client header\n", num_wifi_client); handle_lan2lan_msg_post(get_client_memptr(wlan_client, i)->mac, IPA_LAN_CLIENT_DISCONNECT, IPA_IP_v4); handle_lan2lan_msg_post(get_client_memptr(wlan_client, i)->mac, IPA_LAN_CLIENT_DISCONNECT, IPA_IP_v6); if(get_client_memptr(wlan_client, i)->ipv4_header_set == true) { if (m_header.DeleteHeaderHdl(get_client_memptr(wlan_client, i)->hdr_hdl_v4) == false) { res = IPACM_FAILURE; goto fail; } } if(get_client_memptr(wlan_client, i)->ipv6_header_set == true) { if (m_header.DeleteHeaderHdl(get_client_memptr(wlan_client, i)->hdr_hdl_v6) == false) { res = IPACM_FAILURE; goto fail; } } } /* end of for loop */ /* free the wlan clients cache */ IPACMDBG_H("Free wlan clients cache\n"); /* Delete private subnet*/ #ifdef FEATURE_IPA_ANDROID if (ip_type != IPA_IP_v6) { IPACMDBG_H("current IPACM private subnet_addr number(%d)\n", IPACM_Iface::ipacmcfg->ipa_num_private_subnet); IPACMDBG_H(" Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet); if(IPACM_Iface::ipacmcfg->DelPrivateSubnet(if_ipv4_subnet, ipa_if_num) == false) { IPACMERR(" can't Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet); } } /* reset the IPA-client pipe enum */ handle_tethering_client(true, IPACM_CLIENT_WLAN); #endif /* defined(FEATURE_IPA_ANDROID)*/ fail: /* Delete corresponding ipa_rm_resource_name of RX-endpoint after delete all IPV4V6 FT-rule */ if (rx_prop != NULL) { IPACMDBG_H("dev %s add producer dependency\n", dev_name); IPACMDBG_H("depend Got pipe %d rm index : %d \n", rx_prop->rx[0].src_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe]); IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe]); free(rx_prop); } for (i = 0; i < num_wifi_client; i++) { if(get_client_memptr(wlan_client, i)->p_hdr_info != NULL) { free(get_client_memptr(wlan_client, i)->p_hdr_info); } } if(wlan_client != NULL) { free(wlan_client); } if (tx_prop != NULL) { free(tx_prop); } if (iface_query != NULL) { free(iface_query); } #ifdef FEATURE_ETH_BRIDGE_LE if(eth_bridge_usb_client_rt_info_v4 != NULL) { free(eth_bridge_usb_client_rt_info_v4); } if(eth_bridge_usb_client_rt_info_v6 != NULL) { free(eth_bridge_usb_client_rt_info_v6); } if(eth_bridge_wlan_client_rt_from_usb_info_v4 != NULL) { free(eth_bridge_wlan_client_rt_from_usb_info_v4); } if(eth_bridge_wlan_client_rt_from_usb_info_v6 != NULL) { free(eth_bridge_wlan_client_rt_from_usb_info_v6); } if(eth_bridge_wlan_client_rt_from_wlan_info_v4 != NULL) { free(eth_bridge_wlan_client_rt_from_wlan_info_v4); } if(eth_bridge_wlan_client_rt_from_wlan_info_v6 != NULL) { free(eth_bridge_wlan_client_rt_from_wlan_info_v6); } #endif is_active = false; post_del_self_evt(); return res; } /*handle reset wifi-client rt-rules */ int IPACM_Wlan::handle_wlan_client_reset_rt(ipa_ip_type iptype) { int i, res = IPACM_SUCCESS; /* clean wifi-client routing rules */ IPACMDBG_H("left %d wifi clients to reset ip-type(%d) rules \n ", num_wifi_client, iptype); for (i = 0; i < num_wifi_client; i++) { /* Reset RT rules */ res = delete_default_qos_rtrules(i, iptype); if (res != IPACM_SUCCESS) { IPACMERR("Failed to delete old iptype(%d) rules.\n", iptype); return res; } /* Pass info to LAN2LAN module */ res = handle_lan2lan_msg_post(get_client_memptr(wlan_client, i)->mac, IPA_LAN_CLIENT_DISCONNECT, iptype); if (res != IPACM_SUCCESS) { IPACMERR("Failed to posting delete old iptype(%d) address.\n", iptype); return res; } /* Reset ip-address */ if(iptype == IPA_IP_v4) { get_client_memptr(wlan_client, i)->ipv4_set = false; } else { get_client_memptr(wlan_client, i)->ipv6_set = 0; } } /* end of for loop */ return res; } /*handle lan2lan internal mesg posting*/ int IPACM_Wlan::handle_lan2lan_msg_post(uint8_t *mac_addr, ipa_cm_event_id event,ipa_ip_type iptype) { int client_index; client_index = get_wlan_client_index(mac_addr); if (client_index == IPACM_INVALID_INDEX) { IPACMDBG_H("wlan client not attached\n"); return IPACM_SUCCESS; } ipacm_event_lan_client* lan_client; ipacm_cmd_q_data evt_data; if((get_client_memptr(wlan_client, client_index)->ipv4_set == true) && (iptype == IPA_IP_v4)) /* handle ipv4 case*/ { if(ip_type != IPA_IP_v4 && ip_type != IPA_IP_MAX) { IPACMERR("Client has IPv4 addr but iface does not have IPv4 up.\n"); return IPACM_FAILURE; } lan_client = (ipacm_event_lan_client*)malloc(sizeof(ipacm_event_lan_client)); if(lan_client == NULL) { IPACMERR("Unable to allocate memory.\n"); return IPACM_FAILURE; } memset(lan_client, 0, sizeof(ipacm_event_lan_client)); lan_client->iptype = IPA_IP_v4; lan_client->ipv4_addr = get_client_memptr(wlan_client, client_index)->v4_addr; lan_client->p_iface = this; memset(&evt_data, 0, sizeof(evt_data)); evt_data.event = event; evt_data.evt_data = (void*)lan_client; IPACMDBG_H("Posting event: %d\n",event); IPACM_EvtDispatcher::PostEvt(&evt_data); } if((get_client_memptr(wlan_client, client_index)->ipv6_set > 0) && (iptype == IPA_IP_v6)) /* handle v6 case: may be multiple v6 addr */ { if(ip_type != IPA_IP_v6 && ip_type != IPA_IP_MAX) { IPACMERR("Client has IPv6 addr but iface does not have IPv6 up.\n"); return IPACM_FAILURE; } int i; for(i=0; iipv6_set; i++) { lan_client = (ipacm_event_lan_client*)malloc(sizeof(ipacm_event_lan_client)); if(lan_client == NULL) { IPACMERR("Unable to allocate memory.\n"); return IPACM_FAILURE; } memset(lan_client, 0, sizeof(ipacm_event_lan_client)); lan_client->iptype = IPA_IP_v6; memcpy(lan_client->ipv6_addr, get_client_memptr(wlan_client, client_index)->v6_addr[i], 4*sizeof(uint32_t)); lan_client->p_iface = this; memset(&evt_data, 0, sizeof(evt_data)); evt_data.event = event; evt_data.evt_data = (void*)lan_client; IPACMDBG_H("Posting event: %d\n",event); IPACM_EvtDispatcher::PostEvt(&evt_data); } } return IPACM_SUCCESS; } int IPACM_Wlan::add_lan2lan_hdr(ipa_ip_type iptype, uint8_t* src_mac, uint8_t* dst_mac, uint32_t* hdr_hdl) { if(tx_prop == NULL) { IPACMERR("There is no tx_prop, cannot add header.\n"); return IPACM_FAILURE; } if(src_mac == NULL || dst_mac == NULL) { IPACMERR("Either src_mac or dst_mac is null, cannot add header.\n"); return IPACM_FAILURE; } if(hdr_hdl == NULL) { IPACMERR("Header handle is empty.\n"); return IPACM_FAILURE; } int i, j, k, len; int res = IPACM_SUCCESS; char index[4]; struct ipa_ioc_copy_hdr sCopyHeader; struct ipa_ioc_add_hdr *pHeader; IPACMDBG_H("Get lan2lan header request, src_mac: 0x%02x%02x%02x%02x%02x%02x dst_mac: 0x%02x%02x%02x%02x%02x%02x\n", src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5], dst_mac[0], dst_mac[1], dst_mac[2], dst_mac[3], dst_mac[4], dst_mac[5]); len = sizeof(struct ipa_ioc_add_hdr) + sizeof(struct ipa_hdr_add); pHeader = (struct ipa_ioc_add_hdr *)malloc(len); if (pHeader == NULL) { IPACMERR("Failed to allocate header\n"); return IPACM_FAILURE; } memset(pHeader, 0, len); if(iptype == IPA_IP_v4) { /* copy partial header for v4*/ for(i=0; inum_tx_props; i++) { if(tx_prop->tx[i].ip == IPA_IP_v4) { IPACMDBG_H("Got v4-header name from %d tx props\n", i); memset(&sCopyHeader, 0, sizeof(sCopyHeader)); memcpy(sCopyHeader.name, tx_prop->tx[i].hdr_name, sizeof(sCopyHeader.name)); IPACMDBG_H("Header name: %s\n", sCopyHeader.name); if(m_header.CopyHeader(&sCopyHeader) == false) { IPACMERR("Copy header failed\n"); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("Header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial); if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE) { IPACMERR("Header oversize\n"); res = IPACM_FAILURE; goto fail; } else { memcpy(pHeader->hdr[0].hdr, sCopyHeader.hdr, sCopyHeader.hdr_len); } for(j=0; jmac, IPA_MAC_ADDR_SIZE) == 0) { break; } } if(j == num_wifi_client) { IPACMERR("Not able to find the wifi client from mac addr.\n"); res = IPACM_FAILURE; goto fail; } else { IPACMDBG_H("Find wifi client at position %d\n", j); for(k = 0; k < get_client_memptr(wlan_client, j)->p_hdr_info->num_of_attribs; k++) { if(get_client_memptr(wlan_client, j)->p_hdr_info->attribs[k].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR) { memcpy(&pHeader->hdr[0].hdr[get_client_memptr(wlan_client, j)->p_hdr_info->attribs[k].offset], dst_mac, IPA_MAC_ADDR_SIZE); memcpy(&pHeader->hdr[0].hdr[get_client_memptr(wlan_client, j)->p_hdr_info->attribs[k].offset + IPA_MAC_ADDR_SIZE], src_mac, IPA_MAC_ADDR_SIZE); } else if(get_client_memptr(wlan_client, j)->p_hdr_info->attribs[k].attrib_type == WLAN_HDR_ATTRIB_STA_ID) { memcpy(&pHeader->hdr[0].hdr[get_client_memptr(wlan_client, j)->p_hdr_info->attribs[k].offset], &get_client_memptr(wlan_client, j)->p_hdr_info->attribs[k].u.sta_id, sizeof(get_client_memptr(wlan_client, j)->p_hdr_info->attribs[k].u.sta_id)); } else { IPACMDBG_H("The attribute type is not expected!\n"); } } } pHeader->commit = true; pHeader->num_hdrs = 1; memset(pHeader->hdr[0].name, 0, sizeof(pHeader->hdr[0].name)); strlcpy(pHeader->hdr[0].name, IPA_LAN_TO_LAN_WLAN_HDR_NAME_V4, sizeof(pHeader->hdr[0].name)); for(j=0; jhdr[0].name, index, sizeof(pHeader->hdr[0].name)) > IPA_RESOURCE_NAME_MAX) { IPACMERR(" header name construction failed exceed length (%d)\n", strlen(pHeader->hdr[0].name)); res = IPACM_FAILURE; goto fail; } pHeader->hdr[0].hdr_len = sCopyHeader.hdr_len; pHeader->hdr[0].is_partial = 0; pHeader->hdr[0].hdr_hdl = -1; pHeader->hdr[0].status = -1; if (m_header.AddHeader(pHeader) == false || pHeader->hdr[0].status != 0) { IPACMERR("Ioctl IPA_IOC_ADD_HDR failed with status: %d\n", pHeader->hdr[0].status); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("Installed v4 full header %s header handle 0x%08x\n", pHeader->hdr[0].name, pHeader->hdr[0].hdr_hdl); *hdr_hdl = pHeader->hdr[0].hdr_hdl; lan2lan_hdr_hdl_v4[j].hdr_hdl = pHeader->hdr[0].hdr_hdl; break; } } } else if(iptype == IPA_IP_v6) { /* copy partial header for v6*/ for(i=0; inum_tx_props; i++) { if(tx_prop->tx[i].ip == IPA_IP_v6) { IPACMDBG_H("Got v6-header name from %d tx props\n", i); memset(&sCopyHeader, 0, sizeof(sCopyHeader)); memcpy(sCopyHeader.name, tx_prop->tx[i].hdr_name, sizeof(sCopyHeader.name)); IPACMDBG_H("Header name: %s\n", sCopyHeader.name); if(m_header.CopyHeader(&sCopyHeader) == false) { IPACMERR("Copy header failed\n"); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("Header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial); if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE) { IPACMERR("Header oversize\n"); res = IPACM_FAILURE; goto fail; } else { memcpy(pHeader->hdr[0].hdr, sCopyHeader.hdr, sCopyHeader.hdr_len); } for(j=0; jmac, IPA_MAC_ADDR_SIZE) == 0) { break; } } if(j == num_wifi_client) { IPACMERR("Not able to find the wifi client from mac addr.\n"); res = IPACM_FAILURE; goto fail; } else { IPACMDBG_H("Find wifi client at position %d\n", j); for(k = 0; k < get_client_memptr(wlan_client, j)->p_hdr_info->num_of_attribs; k++) { if(get_client_memptr(wlan_client, j)->p_hdr_info->attribs[k].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR) { memcpy(&pHeader->hdr[0].hdr[get_client_memptr(wlan_client, j)->p_hdr_info->attribs[k].offset], dst_mac, IPA_MAC_ADDR_SIZE); memcpy(&pHeader->hdr[0].hdr[get_client_memptr(wlan_client, j)->p_hdr_info->attribs[k].offset + IPA_MAC_ADDR_SIZE], src_mac, IPA_MAC_ADDR_SIZE); } else if(get_client_memptr(wlan_client, j)->p_hdr_info->attribs[k].attrib_type == WLAN_HDR_ATTRIB_STA_ID) { memcpy(&pHeader->hdr[0].hdr[get_client_memptr(wlan_client, j)->p_hdr_info->attribs[k].offset], &get_client_memptr(wlan_client, j)->p_hdr_info->attribs[k].u.sta_id, sizeof(get_client_memptr(wlan_client, j)->p_hdr_info->attribs[k].u.sta_id)); } else { IPACMDBG_H("The attribute type is not expected!\n"); } } } pHeader->commit = true; pHeader->num_hdrs = 1; memset(pHeader->hdr[0].name, 0, sizeof(pHeader->hdr[0].name)); strlcpy(pHeader->hdr[0].name, IPA_LAN_TO_LAN_WLAN_HDR_NAME_V6, sizeof(pHeader->hdr[0].name)); for(j=0; jhdr[0].name, index, sizeof(pHeader->hdr[0].name)) > IPA_RESOURCE_NAME_MAX) { IPACMERR(" header name construction failed exceed length (%d)\n", strlen(pHeader->hdr[0].name)); res = IPACM_FAILURE; goto fail; } pHeader->hdr[0].hdr_len = sCopyHeader.hdr_len; pHeader->hdr[0].is_partial = 0; pHeader->hdr[0].hdr_hdl = -1; pHeader->hdr[0].status = -1; if (m_header.AddHeader(pHeader) == false || pHeader->hdr[0].status != 0) { IPACMERR("Ioctl IPA_IOC_ADD_HDR failed with status: %d\n", pHeader->hdr[0].status); res = IPACM_FAILURE; goto fail; } IPACMDBG_H("Installed v6 full header %s header handle 0x%08x\n", pHeader->hdr[0].name, pHeader->hdr[0].hdr_hdl); *hdr_hdl = pHeader->hdr[0].hdr_hdl; lan2lan_hdr_hdl_v6[j].hdr_hdl = pHeader->hdr[0].hdr_hdl; break; } } } else { IPACMERR("IP type is not expected.\n"); } fail: free(pHeader); return res; } /* add dummy filtering rules for WLAN AP-AP mode support */ void IPACM_Wlan::add_dummy_flt_rule() { int num_v4_dummy_rule, num_v6_dummy_rule; if(IPACM_Wlan::num_wlan_ap_iface == 1) { if(IPACM_Wlan::dummy_flt_rule_hdl_v4 != NULL || IPACM_Wlan::dummy_flt_rule_hdl_v6 != NULL) { IPACMERR("Either v4 or v6 dummy filtering rule handle is not empty.\n"); return; } #ifdef FEATURE_ETH_BRIDGE_LE num_v4_dummy_rule = IPV4_DEFAULT_FILTERTING_RULES + IPACM_Iface::ipacmcfg->ipa_num_private_subnet + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_USB_CLIENT + IPACM_Iface::ipacmcfg->ipa_num_private_subnet; num_v6_dummy_rule = IPV6_DEFAULT_FILTERTING_RULES + 1 + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_USB_CLIENT; #else #ifndef CT_OPT num_v4_dummy_rule = 2*(IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet); num_v6_dummy_rule = 2*(IPV6_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR); #else num_v4_dummy_rule = 2*(IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet); num_v6_dummy_rule = 2*(IPV6_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR); #endif #ifdef FEATURE_IPA_ANDROID num_v4_dummy_rule = num_v4_dummy_rule - 2* IPACM_Iface::ipacmcfg->ipa_num_private_subnet + 2 * IPA_MAX_PRIVATE_SUBNET_ENTRIES; #endif #endif IPACM_Wlan::dummy_flt_rule_hdl_v4 = (uint32_t*)malloc(num_v4_dummy_rule * sizeof(uint32_t)); if(IPACM_Wlan::dummy_flt_rule_hdl_v4 == NULL) { IPACMERR("Failed to allocate memory.\n"); return; } IPACM_Wlan::dummy_flt_rule_hdl_v6 = (uint32_t*)malloc(num_v6_dummy_rule * sizeof(uint32_t)); if(IPACM_Wlan::dummy_flt_rule_hdl_v6 == NULL) { IPACMERR("Failed to allocate memory.\n"); free(IPACM_Wlan::dummy_flt_rule_hdl_v4); IPACM_Wlan::dummy_flt_rule_hdl_v4 = NULL; return; } memset(IPACM_Wlan::dummy_flt_rule_hdl_v4, 0, num_v4_dummy_rule * sizeof(uint32_t)); memset(IPACM_Wlan::dummy_flt_rule_hdl_v6, 0, num_v6_dummy_rule * sizeof(uint32_t)); install_dummy_flt_rule(IPA_IP_v4, num_v4_dummy_rule); install_dummy_flt_rule(IPA_IP_v6, num_v6_dummy_rule); } return; } /* install dummy filtering rules for WLAN AP-AP mode support */ int IPACM_Wlan::install_dummy_flt_rule(ipa_ip_type iptype, int num_rule) { if(rx_prop == NULL) { IPACMDBG_H("There is no rx_prop for iface %s, not able to add dummy filtering rule.\n", dev_name); return IPACM_FAILURE; } int i, len, res = IPACM_SUCCESS; struct ipa_flt_rule_add flt_rule; ipa_ioc_add_flt_rule* pFilteringTable; len = sizeof(struct ipa_ioc_add_flt_rule) + num_rule * sizeof(struct ipa_flt_rule_add); pFilteringTable = (struct ipa_ioc_add_flt_rule *)malloc(len); if (pFilteringTable == NULL) { IPACMERR("Error allocate flt table memory...\n"); return IPACM_FAILURE; } memset(pFilteringTable, 0, len); pFilteringTable->commit = 1; pFilteringTable->ep = rx_prop->rx[0].src_pipe; pFilteringTable->global = false; pFilteringTable->ip = iptype; pFilteringTable->num_rules = num_rule; memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_add)); flt_rule.rule.retain_hdr = 0; flt_rule.at_rear = true; flt_rule.flt_rule_hdl = -1; flt_rule.status = -1; flt_rule.rule.action = IPA_PASS_TO_EXCEPTION; memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib)); if(iptype == IPA_IP_v4) { flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR; flt_rule.rule.attrib.u.v4.src_addr_mask = ~0; flt_rule.rule.attrib.u.v4.src_addr = ~0; flt_rule.rule.attrib.u.v4.dst_addr_mask = ~0; flt_rule.rule.attrib.u.v4.dst_addr = ~0; for(i=0; irules[i]), &flt_rule, sizeof(struct ipa_flt_rule_add)); } if (false == m_filtering.AddFilteringRule(pFilteringTable)) { IPACMERR("Error adding dummy ipv4 flt rule\n"); res = IPACM_FAILURE; goto fail; } else { /* copy filter rule hdls */ for (int i = 0; i < num_rule; i++) { if (pFilteringTable->rules[i].status == 0) { IPACM_Wlan::dummy_flt_rule_hdl_v4[i] = pFilteringTable->rules[i].flt_rule_hdl; IPACMDBG("Dummy v4 flt rule %d hdl:0x%x\n", i, IPACM_Wlan::dummy_flt_rule_hdl_v4[i]); } else { IPACMERR("Failed adding dummy v4 flt rule %d\n", i); res = IPACM_FAILURE; goto fail; } } } } else if(iptype == IPA_IP_v6) { flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR; flt_rule.rule.attrib.u.v6.src_addr_mask[0] = ~0; flt_rule.rule.attrib.u.v6.src_addr_mask[1] = ~0; flt_rule.rule.attrib.u.v6.src_addr_mask[2] = ~0; flt_rule.rule.attrib.u.v6.src_addr_mask[3] = ~0; flt_rule.rule.attrib.u.v6.src_addr[0] = ~0; flt_rule.rule.attrib.u.v6.src_addr[1] = ~0; flt_rule.rule.attrib.u.v6.src_addr[2] = ~0; flt_rule.rule.attrib.u.v6.src_addr[3] = ~0; flt_rule.rule.attrib.u.v6.dst_addr_mask[0] = ~0; flt_rule.rule.attrib.u.v6.dst_addr_mask[1] = ~0; flt_rule.rule.attrib.u.v6.dst_addr_mask[2] = ~0; flt_rule.rule.attrib.u.v6.dst_addr_mask[3] = ~0; flt_rule.rule.attrib.u.v6.dst_addr[0] = ~0; flt_rule.rule.attrib.u.v6.dst_addr[1] = ~0; flt_rule.rule.attrib.u.v6.dst_addr[2] = ~0; flt_rule.rule.attrib.u.v6.dst_addr[3] = ~0; for(i=0; irules[i]), &flt_rule, sizeof(struct ipa_flt_rule_add)); } if (false == m_filtering.AddFilteringRule(pFilteringTable)) { IPACMERR("Error adding dummy ipv6 flt rule\n"); res = IPACM_FAILURE; goto fail; } else { /* copy filter rule hdls */ for (int i = 0; i < num_rule; i++) { if (pFilteringTable->rules[i].status == 0) { IPACM_Wlan::dummy_flt_rule_hdl_v6[i] = pFilteringTable->rules[i].flt_rule_hdl; IPACMDBG("Lan2lan v6 flt rule %d hdl:0x%x\n", i, IPACM_Wlan::dummy_flt_rule_hdl_v6[i]); } else { IPACMERR("Failed adding v6 flt rule %d\n", i); res = IPACM_FAILURE; goto fail; } } } } else { IPACMERR("IP type is not expected.\n"); goto fail; } fail: free(pFilteringTable); return res; } /* delete dummy flt rule for WLAN AP-AP mode support*/ void IPACM_Wlan::del_dummy_flt_rule() { int num_v4_dummy_rule, num_v6_dummy_rule; if(IPACM_Wlan::num_wlan_ap_iface == 0) { if(IPACM_Wlan::dummy_flt_rule_hdl_v4 == NULL || IPACM_Wlan::dummy_flt_rule_hdl_v4 == NULL) { IPACMERR("Either v4 or v6 dummy flt rule is empty.\n"); return; } #ifndef CT_OPT num_v4_dummy_rule = 2*(IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet); num_v6_dummy_rule = 2*(IPV6_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR); #else num_v4_dummy_rule = 2*(IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet); num_v6_dummy_rule = 2*(IPV6_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR); #endif #ifdef FEATURE_IPA_ANDROID num_v4_dummy_rule = num_v4_dummy_rule - 2* IPACM_Iface::ipacmcfg->ipa_num_private_subnet + 2 * IPA_MAX_PRIVATE_SUBNET_ENTRIES; #endif #ifdef FEATURE_ETH_BRIDGE_LE num_v4_dummy_rule = IPV4_DEFAULT_FILTERTING_RULES + IPACM_Iface::ipacmcfg->ipa_num_private_subnet + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_USB_CLIENT + IPACM_Iface::ipacmcfg->ipa_num_private_subnet; num_v6_dummy_rule = IPV6_DEFAULT_FILTERTING_RULES + 1 + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_USB_CLIENT; #endif if(m_filtering.DeleteFilteringHdls(IPACM_Wlan::dummy_flt_rule_hdl_v4, IPA_IP_v4, num_v4_dummy_rule) == false) { IPACMERR("Failed to delete ipv4 dummy flt rules.\n"); return; } if(m_filtering.DeleteFilteringHdls(IPACM_Wlan::dummy_flt_rule_hdl_v6, IPA_IP_v6, num_v6_dummy_rule) == false) { IPACMERR("Failed to delete ipv6 dummy flt rules.\n"); return; } free(IPACM_Wlan::dummy_flt_rule_hdl_v4); IPACM_Wlan::dummy_flt_rule_hdl_v4 = NULL; free(IPACM_Wlan::dummy_flt_rule_hdl_v6); IPACM_Wlan::dummy_flt_rule_hdl_v6 = NULL; #ifdef FEATURE_ETH_BRIDGE_LE memset(self_client_flt_rule_hdl_v4, 0, IPA_LAN_TO_LAN_MAX_WLAN_CLIENT * sizeof(lan2lan_flt_rule_hdl)); memset(self_client_flt_rule_hdl_v6, 0, IPA_LAN_TO_LAN_MAX_WLAN_CLIENT * sizeof(lan2lan_flt_rule_hdl)); memset(usb_client_flt_rule_hdl_v4, 0, IPA_LAN_TO_LAN_MAX_USB_CLIENT * sizeof(lan2lan_flt_rule_hdl)); memset(usb_client_flt_rule_hdl_v6, 0, IPA_LAN_TO_LAN_MAX_USB_CLIENT * sizeof(lan2lan_flt_rule_hdl)); #endif } return; } /* install TCP control filter rules */ void IPACM_Wlan::install_tcp_ctl_flt_rule(ipa_ip_type iptype) { if (rx_prop == NULL) { IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); return; } int i, len, res = IPACM_SUCCESS, offset; struct ipa_flt_rule_mdfy flt_rule; struct ipa_ioc_mdfy_flt_rule* pFilteringTable; if (iptype == IPA_IP_v4) { if(IPACM_Wlan::dummy_flt_rule_hdl_v4 == NULL) { IPACMERR("Dummy ipv4 flt rule has not been installed.\n"); return; } offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet); #ifdef FEATURE_IPA_ANDROID offset = offset + wlan_ap_index * (IPA_MAX_PRIVATE_SUBNET_ENTRIES - IPACM_Iface::ipacmcfg->ipa_num_private_subnet); #endif } else { if(IPACM_Wlan::dummy_flt_rule_hdl_v6 == NULL) { IPACMERR("Dummy ipv6 flt rule has not been installed.\n"); return; } offset = wlan_ap_index * (IPV6_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR); } len = sizeof(struct ipa_ioc_mdfy_flt_rule) + NUM_TCP_CTL_FLT_RULE * sizeof(struct ipa_flt_rule_mdfy); pFilteringTable = (struct ipa_ioc_mdfy_flt_rule*)malloc(len); if (!pFilteringTable) { IPACMERR("Failed to allocate ipa_ioc_mdfy_flt_rule memory...\n"); return; } memset(pFilteringTable, 0, len); pFilteringTable->commit = 1; pFilteringTable->ip = iptype; pFilteringTable->num_rules = NUM_TCP_CTL_FLT_RULE; memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy)); flt_rule.status = -1; flt_rule.rule.retain_hdr = 1; flt_rule.rule.to_uc = 0; flt_rule.rule.action = IPA_PASS_TO_EXCEPTION; flt_rule.rule.eq_attrib_type = 1; flt_rule.rule.eq_attrib.rule_eq_bitmap = 0; flt_rule.rule.eq_attrib.rule_eq_bitmap |= (1<<14); flt_rule.rule.eq_attrib.metadata_meq32_present = 1; flt_rule.rule.eq_attrib.metadata_meq32.offset = 0; flt_rule.rule.eq_attrib.metadata_meq32.value = rx_prop->rx[0].attrib.meta_data; flt_rule.rule.eq_attrib.metadata_meq32.mask = rx_prop->rx[0].attrib.meta_data_mask; flt_rule.rule.eq_attrib.rule_eq_bitmap |= (1<<1); flt_rule.rule.eq_attrib.protocol_eq_present = 1; flt_rule.rule.eq_attrib.protocol_eq = IPACM_FIREWALL_IPPROTO_TCP; /* add TCP FIN rule*/ flt_rule.rule.eq_attrib.rule_eq_bitmap |= (1<<8); flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].offset = 12; flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); /* add TCP SYN rule*/ flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<rules[1]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); /* add TCP RST rule*/ flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<rules[2]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) { IPACMERR("Failed to modify tcp control filtering rules.\n"); goto fail; } else { if(iptype == IPA_IP_v4) { for(i=0; irules[i].rule_hdl; } } else { for(i=0; irules[i].rule_hdl; } } } fail: free(pFilteringTable); return; } int IPACM_Wlan::add_dummy_private_subnet_flt_rule(ipa_ip_type iptype) { if(rx_prop == NULL) { IPACMDBG_H("There is no rx_prop for iface %s, not able to add dummy lan2lan filtering rule.\n", dev_name); return IPACM_FAILURE; } int offset; if(iptype == IPA_IP_v4) { if(IPACM_Wlan::dummy_flt_rule_hdl_v4 == NULL) { IPACMERR("Dummy ipv4 flt rule has not been installed.\n"); return IPACM_FAILURE; } #ifndef CT_OPT offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet) + IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR; #else offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet) + IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + NUM_TCP_CTL_FLT_RULE; #endif #ifdef FEATURE_IPA_ANDROID offset = offset + wlan_ap_index * (IPA_MAX_PRIVATE_SUBNET_ENTRIES - IPACM_Iface::ipacmcfg->ipa_num_private_subnet); #endif for (int i = 0; i < IPA_MAX_PRIVATE_SUBNET_ENTRIES; i++) { private_fl_rule_hdl[i] = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset+i]; IPACMDBG_H("Private subnet v4 flt rule %d hdl:0x%x\n", i, private_fl_rule_hdl[i]); } } return IPACM_SUCCESS; } int IPACM_Wlan::eth_bridge_add_wlan_guest_ap_flt_rule(ipa_ip_type iptype) { if(rx_prop == NULL) { IPACMDBG_H("There is no rx_prop for iface %s, not able to add wlan guest ap filtering rule.\n", dev_name); return IPACM_SUCCESS; } if(is_guest_ap == false) { IPACMDBG_H("This is not WLAN guest AP, do nothing.\n"); return IPACM_SUCCESS; } int len, i, offset, res = IPACM_SUCCESS; struct ipa_flt_rule_mdfy flt_rule; struct ipa_ioc_mdfy_flt_rule* pFilteringTable = NULL; if(iptype == IPA_IP_v4) { if(IPACM_Wlan::dummy_flt_rule_hdl_v4 == NULL) { IPACMERR("Dummy ipv4 flt rule has not been installed.\n"); return IPACM_FAILURE; } offset = IPV4_DEFAULT_FILTERTING_RULES; len = sizeof(struct ipa_ioc_mdfy_flt_rule) + (IPACM_Iface::ipacmcfg->ipa_num_private_subnet) * sizeof(struct ipa_flt_rule_mdfy); pFilteringTable = (struct ipa_ioc_mdfy_flt_rule*)malloc(len); if (!pFilteringTable) { IPACMERR("Failed to allocate ipa_ioc_mdfy_flt_rule memory...\n"); return IPACM_FAILURE; } memset(pFilteringTable, 0, len); pFilteringTable->commit = 1; pFilteringTable->ip = iptype; pFilteringTable->num_rules = (uint8_t)IPACM_Iface::ipacmcfg->ipa_num_private_subnet; memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy)); flt_rule.status = -1; flt_rule.rule.retain_hdr = 1; flt_rule.rule.to_uc = 0; flt_rule.rule.action = IPA_PASS_TO_EXCEPTION; flt_rule.rule.eq_attrib_type = 0; memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib)); flt_rule.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; for (i = 0; i < (IPACM_Iface::ipacmcfg->ipa_num_private_subnet); i++) { flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset+i]; flt_rule.rule.attrib.u.v4.dst_addr_mask = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask; flt_rule.rule.attrib.u.v4.dst_addr = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_addr; memcpy(&(pFilteringTable->rules[i]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); } if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) { IPACMERR("Failed to modify wlan guest AP IPv4 filtering rules.\n"); res = IPACM_FAILURE; goto fail; } /* copy filter rule hdls */ for (i = 0; i < IPACM_Iface::ipacmcfg->ipa_num_private_subnet; i++) { wlan_guest_ap_flt_rule_hdl_v4[i] = pFilteringTable->rules[i].rule_hdl; } } else { if(IPACM_Wan::wan_up_v6 == true) { eth_bridge_install_wlan_guest_ap_ipv6_flt_rule(); } } fail: if(pFilteringTable != NULL) { free(pFilteringTable); } return res; } int IPACM_Wlan::eth_bridge_install_wlan_guest_ap_ipv6_flt_rule() { if(rx_prop == NULL) { IPACMDBG_H("There is no rx_prop for iface %s, not able to add wlan guest ap filtering rule.\n", dev_name); return IPACM_SUCCESS; } if(is_guest_ap == false) { IPACMDBG_H("This is not WLAN guest AP, do nothing.\n"); return IPACM_SUCCESS; } int len, offset, res = IPACM_SUCCESS; struct ipa_flt_rule_mdfy flt_rule; struct ipa_ioc_mdfy_flt_rule* pFilteringTable = NULL; if(IPACM_Wlan::dummy_flt_rule_hdl_v6 == NULL) { IPACMERR("Dummy ipv6 flt rule has not been installed.\n"); return IPACM_FAILURE; } offset = 0; len = sizeof(struct ipa_ioc_mdfy_flt_rule) + sizeof(struct ipa_flt_rule_mdfy); pFilteringTable = (struct ipa_ioc_mdfy_flt_rule*)malloc(len); if (!pFilteringTable) { IPACMERR("Failed to allocate ipa_ioc_mdfy_flt_rule memory...\n"); return IPACM_FAILURE; } memset(pFilteringTable, 0, len); pFilteringTable->commit = 1; pFilteringTable->ip = IPA_IP_v6; pFilteringTable->num_rules = 1; memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy)); flt_rule.status = -1; flt_rule.rule.retain_hdr = 1; flt_rule.rule.to_uc = 0; flt_rule.rule.action = IPA_PASS_TO_EXCEPTION; flt_rule.rule.eq_attrib_type = 0; memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib)); flt_rule.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; flt_rule.rule.attrib.u.v6.dst_addr[0] = IPACM_Wan::backhaul_ipv6_prefix[0]; flt_rule.rule.attrib.u.v6.dst_addr[1] = IPACM_Wan::backhaul_ipv6_prefix[1]; flt_rule.rule.attrib.u.v6.dst_addr[2] = 0x0; flt_rule.rule.attrib.u.v6.dst_addr[3] = 0x0; flt_rule.rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF; flt_rule.rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; flt_rule.rule.attrib.u.v6.dst_addr_mask[2] = 0x0; flt_rule.rule.attrib.u.v6.dst_addr_mask[3] = 0x0; flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v6[offset]; memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) { IPACMERR("Failed to modify wlan guest AP IPv6 filtering rules.\n"); res = IPACM_FAILURE; goto fail; } /* copy filter rule hdls */ wlan_guest_ap_flt_rule_hdl_v6 = pFilteringTable->rules[0].rule_hdl; fail: if(pFilteringTable != NULL) { free(pFilteringTable); } return res; } int IPACM_Wlan::eth_bridge_handle_dummy_wlan_client_flt_rule(ipa_ip_type iptype) { int i, offset; if(wlan_ap_index == 0) { if(iptype == IPA_IP_v4) { offset = IPV4_DEFAULT_FILTERTING_RULES + IPACM_Iface::ipacmcfg->ipa_num_private_subnet; for(i=0; iipa_num_private_subnet + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; for(i=0; icommit = 1; pFilteringTable->ip = iptype; pFilteringTable->num_rules = 1; /* point to USB-WLAN routing table */ memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy)); flt_rule.status = -1; flt_rule.rule.retain_hdr = 0; flt_rule.rule.to_uc = 0; flt_rule.rule.action = IPA_PASS_TO_ROUTING; flt_rule.rule.eq_attrib_type = 0; if(iptype == IPA_IP_v4) { if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_usb_wlan_v4)) { IPACMERR("Failed to get routing table handle.\n"); res = IPACM_FAILURE; goto fail; } flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_usb_wlan_v4.hdl; IPACMDBG_H("WLAN->USB IPv4 filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_usb_wlan_v4.name); } else { if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_usb_wlan_v6)) { IPACMERR("Failed to get routing table handle.\n"); res = IPACM_FAILURE; goto fail; } flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_usb_wlan_v6.hdl; IPACMDBG_H("WLAN->USB IPv6 filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_usb_wlan_v6.name); } memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib)); if(IPACM_Lan::wlan_hdr_type == IPA_HDR_L2_ETHERNET_II) { flt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II; } else if(IPACM_Lan::wlan_hdr_type == IPA_HDR_L2_802_3) { flt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3; } else { IPACMERR("WLAN hdr type is not expected.\n"); res = IPACM_FAILURE; goto fail; } memcpy(flt_rule.rule.attrib.dst_mac_addr, mac, sizeof(flt_rule.rule.attrib.dst_mac_addr)); memset(flt_rule.rule.attrib.dst_mac_addr_mask, 0xFF, sizeof(flt_rule.rule.attrib.dst_mac_addr_mask)); if(iptype == IPA_IP_v4) { for(i=0; irules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) { IPACMERR("Failed to add wlan client filtering rules.\n"); res = IPACM_FAILURE; goto fail; } if(client_is_found == false) { client_position = num_usb_client; num_usb_client++; } memcpy(eth_bridge_usb_client_flt_info[client_position].mac, mac, sizeof(eth_bridge_usb_client_flt_info[client_position].mac)); if(iptype == IPA_IP_v4) { eth_bridge_usb_client_flt_info[client_position].flt_rule_set_v4 = true; eth_bridge_usb_client_flt_info[client_position].flt_rule_hdl_v4 = usb_client_flt_rule_hdl_v4[i].rule_hdl; } else { eth_bridge_usb_client_flt_info[client_position].flt_rule_set_v6 = true; eth_bridge_usb_client_flt_info[client_position].flt_rule_hdl_v6 = usb_client_flt_rule_hdl_v6[i].rule_hdl; } fail: if(pFilteringTable == NULL) { free(pFilteringTable); } return res; } int IPACM_Wlan::eth_bridge_del_usb_client_flt_rule(uint8_t* mac) { if(mac == NULL) { IPACMERR("Client MAC address is empty.\n"); return IPACM_FAILURE; } IPACMDBG_H("Receive USB client MAC 0x%02x%02x%02x%02x%02x%02x.\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); int i, j, res = IPACM_SUCCESS; for(i=0; icommit = 1; pFilteringTable->ip = iptype; pFilteringTable->num_rules = 1; /* point to USB-WLAN routing table */ memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy)); flt_rule.status = -1; flt_rule.rule.retain_hdr = 0; flt_rule.rule.to_uc = 0; flt_rule.rule.action = IPA_PASS_TO_ROUTING; flt_rule.rule.eq_attrib_type = 0; if(iptype == IPA_IP_v4) { if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v4)) { IPACMERR("Failed to get routing table handle.\n"); res = IPACM_FAILURE; goto fail; } flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v4.hdl; IPACMDBG_H("WLAN->WLAN IPv4 filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v4.name); } else { if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v6)) { IPACMERR("Failed to get routing table handle.\n"); res = IPACM_FAILURE; goto fail; } flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v6.hdl; IPACMDBG_H("WLAN->WLAN IPv4 filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v6.name); } memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib)); flt_rule.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA); //remove meta data mask if(IPACM_Lan::wlan_hdr_type == IPA_HDR_L2_ETHERNET_II) { flt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II; } else if(IPACM_Lan::wlan_hdr_type == IPA_HDR_L2_802_3) { flt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3; } else { IPACMERR("WLAN hdr type is not expected.\n"); res = IPACM_FAILURE; goto fail; } memcpy(flt_rule.rule.attrib.dst_mac_addr, mac, sizeof(flt_rule.rule.attrib.dst_mac_addr)); memset(flt_rule.rule.attrib.dst_mac_addr_mask, 0xFF, sizeof(flt_rule.rule.attrib.dst_mac_addr_mask)); if(iptype == IPA_IP_v4) { for(i=0; irules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) { IPACMERR("Failed to add self client filtering rules.\n"); res = IPACM_FAILURE; goto fail; } if(client_is_found == false) { client_position = wlan_client_flt_info_count; wlan_client_flt_info_count++; } memcpy(eth_bridge_wlan_client_flt_info[client_position].mac, mac, sizeof(eth_bridge_wlan_client_flt_info[client_position].mac)); if(iptype == IPA_IP_v4) { eth_bridge_wlan_client_flt_info[client_position].flt_rule_set_v4 = true; eth_bridge_wlan_client_flt_info[client_position].flt_rule_hdl_v4 = self_client_flt_rule_hdl_v4[i].rule_hdl; } else { eth_bridge_wlan_client_flt_info[client_position].flt_rule_set_v6 = true; eth_bridge_wlan_client_flt_info[client_position].flt_rule_hdl_v6 = self_client_flt_rule_hdl_v6[i].rule_hdl; } fail: if(pFilteringTable == NULL) { free(pFilteringTable); } return res; } int IPACM_Wlan::eth_bridge_del_self_client_flt_rule(uint8_t* mac) { if(mac == NULL) { IPACMERR("Client MAC address is empty.\n"); return IPACM_FAILURE; } IPACMDBG_H("Receive WLAN client MAC 0x%02x%02x%02x%02x%02x%02x.\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); int i, j, res = IPACM_SUCCESS; for(i=0; imac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, SRC_WLAN, iptype)->mac)) == 0) { IPACMDBG_H("The client's routing rule was added before.\n"); return IPACM_SUCCESS; } } memcpy(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_wlan_info_count_v4, src, iptype)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_wlan_info_count_v4, src, iptype)->mac)); } else { for(i=0; imac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, SRC_WLAN, iptype)->mac)) == 0) { IPACMDBG_H("The client's routing rule was added before.\n"); return IPACM_SUCCESS; } } memcpy(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_wlan_info_count_v6, src, iptype)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_wlan_info_count_v6, src, iptype)->mac)); } } else { if(iptype == IPA_IP_v4) { for(i=0; imac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, SRC_USB, iptype)->mac)) == 0) { IPACMDBG_H("The client's routing rule was added before.\n"); return IPACM_SUCCESS; } } memcpy(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_usb_info_count_v4, src, iptype)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_usb_info_count_v4, src, iptype)->mac)); } else { for(i=0; imac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, SRC_USB, iptype)->mac)) == 0) { IPACMDBG_H("The client's routing rule was added before.\n"); return IPACM_SUCCESS; } } memcpy(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_usb_info_count_v6, src, iptype)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_usb_info_count_v6, src, iptype)->mac)); } } if(iptype == IPA_IP_v4) { num_rt_rule = each_client_rt_rule_count_v4; } else { num_rt_rule = each_client_rt_rule_count_v6; } len = sizeof(ipa_ioc_add_rt_rule) + num_rt_rule * sizeof(ipa_rt_rule_add); rt_rule_table = (ipa_ioc_add_rt_rule*)malloc(len); if(rt_rule_table == NULL) { IPACMERR("Failed to allocate memory.\n"); return IPACM_FAILURE; } memset(rt_rule_table, 0, len); rt_rule_table->commit = 1; rt_rule_table->ip = iptype; rt_rule_table->num_rules = num_rt_rule; if(src == SRC_WLAN) { if(iptype == IPA_IP_v4) { strncpy(rt_rule_table->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v4.name, sizeof(rt_rule_table->rt_tbl_name)); } else { strncpy(rt_rule_table->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v6.name, sizeof(rt_rule_table->rt_tbl_name)); } } else { if(iptype == IPA_IP_v4) { strncpy(rt_rule_table->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_usb_wlan_v4.name, sizeof(rt_rule_table->rt_tbl_name)); } else { strncpy(rt_rule_table->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_usb_wlan_v6.name, sizeof(rt_rule_table->rt_tbl_name)); } } memset(&rt_rule, 0, sizeof(ipa_rt_rule_add)); rt_rule.at_rear = false; rt_rule.status = -1; rt_rule.rt_rule_hdl = -1; rt_rule.rule.hdr_hdl = 0; if(src == SRC_WLAN) { rt_rule.rule.hdr_proc_ctx_hdl = IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.proc_ctx_hdl; } else { rt_rule.rule.hdr_proc_ctx_hdl = IPACM_Lan::usb_to_wlan_hdr_proc_ctx.proc_ctx_hdl; } position = 0; for(i=0; inum_tx_props; i++) { if(tx_prop->tx[i].ip == iptype) { if(position >= num_rt_rule) { IPACMERR("Number of routing rules already exceeds limit.\n"); res = IPACM_FAILURE; goto fail; } rt_rule.rule.dst = tx_prop->tx[i].dst_pipe; memcpy(&rt_rule.rule.attrib, &tx_prop->tx[i].attrib, sizeof(rt_rule.rule.attrib)); if(src == SRC_WLAN) //src is WLAN means packet is from WLAN { if(IPACM_Lan::wlan_hdr_type == IPA_HDR_L2_ETHERNET_II) { rt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II; } else { rt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3; } } else //packet is from USB { if(IPACM_Lan::usb_hdr_type == IPA_HDR_L2_ETHERNET_II) { rt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II; } else { rt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3; } } memcpy(rt_rule.rule.attrib.dst_mac_addr, mac, sizeof(rt_rule.rule.attrib.dst_mac_addr)); memset(rt_rule.rule.attrib.dst_mac_addr_mask, 0xFF, sizeof(rt_rule.rule.attrib.dst_mac_addr_mask)); memcpy(&(rt_rule_table->rules[position]), &rt_rule, sizeof(rt_rule_table->rules[position])); position++; } } if(false == m_routing.AddRoutingRule(rt_rule_table)) { IPACMERR("Routing rule addition failed!\n"); res = IPACM_FAILURE; goto fail; } else { if(src == SRC_WLAN) { for(i=0; irt_rule_hdl[i] = rt_rule_table->rules[i].rt_rule_hdl; } else { eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_wlan_info_count_v6, src, iptype)->rt_rule_hdl[i] = rt_rule_table->rules[i].rt_rule_hdl; } } if(iptype == IPA_IP_v4) { wlan_client_rt_from_wlan_info_count_v4++; IPACMDBG_H("Now the number of IPv4 rt rule on wlan-wlan rt table is %d.\n", wlan_client_rt_from_wlan_info_count_v4); } else { wlan_client_rt_from_wlan_info_count_v6++; IPACMDBG_H("Now the number of IPv6 rt rule on wlan-wlan rt table is %d.\n", wlan_client_rt_from_wlan_info_count_v6); } } else { for(i=0; irt_rule_hdl[i] = rt_rule_table->rules[i].rt_rule_hdl; } else { eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_usb_info_count_v6, src, iptype)->rt_rule_hdl[i] = rt_rule_table->rules[i].rt_rule_hdl; } } if(iptype == IPA_IP_v4) { wlan_client_rt_from_usb_info_count_v4++; IPACMDBG_H("Now the number of IPv4 rt rule on usb-wlan rt table is %d.\n", wlan_client_rt_from_usb_info_count_v4); } else { wlan_client_rt_from_usb_info_count_v6++; IPACMDBG_H("Now the number of IPv6 rt rule on usb-wlan rt table is %d.\n", wlan_client_rt_from_usb_info_count_v6); } } } fail: if(rt_rule_table != NULL) { free(rt_rule_table); } return res; } int IPACM_Wlan::eth_bridge_del_wlan_client_rt_rule(uint8_t* mac, eth_bridge_src_iface src) { if(tx_prop == NULL) { IPACMDBG_H("Tx prop is empty, not deleting routing rule.\n"); return IPACM_SUCCESS; } if(mac == NULL) { IPACMERR("Client MAC address is empty.\n"); return IPACM_FAILURE; } IPACMDBG_H("Receive WLAN client MAC 0x%02x%02x%02x%02x%02x%02x.\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); int i, position; /* first delete the rt rules from IPv4 rt table*/ if(src == SRC_WLAN) { for(i=0; imac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v4)->mac)) == 0) { position = i; IPACMDBG_H("The client is found at position %d.\n", position); break; } } if(i == wlan_client_rt_from_wlan_info_count_v4) { IPACMERR("The client is not found.\n"); return IPACM_FAILURE; } } else { for(i=0; imac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v4)->mac)) == 0) { position = i; IPACMDBG_H("The client is found at position %d.\n", position); break; } } if(i == wlan_client_rt_from_usb_info_count_v4) { IPACMERR("The client is not found.\n"); return IPACM_FAILURE; } } for(i=0; irt_rule_hdl[i], IPA_IP_v4) == false) { IPACMERR("Failed to delete routing rule %d.\n", i); return IPACM_FAILURE; } } if(src == SRC_WLAN) { for(i=position+1; imac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v6)->mac)) == 0) { position = i; IPACMDBG_H("The client is found at position %d.\n", position); break; } } if(i == wlan_client_rt_from_wlan_info_count_v6) { IPACMERR("The client is not found.\n"); return IPACM_FAILURE; } } else { for(i=0; imac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v6)->mac)) == 0) { position = i; IPACMDBG_H("The client is found at position %d.\n", position); break; } } if(i == wlan_client_rt_from_usb_info_count_v6) { IPACMERR("The client is not found.\n"); return IPACM_FAILURE; } } for(i=0; irt_rule_hdl[i], IPA_IP_v6) == false) { IPACMERR("Failed to delete routing rule %d.\n", i); return IPACM_FAILURE; } } if(src == SRC_WLAN) { for(i=position+1; i #include #include #include "IPACM_Xml.h" #include "IPACM_Log.h" #include "IPACM_Netlink.h" static char* IPACM_read_content_element ( xmlNode* element ); static int32_t IPACM_util_icmp_string ( const char* xml_str, const char* str ); static int ipacm_cfg_xml_parse_tree ( xmlNode* xml_node, IPACM_conf_t *config ); static int IPACM_firewall_xml_parse_tree ( xmlNode* xml_node, IPACM_firewall_conf_t *config ); /*Reads content (stored as child) of the element */ static char* IPACM_read_content_element ( xmlNode* element ) { xmlNode* child_ptr; for (child_ptr = element->children; child_ptr != NULL; child_ptr = child_ptr->next) { if (child_ptr->type == XML_TEXT_NODE) { return (char*)child_ptr->content; } } return NULL; } /* insensitive comparison of a libxml's string (xml_str) and a regular string (str)*/ static int32_t IPACM_util_icmp_string ( const char* xml_str, const char* str ) { int32_t ret = -1; if (NULL != xml_str && NULL != str) { uint32_t len1 = strlen(str); uint32_t len2 = strlen(xml_str); /* If the lengths match, do the string comparison */ if (len1 == len2) { ret = strncasecmp(xml_str, str, len1); } } return ret; } /* This function read IPACM XML and populate the IPA CM Cfg */ int ipacm_read_cfg_xml(char *xml_file, IPACM_conf_t *config) { xmlDocPtr doc = NULL; xmlNode* root = NULL; int ret_val = IPACM_SUCCESS; /* Invoke the XML parser and obtain the parse tree */ doc = xmlReadFile(xml_file, "UTF-8", XML_PARSE_NOBLANKS); if (doc == NULL) { IPACMDBG_H("IPACM_xml_parse: libxml returned parse error!\n"); return IPACM_FAILURE; } /*Get the root of the tree*/ root = xmlDocGetRootElement(doc); memset(config, 0, sizeof(IPACM_conf_t)); /* parse the xml tree returned by libxml */ ret_val = ipacm_cfg_xml_parse_tree(root, config); if (ret_val != IPACM_SUCCESS) { IPACMDBG_H("IPACM_xml_parse: ipacm_cfg_xml_parse_tree returned parse error!\n"); } /* Free up the libxml's parse tree */ xmlFreeDoc(doc); return ret_val; } /* This function traverses the xml tree*/ static int ipacm_cfg_xml_parse_tree ( xmlNode* xml_node, IPACM_conf_t *config ) { int32_t ret_val = IPACM_SUCCESS; int str_size; char* content; char content_buf[MAX_XML_STR_LEN]; if (NULL == xml_node) return ret_val; while ( xml_node != NULL && ret_val == IPACM_SUCCESS) { switch (xml_node->type) { case XML_ELEMENT_NODE: { if (IPACM_util_icmp_string((char*)xml_node->name, system_TAG) == 0 || IPACM_util_icmp_string((char*)xml_node->name, ODU_TAG) == 0 || IPACM_util_icmp_string((char*)xml_node->name, IPACMCFG_TAG) == 0 || IPACM_util_icmp_string((char*)xml_node->name, IPACMIFACECFG_TAG) == 0 || IPACM_util_icmp_string((char*)xml_node->name, IFACE_TAG) == 0 || IPACM_util_icmp_string((char*)xml_node->name, IPACMPRIVATESUBNETCFG_TAG) == 0 || IPACM_util_icmp_string((char*)xml_node->name, SUBNET_TAG) == 0 || IPACM_util_icmp_string((char*)xml_node->name, IPACMALG_TAG) == 0 || IPACM_util_icmp_string((char*)xml_node->name, ALG_TAG) == 0 || IPACM_util_icmp_string((char*)xml_node->name, IPACMNat_TAG) == 0) { if (0 == IPACM_util_icmp_string((char*)xml_node->name, IFACE_TAG)) { /* increase iface entry number */ config->iface_config.num_iface_entries++; } if (0 == IPACM_util_icmp_string((char*)xml_node->name, SUBNET_TAG)) { /* increase iface entry number */ config->private_subnet_config.num_subnet_entries++; } if (0 == IPACM_util_icmp_string((char*)xml_node->name, ALG_TAG)) { /* increase iface entry number */ config->alg_config.num_alg_entries++; } /* go to child */ ret_val = ipacm_cfg_xml_parse_tree(xml_node->children, config); } else if (IPACM_util_icmp_string((char*)xml_node->name, ODUMODE_TAG) == 0) { IPACMDBG("inside ODU-XML\n"); content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); if (0 == strncasecmp(content_buf, ODU_ROUTER_TAG, str_size)) { config->router_mode_enable = true; IPACMDBG("router-mode enable %d\n", config->router_mode_enable); } else if (0 == strncasecmp(content_buf, ODU_BRIDGE_TAG, str_size)) { config->router_mode_enable = false; IPACMDBG("router-mode enable %d\n", config->router_mode_enable); } } } else if (IPACM_util_icmp_string((char*)xml_node->name, NAME_TAG) == 0) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); strncpy(config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].iface_name, content_buf, str_size); IPACMDBG_H("Name %s\n", config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].iface_name); } } else if (IPACM_util_icmp_string((char*)xml_node->name, CATEGORY_TAG) == 0) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); if (0 == strncasecmp(content_buf, WANIF_TAG, str_size)) { config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_cat = WAN_IF; IPACMDBG_H("Category %d\n", config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_cat); } else if (0 == strncasecmp(content_buf, LANIF_TAG, str_size)) { config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_cat = LAN_IF; IPACMDBG_H("Category %d\n", config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_cat); } else if (0 == strncasecmp(content_buf, WLANIF_TAG, str_size)) { config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_cat = WLAN_IF; IPACMDBG_H("Category %d\n", config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_cat); } else if (0 == strncasecmp(content_buf, VIRTUALIF_TAG, str_size)) { config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_cat = VIRTUAL_IF; IPACMDBG_H("Category %d\n", config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_cat); } else if (0 == strncasecmp(content_buf, UNKNOWNIF_TAG, str_size)) { config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_cat = UNKNOWN_IF; IPACMDBG_H("Category %d\n", config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_cat); } else if (0 == strncasecmp(content_buf, ETHIF_TAG, str_size)) { config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_cat = ETH_IF; IPACMDBG_H("Category %d\n", config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_cat); } else if (0 == strncasecmp(content_buf, ODUIF_TAG, str_size)) { config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_cat = ODU_IF; IPACMDBG("Category %d\n", config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_cat); } } } else if (IPACM_util_icmp_string((char*)xml_node->name, SUBNETADDRESS_TAG) == 0) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); content_buf[MAX_XML_STR_LEN-1] = '\0'; config->private_subnet_config.private_subnet_entries[config->private_subnet_config.num_subnet_entries - 1].subnet_addr = ntohl(inet_addr(content_buf)); IPACMDBG_H("subnet_addr: %s \n", content_buf); } } else if (IPACM_util_icmp_string((char*)xml_node->name, SUBNETMASK_TAG) == 0) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); content_buf[MAX_XML_STR_LEN-1] = '\0'; config->private_subnet_config.private_subnet_entries[config->private_subnet_config.num_subnet_entries - 1].subnet_mask = ntohl(inet_addr(content_buf)); IPACMDBG_H("subnet_mask: %s \n", content_buf); } } else if (IPACM_util_icmp_string((char*)xml_node->name, Protocol_TAG) == 0) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); content_buf[MAX_XML_STR_LEN-1] = '\0'; if (0 == strncasecmp(content_buf, TCP_PROTOCOL_TAG, str_size)) { config->alg_config.alg_entries[config->alg_config.num_alg_entries - 1].protocol = IPPROTO_TCP; IPACMDBG_H("Protocol %s: %d\n", content_buf, config->alg_config.alg_entries[config->alg_config.num_alg_entries - 1].protocol); } else if (0 == strncasecmp(content_buf, UDP_PROTOCOL_TAG, str_size)) { config->alg_config.alg_entries[config->alg_config.num_alg_entries - 1].protocol = IPPROTO_UDP; IPACMDBG_H("Protocol %s: %d\n", content_buf, config->alg_config.alg_entries[config->alg_config.num_alg_entries - 1].protocol); } } } else if (IPACM_util_icmp_string((char*)xml_node->name, Port_TAG) == 0) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); config->alg_config.alg_entries[config->alg_config.num_alg_entries - 1].port = atoi(content_buf); IPACMDBG_H("port %d\n", config->alg_config.alg_entries[config->alg_config.num_alg_entries - 1].port); } } else if (IPACM_util_icmp_string((char*)xml_node->name, NAT_MaxEntries_TAG) == 0) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); config->nat_max_entries = atoi(content_buf); IPACMDBG_H("Nat Table Max Entries %d\n", config->nat_max_entries); } } } break; default: break; } /* go to sibling */ xml_node = xml_node->next; } /* end while */ return ret_val; } /* This function read QCMAP CM Firewall XML and populate the QCMAP CM Cfg */ int IPACM_read_firewall_xml(char *xml_file, IPACM_firewall_conf_t *config) { xmlDocPtr doc = NULL; xmlNode* root = NULL; int ret_val; IPACM_ASSERT(xml_file != NULL); IPACM_ASSERT(config != NULL); /* invoke the XML parser and obtain the parse tree */ doc = xmlReadFile(xml_file, "UTF-8", XML_PARSE_NOBLANKS); if (doc == NULL) { IPACMDBG_H("IPACM_xml_parse: libxml returned parse error\n"); return IPACM_FAILURE; } /*get the root of the tree*/ root = xmlDocGetRootElement(doc); /* parse the xml tree returned by libxml*/ ret_val = IPACM_firewall_xml_parse_tree(root, config); if (ret_val != IPACM_SUCCESS) { IPACMDBG_H("IPACM_xml_parse: ipacm_firewall_xml_parse_tree returned parse error!\n"); } /* free the tree */ xmlFreeDoc(doc); return ret_val; } /* This function traverses the firewall xml tree */ static int IPACM_firewall_xml_parse_tree ( xmlNode* xml_node, IPACM_firewall_conf_t *config ) { int mask_value_v6, mask_index; int32_t ret_val = IPACM_SUCCESS; char *content; int str_size; char content_buf[MAX_XML_STR_LEN]; struct in6_addr ip6_addr; IPACM_ASSERT(config != NULL); if (NULL == xml_node) return ret_val; while ( xml_node != NULL && ret_val == IPACM_SUCCESS) { switch (xml_node->type) { case XML_ELEMENT_NODE: { if (0 == IPACM_util_icmp_string((char*)xml_node->name, system_TAG) || 0 == IPACM_util_icmp_string((char*)xml_node->name, MobileAPFirewallCfg_TAG) || 0 == IPACM_util_icmp_string((char*)xml_node->name, Firewall_TAG) || 0 == IPACM_util_icmp_string((char*)xml_node->name, FirewallEnabled_TAG) || 0 == IPACM_util_icmp_string((char*)xml_node->name, FirewallPktsAllowed_TAG) ) { if (0 == IPACM_util_icmp_string((char*)xml_node->name, Firewall_TAG)) { /* increase firewall entry num */ config->num_extd_firewall_entries++; } if (0 == IPACM_util_icmp_string((char*)xml_node->name, FirewallPktsAllowed_TAG)) { /* setup action of matched rules */ content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); if (atoi(content_buf)==1) { config->rule_action_accept = true; } else { config->rule_action_accept = false; } IPACMDBG_H(" Allow traffic which matches rules ?:%d\n",config->rule_action_accept); } } if (0 == IPACM_util_icmp_string((char*)xml_node->name, FirewallEnabled_TAG)) { /* setup if firewall enable or not */ content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); if (atoi(content_buf)==1) { config->firewall_enable = true; } else { config->firewall_enable = false; } IPACMDBG_H(" Firewall Enable?:%d\n", config->firewall_enable); } } /* go to child */ ret_val = IPACM_firewall_xml_parse_tree(xml_node->children, config); } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, IPFamily_TAG)) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].ip_vsn = (firewall_ip_version_enum)atoi(content_buf); IPACMDBG_H("\n IP family type is %d \n", config->extd_firewall_entries[config->num_extd_firewall_entries - 1].ip_vsn); } } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, IPV4SourceAddress_TAG)) { config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.attrib_mask |= IPA_FLT_SRC_ADDR; /* go to child */ ret_val = IPACM_firewall_xml_parse_tree(xml_node->children, config); } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, IPV4SourceIPAddress_TAG)) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); content_buf[MAX_XML_STR_LEN-1] = '\0'; config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v4.src_addr = ntohl(inet_addr(content_buf)); IPACMDBG_H("IPv4 source address is: %s \n", content_buf); } } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, IPV4SourceSubnetMask_TAG)) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); content_buf[MAX_XML_STR_LEN-1] = '\0'; config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v4.src_addr_mask = ntohl(inet_addr(content_buf)); IPACMDBG_H("IPv4 source subnet mask is: %s \n", content_buf); } } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, IPV4DestinationAddress_TAG)) { config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.attrib_mask |= IPA_FLT_DST_ADDR; /* go to child */ ret_val = IPACM_firewall_xml_parse_tree(xml_node->children, config); } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, IPV4DestinationIPAddress_TAG)) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); content_buf[MAX_XML_STR_LEN-1] = '\0'; config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v4.dst_addr = ntohl(inet_addr(content_buf)); IPACMDBG_H("IPv4 destination address is: %s \n", content_buf); } } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, IPV4DestinationSubnetMask_TAG)) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); content_buf[MAX_XML_STR_LEN-1] = '\0'; if (content_buf > 0) { config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v4.dst_addr_mask = ntohl(inet_addr(content_buf)); IPACMDBG_H("IPv4 destination subnet mask is: %s \n", content_buf); } } } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, IPV4TypeOfService_TAG)) { config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.attrib_mask |= IPA_FLT_TOS; /* go to child */ ret_val = IPACM_firewall_xml_parse_tree(xml_node->children, config); } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, TOSValue_TAG)) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v4.tos = atoi(content_buf); IPACMDBG_H("\n IPV4 TOS val is %d \n", config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v4.tos); } } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, TOSMask_TAG)) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v4.tos &= atoi(content_buf); IPACMDBG_H("\n IPv4 TOS mask is %d \n", config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v4.tos); } } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, IPV4NextHeaderProtocol_TAG)) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.attrib_mask |= IPA_FLT_PROTOCOL; config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v4.protocol = atoi(content_buf); IPACMDBG_H("\n IPv4 next header prot is %d \n", config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v4.protocol); } } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, IPV6SourceAddress_TAG)) { config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.attrib_mask |= IPA_FLT_SRC_ADDR; /* go to child */ ret_val = IPACM_firewall_xml_parse_tree(xml_node->children, config); } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, IPV6SourceIPAddress_TAG)) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); inet_pton(AF_INET6, content_buf, &ip6_addr); memcpy(config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v6.src_addr, ip6_addr.s6_addr, IPACM_IPV6_ADDR_LEN * sizeof(uint8_t)); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v6.src_addr[0]=ntohl(config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v6.src_addr[0]); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v6.src_addr[1]=ntohl(config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v6.src_addr[1]); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v6.src_addr[2]=ntohl(config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v6.src_addr[2]); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v6.src_addr[3]=ntohl(config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v6.src_addr[3]); IPACMDBG_H("\n ipv6 source addr is %d \n ", config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v6.src_addr[0]); } } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, IPV6SourcePrefix_TAG)) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); mask_value_v6 = atoi(content_buf); for (mask_index = 0; mask_index < 4; mask_index++) { if (mask_value_v6 >= 32) { mask_v6(32, &(config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v6.src_addr_mask[mask_index])); mask_value_v6 -= 32; } else { mask_v6(mask_value_v6, &(config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v6.src_addr_mask[mask_index])); mask_value_v6 = 0; } } IPACMDBG_H("\n ipv6 source prefix is %d \n", atoi(content_buf)); } } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, IPV6DestinationAddress_TAG)) { config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.attrib_mask |= IPA_FLT_DST_ADDR; /* go to child */ ret_val = IPACM_firewall_xml_parse_tree(xml_node->children, config); } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, IPV6DestinationIPAddress_TAG)) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); inet_pton(AF_INET6, content_buf, &ip6_addr); memcpy(config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v6.dst_addr, ip6_addr.s6_addr, IPACM_IPV6_ADDR_LEN * sizeof(uint8_t)); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v6.dst_addr[0]=ntohl(config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v6.dst_addr[0]); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v6.dst_addr[1]=ntohl(config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v6.dst_addr[1]); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v6.dst_addr[2]=ntohl(config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v6.dst_addr[2]); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v6.dst_addr[3]=ntohl(config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v6.dst_addr[3]); IPACMDBG_H("\n ipv6 dest addr is %d \n", config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v6.dst_addr[0]); } } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, IPV6DestinationPrefix_TAG)) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); mask_value_v6 = atoi(content_buf); for (mask_index = 0; mask_index < 4; mask_index++) { if (mask_value_v6 >= 32) { mask_v6(32, &(config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v6.dst_addr_mask[mask_index])); mask_value_v6 -= 32; } else { mask_v6(mask_value_v6, &(config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v6.dst_addr_mask[mask_index])); mask_value_v6 = 0; } } IPACMDBG_H("\n ipv6 dest prefix is %d \n", atoi(content_buf)); } } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, IPV6TrafficClass_TAG)) { config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.attrib_mask |= IPA_FLT_TC; /* go to child */ ret_val = IPACM_firewall_xml_parse_tree(xml_node->children, config); } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, TrfClsValue_TAG)) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v6.tc = atoi(content_buf); IPACMDBG_H("\n ipv6 trf class val is %d \n", config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v6.tc); } } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, TrfClsMask_TAG)) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v6.tc &= atoi(content_buf); IPACMDBG_H("\n ipv6 trf class mask is %d \n", atoi(content_buf)); } } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, IPV6NextHeaderProtocol_TAG)) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.attrib_mask |= IPA_FLT_NEXT_HDR; config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v6.next_hdr = atoi(content_buf); IPACMDBG_H("\n ipv6 next header protocol is %d \n", config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v6.next_hdr); } } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, TCPSource_TAG)) { /* go to child */ ret_val = IPACM_firewall_xml_parse_tree(xml_node->children, config); } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, TCPSourcePort_TAG)) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.src_port = atoi(content_buf); } } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, TCPSourceRange_TAG)) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); if (atoi(content_buf) != 0) { config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.attrib_mask |= IPA_FLT_SRC_PORT_RANGE; config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.src_port_lo = config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.src_port; config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.src_port_hi = config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.src_port + atoi(content_buf); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.src_port = 0; IPACMDBG_H("\n tcp source port from %d to %d \n", config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.src_port_lo, config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.src_port_hi); } else { config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.attrib_mask |= IPA_FLT_SRC_PORT; IPACMDBG_H("\n tcp source port= %d \n", config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.src_port); } } } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, TCPDestination_TAG)) { /* go to child */ ret_val = IPACM_firewall_xml_parse_tree(xml_node->children, config); } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, TCPDestinationPort_TAG)) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.dst_port = atoi(content_buf); } } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, TCPDestinationRange_TAG)) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); if(atoi(content_buf)!=0) { config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.attrib_mask |= IPA_FLT_DST_PORT_RANGE; config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.dst_port_lo = config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.dst_port; config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.dst_port_hi = config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.dst_port + atoi(content_buf); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.dst_port = 0; IPACMDBG_H("\n tcp dest port from %d to %d \n", config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.dst_port_lo, config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.dst_port_hi); } else { config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.attrib_mask |= IPA_FLT_DST_PORT; IPACMDBG_H("\n tcp dest port= %d \n", config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.dst_port); } } } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, UDPSource_TAG)) { /* go to child */ ret_val = IPACM_firewall_xml_parse_tree(xml_node->children, config); } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, UDPSourcePort_TAG)) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.src_port = atoi(content_buf); } } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, UDPSourceRange_TAG)) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); if(atoi(content_buf)!=0) { config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.attrib_mask |= IPA_FLT_SRC_PORT_RANGE; config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.src_port_lo = config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.src_port; config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.src_port_hi = config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.src_port + atoi(content_buf); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.src_port = 0; IPACMDBG_H("\n udp source port from %d to %d \n", config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.src_port_lo, config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.src_port_hi); } else { config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.attrib_mask |= IPA_FLT_SRC_PORT; IPACMDBG_H("\n udp source port= %d \n", config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.src_port); } } } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, UDPDestination_TAG)) { /* go to child */ ret_val = IPACM_firewall_xml_parse_tree(xml_node->children, config); } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, UDPDestinationPort_TAG)) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.dst_port = atoi(content_buf); } } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, UDPDestinationRange_TAG)) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); if(atoi(content_buf)!=0) { config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.attrib_mask |= IPA_FLT_DST_PORT_RANGE; config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.dst_port_lo = config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.dst_port; config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.dst_port_hi = config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.dst_port + atoi(content_buf); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.dst_port = 0; IPACMDBG_H("\n UDP dest port from %d to %d \n", config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.dst_port_lo, config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.dst_port_hi); } else { config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.attrib_mask |= IPA_FLT_DST_PORT; IPACMDBG_H("\n UDP dest port= %d \n", config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.dst_port); } } } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, ICMPType_TAG)) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.type = atoi(content_buf); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.attrib_mask |= IPA_FLT_TYPE; IPACMDBG_H("\n icmp type is %d \n", config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.type); } } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, ICMPCode_TAG)) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.code = atoi(content_buf); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.attrib_mask |= IPA_FLT_CODE; IPACMDBG_H("\n icmp code is %d \n", config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.code); } } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, ESPSPI_TAG)) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.spi = atoi(content_buf); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.attrib_mask |= IPA_FLT_SPI; IPACMDBG_H("\n esp spi is %d \n", config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.spi); } } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, TCP_UDPSource_TAG)) { /* go to child */ ret_val = IPACM_firewall_xml_parse_tree(xml_node->children, config); } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, TCP_UDPSourcePort_TAG)) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content,str_size); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.src_port = atoi(content_buf); } } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, TCP_UDPSourceRange_TAG)) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); if(atoi(content_buf)!=0) { config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.attrib_mask |= IPA_FLT_SRC_PORT_RANGE; config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.src_port_lo = config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.src_port; config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.src_port_hi = config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.src_port + atoi(content_buf); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.src_port = 0; IPACMDBG_H("\n tcp_udp source port from %d to %d \n", config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.src_port_lo, config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.src_port_hi); } else { config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.attrib_mask |= IPA_FLT_SRC_PORT; IPACMDBG_H("\n tcp_udp source port= %d \n", config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.src_port); } } } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, TCP_UDPDestination_TAG)) { ret_val = IPACM_firewall_xml_parse_tree(xml_node->children, config); } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, TCP_UDPDestinationPort_TAG)) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.dst_port = atoi(content_buf); } } else if (0 == IPACM_util_icmp_string((char*)xml_node->name, TCP_UDPDestinationRange_TAG)) { content = IPACM_read_content_element(xml_node); if (content) { str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); if(atoi(content_buf)!=0) { config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.attrib_mask |= IPA_FLT_DST_PORT_RANGE; config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.dst_port_lo = config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.dst_port; config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.dst_port_hi = config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.dst_port + atoi(content_buf); config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.dst_port = 0; IPACMDBG_H("\n tcp_udp dest port from %d to %d \n", config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.dst_port_lo, config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.dst_port_hi); } else { config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.attrib_mask |= IPA_FLT_DST_PORT; IPACMDBG_H("\n tcp_udp dest port= %d \n", config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.dst_port); } } } } break; default: break; } /* go to sibling */ xml_node = xml_node->next; } /* end while */ return ret_val; } ================================================ FILE: data-ipa-cfg-mgr/ipacm/src/IPACM_cfg.xml ================================================ router rndis0 LAN ecm0 LAN rmnet_data0 WAN rmnet_data1 WAN rmnet_data2 WAN rmnet_data3 WAN rmnet_data4 WAN rmnet_data5 WAN rmnet_data6 WAN rmnet_data7 WAN wlan0 UNKNOWN wlan1 UNKNOWN eth0 ODU bridge0 VIRTUAL 192.168.225.0 255.255.255.0 TCP 21 FTP TCP 554 RTSP TCP 5060 SIP UDP 5060 SIP TCP 1723 PPTP UDP 69 TFTP UDP 53 DNS TCP 53 DNS UDP 10080 AMANDA UDP 1719 H323 TCP 1720 H323 TCP 6667 IRC UDP 137 NETBIOS_NS TCP 6566 SANE 500 ================================================ FILE: data-ipa-cfg-mgr/ipacm/src/Makefile.am ================================================ AM_CPPFLAGS = -I./../inc \ -I$(top_srcdir)/ipanat/inc \ ${LIBXML_CFLAGS} AM_CPPFLAGS += -Wall -Wundef -Wno-trigraphs AM_CPPFLAGS += -DDEBUG -g -DFEATURE_ETH_BRIDGE_LE ipacm_SOURCES = IPACM_Main.cpp \ IPACM_Conntrack_NATApp.cpp\ IPACM_ConntrackClient.cpp \ IPACM_ConntrackListener.cpp \ IPACM_EvtDispatcher.cpp \ IPACM_Config.cpp \ IPACM_CmdQueue.cpp \ IPACM_Log.cpp \ IPACM_Filtering.cpp \ IPACM_Routing.cpp \ IPACM_Header.cpp \ IPACM_Lan.cpp \ IPACM_Iface.cpp \ IPACM_Wlan.cpp \ IPACM_Wan.cpp \ IPACM_IfaceManager.cpp \ IPACM_Neighbor.cpp \ IPACM_Netlink.cpp \ IPACM_Xml.cpp \ IPACM_LanToLan.cpp bin_PROGRAMS = ipacm requiredlibs = ${LIBXML_LIB} -lxml2 -lpthread -lnetfilter_conntrack -lnfnetlink\ ../../ipanat/src/libipanat.la ipacm_LDADD = $(requiredlibs) AM_CPPFLAGS += "-std=c++0x" LOCAL_MODULE := libipanat LOCAL_PRELINK_MODULE := false include $(BUILD_SHARED_LIBRARY) etcdir = ${sysconfdir} etc_SCRIPTS = IPACM_cfg.xml init_ddir = ${sysconfdir}/init.d init_d_SCRIPTS = start_ipacm_le ================================================ FILE: data-ipa-cfg-mgr/ipacm/src/mobileap_firewall.xml ================================================ 1 0 ================================================ FILE: data-ipa-cfg-mgr/ipacm/src/start_ipacm_le ================================================ #! /bin/sh # ################################ # Copyright (c) 2013, The Linux Foundation. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of The Linux Foundation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN # IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ################################ # ipacm init.d script to start the data-ipa Software's ipacm daemon set -e case "$1" in start) echo -n "Starting ipacm: " start-stop-daemon -S -b -a ipacm echo "done" ;; stop) echo -n "Stopping ipacm: " start-stop-daemon -K -n ipacm echo "done" ;; restart) $0 stop $0 start ;; *) echo "Usage ipacm { start | stop | restart}" >&2 exit 1 ;; esac exit 0 ================================================ FILE: data-ipa-cfg-mgr/ipanat/inc/ipa_nat_drv.h ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "string.h" /* memset */ #include "stdlib.h" /* free, malloc */ #include "stdint.h" /* uint32_t */ /** * struct ipa_nat_ipv4_rule - To hold ipv4 nat rule * @target_ip: destination ip address * @private_ip: private ip address * @target_port: destination port * @private_port: private port * @protocol: protocol of rule (tcp/udp) */ typedef struct { uint32_t target_ip; uint32_t private_ip; uint16_t target_port; uint16_t private_port; uint16_t public_port; uint8_t protocol; } ipa_nat_ipv4_rule; /** * ipa_nat_add_ipv4_tbl() - create ipv4 nat table * @public_ip_addr: [in] public ipv4 address * @number_of_entries: [in] number of nat entries * @table_handle: [out] Handle of new ipv4 nat table * * To create new ipv4 nat table * * Returns: 0 On Success, negative on failure */ int ipa_nat_add_ipv4_tbl(uint32_t public_ip_addr, uint16_t number_of_entries, uint32_t *table_handle); /** * ipa_nat_del_ipv4_tbl() - delete ipv4 table * @table_handle: [in] Handle of ipv4 nat table * * To delete given ipv4 nat table * * Returns: 0 On Success, negative on failure */ int ipa_nat_del_ipv4_tbl(uint32_t table_handle); /** * ipa_nat_add_ipv4_rule() - to insert new ipv4 rule * @table_handle: [in] handle of ipv4 nat table * @rule: [in] Pointer to new rule * @rule_handle: [out] Return the handle to rule * * To insert new ipv4 nat rule into ipv4 nat table * * Returns: 0 On Success, negative on failure */ int ipa_nat_add_ipv4_rule(uint32_t table_handle, const ipa_nat_ipv4_rule * rule, uint32_t *rule_handle); /** * ipa_nat_del_ipv4_rule() - to delete ipv4 nat rule * @table_handle: [in] handle of ipv4 nat table * @rule_handle: [in] ipv4 nat rule handle * * To insert new ipv4 nat rule into ipv4 nat table * * Returns: 0 On Success, negative on failure */ int ipa_nat_del_ipv4_rule(uint32_t table_handle, uint32_t rule_handle); /** * ipa_nat_query_timestamp() - to query timestamp * @table_handle: [in] handle of ipv4 nat table * @rule_handle: [in] ipv4 nat rule handle * @time_stamp: [out] time stamp of rule * * To retrieve the timestamp that lastly the * nat rule was accessed * * Returns: 0 On Success, negative on failure */ int ipa_nat_query_timestamp(uint32_t table_handle, uint32_t rule_handle, uint32_t *time_stamp); ================================================ FILE: data-ipa-cfg-mgr/ipanat/inc/ipa_nat_drvi.h ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef IPA_NAT_DRVI_H #define IPA_NAT_DRVI_H #include #include #include #include #include #include #include #include #include #include "ipa_nat_logi.h" #define NAT_DUMP /*======= IMPLEMENTATION related data structures and functions ======= */ #ifdef IPA_ON_R3PC #define NAT_MMAP_MEM_SIZE (2 * 1024UL * 1024UL - 1) #endif #define IPA_DEV_NAME "/dev/ipa" #define NAT_DEV_DIR "/dev" #define NAT_DEV_NAME "ipaNatTable" #define NAT_DEV_FULL_NAME "/dev/ipaNatTable" #define IPA_NAT_TABLE_VALID 1 #define IPA_NAT_MAX_IP4_TBLS 1 #define IPA_NAT_BASE_TABLE_PERCENTAGE .8 #define IPA_NAT_EXPANSION_TABLE_PERCENTAGE .2 #define IPA_NAT_NUM_OF_BASE_TABLES 2 #define IPA_NAT_UNUSED_BASE_ENTRIES 2 #define IPA_NAT_RULE_FLAG_FIELD_OFFSET 18 #define IPA_NAT_RULE_NEXT_FIELD_OFFSET 8 #define IPA_NAT_RULE_PROTO_FIELD_OFFSET 22 #define IPA_NAT_INDEX_RULE_NEXT_FIELD_OFFSET 2 #define IPA_NAT_INDEX_RULE_NAT_INDEX_FIELD_OFFSET 0 #define IPA_NAT_RULE_FLAG_FIELD_SIZE 2 #define IPA_NAT_RULE_NEXTFIELD_FIELD_SIZE 2 #define IPA_NAT_FLAG_ENABLE_BIT_MASK 0x8000 #define IPA_NAT_FLAG_DISABLE_BIT_MASK 0x0000 #define IPA_NAT_FLAG_ENABLE_BIT 1 #define IPA_NAT_FLAG_DISABLE_BIT 0 #define IPA_NAT_INVALID_PROTO_FIELD_VALUE 0xFF00 #define IPA_NAT_INVALID_PROTO_FIELD_CMP 0xFF #define IPA_NAT_INVALID_INDEX 0xFF #define IPA_NAT_INVALID_NAT_ENTRY 0x0 #define INDX_TBL_ENTRY_SIZE_IN_BITS 16 /* ----------- Rule id ----------------------- ------------------------------------------------ | 3bits | 12 bits | 1 bit | ------------------------------------------------ | reserved | index into table | 0 - base | | | | 1 - expansion | ------------------------------------------------ */ #define IPA_NAT_RULE_HDL_TBL_TYPE_BITS 0x1 #define IPA_NAT_RULE_HDL_TBL_TYPE_MASK 0x1 /* ----------- sw specif parameter ----- ------------------------------------ | 16 bits | 16 bits | ------------------------------------ | index table | prev index | | entry | | ------------------------------------ -----------------------------------------*/ #define IPA_NAT_SW_PARAM_PREV_INDX_BYTE 0 #define IPA_NAT_SW_PARAM_INDX_TBL_ENTRY_BYTE 1 typedef enum { IPA_NAT_BASE_TBL = 0, IPA_NAT_EXPN_TBL = 1, IPA_NAT_INDX_TBL = 2, IPA_NAT_INDEX_EXPN_TBL = 3, } nat_table_type; typedef enum { NEXT_INDEX_FIELD, PUBLIC_PORT_FILED, PRIVATE_PORT_FIELD, TARGET_PORT_FIELD, IP_CHKSUM_FIELD, ENABLE_FIELD, TIME_STAMP_FIELD, PROTOCOL_FIELD, TCP_UDP_CHKSUM_FIELD, SW_SPEC_PARAM_PREV_INDEX_FIELD, SW_SPEC_PARAM_INDX_TBL_ENTRY_FIELD, INDX_TBL_TBL_ENTRY_FIELD, INDX_TBL_NEXT_INDEX_FILED } ipa_nat_rule_field_type; /* --------------------------------------------- | 3 | 2 | 1 | 0 | --------------------------------------------- | Public Port(2B) | Next Index(2B) | --------------------------------------------- */ typedef struct { uint32_t next_index:16; uint32_t public_port:16; } next_index_pub_port; /* --------------------------------------------- | 3 | 2 | 1 | 0 | --------------------------------------------- | Flags(2B) | IP check sum Diff(2B)| |EN|FIN|Resv | | | --------------------------------------------- */ typedef struct { uint32_t ip_chksum:16; uint32_t rsvd1:14; uint32_t redirect:1; uint32_t enable:1; } ipcksum_enbl; /* --------------------------------------- | 7 | 6 | 5 | 4 | --------------------------------------- | Proto | TimeStamp(3B) | | (1B) | | --------------------------------------- */ typedef struct { uint32_t time_stamp:24; uint32_t protocol:8; } time_stamp_proto; /* --------------------------------------------- | 3 | 2 | 1 | 0 | --------------------------------------------- | next_index | Table entry | ---------------------------------------------- */ typedef struct { uint16_t tbl_entry; uint16_t next_index; } tbl_ent_nxt_indx; /*-------------------------------------------------- 32 bit sw_spec_params is interpreted as follows ------------------------------------ | 16 bits | 16 bits | ------------------------------------ | index table | prev index | | entry | | ------------------------------------ --------------------------------------------------*/ typedef struct { uint16_t prev_index; uint16_t index_table_entry; } sw_spec_params; /*------------------------ NAT Table Entry --------------------------------------- ----------------------------------------------------------------------------------- | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ----------------------------------------------------------------------------------- | Target IP(4B) | Private IP(4B) | ----------------------------------------------------------------------------------- |Target Port(2B) | Private Port(2B) | Public Port(2B) | Next Index(2B) | ----------------------------------------------------------------------------------- | Proto | TimeStamp(3B) | Flags(2B) | IP check sum Diff(2B)| | (1B) | |EN|FIN|Resv | | | ----------------------------------------------------------------------------------- | TCP/UDP checksum | Reserved(2B) | SW Specific Parameters(4B) | | diff (2B) | | ----------------------------------------------------------------------------------- Dont change below structure definition. It should be same as above(little endian order) -------------------------------------------------------------------------------*/ struct ipa_nat_rule { uint64_t private_ip:32; uint64_t target_ip:32; uint64_t nxt_indx_pub_port:32; uint64_t private_port:16; uint64_t target_port:16; uint64_t ip_cksm_enbl:32; uint64_t ts_proto:32; /*-------------------------------------------------- 32 bit sw_spec_params is interpreted as follows ------------------------------------ | 16 bits | 16 bits | ------------------------------------ | index table | prev index | | entry | | ------------------------------------ --------------------------------------------------*/ uint64_t sw_spec_params:32; uint64_t rsvd2:16; uint64_t tcp_udp_chksum:16; }; struct ipa_nat_sw_rule { uint64_t private_ip:32; uint64_t target_ip:32; uint64_t next_index:16; uint64_t public_port:16; uint64_t private_port:16; uint64_t target_port:16; uint64_t ip_chksum:16; uint64_t rsvd1:14; uint64_t redirect:1; uint64_t enable:1; uint64_t time_stamp:24; uint64_t protocol:8; /*-------------------------------------------------- 32 bit sw_spec_params is interpreted as follows ------------------------------------ | 16 bits | 16 bits | ------------------------------------ | index table | prev index | | entry | | ------------------------------------ --------------------------------------------------*/ uint64_t prev_index:16; uint64_t indx_tbl_entry:16; uint64_t rsvd2:16; uint64_t tcp_udp_chksum:16; }; #define IPA_NAT_TABLE_ENTRY_SIZE 32 #define IPA_NAT_INDEX_TABLE_ENTRY_SIZE 4 struct ipa_nat_indx_tbl_rule { uint32_t tbl_entry_nxt_indx; }; struct ipa_nat_sw_indx_tbl_rule { uint16_t tbl_entry; uint16_t next_index; }; struct ipa_nat_indx_tbl_meta_info { uint16_t prev_index; }; struct ipa_nat_ip4_table_cache { uint8_t valid; uint32_t public_addr; int nat_fd; int size; uint32_t tbl_addr_offset; char table_name[IPA_RESOURCE_NAME_MAX]; char *ipv4_rules_addr; char *index_table_addr; uint16_t table_entries; char *ipv4_expn_rules_addr; char *index_table_expn_addr; uint16_t expn_table_entries; struct ipa_nat_indx_tbl_meta_info *index_expn_table_meta; uint16_t *rule_id_array; #ifdef IPA_ON_R3PC uint32_t mmap_offset; #endif }; struct ipa_nat_cache { struct ipa_nat_ip4_table_cache ip4_tbl[IPA_NAT_MAX_IP4_TBLS]; int ipa_fd; uint8_t table_cnt; }; struct ipa_nat_indx_tbl_sw_rule { uint16_t tbl_entry; uint16_t next_index; uint16_t prev_index; }; typedef enum { IPA_NAT_DEL_TYPE_ONLY_ONE, IPA_NAT_DEL_TYPE_HEAD, IPA_NAT_DEL_TYPE_MIDDLE, IPA_NAT_DEL_TYPE_LAST, } del_type; /** * ipa_nati_parse_ipv4_rule_hdl() - prase rule handle * @tbl_hdl: [in] nat table rule * @rule_hdl: [in] nat rule handle * @expn_tbl: [out] expansion table or not * @tbl_entry: [out] index into table * * Parse the rule handle to retrieve the nat table * type and entry of nat table * * Returns: None */ void ipa_nati_parse_ipv4_rule_hdl(uint8_t tbl_hdl, uint16_t rule_hdl, uint8_t *expn_tbl, uint16_t *tbl_entry); /** * ipa_nati_make_rule_hdl() - makes nat rule handle * @tbl_hdl: [in] nat table handle * @tbl_entry: [in] nat table entry * * Calculate the nat rule handle which from * nat entry which will be returned to client of * nat driver * * Returns: >0 nat rule handle */ uint16_t ipa_nati_make_rule_hdl(uint16_t tbl_hdl, uint16_t tbl_entry); uint32_t ipa_nati_get_index_entry_offset( struct ipa_nat_ip4_table_cache*, nat_table_type tbl_type, uint16_t indx_tbl_entry); uint32_t ipa_nati_get_entry_offset( struct ipa_nat_ip4_table_cache*, nat_table_type tbl_type, uint16_t tbl_entry); int ipa_nati_add_ipv4_tbl(uint32_t public_ip_addr, uint16_t number_of_entries, uint32_t *table_hanle); int ipa_nati_alloc_table(uint16_t number_of_entries, struct ipa_ioc_nat_alloc_mem *mem, uint16_t*, uint16_t*); int ipa_nati_update_cache(struct ipa_ioc_nat_alloc_mem *, uint32_t public_ip_addr, uint16_t tbl_entries, uint16_t expn_tbl_entries); int ipa_nati_del_ipv4_table(uint32_t tbl_hdl); int ipa_nati_reset_ipv4_table(uint32_t tbl_hdl); int ipa_nati_post_ipv4_init_cmd(uint8_t tbl_index); int ipa_nati_query_timestamp(uint32_t tbl_hdl, uint32_t rule_hdl, uint32_t *time_stamp); int ipa_nati_add_ipv4_rule(uint32_t tbl_hdl, const ipa_nat_ipv4_rule *clnt_rule, uint32_t *rule_hdl); int ipa_nati_generate_rule(uint32_t tbl_hdl, const ipa_nat_ipv4_rule *clnt_rule, struct ipa_nat_sw_rule *rule, struct ipa_nat_indx_tbl_sw_rule *index_sw_rule, uint16_t *tbl_entry, uint16_t *indx_tbl_entry); uint16_t ipa_nati_expn_tbl_free_entry(struct ipa_nat_rule *expn_tbl, uint16_t size); uint16_t ipa_nati_generate_tbl_rule(const ipa_nat_ipv4_rule *clnt_rule, struct ipa_nat_sw_rule *sw_rule, struct ipa_nat_ip4_table_cache *tbl_ptr); uint16_t ipa_nati_generate_index_rule(const ipa_nat_ipv4_rule *clnt_rule, struct ipa_nat_indx_tbl_sw_rule *sw_rule, struct ipa_nat_ip4_table_cache *tbl_ptr); uint16_t ipa_nati_index_expn_get_free_entry(struct ipa_nat_indx_tbl_rule *tbl, uint16_t size); void ipa_nati_copy_ipv4_rule_to_hw( struct ipa_nat_ip4_table_cache *ipv4_cache, struct ipa_nat_sw_rule *rule, uint16_t entry, uint8_t tbl_index); void ipa_nati_copy_ipv4_index_rule_to_hw( struct ipa_nat_ip4_table_cache *ipv4_cache, struct ipa_nat_indx_tbl_sw_rule *indx_sw_rule, uint16_t entry, uint8_t tbl_index); void ipa_nati_write_next_index(uint8_t tbl_indx, nat_table_type tbl_type, uint16_t value, uint32_t offset); int ipa_nati_post_ipv4_dma_cmd(uint8_t tbl_indx, uint16_t entry); int ipa_nati_del_ipv4_rule(uint32_t tbl_hdl, uint32_t rule_hdl); int ipa_nati_post_del_dma_cmd(uint8_t tbl_indx, uint16_t tbl_entry, uint8_t expn_tbl, del_type rule_pos); void ipa_nati_find_index_rule_pos( struct ipa_nat_ip4_table_cache *cache_ptr, uint16_t tbl_entry, del_type *rule_pos); void ipa_nati_del_dead_ipv4_head_nodes(uint8_t tbl_indx); void ipa_nati_find_rule_pos(struct ipa_nat_ip4_table_cache *cache_ptr, uint8_t expn_tbl, uint16_t tbl_entry, del_type *rule_pos); void ipa_nati_del_dead_ipv4_head_nodes(uint8_t tbl_indx); uint16_t Read16BitFieldValue(uint32_t param, ipa_nat_rule_field_type fld_type); /* ======================================================== Debug functions ========================================================*/ #ifdef NAT_DUMP void ipa_nati_print_rule(struct ipa_nat_rule*, uint32_t); void ipa_nat_dump_ipv4_table(uint32_t); void ipa_nati_print_index_rule(struct ipa_nat_indx_tbl_rule*, uint32_t, uint16_t); int ipa_nati_query_nat_rules(uint32_t, nat_table_type); #endif #endif /* #ifndef IPA_NAT_DRVI_H */ ================================================ FILE: data-ipa-cfg-mgr/ipanat/inc/ipa_nat_logi.h ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file ipa_nat_logi.h @brief This file implements the IPAM log functionality. @Author */ #ifndef IPA_NAT_LOGI_H #define IPA_NAT_LOGI_H #ifdef __cplusplus extern "C" { #endif #include #include #include #define PERROR(fmt) printf("%s:%d %s()", __FILE__, __LINE__, __FUNCTION__);\ perror(fmt); #define IPAERR(fmt, ...) printf("ERR: %s:%d %s() " fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); #ifdef DEBUG #define IPADBG(fmt, ...) printf("%s:%d %s() " fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); #define IPADUMP(fmt, ...) printf(fmt, ##__VA_ARGS__); #else #define IPADBG(fmt, ...) #define IPADUMP(fmt, ...) #endif #ifdef __cplusplus } #endif #endif /* IPA_NAT_LOGI_H */ ================================================ FILE: data-ipa-cfg-mgr/ipanat/src/Android.mk ================================================ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_C_INCLUDES := $(LOCAL_PATH)/../inc LOCAL_C_INCLUDES += $(LOCAL_PATH) LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr LOCAL_SRC_FILES := ipa_nat_drv.c \ ipa_nat_drvi.c LOCAL_CFLAGS := -DDEBUG LOCAL_MODULE := libipanat LOCAL_MODULE_TAGS := optional LOCAL_PRELINK_MODULE := false include $(BUILD_SHARED_LIBRARY) ================================================ FILE: data-ipa-cfg-mgr/ipanat/src/Makefile.am ================================================ AM_CFLAGS = -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs AM_CFLAGS += -I./../inc #AM_CFLAGS += -DDEBUG -g common_CFLAGS = -DUSE_GLIB @GLIB_CFLAGS@ common_LDFLAGS = -lrt @GLIB_LIBS@ c_sources = ipa_nat_drv.c \ ipa_nat_drvi.c \ ipa_nat_logi.c library_includedir = $(pkgincludedir) library_include_HEADERS = ./../inc/ipa_nat_drvi.h \ ./../inc/ipa_nat_drv.h \ ./../inc/ipa_nat_logi.h lib_LTLIBRARIES = libipanat.la libipanat_la_C = @C@ libipanat_la_SOURCES = $(c_sources) libipanat_la_CFLAGS = $(AM_CFLAGS) $(common_CFLAGS) libipanat_la_LDFLAGS = -shared $(common_LDFLAGS) -version-info 1:0:0 ================================================ FILE: data-ipa-cfg-mgr/ipanat/src/ipa_nat_drv.c ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ipa_nat_drv.h" #include "ipa_nat_drvi.h" /** * ipa_nat_add_ipv4_tbl() - create ipv4 nat table * @public_ip_addr: [in] public ipv4 address * @number_of_entries: [in] number of nat entries * @table_handle: [out] Handle of new ipv4 nat table * * To create new ipv4 nat table * * Returns: 0 On Success, negative on failure */ int ipa_nat_add_ipv4_tbl(uint32_t public_ip_addr, uint16_t number_of_entries, uint32_t *tbl_hdl) { int ret; if (NULL == tbl_hdl || 0 == number_of_entries) { IPAERR("Invalid parameters \n"); return -EINVAL; } ret = ipa_nati_add_ipv4_tbl(public_ip_addr, number_of_entries, tbl_hdl); if (ret != 0) { IPAERR("unable to add table \n"); return -EINVAL; } IPADBG("Returning table handle 0x%x\n", *tbl_hdl); return ret; } /* __ipa_nat_add_ipv4_tbl() */ /** * ipa_nat_del_ipv4_tbl() - delete ipv4 table * @table_handle: [in] Handle of ipv4 nat table * * To delete given ipv4 nat table * * Returns: 0 On Success, negative on failure */ int ipa_nat_del_ipv4_tbl(uint32_t tbl_hdl) { if (IPA_NAT_INVALID_NAT_ENTRY == tbl_hdl || tbl_hdl > IPA_NAT_MAX_IP4_TBLS) { IPAERR("invalid table handle passed \n"); return -EINVAL; } IPADBG("Passed Table Handle: 0x%x\n", tbl_hdl); return ipa_nati_del_ipv4_table(tbl_hdl); } /** * ipa_nat_add_ipv4_rule() - to insert new ipv4 rule * @table_handle: [in] handle of ipv4 nat table * @rule: [in] Pointer to new rule * @rule_handle: [out] Return the handle to rule * * To insert new ipv4 nat rule into ipv4 nat table * * Returns: 0 On Success, negative on failure */ int ipa_nat_add_ipv4_rule(uint32_t tbl_hdl, const ipa_nat_ipv4_rule *clnt_rule, uint32_t *rule_hdl) { int result = -EINVAL; if (IPA_NAT_INVALID_NAT_ENTRY == tbl_hdl || tbl_hdl > IPA_NAT_MAX_IP4_TBLS || NULL == rule_hdl || NULL == clnt_rule) { IPAERR("invalide table handle passed \n"); return result; } IPADBG("Passed Table handle: 0x%x\n", tbl_hdl); if (ipa_nati_add_ipv4_rule(tbl_hdl, clnt_rule, rule_hdl) != 0) { return result; } IPADBG("returning rule handle 0x%x\n", *rule_hdl); return 0; } /** * ipa_nat_del_ipv4_rule() - to delete ipv4 nat rule * @table_handle: [in] handle of ipv4 nat table * @rule_handle: [in] ipv4 nat rule handle * * To insert new ipv4 nat rule into ipv4 nat table * * Returns: 0 On Success, negative on failure */ int ipa_nat_del_ipv4_rule(uint32_t tbl_hdl, uint32_t rule_hdl) { int result = -EINVAL; if (IPA_NAT_INVALID_NAT_ENTRY == tbl_hdl || IPA_NAT_INVALID_NAT_ENTRY == rule_hdl) { IPAERR("invalide parameters\n"); return result; } IPADBG("Passed Table: 0x%x and rule handle 0x%x\n", tbl_hdl, rule_hdl); result = ipa_nati_del_ipv4_rule(tbl_hdl, rule_hdl); if (result) { IPAERR("unable to delete rule from hw \n"); return result; } return 0; } /** * ipa_nat_query_timestamp() - to query timestamp * @table_handle: [in] handle of ipv4 nat table * @rule_handle: [in] ipv4 nat rule handle * @time_stamp: [out] time stamp of rule * * To retrieve the timestamp that lastly the * nat rule was accessed * * Returns: 0 On Success, negative on failure */ int ipa_nat_query_timestamp(uint32_t tbl_hdl, uint32_t rule_hdl, uint32_t *time_stamp) { if (0 == tbl_hdl || tbl_hdl > IPA_NAT_MAX_IP4_TBLS || NULL == time_stamp) { IPAERR("invalid parameters passed \n"); return -EINVAL; } IPADBG("Passed Table: 0x%x and rule handle 0x%x\n", tbl_hdl, rule_hdl); return ipa_nati_query_timestamp(tbl_hdl, rule_hdl, time_stamp); } ================================================ FILE: data-ipa-cfg-mgr/ipanat/src/ipa_nat_drvi.c ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ipa_nat_drv.h" #include "ipa_nat_drvi.h" #ifdef USE_GLIB #include #define strlcpy g_strlcpy #endif struct ipa_nat_cache ipv4_nat_cache; /* ------------------------------------------ UTILITY FUNCTIONS START --------------------------------------------*/ /** * UpdateSwSpecParams() - updates sw specific params * @rule: [in/out] nat table rule * @param_type: [in] which param need to update * @value: [in] value of param * * Update SW specific params in the passed rule. * * Returns: None */ void UpdateSwSpecParams(struct ipa_nat_rule *rule, uint8_t param_type, uint32_t value) { uint32_t temp = rule->sw_spec_params; if (IPA_NAT_SW_PARAM_INDX_TBL_ENTRY_BYTE == param_type) { value = (value << INDX_TBL_ENTRY_SIZE_IN_BITS); temp &= 0x0000FFFF; } else { temp &= 0xFFFF0000; } temp = (temp | value); rule->sw_spec_params = temp; return; } /** * Read8BitFieldValue() * @rule: [in/out] * @param_type: [in] * @value: [in] * * * * Returns: None */ uint8_t Read8BitFieldValue(uint32_t param, ipa_nat_rule_field_type fld_type) { void *temp = (void *)¶m; switch (fld_type) { case PROTOCOL_FIELD: return ((time_stamp_proto *)temp)->protocol; default: IPAERR("Invalid Field type passed\n"); return 0; } } uint16_t Read16BitFieldValue(uint32_t param, ipa_nat_rule_field_type fld_type) { void *temp = (void *)¶m; switch (fld_type) { case NEXT_INDEX_FIELD: return ((next_index_pub_port *)temp)->next_index; case PUBLIC_PORT_FILED: return ((next_index_pub_port *)temp)->public_port; case ENABLE_FIELD: return ((ipcksum_enbl *)temp)->enable; case SW_SPEC_PARAM_PREV_INDEX_FIELD: return ((sw_spec_params *)temp)->prev_index; case SW_SPEC_PARAM_INDX_TBL_ENTRY_FIELD: return ((sw_spec_params *)temp)->index_table_entry; case INDX_TBL_TBL_ENTRY_FIELD: return ((tbl_ent_nxt_indx *)temp)->tbl_entry; case INDX_TBL_NEXT_INDEX_FILED: return ((tbl_ent_nxt_indx *)temp)->next_index; #ifdef NAT_DUMP case IP_CHKSUM_FIELD: return ((ipcksum_enbl *)temp)->ip_chksum; #endif default: IPAERR("Invalid Field type passed\n"); return 0; } } uint32_t Read32BitFieldValue(uint32_t param, ipa_nat_rule_field_type fld_type) { void *temp = (void *)¶m; switch (fld_type) { case TIME_STAMP_FIELD: return ((time_stamp_proto *)temp)->time_stamp; default: IPAERR("Invalid Field type passed\n"); return 0; } } /** * CreateNatDevice() - Create nat devices * @mem: [in] name of device that need to create * * Create Nat device and Register for file create * notification in given directory and wait till * receive notification * * Returns: 0 on success, negative on failure */ int CreateNatDevice(struct ipa_ioc_nat_alloc_mem *mem) { int ret; ret = ioctl(ipv4_nat_cache.ipa_fd, IPA_IOC_ALLOC_NAT_MEM, mem); if (ret != 0) { perror("CreateNatDevice(): ioctl error value"); IPAERR("unable to post nat mem init. Error ;%d\n", ret); IPADBG("ipa fd %d\n", ipv4_nat_cache.ipa_fd); return -EINVAL; } IPADBG("posted IPA_IOC_ALLOC_NAT_MEM to kernel successfully\n"); return 0; } /** * GetNearest2Power() - Returns the nearest power of 2 * @num: [in] given number * @ret: [out] nearest power of 2 * * Returns the nearest power of 2 for a * given number * * Returns: 0 on success, negative on failure */ int GetNearest2Power(uint16_t num, uint16_t *ret) { uint16_t number = num; uint16_t tmp = 1; *ret = 0; if (0 == num) { return -EINVAL; } if (1 == num) { *ret = 2; return 0; } for (;;) { if (1 == num) { if (number != tmp) { tmp *= 2; } *ret = tmp; return 0; } num >>= 1; tmp *= 2; } return -EINVAL; } /** * GetNearestEven() - Returns the nearest even number * @num: [in] given number * @ret: [out] nearest even number * * Returns the nearest even number for a given number * * Returns: 0 on success, negative on failure */ void GetNearestEven(uint16_t num, uint16_t *ret) { if (num < 2) { *ret = 2; return; } while ((num % 2) != 0) { num = num + 1; } *ret = num; return; } /** * dst_hash() - Find the index into ipv4 base table * @trgt_ip: [in] Target IP address * @trgt_port: [in] Target port * @public_port: [in] Public port * @proto: [in] Protocol (TCP/IP) * @size: [in] size of the ipv4 base Table * * This hash method is used to find the hash index of new nat * entry into ipv4 base table. In case of zero index, the * new entry will be stored into N-1 index where N is size of * ipv4 base table * * Returns: >0 index into ipv4 base table, negative on failure */ static uint16_t dst_hash(uint32_t trgt_ip, uint16_t trgt_port, uint16_t public_port, uint8_t proto, uint16_t size) { uint16_t hash = ((uint16_t)(trgt_ip)) ^ ((uint16_t)(trgt_ip >> 16)) ^ (trgt_port) ^ (public_port) ^ (proto); IPADBG("trgt_ip: 0x%x trgt_port: 0x%x\n", trgt_ip, trgt_port); IPADBG("public_port: 0x%x\n", public_port); IPADBG("proto: 0x%x size: 0x%x\n", proto, size); hash = (hash & size); /* If the hash resulted to zero then set it to maximum value as zero is unused entry in nat tables */ if (0 == hash) { return size; } IPADBG("dst_hash returning value: %d\n", hash); return hash; } /** * src_hash() - Find the index into ipv4 index base table * @priv_ip: [in] Private IP address * @priv_port: [in] Private port * @trgt_ip: [in] Target IP address * @trgt_port: [in] Target Port * @proto: [in] Protocol (TCP/IP) * @size: [in] size of the ipv4 index base Table * * This hash method is used to find the hash index of new nat * entry into ipv4 index base table. In case of zero index, the * new entry will be stored into N-1 index where N is size of * ipv4 index base table * * Returns: >0 index into ipv4 index base table, negative on failure */ static uint16_t src_hash(uint32_t priv_ip, uint16_t priv_port, uint32_t trgt_ip, uint16_t trgt_port, uint8_t proto, uint16_t size) { uint16_t hash = ((uint16_t)(priv_ip)) ^ ((uint16_t)(priv_ip >> 16)) ^ (priv_port) ^ ((uint16_t)(trgt_ip)) ^ ((uint16_t)(trgt_ip >> 16)) ^ (trgt_port) ^ (proto); IPADBG("priv_ip: 0x%x priv_port: 0x%x\n", priv_ip, priv_port); IPADBG("trgt_ip: 0x%x trgt_port: 0x%x\n", trgt_ip, trgt_port); IPADBG("proto: 0x%x size: 0x%x\n", proto, size); hash = (hash & size); /* If the hash resulted to zero then set it to maximum value as zero is unused entry in nat tables */ if (0 == hash) { return size; } IPADBG("src_hash returning value: %d\n", hash); return hash; } /** * ipa_nati_calc_ip_cksum() - Calculate the source nat * IP checksum diff * @pub_ip_addr: [in] public ip address * @priv_ip_addr: [in] Private ip address * * source nat ip checksum different is calculated as * public_ip_addr - private_ip_addr * Here we are using 1's complement to represent -ve number. * So take 1's complement of private ip addr and add it * to public ip addr. * * Returns: >0 ip checksum diff */ static uint16_t ipa_nati_calc_ip_cksum(uint32_t pub_ip_addr, uint32_t priv_ip_addr) { uint16_t ret; uint32_t cksum = 0; /* Add LSB(2 bytes) of public ip address to cksum */ cksum += (pub_ip_addr & 0xFFFF); /* Add MSB(2 bytes) of public ip address to cksum and check for carry forward(CF), if any add it */ cksum += (pub_ip_addr>>16); if (cksum >> 16) { cksum = (cksum & 0x0000FFFF); cksum += 1; } /* Calculate the 1's complement of private ip address */ priv_ip_addr = (~priv_ip_addr); /* Add LSB(2 bytes) of private ip address to cksum and check for carry forward(CF), if any add it */ cksum += (priv_ip_addr & 0xFFFF); if (cksum >> 16) { cksum = (cksum & 0x0000FFFF); cksum += 1; } /* Add MSB(2 bytes) of private ip address to cksum and check for carry forward(CF), if any add it */ cksum += (priv_ip_addr>>16); if (cksum >> 16) { cksum = (cksum & 0x0000FFFF); cksum += 1; } /* Return the LSB(2 bytes) of checksum */ ret = (uint16_t)cksum; return ret; } /** * ipa_nati_calc_tcp_udp_cksum() - Calculate the source nat * TCP/UDP checksum diff * @pub_ip_addr: [in] public ip address * @pub_port: [in] public tcp/udp port * @priv_ip_addr: [in] Private ip address * @priv_port: [in] Private tcp/udp prot * * source nat tcp/udp checksum is calculated as * (pub_ip_addr + pub_port) - (priv_ip_addr + priv_port) * Here we are using 1's complement to represent -ve number. * So take 1's complement of prviate ip addr &private port * and add it public ip addr & public port. * * Returns: >0 tcp/udp checksum diff */ static uint16_t ipa_nati_calc_tcp_udp_cksum(uint32_t pub_ip_addr, uint16_t pub_port, uint32_t priv_ip_addr, uint16_t priv_port) { uint16_t ret = 0; uint32_t cksum = 0; /* Add LSB(2 bytes) of public ip address to cksum */ cksum += (pub_ip_addr & 0xFFFF); /* Add MSB(2 bytes) of public ip address to cksum and check for carry forward(CF), if any add it */ cksum += (pub_ip_addr>>16); if (cksum >> 16) { cksum = (cksum & 0x0000FFFF); cksum += 1; } /* Add public port to cksum and check for carry forward(CF), if any add it */ cksum += pub_port; if (cksum >> 16) { cksum = (cksum & 0x0000FFFF); cksum += 1; } /* Calculate the 1's complement of private ip address */ priv_ip_addr = (~priv_ip_addr); /* Add LSB(2 bytes) of private ip address to cksum and check for carry forward(CF), if any add it */ cksum += (priv_ip_addr & 0xFFFF); if (cksum >> 16) { cksum = (cksum & 0x0000FFFF); cksum += 1; } /* Add MSB(2 bytes) of private ip address to cksum and check for carry forward(CF), if any add */ cksum += (priv_ip_addr>>16); if (cksum >> 16) { cksum = (cksum & 0x0000FFFF); cksum += 1; } /* Calculate the 1's complement of private port */ priv_port = (~priv_port); /* Add public port to cksum and check for carry forward(CF), if any add it */ cksum += priv_port; if (cksum >> 16) { cksum = (cksum & 0x0000FFFF); cksum += 1; } /* return the LSB(2 bytes) of checksum */ ret = (uint16_t)cksum; return ret; } /** * ipa_nati_make_rule_hdl() - makes nat rule handle * @tbl_hdl: [in] nat table handle * @tbl_entry: [in] nat table entry * * Calculate the nat rule handle which from * nat entry which will be returned to client of * nat driver * * Returns: >0 nat rule handle */ uint16_t ipa_nati_make_rule_hdl(uint16_t tbl_hdl, uint16_t tbl_entry) { struct ipa_nat_ip4_table_cache *tbl_ptr; uint16_t rule_hdl = 0; uint16_t cnt = 0; tbl_ptr = &ipv4_nat_cache.ip4_tbl[tbl_hdl-1]; if (tbl_entry >= tbl_ptr->table_entries) { /* Update the index into table */ rule_hdl = tbl_entry - tbl_ptr->table_entries; rule_hdl = (rule_hdl << IPA_NAT_RULE_HDL_TBL_TYPE_BITS); /* Update the table type mask */ rule_hdl = (rule_hdl | IPA_NAT_RULE_HDL_TBL_TYPE_MASK); } else { rule_hdl = tbl_entry; rule_hdl = (rule_hdl << IPA_NAT_RULE_HDL_TBL_TYPE_BITS); } for (; cnt < (tbl_ptr->table_entries + tbl_ptr->expn_table_entries); cnt++) { if (IPA_NAT_INVALID_NAT_ENTRY == tbl_ptr->rule_id_array[cnt]) { tbl_ptr->rule_id_array[cnt] = rule_hdl; return cnt + 1; } } return 0; } /** * ipa_nati_parse_ipv4_rule_hdl() - prase rule handle * @tbl_hdl: [in] nat table rule * @rule_hdl: [in] nat rule handle * @expn_tbl: [out] expansion table or not * @tbl_entry: [out] index into table * * Parse the rule handle to retrieve the nat table * type and entry of nat table * * Returns: None */ void ipa_nati_parse_ipv4_rule_hdl(uint8_t tbl_index, uint16_t rule_hdl, uint8_t *expn_tbl, uint16_t *tbl_entry) { struct ipa_nat_ip4_table_cache *tbl_ptr; uint16_t rule_id; *expn_tbl = 0; *tbl_entry = IPA_NAT_INVALID_NAT_ENTRY; tbl_ptr = &ipv4_nat_cache.ip4_tbl[tbl_index]; if (rule_hdl >= (tbl_ptr->table_entries + tbl_ptr->expn_table_entries)) { IPAERR("invalid rule handle\n"); return; } rule_id = tbl_ptr->rule_id_array[rule_hdl-1]; /* Retrieve the table type */ *expn_tbl = 0; if (rule_id & IPA_NAT_RULE_HDL_TBL_TYPE_MASK) { *expn_tbl = 1; } /* Retrieve the table entry */ *tbl_entry = (rule_id >> IPA_NAT_RULE_HDL_TBL_TYPE_BITS); return; } uint32_t ipa_nati_get_entry_offset(struct ipa_nat_ip4_table_cache *cache_ptr, nat_table_type tbl_type, uint16_t tbl_entry) { struct ipa_nat_rule *tbl_ptr; uint32_t ret = 0; if (IPA_NAT_EXPN_TBL == tbl_type) { tbl_ptr = (struct ipa_nat_rule *)cache_ptr->ipv4_expn_rules_addr; } else { tbl_ptr = (struct ipa_nat_rule *)cache_ptr->ipv4_rules_addr; } ret = (char *)&tbl_ptr[tbl_entry] - (char *)tbl_ptr; ret += cache_ptr->tbl_addr_offset; return ret; } uint32_t ipa_nati_get_index_entry_offset(struct ipa_nat_ip4_table_cache *cache_ptr, nat_table_type tbl_type, uint16_t indx_tbl_entry) { struct ipa_nat_indx_tbl_rule *indx_tbl_ptr; uint32_t ret = 0; if (IPA_NAT_INDEX_EXPN_TBL == tbl_type) { indx_tbl_ptr = (struct ipa_nat_indx_tbl_rule *)cache_ptr->index_table_expn_addr; } else { indx_tbl_ptr = (struct ipa_nat_indx_tbl_rule *)cache_ptr->index_table_addr; } ret = (char *)&indx_tbl_ptr[indx_tbl_entry] - (char *)indx_tbl_ptr; ret += cache_ptr->tbl_addr_offset; return ret; } /* ------------------------------------------ UTILITY FUNCTIONS END --------------------------------------------*/ /* ------------------------------------------ Main Functions --------------------------------------------**/ void ipa_nati_reset_tbl(uint8_t tbl_indx) { uint16_t table_entries = ipv4_nat_cache.ip4_tbl[tbl_indx].table_entries; uint16_t expn_table_entries = ipv4_nat_cache.ip4_tbl[tbl_indx].expn_table_entries; /* Base table */ IPADBG("memset() base table to 0, %p\n", ipv4_nat_cache.ip4_tbl[tbl_indx].ipv4_rules_addr); memset(ipv4_nat_cache.ip4_tbl[tbl_indx].ipv4_rules_addr, 0, IPA_NAT_TABLE_ENTRY_SIZE * table_entries); /* Base expansino table */ IPADBG("memset() expn base table to 0, %p\n", ipv4_nat_cache.ip4_tbl[tbl_indx].ipv4_expn_rules_addr); memset(ipv4_nat_cache.ip4_tbl[tbl_indx].ipv4_expn_rules_addr, 0, IPA_NAT_TABLE_ENTRY_SIZE * expn_table_entries); /* Index table */ IPADBG("memset() index table to 0, %p\n", ipv4_nat_cache.ip4_tbl[tbl_indx].index_table_addr); memset(ipv4_nat_cache.ip4_tbl[tbl_indx].index_table_addr, 0, IPA_NAT_INDEX_TABLE_ENTRY_SIZE * table_entries); /* Index expansion table */ IPADBG("memset() index expn table to 0, %p\n", ipv4_nat_cache.ip4_tbl[tbl_indx].index_table_expn_addr); memset(ipv4_nat_cache.ip4_tbl[tbl_indx].index_table_expn_addr, 0, IPA_NAT_INDEX_TABLE_ENTRY_SIZE * expn_table_entries); IPADBG("returning from ipa_nati_reset_tbl()\n"); return; } int ipa_nati_add_ipv4_tbl(uint32_t public_ip_addr, uint16_t number_of_entries, uint32_t *tbl_hdl) { struct ipa_ioc_nat_alloc_mem mem; uint8_t tbl_indx = ipv4_nat_cache.table_cnt; uint16_t table_entries, expn_table_entries; int ret; *tbl_hdl = 0; /* Allocate table */ memset(&mem, 0, sizeof(mem)); ret = ipa_nati_alloc_table(number_of_entries, &mem, &table_entries, &expn_table_entries); if (0 != ret) { IPAERR("unable to allocate nat table\n"); return -ENOMEM; } /* Update the cache The (IPA_NAT_UNUSED_BASE_ENTRIES/2) indicates zero entry entries for both base and expansion table */ ret = ipa_nati_update_cache(&mem, public_ip_addr, table_entries, expn_table_entries); if (0 != ret) { IPAERR("unable to update cache Error: %d\n", ret); return -EINVAL; } /* Reset the nat table before posting init cmd */ ipa_nati_reset_tbl(tbl_indx); /* Initialize the ipa hw with nat table dimensions */ ret = ipa_nati_post_ipv4_init_cmd(tbl_indx); if (0 != ret) { IPAERR("unable to post nat_init command Error %d\n", ret); return -EINVAL; } /* Return table handle */ ipv4_nat_cache.table_cnt++; *tbl_hdl = ipv4_nat_cache.table_cnt; #ifdef NAT_DUMP ipa_nat_dump_ipv4_table(*tbl_hdl); #endif return 0; } int ipa_nati_alloc_table(uint16_t number_of_entries, struct ipa_ioc_nat_alloc_mem *mem, uint16_t *table_entries, uint16_t *expn_table_entries) { int fd = 0, ret; uint16_t total_entries; /* Copy the table name */ strlcpy(mem->dev_name, NAT_DEV_NAME, IPA_RESOURCE_NAME_MAX); /* Calculate the size for base table and expansion table */ *table_entries = (uint16_t)(number_of_entries * IPA_NAT_BASE_TABLE_PERCENTAGE); if (*table_entries == 0) { *table_entries = 1; } if (GetNearest2Power(*table_entries, table_entries)) { IPAERR("unable to calculate power of 2\n"); return -EINVAL; } *expn_table_entries = (uint16_t)(number_of_entries * IPA_NAT_EXPANSION_TABLE_PERCENTAGE); GetNearestEven(*expn_table_entries, expn_table_entries); total_entries = (*table_entries)+(*expn_table_entries); /* Calclate the memory size for both table and index table entries */ mem->size = (IPA_NAT_TABLE_ENTRY_SIZE * total_entries); IPADBG("Nat Table size: %d\n", mem->size); mem->size += (IPA_NAT_INDEX_TABLE_ENTRY_SIZE * total_entries); IPADBG("Nat Base and Index Table size: %d\n", mem->size); if (!ipv4_nat_cache.ipa_fd) { fd = open(IPA_DEV_NAME, O_RDONLY); if (fd < 0) { perror("ipa_nati_alloc_table(): open error value:"); IPAERR("unable to open ipa device\n"); return -EIO; } ipv4_nat_cache.ipa_fd = fd; } ret = CreateNatDevice(mem); return ret; } int ipa_nati_update_cache(struct ipa_ioc_nat_alloc_mem *mem, uint32_t public_addr, uint16_t tbl_entries, uint16_t expn_tbl_entries) { uint32_t index = ipv4_nat_cache.table_cnt; char *ipv4_rules_addr = NULL; int fd = 0; int flags = MAP_SHARED; int prot = PROT_READ | PROT_WRITE; off_t offset = 0; #ifdef IPA_ON_R3PC int ret = 0; uint32_t nat_mem_offset = 0; #endif ipv4_nat_cache.ip4_tbl[index].valid = IPA_NAT_TABLE_VALID; ipv4_nat_cache.ip4_tbl[index].public_addr = public_addr; ipv4_nat_cache.ip4_tbl[index].size = mem->size; ipv4_nat_cache.ip4_tbl[index].tbl_addr_offset = mem->offset; ipv4_nat_cache.ip4_tbl[index].table_entries = tbl_entries; ipv4_nat_cache.ip4_tbl[index].expn_table_entries = expn_tbl_entries; IPADBG("num of ipv4 rules:%d\n", tbl_entries); IPADBG("num of ipv4 expn rules:%d\n", expn_tbl_entries); /* allocate memory for nat index expansion table */ if (NULL == ipv4_nat_cache.ip4_tbl[index].index_expn_table_meta) { ipv4_nat_cache.ip4_tbl[index].index_expn_table_meta = malloc(sizeof(struct ipa_nat_indx_tbl_meta_info) * expn_tbl_entries); if (NULL == ipv4_nat_cache.ip4_tbl[index].index_expn_table_meta) { IPAERR("Fail to allocate ipv4 index expansion table meta\n"); return 0; } memset(ipv4_nat_cache.ip4_tbl[index].index_expn_table_meta, 0, sizeof(struct ipa_nat_indx_tbl_meta_info) * expn_tbl_entries); } /* Allocate memory for rule_id_array */ if (NULL == ipv4_nat_cache.ip4_tbl[index].rule_id_array) { ipv4_nat_cache.ip4_tbl[index].rule_id_array = malloc(sizeof(uint16_t) * (tbl_entries + expn_tbl_entries)); if (NULL == ipv4_nat_cache.ip4_tbl[index].rule_id_array) { IPAERR("Fail to allocate rule id array\n"); return 0; } memset(ipv4_nat_cache.ip4_tbl[index].rule_id_array, 0, sizeof(uint16_t) * (tbl_entries + expn_tbl_entries)); } /* open the nat table */ strlcpy(mem->dev_name, NAT_DEV_FULL_NAME, IPA_RESOURCE_NAME_MAX); fd = open(mem->dev_name, O_RDWR); if (fd < 0) { perror("ipa_nati_update_cache(): open error value:"); IPAERR("unable to open nat device. Error:%d\n", fd); return -EIO; } /* copy the nat table name */ strlcpy(ipv4_nat_cache.ip4_tbl[index].table_name, mem->dev_name, IPA_RESOURCE_NAME_MAX); ipv4_nat_cache.ip4_tbl[index].nat_fd = fd; /* open the nat device Table */ #ifndef IPA_ON_R3PC ipv4_rules_addr = (void *)mmap(NULL, mem->size, prot, flags, fd, offset); #else IPADBG("user space r3pc\n"); ipv4_rules_addr = (void *)mmap((caddr_t)0, NAT_MMAP_MEM_SIZE, prot, flags, fd, offset); #endif if (NULL == ipv4_rules_addr) { perror("unable to mmap the memory\n"); return -EINVAL; } #ifdef IPA_ON_R3PC ret = ioctl(ipv4_nat_cache.ipa_fd, IPA_IOC_GET_NAT_OFFSET, &nat_mem_offset); if (ret != 0) { perror("ipa_nati_post_ipv4_init_cmd(): ioctl error value"); IPAERR("unable to post ant offset cmd Error: %d\n", ret); IPADBG("ipa fd %d\n", ipv4_nat_cache.ipa_fd); return -EIO; } ipv4_rules_addr += nat_mem_offset; ipv4_nat_cache.ip4_tbl[index].mmap_offset = nat_mem_offset; #endif IPADBG("mmap return value 0x%lx\n", (long unsigned int)ipv4_rules_addr); ipv4_nat_cache.ip4_tbl[index].ipv4_rules_addr = ipv4_rules_addr; ipv4_nat_cache.ip4_tbl[index].ipv4_expn_rules_addr = ipv4_rules_addr + (IPA_NAT_TABLE_ENTRY_SIZE * tbl_entries); ipv4_nat_cache.ip4_tbl[index].index_table_addr = ipv4_rules_addr + (IPA_NAT_TABLE_ENTRY_SIZE * (tbl_entries + expn_tbl_entries)); ipv4_nat_cache.ip4_tbl[index].index_table_expn_addr = ipv4_rules_addr + (IPA_NAT_TABLE_ENTRY_SIZE * (tbl_entries + expn_tbl_entries))+ (IPA_NAT_INDEX_TABLE_ENTRY_SIZE * tbl_entries); return 0; } /* comment: check the implementation once offset should be in terms of byes */ int ipa_nati_post_ipv4_init_cmd(uint8_t tbl_index) { struct ipa_ioc_v4_nat_init cmd; uint32_t offset = ipv4_nat_cache.ip4_tbl[tbl_index].tbl_addr_offset; int ret; cmd.tbl_index = tbl_index; cmd.ipv4_rules_offset = offset; cmd.expn_rules_offset = cmd.ipv4_rules_offset + (ipv4_nat_cache.ip4_tbl[tbl_index].table_entries * IPA_NAT_TABLE_ENTRY_SIZE); cmd.index_offset = cmd.expn_rules_offset + (ipv4_nat_cache.ip4_tbl[tbl_index].expn_table_entries * IPA_NAT_TABLE_ENTRY_SIZE); cmd.index_expn_offset = cmd.index_offset + (ipv4_nat_cache.ip4_tbl[tbl_index].table_entries * IPA_NAT_INDEX_TABLE_ENTRY_SIZE); cmd.table_entries = ipv4_nat_cache.ip4_tbl[tbl_index].table_entries - 1; cmd.expn_table_entries = ipv4_nat_cache.ip4_tbl[tbl_index].expn_table_entries; cmd.ip_addr = ipv4_nat_cache.ip4_tbl[tbl_index].public_addr; ret = ioctl(ipv4_nat_cache.ipa_fd, IPA_IOC_V4_INIT_NAT, &cmd); if (ret != 0) { perror("ipa_nati_post_ipv4_init_cmd(): ioctl error value"); IPAERR("unable to post init cmd Error: %d\n", ret); IPADBG("ipa fd %d\n", ipv4_nat_cache.ipa_fd); return -EINVAL; } IPADBG("Posted IPA_IOC_V4_INIT_NAT to kernel successfully\n"); return 0; } int ipa_nati_del_ipv4_table(uint32_t tbl_hdl) { uint8_t index = (uint8_t)(tbl_hdl - 1); void *addr = (void *)ipv4_nat_cache.ip4_tbl[index].ipv4_rules_addr; struct ipa_ioc_v4_nat_del del_cmd; int ret; if (!ipv4_nat_cache.ip4_tbl[index].valid) { IPAERR("invalid table handle passed\n"); return -EINVAL; } /* unmap the device memory from user space */ #ifndef IPA_ON_R3PC munmap(addr, ipv4_nat_cache.ip4_tbl[index].size); #else addr = (char *)addr - ipv4_nat_cache.ip4_tbl[index].mmap_offset; munmap(addr, NAT_MMAP_MEM_SIZE); #endif /* close the file descriptor of nat device */ if (close(ipv4_nat_cache.ip4_tbl[index].nat_fd)) { IPAERR("unable to close the file descriptor\n"); return -EINVAL; } del_cmd.table_index = index; del_cmd.public_ip_addr = ipv4_nat_cache.ip4_tbl[index].public_addr; ret = ioctl(ipv4_nat_cache.ipa_fd, IPA_IOC_V4_DEL_NAT, &del_cmd); if (ret != 0) { perror("ipa_nati_del_ipv4_table(): ioctl error value"); IPAERR("unable to post nat del command init Error: %d\n", ret); IPADBG("ipa fd %d\n", ipv4_nat_cache.ipa_fd); return -EINVAL; } IPADBG("posted IPA_IOC_V4_DEL_NAT to kernel successfully\n"); free(ipv4_nat_cache.ip4_tbl[index].index_expn_table_meta); free(ipv4_nat_cache.ip4_tbl[index].rule_id_array); memset(&ipv4_nat_cache.ip4_tbl[index], 0, sizeof(ipv4_nat_cache.ip4_tbl[index])); /* Decrease the table count by 1*/ ipv4_nat_cache.table_cnt--; return 0; } int ipa_nati_query_timestamp(uint32_t tbl_hdl, uint32_t rule_hdl, uint32_t *time_stamp) { uint8_t tbl_index = (uint8_t)(tbl_hdl - 1); uint8_t expn_tbl = 0; uint16_t tbl_entry = 0; struct ipa_nat_rule *tbl_ptr = NULL; if (!ipv4_nat_cache.ip4_tbl[tbl_index].valid) { IPAERR("invalid table handle\n"); return -EINVAL; } ipa_nati_parse_ipv4_rule_hdl(tbl_index, (uint16_t)rule_hdl, &expn_tbl, &tbl_entry); tbl_ptr = (struct ipa_nat_rule *)ipv4_nat_cache.ip4_tbl[tbl_index].ipv4_rules_addr; if (expn_tbl) { tbl_ptr = (struct ipa_nat_rule *)ipv4_nat_cache.ip4_tbl[tbl_index].ipv4_expn_rules_addr; } *time_stamp = Read32BitFieldValue(tbl_ptr[tbl_entry].ts_proto, TIME_STAMP_FIELD); return 0; } int ipa_nati_add_ipv4_rule(uint32_t tbl_hdl, const ipa_nat_ipv4_rule *clnt_rule, uint32_t *rule_hdl) { struct ipa_nat_ip4_table_cache *tbl_ptr; struct ipa_nat_sw_rule sw_rule; struct ipa_nat_indx_tbl_sw_rule index_sw_rule; uint16_t new_entry, new_index_tbl_entry; memset(&sw_rule, 0, sizeof(sw_rule)); memset(&index_sw_rule, 0, sizeof(index_sw_rule)); /* Generate rule from client input */ if (ipa_nati_generate_rule(tbl_hdl, clnt_rule, &sw_rule, &index_sw_rule, &new_entry, &new_index_tbl_entry)) { IPAERR("unable to generate rule\n"); return -EINVAL; } tbl_ptr = &ipv4_nat_cache.ip4_tbl[tbl_hdl-1]; ipa_nati_copy_ipv4_rule_to_hw(tbl_ptr, &sw_rule, new_entry, (uint8_t)(tbl_hdl-1)); ipa_nati_copy_ipv4_index_rule_to_hw(tbl_ptr, &index_sw_rule, new_index_tbl_entry, (uint8_t)(tbl_hdl-1)); IPADBG("new entry:%d, new index entry: %d\n", new_entry, new_index_tbl_entry); if (ipa_nati_post_ipv4_dma_cmd((uint8_t)(tbl_hdl - 1), new_entry)) { IPAERR("unable to post dma command\n"); return -EIO; } /* Generate rule handle */ *rule_hdl = ipa_nati_make_rule_hdl((uint16_t)tbl_hdl, new_entry); if (!(*rule_hdl)) { IPAERR("unable to generate rule handle\n"); return -EINVAL; } #ifdef NAT_DUMP ipa_nat_dump_ipv4_table(tbl_hdl); #endif return 0; } int ipa_nati_generate_rule(uint32_t tbl_hdl, const ipa_nat_ipv4_rule *clnt_rule, struct ipa_nat_sw_rule *rule, struct ipa_nat_indx_tbl_sw_rule *index_sw_rule, uint16_t *tbl_entry, uint16_t *indx_tbl_entry) { struct ipa_nat_ip4_table_cache *tbl_ptr; uint16_t tmp; if (NULL == clnt_rule || NULL == index_sw_rule || NULL == rule || NULL == tbl_entry || NULL == indx_tbl_entry) { IPAERR("invalid parameters\n"); return -EINVAL; } tbl_ptr = &ipv4_nat_cache.ip4_tbl[tbl_hdl-1]; *tbl_entry = ipa_nati_generate_tbl_rule(clnt_rule, rule, tbl_ptr); if (IPA_NAT_INVALID_NAT_ENTRY == *tbl_entry) { IPAERR("unable to generate table entry\n"); return -EINVAL; } index_sw_rule->tbl_entry = *tbl_entry; *indx_tbl_entry = ipa_nati_generate_index_rule(clnt_rule, index_sw_rule, tbl_ptr); if (IPA_NAT_INVALID_NAT_ENTRY == *indx_tbl_entry) { IPAERR("unable to generate index table entry\n"); return -EINVAL; } rule->indx_tbl_entry = *indx_tbl_entry; if (*indx_tbl_entry >= tbl_ptr->table_entries) { tmp = *indx_tbl_entry - tbl_ptr->table_entries; tbl_ptr->index_expn_table_meta[tmp].prev_index = index_sw_rule->prev_index; } return 0; } uint16_t ipa_nati_generate_tbl_rule(const ipa_nat_ipv4_rule *clnt_rule, struct ipa_nat_sw_rule *sw_rule, struct ipa_nat_ip4_table_cache *tbl_ptr) { uint32_t pub_ip_addr; uint16_t prev = 0, nxt_indx = 0, new_entry; struct ipa_nat_rule *tbl = NULL, *expn_tbl = NULL; pub_ip_addr = tbl_ptr->public_addr; tbl = (struct ipa_nat_rule *)tbl_ptr->ipv4_rules_addr; expn_tbl = (struct ipa_nat_rule *)tbl_ptr->ipv4_expn_rules_addr; /* copy the values from client rule to sw rule */ sw_rule->private_ip = clnt_rule->private_ip; sw_rule->private_port = clnt_rule->private_port; sw_rule->protocol = clnt_rule->protocol; sw_rule->public_port = clnt_rule->public_port; sw_rule->target_ip = clnt_rule->target_ip; sw_rule->target_port = clnt_rule->target_port; /* consider only public and private ip fields */ sw_rule->ip_chksum = ipa_nati_calc_ip_cksum(pub_ip_addr, clnt_rule->private_ip); if (IPPROTO_TCP == sw_rule->protocol || IPPROTO_UDP == sw_rule->protocol) { /* consider public and private ip & port fields */ sw_rule->tcp_udp_chksum = ipa_nati_calc_tcp_udp_cksum( pub_ip_addr, clnt_rule->public_port, clnt_rule->private_ip, clnt_rule->private_port); } sw_rule->rsvd1 = 0; sw_rule->enable = IPA_NAT_FLAG_DISABLE_BIT; sw_rule->next_index = 0; /* SW sets this timer to 0. The assumption is that 0 is an invalid clock value and no clock wraparounds are expected */ sw_rule->time_stamp = 0; sw_rule->rsvd2 = 0; sw_rule->prev_index = 0; sw_rule->indx_tbl_entry = 0; new_entry = dst_hash(clnt_rule->target_ip, clnt_rule->target_port, clnt_rule->public_port, clnt_rule->protocol, tbl_ptr->table_entries-1); /* check whether there is any collision if no collision return */ if (!Read16BitFieldValue(tbl[new_entry].ip_cksm_enbl, ENABLE_FIELD)) { sw_rule->prev_index = 0; IPADBG("Destination Nat New Entry Index %d\n", new_entry); return new_entry; } /* First collision */ if (Read16BitFieldValue(tbl[new_entry].nxt_indx_pub_port, NEXT_INDEX_FIELD) == IPA_NAT_INVALID_NAT_ENTRY) { sw_rule->prev_index = new_entry; } else { /* check for more than one collision */ /* Find the IPA_NAT_DEL_TYPE_LAST entry in list */ nxt_indx = Read16BitFieldValue(tbl[new_entry].nxt_indx_pub_port, NEXT_INDEX_FIELD); while (nxt_indx != IPA_NAT_INVALID_NAT_ENTRY) { prev = nxt_indx; nxt_indx -= tbl_ptr->table_entries; nxt_indx = Read16BitFieldValue(expn_tbl[nxt_indx].nxt_indx_pub_port, NEXT_INDEX_FIELD); /* Handling error case */ if (prev == nxt_indx) { IPAERR("Error: Prev index:%d and next:%d index should not be same\n", prev, nxt_indx); return IPA_NAT_INVALID_NAT_ENTRY; } } sw_rule->prev_index = prev; } /* On collision check for the free entry in expansion table */ new_entry = ipa_nati_expn_tbl_free_entry(expn_tbl, tbl_ptr->expn_table_entries); if (IPA_NAT_INVALID_NAT_ENTRY == new_entry) { /* Expansion table is full return*/ IPAERR("expansion table is full\n"); return IPA_NAT_INVALID_NAT_ENTRY; } new_entry += tbl_ptr->table_entries; IPADBG("new entry index %d\n", new_entry); return new_entry; } /* returns expn table entry index */ uint16_t ipa_nati_expn_tbl_free_entry(struct ipa_nat_rule *expn_tbl, uint16_t size) { int cnt; for (cnt = 1; cnt < size; cnt++) { if (!Read16BitFieldValue(expn_tbl[cnt].ip_cksm_enbl, ENABLE_FIELD)) { IPADBG("new expansion table entry index %d\n", cnt); return cnt; } } IPAERR("nat expansion table is full\n"); return 0; } uint16_t ipa_nati_generate_index_rule(const ipa_nat_ipv4_rule *clnt_rule, struct ipa_nat_indx_tbl_sw_rule *sw_rule, struct ipa_nat_ip4_table_cache *tbl_ptr) { struct ipa_nat_indx_tbl_rule *indx_tbl, *indx_expn_tbl; uint16_t prev = 0, nxt_indx = 0, new_entry; indx_tbl = (struct ipa_nat_indx_tbl_rule *)tbl_ptr->index_table_addr; indx_expn_tbl = (struct ipa_nat_indx_tbl_rule *)tbl_ptr->index_table_expn_addr; new_entry = src_hash(clnt_rule->private_ip, clnt_rule->private_port, clnt_rule->target_ip, clnt_rule->target_port, clnt_rule->protocol, tbl_ptr->table_entries-1); /* check whether there is any collision if no collision return */ if (!Read16BitFieldValue(indx_tbl[new_entry].tbl_entry_nxt_indx, INDX_TBL_TBL_ENTRY_FIELD)) { sw_rule->prev_index = 0; IPADBG("Source Nat Index Table Entry %d\n", new_entry); return new_entry; } /* check for more than one collision */ if (Read16BitFieldValue(indx_tbl[new_entry].tbl_entry_nxt_indx, INDX_TBL_NEXT_INDEX_FILED) == IPA_NAT_INVALID_NAT_ENTRY) { sw_rule->prev_index = new_entry; IPADBG("First collosion. Entry %d\n", new_entry); } else { /* Find the IPA_NAT_DEL_TYPE_LAST entry in list */ nxt_indx = Read16BitFieldValue(indx_tbl[new_entry].tbl_entry_nxt_indx, INDX_TBL_NEXT_INDEX_FILED); while (nxt_indx != IPA_NAT_INVALID_NAT_ENTRY) { prev = nxt_indx; nxt_indx -= tbl_ptr->table_entries; nxt_indx = Read16BitFieldValue(indx_expn_tbl[nxt_indx].tbl_entry_nxt_indx, INDX_TBL_NEXT_INDEX_FILED); /* Handling error case */ if (prev == nxt_indx) { IPAERR("Error: Prev:%d and next:%d index should not be same\n", prev, nxt_indx); return IPA_NAT_INVALID_NAT_ENTRY; } } sw_rule->prev_index = prev; } /* On collision check for the free entry in expansion table */ new_entry = ipa_nati_index_expn_get_free_entry( indx_expn_tbl, tbl_ptr->expn_table_entries); if (IPA_NAT_INVALID_NAT_ENTRY == new_entry) { /* Expansion table is full return*/ IPAERR("index expansion table is full\n"); return IPA_NAT_INVALID_NAT_ENTRY; } new_entry += tbl_ptr->table_entries; if (sw_rule->prev_index == new_entry) { IPAERR("Error: prev_entry:%d ", sw_rule->prev_index); IPAERR("and new_entry:%d should not be same ", new_entry); IPAERR("infinite loop detected\n"); return IPA_NAT_INVALID_NAT_ENTRY; } IPADBG("index table entry %d\n", new_entry); return new_entry; } /* returns index expn table entry index */ uint16_t ipa_nati_index_expn_get_free_entry( struct ipa_nat_indx_tbl_rule *indx_tbl, uint16_t size) { int cnt; for (cnt = 1; cnt < size; cnt++) { if (!Read16BitFieldValue(indx_tbl[cnt].tbl_entry_nxt_indx, INDX_TBL_TBL_ENTRY_FIELD)) { return cnt; } } IPAERR("nat index expansion table is full\n"); return 0; } void ipa_nati_write_next_index(uint8_t tbl_indx, nat_table_type tbl_type, uint16_t value, uint32_t offset) { struct ipa_ioc_nat_dma_cmd *cmd; IPADBG("Updating next index field of table %d on collosion using dma\n", tbl_type); IPADBG("table index: %d, value: %d offset;%d\n", tbl_indx, value, offset); cmd = (struct ipa_ioc_nat_dma_cmd *) malloc(sizeof(struct ipa_ioc_nat_dma_cmd)+ sizeof(struct ipa_ioc_nat_dma_one)); if (NULL == cmd) { IPAERR("unable to allocate memory\n"); return; } cmd->dma[0].table_index = tbl_indx; cmd->dma[0].base_addr = tbl_type; cmd->dma[0].data = value; cmd->dma[0].offset = offset; cmd->entries = 1; if (ioctl(ipv4_nat_cache.ipa_fd, IPA_IOC_NAT_DMA, cmd)) { perror("ipa_nati_post_ipv4_dma_cmd(): ioctl error value"); IPAERR("unable to call dma icotl to update next index\n"); IPAERR("ipa fd %d\n", ipv4_nat_cache.ipa_fd); goto fail; } fail: free(cmd); return; } void ipa_nati_copy_ipv4_rule_to_hw( struct ipa_nat_ip4_table_cache *ipv4_cache, struct ipa_nat_sw_rule *rule, uint16_t entry, uint8_t tbl_index) { struct ipa_nat_rule *tbl_ptr; uint16_t prev_entry = rule->prev_index; nat_table_type tbl_type; uint32_t offset = 0; if (entry < ipv4_cache->table_entries) { tbl_ptr = (struct ipa_nat_rule *)ipv4_cache->ipv4_rules_addr; memcpy(&tbl_ptr[entry], rule, sizeof(struct ipa_nat_rule)); } else { tbl_ptr = (struct ipa_nat_rule *)ipv4_cache->ipv4_expn_rules_addr; memcpy(&tbl_ptr[entry - ipv4_cache->table_entries], rule, sizeof(struct ipa_nat_rule)); } /* Update the previos entry next_index */ if (IPA_NAT_INVALID_NAT_ENTRY != prev_entry) { if (prev_entry < ipv4_cache->table_entries) { tbl_type = IPA_NAT_BASE_TBL; tbl_ptr = (struct ipa_nat_rule *)ipv4_cache->ipv4_rules_addr; } else { tbl_type = IPA_NAT_EXPN_TBL; /* tbp_ptr is already pointing to expansion table no need to initialize it */ prev_entry = prev_entry - ipv4_cache->table_entries; } offset = ipa_nati_get_entry_offset(ipv4_cache, tbl_type, prev_entry); offset += IPA_NAT_RULE_NEXT_FIELD_OFFSET; ipa_nati_write_next_index(tbl_index, tbl_type, entry, offset); } return; } void ipa_nati_copy_ipv4_index_rule_to_hw( struct ipa_nat_ip4_table_cache *ipv4_cache, struct ipa_nat_indx_tbl_sw_rule *indx_sw_rule, uint16_t entry, uint8_t tbl_index) { struct ipa_nat_indx_tbl_rule *tbl_ptr; struct ipa_nat_sw_indx_tbl_rule sw_rule; uint16_t prev_entry = indx_sw_rule->prev_index; nat_table_type tbl_type; uint16_t offset = 0; sw_rule.next_index = indx_sw_rule->next_index; sw_rule.tbl_entry = indx_sw_rule->tbl_entry; if (entry < ipv4_cache->table_entries) { tbl_ptr = (struct ipa_nat_indx_tbl_rule *)ipv4_cache->index_table_addr; memcpy(&tbl_ptr[entry], &sw_rule, sizeof(struct ipa_nat_indx_tbl_rule)); } else { tbl_ptr = (struct ipa_nat_indx_tbl_rule *)ipv4_cache->index_table_expn_addr; memcpy(&tbl_ptr[entry - ipv4_cache->table_entries], &sw_rule, sizeof(struct ipa_nat_indx_tbl_rule)); } /* Update the next field of previous entry on collosion */ if (IPA_NAT_INVALID_NAT_ENTRY != prev_entry) { if (prev_entry < ipv4_cache->table_entries) { tbl_type = IPA_NAT_INDX_TBL; tbl_ptr = (struct ipa_nat_indx_tbl_rule *)ipv4_cache->index_table_addr; } else { tbl_type = IPA_NAT_INDEX_EXPN_TBL; /* tbp_ptr is already pointing to expansion table no need to initialize it */ prev_entry = prev_entry - ipv4_cache->table_entries; } offset = ipa_nati_get_index_entry_offset(ipv4_cache, tbl_type, prev_entry); offset += IPA_NAT_INDEX_RULE_NEXT_FIELD_OFFSET; IPADBG("Updating next index field of index table on collosion using dma()\n"); ipa_nati_write_next_index(tbl_index, tbl_type, entry, offset); } return; } int ipa_nati_post_ipv4_dma_cmd(uint8_t tbl_indx, uint16_t entry) { struct ipa_ioc_nat_dma_cmd *cmd; struct ipa_nat_rule *tbl_ptr; uint32_t offset = ipv4_nat_cache.ip4_tbl[tbl_indx].tbl_addr_offset; int ret = 0; cmd = (struct ipa_ioc_nat_dma_cmd *) malloc(sizeof(struct ipa_ioc_nat_dma_cmd)+ sizeof(struct ipa_ioc_nat_dma_one)); if (NULL == cmd) { IPAERR("unable to allocate memory\n"); return -ENOMEM; } if (entry < ipv4_nat_cache.ip4_tbl[tbl_indx].table_entries) { tbl_ptr = (struct ipa_nat_rule *)ipv4_nat_cache.ip4_tbl[tbl_indx].ipv4_rules_addr; cmd->dma[0].table_index = tbl_indx; cmd->dma[0].base_addr = IPA_NAT_BASE_TBL; cmd->dma[0].data = IPA_NAT_FLAG_ENABLE_BIT_MASK; cmd->dma[0].offset = (char *)&tbl_ptr[entry] - (char *)tbl_ptr; cmd->dma[0].offset += IPA_NAT_RULE_FLAG_FIELD_OFFSET; } else { tbl_ptr = (struct ipa_nat_rule *)ipv4_nat_cache.ip4_tbl[tbl_indx].ipv4_expn_rules_addr; entry = entry - ipv4_nat_cache.ip4_tbl[tbl_indx].table_entries; cmd->dma[0].table_index = tbl_indx; cmd->dma[0].base_addr = IPA_NAT_EXPN_TBL; cmd->dma[0].data = IPA_NAT_FLAG_ENABLE_BIT_MASK; cmd->dma[0].offset = (char *)&tbl_ptr[entry] - (char *)tbl_ptr; cmd->dma[0].offset += IPA_NAT_RULE_FLAG_FIELD_OFFSET; cmd->dma[0].offset += offset; } cmd->entries = 1; if (ioctl(ipv4_nat_cache.ipa_fd, IPA_IOC_NAT_DMA, cmd)) { perror("ipa_nati_post_ipv4_dma_cmd(): ioctl error value"); IPAERR("unable to call dma icotl\n"); IPADBG("ipa fd %d\n", ipv4_nat_cache.ipa_fd); ret = -EIO; goto fail; } IPADBG("posted IPA_IOC_NAT_DMA to kernel successfully during add operation\n"); fail: free(cmd); return ret; } int ipa_nati_del_ipv4_rule(uint32_t tbl_hdl, uint32_t rule_hdl) { uint8_t expn_tbl; uint16_t tbl_entry; struct ipa_nat_ip4_table_cache *tbl_ptr; del_type rule_pos; uint8_t tbl_indx = (uint8_t)(tbl_hdl - 1); /* Parse the rule handle */ ipa_nati_parse_ipv4_rule_hdl(tbl_indx, (uint16_t)rule_hdl, &expn_tbl, &tbl_entry); if (IPA_NAT_INVALID_NAT_ENTRY == tbl_entry) { IPAERR("Invalid Rule Entry\n"); return -EINVAL; } IPADBG("Delete below rule\n"); IPADBG("tbl_entry:%d expn_tbl:%d\n", tbl_entry, expn_tbl); tbl_ptr = &ipv4_nat_cache.ip4_tbl[tbl_indx]; if (!tbl_ptr->valid) { IPAERR("invalid table handle\n"); return -EINVAL; } ipa_nati_find_rule_pos(tbl_ptr, expn_tbl, tbl_entry, &rule_pos); IPADBG("rule_pos:%d\n", rule_pos); if (ipa_nati_post_del_dma_cmd(tbl_indx, tbl_entry, expn_tbl, rule_pos)) { return -EINVAL; } ipa_nati_del_dead_ipv4_head_nodes(tbl_indx); /* Reset rule_id_array entry */ ipv4_nat_cache.ip4_tbl[tbl_indx].rule_id_array[rule_hdl-1] = IPA_NAT_INVALID_NAT_ENTRY; #ifdef NAT_DUMP IPADBG("Dumping Table after deleting rule\n"); ipa_nat_dump_ipv4_table(tbl_hdl); #endif return 0; } void ReorderCmds(struct ipa_ioc_nat_dma_cmd *cmd, int size) { int indx_tbl_start = 0, cnt, cnt1; struct ipa_ioc_nat_dma_cmd *tmp; IPADBG("called ReorderCmds() with entries :%d\n", cmd->entries); for (cnt = 0; cnt < cmd->entries; cnt++) { if (cmd->dma[cnt].base_addr == IPA_NAT_INDX_TBL || cmd->dma[cnt].base_addr == IPA_NAT_INDEX_EXPN_TBL) { indx_tbl_start = cnt; break; } } if (indx_tbl_start == 0) { IPADBG("Reorder not needed\n"); return; } tmp = (struct ipa_ioc_nat_dma_cmd *)malloc(size); if (tmp == NULL) { IPAERR("unable to allocate memory\n"); return; } cnt1 = 0; tmp->entries = cmd->entries; for (cnt = indx_tbl_start; cnt < cmd->entries; cnt++) { tmp->dma[cnt1] = cmd->dma[cnt]; cnt1++; } for (cnt = 0; cnt < indx_tbl_start; cnt++) { tmp->dma[cnt1] = cmd->dma[cnt]; cnt1++; } memset(cmd, 0, size); memcpy(cmd, tmp, size); free(tmp); return; } int ipa_nati_post_del_dma_cmd(uint8_t tbl_indx, uint16_t cur_tbl_entry, uint8_t expn_tbl, del_type rule_pos) { #define MAX_DMA_ENTRIES_FOR_DEL 3 struct ipa_nat_ip4_table_cache *cache_ptr; struct ipa_nat_indx_tbl_rule *indx_tbl_ptr; struct ipa_nat_rule *tbl_ptr; int ret = 0, size = 0; uint16_t indx_tbl_entry = IPA_NAT_INVALID_NAT_ENTRY; del_type indx_rule_pos; struct ipa_ioc_nat_dma_cmd *cmd; uint8_t no_of_cmds = 0; uint16_t prev_entry = IPA_NAT_INVALID_NAT_ENTRY; uint16_t next_entry = IPA_NAT_INVALID_NAT_ENTRY; uint16_t indx_next_entry = IPA_NAT_INVALID_NAT_ENTRY; uint16_t indx_next_next_entry = IPA_NAT_INVALID_NAT_ENTRY; uint16_t table_entry; size = sizeof(struct ipa_ioc_nat_dma_cmd)+ (MAX_DMA_ENTRIES_FOR_DEL * sizeof(struct ipa_ioc_nat_dma_one)); cmd = (struct ipa_ioc_nat_dma_cmd *)malloc(size); if (NULL == cmd) { IPAERR("unable to allocate memory\n"); return -ENOMEM; } cache_ptr = &ipv4_nat_cache.ip4_tbl[tbl_indx]; if (!expn_tbl) { tbl_ptr = (struct ipa_nat_rule *)cache_ptr->ipv4_rules_addr; } else { tbl_ptr = (struct ipa_nat_rule *)cache_ptr->ipv4_expn_rules_addr; } if (!Read16BitFieldValue(tbl_ptr[cur_tbl_entry].ip_cksm_enbl, ENABLE_FIELD)) { IPAERR("Deleting invalid(not enabled) rule\n"); ret = -EINVAL; goto fail; } indx_tbl_entry = Read16BitFieldValue(tbl_ptr[cur_tbl_entry].sw_spec_params, SW_SPEC_PARAM_INDX_TBL_ENTRY_FIELD); /* ================================================ Base Table rule Deletion ================================================*/ /* Just delete the current rule by disabling the flag field */ if (IPA_NAT_DEL_TYPE_ONLY_ONE == rule_pos) { cmd->dma[no_of_cmds].table_index = tbl_indx; cmd->dma[no_of_cmds].base_addr = IPA_NAT_BASE_TBL; cmd->dma[no_of_cmds].data = IPA_NAT_FLAG_DISABLE_BIT_MASK; cmd->dma[no_of_cmds].offset = ipa_nati_get_entry_offset(cache_ptr, cmd->dma[no_of_cmds].base_addr, cur_tbl_entry); cmd->dma[no_of_cmds].offset += IPA_NAT_RULE_FLAG_FIELD_OFFSET; } /* Just update the protocol field to invalid */ else if (IPA_NAT_DEL_TYPE_HEAD == rule_pos) { cmd->dma[no_of_cmds].table_index = tbl_indx; cmd->dma[no_of_cmds].base_addr = IPA_NAT_BASE_TBL; cmd->dma[no_of_cmds].data = IPA_NAT_INVALID_PROTO_FIELD_VALUE; cmd->dma[no_of_cmds].offset = ipa_nati_get_entry_offset(cache_ptr, cmd->dma[no_of_cmds].base_addr, cur_tbl_entry); cmd->dma[no_of_cmds].offset += IPA_NAT_RULE_PROTO_FIELD_OFFSET; IPADBG("writing invalid proto: 0x%x\n", cmd->dma[no_of_cmds].data); } /* Update the previous entry of next_index field value with current entry next_index field value */ else if (IPA_NAT_DEL_TYPE_MIDDLE == rule_pos) { prev_entry = Read16BitFieldValue(tbl_ptr[cur_tbl_entry].sw_spec_params, SW_SPEC_PARAM_PREV_INDEX_FIELD); cmd->dma[no_of_cmds].table_index = tbl_indx; cmd->dma[no_of_cmds].data = Read16BitFieldValue(tbl_ptr[cur_tbl_entry].nxt_indx_pub_port, NEXT_INDEX_FIELD); cmd->dma[no_of_cmds].base_addr = IPA_NAT_BASE_TBL; if (prev_entry >= cache_ptr->table_entries) { cmd->dma[no_of_cmds].base_addr = IPA_NAT_EXPN_TBL; prev_entry -= cache_ptr->table_entries; } cmd->dma[no_of_cmds].offset = ipa_nati_get_entry_offset(cache_ptr, cmd->dma[no_of_cmds].base_addr, prev_entry); cmd->dma[no_of_cmds].offset += IPA_NAT_RULE_NEXT_FIELD_OFFSET; } /* Reset the previous entry of next_index field with 0 */ else if (IPA_NAT_DEL_TYPE_LAST == rule_pos) { prev_entry = Read16BitFieldValue(tbl_ptr[cur_tbl_entry].sw_spec_params, SW_SPEC_PARAM_PREV_INDEX_FIELD); cmd->dma[no_of_cmds].table_index = tbl_indx; cmd->dma[no_of_cmds].data = IPA_NAT_INVALID_NAT_ENTRY; cmd->dma[no_of_cmds].base_addr = IPA_NAT_BASE_TBL; if (prev_entry >= cache_ptr->table_entries) { cmd->dma[no_of_cmds].base_addr = IPA_NAT_EXPN_TBL; prev_entry -= cache_ptr->table_entries; } cmd->dma[no_of_cmds].offset = ipa_nati_get_entry_offset(cache_ptr, cmd->dma[no_of_cmds].base_addr, prev_entry); cmd->dma[no_of_cmds].offset += IPA_NAT_RULE_NEXT_FIELD_OFFSET; } /* ================================================ Base Table rule Deletion End ================================================*/ /* ================================================ Index Table rule Deletion ================================================*/ ipa_nati_find_index_rule_pos(cache_ptr, indx_tbl_entry, &indx_rule_pos); IPADBG("Index table entry: 0x%x\n", indx_tbl_entry); IPADBG("and position: %d\n", indx_rule_pos); if (indx_tbl_entry >= cache_ptr->table_entries) { indx_tbl_entry -= cache_ptr->table_entries; indx_tbl_ptr = (struct ipa_nat_indx_tbl_rule *)cache_ptr->index_table_expn_addr; } else { indx_tbl_ptr = (struct ipa_nat_indx_tbl_rule *)cache_ptr->index_table_addr; } /* Just delete the current rule by resetting nat_table_index field to 0 */ if (IPA_NAT_DEL_TYPE_ONLY_ONE == indx_rule_pos) { no_of_cmds++; cmd->dma[no_of_cmds].base_addr = IPA_NAT_INDX_TBL; cmd->dma[no_of_cmds].table_index = tbl_indx; cmd->dma[no_of_cmds].data = IPA_NAT_INVALID_NAT_ENTRY; cmd->dma[no_of_cmds].offset = ipa_nati_get_index_entry_offset(cache_ptr, cmd->dma[no_of_cmds].base_addr, indx_tbl_entry); cmd->dma[no_of_cmds].offset += IPA_NAT_INDEX_RULE_NAT_INDEX_FIELD_OFFSET; } /* copy the next entry values to current entry */ else if (IPA_NAT_DEL_TYPE_HEAD == indx_rule_pos) { next_entry = Read16BitFieldValue(indx_tbl_ptr[indx_tbl_entry].tbl_entry_nxt_indx, INDX_TBL_NEXT_INDEX_FILED); next_entry -= cache_ptr->table_entries; no_of_cmds++; cmd->dma[no_of_cmds].base_addr = IPA_NAT_INDX_TBL; cmd->dma[no_of_cmds].table_index = tbl_indx; /* Copy the nat_table_index field value of next entry */ indx_tbl_ptr = (struct ipa_nat_indx_tbl_rule *)cache_ptr->index_table_expn_addr; cmd->dma[no_of_cmds].data = Read16BitFieldValue(indx_tbl_ptr[next_entry].tbl_entry_nxt_indx, INDX_TBL_TBL_ENTRY_FIELD); cmd->dma[no_of_cmds].offset = ipa_nati_get_index_entry_offset(cache_ptr, cmd->dma[no_of_cmds].base_addr, indx_tbl_entry); cmd->dma[no_of_cmds].offset += IPA_NAT_INDEX_RULE_NAT_INDEX_FIELD_OFFSET; /* Copy the next_index field value of next entry */ no_of_cmds++; cmd->dma[no_of_cmds].base_addr = IPA_NAT_INDX_TBL; cmd->dma[no_of_cmds].table_index = tbl_indx; cmd->dma[no_of_cmds].data = Read16BitFieldValue(indx_tbl_ptr[next_entry].tbl_entry_nxt_indx, INDX_TBL_NEXT_INDEX_FILED); cmd->dma[no_of_cmds].offset = ipa_nati_get_index_entry_offset(cache_ptr, cmd->dma[no_of_cmds].base_addr, indx_tbl_entry); cmd->dma[no_of_cmds].offset += IPA_NAT_INDEX_RULE_NEXT_FIELD_OFFSET; indx_next_entry = next_entry; } /* Update the previous entry of next_index field value with current entry next_index field value */ else if (IPA_NAT_DEL_TYPE_MIDDLE == indx_rule_pos) { prev_entry = cache_ptr->index_expn_table_meta[indx_tbl_entry].prev_index; no_of_cmds++; cmd->dma[no_of_cmds].table_index = tbl_indx; cmd->dma[no_of_cmds].data = Read16BitFieldValue(indx_tbl_ptr[indx_tbl_entry].tbl_entry_nxt_indx, INDX_TBL_NEXT_INDEX_FILED); cmd->dma[no_of_cmds].base_addr = IPA_NAT_INDX_TBL; if (prev_entry >= cache_ptr->table_entries) { cmd->dma[no_of_cmds].base_addr = IPA_NAT_INDEX_EXPN_TBL; prev_entry -= cache_ptr->table_entries; } IPADBG("prev_entry: %d update with cur next_index: %d\n", prev_entry, cmd->dma[no_of_cmds].data); IPADBG("prev_entry: %d exist in table_type:%d\n", prev_entry, cmd->dma[no_of_cmds].base_addr); cmd->dma[no_of_cmds].offset = ipa_nati_get_index_entry_offset(cache_ptr, cmd->dma[no_of_cmds].base_addr, prev_entry); cmd->dma[no_of_cmds].offset += IPA_NAT_INDEX_RULE_NEXT_FIELD_OFFSET; } /* Reset the previous entry next_index field with 0 */ else if (IPA_NAT_DEL_TYPE_LAST == indx_rule_pos) { prev_entry = cache_ptr->index_expn_table_meta[indx_tbl_entry].prev_index; no_of_cmds++; cmd->dma[no_of_cmds].table_index = tbl_indx; cmd->dma[no_of_cmds].data = IPA_NAT_INVALID_NAT_ENTRY; cmd->dma[no_of_cmds].base_addr = IPA_NAT_INDX_TBL; if (prev_entry >= cache_ptr->table_entries) { cmd->dma[no_of_cmds].base_addr = IPA_NAT_INDEX_EXPN_TBL; prev_entry -= cache_ptr->table_entries; } IPADBG("Reseting prev_entry: %d next_index\n", prev_entry); IPADBG("prev_entry: %d exist in table_type:%d\n", prev_entry, cmd->dma[no_of_cmds].base_addr); cmd->dma[no_of_cmds].offset = ipa_nati_get_index_entry_offset(cache_ptr, cmd->dma[no_of_cmds].base_addr, prev_entry); cmd->dma[no_of_cmds].offset += IPA_NAT_INDEX_RULE_NEXT_FIELD_OFFSET; } /* ================================================ Index Table rule Deletion End ================================================*/ cmd->entries = no_of_cmds + 1; if (cmd->entries > 1) { ReorderCmds(cmd, size); } if (ioctl(ipv4_nat_cache.ipa_fd, IPA_IOC_NAT_DMA, cmd)) { perror("ipa_nati_post_del_dma_cmd(): ioctl error value"); IPAERR("unable to post cmd\n"); IPADBG("ipa fd %d\n", ipv4_nat_cache.ipa_fd); ret = -EIO; goto fail; } /* if entry exist in IPA_NAT_DEL_TYPE_MIDDLE of list Update the previous entry in sw specific parameters */ if (IPA_NAT_DEL_TYPE_MIDDLE == rule_pos) { /* Retrieve the current entry prev_entry value */ prev_entry = Read16BitFieldValue(tbl_ptr[cur_tbl_entry].sw_spec_params, SW_SPEC_PARAM_PREV_INDEX_FIELD); /* Retrieve the next entry */ next_entry = Read16BitFieldValue(tbl_ptr[cur_tbl_entry].nxt_indx_pub_port, NEXT_INDEX_FIELD); next_entry -= cache_ptr->table_entries; tbl_ptr = (struct ipa_nat_rule *)cache_ptr->ipv4_expn_rules_addr; /* copy the current entry prev_entry value to next entry*/ UpdateSwSpecParams(&tbl_ptr[next_entry], IPA_NAT_SW_PARAM_PREV_INDX_BYTE, prev_entry); } /* Reset the other field values of current delete entry In case of IPA_NAT_DEL_TYPE_HEAD, don't reset */ if (IPA_NAT_DEL_TYPE_HEAD != rule_pos) { memset(&tbl_ptr[cur_tbl_entry], 0, sizeof(struct ipa_nat_rule)); } if (indx_rule_pos == IPA_NAT_DEL_TYPE_HEAD) { /* Update next next entry previous value to current entry as we moved the next entry values to current entry */ indx_next_next_entry = Read16BitFieldValue(indx_tbl_ptr[indx_next_entry].tbl_entry_nxt_indx, INDX_TBL_NEXT_INDEX_FILED); if (indx_next_next_entry != 0 && indx_next_next_entry >= cache_ptr->table_entries) { IPADBG("Next Next entry: %d\n", indx_next_next_entry); indx_next_next_entry -= cache_ptr->table_entries; IPADBG("Updating entry: %d prev index to: %d\n", indx_next_next_entry, indx_tbl_entry); cache_ptr->index_expn_table_meta[indx_next_next_entry].prev_index = indx_tbl_entry; } /* Now reset the next entry as we copied the next entry to current entry */ IPADBG("Resetting, index table entry(Proper): %d\n", (cache_ptr->table_entries + indx_next_entry)); /* This resets both table entry and next index values */ indx_tbl_ptr[indx_next_entry].tbl_entry_nxt_indx = 0; /* In case of IPA_NAT_DEL_TYPE_HEAD, update the sw specific parameters (index table entry) of base table entry */ indx_tbl_ptr = (struct ipa_nat_indx_tbl_rule *)cache_ptr->index_table_addr; table_entry = Read16BitFieldValue(indx_tbl_ptr[indx_tbl_entry].tbl_entry_nxt_indx, INDX_TBL_TBL_ENTRY_FIELD); if (table_entry >= cache_ptr->table_entries) { tbl_ptr = (struct ipa_nat_rule *)cache_ptr->ipv4_expn_rules_addr; table_entry -= cache_ptr->table_entries; } else { tbl_ptr = (struct ipa_nat_rule *)cache_ptr->ipv4_rules_addr; } UpdateSwSpecParams(&tbl_ptr[table_entry], IPA_NAT_SW_PARAM_INDX_TBL_ENTRY_BYTE, indx_tbl_entry); } else { /* Update the prev_entry value (in index_expn_table_meta) for the next_entry in list with current entry prev_entry value */ if (IPA_NAT_DEL_TYPE_MIDDLE == indx_rule_pos) { next_entry = Read16BitFieldValue(indx_tbl_ptr[indx_tbl_entry].tbl_entry_nxt_indx, INDX_TBL_NEXT_INDEX_FILED); if (next_entry >= cache_ptr->table_entries) { next_entry -= cache_ptr->table_entries; } cache_ptr->index_expn_table_meta[next_entry].prev_index = cache_ptr->index_expn_table_meta[indx_tbl_entry].prev_index; cache_ptr->index_expn_table_meta[indx_tbl_entry].prev_index = IPA_NAT_INVALID_NAT_ENTRY; } IPADBG("At, indx_tbl_entry value: %d\n", indx_tbl_entry); IPADBG("At, indx_tbl_entry member address: %p\n", &indx_tbl_ptr[indx_tbl_entry].tbl_entry_nxt_indx); indx_tbl_ptr[indx_tbl_entry].tbl_entry_nxt_indx = 0; } fail: free(cmd); return ret; } void ipa_nati_find_index_rule_pos( struct ipa_nat_ip4_table_cache *cache_ptr, uint16_t tbl_entry, del_type *rule_pos) { struct ipa_nat_indx_tbl_rule *tbl_ptr; if (tbl_entry >= cache_ptr->table_entries) { tbl_ptr = (struct ipa_nat_indx_tbl_rule *)cache_ptr->index_table_expn_addr; tbl_entry -= cache_ptr->table_entries; if (Read16BitFieldValue(tbl_ptr[tbl_entry].tbl_entry_nxt_indx, INDX_TBL_NEXT_INDEX_FILED) == IPA_NAT_INVALID_NAT_ENTRY) { *rule_pos = IPA_NAT_DEL_TYPE_LAST; } else { *rule_pos = IPA_NAT_DEL_TYPE_MIDDLE; } } else { tbl_ptr = (struct ipa_nat_indx_tbl_rule *)cache_ptr->index_table_addr; if (Read16BitFieldValue(tbl_ptr[tbl_entry].tbl_entry_nxt_indx, INDX_TBL_NEXT_INDEX_FILED) == IPA_NAT_INVALID_NAT_ENTRY) { *rule_pos = IPA_NAT_DEL_TYPE_ONLY_ONE; } else { *rule_pos = IPA_NAT_DEL_TYPE_HEAD; } } } void ipa_nati_find_rule_pos(struct ipa_nat_ip4_table_cache *cache_ptr, uint8_t expn_tbl, uint16_t tbl_entry, del_type *rule_pos) { struct ipa_nat_rule *tbl_ptr; if (expn_tbl) { tbl_ptr = (struct ipa_nat_rule *)cache_ptr->ipv4_expn_rules_addr; if (Read16BitFieldValue(tbl_ptr[tbl_entry].nxt_indx_pub_port, NEXT_INDEX_FIELD) == IPA_NAT_INVALID_NAT_ENTRY) { *rule_pos = IPA_NAT_DEL_TYPE_LAST; } else { *rule_pos = IPA_NAT_DEL_TYPE_MIDDLE; } } else { tbl_ptr = (struct ipa_nat_rule *)cache_ptr->ipv4_rules_addr; if (Read16BitFieldValue(tbl_ptr[tbl_entry].nxt_indx_pub_port, NEXT_INDEX_FIELD) == IPA_NAT_INVALID_NAT_ENTRY) { *rule_pos = IPA_NAT_DEL_TYPE_ONLY_ONE; } else { *rule_pos = IPA_NAT_DEL_TYPE_HEAD; } } } void ipa_nati_del_dead_ipv4_head_nodes(uint8_t tbl_indx) { struct ipa_nat_rule *tbl_ptr; uint16_t cnt; tbl_ptr = (struct ipa_nat_rule *)ipv4_nat_cache.ip4_tbl[tbl_indx].ipv4_rules_addr; for (cnt = 0; cnt < ipv4_nat_cache.ip4_tbl[tbl_indx].table_entries; cnt++) { if (Read8BitFieldValue(tbl_ptr[cnt].ts_proto, PROTOCOL_FIELD) == IPA_NAT_INVALID_PROTO_FIELD_CMP && Read16BitFieldValue(tbl_ptr[cnt].nxt_indx_pub_port, NEXT_INDEX_FIELD) == IPA_NAT_INVALID_NAT_ENTRY) { /* Delete the IPA_NAT_DEL_TYPE_HEAD node */ IPADBG("deleting the dead node 0x%x\n", cnt); memset(&tbl_ptr[cnt], 0, sizeof(struct ipa_nat_rule)); } } /* end of for loop */ return; } /* ======================================================== Debug functions ========================================================*/ #ifdef NAT_DUMP void ipa_nat_dump_ipv4_table(uint32_t tbl_hdl) { struct ipa_nat_rule *tbl_ptr; struct ipa_nat_indx_tbl_rule *indx_tbl_ptr; int cnt; uint8_t atl_one = 0; if (IPA_NAT_INVALID_NAT_ENTRY == tbl_hdl || tbl_hdl > IPA_NAT_MAX_IP4_TBLS) { IPAERR("invalid table handle passed\n"); return; } /* Print ipv4 rules */ IPADBG("Dumping ipv4 active rules:\n"); tbl_ptr = (struct ipa_nat_rule *) ipv4_nat_cache.ip4_tbl[tbl_hdl-1].ipv4_rules_addr; for (cnt = 0; cnt < ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries; cnt++) { if (Read16BitFieldValue(tbl_ptr[cnt].ip_cksm_enbl, ENABLE_FIELD)) { atl_one = 1; ipa_nati_print_rule(&tbl_ptr[cnt], cnt); } } if (!atl_one) { IPADBG("No active base rules, total: %d\n", ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries); } atl_one = 0; /* Print ipv4 expansion rules */ IPADBG("Dumping ipv4 active expansion rules:\n"); tbl_ptr = (struct ipa_nat_rule *) ipv4_nat_cache.ip4_tbl[tbl_hdl-1].ipv4_expn_rules_addr; for (cnt = 0; cnt <= ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].expn_table_entries; cnt++) { if (Read16BitFieldValue(tbl_ptr[cnt].ip_cksm_enbl, ENABLE_FIELD)) { atl_one = 1; ipa_nati_print_rule(&tbl_ptr[cnt], (cnt + ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries)); } } if (!atl_one) { IPADBG("No active base expansion rules, total: %d\n", ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].expn_table_entries); } atl_one = 0; /* Print ipv4 index rules */ IPADBG("Dumping ipv4 index active rules:\n"); indx_tbl_ptr = (struct ipa_nat_indx_tbl_rule *) ipv4_nat_cache.ip4_tbl[tbl_hdl-1].index_table_addr; for (cnt = 0; cnt < ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries; cnt++) { if (Read16BitFieldValue(indx_tbl_ptr[cnt].tbl_entry_nxt_indx, INDX_TBL_TBL_ENTRY_FIELD)) { atl_one = 1; ipa_nati_print_index_rule(&indx_tbl_ptr[cnt], cnt, 0); } } if (!atl_one) { IPADBG("No active index table rules, total:%d\n", ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries); } atl_one = 0; /* Print ipv4 index expansion rules */ IPADBG("Dumping ipv4 index expansion active rules:\n"); indx_tbl_ptr = (struct ipa_nat_indx_tbl_rule *) ipv4_nat_cache.ip4_tbl[tbl_hdl-1].index_table_expn_addr; for (cnt = 0; cnt <= ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].expn_table_entries; cnt++) { if (Read16BitFieldValue(indx_tbl_ptr[cnt].tbl_entry_nxt_indx, INDX_TBL_TBL_ENTRY_FIELD)) { atl_one = 1; ipa_nati_print_index_rule(&indx_tbl_ptr[cnt], (cnt + ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries), ipv4_nat_cache.ip4_tbl[tbl_hdl-1].index_expn_table_meta[cnt].prev_index); } } if (!atl_one) { IPADBG("No active index expansion rules, total:%d\n", ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].expn_table_entries); } atl_one = 0; } void ipa_nati_print_rule( struct ipa_nat_rule *param, uint32_t rule_id) { struct ipa_nat_sw_rule sw_rule; memcpy(&sw_rule, param, sizeof(sw_rule)); uint32_t ip_addr; IPADUMP("rule-id:%d ", rule_id); ip_addr = sw_rule.target_ip; IPADUMP("Trgt-IP:%d.%d.%d.%d ", ((ip_addr & 0xFF000000) >> 24), ((ip_addr & 0x00FF0000) >> 16), ((ip_addr & 0x0000FF00) >> 8), ((ip_addr & 0x000000FF))); IPADUMP("Trgt-Port:%d Priv-Port:%d ", sw_rule.target_port, sw_rule.private_port); ip_addr = sw_rule.private_ip; IPADUMP("Priv-IP:%d.%d.%d.%d ", ((ip_addr & 0xFF000000) >> 24), ((ip_addr & 0x00FF0000) >> 16), ((ip_addr & 0x0000FF00) >> 8), ((ip_addr & 0x000000FF))); IPADUMP("Pub-Port:%d Nxt-indx:%d ", sw_rule.public_port, sw_rule.next_index); IPADUMP("IP-cksm-delta:0x%x En-bit:0x%x ", sw_rule.ip_chksum, sw_rule.enable); IPADUMP("TS:0x%x Proto:0x%x ", sw_rule.time_stamp, sw_rule.protocol); IPADUMP("Prv-indx:%d indx_tbl_entry:%d ", sw_rule.prev_index, sw_rule.indx_tbl_entry); IPADUMP("Tcp-udp-cksum-delta:0x%x", sw_rule.tcp_udp_chksum); IPADUMP("\n"); return; } void ipa_nati_print_index_rule( struct ipa_nat_indx_tbl_rule *param, uint32_t rule_id, uint16_t prev_indx) { struct ipa_nat_sw_indx_tbl_rule sw_rule; memcpy(&sw_rule, param, sizeof(sw_rule)); IPADUMP("rule-id:%d Table_entry:%d Next_index:%d, prev_indx:%d", rule_id, sw_rule.tbl_entry, sw_rule.next_index, prev_indx); IPADUMP("\n"); return; } int ipa_nati_query_nat_rules( uint32_t tbl_hdl, nat_table_type tbl_type) { struct ipa_nat_rule *tbl_ptr; struct ipa_nat_indx_tbl_rule *indx_tbl_ptr; int cnt = 0, ret = 0; if (IPA_NAT_INVALID_NAT_ENTRY == tbl_hdl || tbl_hdl > IPA_NAT_MAX_IP4_TBLS) { IPAERR("invalid table handle passed\n"); return ret; } /* Print ipv4 rules */ if (tbl_type == IPA_NAT_BASE_TBL) { IPADBG("Counting ipv4 active rules:\n"); tbl_ptr = (struct ipa_nat_rule *) ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].ipv4_rules_addr; for (cnt = 0; cnt < ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries; cnt++) { if (Read16BitFieldValue(tbl_ptr[cnt].ip_cksm_enbl, ENABLE_FIELD)) { ret++; } } if (!ret) { IPADBG("No active base rules\n"); } IPADBG("Number of active base rules: %d\n", ret); } /* Print ipv4 expansion rules */ if (tbl_type == IPA_NAT_EXPN_TBL) { IPADBG("Counting ipv4 active expansion rules:\n"); tbl_ptr = (struct ipa_nat_rule *) ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].ipv4_expn_rules_addr; for (cnt = 0; cnt < ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].expn_table_entries; cnt++) { if (Read16BitFieldValue(tbl_ptr[cnt].ip_cksm_enbl, ENABLE_FIELD)) { ret++; } } if (!ret) { IPADBG("No active base expansion rules\n"); } IPADBG("Number of active base expansion rules: %d\n", ret); } /* Print ipv4 index rules */ if (tbl_type == IPA_NAT_INDX_TBL) { IPADBG("Counting ipv4 index active rules:\n"); indx_tbl_ptr = (struct ipa_nat_indx_tbl_rule *) ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].index_table_addr; for (cnt = 0; cnt < ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries; cnt++) { if (Read16BitFieldValue(indx_tbl_ptr[cnt].tbl_entry_nxt_indx, INDX_TBL_TBL_ENTRY_FIELD)) { ret++; } } if (!ret) { IPADBG("No active index table rules\n"); } IPADBG("Number of active index table rules: %d\n", ret); } /* Print ipv4 index expansion rules */ if (tbl_type == IPA_NAT_INDEX_EXPN_TBL) { IPADBG("Counting ipv4 index expansion active rules:\n"); indx_tbl_ptr = (struct ipa_nat_indx_tbl_rule *) ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].index_table_expn_addr; for (cnt = 0; cnt < ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].expn_table_entries; cnt++) { if (Read16BitFieldValue(indx_tbl_ptr[cnt].tbl_entry_nxt_indx, INDX_TBL_TBL_ENTRY_FIELD)) { ret++; } } if (!ret) IPADBG("No active index expansion rules\n"); IPADBG("Number of active index expansion rules: %d\n", ret); } return ret; } #endif ================================================ FILE: data-ipa-cfg-mgr/ipanat/src/ipa_nat_logi.c ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! @file IPACM_log.cpp @brief This file implements the IPAM log functionality. @Author Skylar Chang */ #include "ipa_nat_logi.h" #include #include void log_nat_message(char *msg) { return; } ================================================ FILE: data-ipa-cfg-mgr/ipanat/test/Android.mk ================================================ ifneq (,$(filter $(QCOM_BOARD_PLATFORMS),$(TARGET_BOARD_PLATFORM))) ifneq (, $(filter aarch64 arm arm64, $(TARGET_ARCH))) LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_C_INCLUDES := $(LOCAL_PATH)/ LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../ipanat/inc LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr LOCAL_MODULE := ipa_nat_test LOCAL_SRC_FILES := ipa_nat_test000.c \ ipa_nat_test001.c \ ipa_nat_test002.c \ ipa_nat_test003.c \ ipa_nat_test004.c \ ipa_nat_test005.c \ ipa_nat_test006.c \ ipa_nat_test007.c \ ipa_nat_test008.c \ ipa_nat_test009.c \ ipa_nat_test010.c \ ipa_nat_test011.c \ ipa_nat_test012.c \ ipa_nat_test013.c \ ipa_nat_test014.c \ ipa_nat_test015.c \ ipa_nat_test016.c \ ipa_nat_test017.c \ ipa_nat_test018.c \ ipa_nat_test019.c \ ipa_nat_test020.c \ ipa_nat_test021.c \ ipa_nat_test022.c \ main.c LOCAL_SHARED_LIBRARIES := libipanat LOCAL_MODULE_TAGS := debug LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/kernel-tests/ip_accelerator include $(BUILD_EXECUTABLE) endif # $(TARGET_ARCH) endif ================================================ FILE: data-ipa-cfg-mgr/ipanat/test/Makefile.am ================================================ AM_CPPFLAGS = -I./../inc \ -I$(top_srcdir)/ipanat/inc AM_CPPFLAGS += -Wall -Wundef -Wno-trigraphs AM_CPPFLAGS += -g ipanattest_SOURCES = ipa_nat_test000.c \ ipa_nat_test001.c \ ipa_nat_test002.c \ ipa_nat_test003.c \ ipa_nat_test004.c \ ipa_nat_test005.c \ ipa_nat_test006.c \ ipa_nat_test007.c \ ipa_nat_test008.c \ ipa_nat_test009.c \ ipa_nat_test010.c \ ipa_nat_test011.c \ ipa_nat_test012.c \ ipa_nat_test013.c \ ipa_nat_test014.c \ ipa_nat_test015.c \ ipa_nat_test016.c \ ipa_nat_test017.c \ ipa_nat_test018.c \ ipa_nat_test019.c \ ipa_nat_test020.c \ ipa_nat_test021.c \ ipa_nat_test022.c \ main.c bin_PROGRAMS = ipanattest requiredlibs = ../src/libipanat.la ipanattest_LDADD = $(requiredlibs) LOCAL_MODULE := libipanat LOCAL_PRELINK_MODULE := false include $(BUILD_SHARED_LIBRARY) ================================================ FILE: data-ipa-cfg-mgr/ipanat/test/README.txt ================================================ 1 To run this suite separately(each test case creates table and delete table) use below command - To execute test suite nt times with n entries, command "ipanatest sep nt n" Example: To execute test suite 1 time with 100 entries, command "ipanattest sep 100" 2. To run test suite not separately(creates table and delete table only once) use below command - To execute test suite nt times with n entries, command "ipanatest reg nt n" Example: To execute test suite 5 times with 32 entries, command "ipanattest reg 5 32" 3. To run inotify regression test use command, "ipanattest inotify nt" Example: To execute inotify 5 times, command "ipanattest inotify 5" 4. if we just give command "ipanattest", runs test suite 1 time with 100 entries (non separate) ================================================ FILE: data-ipa-cfg-mgr/ipanat/test/ipa_nat_test.h ================================================ /* * Copyright (c) 2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*=========================================================================== INCLUDE FILES FOR MODULE ===========================================================================*/ #include "stdint.h" /* uint32_t */ #include "stdio.h" #include /* for proto definitions */ #define u32 uint32_t #define u16 uint16_t #define u8 uint8_t /*============ Preconditions to run NAT Test cases =========*/ #define IPA_NAT_TEST_PRE_COND_TE 20 #define CHECK_ERR1(x, tbl_hdl) \ if(ipa_nat_validate_ipv4_table(tbl_hdl)) { \ if(sep) {\ ipa_nat_del_ipv4_tbl(tbl_hdl); \ }\ return -1;\ }\ if(x) { \ IPAERR("%d\n", ret); \ if(sep) {\ ipa_nat_del_ipv4_tbl(tbl_hdl); \ }\ return -1; \ } #define CHECK_ERR(x) if(x) { \ IPAERR("%d\n", ret); \ return -1;\ } #if 0 #define CHECK_ERR(x) if(x) { \ IPAERR("%d\n", ret); \ if(sep) {\ ipa_nat_del_ipv4_tbl(tbl_hdl); \ }\ return -1;\ } #endif #define IPADBG(fmt, args...) printf(" %s:%d " fmt, __FUNCTION__, __LINE__, ## args) #define IPAERR(fmt, args...) printf(" %s:%d " fmt, __FUNCTION__, __LINE__, ## args) #define NAT_DUMP int ipa_nat_validate_ipv4_table(u32); int ipa_nat_test000(int, u32, u8); int ipa_nat_test001(int, u32, u8); int ipa_nat_test002(int, u32, u8); int ipa_nat_test003(int, u32, u8); int ipa_nat_test004(int, u32, u8); int ipa_nat_test005(int, u32, u8); int ipa_nat_test006(int, u32, u8); int ipa_nat_test007(int, u32, u8); int ipa_nat_test008(int, u32, u8); int ipa_nat_test009(int, u32, u8); int ipa_nat_test010(int, u32, u8); int ipa_nat_test011(int, u32, u8); int ipa_nat_test012(int, u32, u8); int ipa_nat_test013(int, u32, u8); int ipa_nat_test014(int, u32, u8); int ipa_nat_test015(int, u32, u8); int ipa_nat_test016(int, u32, u8); int ipa_nat_test017(int, u32, u8); int ipa_nat_test018(int, u32, u8); int ipa_nat_test019(int, u32, u8); int ipa_nat_test020(int, u32, u8); int ipa_nat_test021(int, int); int ipa_nat_test022(int, u32, u8); ================================================ FILE: data-ipa-cfg-mgr/ipanat/test/ipa_nat_test000.c ================================================ /* * Copyright (c) 2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*=========================================================================*/ /*! @file ipa_nat_test000.c @brief Verify the following scenario: 1. Add ipv4 table 2. Delete ipv4 table */ /*===========================================================================*/ #include "ipa_nat_test.h" #include "ipa_nat_drv.h" int ipa_nat_test000(int total_entries, u32 tbl_hdl, u8 sep) { int ret; u32 pub_ip_add = 0x011617c0; /* "192.23.22.1" */ ret = ipa_nat_add_ipv4_tbl(pub_ip_add, total_entries, &tbl_hdl); if (0 != ret) { IPAERR("unable to create ipv4 nat table and returning Error:%d\n", ret); return -1; } IPADBG("create nat ipv4 table successfully() \n"); IPADBG("calling ipa_nat_del_ipv4_tbl() \n"); ret = ipa_nat_del_ipv4_tbl(tbl_hdl); if (0 != ret) { IPAERR("Unable to delete ipv4 nat table %d\n", ret); return -1; } IPADBG("deleted ipv4 nat table successfully. Test passed \n"); return 0; } ================================================ FILE: data-ipa-cfg-mgr/ipanat/test/ipa_nat_test001.c ================================================ /* * Copyright (c) 2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*=========================================================================*/ /*! @file ipa_nat_test001.c @brief Verify the following scenario: 1. Add ipv4 table 2. Add ipv4 rule 3. Delete ipv4 table */ /*===========================================================================*/ #include "ipa_nat_test.h" #include "ipa_nat_drv.h" int ipa_nat_test001(int total_entries, u32 tbl_hdl, u8 sep) { int ret; u32 rule_hdl; ipa_nat_ipv4_rule ipv4_rule; u32 pub_ip_add = 0x011617c0; /* "192.23.22.1" */ ipv4_rule.target_ip = 0xC1171601; /* 193.23.22.1 */ ipv4_rule.target_port = 1234; ipv4_rule.private_ip = 0xC2171601; /* 194.23.22.1 */ ipv4_rule.private_port = 5678; ipv4_rule.protocol = IPPROTO_TCP; ipv4_rule.public_port = 9050; IPADBG("%s()\n",__FUNCTION__); if(sep) { ret = ipa_nat_add_ipv4_tbl(pub_ip_add, total_entries, &tbl_hdl); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_tbl(tbl_hdl); CHECK_ERR(ret); } return 0; } ================================================ FILE: data-ipa-cfg-mgr/ipanat/test/ipa_nat_test002.c ================================================ /* * Copyright (c) 2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*=========================================================================*/ /*! @file ipa_nat_test002.c @brief Verify the following scenario: 1. Add ipv4 table 2. Add ipv4 rule 3. delete ipv4 rule 4. Delete ipv4 table */ /*=========================================================================*/ #include "ipa_nat_test.h" #include "ipa_nat_drv.h" int ipa_nat_test002(int total_entries, u32 tbl_hdl, u8 sep) { int ret; u32 rule_hdl; ipa_nat_ipv4_rule ipv4_rule; u32 pub_ip_add = 0x011617c0; /* "192.23.22.1" */ ipv4_rule.target_ip = 0xC1171601; /* 193.23.22.1 */ ipv4_rule.target_port = 1234; ipv4_rule.private_ip = 0xC2171601; /* 194.23.22.1 */ ipv4_rule.private_port = 5678; ipv4_rule.protocol = IPPROTO_TCP; ipv4_rule.public_port = 9050; IPADBG("%s()\n",__FUNCTION__); if(sep) { ret = ipa_nat_add_ipv4_tbl(pub_ip_add, total_entries, &tbl_hdl); CHECK_ERR(ret); } ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl); CHECK_ERR(ret); if(sep) { ret = ipa_nat_del_ipv4_tbl(tbl_hdl); CHECK_ERR(ret); } return 0; } ================================================ FILE: data-ipa-cfg-mgr/ipanat/test/ipa_nat_test003.c ================================================ /* * Copyright (c) 2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*=========================================================================*/ /*! @file IPA_NAT_ipa_nat_test003.cpp @brief Verify the following scenario: 1. Add ipv4 table 2. Add ipv4 rule 3. Add ipv4 rule 4. Delete ipv4 table */ /*=========================================================================*/ #include "ipa_nat_test.h" #include "ipa_nat_drv.h" int ipa_nat_test003(int total_entries, u32 tbl_hdl, u8 sep) { int ret; u32 rule_hdl, rule_hdl1; ipa_nat_ipv4_rule ipv4_rule; u32 pub_ip_add = 0x011617c0; /* "192.23.22.1" */ ipv4_rule.target_ip = 0xC1171601; /* 193.23.22.1 */ ipv4_rule.target_port = 1234; ipv4_rule.private_ip = 0xC2171601; /* 194.23.22.1 */ ipv4_rule.private_port = 5678; ipv4_rule.protocol = IPPROTO_TCP; ipv4_rule.public_port = 9050; IPADBG("%s():\n",__FUNCTION__); if(sep) { ret = ipa_nat_add_ipv4_tbl(pub_ip_add, total_entries, &tbl_hdl); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl1); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_tbl(tbl_hdl); CHECK_ERR(ret); } return 0; } ================================================ FILE: data-ipa-cfg-mgr/ipanat/test/ipa_nat_test004.c ================================================ /* * Copyright (c) 2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*=========================================================================*/ /*! @file ipa_nat_test004.cpp @brief Verify the following scenario: 1. Add ipv4 table 2. Query nat table handle 3. Delete ipv4 table */ /*===========================================================================*/ #include "ipa_nat_test.h" #include "ipa_nat_drv.h" int ipa_nat_test004(int total_entries, u32 tbl_hdl, u8 sep) { int ret = 0; u32 tbl_hdl1 = 0; u32 pub_ip_add = 0x011617c0; /* "192.23.22.1" */ IPADBG("%s():\n",__FUNCTION__); if(sep) { ret = ipa_nat_add_ipv4_tbl(pub_ip_add, total_entries, &tbl_hdl); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_tbl(tbl_hdl); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_tbl(tbl_hdl1); if(ret == 0) { IPAERR("able to delete table using invalid table handle\n"); return -1; } } return 0; } ================================================ FILE: data-ipa-cfg-mgr/ipanat/test/ipa_nat_test005.c ================================================ /* * Copyright (c) 2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*=========================================================================*/ /*! @file ipa_nat_test005.c @brief Verify the following scenario: 1. Add ipv4 table 2. Add ipv4 rule 3. Delete ipv4 rule 4. Add ipv4 rule 5. Delete ipv4 table */ /*=========================================================================*/ #include "ipa_nat_test.h" #include "ipa_nat_drv.h" int ipa_nat_test005(int total_entries, u32 tbl_hdl, u8 sep) { int ret = 0; u32 rule_hdl, rule_hdl1; ipa_nat_ipv4_rule ipv4_rule; u32 pub_ip_add = 0x011617c0; /* "192.23.22.1" */ ipv4_rule.target_ip = 0xC1171601; /* 193.23.22.1 */ ipv4_rule.target_port = 1234; ipv4_rule.private_ip = 0xC2171601; /* 194.23.22.1 */ ipv4_rule.private_port = 5678; ipv4_rule.protocol = IPPROTO_TCP; ipv4_rule.public_port = 9050; if (sep) { ret = ipa_nat_add_ipv4_tbl(pub_ip_add, total_entries, &tbl_hdl); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl1); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_tbl(tbl_hdl); CHECK_ERR(ret); } return 0; } ================================================ FILE: data-ipa-cfg-mgr/ipanat/test/ipa_nat_test006.c ================================================ /* * Copyright (c) 2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*=========================================================================*/ /*! @file ipa_nat_test006.c @brief Verify the following scenario: 1. Add ipv4 table 2. add same ipv rules 3. delete first followed by second 4. Delete ipv4 table */ /*=========================================================================*/ #include "ipa_nat_test.h" #include "ipa_nat_drv.h" int ipa_nat_test006(int total_entries, u32 tbl_hdl, u8 sep) { int ret=0; u32 rule_hdl, rule_hdl1; ipa_nat_ipv4_rule ipv4_rule; u32 pub_ip_add = 0x011617c0; /* "192.23.22.1" */ ipv4_rule.target_ip = 0xC1171601; /* 193.23.22.1 */ ipv4_rule.target_port = 1234; ipv4_rule.private_ip = 0xC2171601; /* 194.23.22.1 */ ipv4_rule.private_port = 5678; ipv4_rule.protocol = IPPROTO_TCP; ipv4_rule.public_port = 9050; IPADBG("%s():\n",__FUNCTION__); if(sep) { ret = ipa_nat_add_ipv4_tbl(pub_ip_add, total_entries, &tbl_hdl); CHECK_ERR(ret); } ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl1); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl1); CHECK_ERR(ret); if(sep) { ret = ipa_nat_del_ipv4_tbl(tbl_hdl); CHECK_ERR(ret); } return 0; } ================================================ FILE: data-ipa-cfg-mgr/ipanat/test/ipa_nat_test007.c ================================================ /* * Copyright (c) 2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*=========================================================================*/ /*! @file ipa_nat_test007.cpp @brief Verify the following scenario: 1. Add ipv4 table 2. add same ipv rules 3. delete second followed by first 4. Delete ipv4 table */ /*=========================================================================*/ #include "ipa_nat_test.h" #include "ipa_nat_drv.h" int ipa_nat_test007(int total_entries, u32 tbl_hdl, u8 sep) { int ret; u32 rule_hdl, rule_hdl1; ipa_nat_ipv4_rule ipv4_rule; u32 pub_ip_add = 0x011617c0; /* "192.23.22.1" */ ipv4_rule.target_ip = 0xC1171601; /* 193.23.22.1 */ ipv4_rule.target_port = 1234; ipv4_rule.private_ip = 0xC2171601; /* 194.23.22.1 */ ipv4_rule.private_port = 5678; ipv4_rule.protocol = IPPROTO_TCP; ipv4_rule.public_port = 9050; IPADBG("%s():\n",__FUNCTION__); if(sep) { ret = ipa_nat_add_ipv4_tbl(pub_ip_add, total_entries, &tbl_hdl); CHECK_ERR(ret); } ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl1); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl1); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl); CHECK_ERR(ret); if(sep) { ret = ipa_nat_del_ipv4_tbl(tbl_hdl); CHECK_ERR(ret); } return 0; } ================================================ FILE: data-ipa-cfg-mgr/ipanat/test/ipa_nat_test008.c ================================================ /* * Copyright (c) 2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*=========================================================================*/ /*! @file ipa_nat_test008.c @brief Verify the following scenario: 1. Add ipv4 table 2. add 2 distinct rules 3. delete first followed by second 4. Delete ipv4 table */ /*=========================================================================*/ #include "ipa_nat_test.h" #include "ipa_nat_drv.h" int ipa_nat_test008(int total_entries, u32 tbl_hdl, u8 sep) { int ret; u32 rule_hdl, rule_hdl1; ipa_nat_ipv4_rule ipv4_rule, ipv4_rule1; u32 pub_ip_add = 0x011617c0; /* "192.23.22.1" */ ipv4_rule.target_ip = 0xC1171601; /* 193.23.22.1 */ ipv4_rule.target_port = 1234; ipv4_rule.private_ip = 0xC2171601; /* 194.23.22.1 */ ipv4_rule.private_port = 5678; ipv4_rule.protocol = IPPROTO_TCP; ipv4_rule.public_port = 9050; ipv4_rule1.target_ip = 0xC1171602; /* 193.23.22.2 */ ipv4_rule1.target_port = 1234; ipv4_rule1.private_ip = 0xC2171602; /* 194.23.22.2 */ ipv4_rule1.private_port = 5678; ipv4_rule1.protocol = IPPROTO_TCP; ipv4_rule1.public_port = 9050; IPADBG("%s():\n",__FUNCTION__); if(sep) { ret = ipa_nat_add_ipv4_tbl(pub_ip_add, total_entries, &tbl_hdl); CHECK_ERR(ret); } ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule1, &rule_hdl1); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl1); CHECK_ERR(ret); if(sep) { ret = ipa_nat_del_ipv4_tbl(tbl_hdl); CHECK_ERR(ret); } return 0; } ================================================ FILE: data-ipa-cfg-mgr/ipanat/test/ipa_nat_test009.c ================================================ /* * Copyright (c) 2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*=========================================================================*/ /*! @file ipa_nat_test009.cpp @brief Verify the following scenario: 1. Add ipv4 table 2. add 2 distinct rules 3. delete second followed by first 4. Delete ipv4 table */ /*=========================================================================*/ #include "ipa_nat_test.h" #include "ipa_nat_drv.h" int ipa_nat_test009(int total_entries, u32 tbl_hdl, u8 sep) { int ret; u32 rule_hdl, rule_hdl1; ipa_nat_ipv4_rule ipv4_rule, ipv4_rule1; u32 pub_ip_add = 0x011617c0; /* "192.23.22.1" */ ipv4_rule.target_ip = 0xC1171601; /* 193.23.22.1 */ ipv4_rule.target_port = 1234; ipv4_rule.private_ip = 0xC2171601; /* 194.23.22.1 */ ipv4_rule.private_port = 5678; ipv4_rule.protocol = IPPROTO_TCP; ipv4_rule.public_port = 9050; ipv4_rule1.target_ip = 0xC1171602; /* 193.23.22.2 */ ipv4_rule1.target_port = 1234; ipv4_rule1.private_ip = 0xC2171602; /* 194.23.22.2 */ ipv4_rule1.private_port = 5678; ipv4_rule1.protocol = IPPROTO_TCP; ipv4_rule1.public_port = 9050; IPADBG("%s():\n",__FUNCTION__); if(sep) { ret = ipa_nat_add_ipv4_tbl(pub_ip_add, total_entries, &tbl_hdl); CHECK_ERR(ret); } ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule1, &rule_hdl1); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl1); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl); CHECK_ERR(ret); if(sep) { ret = ipa_nat_del_ipv4_tbl(tbl_hdl); CHECK_ERR(ret); } return 0; } ================================================ FILE: data-ipa-cfg-mgr/ipanat/test/ipa_nat_test010.c ================================================ /* * Copyright (c) 2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*=========================================================================*/ /*! @file ipa_nat_test010.c @brief Verify the following scenario: 1. Add ipv4 table 2. add 3 distinct ipv4 rules 3. delete first, second followed by last 4. Delete ipv4 table */ /*=========================================================================*/ #include "ipa_nat_test.h" #include "ipa_nat_drv.h" int ipa_nat_test010(int total_entries, u32 tbl_hdl, u8 sep) { int ret; u32 rule_hdl, rule_hdl1, rule_hdl2; ipa_nat_ipv4_rule ipv4_rule, ipv4_rule1, ipv4_rule2; u32 pub_ip_add = 0x011617c0; /* "192.23.22.1" */ ipv4_rule.target_ip = 0xC1171601; /* 193.23.22.1 */ ipv4_rule.target_port = 1234; ipv4_rule.private_ip = 0xC2171601; /* 194.23.22.1 */ ipv4_rule.private_port = 5678; ipv4_rule.protocol = IPPROTO_TCP; ipv4_rule.public_port = 9050; ipv4_rule1.target_ip = 0xC1171601; /* 193.23.22.1 */ ipv4_rule1.target_port = 1235; ipv4_rule1.private_ip = 0xC2171601; /* 194.23.22.1 */ ipv4_rule1.private_port = 5679; ipv4_rule1.protocol = IPPROTO_TCP; ipv4_rule1.public_port = 9051; ipv4_rule2.target_ip = 0xC1171602; /* 193.23.22.2 */ ipv4_rule2.target_port = 1235; ipv4_rule2.private_ip = 0xC2171602; /* 194.23.22.2 */ ipv4_rule2.private_port = 5679; ipv4_rule2.protocol = IPPROTO_TCP; ipv4_rule2.public_port = 9051; IPADBG("%s():\n",__FUNCTION__); if(sep) { ret = ipa_nat_add_ipv4_tbl(pub_ip_add, total_entries, &tbl_hdl); CHECK_ERR(ret); } ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule1, &rule_hdl1); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule2, &rule_hdl2); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl1); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl2); CHECK_ERR(ret); if(sep) { ret = ipa_nat_del_ipv4_tbl(tbl_hdl); CHECK_ERR(ret); } return 0; } ================================================ FILE: data-ipa-cfg-mgr/ipanat/test/ipa_nat_test011.c ================================================ /* * Copyright (c) 2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*=========================================================================*/ /*! @file ipa_nat_test011.cpp @brief Verify the following scenario: 1. Add ipv4 table 2. add 3 distinct ipv4 rules 3. delete second, first followed by last 4. Delete ipv4 table */ /*=========================================================================*/ #include "ipa_nat_test.h" #include "ipa_nat_drv.h" int ipa_nat_test011(int total_entries, u32 tbl_hdl, u8 sep) { int ret; u32 rule_hdl, rule_hdl1, rule_hdl2; ipa_nat_ipv4_rule ipv4_rule, ipv4_rule1, ipv4_rule2; u32 pub_ip_add = 0x011617c0; /* "192.23.22.1" */ ipv4_rule.target_ip = 0xC1171601; /* 193.23.22.1 */ ipv4_rule.target_port = 1234; ipv4_rule.private_ip = 0xC2171601; /* 194.23.22.1 */ ipv4_rule.private_port = 5678; ipv4_rule.protocol = IPPROTO_TCP; ipv4_rule.public_port = 9050; ipv4_rule1.target_ip = 0xF1181601; ipv4_rule1.target_port = 1555; ipv4_rule1.private_ip = 0xF2151601; ipv4_rule1.private_port = 5999; ipv4_rule1.protocol = IPPROTO_TCP; ipv4_rule1.public_port = 9111; ipv4_rule2.target_ip = 0xC1166602; ipv4_rule2.target_port = 1555; ipv4_rule2.private_ip = 0xC2155602; ipv4_rule2.private_port = 5777; ipv4_rule2.protocol = IPPROTO_TCP; ipv4_rule2.public_port = 9000; IPADBG("%s():\n",__FUNCTION__); if(sep) { ret = ipa_nat_add_ipv4_tbl(pub_ip_add, total_entries, &tbl_hdl); CHECK_ERR(ret); } ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule1, &rule_hdl1); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule2, &rule_hdl2); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl1); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl2); CHECK_ERR(ret); if(sep) { ret = ipa_nat_del_ipv4_tbl(tbl_hdl); CHECK_ERR(ret); } return 0; } ================================================ FILE: data-ipa-cfg-mgr/ipanat/test/ipa_nat_test012.c ================================================ /* * Copyright (c) 2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*=========================================================================*/ /*! @file ipa_nat_test012.cpp @brief Verify the following scenario: 1. Add ipv4 table 2. add 3 distinct ipv4 rules 3. Delete third, second, first 4. Delete ipv4 table */ /*=========================================================================*/ #include "ipa_nat_test.h" #include "ipa_nat_drv.h" int ipa_nat_test012(int totoal_entries, u32 tbl_hdl, u8 sep) { int ret; u32 rule_hdl, rule_hdl1, rule_hdl2; ipa_nat_ipv4_rule ipv4_rule, ipv4_rule1, ipv4_rule2; u32 pub_ip_add = 0x011617c0; /* "192.23.22.1" */ ipv4_rule.target_ip = 0xC1171601; /* 193.23.22.1 */ ipv4_rule.target_port = 1234; ipv4_rule.private_ip = 0xC2171601; /* 194.23.22.1 */ ipv4_rule.private_port = 5678; ipv4_rule.protocol = IPPROTO_TCP; ipv4_rule.public_port = 9050; ipv4_rule1.target_ip = 0xD1171601; ipv4_rule1.target_port = 3512; ipv4_rule1.private_ip = 0xD2471601; ipv4_rule1.private_port = 9997; ipv4_rule1.protocol = IPPROTO_TCP; ipv4_rule1.public_port = 8881; ipv4_rule2.target_ip = 0xC1172452; ipv4_rule2.target_port = 1895; ipv4_rule2.private_ip = 0xC2172452; ipv4_rule2.private_port = 6668; ipv4_rule2.protocol = IPPROTO_TCP; ipv4_rule2.public_port = 5551; IPADBG("%s():\n",__FUNCTION__); if(sep) { ret = ipa_nat_add_ipv4_tbl(pub_ip_add, totoal_entries, &tbl_hdl); CHECK_ERR(ret); } ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule1, &rule_hdl1); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule2, &rule_hdl2); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl2); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl1); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl); CHECK_ERR(ret); if(sep) { ret = ipa_nat_del_ipv4_tbl(tbl_hdl); CHECK_ERR(ret); } return 0; } ================================================ FILE: data-ipa-cfg-mgr/ipanat/test/ipa_nat_test013.c ================================================ /* * Copyright (c) 2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*=========================================================================*/ /*! @file ipa_nat_test013.cpp @brief Verify the following scenario: 1. Add ipv4 table 2. add 3 distinct ipv4 rules 3. Delete third, first and second 4. Delete ipv4 table */ /*=========================================================================*/ #include "ipa_nat_test.h" #include "ipa_nat_drv.h" int ipa_nat_test013(int total_entries, u32 tbl_hdl, u8 sep) { int ret; u32 rule_hdl, rule_hdl1, rule_hdl2; ipa_nat_ipv4_rule ipv4_rule, ipv4_rule1, ipv4_rule2; u32 pub_ip_add = 0x011617c0; /* "192.23.22.1" */ ipv4_rule.target_ip = 0xC1171601; /* 193.23.22.1 */ ipv4_rule.target_port = 1234; ipv4_rule.private_ip = 0xC2171601; /* 194.23.22.1 */ ipv4_rule.private_port = 5678; ipv4_rule.protocol = IPPROTO_TCP; ipv4_rule.public_port = 9050; ipv4_rule1.target_ip = 0xC1171609; /* 193.23.22.9 */ ipv4_rule1.target_port = 1235; ipv4_rule1.private_ip = 0xC2171609; /* 194.23.22.9 */ ipv4_rule1.private_port = 6579; ipv4_rule1.protocol = IPPROTO_TCP; ipv4_rule1.public_port = 8951; ipv4_rule2.target_ip = 0xC1171606; /* 193.23.22.6 */ ipv4_rule2.target_port = 1235; ipv4_rule2.private_ip = 0xC2171606; /* 194.23.22.6 */ ipv4_rule2.private_port = 7956; ipv4_rule2.protocol = IPPROTO_TCP; ipv4_rule2.public_port = 5109; IPADBG("%s():\n",__FUNCTION__); if(sep) { ret = ipa_nat_add_ipv4_tbl(pub_ip_add, total_entries, &tbl_hdl); CHECK_ERR(ret); } ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule1, &rule_hdl1); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule2, &rule_hdl2); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl2); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl1); CHECK_ERR(ret); if(sep) { ret = ipa_nat_del_ipv4_tbl(tbl_hdl); CHECK_ERR(ret); } return 0; } ================================================ FILE: data-ipa-cfg-mgr/ipanat/test/ipa_nat_test014.c ================================================ /* * Copyright (c) 2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*=========================================================================*/ /*! @file ipa_nat_test014.cpp @brief Verify the following scenario: 1. Add ipv4 table 2. add same 3 ipv rules 3. delete first, second and third 4. Delete ipv4 table */ /*=========================================================================*/ #include "ipa_nat_test.h" #include "ipa_nat_drv.h" int ipa_nat_test014(int total_entries, u32 tbl_hdl, u8 sep) { int ret; u32 rule_hdl1, rule_hdl2, rule_hdl3; ipa_nat_ipv4_rule ipv4_rule; u32 pub_ip_add = 0x011617c0; /* "192.23.22.1" */ ipv4_rule.target_ip = 0xC1171601; /* 193.23.22.1 */ ipv4_rule.target_port = 1234; ipv4_rule.private_ip = 0xC2171601; /* 194.23.22.1 */ ipv4_rule.private_port = 5678; ipv4_rule.protocol = IPPROTO_TCP; ipv4_rule.public_port = 9050; IPADBG("%s()\n", __FUNCTION__); if(sep) { ret = ipa_nat_add_ipv4_tbl(pub_ip_add, total_entries, &tbl_hdl); CHECK_ERR(ret); } ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl1); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl2); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl3); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl1); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl2); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl3); CHECK_ERR(ret); if(sep) { ret = ipa_nat_del_ipv4_tbl(tbl_hdl); CHECK_ERR(ret); } return 0; } ================================================ FILE: data-ipa-cfg-mgr/ipanat/test/ipa_nat_test015.c ================================================ /* * Copyright (c) 2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*=========================================================================*/ /*! @file ipa_nat_test015.cpp @brief Verify the following scenario: 1. Add ipv4 table 2. add same 3 ipv rules 3. delete first, third and second 4. Delete ipv4 table */ /*=========================================================================*/ #include "ipa_nat_test.h" #include "ipa_nat_drv.h" int ipa_nat_test015(int total_entries, u32 tbl_hdl, u8 sep) { int ret; u32 rule_hdl1, rule_hdl2, rule_hdl3; ipa_nat_ipv4_rule ipv4_rule; u32 pub_ip_add = 0x011617c0; /* "192.23.22.1" */ ipv4_rule.target_ip = 0xC1171601; /* 193.23.22.1 */ ipv4_rule.target_port = 1234; ipv4_rule.private_ip = 0xC2171601; /* 194.23.22.1 */ ipv4_rule.private_port = 5678; ipv4_rule.protocol = IPPROTO_TCP; ipv4_rule.public_port = 9050; IPADBG("%s():\n",__FUNCTION__); if(sep) { ret = ipa_nat_add_ipv4_tbl(pub_ip_add, total_entries, &tbl_hdl); CHECK_ERR(ret); } ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl1); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl2); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl3); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl1); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl3); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl2); CHECK_ERR(ret); if(sep) { ret = ipa_nat_del_ipv4_tbl(tbl_hdl); CHECK_ERR(ret); } return 0; } ================================================ FILE: data-ipa-cfg-mgr/ipanat/test/ipa_nat_test016.c ================================================ /* * Copyright (c) 2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*=========================================================================*/ /*! @file ipa_nat_test016.cpp @brief Verify the following scenario: 1. Add ipv4 table 2. add same 3 ipv rules 3. delete second, first and third 4. Delete ipv4 table */ /*=========================================================================*/ #include "ipa_nat_test.h" #include "ipa_nat_drv.h" int ipa_nat_test016(int total_entries, u32 tbl_hdl, u8 sep) { int ret; u32 rule_hdl1, rule_hdl2, rule_hdl3; ipa_nat_ipv4_rule ipv4_rule; u32 pub_ip_add = 0x011617c0; /* "192.23.22.1" */ ipv4_rule.target_ip = 0xC1171601; /* 193.23.22.1 */ ipv4_rule.target_port = 1234; ipv4_rule.private_ip = 0xC2171601; /* 194.23.22.1 */ ipv4_rule.private_port = 5678; ipv4_rule.protocol = IPPROTO_TCP; ipv4_rule.public_port = 9050; IPADBG("%s():\n",__FUNCTION__); if(sep) { ret = ipa_nat_add_ipv4_tbl(pub_ip_add, total_entries, &tbl_hdl); CHECK_ERR(ret); } ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl1); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl2); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl3); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl2); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl1); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl3); CHECK_ERR(ret); if(sep) { ret = ipa_nat_del_ipv4_tbl(tbl_hdl); CHECK_ERR(ret); } return 0; } ================================================ FILE: data-ipa-cfg-mgr/ipanat/test/ipa_nat_test017.c ================================================ /* * Copyright (c) 2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*=========================================================================*/ /*! @file ipa_nat_test017.cpp @brief Verify the following scenario: 1. Add ipv4 table 2. add same 3 ipv rules 3. delete second, third and first 4. Delete ipv4 table */ /*=========================================================================*/ #include "ipa_nat_test.h" #include "ipa_nat_drv.h" int ipa_nat_test017(int total_entries, u32 tbl_hdl, u8 sep) { int ret; u32 rule_hdl1, rule_hdl2, rule_hdl3; ipa_nat_ipv4_rule ipv4_rule; u32 pub_ip_add = 0x011617c0; /* "192.23.22.1" */ ipv4_rule.target_ip = 0xC1171601; /* 193.23.22.1 */ ipv4_rule.target_port = 1234; ipv4_rule.private_ip = 0xC2171601; /* 194.23.22.1 */ ipv4_rule.private_port = 5678; ipv4_rule.protocol = IPPROTO_TCP; ipv4_rule.public_port = 9050; IPADBG("%s():\n",__FUNCTION__); if(sep) { ret = ipa_nat_add_ipv4_tbl(pub_ip_add, total_entries, &tbl_hdl); CHECK_ERR(ret); } ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl1); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl2); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl3); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl2); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl3); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl1); CHECK_ERR(ret); if(sep) { ret = ipa_nat_del_ipv4_tbl(tbl_hdl); CHECK_ERR(ret); } return 0; } ================================================ FILE: data-ipa-cfg-mgr/ipanat/test/ipa_nat_test018.c ================================================ /* * Copyright (c) 2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*=========================================================================*/ /*! @file ipa_nat_test018.c @brief Verify the following scenario: 1. Add ipv4 table 2. add same 3 ipv rules 3. delete third, second and first 4. Delete ipv4 table */ /*=========================================================================*/ #include "ipa_nat_test.h" #include "ipa_nat_drv.h" int ipa_nat_test018(int total_entries, u32 tbl_hdl, u8 sep) { int ret; u32 rule_hdl1, rule_hdl2, rule_hdl3; ipa_nat_ipv4_rule ipv4_rule; u32 pub_ip_add = 0x011617c0; /* "192.23.22.1" */ ipv4_rule.target_ip = 0xC1171601; /* 193.23.22.1 */ ipv4_rule.target_port = 1234; ipv4_rule.private_ip = 0xC2171601; /* 194.23.22.1 */ ipv4_rule.private_port = 5678; ipv4_rule.protocol = IPPROTO_TCP; ipv4_rule.public_port = 9050; IPADBG("%s():\n",__FUNCTION__); if(sep) { ret = ipa_nat_add_ipv4_tbl(pub_ip_add, total_entries, &tbl_hdl); CHECK_ERR(ret); } ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl1); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl2); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl3); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl3); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl2); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl1); CHECK_ERR(ret); if(sep) { ret = ipa_nat_del_ipv4_tbl(tbl_hdl); CHECK_ERR(ret); } return 0; } ================================================ FILE: data-ipa-cfg-mgr/ipanat/test/ipa_nat_test019.c ================================================ /* * Copyright (c) 2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*=========================================================================*/ /*! @file ipa_nat_test019.c @brief Verify the following scenario: 1. Add ipv4 table 2. add same 3 ipv rules 3. delete third, first and second 4. Delete ipv4 table */ /*=========================================================================*/ #include "ipa_nat_test.h" #include "ipa_nat_drv.h" int ipa_nat_test019(int total_entries, u32 tbl_hdl, u8 sep) { int ret; u32 rule_hdl1, rule_hdl2, rule_hdl3; ipa_nat_ipv4_rule ipv4_rule; u32 pub_ip_add = 0x011617c0; /* "192.23.22.1" */ ipv4_rule.target_ip = 0xC1171601; /* 193.23.22.1 */ ipv4_rule.target_port = 1234; ipv4_rule.private_ip = 0xC2171601; /* 194.23.22.1 */ ipv4_rule.private_port = 5678; ipv4_rule.protocol = IPPROTO_TCP; ipv4_rule.public_port = 9050; IPADBG("%s():\n",__FUNCTION__); if(sep) { ret = ipa_nat_add_ipv4_tbl(pub_ip_add, total_entries, &tbl_hdl); CHECK_ERR(ret); } ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl1); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl2); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl3); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl3); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl1); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl2); CHECK_ERR(ret); if(sep) { ret = ipa_nat_del_ipv4_tbl(tbl_hdl); CHECK_ERR(ret); } return 0; } ================================================ FILE: data-ipa-cfg-mgr/ipanat/test/ipa_nat_test020.c ================================================ /* * Copyright (c) 2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*=========================================================================*/ /*! @file ipa_nat_test020.c @brief Verify the following scenario: 1. Add ipv4 table 2. add same 4 ipv rules 3. delete third, second, fourth and first 4. Delete ipv4 table */ /*=========================================================================*/ #include "ipa_nat_test.h" #include "ipa_nat_drv.h" int ipa_nat_test020(int total_entries, u32 tbl_hdl, u8 sep) { int ret; u32 rule_hdl1, rule_hdl2, rule_hdl3, rule_hdl4; ipa_nat_ipv4_rule ipv4_rule; u32 pub_ip_add = 0x011617c0; /* "192.23.22.1" */ ipv4_rule.target_ip = 0xC1171601; /* 193.23.22.1 */ ipv4_rule.target_port = 1234; ipv4_rule.private_ip = 0xC2171601; /* 194.23.22.1 */ ipv4_rule.private_port = 5678; ipv4_rule.protocol = IPPROTO_TCP; ipv4_rule.public_port = 9050; IPADBG("%s():\n",__FUNCTION__); if(sep) { ret = ipa_nat_add_ipv4_tbl(pub_ip_add, total_entries, &tbl_hdl); CHECK_ERR(ret); } ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl1); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl2); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl3); CHECK_ERR(ret); ret = ipa_nat_add_ipv4_rule(tbl_hdl, &ipv4_rule, &rule_hdl4); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl3); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl2); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl4); CHECK_ERR(ret); ret = ipa_nat_del_ipv4_rule(tbl_hdl, rule_hdl1); CHECK_ERR(ret); if(sep) { ret = ipa_nat_del_ipv4_tbl(tbl_hdl); CHECK_ERR(ret); } return 0; } ================================================ FILE: data-ipa-cfg-mgr/ipanat/test/ipa_nat_test021.c ================================================ /* * Copyright (c) 2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*=========================================================================*/ /*! @file ipa_nat_test021.c @brief Verify the following scenario: 1. Add ipv4 table 2. Delete ipv4 table */ /*=========================================================================*/ #include "ipa_nat_test.h" #include "ipa_nat_drv.h" int ipa_nat_test021(int total_entries, int reg) { int ret, i; u32 tbl_hdl; u32 pub_ip_add = 0x011617c0; /* "192.23.22.1" */ IPADBG("%s():\n",__FUNCTION__); for(i=0; i #include #include #include #include #include #include "ipa_nat_drv.h" #include "ipa_nat_drvi.h" #include "ipa_nat_test.h" extern struct ipa_nat_cache ipv4_nat_cache; int chk_for_loop(u32 tbl_hdl) { struct ipa_nat_rule *tbl_ptr; struct ipa_nat_indx_tbl_rule *indx_tbl_ptr; int cnt; uint16_t cur_entry; if (IPA_NAT_INVALID_NAT_ENTRY == tbl_hdl || tbl_hdl > IPA_NAT_MAX_IP4_TBLS) { IPAERR("invalid table handle passed \n"); return -EINVAL; } IPADBG("checking ipv4 rules:\n"); tbl_ptr = (struct ipa_nat_rule *) ipv4_nat_cache.ip4_tbl[tbl_hdl-1].ipv4_rules_addr; for (cnt = 0; cnt < ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries; cnt++) { if (Read16BitFieldValue(tbl_ptr[cnt].ip_cksm_enbl,ENABLE_FIELD)) { if(Read16BitFieldValue(tbl_ptr[cnt].nxt_indx_pub_port, NEXT_INDEX_FIELD) == cnt) { IPAERR("Infinite loop detected, entry\n"); ipa_nati_print_rule(&tbl_ptr[cnt], cnt); return -EINVAL; } } } /* Print ipv4 expansion rules */ IPADBG("checking ipv4 active expansion rules:\n"); tbl_ptr = (struct ipa_nat_rule *) ipv4_nat_cache.ip4_tbl[tbl_hdl-1].ipv4_expn_rules_addr; for (cnt = 0; cnt <= ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].expn_table_entries; cnt++) { if (Read16BitFieldValue(tbl_ptr[cnt].ip_cksm_enbl, ENABLE_FIELD)) { cur_entry = cnt + ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries; if (Read16BitFieldValue(tbl_ptr[cnt].nxt_indx_pub_port, NEXT_INDEX_FIELD) == cur_entry) { IPAERR("Infinite loop detected\n"); ipa_nati_print_rule(&tbl_ptr[cnt], (cnt + ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries)); return -EINVAL; } } } /* Print ipv4 index rules */ IPADBG("checking ipv4 index active rules: \n"); indx_tbl_ptr = (struct ipa_nat_indx_tbl_rule *) ipv4_nat_cache.ip4_tbl[tbl_hdl-1].index_table_addr; for (cnt = 0; cnt < ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries; cnt++) { if (Read16BitFieldValue(indx_tbl_ptr[cnt].tbl_entry_nxt_indx, INDX_TBL_TBL_ENTRY_FIELD)) { if (Read16BitFieldValue(indx_tbl_ptr[cnt].tbl_entry_nxt_indx, INDX_TBL_NEXT_INDEX_FILED) == cnt) { IPAERR("Infinite loop detected\n"); ipa_nati_print_index_rule(&indx_tbl_ptr[cnt], cnt, 0); return -EINVAL; } } } /* Print ipv4 index expansion rules */ IPADBG("Checking ipv4 index expansion active rules: \n"); indx_tbl_ptr = (struct ipa_nat_indx_tbl_rule *) ipv4_nat_cache.ip4_tbl[tbl_hdl-1].index_table_expn_addr; for (cnt = 0; cnt <= ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].expn_table_entries; cnt++) { if (Read16BitFieldValue(indx_tbl_ptr[cnt].tbl_entry_nxt_indx, INDX_TBL_TBL_ENTRY_FIELD)) { cur_entry = cnt + ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries; if (Read16BitFieldValue(indx_tbl_ptr[cnt].tbl_entry_nxt_indx, INDX_TBL_NEXT_INDEX_FILED) == cur_entry) { IPAERR("Infinite loop detected\n"); ipa_nati_print_index_rule(&indx_tbl_ptr[cnt], (cnt + ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries), ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].index_expn_table_meta[cnt].prev_index); return -EINVAL; } } } return 0; } uint8_t is_base_entry_valid(u32 tbl_hdl, u16 entry) { struct ipa_nat_rule *tbl_ptr; if (entry > ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries) { tbl_ptr = (struct ipa_nat_rule *) ipv4_nat_cache.ip4_tbl[tbl_hdl-1].ipv4_expn_rules_addr; entry -= ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries; } else { tbl_ptr = (struct ipa_nat_rule *) ipv4_nat_cache.ip4_tbl[tbl_hdl-1].ipv4_rules_addr; } return (Read16BitFieldValue(tbl_ptr[entry].ip_cksm_enbl, ENABLE_FIELD)); } uint8_t is_index_entry_valid(u32 tbl_hdl, u16 entry) { struct ipa_nat_indx_tbl_rule *tbl_ptr; if (entry > ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries) { tbl_ptr = (struct ipa_nat_indx_tbl_rule *) ipv4_nat_cache.ip4_tbl[tbl_hdl-1].index_table_expn_addr; entry -= ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries; } else { tbl_ptr = (struct ipa_nat_indx_tbl_rule *) ipv4_nat_cache.ip4_tbl[tbl_hdl-1].index_table_addr; } if (Read16BitFieldValue(tbl_ptr[entry].tbl_entry_nxt_indx, INDX_TBL_TBL_ENTRY_FIELD)) { return 1; } else { return 0; } } int chk_for_validity(u32 tbl_hdl) { struct ipa_nat_rule *tbl_ptr; struct ipa_nat_indx_tbl_rule *indx_tbl_ptr; uint16_t nxt_index, prv_index; int cnt; if (IPA_NAT_INVALID_NAT_ENTRY == tbl_hdl || tbl_hdl > IPA_NAT_MAX_IP4_TBLS) { IPAERR("invalid table handle passed \n"); return -EINVAL; } /* Validate base table next_indx and prev_indx values */ IPADBG("Validating ipv4 active rules: \n"); tbl_ptr = (struct ipa_nat_rule *) ipv4_nat_cache.ip4_tbl[tbl_hdl-1].ipv4_rules_addr; for (cnt = 0; cnt < ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries; cnt++) { if (Read16BitFieldValue(tbl_ptr[cnt].ip_cksm_enbl, ENABLE_FIELD)) { nxt_index = Read16BitFieldValue(tbl_ptr[cnt].nxt_indx_pub_port, NEXT_INDEX_FIELD); if (!is_base_entry_valid(tbl_hdl, nxt_index)) { IPAERR("Invalid next index found, entry:%d\n", cnt); } } } IPADBG("Validating ipv4 expansion active rules: \n"); tbl_ptr = (struct ipa_nat_rule *) ipv4_nat_cache.ip4_tbl[tbl_hdl-1].ipv4_expn_rules_addr; for (cnt = 0; cnt <= ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].expn_table_entries; cnt++) { if (Read16BitFieldValue(tbl_ptr[cnt].ip_cksm_enbl, ENABLE_FIELD)) { /* Validate next index */ nxt_index = Read16BitFieldValue(tbl_ptr[cnt].nxt_indx_pub_port, NEXT_INDEX_FIELD); if (!is_base_entry_valid(tbl_hdl, nxt_index)) { IPAERR("Invalid next index found, entry:%d\n", cnt); } /* Validate previous index */ prv_index = Read16BitFieldValue(tbl_ptr[cnt].sw_spec_params, SW_SPEC_PARAM_PREV_INDEX_FIELD); if (!is_base_entry_valid(tbl_hdl, prv_index)) { IPAERR("Invalid Previous index found, entry:%d\n", cnt); } } } IPADBG("Validating ipv4 index active rules: \n"); indx_tbl_ptr = (struct ipa_nat_indx_tbl_rule *) ipv4_nat_cache.ip4_tbl[tbl_hdl-1].index_table_addr; for (cnt = 0; cnt < ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].table_entries; cnt++) { if (Read16BitFieldValue(indx_tbl_ptr[cnt].tbl_entry_nxt_indx, INDX_TBL_TBL_ENTRY_FIELD)) { nxt_index = Read16BitFieldValue(indx_tbl_ptr[cnt].tbl_entry_nxt_indx, INDX_TBL_NEXT_INDEX_FILED); if (!is_index_entry_valid(tbl_hdl, nxt_index)) { IPAERR("Invalid next index found, entry:%d\n", cnt); } } } IPADBG("Validating ipv4 index expansion active rules: \n"); indx_tbl_ptr = (struct ipa_nat_indx_tbl_rule *) ipv4_nat_cache.ip4_tbl[tbl_hdl-1].index_table_expn_addr; for (cnt = 0; cnt <= ipv4_nat_cache.ip4_tbl[tbl_hdl - 1].expn_table_entries; cnt++) { if (Read16BitFieldValue(indx_tbl_ptr[cnt].tbl_entry_nxt_indx, INDX_TBL_TBL_ENTRY_FIELD)) { /* Validate next index*/ nxt_index = Read16BitFieldValue(indx_tbl_ptr[cnt].tbl_entry_nxt_indx, INDX_TBL_NEXT_INDEX_FILED); if (!is_index_entry_valid(tbl_hdl, nxt_index)) { IPAERR("Invalid next index found, entry:%d\n", cnt); } /* Validate previous index*/ prv_index = ipv4_nat_cache.ip4_tbl[tbl_hdl-1].index_expn_table_meta[cnt].prev_index; if (!is_index_entry_valid(tbl_hdl, prv_index)) { IPAERR("Invalid Previous index found, entry:%d\n", cnt); } } } return 0; } int ipa_nat_validate_ipv4_table(u32 tbl_hdl) { int ret = 0; ret = chk_for_loop(tbl_hdl); if (ret) return ret; ret = chk_for_validity(tbl_hdl); return ret; } int main(int argc, char* argv[]) { int exec = 0, pass = 0, ret; int cnt, nt=1; int total_entries = 100; u8 sep = 0; u32 tbl_hdl = 0; u32 pub_ip_add = 0x011617c0; /* "192.23.22.1" */ IPADBG("ipa_nat_testing user space nat driver\n"); if (argc == 4) { if (!strncmp(argv[1], "reg", 3)) { nt = atoi(argv[2]); total_entries = atoi(argv[3]); IPADBG("Reg: %d, Nat Entries: %d\n", nt, total_entries); } else if (!strncmp(argv[1], "sep", 3)) { sep = 1; nt = atoi(argv[2]); total_entries = atoi(argv[3]); } } else if (argc == 3) { if (!strncmp(argv[1], "inotify", 7)) { ipa_nat_test021(total_entries, atoi(argv[2])); return 0; } else if (!strncmp(argv[1], "sep", 3)) { sep = 1; total_entries = atoi(argv[2]); } } else if (argc == 2) { total_entries = atoi(argv[1]); IPADBG("Nat Entries: %d\n", total_entries); } for (cnt=0; cnt= IPA_NAT_TEST_PRE_COND_TE) { IPADBG("\n\nExecuting ipa_nat_test0%d\n", exec); ret = ipa_nat_test010(total_entries, tbl_hdl, sep); if (!ret) { pass++; } else { IPAERR("ipa_nat_test0%d Fail\n", exec); } exec++; IPADBG("\n\nExecuting ipa_nat_test0%d\n", exec); ret = ipa_nat_test011(total_entries, tbl_hdl, sep); if (!ret) { pass++; } else { IPAERR("ipa_nat_test0%d Fail\n", exec); } exec++; IPADBG("\n\nExecuting ipa_nat_test0%d\n", exec); ret = ipa_nat_test012(total_entries, tbl_hdl, sep); if (!ret) { pass++; } else { IPAERR("ipa_nat_test0%d Fail\n", exec); } exec++; IPADBG("\n\nExecuting ipa_nat_test0%d\n", exec); ret = ipa_nat_test013(total_entries, tbl_hdl, sep); if (!ret) { pass++; } else { IPAERR("ipa_nat_test0%d Fail\n", exec); } exec++; IPADBG("\n\nExecuting ipa_nat_test0%d\n", exec); ret = ipa_nat_test014(total_entries, tbl_hdl, sep); if (!ret) { pass++; } else { IPAERR("ipa_nat_test0%d Fail\n", exec); } exec++; IPADBG("\n\nExecuting ipa_nat_test0%d\n", exec); ret = ipa_nat_test015(total_entries, tbl_hdl, sep); if (!ret) { pass++; } else { IPAERR("ipa_nat_test0%d Fail\n", exec); } exec++; IPADBG("\n\nExecuting ipa_nat_test0%d\n", exec); ret = ipa_nat_test016(total_entries, tbl_hdl, sep); if (!ret) { pass++; } else { IPAERR("ipa_nat_test0%d Fail\n", exec); } exec++; IPADBG("\n\nExecuting ipa_nat_test0%d\n", exec); ret = ipa_nat_test017(total_entries, tbl_hdl, sep); if (!ret) { pass++; } else { IPAERR("ipa_nat_test0%d Fail\n", exec); } exec++; IPADBG("\n\nExecuting ipa_nat_test0%d\n", exec); ret = ipa_nat_test018(total_entries, tbl_hdl, sep); if (!ret) { pass++; } else { IPAERR("ipa_nat_test0%d Fail\n", exec); } exec++; IPADBG("\n\nExecuting ipa_nat_test0%d\n", exec); ret = ipa_nat_test019(total_entries, tbl_hdl, sep); if (!ret) { pass++; } else { IPAERR("ipa_nat_test0%d Fail\n", exec); } exec++; IPADBG("\n\nExecuting ipa_nat_test0%d\n", exec); ret = ipa_nat_test020(total_entries, tbl_hdl, sep); if (!ret) { pass++; } else { IPAERR("ipa_nat_test0%d Fail\n", exec); } exec++; IPADBG("\n\nExecuting ipa_nat_test0%d\n", exec); ret = ipa_nat_test022(total_entries, tbl_hdl, sep); if (!ret) { pass++; } else { IPAERR("ipa_nat_test0%d Fail\n", exec); } exec++; } if (!sep) { ret = ipa_nat_del_ipv4_tbl(tbl_hdl); CHECK_ERR(ret); } } /*======= Printing Results ==========*/ IPADBG("Total ipa_nat Tests Run:%d, Pass:%d, Fail:%d\n",exec, pass, exec-pass); return 0; } ================================================ FILE: device.mk ================================================ # # Copyright (C) 2015 The CyanogenMod Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # $(call inherit-product-if-exists, vendor/oneplus/oneplus2/oneplus2-vendor.mk) # Overlays DEVICE_PACKAGE_OVERLAYS += $(LOCAL_PATH)/overlay # Permissions PRODUCT_COPY_FILES += \ external/ant-wireless/antradio-library/com.dsi.ant.antradio_library.xml:system/etc/permissions/com.dsi.ant.antradio_library.xml \ frameworks/native/data/etc/android.hardware.audio.low_latency.xml:system/etc/permissions/android.hardware.audio.low_latency.xml \ frameworks/native/data/etc/android.hardware.bluetooth_le.xml:system/etc/permissions/android.hardware.bluetooth_le.xml \ frameworks/native/data/etc/android.hardware.bluetooth.xml:system/etc/permissions/android.hardware.bluetooth.xml \ frameworks/native/data/etc/android.hardware.camera.flash-autofocus.xml:system/etc/permissions/android.hardware.camera.flash-autofocus.xml \ frameworks/native/data/etc/android.hardware.camera.front.xml:system/etc/permissions/android.hardware.camera.front.xml \ frameworks/native/data/etc/android.hardware.camera.full.xml:system/etc/permissions/android.hardware.camera.full.xml \ frameworks/native/data/etc/android.hardware.camera.raw.xml:system/etc/permissions/android.hardware.camera.raw.xml \ frameworks/native/data/etc/android.hardware.fingerprint.xml:system/etc/permissions/android.hardware.fingerprint.xml \ frameworks/native/data/etc/android.hardware.location.gps.xml:system/etc/permissions/android.hardware.location.gps.xml \ frameworks/native/data/etc/android.hardware.hdmi.cec.xml:system/etc/permissions/android.hardware.hdmi.cec.xml \ frameworks/native/data/etc/android.hardware.opengles.aep.xml:system/etc/permissions/android.hardware.opengles.aep.xml \ frameworks/native/data/etc/android.hardware.sensor.accelerometer.xml:system/etc/permissions/android.hardware.sensor.accelerometer.xml \ frameworks/native/data/etc/android.hardware.sensor.compass.xml:system/etc/permissions/android.hardware.sensor.compass.xml \ frameworks/native/data/etc/android.hardware.sensor.light.xml:system/etc/permissions/android.hardware.sensor.light.xml \ frameworks/native/data/etc/android.hardware.sensor.gyroscope.xml:system/etc/permissions/android.hardware.sensor.gyroscope.xml \ frameworks/native/data/etc/android.hardware.sensor.proximity.xml:system/etc/permissions/android.hardware.sensor.proximity.xml \ frameworks/native/data/etc/android.hardware.sensor.stepcounter.xml:system/etc/permissions/android.hardware.sensor.stepcounter.xml \ frameworks/native/data/etc/android.hardware.sensor.stepdetector.xml:system/etc/permissions/android.hardware.sensor.stepdetector.xml \ frameworks/native/data/etc/android.hardware.telephony.cdma.xml:system/etc/permissions/android.hardware.telephony.cdma.xml \ frameworks/native/data/etc/android.software.sip.voip.xml:system/etc/permissions/android.software.sip.voip.xml \ frameworks/native/data/etc/android.hardware.telephony.gsm.xml:system/etc/permissions/android.hardware.telephony.gsm.xml \ frameworks/native/data/etc/android.hardware.touchscreen.multitouch.jazzhand.xml:system/etc/permissions/android.hardware.touchscreen.multitouch.jazzhand.xml \ frameworks/native/data/etc/android.hardware.usb.accessory.xml:system/etc/permissions/android.hardware.usb.accessory.xml \ frameworks/native/data/etc/android.hardware.usb.host.xml:system/etc/permissions/android.hardware.usb.host.xml \ frameworks/native/data/etc/android.hardware.wifi.xml:system/etc/permissions/android.hardware.wifi.xml \ frameworks/native/data/etc/android.hardware.wifi.direct.xml:system/etc/permissions/android.hardware.wifi.direct.xml \ frameworks/native/data/etc/handheld_core_hardware.xml:system/etc/permissions/handheld_core_hardware.xml \ frameworks/native/data/etc/android.hardware.opengles.aep.xml:system/etc/permissions/android.hardware.opengles.aep.xml \ frameworks/native/data/etc/android.hardware.vr.high_performance.xml:system/etc/permissions/android.hardware.vr.high_performance.xml \ frameworks/native/data/etc/android.hardware.vulkan.level-0.xml:system/etc/permissions/android.hardware.vulkan.level.xml \ frameworks/native/data/etc/android.hardware.vulkan.version-1_0_3.xml:system/etc/permissions/android.hardware.vulkan.version.xml # Device uses high-density artwork where available PRODUCT_AAPT_CONFIG := normal PRODUCT_AAPT_PREF_CONFIG := xxhdpi # Boot animation TARGET_SCREEN_HEIGHT := 1920 TARGET_SCREEN_WIDTH := 1080 $(call inherit-product, frameworks/native/build/phone-xxxhdpi-4096-dalvik-heap.mk) $(call inherit-product, frameworks/native/build/phone-xxxhdpi-4096-hwui-memory.mk) # Haters gonna hate.. PRODUCT_CHARACTERISTICS := nosdcard # Audio PRODUCT_PACKAGES += \ audiod \ audio.a2dp.default \ audio.primary.msm8994 \ audio.r_submix.default \ audio.usb.default \ audio_policy.msm8994 \ libaudio-resampler \ libqcompostprocbundle \ libqcomvisualizer \ libqcomvoiceprocessing \ tinymix PRODUCT_COPY_FILES += \ $(LOCAL_PATH)/audio/aanc_tuning_mixer.txt:system/etc/aanc_tuning_mixer.txt \ $(LOCAL_PATH)/audio/audio_effects.conf:system/vendor/etc/audio_effects.conf \ $(LOCAL_PATH)/audio/audio_output_policy.conf:system/vendor/etc/audio_output_policy.conf \ $(LOCAL_PATH)/audio/audio_platform_info.xml:system/etc/audio_platform_info.xml \ $(LOCAL_PATH)/audio/audio_policy.conf:system/etc/audio_policy.conf \ $(LOCAL_PATH)/audio/listen_platform_info.xml:system/etc/listen_platform_info.xml \ $(LOCAL_PATH)/audio/mixer_paths.xml:system/etc/mixer_paths.xml \ $(LOCAL_PATH)/audio/sound_trigger_mixer_paths.xml:system/etc/sound_trigger_mixer_paths.xml \ $(LOCAL_PATH)/audio/sound_trigger_platform_info.xml:system/etc/sound_trigger_platform_info.xml # ANT+ PRODUCT_PACKAGES += \ AntHalService \ com.dsi.ant.antradio_library \ libantradio # Camera PRODUCT_PACKAGES += \ camera.msm8994 \ libshim_camera \ libshim_ims-camera \ sensors.hal.tof \ Snap # Connectivity Engine support (CNE) PRODUCT_PACKAGES += \ cneapiclient \ com.quicinc.cne \ libcnefeatureconfig \ services-ext # Display PRODUCT_PACKAGES += \ copybit.msm8994 \ gralloc.msm8994 \ hwcomposer.msm8994 \ memtrack.msm8994 \ liboverlay \ libtinyxml # Doze mode PRODUCT_PACKAGES += \ OneplusDoze # Filesystem management tools PRODUCT_PACKAGES += \ e2fsck \ make_ext4fs \ setup_fs # Fingerprint sensor PRODUCT_PACKAGES += \ fingerprintd # For android_filesystem_config.h PRODUCT_PACKAGES += \ fs_config_files # Gello PRODUCT_PACKAGES += \ Gello # GPS PRODUCT_PACKAGES += \ gps.msm8994 \ flp.conf \ gps.conf \ izat.conf \ lowi.conf \ quipc.conf \ sap.conf \ xtwifi.conf # IPv6 PRODUCT_PACKAGES += \ ebtables \ ethertypes # IRQ PRODUCT_COPY_FILES += \ $(LOCAL_PATH)/configs/msm_irqbalance.conf:system/vendor/etc/msm_irqbalance.conf # IRSC PRODUCT_COPY_FILES += \ $(LOCAL_PATH)/configs/sec_config:system/etc/sec_config # Keylayouts PRODUCT_COPY_FILES += \ $(LOCAL_PATH)/keylayout/fpc1020.kl:system/usr/keylayout/fpc1020.kl \ $(LOCAL_PATH)/keylayout/synaptics.kl:system/usr/keylayout/synaptics.kl # Lights PRODUCT_PACKAGES += \ lights.msm8994 # LiveDisplay native PRODUCT_PACKAGES += \ libjni_livedisplay # Media PRODUCT_COPY_FILES += \ $(LOCAL_PATH)/configs/media_codecs.xml:system/etc/media_codecs.xml \ $(LOCAL_PATH)/configs/media_codecs_performance.xml:system/etc/media_codecs_performance.xml \ $(LOCAL_PATH)/configs/media_profiles.xml:system/etc/media_profiles.xml PRODUCT_COPY_FILES += \ frameworks/av/media/libstagefright/data/media_codecs_google_audio.xml:system/etc/media_codecs_google_audio.xml \ frameworks/av/media/libstagefright/data/media_codecs_google_telephony.xml:system/etc/media_codecs_google_telephony.xml \ frameworks/av/media/libstagefright/data/media_codecs_google_video.xml:system/etc/media_codecs_google_video.xml # OMX PRODUCT_PACKAGES += \ libc2dcolorconvert \ libdashplayer \ libdivxdrmdecrypt \ libextmedia_jni \ libOmxAacEnc \ libOmxAmrEnc \ libOmxCore \ libOmxEvrcEnc \ libOmxQcelp13Enc \ libOmxSwVencMpeg4 \ libOmxSwVencHevc \ libOmxVdec \ libOmxVdecHevc \ libOmxVenc \ libOmxVidcCommon \ libstagefrighthw \ libstagefright_soft_flacdec # Power PRODUCT_PACKAGES += \ power.msm8994 # Ramdisk PRODUCT_PACKAGES += \ init.qcom.bt.sh \ init.zram.sh PRODUCT_PACKAGES += \ fstab.qcom \ init.qcom.power.rc \ init.qcom.rc \ init.qcom.sh \ init.qcom.usb.rc \ init.qcom.usb.sh \ ueventd.qcom.rc # RIL PRODUCT_PACKAGES += \ librmnetctl \ libxml2 PRODUCT_PACKAGES += telephony-ext PRODUCT_BOOT_JARS += telephony-ext # Sensors PRODUCT_PACKAGES += \ sensors.msm8994 \ sensors.ssc.wrapper PRODUCT_COPY_FILES += \ $(LOCAL_PATH)/configs/sensors/hals.conf:system/etc/sensors/hals.conf # USB PRODUCT_PACKAGES += \ com.android.future.usb.accessory # VR PRODUCT_PACKAGES += \ vr.msm8994 # MIDI feature PRODUCT_COPY_FILES += \ frameworks/native/data/etc/android.software.midi.xml:system/etc/permissions/android.software.midi.xml # WiFi PRODUCT_PACKAGES += \ ipacm \ ipacm-diag \ IPACM_cfg.xml \ hostapd \ libwpa_client \ wpa_supplicant \ wpa_supplicant.conf PRODUCT_COPY_FILES += \ $(LOCAL_PATH)/wifi/hostapd.accept:system/etc/hostapd/hostapd.accept \ $(LOCAL_PATH)/wifi/hostapd.conf:system/etc/hostapd/hostapd_default.conf \ $(LOCAL_PATH)/wifi/hostapd.deny:system/etc/hostapd/hostapd.deny \ $(LOCAL_PATH)/wifi/p2p_supplicant_overlay.conf:system/etc/wifi/p2p_supplicant_overlay.conf \ $(LOCAL_PATH)/wifi/wpa_supplicant_overlay.conf:system/etc/wifi/wpa_supplicant_overlay.conf PRODUCT_COPY_FILES += \ $(LOCAL_PATH)/wifi/WCNSS_cfg.dat:system/etc/wifi/WCNSS_cfg.dat \ $(LOCAL_PATH)/wifi/WCNSS_qcom_cfg.ini:system/etc/wifi/WCNSS_qcom_cfg.ini # Inherit from oppo-common $(call inherit-product, device/oppo/common/common.mk) ================================================ FILE: doze/Android.mk ================================================ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_PACKAGE_NAME := OneplusDoze LOCAL_CERTIFICATE := platform LOCAL_PRIVILEGED_MODULE := true LOCAL_STATIC_JAVA_LIBRARIES := \ android-support-v4 \ android-support-v13 \ android-support-v7-recyclerview \ android-support-v7-preference \ android-support-v7-appcompat \ android-support-v14-preference \ org.cyanogenmod.platform.internal LOCAL_RESOURCE_DIR := \ $(LOCAL_PATH)/res \ $(LOCAL_PATH)/../../../../packages/resources/devicesettings/res \ frameworks/support/v7/preference/res \ frameworks/support/v14/preference/res \ frameworks/support/v7/appcompat/res \ frameworks/support/v7/recyclerview/res LOCAL_AAPT_FLAGS := --auto-add-overlay \ --extra-packages android.support.v7.preference:android.support.v14.preference:android.support.v17.preference:android.support.v7.appcompat:android.support.v7.recyclerview LOCAL_PROGUARD_FLAG_FILES := proguard.flags include frameworks/base/packages/SettingsLib/common.mk include $(BUILD_PACKAGE) include $(call all-makefiles-under,$(LOCAL_PATH)) ================================================ FILE: doze/AndroidManifest.xml ================================================ ================================================ FILE: doze/proguard.flags ================================================ -keepclasseswithmembers class * { public (android.content.Context, android.util.AttributeSet); } -keep class ** extends android.support.v14.preference.PreferenceFragment -keep class com.cyanogenmod.settings.doze.* { *; } ================================================ FILE: doze/res/drawable/ic_settings_doze.xml ================================================ ================================================ FILE: doze/res/drawable/switchbar_background.xml ================================================ ================================================ FILE: doze/res/layout/doze.xml ================================================ ================================================ FILE: doze/res/layout/switch_bar.xml ================================================ ================================================ FILE: doze/res/values/colors.xml ================================================ #ff37474f #ff7fcac3 #ff37474F ================================================ FILE: doze/res/values/styles.xml ================================================ ================================================ FILE: doze/res/xml/doze_settings.xml ================================================ ================================================ FILE: doze/src/com/cyanogenmod/settings/doze/BootCompletedReceiver.java ================================================ /* * Copyright (c) 2015 The CyanogenMod Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.cyanogenmod.settings.doze; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; public class BootCompletedReceiver extends BroadcastReceiver { private static final boolean DEBUG = false; private static final String TAG = "OneplusDoze"; @Override public void onReceive(final Context context, Intent intent) { if (Utils.isDozeEnabled(context) && Utils.sensorsEnabled(context)) { if (DEBUG) Log.d(TAG, "Starting service"); Utils.startService(context); } } } ================================================ FILE: doze/src/com/cyanogenmod/settings/doze/DozeReceiver.java ================================================ /* * Copyright (C) 2016 The CyanogenMod Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.cyanogenmod.settings.doze; import android.content.Context; import android.content.Intent; import android.util.Log; import cyanogenmod.preference.RemotePreferenceUpdater; public class DozeReceiver extends RemotePreferenceUpdater { private static final boolean DEBUG = false; private static final String TAG = "OneplusDoze"; private static final String DOZE_CATEGORY_KEY = "doze_device_settings"; @Override public void onReceive(Context context, Intent intent) { super.onReceive(context, intent); if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) { if (Utils.isDozeEnabled(context) && Utils.sensorsEnabled(context)) { if (DEBUG) Log.d(TAG, "Starting service"); Utils.startService(context); } } } @Override public String getSummary(Context context, String key) { if (DOZE_CATEGORY_KEY.equals(key)) { return DozeSettingsFragment.getDozeSummary(context); } return null; } static void notifyChanged(Context context) { notifyChanged(context, DOZE_CATEGORY_KEY); } } ================================================ FILE: doze/src/com/cyanogenmod/settings/doze/DozeService.java ================================================ /* * Copyright (c) 2015 The CyanogenMod Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.cyanogenmod.settings.doze; import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.IBinder; import android.util.Log; public class DozeService extends Service { private static final String TAG = "DozeService"; private static final boolean DEBUG = false; private ProximitySensor mProximitySensor; private TiltSensor mTiltSensor; @Override public void onCreate() { if (DEBUG) Log.d(TAG, "Creating service"); mProximitySensor = new ProximitySensor(this); mTiltSensor = new TiltSensor(this); IntentFilter screenStateFilter = new IntentFilter(Intent.ACTION_SCREEN_ON); screenStateFilter.addAction(Intent.ACTION_SCREEN_OFF); registerReceiver(mScreenStateReceiver, screenStateFilter); } @Override public int onStartCommand(Intent intent, int flags, int startId) { if (DEBUG) Log.d(TAG, "Starting service"); return START_STICKY; } @Override public void onDestroy() { if (DEBUG) Log.d(TAG, "Destroying service"); super.onDestroy(); this.unregisterReceiver(mScreenStateReceiver); mProximitySensor.disable(); mTiltSensor.disable(); } @Override public IBinder onBind(Intent intent) { return null; } private void onDisplayOn() { if (DEBUG) Log.d(TAG, "Display on"); if (Utils.pickUpEnabled(this)) { mTiltSensor.disable(); } if (Utils.handwaveGestureEnabled(this) || Utils.pocketGestureEnabled(this)) { mProximitySensor.disable(); } } private void onDisplayOff() { if (DEBUG) Log.d(TAG, "Display off"); if (Utils.pickUpEnabled(this)) { mTiltSensor.enable(); } if (Utils.handwaveGestureEnabled(this) || Utils.pocketGestureEnabled(this)) { mProximitySensor.enable(); } } private BroadcastReceiver mScreenStateReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { onDisplayOn(); } else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { onDisplayOff(); } } }; } ================================================ FILE: doze/src/com/cyanogenmod/settings/doze/DozeSettings.java ================================================ /* * Copyright (C) 2016 The CyanogenMod Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.cyanogenmod.settings.doze; import android.app.Activity; import android.os.Bundle; import android.view.MenuItem; import com.android.settingslib.drawer.SettingsDrawerActivity; /** * Created by shade on 10/14/16. */ public class DozeSettings extends SettingsDrawerActivity { private static final String TAG_DOZE = "doze"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.doze); getFragmentManager().beginTransaction().replace(R.id.content_frame, new DozeSettingsFragment(), TAG_DOZE).commit(); } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == android.R.id.home) { onBackPressed(); return true; } return false; } } ================================================ FILE: doze/src/com/cyanogenmod/settings/doze/DozeSettingsFragment.java ================================================ /* * Copyright (C) 2015 The CyanogenMod Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.cyanogenmod.settings.doze; import android.app.ActionBar; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.app.DialogFragment; import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; import android.database.ContentObserver; import android.os.Bundle; import android.os.Handler; import android.support.v14.preference.PreferenceFragment; import android.support.v14.preference.SwitchPreference; import android.support.v7.preference.Preference; import android.support.v7.preference.Preference.OnPreferenceChangeListener; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.CompoundButton; import android.widget.Switch; public class DozeSettingsFragment extends PreferenceFragment implements OnPreferenceChangeListener, CompoundButton.OnCheckedChangeListener { private SharedPreferences mPreferences; private Switch mSwitch; private SwitchPreference mPickUpPreference; private SwitchPreference mHandwavePreference; private SwitchPreference mPocketPreference; private ContentObserver mDozeObserver = new ContentObserver(new Handler()) { @Override public void onChange(boolean selfChange) { super.onChange(selfChange); boolean enabled = Utils.isDozeEnabled(getActivity()); updateSwitches(Utils.isDozeEnabled(getActivity())); DozeReceiver.notifyChanged(getActivity()); } }; static String getDozeSummary(Context context) { if (Utils.isDozeEnabled(context)) { return context.getString(R.string.ambient_display_summary_on); } return context.getString(R.string.ambient_display_summary_off); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); getActivity().getActionBar().setDisplayHomeAsUpEnabled(true); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final View view = LayoutInflater.from(getContext()).inflate(R.layout.doze, container, false); ((ViewGroup) view).addView(super.onCreateView(inflater, container, savedInstanceState)); return view; } @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { addPreferencesFromResource(R.xml.doze_settings); // get shared preference mPreferences = getActivity().getSharedPreferences("doze_settings", Activity.MODE_PRIVATE); if (savedInstanceState == null && !mPreferences.getBoolean("first_help_shown", false)) { showHelp(); } mPickUpPreference = (SwitchPreference) findPreference(Utils.GESTURE_PICK_UP_KEY); mPickUpPreference.setOnPreferenceChangeListener(this); mHandwavePreference = (SwitchPreference) findPreference(Utils.GESTURE_HAND_WAVE_KEY); mHandwavePreference.setOnPreferenceChangeListener(this); mPocketPreference = (SwitchPreference) findPreference(Utils.GESTURE_POCKET_KEY); mPocketPreference.setOnPreferenceChangeListener(this); } @Override public void onResume() { super.onResume(); getActivity().getContentResolver().registerContentObserver( Utils.DOZE_ENABLED_URI, false, mDozeObserver); updateSwitches(Utils.isDozeEnabled(getActivity())); } @Override public void onPause() { super.onPause(); getActivity().getContentResolver().unregisterContentObserver(mDozeObserver); } private void updateSwitches(boolean enabled) { mPickUpPreference.setEnabled(enabled); mHandwavePreference.setEnabled(enabled); mPocketPreference.setEnabled(enabled); } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); View switchBar = view.findViewById(R.id.switch_bar); mSwitch = (Switch) switchBar.findViewById(android.R.id.switch_widget); mSwitch.setChecked(Utils.isDozeEnabled(getActivity())); mSwitch.setOnCheckedChangeListener(this); switchBar.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mSwitch.setChecked(!mSwitch.isChecked()); } }); } @Override public boolean onPreferenceChange(Preference preference, Object newValue) { final String key = preference.getKey(); final boolean value = (Boolean) newValue; if (Utils.GESTURE_PICK_UP_KEY.equals(key)) { mPickUpPreference.setChecked(value); } else if (Utils.GESTURE_HAND_WAVE_KEY.equals(key)) { mHandwavePreference.setChecked(value); } else if (Utils.GESTURE_POCKET_KEY.equals(key)) { mPocketPreference.setChecked(value); } else { return false; } Utils.startService(getActivity()); return true; } @Override public void onCheckedChanged(CompoundButton compoundButton, boolean b) { Utils.enableDoze(b, getActivity()); } public static class HelpDialogFragment extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { return new AlertDialog.Builder(getActivity()) .setTitle(R.string.doze_settings_help_title) .setMessage(R.string.doze_settings_help_text) .setNegativeButton(R.string.dialog_ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.cancel(); } }) .create(); } @Override public void onCancel(DialogInterface dialog) { getActivity().getSharedPreferences("doze_settings", Activity.MODE_PRIVATE) .edit() .putBoolean("first_help_shown", true) .commit(); } } private void showHelp() { HelpDialogFragment fragment = new HelpDialogFragment(); fragment.show(getFragmentManager(), "help_dialog"); } } ================================================ FILE: doze/src/com/cyanogenmod/settings/doze/ProximitySensor.java ================================================ /* * Copyright (c) 2015 The CyanogenMod Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.cyanogenmod.settings.doze; import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.util.Log; public class ProximitySensor implements SensorEventListener { private static final boolean DEBUG = false; private static final String TAG = "ProximitySensor"; private static final int POCKET_DELTA_NS = 1000 * 1000 * 1000; private SensorManager mSensorManager; private Sensor mSensor; private Context mContext; private boolean mSawNear = false; private long mInPocketTime = 0; public ProximitySensor(Context context) { mContext = context; mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE); mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); } @Override public void onSensorChanged(SensorEvent event) { boolean isNear = event.values[0] < mSensor.getMaximumRange(); if (mSawNear && !isNear) { if (shouldPulse(event.timestamp)) { Utils.launchDozePulse(mContext); } } else { mInPocketTime = event.timestamp; } mSawNear = isNear; } private boolean shouldPulse(long timestamp) { long delta = timestamp - mInPocketTime; if (Utils.handwaveGestureEnabled(mContext) && Utils.pocketGestureEnabled(mContext)) { return true; } else if (Utils.handwaveGestureEnabled(mContext) && !Utils.pocketGestureEnabled(mContext)) { return delta < POCKET_DELTA_NS; } else if (!Utils.handwaveGestureEnabled(mContext) && Utils.pocketGestureEnabled(mContext)) { return delta >= POCKET_DELTA_NS; } return false; } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { /* Empty */ } protected void enable() { if (DEBUG) Log.d(TAG, "Enabling"); mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL); } protected void disable() { if (DEBUG) Log.d(TAG, "Disabling"); mSensorManager.unregisterListener(this, mSensor); } } ================================================ FILE: doze/src/com/cyanogenmod/settings/doze/TiltSensor.java ================================================ /* * Copyright (c) 2015 The CyanogenMod Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.cyanogenmod.settings.doze; import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.PowerManager; import android.os.PowerManager.WakeLock; import android.os.SystemClock; import android.util.Log; public class TiltSensor implements SensorEventListener { private static final boolean DEBUG = false; private static final String TAG = "TiltSensor"; private static final int SENSOR_WAKELOCK_DURATION = 200; private static final int BATCH_LATENCY_IN_MS = 100; private static final int MIN_PULSE_INTERVAL_MS = 2500; private PowerManager mPowerManager; private SensorManager mSensorManager; private Sensor mSensor; private WakeLock mSensorWakeLock; private Context mContext; private long mEntryTimestamp; public TiltSensor(Context context) { mContext = context; mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE); mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_TILT_DETECTOR); mSensorWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SensorWakeLock"); } @Override public void onSensorChanged(SensorEvent event) { if (DEBUG) Log.d(TAG, "Got sensor event: " + event.values[0]); long delta = SystemClock.elapsedRealtime() - mEntryTimestamp; if (delta < MIN_PULSE_INTERVAL_MS) { return; } else { mEntryTimestamp = SystemClock.elapsedRealtime(); } if (event.values[0] == 1) { Utils.launchDozePulse(mContext); } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { /* Empty */ } protected void enable() { if (DEBUG) Log.d(TAG, "Enabling"); mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL, BATCH_LATENCY_IN_MS * 1000); mEntryTimestamp = SystemClock.elapsedRealtime(); } protected void disable() { if (DEBUG) Log.d(TAG, "Disabling"); mSensorManager.unregisterListener(this, mSensor); } } ================================================ FILE: doze/src/com/cyanogenmod/settings/doze/Utils.java ================================================ /* * Copyright (c) 2015 The CyanogenMod Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.cyanogenmod.settings.doze; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.UserHandle; import android.support.v7.preference.PreferenceManager; import android.provider.Settings; import android.util.Log; import static android.provider.Settings.Secure.DOZE_ENABLED; public final class Utils { private static final String TAG = "DozeUtils"; private static final boolean DEBUG = false; private static final String DOZE_INTENT = "com.android.systemui.doze.pulse"; protected static final String AMBIENT_DISPLAY_KEY = "doze_enabled"; protected static final String GESTURE_PICK_UP_KEY = "gesture_pick_up"; protected static final String GESTURE_HAND_WAVE_KEY = "gesture_hand_wave"; protected static final String GESTURE_POCKET_KEY = "gesture_pocket"; public static final Uri DOZE_ENABLED_URI = Settings.Secure.getUriFor(DOZE_ENABLED); protected static void startService(Context context) { if (DEBUG) Log.d(TAG, "Starting service"); context.startService(new Intent(context, DozeService.class)); } protected static void stopService(Context context) { if (DEBUG) Log.d(TAG, "Stopping service"); context.stopService(new Intent(context, DozeService.class)); } protected static boolean isDozeEnabled(Context context) { return Settings.Secure.getInt(context.getContentResolver(), DOZE_ENABLED, 1) != 0; } protected static boolean enableDoze(boolean enable, Context context) { boolean dozeEnabled = Settings.Secure.putInt(context.getContentResolver(), DOZE_ENABLED, enable ? 1 : 0); if (enable) { startService(context); } else { stopService(context); } return dozeEnabled; } protected static void launchDozePulse(Context context) { if (DEBUG) Log.d(TAG, "Launch doze pulse"); context.sendBroadcastAsUser(new Intent(DOZE_INTENT), new UserHandle(UserHandle.USER_CURRENT)); } protected static boolean pickUpEnabled(Context context) { return PreferenceManager.getDefaultSharedPreferences(context) .getBoolean(GESTURE_PICK_UP_KEY, false); } protected static boolean handwaveGestureEnabled(Context context) { return PreferenceManager.getDefaultSharedPreferences(context) .getBoolean(GESTURE_HAND_WAVE_KEY, false); } protected static boolean pocketGestureEnabled(Context context) { return PreferenceManager.getDefaultSharedPreferences(context) .getBoolean(GESTURE_POCKET_KEY, false); } protected static boolean sensorsEnabled(Context context) { return pickUpEnabled(context) || handwaveGestureEnabled(context) || pocketGestureEnabled(context); } } ================================================ FILE: extract-files.sh ================================================ #!/bin/bash # # Copyright (C) 2016 The CyanogenMod Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # set -e DEVICE=oneplus2 VENDOR=oneplus # Load extractutils and do some sanity checks MY_DIR="${BASH_SOURCE%/*}" if [[ ! -d "$MY_DIR" ]]; then MY_DIR="$PWD"; fi CM_ROOT="$MY_DIR"/../../.. HELPER="$CM_ROOT"/vendor/cm/build/tools/extract_utils.sh if [ ! -f "$HELPER" ]; then echo "Unable to find helper script at $HELPER" exit 1 fi . "$HELPER" if [ $# -eq 0 ]; then SRC=adb else if [ $# -eq 1 ]; then SRC=$1 else echo "$0: bad number of arguments" echo "" echo "usage: $0 [PATH_TO_EXPANDED_ROM]" echo "" echo "If PATH_TO_EXPANDED_ROM is not specified, blobs will be extracted from" echo "the device using adb pull." exit 1 fi fi # Initialize the helper setup_vendor "$DEVICE" "$VENDOR" "$CM_ROOT" extract "$MY_DIR"/proprietary-files.txt "$SRC" "$MY_DIR"/setup-makefiles.sh ================================================ FILE: gps/Android.mk ================================================ # # Copyright (C) 2015 The CyanogenMod Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # LOCAL_PATH := $(call my-dir) include $(call all-subdir-makefiles,$(LOCAL_PATH)) ================================================ FILE: gps/CleanSpec.mk ================================================ # Copyright (C) 2007 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # If you don't need to do a full clean build but would like to touch # a file or delete some intermediate files, add a clean step to the end # of the list. These steps will only be run once, if they haven't been # run before. # # E.g.: # $(call add-clean-step, touch -c external/sqlite/sqlite3.h) # $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates) # # Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with # files that are missing or have been moved. # # Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory. # Use $(OUT_DIR) to refer to the "out" directory. # # If you need to re-do something that's already mentioned, just copy # the command and add it to the bottom of the list. E.g., if a change # that you made last week required touching a file and a change you # made today requires touching the same file, just copy the old # touch step and add it to the end of the list. # # ************************************************ # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST # ************************************************ # For example: #$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates) #$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates) #$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f) #$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*) # ************************************************ # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST # ************************************************ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libloc_api*) ================================================ FILE: gps/Makefile.am ================================================ # Makefile.am - Automake script for gps loc_api # ACLOCAL_AMFLAGS = -I m4 SUBDIRS = utils loc_api/libloc_api_50001 loc_api/loc_api_v02 pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = loc-api.pc EXTRA_DIST = $(pkgconfig_DATA) ================================================ FILE: gps/configure.ac ================================================ # configure.ac -- Autoconf script for gps loc_api # # Process this file with autoconf to produce a configure script # Requires autoconf tool later than 2.61 AC_PREREQ(2.61) # Initialize the gps loc_api package version 1.0.0 AC_INIT([loc-api],1.0.0) # Does not strictly follow GNU Coding standards AM_INIT_AUTOMAKE([foreign]) # Disables auto rebuilding of configure, Makefile.ins AM_MAINTAINER_MODE # Verifies the --srcdir is correct by checking for the path AC_CONFIG_SRCDIR([utils/loc_cfg.cpp]) # defines some macros variable to be included by source AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) # Checks for programs. AC_PROG_LIBTOOL AC_PROG_CXX AC_PROG_CC AM_PROG_CC_C_O AC_PROG_AWK AC_PROG_CPP AC_PROG_INSTALL AC_PROG_LN_S AC_PROG_MAKE_SET PKG_PROG_PKG_CONFIG # Checks for libraries. PKG_CHECK_MODULES([QMIF], [qmi-framework]) AC_SUBST([QMIF_CFLAGS]) AC_SUBST([QMIF_LIBS]) AC_ARG_WITH([libhardware_includes], AC_HELP_STRING([--with-libhardware-includes=@<:@dir@:>@], [Specify the location of the libhardware headers]), [libhardware_incdir=$withval], with_libhardware_includes=no) if test "x$with_libhardware_includes" != "xno"; then CPPFLAGS="${CPPFLAGS} -I${libhardware_incdir}" fi AC_ARG_WITH([core_includes], AC_HELP_STRING([--with-core-includes=@<:@dir@:>@], [Specify the location of the core headers]), [core_incdir=$withval], with_core_includes=no) if test "x$with_core_includes" != "xno"; then CPPFLAGS="${CPPFLAGS} -I${core_incdir}" fi AC_SUBST([CPPFLAGS]) AC_ARG_WITH([glib], AC_HELP_STRING([--with-glib], [enable glib, building HLOS systems which use glib])) if (test "x${with_glib}" = "xyes"); then AC_DEFINE(ENABLE_USEGLIB, 1, [Define if HLOS systems uses glib]) PKG_CHECK_MODULES(GTHREAD, gthread-2.0 >= 2.16, dummy=yes, AC_MSG_ERROR(GThread >= 2.16 is required)) PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16, dummy=yes, AC_MSG_ERROR(GLib >= 2.16 is required)) GLIB_CFLAGS="$GLIB_CFLAGS $GTHREAD_CFLAGS" GLIB_LIBS="$GLIB_LIBS $GTHREAD_LIBS" AC_SUBST(GLIB_CFLAGS) AC_SUBST(GLIB_LIBS) fi AM_CONDITIONAL(USE_GLIB, test "x${with_glib}" = "xyes") AC_CONFIG_FILES([ \ Makefile \ utils/Makefile \ loc_api/libloc_api_50001/Makefile \ loc_api/loc_api_v02/Makefile \ loc-api.pc \ ]) AC_OUTPUT ================================================ FILE: gps/core/Android.mk ================================================ ifneq ($(BUILD_TINY_ANDROID),true) LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := libloc_core LOCAL_MODULE_OWNER := qcom LOCAL_MODULE_TAGS := optional ifeq ($(TARGET_DEVICE),apq8026_lw) LOCAL_CFLAGS += -DPDK_FEATURE_SET else ifeq ($(BOARD_VENDOR_QCOM_LOC_PDK_FEATURE_SET),true) LOCAL_CFLAGS += -DPDK_FEATURE_SET endif LOCAL_SHARED_LIBRARIES := \ libutils \ libcutils \ libgps.utils \ libdl LOCAL_SRC_FILES += \ LocApiBase.cpp \ LocAdapterBase.cpp \ ContextBase.cpp \ LocDualContext.cpp \ loc_core_log.cpp LOCAL_CFLAGS += \ -fno-short-enums \ -D_ANDROID_ LOCAL_C_INCLUDES:= \ $(TARGET_OUT_HEADERS)/gps.utils \ $(TARGET_OUT_HEADERS)/libflp LOCAL_COPY_HEADERS_TO:= libloc_core/ LOCAL_COPY_HEADERS:= \ LocApiBase.h \ LocAdapterBase.h \ ContextBase.h \ LocDualContext.h \ LBSProxyBase.h \ UlpProxyBase.h \ gps_extended_c.h \ gps_extended.h \ loc_core_log.h \ LocAdapterProxyBase.h \ fused_location_extended.h LOCAL_PRELINK_MODULE := false include $(BUILD_SHARED_LIBRARY) endif # not BUILD_TINY_ANDROID ================================================ FILE: gps/core/ContextBase.cpp ================================================ /* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #define LOG_NDDEBUG 0 #define LOG_TAG "LocSvc_CtxBase" #include #include #include #include #include #include #include #include namespace loc_core { LBSProxyBase* ContextBase::getLBSProxy(const char* libName) { LBSProxyBase* proxy = NULL; LOC_LOGD("%s:%d]: getLBSProxy libname: %s\n", __func__, __LINE__, libName); void* lib = dlopen(libName, RTLD_NOW); if ((void*)NULL != lib) { getLBSProxy_t* getter = (getLBSProxy_t*)dlsym(lib, "getLBSProxy"); if (NULL != getter) { proxy = (*getter)(); } } if (NULL == proxy) { proxy = new LBSProxyBase(); } LOC_LOGD("%s:%d]: Exiting\n", __func__, __LINE__); return proxy; } LocApiBase* ContextBase::createLocApi(LOC_API_ADAPTER_EVENT_MASK_T exMask) { LocApiBase* locApi = NULL; // first if can not be MPQ if (TARGET_MPQ != loc_get_target()) { if (NULL == (locApi = mLBSProxy->getLocApi(mMsgTask, exMask, this))) { void *handle = NULL; //try to see if LocApiV02 is present if((handle = dlopen("libloc_api_v02.so", RTLD_NOW)) != NULL) { LOC_LOGD("%s:%d]: libloc_api_v02.so is present", __func__, __LINE__); getLocApi_t* getter = (getLocApi_t*)dlsym(handle, "getLocApi"); if(getter != NULL) { LOC_LOGD("%s:%d]: getter is not NULL for LocApiV02", __func__, __LINE__); locApi = (*getter)(mMsgTask, exMask, this); } } // only RPC is the option now else { LOC_LOGD("%s:%d]: libloc_api_v02.so is NOT present. Trying RPC", __func__, __LINE__); handle = dlopen("libloc_api-rpc-qc.so", RTLD_NOW); if (NULL != handle) { getLocApi_t* getter = (getLocApi_t*)dlsym(handle, "getLocApi"); if (NULL != getter) { LOC_LOGD("%s:%d]: getter is not NULL in RPC", __func__, __LINE__); locApi = (*getter)(mMsgTask, exMask, this); } } } } } // locApi could still be NULL at this time // we would then create a dummy one if (NULL == locApi) { locApi = new LocApiBase(mMsgTask, exMask, this); } return locApi; } ContextBase::ContextBase(const MsgTask* msgTask, LOC_API_ADAPTER_EVENT_MASK_T exMask, const char* libName) : mLBSProxy(getLBSProxy(libName)), mMsgTask(msgTask), mLocApi(createLocApi(exMask)), mLocApiProxy(mLocApi->getLocApiProxy()) { } } ================================================ FILE: gps/core/ContextBase.h ================================================ /* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef __LOC_CONTEXT_BASE__ #define __LOC_CONTEXT_BASE__ #include #include #include #include #include namespace loc_core { class LocAdapterBase; class ContextBase { static LBSProxyBase* getLBSProxy(const char* libName); LocApiBase* createLocApi(LOC_API_ADAPTER_EVENT_MASK_T excludedMask); protected: const LBSProxyBase* mLBSProxy; const MsgTask* mMsgTask; LocApiBase* mLocApi; LocApiProxyBase *mLocApiProxy; public: ContextBase(const MsgTask* msgTask, LOC_API_ADAPTER_EVENT_MASK_T exMask, const char* libName); inline virtual ~ContextBase() { delete mLocApi; delete mLBSProxy; } inline const MsgTask* getMsgTask() { return mMsgTask; } inline LocApiBase* getLocApi() { return mLocApi; } inline LocApiProxyBase* getLocApiProxy() { return mLocApiProxy; } inline bool hasAgpsExtendedCapabilities() { return mLBSProxy->hasAgpsExtendedCapabilities(); } inline bool hasCPIExtendedCapabilities() { return mLBSProxy->hasCPIExtendedCapabilities(); } inline void modemPowerVote(bool power) const { return mLBSProxy->modemPowerVote(power); } inline void requestUlp(LocAdapterBase* adapter, unsigned long capabilities) { mLBSProxy->requestUlp(adapter, capabilities); } inline IzatDevId_t getIzatDevId() const { return mLBSProxy->getIzatDevId(); } inline void sendMsg(const LocMsg *msg) { getMsgTask()->sendMsg(msg); } }; } // namespace loc_core #endif //__LOC_CONTEXT_BASE__ ================================================ FILE: gps/core/LBSProxyBase.h ================================================ /* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef IZAT_PROXY_BASE_H #define IZAT_PROXY_BASE_H #include #include namespace loc_core { class LocApiBase; class LocAdapterBase; class ContextBase; class LBSProxyBase { friend class ContextBase; inline virtual LocApiBase* getLocApi(const MsgTask* msgTask, LOC_API_ADAPTER_EVENT_MASK_T exMask, ContextBase* context) const { return NULL; } protected: inline LBSProxyBase() {} public: inline virtual ~LBSProxyBase() {} inline virtual void requestUlp(LocAdapterBase* adapter, unsigned long capabilities) const {} inline virtual bool hasAgpsExtendedCapabilities() const { return false; } inline virtual bool hasCPIExtendedCapabilities() const { return false; } inline virtual void modemPowerVote(bool power) const {} virtual void injectFeatureConfig(ContextBase* context) const {} inline virtual IzatDevId_t getIzatDevId() const { return 0; } }; typedef LBSProxyBase* (getLBSProxy_t)(); } // namespace loc_core #endif // IZAT_PROXY_BASE_H ================================================ FILE: gps/core/LocAdapterBase.cpp ================================================ /* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #define LOG_NDDEBUG 0 #define LOG_TAG "LocSvc_LocAdapterBase" #include #include #include #include #include namespace loc_core { // This is the top level class, so the constructor will // always gets called. Here we prepare for the default. // But if getLocApi(targetEnumType target) is overriden, // the right locApi should get created. LocAdapterBase::LocAdapterBase(const LOC_API_ADAPTER_EVENT_MASK_T mask, ContextBase* context, LocAdapterProxyBase *adapterProxyBase) : mEvtMask(mask), mContext(context), mLocApi(context->getLocApi()), mLocAdapterProxyBase(adapterProxyBase), mMsgTask(context->getMsgTask()) { mLocApi->addAdapter(this); } void LocAdapterBase::handleEngineUpEvent() { if (mLocAdapterProxyBase) { mLocAdapterProxyBase->handleEngineUpEvent(); } } void LocAdapterBase::handleEngineDownEvent() { if (mLocAdapterProxyBase) { mLocAdapterProxyBase->handleEngineDownEvent(); } } void LocAdapterBase:: reportPosition(UlpLocation &location, GpsLocationExtended &locationExtended, void* locationExt, enum loc_sess_status status, LocPosTechMask loc_technology_mask) { if (mLocAdapterProxyBase == NULL || !mLocAdapterProxyBase->reportPosition(location, locationExtended, status, loc_technology_mask)) { DEFAULT_IMPL() } } void LocAdapterBase:: reportSv(QcomSvStatus &svStatus, GpsLocationExtended &locationExtended, void* svExt) DEFAULT_IMPL() void LocAdapterBase:: reportStatus(GpsStatusValue status) DEFAULT_IMPL() void LocAdapterBase:: reportNmea(const char* nmea, int length) DEFAULT_IMPL() bool LocAdapterBase:: reportXtraServer(const char* url1, const char* url2, const char* url3, const int maxlength) DEFAULT_IMPL(false) bool LocAdapterBase:: requestXtraData() DEFAULT_IMPL(false) bool LocAdapterBase:: requestTime() DEFAULT_IMPL(false) bool LocAdapterBase:: requestLocation() DEFAULT_IMPL(false) bool LocAdapterBase:: requestATL(int connHandle, AGpsType agps_type) DEFAULT_IMPL(false) bool LocAdapterBase:: releaseATL(int connHandle) DEFAULT_IMPL(false) bool LocAdapterBase:: requestSuplES(int connHandle) DEFAULT_IMPL(false) bool LocAdapterBase:: reportDataCallOpened() DEFAULT_IMPL(false) bool LocAdapterBase:: reportDataCallClosed() DEFAULT_IMPL(false) bool LocAdapterBase:: requestNiNotify(GpsNiNotification ¬ify, const void* data) DEFAULT_IMPL(false) void LocAdapterBase:: reportGpsMeasurementData(GpsData &gpsMeasurementData) DEFAULT_IMPL() } // namespace loc_core ================================================ FILE: gps/core/LocAdapterBase.h ================================================ /* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef LOC_API_ADAPTER_BASE_H #define LOC_API_ADAPTER_BASE_H #include #include #include namespace loc_core { class LocAdapterProxyBase; class LocAdapterBase { protected: LOC_API_ADAPTER_EVENT_MASK_T mEvtMask; ContextBase* mContext; LocApiBase* mLocApi; LocAdapterProxyBase* mLocAdapterProxyBase; const MsgTask* mMsgTask; inline LocAdapterBase(const MsgTask* msgTask) : mEvtMask(0), mContext(NULL), mLocApi(NULL), mLocAdapterProxyBase(NULL), mMsgTask(msgTask) {} public: inline virtual ~LocAdapterBase() { mLocApi->removeAdapter(this); } LocAdapterBase(const LOC_API_ADAPTER_EVENT_MASK_T mask, ContextBase* context, LocAdapterProxyBase *adapterProxyBase = NULL); inline LOC_API_ADAPTER_EVENT_MASK_T checkMask(LOC_API_ADAPTER_EVENT_MASK_T mask) const { return mEvtMask & mask; } inline LOC_API_ADAPTER_EVENT_MASK_T getEvtMask() const { return mEvtMask; } inline void sendMsg(const LocMsg* msg) const { mMsgTask->sendMsg(msg); } inline void sendMsg(const LocMsg* msg) { mMsgTask->sendMsg(msg); } inline void updateEvtMask(LOC_API_ADAPTER_EVENT_MASK_T event, loc_registration_mask_status isEnabled) { mEvtMask = isEnabled == LOC_REGISTRATION_MASK_ENABLED ? (mEvtMask|event):(mEvtMask&~event); mLocApi->updateEvtMask(); } // This will be overridden by the individual adapters // if necessary. inline virtual void setUlpProxy(UlpProxyBase* ulp) {} virtual void handleEngineUpEvent(); virtual void handleEngineDownEvent(); inline virtual void setPositionModeInt(LocPosMode& posMode) {} virtual void startFixInt() {} virtual void stopFixInt() {} virtual void getZppInt() {} virtual void reportPosition(UlpLocation &location, GpsLocationExtended &locationExtended, void* locationExt, enum loc_sess_status status, LocPosTechMask loc_technology_mask); virtual void reportSv(QcomSvStatus &svStatus, GpsLocationExtended &locationExtended, void* svExt); virtual void reportStatus(GpsStatusValue status); virtual void reportNmea(const char* nmea, int length); virtual bool reportXtraServer(const char* url1, const char* url2, const char* url3, const int maxlength); virtual bool requestXtraData(); virtual bool requestTime(); virtual bool requestLocation(); virtual bool requestATL(int connHandle, AGpsType agps_type); virtual bool releaseATL(int connHandle); virtual bool requestSuplES(int connHandle); virtual bool reportDataCallOpened(); virtual bool reportDataCallClosed(); virtual bool requestNiNotify(GpsNiNotification ¬ify, const void* data); inline virtual bool isInSession() { return false; } ContextBase* getContext() const { return mContext; } virtual void reportGpsMeasurementData(GpsData &gpsMeasurementData); }; } // namespace loc_core #endif //LOC_API_ADAPTER_BASE_H ================================================ FILE: gps/core/LocAdapterProxyBase.h ================================================ /* Copyright (c) 2014 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef LOC_ADAPTER_PROXY_BASE_H #define LOC_ADAPTER_PROXY_BASE_H #include #include namespace loc_core { class LocAdapterProxyBase { private: LocAdapterBase *mLocAdapterBase; protected: inline LocAdapterProxyBase(const LOC_API_ADAPTER_EVENT_MASK_T mask, ContextBase* context): mLocAdapterBase(new LocAdapterBase(mask, context, this)) { } inline virtual ~LocAdapterProxyBase() { delete mLocAdapterBase; } ContextBase* getContext() const { return mLocAdapterBase->getContext(); } inline void updateEvtMask(LOC_API_ADAPTER_EVENT_MASK_T event, loc_registration_mask_status isEnabled) { mLocAdapterBase->updateEvtMask(event,isEnabled); } public: inline virtual void handleEngineUpEvent() {}; inline virtual void handleEngineDownEvent() {}; inline virtual bool reportPosition(UlpLocation &location, GpsLocationExtended &locationExtended, enum loc_sess_status status, LocPosTechMask loc_technology_mask) { return false; } }; } // namespace loc_core #endif //LOC_ADAPTER_PROXY_BASE_H ================================================ FILE: gps/core/LocApiBase.cpp ================================================ /* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #define LOG_NDDEBUG 0 #define LOG_TAG "LocSvc_LocApiBase" #include #include #include #include #include namespace loc_core { #define TO_ALL_LOCADAPTERS(call) TO_ALL_ADAPTERS(mLocAdapters, (call)) #define TO_1ST_HANDLING_LOCADAPTERS(call) TO_1ST_HANDLING_ADAPTER(mLocAdapters, (call)) int hexcode(char *hexstring, int string_size, const char *data, int data_size) { int i; for (i = 0; i < data_size; i++) { char ch = data[i]; if (i*2 + 3 <= string_size) { snprintf(&hexstring[i*2], 3, "%02X", ch); } else { break; } } return i; } int decodeAddress(char *addr_string, int string_size, const char *data, int data_size) { const char addr_prefix = 0x91; int i, idxOutput = 0; if (!data || !addr_string) { return 0; } if (data[0] != addr_prefix) { LOC_LOGW("decodeAddress: address prefix is not 0x%x but 0x%x", addr_prefix, data[0]); addr_string[0] = '\0'; return 0; // prefix not correct } for (i = 1; i < data_size; i++) { unsigned char ch = data[i], low = ch & 0x0F, hi = ch >> 4; if (low <= 9 && idxOutput < string_size - 1) { addr_string[idxOutput++] = low + '0'; } if (hi <= 9 && idxOutput < string_size - 1) { addr_string[idxOutput++] = hi + '0'; } } addr_string[idxOutput] = '\0'; // Terminates the string return idxOutput; } struct LocSsrMsg : public LocMsg { LocApiBase* mLocApi; inline LocSsrMsg(LocApiBase* locApi) : LocMsg(), mLocApi(locApi) { locallog(); } inline virtual void proc() const { mLocApi->close(); mLocApi->open(mLocApi->getEvtMask()); } inline void locallog() { LOC_LOGV("LocSsrMsg"); } inline virtual void log() { locallog(); } }; struct LocOpenMsg : public LocMsg { LocApiBase* mLocApi; LOC_API_ADAPTER_EVENT_MASK_T mMask; inline LocOpenMsg(LocApiBase* locApi, LOC_API_ADAPTER_EVENT_MASK_T mask) : LocMsg(), mLocApi(locApi), mMask(mask) { locallog(); } inline virtual void proc() const { mLocApi->open(mMask); } inline void locallog() { LOC_LOGV("%s:%d]: LocOpen Mask: %x\n", __func__, __LINE__, mMask); } inline virtual void log() { locallog(); } }; LocApiBase::LocApiBase(const MsgTask* msgTask, LOC_API_ADAPTER_EVENT_MASK_T excludedMask, ContextBase* context) : mExcludedMask(excludedMask), mMsgTask(msgTask), mMask(0), mSupportedMsg(0), mContext(context) { memset(mLocAdapters, 0, sizeof(mLocAdapters)); } LOC_API_ADAPTER_EVENT_MASK_T LocApiBase::getEvtMask() { LOC_API_ADAPTER_EVENT_MASK_T mask = 0; TO_ALL_LOCADAPTERS(mask |= mLocAdapters[i]->getEvtMask()); return mask & ~mExcludedMask; } bool LocApiBase::isInSession() { bool inSession = false; for (int i = 0; !inSession && i < MAX_ADAPTERS && NULL != mLocAdapters[i]; i++) { inSession = mLocAdapters[i]->isInSession(); } return inSession; } void LocApiBase::addAdapter(LocAdapterBase* adapter) { for (int i = 0; i < MAX_ADAPTERS && mLocAdapters[i] != adapter; i++) { if (mLocAdapters[i] == NULL) { mLocAdapters[i] = adapter; mMsgTask->sendMsg(new LocOpenMsg(this, (adapter->getEvtMask()))); break; } } } void LocApiBase::removeAdapter(LocAdapterBase* adapter) { for (int i = 0; i < MAX_ADAPTERS && NULL != mLocAdapters[i]; i++) { if (mLocAdapters[i] == adapter) { mLocAdapters[i] = NULL; // shift the rest of the adapters up so that the pointers // in the array do not have holes. This should be more // performant, because the array maintenance is much much // less frequent than event handlings, which need to linear // search all the adapters int j = i; while (++i < MAX_ADAPTERS && mLocAdapters[i] != NULL); // i would be MAX_ADAPTERS or point to a NULL i--; // i now should point to a none NULL adapter within valid // range although i could be equal to j, but it won't hurt. // No need to check it, as it gains nothing. mLocAdapters[j] = mLocAdapters[i]; // this makes sure that we exit the for loop mLocAdapters[i] = NULL; // if we have an empty list of adapters if (0 == i) { close(); } else { // else we need to remove the bit mMsgTask->sendMsg(new LocOpenMsg(this, getEvtMask())); } } } } void LocApiBase::updateEvtMask() { mMsgTask->sendMsg(new LocOpenMsg(this, getEvtMask())); } void LocApiBase::handleEngineUpEvent() { // This will take care of renegotiating the loc handle mMsgTask->sendMsg(new LocSsrMsg(this)); LocDualContext::injectFeatureConfig(mContext); // loop through adapters, and deliver to all adapters. TO_ALL_LOCADAPTERS(mLocAdapters[i]->handleEngineUpEvent()); } void LocApiBase::handleEngineDownEvent() { // loop through adapters, and deliver to all adapters. TO_ALL_LOCADAPTERS(mLocAdapters[i]->handleEngineDownEvent()); } void LocApiBase::reportPosition(UlpLocation &location, GpsLocationExtended &locationExtended, void* locationExt, enum loc_sess_status status, LocPosTechMask loc_technology_mask) { // print the location info before delivering LOC_LOGV("flags: %d\n source: %d\n latitude: %f\n longitude: %f\n " "altitude: %f\n speed: %f\n bearing: %f\n accuracy: %f\n " "timestamp: %lld\n rawDataSize: %d\n rawData: %p\n " "Session status: %d\n Technology mask: %u", location.gpsLocation.flags, location.position_source, location.gpsLocation.latitude, location.gpsLocation.longitude, location.gpsLocation.altitude, location.gpsLocation.speed, location.gpsLocation.bearing, location.gpsLocation.accuracy, location.gpsLocation.timestamp, location.rawDataSize, location.rawData, status, loc_technology_mask); // loop through adapters, and deliver to all adapters. TO_ALL_LOCADAPTERS( mLocAdapters[i]->reportPosition(location, locationExtended, locationExt, status, loc_technology_mask) ); } void LocApiBase::reportSv(QcomSvStatus &svStatus, GpsLocationExtended &locationExtended, void* svExt) { // print the SV info before delivering LOC_LOGV("num sv: %d\n ephemeris mask: %dxn almanac mask: %x\n gps/glo/bds in use" " mask: %x/%x/%x\n sv: prn snr elevation azimuth", svStatus.num_svs, svStatus.ephemeris_mask, svStatus.almanac_mask, svStatus.gps_used_in_fix_mask, svStatus.glo_used_in_fix_mask, svStatus.bds_used_in_fix_mask); for (int i = 0; i < svStatus.num_svs && i < GPS_MAX_SVS; i++) { LOC_LOGV(" %d: %d %f %f %f", i, svStatus.sv_list[i].prn, svStatus.sv_list[i].snr, svStatus.sv_list[i].elevation, svStatus.sv_list[i].azimuth); } // loop through adapters, and deliver to all adapters. TO_ALL_LOCADAPTERS( mLocAdapters[i]->reportSv(svStatus, locationExtended, svExt) ); } void LocApiBase::reportStatus(GpsStatusValue status) { // loop through adapters, and deliver to all adapters. TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportStatus(status)); } void LocApiBase::reportNmea(const char* nmea, int length) { // loop through adapters, and deliver to all adapters. TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportNmea(nmea, length)); } void LocApiBase::reportXtraServer(const char* url1, const char* url2, const char* url3, const int maxlength) { // loop through adapters, and deliver to the first handling adapter. TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->reportXtraServer(url1, url2, url3, maxlength)); } void LocApiBase::requestXtraData() { // loop through adapters, and deliver to the first handling adapter. TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->requestXtraData()); } void LocApiBase::requestTime() { // loop through adapters, and deliver to the first handling adapter. TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->requestTime()); } void LocApiBase::requestLocation() { // loop through adapters, and deliver to the first handling adapter. TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->requestLocation()); } void LocApiBase::requestATL(int connHandle, AGpsType agps_type) { // loop through adapters, and deliver to the first handling adapter. TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->requestATL(connHandle, agps_type)); } void LocApiBase::releaseATL(int connHandle) { // loop through adapters, and deliver to the first handling adapter. TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->releaseATL(connHandle)); } void LocApiBase::requestSuplES(int connHandle) { // loop through adapters, and deliver to the first handling adapter. TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->requestSuplES(connHandle)); } void LocApiBase::reportDataCallOpened() { // loop through adapters, and deliver to the first handling adapter. TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->reportDataCallOpened()); } void LocApiBase::reportDataCallClosed() { // loop through adapters, and deliver to the first handling adapter. TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->reportDataCallClosed()); } void LocApiBase::requestNiNotify(GpsNiNotification ¬ify, const void* data) { // loop through adapters, and deliver to the first handling adapter. TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->requestNiNotify(notify, data)); } void LocApiBase::saveSupportedMsgList(uint64_t supportedMsgList) { mSupportedMsg = supportedMsgList; } void* LocApiBase :: getSibling() DEFAULT_IMPL(NULL) LocApiProxyBase* LocApiBase :: getLocApiProxy() DEFAULT_IMPL(NULL) void LocApiBase::reportGpsMeasurementData(GpsData &gpsMeasurementData) { // loop through adapters, and deliver to all adapters. TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportGpsMeasurementData(gpsMeasurementData)); } enum loc_api_adapter_err LocApiBase:: open(LOC_API_ADAPTER_EVENT_MASK_T mask) DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) enum loc_api_adapter_err LocApiBase:: close() DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) enum loc_api_adapter_err LocApiBase:: startFix(const LocPosMode& posMode) DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) enum loc_api_adapter_err LocApiBase:: stopFix() DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) enum loc_api_adapter_err LocApiBase:: deleteAidingData(GpsAidingData f) DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) enum loc_api_adapter_err LocApiBase:: enableData(int enable) DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) enum loc_api_adapter_err LocApiBase:: setAPN(char* apn, int len) DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) enum loc_api_adapter_err LocApiBase:: injectPosition(double latitude, double longitude, float accuracy) DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) enum loc_api_adapter_err LocApiBase:: setTime(GpsUtcTime time, int64_t timeReference, int uncertainty) DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) enum loc_api_adapter_err LocApiBase:: setXtraData(char* data, int length) DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) enum loc_api_adapter_err LocApiBase:: requestXtraServer() DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) enum loc_api_adapter_err LocApiBase:: atlOpenStatus(int handle, int is_succ, char* apn, AGpsBearerType bear, AGpsType agpsType) DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) enum loc_api_adapter_err LocApiBase:: atlCloseStatus(int handle, int is_succ) DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) enum loc_api_adapter_err LocApiBase:: setPositionMode(const LocPosMode& posMode) DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) enum loc_api_adapter_err LocApiBase:: setServer(const char* url, int len) DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) enum loc_api_adapter_err LocApiBase:: setServer(unsigned int ip, int port, LocServerType type) DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) enum loc_api_adapter_err LocApiBase:: informNiResponse(GpsUserResponseType userResponse, const void* passThroughData) DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) enum loc_api_adapter_err LocApiBase:: setSUPLVersion(uint32_t version) DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) enum loc_api_adapter_err LocApiBase:: setLPPConfig(uint32_t profile) DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) enum loc_api_adapter_err LocApiBase:: setSensorControlConfig(int sensorUsage, int sensorProvider) DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) enum loc_api_adapter_err LocApiBase:: setSensorProperties(bool gyroBiasVarianceRandomWalk_valid, float gyroBiasVarianceRandomWalk, bool accelBiasVarianceRandomWalk_valid, float accelBiasVarianceRandomWalk, bool angleBiasVarianceRandomWalk_valid, float angleBiasVarianceRandomWalk, bool rateBiasVarianceRandomWalk_valid, float rateBiasVarianceRandomWalk, bool velocityBiasVarianceRandomWalk_valid, float velocityBiasVarianceRandomWalk) DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) enum loc_api_adapter_err LocApiBase:: setSensorPerfControlConfig(int controlMode, int accelSamplesPerBatch, int accelBatchesPerSec, int gyroSamplesPerBatch, int gyroBatchesPerSec, int accelSamplesPerBatchHigh, int accelBatchesPerSecHigh, int gyroSamplesPerBatchHigh, int gyroBatchesPerSecHigh, int algorithmConfig) DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) enum loc_api_adapter_err LocApiBase:: setExtPowerConfig(int isBatteryCharging) DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) enum loc_api_adapter_err LocApiBase:: setAGLONASSProtocol(unsigned long aGlonassProtocol) DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) enum loc_api_adapter_err LocApiBase:: getWwanZppFix(GpsLocation& zppLoc) DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) enum loc_api_adapter_err LocApiBase:: getBestAvailableZppFix(GpsLocation& zppLoc) { memset(&zppLoc, 0, sizeof(zppLoc)); DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) } enum loc_api_adapter_err LocApiBase:: getBestAvailableZppFix(GpsLocation & zppLoc, LocPosTechMask & tech_mask) { memset(&zppLoc, 0, sizeof(zppLoc)); memset(&tech_mask, 0, sizeof(tech_mask)); DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) } int LocApiBase:: initDataServiceClient() DEFAULT_IMPL(-1) int LocApiBase:: openAndStartDataCall() DEFAULT_IMPL(-1) void LocApiBase:: stopDataCall() DEFAULT_IMPL() void LocApiBase:: closeDataCall() DEFAULT_IMPL() int LocApiBase:: setGpsLock(LOC_GPS_LOCK_MASK lock) DEFAULT_IMPL(-1) void LocApiBase:: installAGpsCert(const DerEncodedCertificate* pData, size_t length, uint32_t slotBitMask) DEFAULT_IMPL() int LocApiBase:: getGpsLock() DEFAULT_IMPL(-1) enum loc_api_adapter_err LocApiBase:: setXtraVersionCheck(enum xtra_version_check check) DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) int LocApiBase:: updateRegistrationMask(LOC_API_ADAPTER_EVENT_MASK_T event, loc_registration_mask_status isEnabled) DEFAULT_IMPL(-1) bool LocApiBase:: gnssConstellationConfig() DEFAULT_IMPL(false) } // namespace loc_core ================================================ FILE: gps/core/LocApiBase.h ================================================ /* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef LOC_API_BASE_H #define LOC_API_BASE_H #include #include #include #include #include namespace loc_core { class ContextBase; int hexcode(char *hexstring, int string_size, const char *data, int data_size); int decodeAddress(char *addr_string, int string_size, const char *data, int data_size); #define MAX_ADAPTERS 10 #define TO_ALL_ADAPTERS(adapters, call) \ for (int i = 0; i < MAX_ADAPTERS && NULL != (adapters)[i]; i++) { \ call; \ } #define TO_1ST_HANDLING_ADAPTER(adapters, call) \ for (int i = 0; i sendMsg(msg); } void addAdapter(LocAdapterBase* adapter); void removeAdapter(LocAdapterBase* adapter); // upward calls void handleEngineUpEvent(); void handleEngineDownEvent(); void reportPosition(UlpLocation &location, GpsLocationExtended &locationExtended, void* locationExt, enum loc_sess_status status, LocPosTechMask loc_technology_mask = LOC_POS_TECH_MASK_DEFAULT); void reportSv(QcomSvStatus &svStatus, GpsLocationExtended &locationExtended, void* svExt); void reportStatus(GpsStatusValue status); void reportNmea(const char* nmea, int length); void reportXtraServer(const char* url1, const char* url2, const char* url3, const int maxlength); void requestXtraData(); void requestTime(); void requestLocation(); void requestATL(int connHandle, AGpsType agps_type); void releaseATL(int connHandle); void requestSuplES(int connHandle); void reportDataCallOpened(); void reportDataCallClosed(); void requestNiNotify(GpsNiNotification ¬ify, const void* data); void saveSupportedMsgList(uint64_t supportedMsgList); void reportGpsMeasurementData(GpsData &gpsMeasurementData); // downward calls // All below functions are to be defined by adapter specific modules: // RPC, QMI, etc. The default implementation is empty. virtual void* getSibling(); virtual LocApiProxyBase* getLocApiProxy(); virtual enum loc_api_adapter_err startFix(const LocPosMode& posMode); virtual enum loc_api_adapter_err stopFix(); virtual enum loc_api_adapter_err deleteAidingData(GpsAidingData f); virtual enum loc_api_adapter_err enableData(int enable); virtual enum loc_api_adapter_err setAPN(char* apn, int len); virtual enum loc_api_adapter_err injectPosition(double latitude, double longitude, float accuracy); virtual enum loc_api_adapter_err setTime(GpsUtcTime time, int64_t timeReference, int uncertainty); virtual enum loc_api_adapter_err setXtraData(char* data, int length); virtual enum loc_api_adapter_err requestXtraServer(); virtual enum loc_api_adapter_err atlOpenStatus(int handle, int is_succ, char* apn, AGpsBearerType bear, AGpsType agpsType); virtual enum loc_api_adapter_err atlCloseStatus(int handle, int is_succ); virtual enum loc_api_adapter_err setPositionMode(const LocPosMode& posMode); virtual enum loc_api_adapter_err setServer(const char* url, int len); virtual enum loc_api_adapter_err setServer(unsigned int ip, int port, LocServerType type); virtual enum loc_api_adapter_err informNiResponse(GpsUserResponseType userResponse, const void* passThroughData); virtual enum loc_api_adapter_err setSUPLVersion(uint32_t version); virtual enum loc_api_adapter_err setLPPConfig(uint32_t profile); virtual enum loc_api_adapter_err setSensorControlConfig(int sensorUsage, int sensorProvider); virtual enum loc_api_adapter_err setSensorProperties(bool gyroBiasVarianceRandomWalk_valid, float gyroBiasVarianceRandomWalk, bool accelBiasVarianceRandomWalk_valid, float accelBiasVarianceRandomWalk, bool angleBiasVarianceRandomWalk_valid, float angleBiasVarianceRandomWalk, bool rateBiasVarianceRandomWalk_valid, float rateBiasVarianceRandomWalk, bool velocityBiasVarianceRandomWalk_valid, float velocityBiasVarianceRandomWalk); virtual enum loc_api_adapter_err setSensorPerfControlConfig(int controlMode, int accelSamplesPerBatch, int accelBatchesPerSec, int gyroSamplesPerBatch, int gyroBatchesPerSec, int accelSamplesPerBatchHigh, int accelBatchesPerSecHigh, int gyroSamplesPerBatchHigh, int gyroBatchesPerSecHigh, int algorithmConfig); virtual enum loc_api_adapter_err setExtPowerConfig(int isBatteryCharging); virtual enum loc_api_adapter_err setAGLONASSProtocol(unsigned long aGlonassProtocol); virtual enum loc_api_adapter_err getWwanZppFix(GpsLocation & zppLoc); virtual enum loc_api_adapter_err getBestAvailableZppFix(GpsLocation & zppLoc); virtual enum loc_api_adapter_err getBestAvailableZppFix(GpsLocation & zppLoc, LocPosTechMask & tech_mask); virtual int initDataServiceClient(); virtual int openAndStartDataCall(); virtual void stopDataCall(); virtual void closeDataCall(); virtual void installAGpsCert(const DerEncodedCertificate* pData, size_t length, uint32_t slotBitMask); inline virtual void setInSession(bool inSession) {} inline bool isMessageSupported (LocCheckingMessagesID msgID) const { if (msgID > (sizeof(mSupportedMsg) << 3)) { return false; } else { uint32_t messageChecker = 1 << msgID; return (messageChecker & mSupportedMsg) == messageChecker; } } void updateEvtMask(); /*Values for lock 1 = Do not lock any position sessions 2 = Lock MI position sessions 3 = Lock MT position sessions 4 = Lock all position sessions */ virtual int setGpsLock(LOC_GPS_LOCK_MASK lock); /* Returns Current value of GPS Lock on success -1 on failure */ virtual int getGpsLock(void); virtual enum loc_api_adapter_err setXtraVersionCheck(enum xtra_version_check check); /* Update gps reporting events */ virtual int updateRegistrationMask(LOC_API_ADAPTER_EVENT_MASK_T event, loc_registration_mask_status isEnabled); /* Check if the modem support the service */ virtual bool gnssConstellationConfig(); }; typedef LocApiBase* (getLocApi_t)(const MsgTask* msgTask, LOC_API_ADAPTER_EVENT_MASK_T exMask, ContextBase *context); } // namespace loc_core #endif //LOC_API_BASE_H ================================================ FILE: gps/core/LocDualContext.cpp ================================================ /* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #define LOG_NDDEBUG 0 #define LOG_TAG "LocSvc_DualCtx" #include #include #include #include #include #include namespace loc_core { // nothing exclude for foreground const LOC_API_ADAPTER_EVENT_MASK_T LocDualContext::mFgExclMask = 0; // excluded events for background clients const LOC_API_ADAPTER_EVENT_MASK_T LocDualContext::mBgExclMask = (LOC_API_ADAPTER_BIT_PARSED_POSITION_REPORT | LOC_API_ADAPTER_BIT_SATELLITE_REPORT | LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT | LOC_API_ADAPTER_BIT_NMEA_POSITION_REPORT | LOC_API_ADAPTER_BIT_IOCTL_REPORT | LOC_API_ADAPTER_BIT_STATUS_REPORT | LOC_API_ADAPTER_BIT_GEOFENCE_GEN_ALERT | LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT); const MsgTask* LocDualContext::mMsgTask = NULL; ContextBase* LocDualContext::mFgContext = NULL; ContextBase* LocDualContext::mBgContext = NULL; ContextBase* LocDualContext::mInjectContext = NULL; // the name must be shorter than 15 chars const char* LocDualContext::mLocationHalName = "Loc_hal_worker"; const char* LocDualContext::mLBSLibName = "liblbs_core.so"; pthread_mutex_t LocDualContext::mGetLocContextMutex = PTHREAD_MUTEX_INITIALIZER; const MsgTask* LocDualContext::getMsgTask(LocThread::tCreate tCreator, const char* name, bool joinable) { if (NULL == mMsgTask) { mMsgTask = new MsgTask(tCreator, name, joinable); } return mMsgTask; } inline const MsgTask* LocDualContext::getMsgTask(const char* name, bool joinable) { return getMsgTask((LocThread::tCreate)NULL, name, joinable); } ContextBase* LocDualContext::getLocFgContext(LocThread::tCreate tCreator, LocMsg* firstMsg, const char* name, bool joinable) { pthread_mutex_lock(&LocDualContext::mGetLocContextMutex); LOC_LOGD("%s:%d]: querying ContextBase with tCreator", __func__, __LINE__); if (NULL == mFgContext) { LOC_LOGD("%s:%d]: creating msgTask with tCreator", __func__, __LINE__); const MsgTask* msgTask = getMsgTask(tCreator, name, joinable); mFgContext = new LocDualContext(msgTask, mFgExclMask); } if(NULL == mInjectContext) { LOC_LOGD("%s:%d]: mInjectContext is FgContext", __func__, __LINE__); mInjectContext = mFgContext; injectFeatureConfig(mInjectContext); } pthread_mutex_unlock(&LocDualContext::mGetLocContextMutex); if (firstMsg) { mFgContext->sendMsg(firstMsg); } return mFgContext; } ContextBase* LocDualContext::getLocBgContext(LocThread::tCreate tCreator, LocMsg* firstMsg, const char* name, bool joinable) { pthread_mutex_lock(&LocDualContext::mGetLocContextMutex); LOC_LOGD("%s:%d]: querying ContextBase with tCreator", __func__, __LINE__); if (NULL == mBgContext) { LOC_LOGD("%s:%d]: creating msgTask with tCreator", __func__, __LINE__); const MsgTask* msgTask = getMsgTask(tCreator, name, joinable); mBgContext = new LocDualContext(msgTask, mBgExclMask); } if(NULL == mInjectContext) { LOC_LOGD("%s:%d]: mInjectContext is BgContext", __func__, __LINE__); mInjectContext = mBgContext; injectFeatureConfig(mInjectContext); } pthread_mutex_unlock(&LocDualContext::mGetLocContextMutex); if (firstMsg) { mBgContext->sendMsg(firstMsg); } return mBgContext; } void LocDualContext :: injectFeatureConfig(ContextBase *curContext) { LOC_LOGD("%s:%d]: Enter", __func__, __LINE__); if(curContext == mInjectContext) { LOC_LOGD("%s:%d]: Calling LBSProxy (%p) to inject feature config", __func__, __LINE__, ((LocDualContext *)mInjectContext)->mLBSProxy); ((LocDualContext *)mInjectContext)->mLBSProxy->injectFeatureConfig(curContext); } LOC_LOGD("%s:%d]: Exit", __func__, __LINE__); } LocDualContext::LocDualContext(const MsgTask* msgTask, LOC_API_ADAPTER_EVENT_MASK_T exMask) : ContextBase(msgTask, exMask, mLBSLibName) { } } ================================================ FILE: gps/core/LocDualContext.h ================================================ /* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef __LOC_ENG_CONTEXT__ #define __LOC_ENG_CONTEXT__ #include #include #include #include namespace loc_core { class LocDualContext : public ContextBase { static const MsgTask* mMsgTask; static ContextBase* mFgContext; static ContextBase* mBgContext; static ContextBase* mInjectContext; static const MsgTask* getMsgTask(LocThread::tCreate tCreator, const char* name, bool joinable = true); static const MsgTask* getMsgTask(const char* name, bool joinable = true); static pthread_mutex_t mGetLocContextMutex; protected: LocDualContext(const MsgTask* msgTask, LOC_API_ADAPTER_EVENT_MASK_T exMask); inline virtual ~LocDualContext() {} public: static const char* mLBSLibName; static const LOC_API_ADAPTER_EVENT_MASK_T mFgExclMask; static const LOC_API_ADAPTER_EVENT_MASK_T mBgExclMask; static const char* mLocationHalName; static ContextBase* getLocFgContext(LocThread::tCreate tCreator, LocMsg* firstMsg, const char* name, bool joinable = true); inline static ContextBase* getLocFgContext(const char* name, bool joinable = true) { return getLocFgContext(NULL, NULL, name, joinable); } static ContextBase* getLocBgContext(LocThread::tCreate tCreator, LocMsg* firstMsg, const char* name, bool joinable = true); inline static ContextBase* getLocBgContext(const char* name, bool joinable = true) { return getLocBgContext(NULL, NULL, name, joinable); } static void injectFeatureConfig(ContextBase *context); }; } #endif //__LOC_ENG_CONTEXT__ ================================================ FILE: gps/core/UlpProxyBase.h ================================================ /* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef ULP_PROXY_BASE_H #define ULP_PROXY_BASE_H #include #include "fused_location_extended.h" namespace loc_core { class LocAdapterBase; class UlpProxyBase { public: LocPosMode mPosMode; bool mFixSet; inline UlpProxyBase() { mPosMode.mode = LOC_POSITION_MODE_INVALID; mFixSet = false; } inline virtual ~UlpProxyBase() {} inline virtual bool sendStartFix() { mFixSet = true; return false; } inline virtual bool sendStopFix() { mFixSet = false; return false; } inline virtual bool sendFixMode(LocPosMode ¶ms) { mPosMode = params; return false; } inline virtual bool reportPosition(UlpLocation &location, GpsLocationExtended &locationExtended, void* locationExt, enum loc_sess_status status, LocPosTechMask loc_technology_mask) { return false; } inline virtual bool reportSv(QcomSvStatus &svStatus, GpsLocationExtended &locationExtended, void* svExt) { return false; } inline virtual bool reportStatus(GpsStatusValue status) { return false; } inline virtual void setAdapter(LocAdapterBase* adapter) {} inline virtual void setCapabilities(unsigned long capabilities) {} inline virtual bool reportBatchingSession(FlpExtBatchOptions &options, bool active) { return false; } inline virtual bool reportPositions(const FlpExtLocation* locations, int32_t number_of_locations) { return false; } }; } // namespace loc_core #endif // ULP_PROXY_BASE_H ================================================ FILE: gps/core/fused_location_extended.h ================================================ /* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef FUSED_LOCATION_EXTENDED_H #define FUSED_LOCATION_EXTENDED_H /** Batching default ID for dummy batching session*/ #define GPS_BATCHING_DEFAULT_ID 1 /** This cap is used to decide the FLP session cache size on AP. If the BATCH_SIZE in flp.conf is less than GPS_AP_BATCHING_SIZE_CAP, FLP session cache size will be twice the BATCH_SIZE defined in flp.conf. Otherwise, FLP session cache size will be equal to the BATCH_SIZE.*/ #define GPS_AP_BATCHING_SIZE_CAP 40 #define GPS_BATCHING_OPERATION_SUCCEESS 1 #define GPS_BATCHING_OPERATION_FAILURE 0 /** GPS extended batching flags*/ #define GPS_EXT_BATCHING_ON_FULL 0x0000001 #define GPS_EXT_BATCHING_ON_FIX 0x000000 typedef struct { double max_power_allocation_mW; uint32_t sources_to_use; uint32_t flags; int64_t period_ns; } FlpExtBatchOptions; /** GpsLocationExtended has valid latitude and longitude. */ #define GPS_LOCATION_EXTENDED_HAS_LAT_LONG (1U<<0) /** GpsLocationExtended has valid altitude. */ #define GPS_LOCATION_EXTENDED_HAS_ALTITUDE (1U<<1) /** GpsLocationExtended has valid speed. */ #define GPS_LOCATION_EXTENDED_HAS_SPEED (1U<<2) /** GpsLocationExtended has valid bearing. */ #define GPS_LOCATION_EXTENDED_HAS_BEARING (1U<<4) /** GpsLocationExtended has valid accuracy. */ #define GPS_LOCATION_EXTENDED_HAS_ACCURACY (1U<<8) /** GPS extended supports geofencing */ #define GPS_EXTENDED_CAPABILITY_GEOFENCE 0x0000001 /** GPS extended supports batching */ #define GPS_EXTENDED_CAPABILITY_BATCHING 0x0000002 typedef struct FlpExtLocation_s { size_t size; uint16_t flags; double latitude; double longitude; double altitude; float speed; float bearing; float accuracy; int64_t timestamp; uint32_t sources_used; } FlpExtLocation; #endif /* FUSED_LOCATION_EXTENDED_H */ ================================================ FILE: gps/core/gps_extended.h ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPS_EXTENDED_H #define GPS_EXTENDED_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #include struct LocPosMode { LocPositionMode mode; GpsPositionRecurrence recurrence; uint32_t min_interval; uint32_t preferred_accuracy; uint32_t preferred_time; char credentials[14]; char provider[8]; LocPosMode(LocPositionMode m, GpsPositionRecurrence recr, uint32_t gap, uint32_t accu, uint32_t time, const char* cred, const char* prov) : mode(m), recurrence(recr), min_interval(gap < MIN_POSSIBLE_FIX_INTERVAL ? MIN_POSSIBLE_FIX_INTERVAL : gap), preferred_accuracy(accu), preferred_time(time) { memset(credentials, 0, sizeof(credentials)); memset(provider, 0, sizeof(provider)); if (NULL != cred) { memcpy(credentials, cred, sizeof(credentials)-1); } if (NULL != prov) { memcpy(provider, prov, sizeof(provider)-1); } } inline LocPosMode() : mode(LOC_POSITION_MODE_MS_BASED), recurrence(GPS_POSITION_RECURRENCE_PERIODIC), min_interval(MIN_POSSIBLE_FIX_INTERVAL), preferred_accuracy(50), preferred_time(120000) { memset(credentials, 0, sizeof(credentials)); memset(provider, 0, sizeof(provider)); } inline bool equals(const LocPosMode &anotherMode) const { return anotherMode.mode == mode && anotherMode.recurrence == recurrence && anotherMode.min_interval == min_interval && anotherMode.preferred_accuracy == preferred_accuracy && anotherMode.preferred_time == preferred_time && !strncmp(anotherMode.credentials, credentials, sizeof(credentials)-1) && !strncmp(anotherMode.provider, provider, sizeof(provider)-1); } void logv() const; }; #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* GPS_EXTENDED_H */ ================================================ FILE: gps/core/gps_extended_c.h ================================================ /* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPS_EXTENDED_C_H #define GPS_EXTENDED_C_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #include #include #include #include #include /** Location has valid source information. */ #define LOCATION_HAS_SOURCE_INFO 0x0020 /** GpsLocation has valid "is indoor?" flag */ #define GPS_LOCATION_HAS_IS_INDOOR 0x0040 /** GpsLocation has valid floor number */ #define GPS_LOCATION_HAS_FLOOR_NUMBER 0x0080 /** GpsLocation has valid map URL*/ #define GPS_LOCATION_HAS_MAP_URL 0x0100 /** GpsLocation has valid map index */ #define GPS_LOCATION_HAS_MAP_INDEX 0x0200 /** Sizes for indoor fields */ #define GPS_LOCATION_MAP_URL_SIZE 400 #define GPS_LOCATION_MAP_INDEX_SIZE 16 /** Position source is ULP */ #define ULP_LOCATION_IS_FROM_HYBRID 0x0001 /** Position source is GNSS only */ #define ULP_LOCATION_IS_FROM_GNSS 0x0002 /** Position source is ZPP only */ #define ULP_LOCATION_IS_FROM_ZPP 0x0004 /** Position is from a Geofence Breach Event */ #define ULP_LOCATION_IS_FROM_GEOFENCE 0X0008 /** Position is from Hardware FLP */ #define ULP_LOCATION_IS_FROM_HW_FLP 0x0010 /** Position is from NLP */ #define ULP_LOCATION_IS_FROM_NLP 0x0020 /** Position is from PIP */ #define ULP_LOCATION_IS_FROM_PIP 0x0040 #define ULP_MIN_INTERVAL_INVALID 0xffffffff /*Emergency SUPL*/ #define GPS_NI_TYPE_EMERGENCY_SUPL 4 #define AGPS_CERTIFICATE_MAX_LENGTH 2000 #define AGPS_CERTIFICATE_MAX_SLOTS 10 enum loc_registration_mask_status { LOC_REGISTRATION_MASK_ENABLED, LOC_REGISTRATION_MASK_DISABLED }; typedef struct { /** set to sizeof(UlpLocation) */ size_t size; GpsLocation gpsLocation; /* Provider indicator for HYBRID or GPS */ uint16_t position_source; /*allows HAL to pass additional information related to the location */ int rawDataSize; /* in # of bytes */ void * rawData; bool is_indoor; float floor_number; char map_url[GPS_LOCATION_MAP_URL_SIZE]; unsigned char map_index[GPS_LOCATION_MAP_INDEX_SIZE]; } UlpLocation; /** AGPS type */ typedef int16_t AGpsExtType; #define AGPS_TYPE_INVALID -1 #define AGPS_TYPE_ANY 0 #define AGPS_TYPE_SUPL 1 #define AGPS_TYPE_C2K 2 #define AGPS_TYPE_WWAN_ANY 3 #define AGPS_TYPE_WIFI 4 #define AGPS_TYPE_SUPL_ES 5 /** SSID length */ #define SSID_BUF_SIZE (32+1) typedef int16_t AGpsBearerType; #define AGPS_APN_BEARER_INVALID -1 #define AGPS_APN_BEARER_IPV4 0 #define AGPS_APN_BEARER_IPV6 1 #define AGPS_APN_BEARER_IPV4V6 2 /** GPS extended callback structure. */ typedef struct { /** set to sizeof(GpsCallbacks) */ size_t size; gps_set_capabilities set_capabilities_cb; gps_acquire_wakelock acquire_wakelock_cb; gps_release_wakelock release_wakelock_cb; gps_create_thread create_thread_cb; gps_request_utc_time request_utc_time_cb; } GpsExtCallbacks; /** Callback to report the xtra server url to the client. * The client should use this url when downloading xtra unless overwritten * in the gps.conf file */ typedef void (* report_xtra_server)(const char*, const char*, const char*); /** Callback structure for the XTRA interface. */ typedef struct { gps_xtra_download_request download_request_cb; gps_create_thread create_thread_cb; report_xtra_server report_xtra_server_cb; } GpsXtraExtCallbacks; /** Represents the status of AGPS. */ typedef struct { /** set to sizeof(AGpsExtStatus) */ size_t size; AGpsExtType type; AGpsStatusValue status; uint32_t ipv4_addr; struct sockaddr_storage addr; char ssid[SSID_BUF_SIZE]; char password[SSID_BUF_SIZE]; } AGpsExtStatus; /** Callback with AGPS status information. * Can only be called from a thread created by create_thread_cb. */ typedef void (* agps_status_extended)(AGpsExtStatus* status); /** Callback structure for the AGPS interface. */ typedef struct { agps_status_extended status_cb; gps_create_thread create_thread_cb; } AGpsExtCallbacks; /** GPS NI callback structure. */ typedef struct { /** * Sends the notification request from HAL to GPSLocationProvider. */ gps_ni_notify_callback notify_cb; gps_create_thread create_thread_cb; } GpsNiExtCallbacks; typedef enum loc_server_type { LOC_AGPS_CDMA_PDE_SERVER, LOC_AGPS_CUSTOM_PDE_SERVER, LOC_AGPS_MPC_SERVER, LOC_AGPS_SUPL_SERVER } LocServerType; typedef enum loc_position_mode_type { LOC_POSITION_MODE_INVALID = -1, LOC_POSITION_MODE_STANDALONE = 0, LOC_POSITION_MODE_MS_BASED, LOC_POSITION_MODE_MS_ASSISTED, LOC_POSITION_MODE_RESERVED_1, LOC_POSITION_MODE_RESERVED_2, LOC_POSITION_MODE_RESERVED_3, LOC_POSITION_MODE_RESERVED_4, LOC_POSITION_MODE_RESERVED_5 } LocPositionMode; #define MIN_POSSIBLE_FIX_INTERVAL 1000 /* msec */ /** Flags to indicate which values are valid in a GpsLocationExtended. */ typedef uint16_t GpsLocationExtendedFlags; /** GpsLocationExtended has valid pdop, hdop, vdop. */ #define GPS_LOCATION_EXTENDED_HAS_DOP 0x0001 /** GpsLocationExtended has valid altitude mean sea level. */ #define GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL 0x0002 /** UlpLocation has valid magnetic deviation. */ #define GPS_LOCATION_EXTENDED_HAS_MAG_DEV 0x0004 /** UlpLocation has valid mode indicator. */ #define GPS_LOCATION_EXTENDED_HAS_MODE_IND 0x0008 /** GpsLocationExtended has valid vertical uncertainty */ #define GPS_LOCATION_EXTENDED_HAS_VERT_UNC 0x0010 /** GpsLocationExtended has valid speed uncertainty */ #define GPS_LOCATION_EXTENDED_HAS_SPEED_UNC 0x0020 /** GpsLocationExtended has valid heading uncertainty */ #define GPS_LOCATION_EXTENDED_HAS_BEARING_UNC 0x0040 /** GpsLocationExtended has valid horizontal reliability */ #define GPS_LOCATION_EXTENDED_HAS_HOR_RELIABILITY 0x0080 /** GpsLocationExtended has valid vertical reliability */ #define GPS_LOCATION_EXTENDED_HAS_VERT_RELIABILITY 0x0100 typedef enum { LOC_RELIABILITY_NOT_SET = 0, LOC_RELIABILITY_VERY_LOW = 1, LOC_RELIABILITY_LOW = 2, LOC_RELIABILITY_MEDIUM = 3, LOC_RELIABILITY_HIGH = 4 }LocReliability; /** Represents gps location extended. */ typedef struct { /** set to sizeof(GpsLocationExtended) */ size_t size; /** Contains GpsLocationExtendedFlags bits. */ uint16_t flags; /** Contains the Altitude wrt mean sea level */ float altitudeMeanSeaLevel; /** Contains Position Dilusion of Precision. */ float pdop; /** Contains Horizontal Dilusion of Precision. */ float hdop; /** Contains Vertical Dilusion of Precision. */ float vdop; /** Contains Magnetic Deviation. */ float magneticDeviation; /** vertical uncertainty in meters */ float vert_unc; /** speed uncertainty in m/s */ float speed_unc; /** heading uncertainty in degrees (0 to 359.999) */ float bearing_unc; /** horizontal reliability. */ LocReliability horizontal_reliability; /** vertical reliability. */ LocReliability vertical_reliability; } GpsLocationExtended; /** Represents SV status. */ typedef struct { /** set to sizeof(QcomSvStatus) */ size_t size; /** Number of SVs currently visible. */ int num_svs; /** Contains an array of SV information. */ GpsSvInfo sv_list[GPS_MAX_SVS]; /** Represents a bit mask indicating which SVs * have ephemeris data. */ uint32_t ephemeris_mask; /** Represents a bit mask indicating which SVs * have almanac data. */ uint32_t almanac_mask; /** * Represents a bit mask indicating which GPS SVs * were used for computing the most recent position fix. */ uint32_t gps_used_in_fix_mask; /** * Represents a bit mask indicating which GLONASS SVs * were used for computing the most recent position fix. */ uint32_t glo_used_in_fix_mask; /** * Represents a bit mask indicating which BDS SVs * were used for computing the most recent position fix. */ uint64_t bds_used_in_fix_mask; } QcomSvStatus; enum loc_sess_status { LOC_SESS_SUCCESS, LOC_SESS_INTERMEDIATE, LOC_SESS_FAILURE }; typedef uint32_t LocPosTechMask; #define LOC_POS_TECH_MASK_DEFAULT ((LocPosTechMask)0x00000000) #define LOC_POS_TECH_MASK_SATELLITE ((LocPosTechMask)0x00000001) #define LOC_POS_TECH_MASK_CELLID ((LocPosTechMask)0x00000002) #define LOC_POS_TECH_MASK_WIFI ((LocPosTechMask)0x00000004) #define LOC_POS_TECH_MASK_SENSORS ((LocPosTechMask)0x00000008) #define LOC_POS_TECH_MASK_REFERENCE_LOCATION ((LocPosTechMask)0x00000010) #define LOC_POS_TECH_MASK_INJECTED_COARSE_POSITION ((LocPosTechMask)0x00000020) #define LOC_POS_TECH_MASK_AFLT ((LocPosTechMask)0x00000040) #define LOC_POS_TECH_MASK_HYBRID ((LocPosTechMask)0x00000080) typedef enum { LOC_ENG_IF_REQUEST_SENDER_ID_QUIPC = 0, LOC_ENG_IF_REQUEST_SENDER_ID_MSAPM, LOC_ENG_IF_REQUEST_SENDER_ID_MSAPU, LOC_ENG_IF_REQUEST_SENDER_ID_GPSONE_DAEMON, LOC_ENG_IF_REQUEST_SENDER_ID_MODEM, LOC_ENG_IF_REQUEST_SENDER_ID_UNKNOWN } loc_if_req_sender_id_e_type; #define smaller_of(a, b) (((a) > (b)) ? (b) : (a)) #define MAX_APN_LEN 100 // This will be overridden by the individual adapters // if necessary. #define DEFAULT_IMPL(rtv) \ { \ LOC_LOGD("%s: default implementation invoked", __func__); \ return rtv; \ } enum loc_api_adapter_err { LOC_API_ADAPTER_ERR_SUCCESS = 0, LOC_API_ADAPTER_ERR_GENERAL_FAILURE = 1, LOC_API_ADAPTER_ERR_UNSUPPORTED = 2, LOC_API_ADAPTER_ERR_INVALID_HANDLE = 4, LOC_API_ADAPTER_ERR_INVALID_PARAMETER = 5, LOC_API_ADAPTER_ERR_ENGINE_BUSY = 6, LOC_API_ADAPTER_ERR_PHONE_OFFLINE = 7, LOC_API_ADAPTER_ERR_TIMEOUT = 8, LOC_API_ADAPTER_ERR_SERVICE_NOT_PRESENT = 9, LOC_API_ADAPTER_ERR_INTERNAL = 10, /* equating engine down to phone offline, as they are the same errror */ LOC_API_ADAPTER_ERR_ENGINE_DOWN = LOC_API_ADAPTER_ERR_PHONE_OFFLINE, LOC_API_ADAPTER_ERR_FAILURE = 101, LOC_API_ADAPTER_ERR_UNKNOWN }; enum loc_api_adapter_event_index { LOC_API_ADAPTER_REPORT_POSITION = 0, // Position report comes in loc_parsed_position_s_type LOC_API_ADAPTER_REPORT_SATELLITE, // Satellite in view report LOC_API_ADAPTER_REPORT_NMEA_1HZ, // NMEA report at 1HZ rate LOC_API_ADAPTER_REPORT_NMEA_POSITION, // NMEA report at position report rate LOC_API_ADAPTER_REQUEST_NI_NOTIFY_VERIFY, // NI notification/verification request LOC_API_ADAPTER_REQUEST_ASSISTANCE_DATA, // Assistance data, eg: time, predicted orbits request LOC_API_ADAPTER_REQUEST_LOCATION_SERVER, // Request for location server LOC_API_ADAPTER_REPORT_IOCTL, // Callback report for loc_ioctl LOC_API_ADAPTER_REPORT_STATUS, // Misc status report: eg, engine state LOC_API_ADAPTER_REQUEST_WIFI, // LOC_API_ADAPTER_SENSOR_STATUS, // LOC_API_ADAPTER_REQUEST_TIME_SYNC, // LOC_API_ADAPTER_REPORT_SPI, // LOC_API_ADAPTER_REPORT_NI_GEOFENCE, // LOC_API_ADAPTER_GEOFENCE_GEN_ALERT, // LOC_API_ADAPTER_REPORT_GENFENCE_BREACH, // LOC_API_ADAPTER_PEDOMETER_CTRL, // LOC_API_ADAPTER_MOTION_CTRL, // LOC_API_ADAPTER_REQUEST_WIFI_AP_DATA, // Wifi ap data LOC_API_ADAPTER_BATCH_FULL, // Batching on full LOC_API_ADAPTER_BATCHED_POSITION_REPORT, // Batching on fix LOC_API_ADAPTER_BATCHED_GENFENCE_BREACH_REPORT, // LOC_API_ADAPTER_GDT_UPLOAD_BEGIN_REQ, // GDT upload start request LOC_API_ADAPTER_GDT_UPLOAD_END_REQ, // GDT upload end request LOC_API_ADAPTER_GNSS_MEASUREMENT, // GNSS Measurement report LOC_API_ADAPTER_REQUEST_TIMEZONE, // Timezone injection request LOC_API_ADAPTER_EVENT_MAX }; #define LOC_API_ADAPTER_BIT_PARSED_POSITION_REPORT (1< #include #include void LocPosMode::logv() const { LOC_LOGV ("Position mode: %s\n Position recurrence: %s\n " "min interval: %d\n preferred accuracy: %d\n " "preferred time: %d\n credentials: %s provider: %s", loc_get_position_mode_name(mode), loc_get_position_recurrence_name(recurrence), min_interval, preferred_accuracy, preferred_time, credentials, provider); } /* GPS status names */ static loc_name_val_s_type gps_status_name[] = { NAME_VAL( GPS_STATUS_NONE ), NAME_VAL( GPS_STATUS_SESSION_BEGIN ), NAME_VAL( GPS_STATUS_SESSION_END ), NAME_VAL( GPS_STATUS_ENGINE_ON ), NAME_VAL( GPS_STATUS_ENGINE_OFF ), }; static int gps_status_num = sizeof(gps_status_name) / sizeof(loc_name_val_s_type); /* Find Android GPS status name */ const char* loc_get_gps_status_name(GpsStatusValue gps_status) { return loc_get_name_from_val(gps_status_name, gps_status_num, (long) gps_status); } static loc_name_val_s_type loc_eng_position_modes[] = { NAME_VAL( LOC_POSITION_MODE_STANDALONE ), NAME_VAL( LOC_POSITION_MODE_MS_BASED ), NAME_VAL( LOC_POSITION_MODE_MS_ASSISTED ), NAME_VAL( LOC_POSITION_MODE_RESERVED_1 ), NAME_VAL( LOC_POSITION_MODE_RESERVED_2 ), NAME_VAL( LOC_POSITION_MODE_RESERVED_3 ), NAME_VAL( LOC_POSITION_MODE_RESERVED_4 ), NAME_VAL( LOC_POSITION_MODE_RESERVED_5 ) }; static int loc_eng_position_mode_num = sizeof(loc_eng_position_modes) / sizeof(loc_name_val_s_type); const char* loc_get_position_mode_name(GpsPositionMode mode) { return loc_get_name_from_val(loc_eng_position_modes, loc_eng_position_mode_num, (long) mode); } static loc_name_val_s_type loc_eng_position_recurrences[] = { NAME_VAL( GPS_POSITION_RECURRENCE_PERIODIC ), NAME_VAL( GPS_POSITION_RECURRENCE_SINGLE ) }; static int loc_eng_position_recurrence_num = sizeof(loc_eng_position_recurrences) / sizeof(loc_name_val_s_type); const char* loc_get_position_recurrence_name(GpsPositionRecurrence recur) { return loc_get_name_from_val(loc_eng_position_recurrences, loc_eng_position_recurrence_num, (long) recur); } static loc_name_val_s_type loc_eng_aiding_data_bits[] = { NAME_VAL( GPS_DELETE_EPHEMERIS ), NAME_VAL( GPS_DELETE_ALMANAC ), NAME_VAL( GPS_DELETE_POSITION ), NAME_VAL( GPS_DELETE_TIME ), NAME_VAL( GPS_DELETE_IONO ), NAME_VAL( GPS_DELETE_UTC ), NAME_VAL( GPS_DELETE_HEALTH ), NAME_VAL( GPS_DELETE_SVDIR ), NAME_VAL( GPS_DELETE_SVSTEER ), NAME_VAL( GPS_DELETE_SADATA ), NAME_VAL( GPS_DELETE_RTI ), NAME_VAL( GPS_DELETE_CELLDB_INFO ), NAME_VAL( GPS_DELETE_ALL) }; static int loc_eng_aiding_data_bit_num = sizeof(loc_eng_aiding_data_bits) / sizeof(loc_name_val_s_type); const char* loc_get_aiding_data_mask_names(GpsAidingData data) { return NULL; } static loc_name_val_s_type loc_eng_agps_types[] = { NAME_VAL( AGPS_TYPE_INVALID ), NAME_VAL( AGPS_TYPE_ANY ), NAME_VAL( AGPS_TYPE_SUPL ), NAME_VAL( AGPS_TYPE_C2K ), NAME_VAL( AGPS_TYPE_WWAN_ANY ) }; static int loc_eng_agps_type_num = sizeof(loc_eng_agps_types) / sizeof(loc_name_val_s_type); const char* loc_get_agps_type_name(AGpsType type) { return loc_get_name_from_val(loc_eng_agps_types, loc_eng_agps_type_num, (long) type); } static loc_name_val_s_type loc_eng_ni_types[] = { NAME_VAL( GPS_NI_TYPE_VOICE ), NAME_VAL( GPS_NI_TYPE_UMTS_SUPL ), NAME_VAL( GPS_NI_TYPE_UMTS_CTRL_PLANE ), NAME_VAL( GPS_NI_TYPE_EMERGENCY_SUPL ) }; static int loc_eng_ni_type_num = sizeof(loc_eng_ni_types) / sizeof(loc_name_val_s_type); const char* loc_get_ni_type_name(GpsNiType type) { return loc_get_name_from_val(loc_eng_ni_types, loc_eng_ni_type_num, (long) type); } static loc_name_val_s_type loc_eng_ni_responses[] = { NAME_VAL( GPS_NI_RESPONSE_ACCEPT ), NAME_VAL( GPS_NI_RESPONSE_DENY ), NAME_VAL( GPS_NI_RESPONSE_DENY ) }; static int loc_eng_ni_reponse_num = sizeof(loc_eng_ni_responses) / sizeof(loc_name_val_s_type); const char* loc_get_ni_response_name(GpsUserResponseType response) { return loc_get_name_from_val(loc_eng_ni_responses, loc_eng_ni_reponse_num, (long) response); } static loc_name_val_s_type loc_eng_ni_encodings[] = { NAME_VAL( GPS_ENC_NONE ), NAME_VAL( GPS_ENC_SUPL_GSM_DEFAULT ), NAME_VAL( GPS_ENC_SUPL_UTF8 ), NAME_VAL( GPS_ENC_SUPL_UCS2 ), NAME_VAL( GPS_ENC_UNKNOWN ) }; static int loc_eng_ni_encoding_num = sizeof(loc_eng_ni_encodings) / sizeof(loc_name_val_s_type); const char* loc_get_ni_encoding_name(GpsNiEncodingType encoding) { return loc_get_name_from_val(loc_eng_ni_encodings, loc_eng_ni_encoding_num, (long) encoding); } static loc_name_val_s_type loc_eng_agps_bears[] = { NAME_VAL( AGPS_APN_BEARER_INVALID ), NAME_VAL( AGPS_APN_BEARER_IPV4 ), NAME_VAL( AGPS_APN_BEARER_IPV6 ), NAME_VAL( AGPS_APN_BEARER_IPV4V6 ) }; static int loc_eng_agps_bears_num = sizeof(loc_eng_agps_bears) / sizeof(loc_name_val_s_type); const char* loc_get_agps_bear_name(AGpsBearerType bearer) { return loc_get_name_from_val(loc_eng_agps_bears, loc_eng_agps_bears_num, (long) bearer); } static loc_name_val_s_type loc_eng_server_types[] = { NAME_VAL( LOC_AGPS_CDMA_PDE_SERVER ), NAME_VAL( LOC_AGPS_CUSTOM_PDE_SERVER ), NAME_VAL( LOC_AGPS_MPC_SERVER ), NAME_VAL( LOC_AGPS_SUPL_SERVER ) }; static int loc_eng_server_types_num = sizeof(loc_eng_server_types) / sizeof(loc_name_val_s_type); const char* loc_get_server_type_name(LocServerType type) { return loc_get_name_from_val(loc_eng_server_types, loc_eng_server_types_num, (long) type); } static loc_name_val_s_type loc_eng_position_sess_status_types[] = { NAME_VAL( LOC_SESS_SUCCESS ), NAME_VAL( LOC_SESS_INTERMEDIATE ), NAME_VAL( LOC_SESS_FAILURE ) }; static int loc_eng_position_sess_status_num = sizeof(loc_eng_position_sess_status_types) / sizeof(loc_name_val_s_type); const char* loc_get_position_sess_status_name(enum loc_sess_status status) { return loc_get_name_from_val(loc_eng_position_sess_status_types, loc_eng_position_sess_status_num, (long) status); } static loc_name_val_s_type loc_eng_agps_status_names[] = { NAME_VAL( GPS_REQUEST_AGPS_DATA_CONN ), NAME_VAL( GPS_RELEASE_AGPS_DATA_CONN ), NAME_VAL( GPS_AGPS_DATA_CONNECTED ), NAME_VAL( GPS_AGPS_DATA_CONN_DONE ), NAME_VAL( GPS_AGPS_DATA_CONN_FAILED ) }; static int loc_eng_agps_status_num = sizeof(loc_eng_agps_status_names) / sizeof(loc_name_val_s_type); const char* loc_get_agps_status_name(AGpsStatusValue status) { return loc_get_name_from_val(loc_eng_agps_status_names, loc_eng_agps_status_num, (long) status); } ================================================ FILE: gps/core/loc_core_log.h ================================================ /* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef LOC_CORE_LOG_H #define LOC_CORE_LOG_H #ifdef __cplusplus extern "C" { #endif #include #include const char* loc_get_gps_status_name(GpsStatusValue gps_status); const char* loc_get_position_mode_name(GpsPositionMode mode); const char* loc_get_position_recurrence_name(GpsPositionRecurrence recur); const char* loc_get_aiding_data_mask_names(GpsAidingData data); const char* loc_get_agps_type_name(AGpsType type); const char* loc_get_ni_type_name(GpsNiType type); const char* loc_get_ni_response_name(GpsUserResponseType response); const char* loc_get_ni_encoding_name(GpsNiEncodingType encoding); const char* loc_get_agps_bear_name(AGpsBearerType bear); const char* loc_get_server_type_name(LocServerType type); const char* loc_get_position_sess_status_name(enum loc_sess_status status); const char* loc_get_agps_status_name(AGpsStatusValue status); #ifdef __cplusplus } #endif #endif /* LOC_CORE_LOG_H */ ================================================ FILE: gps/etc/Android.mk ================================================ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := flp.conf LOCAL_MODULE_TAGS := optional LOCAL_MODULE_CLASS := ETC LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/ LOCAL_SRC_FILES := flp.conf include $(BUILD_PREBUILT) include $(CLEAR_VARS) LOCAL_MODULE := gps.conf LOCAL_MODULE_TAGS := optional LOCAL_MODULE_CLASS := ETC LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/ LOCAL_SRC_FILES := gps.conf include $(BUILD_PREBUILT) include $(CLEAR_VARS) LOCAL_MODULE := izat.conf LOCAL_MODULE_TAGS := optional LOCAL_MODULE_CLASS := ETC LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/ LOCAL_SRC_FILES := izat.conf include $(BUILD_PREBUILT) include $(CLEAR_VARS) LOCAL_MODULE := lowi.conf LOCAL_MODULE_TAGS := optional LOCAL_MODULE_CLASS := ETC LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/ LOCAL_SRC_FILES := lowi.conf include $(BUILD_PREBUILT) include $(CLEAR_VARS) LOCAL_MODULE := sap.conf LOCAL_MODULE_TAGS := optional LOCAL_MODULE_CLASS := ETC LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/ LOCAL_SRC_FILES := sap.conf include $(BUILD_PREBUILT) include $(CLEAR_VARS) LOCAL_MODULE := xtwifi.conf LOCAL_MODULE_TAGS := optional LOCAL_MODULE_CLASS := ETC LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/ LOCAL_SRC_FILES := xtwifi.conf include $(BUILD_PREBUILT) ================================================ FILE: gps/etc/flp.conf ================================================ ################################### ##### FLP settings ##### ################################### ################################### # FLP BATCHING SIZE ################################### # The number of batched locations # requested to modem. The desired number # defined below may not be satisfied, as # the modem can only return the number # of batched locations that can be allocated, # which is limited by memory. The default # batch size defined as 20 as below. BATCH_SIZE=20 ################################### # FLP BATCHING SESSION TIMEOUT ################################### # Duration with which batch session timeout # happens in milliseconds. If not specified # or set to zero, batching session timeout # defaults to 20 seconds by the modem. # BATCH_SESSION_TIMEOUT=20000 ################################### # FLP CAPABILITIES BIT MASK ################################### # GEOFENCE = 0x01 # BATCHING = 0x02 # default = GEOFENCE | BATCHING CAPABILITIES=0x03 ################################### # FLP BATCHING ACCURACY ################################### # Set to one of the defined values below # to define the accuracy of batching. # If not specified, accuracy defaults # to LOW. # FLP BATCHING ACCURACY values: # Low accuracy = 0 # Medium accuracy = 1 # High accuracy = 2 ACCURACY=0 ################################### # FLP GEOFENCE RESPONSIVENESS ################################### # If set to one of the defined values below, # it will override the responsiveness for # FLP geofence, which implements the fused # location API. If not set to a value defined # below, which is default, it will not # override the responsivness. # FLP_GEOFENCE_RESPONSIVENESS_OVERRIDE Values: # 1: LOW responsiveness # 2: MEDIUM responsiveness # 3: HIGH responsiveness FLP_GEOFENCE_RESPONSIVENESS_OVERRIDE = 0 ================================================ FILE: gps/etc/gps.conf ================================================ #Uncommenting these urls would only enable #the power up auto injection and force injection(test case). #XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra2.bin #XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra2.bin #XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra2.bin #ifdef VENDOR_EDIT # zuoyonghua@oneplus.cn add gps xtra server for speed up gps cold start XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin #endif #Version check for XTRA #DISABLE = 0 #AUTO = 1 #XTRA2 = 2 #XTRA3 = 3 XTRA_VERSION_CHECK=0 # Error Estimate # _SET = 1 # _CLEAR = 0 ERR_ESTIMATE=0 #Test NTP_SERVER=time.gpsonextra.net #Asia # NTP_SERVER=asia.pool.ntp.org #Europe # NTP_SERVER=europe.pool.ntp.org #North America # NTP_SERVER=north-america.pool.ntp.org # DEBUG LEVELS: 0 - none, 1 - Error, 2 - Warning, 3 - Info # 4 - Debug, 5 - Verbose # If DEBUG_LEVEL is commented, Android's logging levels will be used DEBUG_LEVEL = 2 # Intermediate position report, 1=enable, 0=disable INTERMEDIATE_POS=0 # Below bit mask configures how GPS functionalities # should be locked when user turns off GPS on Settings # Set bit 0x1 if MO GPS functionalities are to be locked # Set bit 0x2 if NI GPS functionalities are to be locked # default - non is locked for backward compatibility #GPS_LOCK = 0 # supl version 1.0 SUPL_VER=0x10000 # Emergency SUPL, 1=enable, 0=disable SUPL_ES=0 #Choose PDN for Emergency SUPL #1 - Use emergency PDN #0 - Use regular SUPL PDN for Emergency SUPL USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1 #SUPL_MODE is a bit mask set in config.xml per carrier by default. #If it is uncommented here, this value will over write the value from #config.xml. #MSA=0X2 #MSB=0X1 #SUPL_MODE= # GPS Capabilities bit mask # SCHEDULING = 0x01 # MSB = 0x02 # MSA = 0x04 # ON_DEMAND_TIME = 0x10 # GEOFENCE = 0x20 # default = ON_DEMAND_TIME | MSA | MSB | SCHEDULING | GEOFENCE CAPABILITIES=0x31 # Accuracy threshold for intermediate positions # less accurate positions are ignored, 0 for passing all positions # ACCURACY_THRES=5000 ################################ ##### AGPS server settings ##### ################################ # FOR SUPL SUPPORT, set the following # SUPL_HOST=supl.host.com or IP # SUPL_PORT=1234 # FOR C2K PDE SUPPORT, set the following # C2K_HOST=c2k.pde.com or IP # C2K_PORT=1234 # Bitmask of slots that are available # for write/install to, where 1s indicate writable, # and the default value is 0 where no slots # are writable. For example, AGPS_CERT_WRITABLE_MASK # of b1000001010 makes 3 slots available # and the remaining 7 slots unwritable. #AGPS_CERT_WRITABLE_MASK=0 #################################### # LTE Positioning Profile Settings #################################### # 0: Enable RRLP on LTE(Default) # 1: Enable LPP_User_Plane on LTE # 2: Enable LPP_Control_Plane # 3: Enable both LPP_User_Plane and LPP_Control_Plane LPP_PROFILE = 0 ################################ # EXTRA SETTINGS ################################ # NMEA provider (1=Modem Processor, 0=Application Processor) NMEA_PROVIDER=0 # Mark if it is a SGLTE target (1=SGLTE, 0=nonSGLTE) SGLTE_TARGET=0 ################################################## # Select Positioning Protocol on A-GLONASS system ################################################## # 0x1: RRC CPlane # 0x2: RRLP UPlane # 0x4: LLP Uplane #ifndef zuoyonghua@oneplus.cn enable all bit mask for GLONASS #A_GLONASS_POS_PROTOCOL_SELECT = 0 #else A_GLONASS_POS_PROTOCOL_SELECT = 15 #endif ================================================ FILE: gps/etc/izat.conf ================================================ ######################################### # Log verbosity control for izat modules ######################################### # OFF = 0, ERROR = 1, WARNING = 2, INFO = 3, DEBUG = 4, VERBOSE = 5 IZAT_DEBUG_LEVEL = 2 ################################################## # Select WIFI Wait Timeout value in seconds for SUPL ################################################## WIFI_WAIT_TIMEOUT_SELECT = 0 ################################ # NLP Settings ################################ # NLP_MODE 1: GNP Only, 2: QNP Only, 3: Combo # NLP_TOLERANCE_TIME_FIRST: Time in ms used in Combo mode # to determine how much Tolerance for first position # NLP_TOLERANCE_TIME_AFTER: Time in ms used in Combo mode # to determine how much Tolerance for positions after first # NLP_THRESHOLD: Sets how many failures needed before # switching preferred NLP in Combo mode # NLP_ACCURACY_MULTIPLE: Determines how far off the accuracy # must be, in multiples, between two NLP location reports to # be considered much worse accuracy. Used in switching logic # NLP COMBO MODE USES QNP WITH NO EULA CONSENT: Determines # whether or not to still send network location requests to # QNP when the EULA is not consented to by the user. QNP can # still return ZPP locations or injected locations even # without EULA consent, but the uncertainty can be high. NLP_MODE = 3 NLP_TOLERANCE_TIME_FIRST = 5000 NLP_TOLERANCE_TIME_AFTER = 20000 NLP_THRESHOLD = 3 NLP_ACCURACY_MULTIPLE = 2 NLP_COMBO_MODE_USES_QNP_WITH_NO_EULA_CONSENT = 1 # Threshold period for ZPP triggers ZPP_TRIGGER_THRESHOLD=60000 ################################### # GEOFENCE SERVICES ################################### # If set to one of the defined values below, it will override # the responsiveness for geofence services, which implements # the Proximity Alert API. If not set to a value defined below, # which is default, it will not override the responsivness. # The geofence HAL API is unaffected by this value. # GEOFENCE_SERVICES_RESPONSIVENESS_OVERRIDE Values: # 1: LOW responsiveness # 2: MEDIUM responsiveness # 3: HIGH responsiveness GEOFENCE_SERVICES_RESPONSIVENESS_OVERRIDE = 0 ##################################### # IZAT PREMIUM FEATURE SETTINGS ##################################### #Possible states of a feature: #DISABLED #BASIC #PREMIUM #GTP_CELL_PROC valid options: # AP # MODEM GTP_CELL_PROC=MODEM #GTP_CELL valid modes: # DISABLED # BASIC GTP_CELL=DISABLED #GTP_WIFI valid modes: # DISABLED # BASIC GTP_WIFI=DISABLED #GTP_WAA valid modes: # DISABLED # BASIC GTP_WAA=DISABLED #SAP valid modes: # DISABLED # BASIC # PREMIUM SAP=DISABLED #ODCPI valid modes: #DISABLED #BASIC ODCPI=DISABLED #FREE_WIFI_SCAN_INJECT valid modes: #DISABLED #BASIC FREE_WIFI_SCAN_INJECT=DISABLED #SUPL_WIFI valid modes: #DISABLED #BASIC SUPL_WIFI=DISABLED #WIFI_SUPPLICANT_INFO valid modes: #DISABLED #BASIC WIFI_SUPPLICANT_INFO=DISABLED ##################################### # Location process launcher settings ##################################### #Values for PROCESS_STATE: # ENABLED # DISABLED #FEATURE MASKS: # GTP-WIFI 0X03 # GTP-AP-CELL 0X0c # GTP-MP-CELL 0xc00 # GTP-WAA 0X300 # SAP 0Xc0 # ODCPI 0x1000 # FREE_WIFI_SCAN_INJECT 0x2000 # SUPL_WIFI 0x4000 # WIFI_SUPPLICANT_INFO 0x8000 #Values for PLATFORMS can be: #1. Any valid values obtained from ro.board.platform separated by single space. For example: msm8960 msm8226 #2. all -> for All platforms #Values for BASEBAND can be: #1. Any valid values obtained from ro.baseband separated by single space. For example: sglte sglte2 #2. all -> for all basebands #Valyes for LEAN_TARGETS can be: #ENABLED -> if this process is supposed to run on lean and mean targets #DISABLED -> if this process is to be disabled on lean and mean targets PROCESS_NAME=/system/bin/garden_app PROCESS_ARGUMENT=-u 0 -q 0 -j 0 -g 0 -l 0 -Z 0 -T 1 PROCESS_STATE=DISABLED PROCESS_GROUPS=gps net_raw PREMIUM_FEATURE=0 IZAT_FEATURE_MASK=0 PLATFORMS=all BASEBAND=auto LEAN_TARGETS=DISABLED PROCESS_NAME=/system/bin/gpsone_daemon PROCESS_ARGUMENT= PROCESS_STATE=DISABLED PROCESS_GROUPS=inet net_raw PREMIUM_FEATURE=0 IZAT_FEATURE_MASK=0 PLATFORMS=msm7630_fusion BASEBAND=svlte2a sglte sglte2 LEAN_TARGETS=DISABLED PROCESS_NAME=/system/bin/lowi-server PROCESS_ARGUMENT= PROCESS_STATE=DISABLED PROCESS_GROUPS=gps net_admin wifi inet qcom_diag net_raw PREMIUM_FEATURE=0 IZAT_FEATURE_MASK=0xf303 PLATFORMS=all BASEBAND=all LEAN_TARGETS=DISABLED PROCESS_NAME=/system/bin/xtwifi-inet-agent PROCESS_ARGUMENT= PROCESS_STATE=DISABLED PROCESS_GROUPS=inet gps PREMIUM_FEATURE=1 IZAT_FEATURE_MASK=0xc0f PLATFORMS=all BASEBAND=all LEAN_TARGETS=DISABLED PROCESS_NAME=/system/bin/xtwifi-client PROCESS_ARGUMENT= PROCESS_STATE=DISABLED PROCESS_GROUPS=net_admin wifi inet gps net_raw rfs_shared PREMIUM_FEATURE=1 IZAT_FEATURE_MASK=0xf0f PLATFORMS=all BASEBAND=all LEAN_TARGETS=DISABLED PROCESS_NAME=/system/vendor/bin/slim_daemon PROCESS_ARGUMENT= PROCESS_STATE=DISABLED PROCESS_GROUPS=gps net_raw qcom_diag PREMIUM_FEATURE=1 IZAT_FEATURE_MASK=0xf0 PLATFORMS=all BASEBAND=all LEAN_TARGETS=DISABLED ================================================ FILE: gps/etc/lowi.conf ================================================ #*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====* # # LOWI Config file # # GENERAL DESCRIPTION # This file contains the config params for LOWI # # Copyright (c) 2012-2013 Qualcomm Atheros, Inc. # All Rights Reserved. # Qualcomm Atheros Confidential and Proprietary. # # Export of this technology or software is regulated by the U.S. Government. # Diversion contrary to U.S. law prohibited. #=============================================================================*/ # X86 ONLY - UBUNTU: # Copy this file in the same directory where the executable is # The RSSI threshold used in the RTT outlier detection in half decibels. Default value recommended by the # system team currently is -140 (corresponding to -70 dB). LOWI_RSSI_THRESHOLD_FOR_RTT = -140 # Number of measurment per AP for RTS/CTS LOWI_RTS_CTS_NUM_MEAS = 5 # Maximum Number of Outstanding Requests supported LOWI_MAX_OUTSTANDING_REQUEST = 255 # Maximum number of records in Cache LOWI_MAX_NUM_CACHE_RECORDS = 200 # Default threshold before issuing another fresh scan (ms) LOWI_FRESH_SCAN_THRESHOLD = 500 # Timeout in case no result is reported by the driver (seconds) LOWI_NO_RESULT_WAIT_TOLERANCE = 10 # Use Fake Wifi driver. Only valid for engineering builds LOWI_USE_FAKE_WIFI_DRIVER = 0 # Use ROME Wifi driver. Only valid for engineering builds # Will be removed later only for development support LOWI_USE_ROME_WIFI_DRIVER = 0 # Use LOWI LP. # When enabled the Discovery Request will be routed to LOWI-LP LOWI_USE_LOWI_LP = 1 # Log level # EL_LOG_OFF = 0, EL_ERROR = 1, EL_WARNING = 2, EL_INFO = 3, EL_DEBUG = 4, EL_VERBOSE = 5, EL_LOG_ALL = 100 LOWI_LOG_LEVEL = 2 ================================================ FILE: gps/etc/sap.conf ================================================ ################################ # Sensor Settings ################################ #The following parameters are optional. #Internal defaults support MEMS sensors #native to most handset devices. #Device specific sensor characterization #for improved performance is possible as #described in SAP application notes. #GYRO_BIAS_RANDOM_WALK= #ACCEL_RANDOM_WALK_SPECTRAL_DENSITY= #ANGLE_RANDOM_WALK_SPECTRAL_DENSITY= #RATE_RANDOM_WALK_SPECTRAL_DENSITY= #VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY= # Sensor Sampling Rate Parameters for Low-Data Rate Filter (should be greater than 0) # used in loc_eng_reinit SENSOR_ACCEL_BATCHES_PER_SEC=2 SENSOR_ACCEL_SAMPLES_PER_BATCH=5 SENSOR_GYRO_BATCHES_PER_SEC=2 SENSOR_GYRO_SAMPLES_PER_BATCH=5 # Sensor Sampling Rate Parameters for High-Data Rate Filter (should be greater than 0) SENSOR_ACCEL_BATCHES_PER_SEC_HIGH=4 SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH=25 SENSOR_GYRO_BATCHES_PER_SEC_HIGH=4 SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH=25 # Sensor Control Mode (0=AUTO, 1=FORCE_ON) # used in loc_eng_reinit SENSOR_CONTROL_MODE=0 # Enable or Disable Sensors for GPS use (0=Enable, 1=Disable) # used in loc_eng_reinit SENSOR_USAGE=0 # Choose GSIFF sensor provider (1=Snapdragon Sensors Core, 2=Android NDK) SENSOR_PROVIDER=1 # Bit mask used to define which sensor algorithms are used. # Setting each bit has the following definition: # 0x1 - DISABLE_INS_POSITIONING_FILTER # 0x0 - ENABLE_INS_POSITIONING_FILTER SENSOR_ALGORITHM_CONFIG_MASK=0x1 # Time source used by Sensor HAL # Setting this value controls accuracy of location sensor services. # 0 - Unknown # 1 - CLOCK_BOOTTIME # 2 - CLOCK_MONOTONIC # 3 - CLOCK_REALTIME # 4 - CLOCK_BOOTTIME using Alarm timer interface NDK_PROVIDER_TIME_SOURCE=1 ================================================ FILE: gps/etc/xtwifi.conf ================================================ #GTP AP Project client core config file # #GENERAL DESCRIPTION #This is used by client core # #Copyright (c) 2012-2014 Qualcomm Atheros, Inc. #All Rights Reserved. #Qualcomm Atheros Confidential and Proprietary. # Log verbosity control for most of the GTP WiFi system, including native and # Java componenets # OFF = 0, ERROR = 1, WARNING = 2, INFO = 3, DEBUG = 4, VERBOSE = 5, ALL = 100 DEBUG_GLOBAL_LOG_LEVEL = 2 # this is used at the server side to distinguish uploads from different maker/model # default "Qualcomm" OEM_ID_IN_REQUEST_TO_SERVER = "Qualcomm" # this is used at the server side to distinguish uploads from different maker/model # default "UNKNOWN" MODEL_ID_IN_REQUEST_TO_SERVER = "UNKNOWN" ############################################################################## # GTP-WiFi positioning config # ############################################################################## # URL for the server position request XT_SERVER_ROOT_URL = https://gtpa1.izatcloud.net:443/uds/v2 # size, in bytes, of the cache on device SIZE_BYTE_TOTAL_CACHE = 5000000 # value 0: (default) use the async LOWI wifi scanner # value 10: FAKE AP wifi scanner WIFI_SCANNER_CHOICE = 0 ############################################################################## # XT-WiFi crowd sourcing config # ############################################################################## # Use server suggestion for crowd sourcing configuration ENABLE_SERVER_SUGGESTION_FOR_CROWD_SOURCING = 1 # Maximum number of APs to be collected for upload NUM_MAX_AP_PER_UPLOAD = 16383 # Number of minutes between upload: 24 hours INTERVAL_MIN_UPLOAD = 1440 # Number of minutes between forced upload: 5 days INTERVAL_MIN_FORCED_UPLOAD = 7200 # The minimum time between two collected AP data sets in seconds INTERVAL_SEC_AP_SETS_COLLECT = 10 # Timeout for scan interval when phone is on: 600 seconds (10 minute) INTERVAL_SEC_SCAN = 600 # Timeout for scan interval when phone has not continusouly on for INTERVAL_MIN_SCAN INTERVAL_MIN_FORCED_SCAN = 480 # Maximum number of Cell DB records for upload WWAN_MAX_CELLDB_RECORDS_PER_UPLOAD = 1000 ############################################################################## # GTP AP cell config # ############################################################################## # This item specifies the RIL server name. # This configure item can not be removed in Android target. XTRAT_WWAN_LITE_LOC_RIL_SERVER_NAME = "OS-Agent" # Maximum total number of SNA records cached in mobile storage. # Max allowed value is 10000 # Min value is 100 XTRAT_WWAN_LITE_MAX_DL_SNA = 10000 # Maximum total number of BSA records cached in mobile storage. # Max allowed value is 65000 # Min value is 100 XTRAT_WWAN_LITE_MAX_DL_BSA = 65000 ############################################################################## # Qualcomm Network Location Provider config # ############################################################################## # Accuracy Threshold for NLP position. Position exceeds thsi threshold will be filtered out. # Default is 25000 meters. LARGE_ACCURACY_THRESHOLD_TO_FILTER_NLP_POSITION = 25000 ================================================ FILE: gps/loc-api.pc.in ================================================ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: loc-api Description: Qualcomm GPS Location API Version: @VERSION@ Libs: -L${libdir} -lgps_utils_so -lloc_adapter_so -lloc_eng_so -lgps_default_so -lloc_api Cflags: -I${includedir}/loc-api/libloc_api_50001 -I${includedir}/loc-api/utils -I${includedir}/ -I${includedir}/loc-api ================================================ FILE: gps/loc_api/Android.mk ================================================ LOCAL_PATH := $(call my-dir) # add RPC dirs if RPC is available ifneq ($(TARGET_NO_RPC),true) GPS_DIR_LIST += $(LOCAL_PATH)/libloc_api-rpc-50001/ endif #TARGET_NO_RPC GPS_DIR_LIST += $(LOCAL_PATH)/libloc_api_50001/ #call the subfolders include $(addsuffix Android.mk, $(GPS_DIR_LIST)) ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/Android.mk ================================================ ifeq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_AMSS_VERSION),50001) include $(call all-subdir-makefiles) endif ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/libloc_api-rpc-glue/Android.mk ================================================ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) RPC_INC:=rpc_inc source_files:= \ src/loc_api_rpc_glue.c \ src/loc_api_sync_call.c \ src/loc_apicb_appinit.c \ src/loc_api_fixup.c \ src/loc_api_log.c \ src/LocApiRpc.cpp LOCAL_SRC_FILES:= $(source_files) LOCAL_CFLAGS:=-fno-short-enums LOCAL_CFLAGS+=-DDEBUG -DUSE_QCOM_AUTO_RPC -DUSE_QCOM_AUTO_RPC LOCAL_CFLAGS+=$(GPS_FEATURES) # for loc_api_fixup.c LOCAL_CFLAGS+=-DADD_XDR_FLOAT -DADD_XDR_BOOL LOCAL_SHARED_LIBRARIES:= \ librpc \ libutils \ libcutils \ libcommondefs \ libgps.utils \ libloc_core LOCAL_STATIC_LIBRARIES := \ libloc_api_rpcgen LOCAL_PRELINK_MODULE:= false LOCAL_C_INCLUDES:= \ $(LOCAL_PATH) \ $(LOCAL_PATH)/rpc_inc \ $(TARGET_OUT_HEADERS)/gps.utils \ $(TARGET_OUT_HEADERS)/libloc_core \ $(TARGET_OUT_HEADERS)/loc_api/rpcgen/inc \ $(TARGET_OUT_HEADERS)/libcommondefs/rpcgen/inc \ $(TARGET_OUT_HEADERS)/librpc \ $(TARGET_OUT_HEADERS)/libloc-rpc/rpc_inc \ $(TOP)/hardware/msm7k/librpc LOCAL_COPY_HEADERS_TO:= libloc_api-rpc-qc/$(RPC_INC) LOCAL_COPY_HEADERS:= \ $(RPC_INC)/loc_api_rpc_glue.h \ $(RPC_INC)/loc_api_fixup.h \ $(RPC_INC)/loc_api_sync_call.h \ $(RPC_INC)/loc_apicb_appinit.h \ $(RPC_INC)/LocApiRpc.h LOCAL_MODULE:= libloc_api-rpc-qc LOCAL_MODULE_OWNER := qcom LOCAL_MODULE_TAGS := optional include $(BUILD_SHARED_LIBRARY) ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/libloc_api-rpc-glue/Makefile.am ================================================ AM_CFLAGS = \ -I../../../utils \ -I../../../platform_lib_abstractions \ -I./rpc_inc \ -I../libloc_api-rpc-stub/inc \ -I../../libloc_api_50001 \ $(MSM7K_CFLAGS) \ -DUSE_QCOM_AUTO_RPC requiredlibs = \ ../../../utils/libgps_utils_so.la \ $(MSM7K_LIBS) h_sources = \ rpc_inc/loc_api_rpc_glue.h \ rpc_inc/loc_api_fixup.h \ rpc_inc/loc_api_sync_call.h \ rpc_inc/loc_apicb_appinit.h \ c_sources = \ src/loc_api_rpc_glue.c \ src/loc_api_sync_call.c \ src/loc_apicb_appinit.c \ src/loc_api_fixup.c \ src/loc_api_log.c \ src/LocApiRpcAdapter.cpp \ library_includedir = $(pkgincludedir)/libloc_api-rpc-50001/libloc_api-rpc-glue/rpc_inc library_include_HEADERS = $(h_sources) libloc_api_rpc_qc_la_SOURCES = $(c_sources) $(h_sources) if USE_GLIB libloc_api_rpc_qc_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@ libloc_api_rpc_qc_la_LDFLAGS = -lstdc++ -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0 libloc_api_rpc_qc_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@ else libloc_api_rpc_qc_la_CFLAGS = $(AM_CFLAGS) libloc_api_rpc_qc_la_LDFLAGS = -lpthread -shared -version-info 1:0:0 libloc_api_rpc_qc_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS) endif libloc_api_rpc_qc_la_LIBADD = $(requiredlibs) -lstdc++ #Create and Install Libraries lib_LTLIBRARIES = libloc_api_rpc_qc.la ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/libloc_api-rpc-glue/rpc_inc/LocApiRpc.h ================================================ /* Copyright (c) 2011,2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef LOC_API_RPC_H #define LOC_API_RPC_H #include #include #include #include #include using namespace loc_core; class LocApiRpc : public LocApiBase { protected: // RPC communication establishment rpc_loc_client_handle_type client_handle; private: int dataEnableLastSet; char apnLastSet[MAX_APN_LEN]; static const LOC_API_ADAPTER_EVENT_MASK_T maskAll; static const rpc_loc_event_mask_type locBits[]; static rpc_loc_event_mask_type convertMask(LOC_API_ADAPTER_EVENT_MASK_T mask); static rpc_loc_lock_e_type convertGpsLockMask(LOC_GPS_LOCK_MASK lockMask); static enum loc_api_adapter_err convertErr(int rpcErr); static GpsNiEncodingType convertNiEncodingType(int loc_encoding); static int NIEventFillVerfiyType(GpsNiNotification ¬if, rpc_loc_ni_notify_verify_e_type notif_priv); void reportPosition(const rpc_loc_parsed_position_s_type *location_report_ptr); void reportSv(const rpc_loc_gnss_info_s_type *gnss_report_ptr); void reportStatus(const rpc_loc_status_event_s_type *status_report_ptr); void reportNmea(const rpc_loc_nmea_report_s_type *nmea_report_ptr); void ATLEvent(const rpc_loc_server_request_s_type *server_request_ptr); void NIEvent(const rpc_loc_ni_event_s_type *ni_req_ptr); protected: virtual enum loc_api_adapter_err open(LOC_API_ADAPTER_EVENT_MASK_T mask); virtual enum loc_api_adapter_err close(); public: LocApiRpc(const MsgTask* msgTask, LOC_API_ADAPTER_EVENT_MASK_T exMask); ~LocApiRpc(); virtual int locEventCB(rpc_loc_client_handle_type client_handle, rpc_loc_event_mask_type loc_event, const rpc_loc_event_payload_u_type* loc_event_payload); void locRpcGlobalCB(CLIENT* clnt, enum rpc_reset_event event); // RPC adapter interface implementations virtual enum loc_api_adapter_err startFix(const LocPosMode& posMode); virtual enum loc_api_adapter_err stopFix(); virtual enum loc_api_adapter_err setPositionMode(const LocPosMode& mode); inline virtual enum loc_api_adapter_err enableData(int enable) { return enableData(enable, false); } virtual enum loc_api_adapter_err enableData(int enable, boolean force); virtual enum loc_api_adapter_err setTime(GpsUtcTime time, int64_t timeReference, int uncertainty); virtual enum loc_api_adapter_err injectPosition(double latitude, double longitude, float accuracy); virtual enum loc_api_adapter_err deleteAidingData(GpsAidingData f); virtual enum loc_api_adapter_err informNiResponse(GpsUserResponseType userResponse, const void* passThroughData); inline virtual enum loc_api_adapter_err setAPN(char* apn, int len) { return setAPN(apn, len, false); } virtual enum loc_api_adapter_err setAPN(char* apn, int len, boolean force); virtual enum loc_api_adapter_err setServer(const char* url, int len); virtual enum loc_api_adapter_err setServer(unsigned int ip, int port, LocServerType type); virtual enum loc_api_adapter_err setXtraData(char* data, int length); virtual enum loc_api_adapter_err requestXtraServer(); virtual enum loc_api_adapter_err atlOpenStatus(int handle, int is_succ, char* apn, AGpsBearerType bear, AGpsType agpsType); virtual enum loc_api_adapter_err atlCloseStatus(int handle, int is_succ); virtual enum loc_api_adapter_err setSUPLVersion(uint32_t version); virtual void setInSession(bool inSession); /*Values for lock 1 = Do not lock any position sessions 2 = Lock MI position sessions 3 = Lock MT position sessions 4 = Lock all position sessions */ virtual int setGpsLock(LOC_GPS_LOCK_MASK lock); /* Returns Current value of GPS Lock on success -1 on failure */ virtual int getGpsLock(void); }; extern "C" LocApiBase* getLocApi(const MsgTask* msgTask, LOC_API_ADAPTER_EVENT_MASK_T exMask, ContextBase *context); #endif //LOC_API_RPC_H ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/libloc_api-rpc-glue/rpc_inc/debug.h ================================================ /* Copyright (c) 2011, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef DEBUG_H #define DEBUG_H #include #define LOG_TAG "LocSvc_rpc" #include #define PRINT(x...) do { \ fprintf(stdout, "%s(%d) ", __FUNCTION__, __LINE__); \ fprintf(stdout, ##x); \ ALOGD(x); \ } while(0) #ifdef DEBUG #define D PRINT #else #define D(x...) do { } while(0) #endif #ifdef VERBOSE #define V PRINT #else #define V(x...) do { } while(0) #endif #define E(x...) do { \ fprintf(stderr, "%s(%d) ", __FUNCTION__, __LINE__); \ fprintf(stderr, ##x); \ ALOGE(x); \ } while(0) #define FAILIF(cond, msg...) do { \ if (__builtin_expect (cond, 0)) { \ fprintf(stderr, "%s:%s:(%d): ", __FILE__, __FUNCTION__, __LINE__); \ fprintf(stderr, ##msg); \ ALOGE(##msg); \ } \ } while(0) #endif/*DEBUG_H*/ ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/libloc_api-rpc-glue/rpc_inc/loc_api_fixup.h ================================================ /* Copyright (c) 2011, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef LOC_API_FIXUP_H #define LOC_API_FIXUP_H #ifdef __cplusplus extern "C" { #endif #ifndef NULLPROC #define NULLPROC 0 #endif /* NULLPROC */ #ifdef ADD_XDR_FLOAT extern bool_t xdr_float (XDR *__xdrs, float *__fp); extern bool_t xdr_double (XDR *__xdrs, double *__dp); #endif /* ADD_XDR_FLOAT */ #ifdef ADD_XDR_BOOL extern bool_t xdr_bool(XDR *__xdrs, int *__bp); #endif /* ADD_XDR_BOOL */ #define RPC_LOC_API_MAJOR_VERSION_NUMBER 1 #define RPC_LOC_API_MINOR_VERSION_NUMBER 0 // Return value for loc_open in case of failure. #define RPC_LOC_CLIENT_HANDLE_INVALID -1 // Return value of loc api calls for loc_close, loc_start_fix, loc_stop_fix and loc_ioctl // These are also the status for the ioctl callback #define RPC_LOC_API_SUCCESS 0 #define RPC_LOC_API_GENERAL_FAILURE 1 #define RPC_LOC_API_UNSUPPORTED 2 #define RPC_LOC_API_INVALID_HANDLE 4 #define RPC_LOC_API_INVALID_PARAMETER 5 #define RPC_LOC_API_ENGINE_BUSY 6 #define RPC_LOC_API_PHONE_OFFLINE 7 #define RPC_LOC_API_TIMEOUT 8 // Special return value for loc api calls in case of RPC failure #define RPC_LOC_API_RPC_FAILURE (-1234) // Special return value for modem restart incurred RPC failure #define RPC_LOC_API_RPC_MODEM_RESTART (-1235) #define RPC_LOC_API_MAX_SV_COUNT 80 #define RPC_LOC_API_MAX_NMEA_STRING_LENGTH 1200 // Maximum server address that will be used in location API #define RPC_LOC_API_MAX_SERVER_ADDR_LENGTH 256 #define RPC_LOC_API_MAX_NUM_PREDICTED_ORBITS_SERVERS 3 #define RPC_LOC_API_MAX_NUM_NTP_SERVERS 3 #define RPC_LOC_EVENT_PARSED_POSITION_REPORT 0x00000001 // Position report comes in loc_parsed_position_s_type #define RPC_LOC_EVENT_SATELLITE_REPORT 0x00000002 // Satellite in view report #define RPC_LOC_EVENT_NMEA_1HZ_REPORT 0x00000004 // NMEA report at 1HZ rate #define RPC_LOC_EVENT_NMEA_POSITION_REPORT 0x00000008 // NMEA report at position report rate #define RPC_LOC_EVENT_NI_NOTIFY_VERIFY_REQUEST 0x00000010 // NI notification/verification request #define RPC_LOC_EVENT_ASSISTANCE_DATA_REQUEST 0x00000020 // Assistance data, eg: time, predicted orbits request #define RPC_LOC_EVENT_LOCATION_SERVER_REQUEST 0x00000040 // Request for location server #define RPC_LOC_EVENT_IOCTL_REPORT 0x00000080 // Callback report for loc_ioctl #define RPC_LOC_EVENT_STATUS_REPORT 0x00000100 // Misc status report: eg, engine state #define RPC_LOC_POS_VALID_SESSION_STATUS 0x00000001 #define RPC_LOC_POS_VALID_TIMESTAMP_CALENDAR 0x00000002 #define RPC_LOC_POS_VALID_TIMESTAMP_UTC 0x00000004 #define RPC_LOC_POS_VALID_LEAP_SECONDS 0x00000008 #define RPC_LOC_POS_VALID_TIME_UNC 0x00000010 #define RPC_LOC_POS_VALID_LATITUDE 0x00000020 #define RPC_LOC_POS_VALID_LONGITUDE 0x00000040 #define RPC_LOC_POS_VALID_ALTITUDE_WRT_ELLIPSOID 0x00000080 #define RPC_LOC_POS_VALID_ALTITUDE_WRT_MEAN_SEA_LEVEL 0x00000100 #define RPC_LOC_POS_VALID_SPEED_HORIZONTAL 0x00000200 #define RPC_LOC_POS_VALID_SPEED_VERTICAL 0x00000400 #define RPC_LOC_POS_VALID_HEADING 0x00000800 #define RPC_LOC_POS_VALID_HOR_UNC_CIRCULAR 0x00001000 #define RPC_LOC_POS_VALID_HOR_UNC_ELLI_SEMI_MAJ 0x00002000 #define RPC_LOC_POS_VALID_HOR_UNC_ELLI_SEMI_MIN 0x00004000 #define RPC_LOC_POS_VALID_HOR_UNC_ELLI_ORIENT_AZIMUTH 0x00008000 #define RPC_LOC_POS_VALID_VERTICAL_UNC 0x00010000 #define RPC_LOC_POS_VALID_SPEED_UNC 0x00020000 #define RPC_LOC_POS_VALID_HEADING_UNC 0x00040000 #define RPC_LOC_POS_VALID_CONFIDENCE_HORIZONTAL 0x00080000 #define RPC_LOC_POS_VALID_CONFIDENCE_VERTICAL 0x00100000 #define RPC_LOC_POS_VALID_MAGNETIC_VARIATION 0x00200000 #define RPC_LOC_POS_VALID_TECHNOLOGY_MASK 0x00400000 #define RPC_LOC_POS_TECH_SATELLITE 0x00000001 #define RPC_LOC_POS_TECH_CELLID 0x00000002 #define RPC_LOC_POS_TECH_WIFI 0x00000004 #define RPC_LOC_SV_INFO_VALID_SYSTEM 0x00000001 #define RPC_LOC_SV_INFO_VALID_PRN 0x00000002 #define RPC_LOC_SV_INFO_VALID_HEALTH_STATUS 0x00000004 #define RPC_LOC_SV_INFO_VALID_PROCESS_STATUS 0x00000008 #define RPC_LOC_SV_INFO_VALID_HAS_EPH 0x00000010 #define RPC_LOC_SV_INFO_VALID_HAS_ALM 0x00000020 #define RPC_LOC_SV_INFO_VALID_ELEVATION 0x00000040 #define RPC_LOC_SV_INFO_VALID_AZIMUTH 0x00000080 #define RPC_LOC_SV_INFO_VALID_SNR 0x00000100 #define RPC_LOC_GNSS_INFO_VALID_POS_DOP 0x00000001 #define RPC_LOC_GNSS_INFO_VALID_HOR_DOP 0x00000002 #define RPC_LOC_GNSS_INFO_VALID_VERT_DOP 0x00000004 #define RPC_LOC_GNSS_INFO_VALID_ALTITUDE_ASSUMED 0x00000008 #define RPC_LOC_GNSS_INFO_VALID_SV_COUNT 0x00000010 #define RPC_LOC_GNSS_INFO_VALID_SV_LIST 0x00000020 #define RPC_LOC_NI_MAX_REQUESTOR_ID_LENGTH 200 #define RPC_LOC_NI_SUPL_HASH_LENGTH 8 #define RPC_LOC_NI_SUPL_SLP_SESSION_ID_BYTE_LENGTH 4 #define RPC_LOC_NI_MAX_CLIENT_NAME_LENGTH 64 #define RPC_LOC_NI_MAX_EXT_CLIENT_ADDRESS 20 #define RPC_LOC_NI_CODEWORD_LENGTH 20 #define RPC_LOC_NI_SUPL_QOP_VALID 0x01 #define RPC_LOC_NI_SUPL_QOP_VERACC_VALID 0x02 #define RPC_LOC_NI_SUPL_QOP_MAXAGE_VALID 0x04 #define RPC_LOC_NI_SUPL_QOP_DELAY_VALID 0x08 #define RPC_LOC_FIX_CRIT_VALID_RECURRENCE_TYPE 0x00000001 #define RPC_LOC_FIX_CRIT_VALID_PREFERRED_OPERATION_MODE 0x00000002 #define RPC_LOC_FIX_CRIT_VALID_PREFERRED_ACCURACY 0x00000004 #define RPC_LOC_FIX_CRIT_VALID_PREFERRED_RESPONSE_TIME 0x00000008 #define RPC_LOC_FIX_CRIT_VALID_INTERMEDIATE_POS_REPORT_ENABLED 0x00000010 #define RPC_LOC_FIX_CRIT_VALID_NOTIFY_TYPE 0x00000020 #define RPC_LOC_FIX_CRIT_VALID_MIN_INTERVAL 0x00000040 #define RPC_LOC_FIX_CRIT_VALID_MIN_DISTANCE 0x00000080 #define RPC_LOC_FIX_CRIT_VALID_MIN_DIST_SAMPLE_INTERVAL 0x00000100 #define RPC_LOC_ASSIST_POS_VALID_TIMESTAMP_UTC 0x00000001 #define RPC_LOC_ASSIST_POS_VALID_LATITUDE 0x00000002 #define RPC_LOC_ASSIST_POS_VALID_LONGITUDE 0x00000004 #define RPC_LOC_ASSIST_POS_VALID_ALTITUDE_WRT_ELLIPSOID 0x00000008 #define RPC_LOC_ASSIST_POS_VALID_ALTITUDE_WRT_MEAN_SEA_LEVEL 0x00000010 #define RPC_LOC_ASSIST_POS_VALID_HOR_UNC_CIRCULAR 0x00000020 #define RPC_LOC_ASSIST_POS_VALID_VERT_UNC 0x00000040 #define RPC_LOC_ASSIST_POS_VALID_CONFIDENCE_HORIZONTAL 0x00000080 #define RPC_LOC_ASSIST_POS_VALID_CONFIDENCE_VERTICAL 0x00000100 #define RPC_LOC_ASSIST_POS_VALID_TIMESTAMP_AGE 0x00000200 #define RPC_LOC_ASSIST_DATA_ALL 0xFFFFFFFF #define RPC_LOC_NMEA_MASK_ALL 0xffff #define RPC_LOC_NMEA_MASK_GGA 0x0001 #define RPC_LOC_NMEA_MASK_RMC 0x0002 #define RPC_LOC_NMEA_MASK_GSV 0x0004 #define RPC_LOC_NMEA_MASK_GSA 0x0008 #define RPC_LOC_NMEA_MASK_VTG 0x0010 /* EFS data access */ #define RPC_LOC_EFS_MAX_PATH_LEN_BYTES 64 /* Max file name length in bytes that can be written*/ #define RPC_LOC_EFS_MAX_FILE_LEN_BYTES 2000 /* Max file size in bytes that can be written */ /* WIPER valid information flag in log report */ #define RPC_LOC_WIPER_LOG_TIME_VALID 0x01 #define RPC_LOC_WIPER_LOG_POS_VALID 0x02 #define RPC_LOC_WIPER_LOG_AP_SET_VALID 0x04 /* General WIPER defines */ #define RPC_LOC_WIPER_MAC_ADDR_LENGTH 6 // Do not change this number since it affects RPC and log packet sizes #define RPC_LOC_WIPER_MAX_REPORTED_APS_PER_LOG_MSG 50 // Do not change this number since it affects RPC and log packet sizes /* WIPER AP Qualifier */ #define RPC_LOC_WIPER_AP_QUALIFIER_BEING_USED 0x1 /* AP is being used by WPS */ #define RPC_LOC_WIPER_AP_QUALIFIER_HIDDEN_SSID 0x2 /* AP does not broadcast SSID */ #define RPC_LOC_WIPER_AP_QUALIFIER_PRIVATE 0x4 /* AP has encryption turned on */ #define RPC_LOC_WIPER_AP_QUALIFIER_INFRASTRUCTURE_MODE 0x8 /* AP is in infrastructure mode and not in ad-hoc/unknown mode */ /* flags for notification */ #define RPC_LOC_NI_CLIENT_NAME_PRESENT 0x0001 #define RPC_LOC_NI_CLIENT_EXTADDR_PRESENT 0x0002 #define RPC_LOC_NI_DEF_LOCATION_TYPE_PRESENT 0x0010 #define RPC_LOC_NI_REQUESTOR_ID_PRESENT 0x0020 #define RPC_LOC_NI_CODEWORD_PRESENT 0x0040 #define RPC_LOC_NI_SERVICE_TYPE_ID_PRESENT 0x0080 #define RPC_LOC_NI_ENCODING_TYPE_PRESENT 0x0100 /* below are for RPC_LOC_IOCTL_SET_LBS_APN_PROFILE data */ /* values for apn_profiles[0].srv_system_type */ #define LOC_APN_PROFILE_SRV_SYS_CDMA 0x01 #define LOC_APN_PROFILE_SRV_SYS_HDR 0x02 #define LOC_APN_PROFILE_SRV_SYS_GSM 0x04 #define LOC_APN_PROFILE_SRV_SYS_WCDMA 0x08 #define LOC_APN_PROFILE_SRV_SYS_LTE 0x10 #define LOC_APN_PROFILE_SRV_SYS_MAX 0x1F /* values for apn_profiles[0].pdp_type */ #define LOC_APN_PROFILE_PDN_TYPE_IPV4 0x01 #define LOC_APN_PROFILE_PDN_TYPE_IPV6 0x02 #define LOC_APN_PROFILE_PDN_TYPE_IPV4V6 0x03 #define LOC_APN_PROFILE_PDN_TYPE_PPP 0x04 #define LOC_APN_PROFILE_PDN_TYPE_MAX 0x04 #ifdef __cplusplus } #endif #endif /* LOC_API_FIXUP_H */ ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/libloc_api-rpc-glue/rpc_inc/loc_api_log.h ================================================ /* Copyright (c) 2011 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef LOC_API_LOG_H #define LOC_API_LOG_H #ifdef __cplusplus extern "C" { #endif #include #include "loc_api_rpcgen_common_rpc.h" extern int loc_callback_log( rpc_loc_event_mask_type loc_event, /* event mask */ const rpc_loc_event_payload_u_type* loc_event_payload /* payload */ ); extern const char* loc_get_event_atl_open_name(rpc_loc_server_request_e_type loc_event_atl_open); extern const char* loc_get_event_name(rpc_loc_event_mask_type loc_event_mask); extern const char* loc_get_ioctl_type_name(rpc_loc_ioctl_e_type ioctl_type); extern const char* loc_get_ioctl_status_name(uint32 status); extern const char* loc_get_sess_status_name(rpc_loc_session_status_e_type status); extern const char* loc_get_engine_state_name(rpc_loc_engine_state_e_type state); extern const char* loc_get_fix_session_state_name(rpc_loc_fix_session_state_e_type state); extern const char* loc_get_rpc_reset_event_name(enum rpc_reset_event event); #ifdef __cplusplus } #endif #endif /* LOC_API_LOG_H */ ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/libloc_api-rpc-glue/rpc_inc/loc_api_rpc_glue.h ================================================ /* Copyright (c) 2011, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef LOC_API_RPC_GLUE_H #define LOC_API_RPC_GLUE_H /* Include RPC headers */ #ifdef USE_LOCAL_RPC #include "rpc_inc/loc_api_common.h" #include "rpc_inc/loc_api.h" #include "rpc_inc/loc_api_cb.h" #endif #ifdef USE_QCOM_AUTO_RPC #include "loc_api_rpcgen_rpc.h" #include "loc_api_rpcgen_common_rpc.h" #include "loc_api_rpcgen_cb_rpc.h" #endif /* Boolean */ /* Other data types in comdef.h are defined in rpc stubs, so fix it here */ typedef unsigned char boolean; #define TRUE 1 #define FALSE 0 #include "loc_api_fixup.h" #include "loc_api_sync_call.h" #include #ifdef __cplusplus extern "C" { #endif extern int loc_api_glue_init(void); extern int loc_api_null(void); typedef int32 (loc_event_cb_f_type)( void* userData, rpc_loc_client_handle_type loc_handle, /* handle of the client */ rpc_loc_event_mask_type loc_event, /* event mask */ const rpc_loc_event_payload_u_type* loc_event_payload /* payload */ ); typedef void (loc_reset_notif_cb_f_type)( void* userData, CLIENT* clnt, enum rpc_reset_event event ); extern rpc_loc_client_handle_type loc_open( rpc_loc_event_mask_type event_reg_mask, loc_event_cb_f_type *event_callback, loc_reset_notif_cb_f_type *rpc_global_cb, void* userData ); extern int32 loc_close ( rpc_loc_client_handle_type handle ); extern void loc_clear ( rpc_loc_client_handle_type handle ); extern int32 loc_start_fix ( rpc_loc_client_handle_type handle ); extern int32 loc_stop_fix ( rpc_loc_client_handle_type handle ); extern int32 loc_ioctl ( rpc_loc_client_handle_type handle, rpc_loc_ioctl_e_type ioctl_type, rpc_loc_ioctl_data_u_type* ioctl_data ); extern int loc_eng_ioctl ( rpc_loc_client_handle_type handle, rpc_loc_ioctl_e_type ioctl_type, rpc_loc_ioctl_data_u_type* ioctl_data_ptr, uint32 timeout_msec, rpc_loc_ioctl_callback_s_type *cb_data_ptr ); #ifdef __cplusplus } #endif #endif /* LOC_API_RPC_GLUE_H */ ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/libloc_api-rpc-glue/rpc_inc/loc_api_sync_call.h ================================================ /* Copyright (c) 2011, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef LOC_API_CB_SYNC_H #define LOC_API_CB_SYNC_H #ifdef __cplusplus extern "C" { #endif #include "loc_api_rpc_glue.h" #define LOC_SYNC_CALL_SLOTS_MAX 8 typedef struct { pthread_mutex_t lock; /* Client ID */ rpc_loc_client_handle_type loc_handle; /* Callback waiting conditional variable */ pthread_cond_t loc_cb_arrived_cond; /* Callback waiting data block, protected by loc_cb_data_mutex */ boolean in_use; boolean signal_sent; boolean not_available; rpc_loc_event_mask_type loc_cb_wait_event_mask; /* event to wait for */ rpc_loc_ioctl_e_type ioctl_type; /* ioctl to wait for */ rpc_loc_event_payload_u_type loc_cb_received_payload; /* received payload */ rpc_loc_event_mask_type loc_cb_received_event_mask; /* received event */ } loc_sync_call_slot_s_type; typedef struct { int num_of_slots; loc_sync_call_slot_s_type slots[LOC_SYNC_CALL_SLOTS_MAX]; } loc_sync_call_slot_array_s_type; /* Init function */ void loc_api_sync_call_init(); /* Destroy function */ void loc_api_sync_call_destroy(); /* Process Loc API callbacks to wake up blocked user threads */ void loc_api_callback_process_sync_call( rpc_loc_client_handle_type loc_handle, /* handle of the client */ rpc_loc_event_mask_type loc_event, /* event mask */ const rpc_loc_event_payload_u_type* loc_event_payload /* payload */ ); /* Reentrant synchronous IOCTL call, using Loc API return code */ int loc_api_sync_ioctl ( rpc_loc_client_handle_type handle, rpc_loc_ioctl_e_type ioctl_type, rpc_loc_ioctl_data_u_type* ioctl_data_ptr, uint32 timeout_msec, rpc_loc_ioctl_callback_s_type *cb_data_ptr ); #ifdef __cplusplus } #endif #endif /* LOC_API_CB_SYNC_H */ ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/libloc_api-rpc-glue/rpc_inc/loc_apicb_appinit.h ================================================ /* Copyright (c) 2011, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef LOC_APICB_APPINIT_H #define LOC_APICB_APPINIT_H #ifdef __cplusplus extern "C" { #endif /* Initialization function for callbacks */ extern int loc_apicb_app_init(); extern void loc_apicb_app_deinit(); #ifdef __cplusplus } #endif #endif /* LOC_APICB_APPINIT_H */ ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/libloc_api-rpc-glue/src/LocApiRpc.cpp ================================================ /* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #define LOG_NDDEBUG 0 #define LOG_TAG "LocSvc_api_rpc" #include #include #ifndef USE_GLIB #include #endif /* USE_GLIB */ #include #include #include #include #include #include #include #ifdef USE_GLIB #include #endif #include #include using namespace loc_core; #define LOC_XTRA_INJECT_DEFAULT_TIMEOUT (3100) #define XTRA_BLOCK_SIZE (3072) #define LOC_IOCTL_DEFAULT_TIMEOUT 1000 // 1000 milli-seconds #define LOC_NI_NOTIF_KEY_ADDRESS "Address" /*=========================================================================== FUNCTION loc_event_cb DESCRIPTION This is the callback function registered by loc_open. DEPENDENCIES N/A RETURN VALUE RPC_LOC_API_SUCCESS SIDE EFFECTS N/A ===========================================================================*/ static int32 loc_event_cb ( void* user, rpc_loc_client_handle_type client_handle, rpc_loc_event_mask_type loc_event, const rpc_loc_event_payload_u_type* loc_event_payload ) { MODEM_LOG_CALLFLOW(%s, loc_get_event_name(loc_event)); loc_callback_log(loc_event, loc_event_payload); int32 ret_val = ((LocApiRpc*)user)->locEventCB(client_handle, loc_event, loc_event_payload); EXIT_LOG(%d, ret_val); return ret_val; } /*=========================================================================== FUNCTION loc_eng_rpc_global_cb DESCRIPTION This is the callback function registered by loc_open for RPC global events DEPENDENCIES N/A RETURN VALUE RPC_LOC_API_SUCCESS SIDE EFFECTS N/A ===========================================================================*/ static void loc_rpc_global_cb(void* user, CLIENT* clnt, enum rpc_reset_event event) { MODEM_LOG_CALLFLOW(%s, loc_get_rpc_reset_event_name(event)); ((LocApiRpc*)user)->locRpcGlobalCB(clnt, event); EXIT_LOG(%p, VOID_RET); } const LOC_API_ADAPTER_EVENT_MASK_T LocApiRpc::maskAll = LOC_API_ADAPTER_BIT_PARSED_POSITION_REPORT | LOC_API_ADAPTER_BIT_SATELLITE_REPORT | LOC_API_ADAPTER_BIT_LOCATION_SERVER_REQUEST | LOC_API_ADAPTER_BIT_ASSISTANCE_DATA_REQUEST | LOC_API_ADAPTER_BIT_IOCTL_REPORT | LOC_API_ADAPTER_BIT_STATUS_REPORT | LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT | LOC_API_ADAPTER_BIT_NI_NOTIFY_VERIFY_REQUEST; const rpc_loc_event_mask_type LocApiRpc::locBits[] = { RPC_LOC_EVENT_PARSED_POSITION_REPORT, RPC_LOC_EVENT_SATELLITE_REPORT, RPC_LOC_EVENT_NMEA_1HZ_REPORT, RPC_LOC_EVENT_NMEA_POSITION_REPORT, RPC_LOC_EVENT_NI_NOTIFY_VERIFY_REQUEST, RPC_LOC_EVENT_ASSISTANCE_DATA_REQUEST, RPC_LOC_EVENT_LOCATION_SERVER_REQUEST, RPC_LOC_EVENT_IOCTL_REPORT, RPC_LOC_EVENT_STATUS_REPORT, RPC_LOC_EVENT_WPS_NEEDED_REQUEST }; // constructor LocApiRpc::LocApiRpc(const MsgTask* msgTask, LOC_API_ADAPTER_EVENT_MASK_T exMask, ContextBase* context) : LocApiBase(msgTask, exMask, context), client_handle(RPC_LOC_CLIENT_HANDLE_INVALID), dataEnableLastSet(-1) { memset(apnLastSet, 0, sizeof(apnLastSet)); loc_api_glue_init(); } LocApiRpc::~LocApiRpc() { close(); } rpc_loc_event_mask_type LocApiRpc::convertMask(LOC_API_ADAPTER_EVENT_MASK_T mask) { rpc_loc_event_mask_type newMask = 0; for (unsigned int i = 0, bit=1; 0 != mask; i++, bit<<=1) { if (mask & bit) { newMask |= locBits[i]; mask ^= bit; } } return newMask; } rpc_loc_lock_e_type LocApiRpc::convertGpsLockMask(LOC_GPS_LOCK_MASK lockMask) { if (isGpsLockAll(lockMask)) return RPC_LOC_LOCK_ALL; if (isGpsLockMO(lockMask)) return RPC_LOC_LOCK_MI; if (isGpsLockMT(lockMask)) return RPC_LOC_LOCK_MT; if (isGpsLockNone(lockMask)) return RPC_LOC_LOCK_NONE; return (rpc_loc_lock_e_type)lockMask; } enum loc_api_adapter_err LocApiRpc::convertErr(int rpcErr) { switch(rpcErr) { case RPC_LOC_API_SUCCESS: return LOC_API_ADAPTER_ERR_SUCCESS; case RPC_LOC_API_GENERAL_FAILURE: return LOC_API_ADAPTER_ERR_GENERAL_FAILURE; case RPC_LOC_API_UNSUPPORTED: return LOC_API_ADAPTER_ERR_UNSUPPORTED; case RPC_LOC_API_INVALID_HANDLE: return LOC_API_ADAPTER_ERR_INVALID_HANDLE; case RPC_LOC_API_INVALID_PARAMETER: return LOC_API_ADAPTER_ERR_INVALID_PARAMETER; case RPC_LOC_API_ENGINE_BUSY: return LOC_API_ADAPTER_ERR_ENGINE_BUSY; case RPC_LOC_API_PHONE_OFFLINE: return LOC_API_ADAPTER_ERR_PHONE_OFFLINE; case RPC_LOC_API_TIMEOUT: return LOC_API_ADAPTER_ERR_TIMEOUT; case RPC_LOC_API_RPC_MODEM_RESTART: return LOC_API_ADAPTER_ERR_ENGINE_DOWN; case RPC_LOC_API_RPC_FAILURE: return LOC_API_ADAPTER_ERR_FAILURE; default: return LOC_API_ADAPTER_ERR_UNKNOWN; } } void LocApiRpc::locRpcGlobalCB(CLIENT* clnt, enum rpc_reset_event event) { static rpc_loc_engine_state_e_type last_state = RPC_LOC_ENGINE_STATE_MAX; switch (event) { case RPC_SUBSYSTEM_RESTART_BEGIN: if (RPC_LOC_ENGINE_STATE_OFF != last_state) { last_state = RPC_LOC_ENGINE_STATE_OFF; handleEngineDownEvent(); } break; case RPC_SUBSYSTEM_RESTART_END: if (RPC_LOC_ENGINE_STATE_ON != last_state) { last_state = RPC_LOC_ENGINE_STATE_ON; handleEngineUpEvent(); } break; } } int32 LocApiRpc::locEventCB(rpc_loc_client_handle_type client_handle, rpc_loc_event_mask_type loc_event, const rpc_loc_event_payload_u_type* loc_event_payload) { // Parsed report if (loc_event & RPC_LOC_EVENT_PARSED_POSITION_REPORT) { reportPosition(&loc_event_payload->rpc_loc_event_payload_u_type_u. parsed_location_report); } // Satellite report if (loc_event & RPC_LOC_EVENT_SATELLITE_REPORT) { reportSv(&loc_event_payload->rpc_loc_event_payload_u_type_u.gnss_report); } // Status report if (loc_event & RPC_LOC_EVENT_STATUS_REPORT) { reportStatus(&loc_event_payload->rpc_loc_event_payload_u_type_u.status_report); } // NMEA if (loc_event & RPC_LOC_EVENT_NMEA_1HZ_REPORT) { reportNmea(&(loc_event_payload->rpc_loc_event_payload_u_type_u.nmea_report)); } // XTRA support: supports only XTRA download if (loc_event & RPC_LOC_EVENT_ASSISTANCE_DATA_REQUEST) { if (loc_event_payload->rpc_loc_event_payload_u_type_u.assist_data_request.event == RPC_LOC_ASSIST_DATA_PREDICTED_ORBITS_REQ) { requestXtraData(); } else if (loc_event_payload->rpc_loc_event_payload_u_type_u.assist_data_request.event == RPC_LOC_ASSIST_DATA_TIME_REQ) { requestTime(); } else if (loc_event_payload->rpc_loc_event_payload_u_type_u.assist_data_request.event == RPC_LOC_ASSIST_DATA_POSITION_INJECTION_REQ) { requestLocation(); } } // AGPS data request if (loc_event & RPC_LOC_EVENT_LOCATION_SERVER_REQUEST) { ATLEvent(&loc_event_payload->rpc_loc_event_payload_u_type_u. loc_server_request); } // NI notify request if (loc_event & RPC_LOC_EVENT_NI_NOTIFY_VERIFY_REQUEST) { NIEvent(&loc_event_payload->rpc_loc_event_payload_u_type_u.ni_request); } return RPC_LOC_API_SUCCESS;//We simply want to return sucess here as we do not want to // cause any issues in RPC thread context } enum loc_api_adapter_err LocApiRpc::open(LOC_API_ADAPTER_EVENT_MASK_T mask) { enum loc_api_adapter_err ret_val = LOC_API_ADAPTER_ERR_SUCCESS; // RPC does not dynamically update the event mask. And in the // case of RPC, all we support are positioning (gps + agps) // masks anyways, so we simply mask all of them on always. // After doing so the first time in a power cycle, we know there // will the following if condition will never be true any more. mask = maskAll; if (mask != mMask) { if (RPC_LOC_CLIENT_HANDLE_INVALID != client_handle) { close(); } mMask = mask; // it is important to cap the mask here, because not all LocApi's // can enable the same bits, e.g. foreground and bckground. client_handle = loc_open(convertMask(mask), loc_event_cb, loc_rpc_global_cb, this); if (client_handle < 0) { mMask = 0; client_handle = RPC_LOC_CLIENT_HANDLE_INVALID; ret_val = LOC_API_ADAPTER_ERR_INVALID_HANDLE; } } return ret_val; } enum loc_api_adapter_err LocApiRpc::close() { if (RPC_LOC_CLIENT_HANDLE_INVALID != client_handle) { loc_clear(client_handle); } loc_close(client_handle); mMask = 0; client_handle = RPC_LOC_CLIENT_HANDLE_INVALID; return LOC_API_ADAPTER_ERR_SUCCESS; } enum loc_api_adapter_err LocApiRpc::startFix(const LocPosMode& posMode) { LOC_LOGD("LocApiRpc::startFix() called"); return convertErr( loc_start_fix(client_handle) ); } enum loc_api_adapter_err LocApiRpc::stopFix() { LOC_LOGD("LocApiRpc::stopFix() called"); return convertErr( loc_stop_fix(client_handle) ); } enum loc_api_adapter_err LocApiRpc::setPositionMode(const LocPosMode& posMode) { rpc_loc_ioctl_data_u_type ioctl_data; rpc_loc_fix_criteria_s_type *fix_criteria_ptr = &ioctl_data.rpc_loc_ioctl_data_u_type_u.fix_criteria; rpc_loc_ioctl_e_type ioctl_type = RPC_LOC_IOCTL_SET_FIX_CRITERIA; rpc_loc_operation_mode_e_type op_mode; int ret_val; const LocPosMode* fixCriteria = &posMode; ALOGD ("loc_eng_set_position mode, client = %d, interval = %d, mode = %d\n", (int32) client_handle, fixCriteria->min_interval, fixCriteria->mode); switch (fixCriteria->mode) { case LOC_POSITION_MODE_MS_BASED: op_mode = RPC_LOC_OPER_MODE_MSB; break; case LOC_POSITION_MODE_MS_ASSISTED: op_mode = RPC_LOC_OPER_MODE_MSA; break; case LOC_POSITION_MODE_RESERVED_1: op_mode = RPC_LOC_OPER_MODE_SPEED_OPTIMAL; break; case LOC_POSITION_MODE_RESERVED_2: op_mode = RPC_LOC_OPER_MODE_ACCURACY_OPTIMAL; break; case LOC_POSITION_MODE_RESERVED_3: op_mode = RPC_LOC_OPER_MODE_DATA_OPTIMAL; break; case LOC_POSITION_MODE_RESERVED_4: case LOC_POSITION_MODE_RESERVED_5: op_mode = RPC_LOC_OPER_MODE_MSA; fix_criteria_ptr->preferred_response_time = 0; break; default: op_mode = RPC_LOC_OPER_MODE_STANDALONE; } fix_criteria_ptr->valid_mask = RPC_LOC_FIX_CRIT_VALID_PREFERRED_OPERATION_MODE | RPC_LOC_FIX_CRIT_VALID_RECURRENCE_TYPE; fix_criteria_ptr->min_interval = fixCriteria->min_interval; fix_criteria_ptr->preferred_operation_mode = op_mode; fix_criteria_ptr->min_interval = fixCriteria->min_interval; fix_criteria_ptr->valid_mask |= RPC_LOC_FIX_CRIT_VALID_MIN_INTERVAL; if (fixCriteria->preferred_accuracy > 0) { fix_criteria_ptr->preferred_accuracy = fixCriteria->preferred_accuracy; fix_criteria_ptr->valid_mask |= RPC_LOC_FIX_CRIT_VALID_PREFERRED_ACCURACY; } if (fixCriteria->preferred_time > 0) { fix_criteria_ptr->preferred_response_time = fixCriteria->preferred_time; fix_criteria_ptr->valid_mask |= RPC_LOC_FIX_CRIT_VALID_PREFERRED_RESPONSE_TIME; } switch (fixCriteria->recurrence) { case GPS_POSITION_RECURRENCE_SINGLE: fix_criteria_ptr->recurrence_type = RPC_LOC_SINGLE_FIX; break; case GPS_POSITION_RECURRENCE_PERIODIC: default: fix_criteria_ptr->recurrence_type = RPC_LOC_PERIODIC_FIX; break; } ioctl_data.disc = ioctl_type; ret_val = loc_eng_ioctl (client_handle, ioctl_type, &ioctl_data, LOC_IOCTL_DEFAULT_TIMEOUT, NULL /* No output information is expected*/); return convertErr(ret_val); } enum loc_api_adapter_err LocApiRpc::setTime(GpsUtcTime time, int64_t timeReference, int uncertainty) { rpc_loc_ioctl_data_u_type ioctl_data; rpc_loc_assist_data_time_s_type *time_info_ptr; rpc_loc_ioctl_e_type ioctl_type = RPC_LOC_IOCTL_INJECT_UTC_TIME; int ret_val; LOC_LOGD ("loc_eng_inject_time, uncertainty = %d\n", uncertainty); time_info_ptr = &ioctl_data.rpc_loc_ioctl_data_u_type_u.assistance_data_time; time_info_ptr->time_utc = time; time_info_ptr->time_utc += (int64_t)(ELAPSED_MILLIS_SINCE_BOOT_PLATFORM_LIB_ABSTRACTION - timeReference); time_info_ptr->uncertainty = uncertainty; // Uncertainty in ms ioctl_data.disc = ioctl_type; ret_val = loc_eng_ioctl (client_handle, ioctl_type, &ioctl_data, LOC_IOCTL_DEFAULT_TIMEOUT, NULL /* No output information is expected*/); return convertErr(ret_val); } enum loc_api_adapter_err LocApiRpc::injectPosition(double latitude, double longitude, float accuracy) { /* IOCTL data */ rpc_loc_ioctl_data_u_type ioctl_data; rpc_loc_assist_data_pos_s_type *assistance_data_position = &ioctl_data.rpc_loc_ioctl_data_u_type_u.assistance_data_position; int ret_val; /************************************************ * Fill in latitude, longitude & accuracy ************************************************/ /* This combo is required */ assistance_data_position->valid_mask = RPC_LOC_ASSIST_POS_VALID_LATITUDE | RPC_LOC_ASSIST_POS_VALID_LONGITUDE | RPC_LOC_ASSIST_POS_VALID_HOR_UNC_CIRCULAR | RPC_LOC_ASSIST_POS_VALID_CONFIDENCE_HORIZONTAL; assistance_data_position->latitude = latitude; assistance_data_position->longitude = longitude; assistance_data_position->hor_unc_circular = accuracy; /* Meters assumed */ assistance_data_position->confidence_horizontal = 63; /* 63% (1 std dev) assumed */ /* Log */ LOC_LOGD("Inject coarse position Lat=%lf, Lon=%lf, Acc=%.2lf\n", (double) assistance_data_position->latitude, (double) assistance_data_position->longitude, (double) assistance_data_position->hor_unc_circular); ret_val = loc_eng_ioctl( client_handle, RPC_LOC_IOCTL_INJECT_POSITION, &ioctl_data, LOC_IOCTL_DEFAULT_TIMEOUT, NULL /* No output information is expected*/); return convertErr(ret_val); } enum loc_api_adapter_err LocApiRpc::informNiResponse(GpsUserResponseType userResponse, const void* passThroughData) { rpc_loc_ioctl_data_u_type data; rpc_loc_ioctl_callback_s_type callback_payload; memcpy(&data.rpc_loc_ioctl_data_u_type_u.user_verify_resp.ni_event_pass_back, passThroughData, sizeof (rpc_loc_ni_event_s_type)); rpc_loc_ni_user_resp_e_type resp; switch (userResponse) { case GPS_NI_RESPONSE_ACCEPT: data.rpc_loc_ioctl_data_u_type_u.user_verify_resp.user_resp = RPC_LOC_NI_LCS_NOTIFY_VERIFY_ACCEPT; break; case GPS_NI_RESPONSE_DENY: data.rpc_loc_ioctl_data_u_type_u.user_verify_resp.user_resp = RPC_LOC_NI_LCS_NOTIFY_VERIFY_DENY; break; case GPS_NI_RESPONSE_NORESP: default: data.rpc_loc_ioctl_data_u_type_u.user_verify_resp.user_resp = RPC_LOC_NI_LCS_NOTIFY_VERIFY_NORESP; break; } return convertErr( loc_eng_ioctl(client_handle, RPC_LOC_IOCTL_INFORM_NI_USER_RESPONSE, &data, LOC_IOCTL_DEFAULT_TIMEOUT, &callback_payload) ); } enum loc_api_adapter_err LocApiRpc::setAPN(char* apn, int len, boolean force) { enum loc_api_adapter_err rtv = LOC_API_ADAPTER_ERR_SUCCESS; int size = sizeof(apnLastSet); if (force || memcmp(apnLastSet, apn, size)) { if (len < size) { // size will be not larger than its original value size = len + 1; } memcpy(apnLastSet, apn, size); if (!isInSession()) { rpc_loc_ioctl_data_u_type ioctl_data = {RPC_LOC_IOCTL_SET_LBS_APN_PROFILE, {0}}; ioctl_data.rpc_loc_ioctl_data_u_type_u.apn_profiles[0].srv_system_type = LOC_APN_PROFILE_SRV_SYS_MAX; ioctl_data.rpc_loc_ioctl_data_u_type_u.apn_profiles[0].pdp_type = LOC_APN_PROFILE_PDN_TYPE_IPV4; memcpy(&(ioctl_data.rpc_loc_ioctl_data_u_type_u.apn_profiles[0].apn_name), apn, size); rtv = convertErr( loc_eng_ioctl (client_handle, RPC_LOC_IOCTL_SET_LBS_APN_PROFILE, &ioctl_data, LOC_IOCTL_DEFAULT_TIMEOUT, NULL) ); } } return rtv; } void LocApiRpc::setInSession(bool inSession) { if (!inSession) { enableData(dataEnableLastSet, true); setAPN(apnLastSet, sizeof(apnLastSet)-1, true); } } enum loc_api_adapter_err LocApiRpc::setServer(const char* url, int len) { rpc_loc_ioctl_data_u_type ioctl_data; rpc_loc_server_info_s_type *server_info_ptr; rpc_loc_ioctl_e_type ioctl_cmd; ioctl_cmd = RPC_LOC_IOCTL_SET_UMTS_SLP_SERVER_ADDR; ioctl_data.disc = ioctl_cmd; server_info_ptr = &ioctl_data.rpc_loc_ioctl_data_u_type_u.server_addr; server_info_ptr->addr_type = RPC_LOC_SERVER_ADDR_URL; server_info_ptr->addr_info.disc = server_info_ptr->addr_type; server_info_ptr->addr_info.rpc_loc_server_addr_u_type_u.url.length = len; #if (AMSS_VERSION==3200) server_info_ptr->addr_info.rpc_loc_server_addr_u_type_u.url.addr.addr_val = (char*) url; server_info_ptr->addr_info.rpc_loc_server_addr_u_type_u.url.addr.addr_len= len; #else strlcpy(server_info_ptr->addr_info.rpc_loc_server_addr_u_type_u.url.addr, url, sizeof server_info_ptr->addr_info.rpc_loc_server_addr_u_type_u.url.addr); #endif /* #if (AMSS_VERSION==3200) */ LOC_LOGD ("loc_eng_set_server, addr = %s\n", url); return convertErr( loc_eng_ioctl (client_handle, ioctl_cmd, &ioctl_data, LOC_IOCTL_DEFAULT_TIMEOUT, NULL /* No output information is expected*/) ); } enum loc_api_adapter_err LocApiRpc::setServer(unsigned int ip, int port, LocServerType type) { rpc_loc_ioctl_data_u_type ioctl_data; rpc_loc_server_info_s_type *server_info_ptr; rpc_loc_ioctl_e_type ioctl_cmd; switch (type) { case LOC_AGPS_MPC_SERVER: ioctl_cmd = RPC_LOC_IOCTL_SET_CDMA_MPC_SERVER_ADDR; break; case LOC_AGPS_CUSTOM_PDE_SERVER: ioctl_cmd = RPC_LOC_IOCTL_SET_CUSTOM_PDE_SERVER_ADDR; break; default: ioctl_cmd = RPC_LOC_IOCTL_SET_CDMA_PDE_SERVER_ADDR; break; } ioctl_data.disc = ioctl_cmd; server_info_ptr = &ioctl_data.rpc_loc_ioctl_data_u_type_u.server_addr; server_info_ptr->addr_type = RPC_LOC_SERVER_ADDR_IPV4; server_info_ptr->addr_info.disc = server_info_ptr->addr_type; server_info_ptr->addr_info.rpc_loc_server_addr_u_type_u.ipv4.addr = ip; server_info_ptr->addr_info.rpc_loc_server_addr_u_type_u.ipv4.port = port; LOC_LOGD ("setServer, addr = %X:%d\n", (unsigned int) ip, (unsigned int) port); return convertErr( loc_eng_ioctl (client_handle, ioctl_cmd, &ioctl_data, LOC_IOCTL_DEFAULT_TIMEOUT, NULL /* No output information is expected*/) ); } enum loc_api_adapter_err LocApiRpc::enableData(int enable, boolean force) { enum loc_api_adapter_err rtv = LOC_API_ADAPTER_ERR_SUCCESS; if (force || dataEnableLastSet != enable) { dataEnableLastSet = enable; if (!isInSession()) { rpc_loc_ioctl_data_u_type ioctl_data = {RPC_LOC_IOCTL_SET_DATA_ENABLE, {0}}; ioctl_data.rpc_loc_ioctl_data_u_type_u.data_enable = enable; rtv = convertErr( loc_eng_ioctl (client_handle, RPC_LOC_IOCTL_SET_DATA_ENABLE, &ioctl_data, LOC_IOCTL_DEFAULT_TIMEOUT, NULL) ); } } return rtv; } enum loc_api_adapter_err LocApiRpc::deleteAidingData(GpsAidingData bits) { rpc_loc_ioctl_data_u_type ioctl_data = {RPC_LOC_IOCTL_DELETE_ASSIST_DATA, {0}}; ioctl_data.rpc_loc_ioctl_data_u_type_u.assist_data_delete.type = bits; return convertErr( loc_eng_ioctl (client_handle, RPC_LOC_IOCTL_DELETE_ASSIST_DATA, &ioctl_data, LOC_IOCTL_DEFAULT_TIMEOUT, NULL) ); } void LocApiRpc::reportPosition(const rpc_loc_parsed_position_s_type *location_report_ptr) { LocPosTechMask tech_Mask = LOC_POS_TECH_MASK_DEFAULT; UlpLocation location = {0}; GpsLocationExtended locationExtended = {0}; location.size = sizeof(location); locationExtended.size = sizeof(locationExtended); if (location_report_ptr->valid_mask & RPC_LOC_POS_VALID_SESSION_STATUS) { // Process the position from final and intermediate reports if (location_report_ptr->session_status == RPC_LOC_SESS_STATUS_SUCCESS || location_report_ptr->session_status == RPC_LOC_SESS_STATUS_IN_PROGESS) { // Latitude & Longitude if ((location_report_ptr->valid_mask & RPC_LOC_POS_VALID_LATITUDE) && (location_report_ptr->valid_mask & RPC_LOC_POS_VALID_LONGITUDE) && (location_report_ptr->latitude != 0 || location_report_ptr->longitude != 0)) { location.gpsLocation.flags |= GPS_LOCATION_HAS_LAT_LONG; location.gpsLocation.latitude = location_report_ptr->latitude; location.gpsLocation.longitude = location_report_ptr->longitude; // Time stamp (UTC) if (location_report_ptr->valid_mask & RPC_LOC_POS_VALID_TIMESTAMP_UTC) { location.gpsLocation.timestamp = location_report_ptr->timestamp_utc; } // Altitude if (location_report_ptr->valid_mask & RPC_LOC_POS_VALID_ALTITUDE_WRT_ELLIPSOID ) { location.gpsLocation.flags |= GPS_LOCATION_HAS_ALTITUDE; location.gpsLocation.altitude = location_report_ptr->altitude_wrt_ellipsoid; } // Speed if (location_report_ptr->valid_mask & RPC_LOC_POS_VALID_SPEED_HORIZONTAL) { location.gpsLocation.flags |= GPS_LOCATION_HAS_SPEED; location.gpsLocation.speed = location_report_ptr->speed_horizontal; } // Heading if (location_report_ptr->valid_mask & RPC_LOC_POS_VALID_HEADING) { location.gpsLocation.flags |= GPS_LOCATION_HAS_BEARING; location.gpsLocation.bearing = location_report_ptr->heading; } // Uncertainty (circular) if ( (location_report_ptr->valid_mask & RPC_LOC_POS_VALID_HOR_UNC_CIRCULAR) ) { location.gpsLocation.flags |= GPS_LOCATION_HAS_ACCURACY; location.gpsLocation.accuracy = location_report_ptr->hor_unc_circular; } // Technology Mask tech_Mask |= location_report_ptr->technology_mask; //Mark the location source as from GNSS location.gpsLocation.flags |= LOCATION_HAS_SOURCE_INFO; location.position_source = ULP_LOCATION_IS_FROM_GNSS; if (location_report_ptr->valid_mask & RPC_LOC_POS_VALID_ALTITUDE_WRT_MEAN_SEA_LEVEL) { locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL; locationExtended.altitudeMeanSeaLevel = location_report_ptr->altitude_wrt_mean_sea_level; } if (location_report_ptr->valid_mask & RPC_LOC_POS_VALID_MAGNETIC_VARIATION ) { locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_MAG_DEV; locationExtended.magneticDeviation = location_report_ptr->magnetic_deviation; } if (location_report_ptr->valid_mask & RPC_LOC_POS_VALID_VERTICAL_UNC) { locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_VERT_UNC; locationExtended.vert_unc = location_report_ptr->vert_unc; } if (location_report_ptr->valid_mask & RPC_LOC_POS_VALID_SPEED_UNC) { locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_SPEED_UNC; locationExtended.speed_unc = location_report_ptr->speed_unc; } LOC_LOGV("reportPosition: fire callback\n"); enum loc_sess_status fixStatus = (location_report_ptr->session_status == RPC_LOC_SESS_STATUS_IN_PROGESS ? LOC_SESS_INTERMEDIATE : LOC_SESS_SUCCESS); LocApiBase::reportPosition(location, locationExtended, (void*)location_report_ptr, fixStatus, tech_Mask); } } else { LocApiBase::reportPosition(location, locationExtended, NULL, LOC_SESS_FAILURE); LOC_LOGV("loc_eng_report_position: ignore position report " "when session status = %d\n", location_report_ptr->session_status); } } else { LOC_LOGV("loc_eng_report_position: ignore position report " "when session status is not set\n"); } } void LocApiRpc::reportSv(const rpc_loc_gnss_info_s_type *gnss_report_ptr) { GnssSvStatus SvStatus = {0}; GpsLocationExtended locationExtended = {0}; locationExtended.size = sizeof(locationExtended); int num_svs_max = 0; const rpc_loc_sv_info_s_type *sv_info_ptr; if (gnss_report_ptr->valid_mask & RPC_LOC_GNSS_INFO_VALID_SV_COUNT) { num_svs_max = gnss_report_ptr->sv_count; if (num_svs_max > GPS_MAX_SVS) { num_svs_max = GPS_MAX_SVS; } } if (gnss_report_ptr->valid_mask & RPC_LOC_GNSS_INFO_VALID_SV_LIST) { SvStatus.num_svs = 0; for (int i = 0; i < num_svs_max; i++) { sv_info_ptr = &(gnss_report_ptr->sv_list.sv_list_val[i]); if (sv_info_ptr->valid_mask & RPC_LOC_SV_INFO_VALID_SYSTEM) { if (sv_info_ptr->system == RPC_LOC_SV_SYSTEM_GPS) { SvStatus.sv_list[SvStatus.num_svs].size = sizeof(GpsSvInfo); SvStatus.sv_list[SvStatus.num_svs].prn = sv_info_ptr->prn; // We only have the data field to report gps eph and alm mask if ((sv_info_ptr->valid_mask & RPC_LOC_SV_INFO_VALID_HAS_EPH) && (sv_info_ptr->has_eph == 1)) { SvStatus.ephemeris_mask |= (1 << (sv_info_ptr->prn-1)); } if ((sv_info_ptr->valid_mask & RPC_LOC_SV_INFO_VALID_HAS_ALM) && (sv_info_ptr->has_alm == 1)) { SvStatus.almanac_mask |= (1 << (sv_info_ptr->prn-1)); } if ((sv_info_ptr->valid_mask & RPC_LOC_SV_INFO_VALID_PROCESS_STATUS) && (sv_info_ptr->process_status == RPC_LOC_SV_STATUS_TRACK)) { SvStatus.gps_used_in_fix_mask |= (1 << (sv_info_ptr->prn-1)); } } // SBAS: GPS RPN: 120-151, // In exteneded measurement report, we follow nmea standard, which is from 33-64. else if (sv_info_ptr->system == RPC_LOC_SV_SYSTEM_SBAS) { SvStatus.sv_list[SvStatus.num_svs].prn = sv_info_ptr->prn + 33 - 120; } // Gloness: Slot id: 1-32 // In extended measurement report, we follow nmea standard, which is 65-96 else if (sv_info_ptr->system == RPC_LOC_SV_SYSTEM_GLONASS) { if ((sv_info_ptr->valid_mask & RPC_LOC_SV_INFO_VALID_PROCESS_STATUS) && (sv_info_ptr->process_status == RPC_LOC_SV_STATUS_TRACK)) { SvStatus.glo_used_in_fix_mask |= (1 << (sv_info_ptr->prn-1)); } SvStatus.sv_list[SvStatus.num_svs].prn = sv_info_ptr->prn + (65-1); } // Unsupported SV system else { continue; } } if (sv_info_ptr->valid_mask & RPC_LOC_SV_INFO_VALID_SNR) { SvStatus.sv_list[SvStatus.num_svs].snr = sv_info_ptr->snr; } if (sv_info_ptr->valid_mask & RPC_LOC_SV_INFO_VALID_ELEVATION) { SvStatus.sv_list[SvStatus.num_svs].elevation = sv_info_ptr->elevation; } if (sv_info_ptr->valid_mask & RPC_LOC_SV_INFO_VALID_AZIMUTH) { SvStatus.sv_list[SvStatus.num_svs].azimuth = sv_info_ptr->azimuth; } SvStatus.num_svs++; } } if ((gnss_report_ptr->valid_mask & RPC_LOC_GNSS_INFO_VALID_POS_DOP) && (gnss_report_ptr->valid_mask & RPC_LOC_GNSS_INFO_VALID_HOR_DOP) && (gnss_report_ptr->valid_mask & RPC_LOC_GNSS_INFO_VALID_VERT_DOP)) { locationExtended.flags |= GPS_LOCATION_EXTENDED_HAS_DOP; locationExtended.pdop = gnss_report_ptr->position_dop; locationExtended.hdop = gnss_report_ptr->horizontal_dop; locationExtended.vdop = gnss_report_ptr->vertical_dop; } if (SvStatus.num_svs >= 0) { LocApiBase::reportSv(SvStatus, locationExtended, (void*)gnss_report_ptr); } } void LocApiRpc::reportStatus(const rpc_loc_status_event_s_type *status_report_ptr) { if (status_report_ptr->event == RPC_LOC_STATUS_EVENT_ENGINE_STATE) { if (status_report_ptr->payload.rpc_loc_status_event_payload_u_type_u.engine_state == RPC_LOC_ENGINE_STATE_ON) { LocApiBase::reportStatus(GPS_STATUS_ENGINE_ON); LocApiBase::reportStatus(GPS_STATUS_SESSION_BEGIN); } else if (status_report_ptr->payload.rpc_loc_status_event_payload_u_type_u.engine_state == RPC_LOC_ENGINE_STATE_OFF) { LocApiBase::reportStatus(GPS_STATUS_SESSION_END); LocApiBase::reportStatus(GPS_STATUS_ENGINE_OFF); } else { LocApiBase::reportStatus(GPS_STATUS_NONE); } } } void LocApiRpc::reportNmea(const rpc_loc_nmea_report_s_type *nmea_report_ptr) { #if (AMSS_VERSION==3200) LocApiBase::reportNmea(nmea_report_ptr->nmea_sentences.nmea_sentences_val, nmea_report_ptr->nmea_sentences.nmea_sentences_len); #else LocApiBase::reportNmea(nmea_report_ptr->nmea_sentences, nmea_report_ptr->length); LOC_LOGD("loc_eng_report_nmea: $%c%c%c\n", nmea_report_ptr->nmea_sentences[3], nmea_report_ptr->nmea_sentences[4], nmea_report_ptr->nmea_sentences[5]); #endif /* #if (AMSS_VERSION==3200) */ } enum loc_api_adapter_err LocApiRpc::setXtraData(char* data, int length) { int rpc_ret_val = RPC_LOC_API_GENERAL_FAILURE; int total_parts; uint8 part; uint16 part_len; uint16 len_injected; rpc_loc_ioctl_data_u_type ioctl_data; rpc_loc_ioctl_e_type ioctl_type = RPC_LOC_IOCTL_INJECT_PREDICTED_ORBITS_DATA; rpc_loc_predicted_orbits_data_s_type *predicted_orbits_data_ptr; LOC_LOGD("qct_loc_eng_inject_xtra_data, xtra size = %d, data ptr = 0x%lx\n", length, (long) data); predicted_orbits_data_ptr = &ioctl_data.rpc_loc_ioctl_data_u_type_u.predicted_orbits_data; predicted_orbits_data_ptr->format_type = RPC_LOC_PREDICTED_ORBITS_XTRA; predicted_orbits_data_ptr->total_size = length; total_parts = (length - 1) / XTRA_BLOCK_SIZE + 1; predicted_orbits_data_ptr->total_parts = total_parts; len_injected = 0; // O bytes injected ioctl_data.disc = ioctl_type; // XTRA injection starts with part 1 for (part = 1; part <= total_parts; part++) { predicted_orbits_data_ptr->part = part; predicted_orbits_data_ptr->part_len = XTRA_BLOCK_SIZE; if (XTRA_BLOCK_SIZE > (length - len_injected)) { predicted_orbits_data_ptr->part_len = length - len_injected; } predicted_orbits_data_ptr->data_ptr.data_ptr_len = predicted_orbits_data_ptr->part_len; predicted_orbits_data_ptr->data_ptr.data_ptr_val = data + len_injected; LOC_LOGD("qct_loc_eng_inject_xtra_data, part %d/%d, len = %d, total = %d\n", predicted_orbits_data_ptr->part, total_parts, predicted_orbits_data_ptr->part_len, len_injected); if (part < total_parts) { // No callback in this case rpc_ret_val = loc_ioctl (client_handle, ioctl_type, &ioctl_data); if (rpc_ret_val != RPC_LOC_API_SUCCESS) { LOC_LOGE("loc_ioctl for xtra error: %s\n", loc_get_ioctl_status_name(rpc_ret_val)); break; } //Add a delay of 10 ms so that repeated RPC calls dont starve the modem processor usleep(10 * 1000); } else // part == total_parts { // Last part injection, will need to wait for callback if (!loc_eng_ioctl(client_handle, ioctl_type, &ioctl_data, LOC_XTRA_INJECT_DEFAULT_TIMEOUT, NULL)) { rpc_ret_val = RPC_LOC_API_GENERAL_FAILURE; } break; // done with injection } len_injected += predicted_orbits_data_ptr->part_len; LOC_LOGD("loc_ioctl XTRA injected length: %d\n", len_injected); } return convertErr(rpc_ret_val); } /* Request the Xtra Server Url from the modem */ enum loc_api_adapter_err LocApiRpc::requestXtraServer() { loc_api_adapter_err err; rpc_loc_ioctl_data_u_type data; rpc_loc_ioctl_callback_s_type callback_data; err = convertErr(loc_eng_ioctl(client_handle, RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_SOURCE, &data, LOC_IOCTL_DEFAULT_TIMEOUT, &callback_data)); if (LOC_API_ADAPTER_ERR_SUCCESS != err) { LOC_LOGE("RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_SOURCE failed!: err=%d\n", err); return err; } else if (RPC_LOC_SESS_STATUS_SUCCESS != callback_data.status) { LOC_LOGE("RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_SOURCE failed!: status=%ld\n", callback_data.status); return LOC_API_ADAPTER_ERR_GENERAL_FAILURE; } else if (RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_SOURCE != callback_data.type) { LOC_LOGE("RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_SOURCE is not the type expected! type=%d\n", callback_data.type); return LOC_API_ADAPTER_ERR_GENERAL_FAILURE; } else if (RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_SOURCE != callback_data.data.disc) { LOC_LOGE("RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_SOURCE is not the disc expected! disc=%d\n", callback_data.data.disc); return LOC_API_ADAPTER_ERR_GENERAL_FAILURE; } reportXtraServer(callback_data.data.rpc_loc_ioctl_callback_data_u_type_u. predicted_orbits_data_source.servers[0], callback_data.data.rpc_loc_ioctl_callback_data_u_type_u. predicted_orbits_data_source.servers[1], callback_data.data.rpc_loc_ioctl_callback_data_u_type_u. predicted_orbits_data_source.servers[2], 255); return LOC_API_ADAPTER_ERR_SUCCESS; } enum loc_api_adapter_err LocApiRpc::atlOpenStatus(int handle, int is_succ, char* apn, AGpsBearerType bearer, AGpsType agpsType) { rpc_loc_server_open_status_e_type open_status = is_succ ? RPC_LOC_SERVER_OPEN_SUCCESS : RPC_LOC_SERVER_OPEN_FAIL; rpc_loc_ioctl_data_u_type ioctl_data; if (AGPS_TYPE_INVALID == agpsType) { rpc_loc_server_open_status_s_type *conn_open_status_ptr = &ioctl_data.rpc_loc_ioctl_data_u_type_u.conn_open_status; // Fill in data ioctl_data.disc = RPC_LOC_IOCTL_INFORM_SERVER_OPEN_STATUS; conn_open_status_ptr->conn_handle = handle; conn_open_status_ptr->open_status = open_status; #if (AMSS_VERSION==3200) conn_open_status_ptr->apn_name = apn; /* requires APN */ #else if (is_succ) { strlcpy(conn_open_status_ptr->apn_name, apn, sizeof conn_open_status_ptr->apn_name); } else { conn_open_status_ptr->apn_name[0] = 0; } #endif /* #if (AMSS_VERSION==3200) */ LOC_LOGD("ATL RPC_LOC_IOCTL_INFORM_SERVER_OPEN_STATUS open %s, APN name = [%s]\n", log_succ_fail_string(is_succ), apn); } else { rpc_loc_server_multi_open_status_s_type *conn_multi_open_status_ptr = &ioctl_data.rpc_loc_ioctl_data_u_type_u.multi_conn_open_status; // Fill in data ioctl_data.disc = RPC_LOC_IOCTL_INFORM_SERVER_MULTI_OPEN_STATUS; conn_multi_open_status_ptr->conn_handle = handle; conn_multi_open_status_ptr->open_status = open_status; if (is_succ) { strlcpy(conn_multi_open_status_ptr->apn_name, apn, sizeof conn_multi_open_status_ptr->apn_name); } else { conn_multi_open_status_ptr->apn_name[0] = 0; } switch(bearer) { case AGPS_APN_BEARER_IPV4: conn_multi_open_status_ptr->pdp_type = RPC_LOC_SERVER_PDP_IP; break; case AGPS_APN_BEARER_IPV6: conn_multi_open_status_ptr->pdp_type = RPC_LOC_SERVER_PDP_IPV6; break; case AGPS_APN_BEARER_IPV4V6: conn_multi_open_status_ptr->pdp_type = RPC_LOC_SERVER_PDP_IPV4V6; break; default: conn_multi_open_status_ptr->pdp_type = RPC_LOC_SERVER_PDP_PPP; } LOC_LOGD("ATL RPC_LOC_IOCTL_INFORM_SERVER_MULTI_OPEN_STATUS open %s, APN name = [%s], pdp_type = %d\n", log_succ_fail_string(is_succ), apn, conn_multi_open_status_ptr->pdp_type); } // Make the IOCTL call return convertErr( loc_eng_ioctl(client_handle, ioctl_data.disc, &ioctl_data, LOC_IOCTL_DEFAULT_TIMEOUT, NULL) ); } enum loc_api_adapter_err LocApiRpc::atlCloseStatus(int handle, int is_succ) { rpc_loc_ioctl_data_u_type ioctl_data; ioctl_data.disc = RPC_LOC_IOCTL_INFORM_SERVER_CLOSE_STATUS; rpc_loc_server_close_status_s_type *conn_close_status_ptr = &ioctl_data.rpc_loc_ioctl_data_u_type_u.conn_close_status; conn_close_status_ptr->conn_handle = handle; conn_close_status_ptr->close_status = is_succ ? RPC_LOC_SERVER_CLOSE_SUCCESS : RPC_LOC_SERVER_CLOSE_FAIL; // Make the IOCTL call return convertErr( loc_eng_ioctl(client_handle, ioctl_data.disc, &ioctl_data, LOC_IOCTL_DEFAULT_TIMEOUT, NULL) ); } void LocApiRpc::ATLEvent(const rpc_loc_server_request_s_type *server_request_ptr) { int connHandle; AGpsType agps_type; LOC_LOGV("RPC_LOC_EVENT_ASSISTANCE_DATA_REQUEST event %s)", loc_get_event_atl_open_name(server_request_ptr->event)); switch (server_request_ptr->event) { case RPC_LOC_SERVER_REQUEST_MULTI_OPEN: connHandle = server_request_ptr->payload.rpc_loc_server_request_u_type_u.multi_open_req.conn_handle; if (server_request_ptr->payload.rpc_loc_server_request_u_type_u.multi_open_req.connection_type == RPC_LOC_SERVER_CONNECTION_LBS) { agps_type = AGPS_TYPE_SUPL; LOC_LOGV("ATLEvent: event - RPC_LOC_SERVER_REQUEST_MULTI_OPEN\n type - AGPS_TYPE_SUPL\n handle - %d", connHandle); } else { agps_type = AGPS_TYPE_WWAN_ANY; LOC_LOGV("ATLEvent: event - RPC_LOC_SERVER_REQUEST_MULTI_OPEN\n type - AGPS_TYPE_WWAN_ANY\n handle - %d", connHandle); } requestATL(connHandle, agps_type); break; case RPC_LOC_SERVER_REQUEST_OPEN: connHandle = server_request_ptr->payload.rpc_loc_server_request_u_type_u.open_req.conn_handle; LOC_LOGV("ATLEvent: event - RPC_LOC_SERVER_REQUEST_OPEN\n handle - %d", connHandle); requestATL(connHandle, AGPS_TYPE_INVALID); break; case RPC_LOC_SERVER_REQUEST_CLOSE: connHandle = server_request_ptr->payload.rpc_loc_server_request_u_type_u.close_req.conn_handle; LOC_LOGV("ATLEvent: event - RPC_LOC_SERVER_REQUEST_CLOSE\n handle - %d", connHandle); releaseATL(connHandle); break; default: LOC_LOGE("ATLEvent: event type %d invalid", server_request_ptr->event); } } void LocApiRpc::NIEvent(const rpc_loc_ni_event_s_type *ni_req) { GpsNiNotification notif = {0}; switch (ni_req->event) { case RPC_LOC_NI_EVENT_VX_NOTIFY_VERIFY_REQ: { const rpc_loc_ni_vx_notify_verify_req_s_type *vx_req = &ni_req->payload.rpc_loc_ni_event_payload_u_type_u.vx_req; LOC_LOGI("VX Notification"); notif.ni_type = GPS_NI_TYPE_VOICE; // Requestor ID hexcode(notif.requestor_id, sizeof notif.requestor_id, vx_req->requester_id.requester_id, vx_req->requester_id.requester_id_length); notif.text_encoding = 0; // No text and no encoding notif.requestor_id_encoding = convertNiEncodingType(vx_req->encoding_scheme); NIEventFillVerfiyType(notif, vx_req->notification_priv_type); } break; case RPC_LOC_NI_EVENT_UMTS_CP_NOTIFY_VERIFY_REQ: { const rpc_loc_ni_umts_cp_notify_verify_req_s_type *umts_cp_req = &ni_req->payload.rpc_loc_ni_event_payload_u_type_u.umts_cp_req; LOC_LOGI("UMTS CP Notification\n"); notif.ni_type= GPS_NI_TYPE_UMTS_CTRL_PLANE; // Stores notification text #if (AMSS_VERSION==3200) hexcode(notif.text, sizeof notif.text, umts_cp_req->notification_text.notification_text_val, umts_cp_req->notification_length); hexcode(notif.requestor_id, sizeof notif.requestor_id, umts_cp_req->requestor_id.requestor_id_string.requestor_id_string_val, umts_cp_req->requestor_id.string_len); #else hexcode(notif.text, sizeof notif.text, umts_cp_req->notification_text, umts_cp_req->notification_length); hexcode(notif.requestor_id, sizeof notif.requestor_id, umts_cp_req->requestor_id.requestor_id_string, umts_cp_req->requestor_id.string_len); #endif notif.text_encoding = convertNiEncodingType(umts_cp_req->datacoding_scheme); notif.requestor_id_encoding = notif.text_encoding; NIEventFillVerfiyType(notif, umts_cp_req->notification_priv_type); // LCS address (using extras field) if (umts_cp_req->ext_client_address_data.ext_client_address_len != 0) { // Copy LCS Address into notif.extras in the format: Address = 012345 strlcat(notif.extras, LOC_NI_NOTIF_KEY_ADDRESS, sizeof notif.extras); strlcat(notif.extras, " = ", sizeof notif.extras); int addr_len = 0; const char *address_source = NULL; #if (AMSS_VERSION==3200) address_source = umts_cp_req->ext_client_address_data.ext_client_address.ext_client_address_val; #else address_source = umts_cp_req->ext_client_address_data.ext_client_address; #endif /* #if (AMSS_VERSION==3200) */ char lcs_addr[32]; // Decoded LCS address for UMTS CP NI addr_len = decodeAddress(lcs_addr, sizeof lcs_addr, address_source, umts_cp_req->ext_client_address_data.ext_client_address_len); // The address is ASCII string if (addr_len) { strlcat(notif.extras, lcs_addr, sizeof notif.extras); } } } break; case RPC_LOC_NI_EVENT_SUPL_NOTIFY_VERIFY_REQ: { const rpc_loc_ni_supl_notify_verify_req_s_type *supl_req = &ni_req->payload.rpc_loc_ni_event_payload_u_type_u.supl_req; LOC_LOGI("SUPL Notification\n"); notif.ni_type = GPS_NI_TYPE_UMTS_SUPL; if (supl_req->flags & RPC_LOC_NI_CLIENT_NAME_PRESENT) { #if (AMSS_VERSION==3200) hexcode(notif.text, sizeof notif.text, supl_req->client_name.client_name_string.client_name_string_val, /* buffer */ supl_req->client_name.string_len /* length */ ); #else hexcode(notif.text, sizeof notif.text, supl_req->client_name.client_name_string, /* buffer */ supl_req->client_name.string_len /* length */ ); #endif /* #if (AMSS_VERSION==3200) */ LOC_LOGV("SUPL NI: client_name: %s len=%d", notif.text, supl_req->client_name.string_len); } else { LOC_LOGV("SUPL NI: client_name not present."); } // Requestor ID if (supl_req->flags & RPC_LOC_NI_REQUESTOR_ID_PRESENT) { #if (AMSS_VERSION==3200) hexcode(notif.requestor_id, sizeof notif.requestor_id, supl_req->requestor_id.requestor_id_string.requestor_id_string_val, /* buffer */ supl_req->requestor_id.string_len /* length */ ); #else hexcode(notif.requestor_id, sizeof notif.requestor_id, supl_req->requestor_id.requestor_id_string, /* buffer */ supl_req->requestor_id.string_len /* length */ ); #endif /* #if (AMSS_VERSION==3200) */ LOC_LOGV("SUPL NI: requestor_id: %s len=%d", notif.requestor_id, supl_req->requestor_id.string_len); } else { LOC_LOGV("SUPL NI: requestor_id not present."); } // Encoding type if (supl_req->flags & RPC_LOC_NI_ENCODING_TYPE_PRESENT) { notif.text_encoding = convertNiEncodingType(supl_req->datacoding_scheme); notif.requestor_id_encoding = notif.text_encoding; } else { notif.text_encoding = notif.requestor_id_encoding = GPS_ENC_UNKNOWN; } NIEventFillVerfiyType(notif, ni_req->payload.rpc_loc_ni_event_payload_u_type_u.supl_req.notification_priv_type); } break; default: LOC_LOGE("Unknown NI event: %x\n", (int) ni_req->event); return; } // this copy will get freed in loc_eng_ni when loc_ni_respond() is called rpc_loc_ni_event_s_type *copy = (rpc_loc_ni_event_s_type *)malloc(sizeof(*copy)); memcpy(copy, ni_req, sizeof(*copy)); requestNiNotify(notif, (const void*)copy); } int LocApiRpc::NIEventFillVerfiyType(GpsNiNotification ¬if, rpc_loc_ni_notify_verify_e_type notif_priv) { switch (notif_priv) { case RPC_LOC_NI_USER_NO_NOTIFY_NO_VERIFY: notif.notify_flags = 0; notif.default_response = GPS_NI_RESPONSE_NORESP; return 1; case RPC_LOC_NI_USER_NOTIFY_ONLY: notif.notify_flags = GPS_NI_NEED_NOTIFY; notif.default_response = GPS_NI_RESPONSE_NORESP; return 1; case RPC_LOC_NI_USER_NOTIFY_VERIFY_ALLOW_NO_RESP: notif.notify_flags = GPS_NI_NEED_NOTIFY | GPS_NI_NEED_VERIFY; notif.default_response = GPS_NI_RESPONSE_ACCEPT; return 1; case RPC_LOC_NI_USER_NOTIFY_VERIFY_NOT_ALLOW_NO_RESP: notif.notify_flags = GPS_NI_NEED_NOTIFY | GPS_NI_NEED_VERIFY; notif.default_response = GPS_NI_RESPONSE_DENY; return 1; case RPC_LOC_NI_USER_PRIVACY_OVERRIDE: notif.notify_flags = GPS_NI_PRIVACY_OVERRIDE; notif.default_response = GPS_NI_RESPONSE_NORESP; return 1; default: return 0; } } enum loc_api_adapter_err LocApiRpc::setSUPLVersion(uint32_t version) { rpc_loc_ioctl_data_u_type ioctl_data = {RPC_LOC_IOCTL_SET_SUPL_VERSION, {0}}; ioctl_data.rpc_loc_ioctl_data_u_type_u.supl_version = (int)version; return convertErr( loc_eng_ioctl (client_handle, RPC_LOC_IOCTL_SET_SUPL_VERSION, &ioctl_data, LOC_IOCTL_DEFAULT_TIMEOUT, NULL) ); } GpsNiEncodingType LocApiRpc::convertNiEncodingType(int loc_encoding) { switch (loc_encoding) { case RPC_LOC_NI_SUPL_UTF8: return GPS_ENC_SUPL_UTF8; case RPC_LOC_NI_SUPL_UCS2: return GPS_ENC_SUPL_UCS2; case RPC_LOC_NI_SUPL_GSM_DEFAULT: return GPS_ENC_SUPL_GSM_DEFAULT; case RPC_LOC_NI_SS_LANGUAGE_UNSPEC: return GPS_ENC_SUPL_GSM_DEFAULT; // SS_LANGUAGE_UNSPEC = GSM default: return GPS_ENC_UNKNOWN; } } LocApiBase* getLocApi(const MsgTask* msgTask, LOC_API_ADAPTER_EVENT_MASK_T exMask, ContextBase *context) { return new LocApiRpc(msgTask, exMask, context); } /*Values for lock 1 = Do not lock any position sessions 2 = Lock MI position sessions 3 = Lock MT position sessions 4 = Lock all position sessions */ int LocApiRpc::setGpsLock(LOC_GPS_LOCK_MASK lockMask) { rpc_loc_ioctl_data_u_type ioctl_data; boolean ret_val; LOC_LOGD("%s:%d]: lock: %x\n", __func__, __LINE__, lockMask); ioctl_data.rpc_loc_ioctl_data_u_type_u.engine_lock = convertGpsLockMask(lockMask); ioctl_data.disc = RPC_LOC_IOCTL_SET_ENGINE_LOCK; ret_val = loc_eng_ioctl (loc_eng_data.client_handle, RPC_LOC_IOCTL_SET_ENGINE_LOCK, &ioctl_data, LOC_IOCTL_DEFAULT_TIMEOUT, NULL /* No output information is expected*/); LOC_LOGD("%s:%d]: ret_val: %d\n", __func__, __LINE__, (int)ret_val); return (ret_val == TRUE ? 0 : -1); } /* Returns Current value of GPS lock on success -1 on failure */ int LocApiRpc :: getGpsLock() { rpc_loc_ioctl_data_u_type ioctl_data; rpc_loc_ioctl_callback_s_type callback_payload; boolean ret_val; int ret=0; LOC_LOGD("%s:%d]: Enter\n", __func__, __LINE__); ret_val = loc_eng_ioctl (loc_eng_data.client_handle, RPC_LOC_IOCTL_GET_ENGINE_LOCK, &ioctl_data, LOC_IOCTL_DEFAULT_TIMEOUT, &callback_payload); if(ret_val == TRUE) { ret = (int)callback_payload.data.engine_lock; LOC_LOGD("%s:%d]: Lock type: %d\n", __func__, __LINE__, ret); } else { LOC_LOGE("%s:%d]: Ioctl failed", __func__, __LINE__); ret = -1; } LOC_LOGD("%s:%d]: Exit\n", __func__, __LINE__); return ret; } ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/libloc_api-rpc-glue/src/loc_api_fixup.c ================================================ /* Copyright (c) 2011, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "loc_api_fixup.h" #ifdef ADD_XDR_FLOAT int xdr_float(xdrp, fp) XDR *xdrp; float *fp; { return xdr_long(xdrp, (long*)fp); } int xdr_double(xdrp, dp) XDR *xdrp; double *dp; { return xdr_long(xdrp, (long*)dp + 1) && xdr_long(xdrp, (long*)dp); } #endif /* ADD_XDR_FLOAT */ ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/libloc_api-rpc-glue/src/loc_api_log.c ================================================ /* Copyright (c) 2011 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #define LOG_NDDEBUG 0 #define LOG_TAG "LocSvc_api_rpc_glue" #include "loc_api_log.h" #include "loc_log.h" #include "log_util.h" #include "platform_lib_includes.h" #include "rpc/rpc.h" #include "loc_api_fixup.h" /* Event names */ loc_name_val_s_type loc_event_name[] = { NAME_VAL( RPC_LOC_EVENT_PARSED_POSITION_REPORT ), NAME_VAL( RPC_LOC_EVENT_SATELLITE_REPORT ), NAME_VAL( RPC_LOC_EVENT_NMEA_1HZ_REPORT ), NAME_VAL( RPC_LOC_EVENT_NMEA_POSITION_REPORT ), NAME_VAL( RPC_LOC_EVENT_NI_NOTIFY_VERIFY_REQUEST ), NAME_VAL( RPC_LOC_EVENT_ASSISTANCE_DATA_REQUEST ), NAME_VAL( RPC_LOC_EVENT_LOCATION_SERVER_REQUEST ), NAME_VAL( RPC_LOC_EVENT_IOCTL_REPORT ), NAME_VAL( RPC_LOC_EVENT_STATUS_REPORT ), NAME_VAL( RPC_LOC_EVENT_WPS_NEEDED_REQUEST ), }; int loc_event_num = sizeof loc_event_name / sizeof(loc_name_val_s_type); /* Event names */ loc_name_val_s_type loc_event_atl_open_name[] = { NAME_VAL( RPC_LOC_SERVER_REQUEST_OPEN ), NAME_VAL( RPC_LOC_SERVER_REQUEST_CLOSE ), NAME_VAL( RPC_LOC_SERVER_REQUEST_MULTI_OPEN ) }; int loc_event_atl_open_num = sizeof loc_event_atl_open_name / sizeof(loc_name_val_s_type); /* Finds the first event found in the mask */ const char* loc_get_event_atl_open_name(rpc_loc_server_request_e_type loc_event_atl_open) { return loc_get_name_from_val(loc_event_atl_open_name, loc_event_atl_open_num, (long) loc_event_atl_open); } /* IOCTL Type names */ loc_name_val_s_type loc_ioctl_type_name[] = { NAME_VAL( RPC_LOC_IOCTL_GET_API_VERSION ), NAME_VAL( RPC_LOC_IOCTL_SET_FIX_CRITERIA ), NAME_VAL( RPC_LOC_IOCTL_GET_FIX_CRITERIA ), NAME_VAL( RPC_LOC_IOCTL_INFORM_NI_USER_RESPONSE ), NAME_VAL( RPC_LOC_IOCTL_INJECT_PREDICTED_ORBITS_DATA ), NAME_VAL( RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_VALIDITY ), NAME_VAL( RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_SOURCE ), NAME_VAL( RPC_LOC_IOCTL_SET_PREDICTED_ORBITS_DATA_AUTO_DOWNLOAD ), NAME_VAL( RPC_LOC_IOCTL_INJECT_UTC_TIME ), NAME_VAL( RPC_LOC_IOCTL_INJECT_RTC_VALUE ), NAME_VAL( RPC_LOC_IOCTL_INJECT_POSITION ), NAME_VAL( RPC_LOC_IOCTL_QUERY_ENGINE_STATE ), NAME_VAL( RPC_LOC_IOCTL_ERROR_ESTIMATE_CONFIG), NAME_VAL( RPC_LOC_IOCTL_INFORM_SERVER_MULTI_OPEN_STATUS ), NAME_VAL( RPC_LOC_IOCTL_INFORM_SERVER_OPEN_STATUS ), NAME_VAL( RPC_LOC_IOCTL_INFORM_SERVER_CLOSE_STATUS ), NAME_VAL( RPC_LOC_IOCTL_SEND_WIPER_POSITION_REPORT ), NAME_VAL( RPC_LOC_IOCTL_NOTIFY_WIPER_STATUS ), NAME_VAL( RPC_LOC_IOCTL_SET_ENGINE_LOCK ), NAME_VAL( RPC_LOC_IOCTL_GET_ENGINE_LOCK ), NAME_VAL( RPC_LOC_IOCTL_SET_SBAS_CONFIG ), NAME_VAL( RPC_LOC_IOCTL_GET_SBAS_CONFIG ), NAME_VAL( RPC_LOC_IOCTL_SET_NMEA_TYPES ), NAME_VAL( RPC_LOC_IOCTL_GET_NMEA_TYPES ), NAME_VAL( RPC_LOC_IOCTL_SET_CDMA_PDE_SERVER_ADDR ), NAME_VAL( RPC_LOC_IOCTL_GET_CDMA_PDE_SERVER_ADDR ), NAME_VAL( RPC_LOC_IOCTL_SET_CDMA_MPC_SERVER_ADDR ), NAME_VAL( RPC_LOC_IOCTL_GET_CDMA_MPC_SERVER_ADDR ), NAME_VAL( RPC_LOC_IOCTL_SET_UMTS_SLP_SERVER_ADDR ), NAME_VAL( RPC_LOC_IOCTL_GET_UMTS_SLP_SERVER_ADDR ), NAME_VAL( RPC_LOC_IOCTL_SET_ON_DEMAND_LPM ), NAME_VAL( RPC_LOC_IOCTL_GET_ON_DEMAND_LPM ), NAME_VAL( RPC_LOC_IOCTL_SET_XTRA_T_SESSION_CONTROL ), NAME_VAL( RPC_LOC_IOCTL_GET_XTRA_T_SESSION_CONTROL ), NAME_VAL( RPC_LOC_IOCTL_SET_LBS_APN_PROFILE ), NAME_VAL( RPC_LOC_IOCTL_GET_LBS_APN_PROFILE ), NAME_VAL( RPC_LOC_IOCTL_SET_XTRA_APN_PROFILE ), NAME_VAL( RPC_LOC_IOCTL_GET_XTRA_APN_PROFILE ), NAME_VAL( RPC_LOC_IOCTL_SET_DATA_ENABLE ), NAME_VAL( RPC_LOC_IOCTL_SET_SUPL_VERSION ), NAME_VAL( RPC_LOC_IOCTL_GET_SUPL_VERSION ), NAME_VAL( RPC_LOC_IOCTL_DELETE_ASSIST_DATA ), NAME_VAL( RPC_LOC_IOCTL_SET_CUSTOM_PDE_SERVER_ADDR ), NAME_VAL( RPC_LOC_IOCTL_GET_CUSTOM_PDE_SERVER_ADDR ), }; int loc_ioctl_type_num = sizeof loc_ioctl_type_name / sizeof(loc_name_val_s_type); /* IOCTL Status names */ loc_name_val_s_type loc_ioctl_status_name[] = { NAME_VAL( RPC_LOC_API_SUCCESS ), NAME_VAL( RPC_LOC_API_GENERAL_FAILURE ), NAME_VAL( RPC_LOC_API_UNSUPPORTED ), NAME_VAL( RPC_LOC_API_INVALID_HANDLE ), NAME_VAL( RPC_LOC_API_INVALID_PARAMETER ), NAME_VAL( RPC_LOC_API_ENGINE_BUSY ), NAME_VAL( RPC_LOC_API_PHONE_OFFLINE ), NAME_VAL( RPC_LOC_API_TIMEOUT ), NAME_VAL( RPC_LOC_API_RPC_FAILURE ), NAME_VAL( RPC_LOC_API_RPC_MODEM_RESTART ) }; int loc_ioctl_status_num = sizeof loc_ioctl_status_name / sizeof(loc_name_val_s_type); /* Fix session status names */ loc_name_val_s_type loc_sess_status_name[] = { NAME_VAL( RPC_LOC_SESS_STATUS_SUCCESS ), NAME_VAL( RPC_LOC_SESS_STATUS_IN_PROGESS ), NAME_VAL( RPC_LOC_SESS_STATUS_GENERAL_FAILURE ), NAME_VAL( RPC_LOC_SESS_STATUS_TIMEOUT ), NAME_VAL( RPC_LOC_SESS_STATUS_USER_END ), NAME_VAL( RPC_LOC_SESS_STATUS_BAD_PARAMETER ), NAME_VAL( RPC_LOC_SESS_STATUS_PHONE_OFFLINE ), NAME_VAL( RPC_LOC_SESS_STATUS_USER_END ), NAME_VAL( RPC_LOC_SESS_STATUS_ENGINE_LOCKED ) }; int loc_sess_status_num = sizeof loc_sess_status_name / sizeof(loc_name_val_s_type); /* Engine state names */ loc_name_val_s_type loc_engine_state_name[] = { NAME_VAL( RPC_LOC_ENGINE_STATE_ON ), NAME_VAL( RPC_LOC_ENGINE_STATE_OFF ) }; int loc_engine_state_num = sizeof loc_engine_state_name / sizeof(loc_name_val_s_type); /* Fix session state names */ loc_name_val_s_type loc_fix_session_state_name[] = { NAME_VAL( RPC_LOC_FIX_SESSION_STATE_BEGIN ), NAME_VAL( RPC_LOC_FIX_SESSION_STATE_END ) }; int loc_fix_session_state_num = sizeof loc_fix_session_state_name / sizeof(loc_name_val_s_type); static const char* log_final_interm_string(int is_final) { return is_final ? "final" : "intermediate"; } /* Logs parsed report */ static void log_parsed_report(const rpc_loc_parsed_position_s_type *parsed_report) { rpc_loc_session_status_e_type status = parsed_report->session_status; LOC_LOGD("Session status: %s Valid mask: 0x%X\n", loc_get_sess_status_name(status), (uint) parsed_report->valid_mask); LOC_LOGD("Latitude: %.7f (%s)\n", parsed_report->latitude, log_final_interm_string( (parsed_report->valid_mask & RPC_LOC_POS_VALID_LATITUDE) && parsed_report->session_status == RPC_LOC_SESS_STATUS_SUCCESS)); LOC_LOGD("Longitude: %.7f\n", parsed_report->longitude); LOC_LOGD("Accuracy: %.7f\n", parsed_report->hor_unc_circular); } /* Logs status report */ static void log_status_report(const rpc_loc_status_event_s_type *status_event) { rpc_loc_status_event_e_type event = status_event->event; switch (event) { case RPC_LOC_STATUS_EVENT_ENGINE_STATE: LOC_LOGD("Engine state: %s\n", loc_get_engine_state_name( status_event->payload.rpc_loc_status_event_payload_u_type_u.engine_state)); break; case RPC_LOC_STATUS_EVENT_FIX_SESSION_STATE: LOC_LOGD("Fix session state: %s\n", loc_get_fix_session_state_name( status_event->payload.rpc_loc_status_event_payload_u_type_u.fix_session_state)); break; default: break; } } /* Logs valid fields in the GNSS SV constellation report */ static void log_satellite_report(const rpc_loc_gnss_info_s_type *gnss) { if (gnss->valid_mask & RPC_LOC_GNSS_INFO_VALID_POS_DOP) { LOC_LOGV("position dop: %.3f\n", (float) gnss->position_dop); } if (gnss->valid_mask & RPC_LOC_GNSS_INFO_VALID_HOR_DOP) { LOC_LOGV("horizontal dop: %.3f\n", (float) gnss->horizontal_dop); } if (gnss->valid_mask & RPC_LOC_GNSS_INFO_VALID_VERT_DOP) { LOC_LOGV("vertical dop: %.3f\n", (float) gnss->vertical_dop); } if (gnss->valid_mask & RPC_LOC_GNSS_INFO_VALID_ALTITUDE_ASSUMED) { LOC_LOGV("altitude assumed: %d\n", (int) gnss->altitude_assumed); } if (gnss->valid_mask & RPC_LOC_GNSS_INFO_VALID_SV_COUNT) { LOC_LOGD("sv count: %d\n", (int) gnss->sv_count); } if (gnss->valid_mask & RPC_LOC_GNSS_INFO_VALID_SV_LIST) { LOC_LOGV("sv list: "); if (gnss->sv_count) { LOC_LOGV("\n\tsys\tprn\thlth\tproc\teph\talm\telev\tazi\tsnr\n"); } else { LOC_LOGV("empty\n"); } int i; for (i = 0; i < gnss->sv_count; i++) { const rpc_loc_sv_info_s_type *sv = &gnss->sv_list.sv_list_val[i]; rpc_loc_sv_info_valid_mask_type mask = sv->valid_mask; LOC_LOGV(" %d: \t%d\t%d\t%d\t%d\t%d\t%d\t%.3f\t%.3f\t%.3f\n", i, CHECK_MASK(int, sv->system, mask, RPC_LOC_SV_INFO_VALID_SYSTEM), CHECK_MASK(int, sv->prn, mask, RPC_LOC_SV_INFO_VALID_PRN), CHECK_MASK(int, sv->health_status, mask, RPC_LOC_SV_INFO_VALID_HEALTH_STATUS), CHECK_MASK(int, sv->process_status, mask, RPC_LOC_SV_INFO_VALID_PROCESS_STATUS), CHECK_MASK(int, sv->has_eph, mask, RPC_LOC_SV_INFO_VALID_HAS_EPH), CHECK_MASK(int, sv->has_alm, mask, RPC_LOC_SV_INFO_VALID_HAS_ALM), CHECK_MASK(float, sv->elevation, mask, RPC_LOC_SV_INFO_VALID_ELEVATION), CHECK_MASK(float, sv->azimuth, mask, RPC_LOC_SV_INFO_VALID_AZIMUTH), CHECK_MASK(float, sv->snr, mask, RPC_LOC_SV_INFO_VALID_SNR) ); } } } /* Logs a callback event */ int loc_callback_log( rpc_loc_event_mask_type loc_event, /* event mask */ const rpc_loc_event_payload_u_type* loc_event_payload /* payload */ ) { switch (loc_event) { case RPC_LOC_EVENT_SATELLITE_REPORT: log_satellite_report(&loc_event_payload-> rpc_loc_event_payload_u_type_u.gnss_report); break; case RPC_LOC_EVENT_STATUS_REPORT: log_status_report(&loc_event_payload-> rpc_loc_event_payload_u_type_u.status_report); break; case RPC_LOC_EVENT_PARSED_POSITION_REPORT: log_parsed_report(&loc_event_payload-> rpc_loc_event_payload_u_type_u.parsed_location_report); break; default: break; } return 0; } /* Finds the first event found in the mask */ const char* loc_get_event_name(rpc_loc_event_mask_type loc_event_mask) { return loc_get_name_from_mask(loc_event_name, loc_event_num, (long) loc_event_mask); } /* Finds IOCTL type name */ const char* loc_get_ioctl_type_name(rpc_loc_ioctl_e_type ioctl_type) { return loc_get_name_from_val(loc_ioctl_type_name, loc_ioctl_type_num, (long) ioctl_type); } /* Finds IOCTL status name */ const char* loc_get_ioctl_status_name(uint32 status) { return loc_get_name_from_val(loc_ioctl_status_name, loc_ioctl_status_num, (long) status); } /* Finds session status name */ const char* loc_get_sess_status_name(rpc_loc_session_status_e_type status) { return loc_get_name_from_val(loc_sess_status_name, loc_sess_status_num, (long) status); } /* Find engine state name */ const char* loc_get_engine_state_name(rpc_loc_engine_state_e_type state) { return loc_get_name_from_val(loc_engine_state_name, loc_engine_state_num, (long) state); } /* Find engine state name */ const char* loc_get_fix_session_state_name(rpc_loc_fix_session_state_e_type state) { return loc_get_name_from_val(loc_fix_session_state_name, loc_fix_session_state_num, (long) state); } /* Event names */ loc_name_val_s_type rpc_reset_event_name[] = { NAME_VAL( RPC_SUBSYSTEM_RESTART_BEGIN ), NAME_VAL( RPC_SUBSYSTEM_RESTART_END ) }; int rpc_reset_event_num = sizeof rpc_reset_event_name / sizeof(loc_name_val_s_type); const char* loc_get_rpc_reset_event_name(enum rpc_reset_event event) { return loc_get_name_from_val(rpc_reset_event_name, rpc_reset_event_num, event); } ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/libloc_api-rpc-glue/src/loc_api_rpc_glue.c ================================================ /* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*===================================================================== INCLUDE FILES FOR MODULE ======================================================================*/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* Include RPC headers */ #include "rpc_inc/loc_api_rpc_glue.h" /* Callback init */ #include "rpc_inc/loc_apicb_appinit.h" /* Logging */ #define LOG_TAG "LocSvc_api_rpc_glue" #define LOG_NDDEBUG 0 #ifndef USE_GLIB #include #endif /* USE_GLIB */ /* Logging Improvement */ #include "log_util.h" #include "platform_lib_includes.h" /*Maximum number of Modem init*/ #define RPC_TRY_NUM 10 /*Maximum number of Modem init*/ #define RPC_TRY_NUM 10 /* Uncomment to force ALOGD messages */ // #define ALOGD ALOGI /*===================================================================== External declarations ======================================================================*/ CLIENT* loc_api_clnt = NULL; /* Callback ID and pointer */ #define LOC_API_CB_MAX_CLIENTS 16 typedef struct { uint32 cb_id; /* same as rpc/types.h */ loc_event_cb_f_type *cb_func; /* callback func */ loc_reset_notif_cb_f_type *rpc_cb; /* callback from RPC */ rpc_loc_client_handle_type handle; /* stores handle for client closing */ void* user; /* user's own data handle */ } loc_glue_cb_entry_s_type; loc_glue_cb_entry_s_type loc_glue_callback_table[LOC_API_CB_MAX_CLIENTS]; #define RPC_FUNC_VERSION_BASE(a,b) a ## b #define RPC_FUNC_VERSION(a,b) RPC_FUNC_VERSION_BASE(a,b) #define RPC_CALLBACK_FUNC_VERSION_BASE(a,v,b) a ## v ## b #define RPC_CALLBACK_FUNC_VERSION(a,v,b) RPC_CALLBACK_FUNC_VERSION_BASE(a,v,b) #define LOC_GLUE_CHECK_INIT(ret_type) \ if (loc_api_clnt == NULL) { EXIT_LOG_CALLFLOW(%d, RPC_LOC_API_RPC_FAILURE); return (ret_type) RPC_LOC_API_RPC_FAILURE; } #define LOC_GLUE_CHECK_RESULT(stat, ret_type) \ if (stat != RPC_SUCCESS) { \ LOC_LOGE("%s:%d] failure code %d", __func__, __LINE__, stat); \ return (ret_type)((stat == RPC_SUBSYSTEM_RESTART) ? \ RPC_LOC_API_RPC_MODEM_RESTART : RPC_LOC_API_RPC_FAILURE); \ } /* Callback functions */ /* Returns 1 if successful */ bool_t rpc_loc_event_cb_f_type_svc( rpc_loc_event_cb_f_type_args *argp, rpc_loc_event_cb_f_type_rets *ret, struct svc_req *req) { // The lower word of cd_id is the index int index = argp->cb_id & 0xFFFF; /* Callback not registered, or unexpected ID (shouldn't happen) */ if (index >= LOC_API_CB_MAX_CLIENTS || loc_glue_callback_table[index].cb_func == NULL) { LOC_LOGE("Warning: No callback handler %d.\n", index); ret->loc_event_cb_f_type_result = 0; return 1; /* simply return */ } LOC_LOGV("proc: %x prog: %x vers: %x\n", (int) req->rq_proc, (int) req->rq_prog, (int) req->rq_vers); LOC_LOGV("Callback received: %x (cb_id=%p handle=%d ret_ptr=%d)\n", (int) argp->loc_event, argp->cb_id, (int) argp->loc_handle, (int) ret); /* Forward callback to real callback procedure */ rpc_loc_client_handle_type loc_handle = argp->loc_handle; rpc_loc_event_mask_type loc_event = argp->loc_event; const rpc_loc_event_payload_u_type* loc_event_payload = (const rpc_loc_event_payload_u_type*) argp->loc_event_payload; /* Gives control to synchronous call handler */ loc_api_callback_process_sync_call(loc_handle, loc_event, loc_event_payload); int32 rc = (loc_glue_callback_table[index].cb_func)(loc_glue_callback_table[index].user, loc_handle, loc_event, loc_event_payload); LOC_LOGV("cb_func=%p", loc_glue_callback_table[index].cb_func); ret->loc_event_cb_f_type_result = rc; return 1; /* ok */ } int loc_apicbprog_freeresult (SVCXPRT *transp, xdrproc_t xdr_result, caddr_t result) { xdr_free (xdr_result, result); /* * Insert additional freeing code here, if needed */ // LOC_LOGD("***** loc_apicbprog_freeresult\n"); return 1; } /*=========================================================================== FUNCTION rpc_loc_event_cb_f_type__svc (MACRO) DESCRIPTION Callback function for Loc API RETURN VALUE 1 for success 0 for failure ===========================================================================*/ bool_t RPC_CALLBACK_FUNC_VERSION(rpc_loc_event_cb_f_type_, RPC_LOC_EVENT_CB_F_TYPE_VERSION, _svc) ( rpc_loc_event_cb_f_type_args *argp, rpc_loc_event_cb_f_type_rets *ret, struct svc_req *req) { return rpc_loc_event_cb_f_type_svc(argp, ret, req); } /*=========================================================================== FUNCTION loc_apicbprog__freeresult (MACRO) DESCRIPTION Free up RPC data structure RETURN VALUE 1 for success 0 for failure ===========================================================================*/ #define VERSION_CONCAT(MAJOR,MINOR) MAJOR##MINOR #define loc_apicb_prog_VER_freeresult(M,N) \ int RPC_CALLBACK_FUNC_VERSION(loc_apicbprog_, VERSION_CONCAT(M,N), _freeresult) \ (SVCXPRT *transp, xdrproc_t xdr_result, caddr_t result) \ { \ return loc_apicbprog_freeresult(transp, xdr_result, result); \ } /* Define all of the possible minors */ loc_apicb_prog_VER_freeresult(RPC_LOC_API_API_MAJOR_NUM, 0001); loc_apicb_prog_VER_freeresult(RPC_LOC_API_API_MAJOR_NUM, 0002); loc_apicb_prog_VER_freeresult(RPC_LOC_API_API_MAJOR_NUM, 0003); loc_apicb_prog_VER_freeresult(RPC_LOC_API_API_MAJOR_NUM, 0004); loc_apicb_prog_VER_freeresult(RPC_LOC_API_API_MAJOR_NUM, 0005); loc_apicb_prog_VER_freeresult(RPC_LOC_API_API_MAJOR_NUM, 0006); /*=========================================================================== FUNCTION rpc_loc_api_cb_null__svc (MACRO) [Patch for wrong RPCGEN stubs] DESCRIPTION Null callback function for Loc API RETURN VALUE 1 for success ===========================================================================*/ #define rpc_loc_api_cb_null_VER_svc(M,N) \ bool_t RPC_CALLBACK_FUNC_VERSION(rpc_loc_api_cb_null_, VERSION_CONCAT(M,N), _svc) ( \ void *a, int *b, struct svc_req *req) \ { \ return 1; \ } /* Define all of the possible minors */ rpc_loc_api_cb_null_VER_svc(RPC_LOC_API_API_MAJOR_NUM, 0001); rpc_loc_api_cb_null_VER_svc(RPC_LOC_API_API_MAJOR_NUM, 0002); rpc_loc_api_cb_null_VER_svc(RPC_LOC_API_API_MAJOR_NUM, 0003); rpc_loc_api_cb_null_VER_svc(RPC_LOC_API_API_MAJOR_NUM, 0004); rpc_loc_api_cb_null_VER_svc(RPC_LOC_API_API_MAJOR_NUM, 0005); rpc_loc_api_cb_null_VER_svc(RPC_LOC_API_API_MAJOR_NUM, 0006); static void loc_api_glue_rpc_cb(CLIENT* client, enum rpc_reset_event event) { int i; for (i = 0; i < LOC_API_CB_MAX_CLIENTS; i++) { if (NULL != loc_glue_callback_table[i].rpc_cb) { loc_glue_callback_table[i].rpc_cb(loc_glue_callback_table[i].user, client, event); } } } /*=========================================================================== FUNCTION loc_api_glue_init DESCRIPTION Initiates the RPC client RETURN VALUE 1 for success 0 for failure ===========================================================================*/ int loc_api_glue_init(void) { if (loc_api_clnt == NULL) { /* Initialize data */ int i; int pid = getpid(); for (i = 0; i < LOC_API_CB_MAX_CLIENTS; i++) { loc_glue_callback_table[i].cb_id = i | (pid << 16); loc_glue_callback_table[i].cb_func = NULL; loc_glue_callback_table[i].handle = -1; loc_glue_callback_table[i].rpc_cb = NULL; loc_glue_callback_table[i].user = NULL; } /* Print msg */ LOC_LOGV("Trying to create RPC client...\n"); loc_api_clnt = clnt_create(NULL, LOC_APIPROG, LOC_APIVERS, NULL); LOC_LOGV("Created loc_api_clnt ---- %x\n", (unsigned int)loc_api_clnt); if (loc_api_clnt == NULL) { LOC_LOGE("Error: cannot create RPC client.\n"); return 0; } /* Init RPC callbacks */ loc_api_sync_call_init(); int rc = loc_apicb_app_init(); if (rc >= 0) { LOC_LOGD("Loc API RPC client initialized.\n"); clnt_register_reset_notification_cb(loc_api_clnt, loc_api_glue_rpc_cb); } else { LOC_LOGE("Loc API callback initialization failed.\n"); return 0; } } return 1; } rpc_loc_client_handle_type loc_open ( rpc_loc_event_mask_type event_reg_mask, loc_event_cb_f_type *event_callback, loc_reset_notif_cb_f_type *rpc_cb, void* userData ) { int try_num = RPC_TRY_NUM; ENTRY_LOG(); LOC_GLUE_CHECK_INIT(rpc_loc_client_handle_type); rpc_loc_client_handle_type ret_val; rpc_loc_open_args args; args.event_reg_mask = event_reg_mask; int i, j = LOC_API_CB_MAX_CLIENTS; for (i = 0; i < LOC_API_CB_MAX_CLIENTS; i++) { if (loc_glue_callback_table[i].user == userData) { LOC_LOGW("Client already opened service (callback=%p)...\n", event_callback); break; } else if (j == LOC_API_CB_MAX_CLIENTS && loc_glue_callback_table[i].user == NULL) { j = i; } } if (i == LOC_API_CB_MAX_CLIENTS) { i = j; } if (i == LOC_API_CB_MAX_CLIENTS) { LOC_LOGE("Too many clients opened at once...\n"); return RPC_LOC_CLIENT_HANDLE_INVALID; } loc_glue_callback_table[i].cb_func = event_callback; loc_glue_callback_table[i].rpc_cb = rpc_cb; loc_glue_callback_table[i].user = userData; args.event_callback = loc_glue_callback_table[i].cb_id; LOC_LOGV("cb_id=%d, func=0x%x", i, (unsigned int) event_callback); rpc_loc_open_rets rets; enum clnt_stat stat = RPC_SUCCESS; EXIT_LOG_CALLFLOW(%s, "loc client open"); /*try more for rpc_loc_open_xx()*/ do { stat = RPC_FUNC_VERSION(rpc_loc_open_, RPC_LOC_OPEN_VERSION)(&args, &rets, loc_api_clnt); ret_val = (rpc_loc_client_handle_type) rets.loc_open_result; try_num--; }while( (RPC_SUCCESS != stat||0 > ret_val) && 0 != try_num ); LOC_GLUE_CHECK_RESULT(stat, int32); /* save the handle in the table */ loc_glue_callback_table[i].handle = (rpc_loc_client_handle_type) rets.loc_open_result; return ret_val; } int32 loc_close ( rpc_loc_client_handle_type handle ) { ENTRY_LOG(); LOC_GLUE_CHECK_INIT(int32); int32 ret_val; rpc_loc_close_args args; args.handle = handle; rpc_loc_close_rets rets; enum clnt_stat stat = RPC_SUCCESS; EXIT_LOG_CALLFLOW(%s, "loc client close"); stat = RPC_FUNC_VERSION(rpc_loc_close_, RPC_LOC_CLOSE_VERSION)(&args, &rets, loc_api_clnt); loc_clear(handle); LOC_GLUE_CHECK_RESULT(stat, int32); ret_val = (int32) rets.loc_close_result; return ret_val; } void loc_clear(rpc_loc_client_handle_type handle) { /* Clean the client's callback function in callback table */ int i; for (i = 0; i < LOC_API_CB_MAX_CLIENTS; i++) { if (loc_glue_callback_table[i].handle == handle) { /* Found the client */ loc_glue_callback_table[i].cb_func = NULL; loc_glue_callback_table[i].rpc_cb = NULL; loc_glue_callback_table[i].handle = -1; loc_glue_callback_table[i].user = NULL; break; } } if (i == LOC_API_CB_MAX_CLIENTS) { LOC_LOGW("Handle not found (handle=%d)...\n", (int) handle); } } int32 loc_start_fix ( rpc_loc_client_handle_type handle ) { ENTRY_LOG(); LOC_GLUE_CHECK_INIT(int32); int32 ret_val; rpc_loc_start_fix_args args; args.handle = handle; rpc_loc_start_fix_rets rets; enum clnt_stat stat = RPC_SUCCESS; EXIT_LOG_CALLFLOW(%s, "loc start fix"); stat = RPC_FUNC_VERSION(rpc_loc_start_fix_, RPC_LOC_START_FIX_VERSION)(&args, &rets, loc_api_clnt); LOC_GLUE_CHECK_RESULT(stat, int32); ret_val = (int32) rets.loc_start_fix_result; return ret_val; } int32 loc_stop_fix ( rpc_loc_client_handle_type handle ) { ENTRY_LOG(); LOC_GLUE_CHECK_INIT(int32); int32 ret_val; rpc_loc_stop_fix_args args; args.handle = handle; rpc_loc_stop_fix_rets rets; enum clnt_stat stat = RPC_SUCCESS; EXIT_LOG_CALLFLOW(%s, "loc stop fix"); stat = RPC_FUNC_VERSION(rpc_loc_stop_fix_, RPC_LOC_STOP_FIX_VERSION)(&args, &rets, loc_api_clnt); LOC_GLUE_CHECK_RESULT(stat, int32); ret_val = (int32) rets.loc_stop_fix_result; return ret_val; } int32 loc_ioctl ( rpc_loc_client_handle_type handle, rpc_loc_ioctl_e_type ioctl_type, rpc_loc_ioctl_data_u_type* ioctl_data ) { ENTRY_LOG(); LOC_GLUE_CHECK_INIT(int32); int32 ret_val; rpc_loc_ioctl_args args; args.handle = handle; args.ioctl_data = ioctl_data; args.ioctl_type = ioctl_type; if (ioctl_data != NULL) { /* Assign ioctl union discriminator */ ioctl_data->disc = ioctl_type; /* In case the user hasn't filled in other disc fields, automatically fill them in here */ switch (ioctl_type) { case RPC_LOC_IOCTL_GET_API_VERSION: break; case RPC_LOC_IOCTL_SET_FIX_CRITERIA: break; case RPC_LOC_IOCTL_GET_FIX_CRITERIA: break; case RPC_LOC_IOCTL_INFORM_NI_USER_RESPONSE: break; case RPC_LOC_IOCTL_INJECT_PREDICTED_ORBITS_DATA: break; case RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_VALIDITY: break; case RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_SOURCE: break; case RPC_LOC_IOCTL_SET_PREDICTED_ORBITS_DATA_AUTO_DOWNLOAD: break; case RPC_LOC_IOCTL_INJECT_UTC_TIME: break; case RPC_LOC_IOCTL_INJECT_RTC_VALUE: break; case RPC_LOC_IOCTL_INJECT_POSITION: break; case RPC_LOC_IOCTL_QUERY_ENGINE_STATE: break; case RPC_LOC_IOCTL_INFORM_SERVER_OPEN_STATUS: break; case RPC_LOC_IOCTL_INFORM_SERVER_CLOSE_STATUS: break; case RPC_LOC_IOCTL_SET_ENGINE_LOCK: break; case RPC_LOC_IOCTL_GET_ENGINE_LOCK: break; case RPC_LOC_IOCTL_SET_SBAS_CONFIG: break; case RPC_LOC_IOCTL_GET_SBAS_CONFIG: break; case RPC_LOC_IOCTL_SET_NMEA_TYPES: break; case RPC_LOC_IOCTL_GET_NMEA_TYPES: break; case RPC_LOC_IOCTL_SET_CDMA_PDE_SERVER_ADDR: case RPC_LOC_IOCTL_SET_CDMA_MPC_SERVER_ADDR: case RPC_LOC_IOCTL_SET_UMTS_SLP_SERVER_ADDR: case RPC_LOC_IOCTL_SET_CUSTOM_PDE_SERVER_ADDR: args.ioctl_data->rpc_loc_ioctl_data_u_type_u.server_addr.addr_info.disc = args.ioctl_data->rpc_loc_ioctl_data_u_type_u.server_addr.addr_type; break; case RPC_LOC_IOCTL_GET_CDMA_PDE_SERVER_ADDR: case RPC_LOC_IOCTL_GET_CDMA_MPC_SERVER_ADDR: case RPC_LOC_IOCTL_GET_UMTS_SLP_SERVER_ADDR: case RPC_LOC_IOCTL_GET_CUSTOM_PDE_SERVER_ADDR: break; case RPC_LOC_IOCTL_SET_ON_DEMAND_LPM: break; case RPC_LOC_IOCTL_GET_ON_DEMAND_LPM: break; case RPC_LOC_IOCTL_DELETE_ASSIST_DATA: break; default: break; } /* switch */ } /* ioctl_data != NULL */ rpc_loc_ioctl_rets rets; enum clnt_stat stat = RPC_SUCCESS; EXIT_LOG_CALLFLOW(%s, loc_get_ioctl_type_name(ioctl_type)); stat = RPC_FUNC_VERSION(rpc_loc_ioctl_, RPC_LOC_IOCTL_VERSION)(&args, &rets, loc_api_clnt); LOC_GLUE_CHECK_RESULT(stat, int32); ret_val = (int32) rets.loc_ioctl_result; return ret_val; } /* Returns 0 if error */ int32 loc_api_null(void) { LOC_GLUE_CHECK_INIT(int32); int32 rets; enum clnt_stat stat = RPC_SUCCESS; clnt_unregister_reset_notification_cb(loc_api_clnt); stat = RPC_FUNC_VERSION(rpc_loc_api_null_, RPC_LOC_API_NULL_VERSION)(NULL, &rets, loc_api_clnt); LOC_GLUE_CHECK_RESULT(stat, int32); return (int32) rets; } /*=========================================================================== FUNCTION loc_eng_ioctl DESCRIPTION This function calls loc_ioctl and waits for the callback result before returning back to the user. DEPENDENCIES N/A RETURN VALUE TRUE if successful FALSE if failed SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_ioctl ( rpc_loc_client_handle_type handle, rpc_loc_ioctl_e_type ioctl_type, rpc_loc_ioctl_data_u_type* ioctl_data_ptr, uint32 timeout_msec, rpc_loc_ioctl_callback_s_type *cb_data_ptr ) { int ret_val = RPC_LOC_API_SUCCESS; ret_val = loc_api_sync_ioctl(handle, ioctl_type, ioctl_data_ptr, timeout_msec, cb_data_ptr); LOC_LOGD("loc_eng_ioctl result: client = %d, ioctl_type = %s, returt %s\n", (int32) handle, loc_get_ioctl_type_name(ioctl_type), loc_get_ioctl_status_name(ret_val) ); return ret_val; } ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/libloc_api-rpc-glue/src/loc_api_sync_call.c ================================================ /* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include "loc_api_sync_call.h" /* Logging */ #define LOG_TAG "LocSvc_api_rpc_glue" // #define LOG_NDDEBUG 0 #ifndef USE_GLIB #include #endif /* USE_GLIB */ /*************************************************************************** * DATA FOR ASYNCHRONOUS RPC PROCESSING **************************************************************************/ loc_sync_call_slot_array_s_type loc_sync_data; pthread_mutex_t loc_sync_call_mutex = PTHREAD_MUTEX_INITIALIZER; boolean loc_sync_call_inited = 0; /*=========================================================================== FUNCTION loc_api_sync_call_init DESCRIPTION Initialize this module DEPENDENCIES N/A RETURN VALUE none SIDE EFFECTS N/A ===========================================================================*/ void loc_api_sync_call_init() { pthread_mutex_lock(&loc_sync_call_mutex); if (loc_sync_call_inited == 1) { pthread_mutex_unlock(&loc_sync_call_mutex); return; } loc_sync_call_inited = 1; loc_sync_data.num_of_slots = LOC_SYNC_CALL_SLOTS_MAX; int i; for (i = 0; i < loc_sync_data.num_of_slots; i++) { loc_sync_call_slot_s_type *slot = &loc_sync_data.slots[i]; pthread_mutex_init(&slot->lock, NULL); pthread_cond_init(&slot->loc_cb_arrived_cond, NULL); slot->not_available = 0; slot->in_use = 0; slot->loc_handle = -1; slot->loc_cb_wait_event_mask = 0; /* event to wait */ slot->loc_cb_received_event_mask = 0; /* received event */ } pthread_mutex_unlock(&loc_sync_call_mutex); } /*=========================================================================== FUNCTION loc_api_sync_call_destroy DESCRIPTION Initialize this module DEPENDENCIES N/A RETURN VALUE none SIDE EFFECTS N/A ===========================================================================*/ void loc_api_sync_call_destroy() { int i; pthread_mutex_lock(&loc_sync_call_mutex); if (loc_sync_call_inited == 0) { pthread_mutex_unlock(&loc_sync_call_mutex); return; } loc_sync_call_inited = 0; for (i = 0; i < loc_sync_data.num_of_slots; i++) { loc_sync_call_slot_s_type *slot = &loc_sync_data.slots[i]; pthread_mutex_lock(&slot->lock); slot->not_available = 1; pthread_mutex_unlock(&slot->lock); pthread_cond_destroy(&slot->loc_cb_arrived_cond); pthread_mutex_destroy(&slot->lock); } pthread_mutex_unlock(&loc_sync_call_mutex); } /*=========================================================================== FUNCTION loc_match_callback DESCRIPTION Checks if an awaited event has arrived RETURN VALUE TRUE arrived FALSE not matching ===========================================================================*/ static boolean loc_match_callback( rpc_loc_event_mask_type wait_mask, rpc_loc_ioctl_e_type wait_ioctl, rpc_loc_event_mask_type event_mask, const rpc_loc_event_payload_u_type *callback_payload ) { if ((event_mask & wait_mask) == 0) return FALSE; if (event_mask != RPC_LOC_EVENT_IOCTL_REPORT || wait_ioctl == 0 || ( (callback_payload != NULL) && callback_payload->rpc_loc_event_payload_u_type_u.ioctl_report.type == wait_ioctl) ) return TRUE; return FALSE; } /*=========================================================================== FUNCTION loc_api_callback_process_sync_call DESCRIPTION Wakes up blocked API calls to check if the needed callback has arrived DEPENDENCIES N/A RETURN VALUE none SIDE EFFECTS N/A ===========================================================================*/ void loc_api_callback_process_sync_call( rpc_loc_client_handle_type loc_handle, /* handle of the client */ rpc_loc_event_mask_type loc_event, /* event mask */ const rpc_loc_event_payload_u_type* loc_event_payload /* payload */ ) { int i; ALOGV("loc_handle = 0x%lx, loc_event = 0x%lx", loc_handle, loc_event); for (i = 0; i < loc_sync_data.num_of_slots; i++) { loc_sync_call_slot_s_type *slot = &loc_sync_data.slots[i]; pthread_mutex_lock(&slot->lock); if (slot->in_use && slot->signal_sent == 0 && slot->loc_handle == loc_handle && loc_match_callback(slot->loc_cb_wait_event_mask, slot->ioctl_type, loc_event, loc_event_payload)) { memcpy(&slot->loc_cb_received_payload, loc_event_payload, sizeof (rpc_loc_event_payload_u_type)); slot->loc_cb_received_event_mask = loc_event; ALOGV("signal slot %d in_use %d, loc_handle 0x%lx, event_mask 0x%1x, ioctl_type %d", i, slot->in_use, slot->loc_handle, (int) slot->loc_cb_wait_event_mask, (int) slot->ioctl_type); pthread_cond_signal(&slot->loc_cb_arrived_cond); slot->signal_sent = 1; pthread_mutex_unlock(&slot->lock); break; } else { /* do nothing */ } pthread_mutex_unlock(&slot->lock); } } /*=========================================================================== FUNCTION loc_lock_a_slot DESCRIPTION Allocates a buffer slot for the synchronous API call DEPENDENCIES N/A RETURN VALUE Select ID (>=0) : successful -1 : buffer full SIDE EFFECTS N/A ===========================================================================*/ static int loc_lock_a_slot() { int i, select_id = -1; /* no free buffer */ for (i = 0; i < loc_sync_data.num_of_slots; i++) { loc_sync_call_slot_s_type *slot = &loc_sync_data.slots[i]; if (pthread_mutex_trylock(&slot->lock) == EBUSY) { ALOGV("trylock EBUSY : %d", i); continue; } if (!slot->in_use && !slot->not_available) { select_id = i; /* Return from here and leave the mutex locked. * will unlock it in loc_unlock_slot() */ break; } /* ALOGV("slot %d in_use = %d, not_available = %d : %d", i, slot->in_use, slot->not_available, i); */ pthread_mutex_unlock(&slot->lock); } return select_id; } /*=========================================================================== FUNCTION loc_unlock_slot DESCRIPTION Unlocks a buffer slot DEPENDENCIES N/A RETURN VALUE None SIDE EFFECTS N/A ===========================================================================*/ static void loc_unlock_slot(int select_id) { pthread_mutex_unlock(&loc_sync_data.slots[select_id].lock); } /*=========================================================================== FUNCTION loc_lock_slot DESCRIPTION Locks a specific slot that was previously locked from loc_lock_a_slot DEPENDENCIES N/A RETURN VALUE None SIDE EFFECTS N/A ===========================================================================*/ static void loc_lock_slot(int select_id) { pthread_mutex_lock(&loc_sync_data.slots[select_id].lock); } /*=========================================================================== FUNCTION loc_set_slot_in_use DESCRIPTION Sets the in_use flag of slot to true or false. Should be called only after the slot is locked DEPENDENCIES N/A RETURN VALUE None SIDE EFFECTS N/A ===========================================================================*/ static void loc_set_slot_in_use(int select_id, boolean in_use) { loc_sync_data.slots[select_id].in_use = in_use; if (in_use == 1) loc_sync_data.slots[select_id].signal_sent = 0; } /*=========================================================================== FUNCTION loc_api_save_callback DESCRIPTION Selects which callback or IOCTL event to wait for. The event_mask specifies the event(s). If it is RPC_LOC_EVENT_IOCTL_REPORT, then ioctl_type specifies the IOCTL event. If ioctl_type is non-zero, RPC_LOC_EVENT_IOCTL_REPORT is automatically added. DEPENDENCIES N/A RETURN VALUE Select ID (>=0) : successful -1 : out of buffer SIDE EFFECTS N/A ===========================================================================*/ static void loc_api_save_callback( int select_id, /* Selected slot */ rpc_loc_client_handle_type loc_handle, /* Client handle */ rpc_loc_event_mask_type event_mask, /* Event mask to wait for */ rpc_loc_ioctl_e_type ioctl_type /* IOCTL type to wait for */ ) { loc_sync_call_slot_s_type *slot = &loc_sync_data.slots[select_id]; slot->loc_handle = loc_handle; slot->loc_cb_wait_event_mask = event_mask; slot->ioctl_type = ioctl_type; if (ioctl_type) slot->loc_cb_wait_event_mask |= RPC_LOC_EVENT_IOCTL_REPORT; return; } /*=========================================================================== FUNCTION loc_save_user_payload DESCRIPTION Saves received payload into user data structures RETURN VALUE None ===========================================================================*/ static void loc_save_user_payload( rpc_loc_event_payload_u_type *user_cb_payload, rpc_loc_ioctl_callback_s_type *user_ioctl_buffer, const rpc_loc_event_payload_u_type *received_cb_payload ) { if (user_cb_payload) { memcpy(user_cb_payload, received_cb_payload, sizeof (rpc_loc_event_payload_u_type)); } if (user_ioctl_buffer) { memcpy(user_ioctl_buffer, &received_cb_payload->rpc_loc_event_payload_u_type_u.ioctl_report, sizeof *user_ioctl_buffer); } } /*=========================================================================== FUNCTION loc_api_wait_callback DESCRIPTION Waits for a selected callback. The wait expires in timeout_seconds seconds. If the function is called before an existing wait has finished, it will immediately return EBUSY. DEPENDENCIES N/A RETURN VALUE RPC_LOC_API_SUCCESS if successful (0) RPC_LOC_API_TIMEOUT if timed out RPC_LOC_API_ENGINE_BUSY if already in a wait RPC_LOC_API_INVALID_PARAMETER if callback is not yet selected SIDE EFFECTS N/A ===========================================================================*/ static int loc_api_wait_callback( int select_id, /* ID from loc_select_callback() */ int timeout_seconds, /* Timeout in this number of seconds */ rpc_loc_event_payload_u_type *callback_payload, /* Pointer to callback payload buffer, can be NULL */ rpc_loc_ioctl_callback_s_type *ioctl_payload /* Pointer to IOCTL payload, can be NULL */ ) { int ret_val = RPC_LOC_API_SUCCESS; /* the return value of this function: 0 = no error */ int rc = 0; /* return code from pthread calls */ struct timespec expire_time; loc_sync_call_slot_s_type *slot = &loc_sync_data.slots[select_id]; clock_gettime(CLOCK_REALTIME, &expire_time); expire_time.tv_sec += timeout_seconds; /* Waiting */ while (slot->signal_sent == 0 && rc != ETIMEDOUT) { rc = pthread_cond_timedwait(&slot->loc_cb_arrived_cond, &slot->lock, &expire_time); } if (rc == ETIMEDOUT) { ret_val = RPC_LOC_API_TIMEOUT; /* Timed out */ ALOGE("TIMEOUT: %d", select_id); } else { /* Obtained the first awaited callback */ ret_val = RPC_LOC_API_SUCCESS; /* Successful */ loc_save_user_payload(callback_payload, ioctl_payload, &slot->loc_cb_received_payload); } return ret_val; } /*=========================================================================== FUNCTION loc_api_sync_ioctl DESCRIPTION Synchronous IOCTL call (reentrant version) DEPENDENCIES N/A RETURN VALUE Loc API error code (0 = success) SIDE EFFECTS N/A ===========================================================================*/ int loc_api_sync_ioctl ( rpc_loc_client_handle_type handle, rpc_loc_ioctl_e_type ioctl_type, rpc_loc_ioctl_data_u_type* ioctl_data_ptr, uint32 timeout_msec, rpc_loc_ioctl_callback_s_type *cb_data_ptr ) { int rc = -1; int select_id; rpc_loc_ioctl_callback_s_type callback_data; select_id = loc_lock_a_slot(); if (select_id < 0 || select_id >= loc_sync_data.num_of_slots) { ALOGE("slot not available ioctl_type = %s", loc_get_ioctl_type_name(ioctl_type)); return rc; } loc_set_slot_in_use(select_id, 1); // set slot in use to true // Select the callback we are waiting for loc_api_save_callback(select_id, handle, 0, ioctl_type); loc_unlock_slot(select_id); // slot is unlocked, but in_use is still true // we want to avoid keeping the slot locked during the loc_ioctl because the rpc // framework will also lock a different mutex during this call, and typically // locking two different mutexes at the same time can lead to deadlock. rc = loc_ioctl(handle, ioctl_type, ioctl_data_ptr); loc_lock_slot(select_id); if (rc != RPC_LOC_API_SUCCESS) { ALOGE("loc_ioctl failed select_id = %d, ioctl_type %s, returned %s", select_id, loc_get_ioctl_type_name(ioctl_type), loc_get_ioctl_status_name(rc)); } else { ALOGV("select_id = %d, ioctl_type %d, returned RPC_LOC_API_SUCCESS", select_id, ioctl_type); // Wait for the callback of loc_ioctl if ((rc = loc_api_wait_callback(select_id, timeout_msec / 1000, NULL, &callback_data)) != 0) { // Callback waiting failed ALOGE("callback wait failed select_id = %d, ioctl_type %s, returned %s", select_id, loc_get_ioctl_type_name(ioctl_type), loc_get_ioctl_status_name(rc)); } else { if (cb_data_ptr) memcpy(cb_data_ptr, &callback_data, sizeof *cb_data_ptr); if (callback_data.status != RPC_LOC_API_SUCCESS) { rc = callback_data.status; ALOGE("callback status failed select_id = %d, ioctl_type %s, returned %s", select_id, loc_get_ioctl_type_name(ioctl_type), loc_get_ioctl_status_name(rc)); } else { ALOGV("callback status success select_id = %d, ioctl_type %d, returned %d", select_id, ioctl_type, rc); } } /* wait callback */ } /* loc_ioctl */ loc_set_slot_in_use(select_id, 0); // set slot in use to false loc_unlock_slot(select_id); return rc; } ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/libloc_api-rpc-glue/src/loc_apicb_appinit.c ================================================ /* Copyright (c) 2011, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "rpc/rpc.h" /* Include RPC headers */ #ifdef USE_LOCAL_RPC #include "rpc_inc/loc_api_common.h" #include "rpc_inc/loc_api.h" #include "rpc_inc/loc_api_cb.h" #endif #ifdef USE_QCOM_AUTO_RPC #include "loc_api_rpcgen_rpc.h" #include "loc_api_rpcgen_common_rpc.h" #include "loc_api_rpcgen_cb_rpc.h" #endif #include "rpc_inc/loc_api_fixup.h" #include "loc_apicb_appinit.h" #define RPC_FUNC_VERSION_BASE(a,b) a ## b #define RPC_CB_FUNC_VERS(a,b) RPC_FUNC_VERSION_BASE(a,b) static SVCXPRT* svrPort = NULL; extern void RPC_CB_FUNC_VERS(loc_apicbprog_,LOC_APICBVERS_0001)(struct svc_req *rqstp, register SVCXPRT *transp); int loc_apicb_app_init(void) { /* Register a callback server to use the loc_apicbprog_* function */ if (svrPort == NULL) { svrPort = svcrtr_create(); } if (!svrPort) return -1; xprt_register(svrPort); if(svc_register(svrPort, LOC_APICBPROG, LOC_APICBVERS_0001, RPC_CB_FUNC_VERS(loc_apicbprog_,LOC_APICBVERS_0001),0)) { return 0; } else { return -1; } } void loc_apicb_app_deinit(void) { if (svrPort == NULL) { return; } svc_unregister(svrPort, LOC_APICBPROG, LOC_APICBVERS_0001); xprt_unregister(svrPort); svc_destroy(svrPort); svrPort = NULL; } ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/libloc_api-rpc-stub/Android.mk ================================================ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) # functions LOC_RPCGEN_APIS_PATH := $(TARGET_OUT_INTERMEDIATES)/loc_api/libloc_api_rpcgen_intermediates LOC_RPCGEN_APIS_PATH_FL := ../../../../../$(TARGET_OUT_INTERMEDIATES)/loc_api/libloc_api_rpcgen_intermediates LOCAL_MODULE := libloc_api_rpcgen LOCAL_MODULE_OWNER := qcom LOCAL_SHARED_LIBRARIES := \ librpc \ libcommondefs LOCAL_SRC_FILES += \ src/loc_api_rpcgen_cb_xdr.c \ src/loc_api_rpcgen_common_xdr.c \ src/loc_api_rpcgen_cb_svc.c \ src/loc_api_rpcgen_clnt.c \ src/loc_api_rpcgen_xdr.c LOCAL_C_INCLUDES += hardware/msm7k/librpc LOCAL_C_INCLUDES += $(LOC_RPCGEN_APIS_PATH)/../../SHARED_LIBRARIES/libcommondefs_intermediates/inc LOCAL_C_INCLUDES += $(LOCAL_PATH)/inc LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/libcommondefs/rpcgen/inc LOCAL_COPY_HEADERS_TO := loc_api/rpcgen/inc LOCAL_COPY_HEADERS := inc/loc_api_rpcgen_rpc.h LOCAL_COPY_HEADERS += inc/loc_api_rpcgen_common_rpc.h LOCAL_COPY_HEADERS += inc/loc_api_rpcgen_cb_rpc.h LOCAL_COPY_HEADERS += inc/loc_apicb_appinit.h LOCAL_LDLIBS += -lpthread LOCAL_PRELINK_MODULE := false include $(BUILD_STATIC_LIBRARY) ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/libloc_api-rpc-stub/Makefile.am ================================================ AM_CFLAGS = \ -I../../../utils \ -I./inc \ $(MSM7K_CFLAGS) requiredlibs = \ ../../../utils/libgps_utils_so.la \ $(MSM7K_LIBS) h_sources = \ inc/loc_api_rpcgen_rpc.h \ inc/loc_api_rpcgen_common_rpc.h \ inc/loc_api_rpcgen_cb_rpc.h \ inc/loc_apicb_appinit.h c_sources = \ src/loc_api_rpcgen_cb_xdr.c \ src/loc_api_rpcgen_common_xdr.c \ src/loc_api_rpcgen_cb_svc.c \ src/loc_api_rpcgen_clnt.c \ src/loc_api_rpcgen_xdr.c library_includedir = $(pkgincludedir)/libloc_api-rpc-50001/libloc_api-rpc-stub/inc library_include_HEADERS = $(h_sources) libloc_api_rpcgen_la_SOURCES = $(c_sources) $(h_sources) if USE_GLIB libloc_api_rpcgen_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@ libloc_api_rpcgen_la_LDFLAGS = -lstdc++ -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0 libloc_api_rpcgen_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@ else libloc_api_rpcgen_la_CFLAGS = $(AM_CFLAGS) libloc_api_rpcgen_la_LDFLAGS = -lpthread -shared -version-info 1:0:0 libloc_api_rpcgen_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS) endif libloc_api_rpcgen_la_LIBADD = $(requiredlibs) -lstdc++ #Create and Install Libraries lib_LTLIBRARIES = libloc_api_rpcgen.la ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/libloc_api-rpc-stub/inc/loc_api_rpcgen_cb_rpc.h ================================================ /* Copyright (c) 2011, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /* * Please do not edit this file. * It was generated using rpcgen. */ #ifndef _LOC_API_CB_RPC_H_RPCGEN #define _LOC_API_CB_RPC_H_RPCGEN #include "librpc.h" #include "commondefs_rpcgen_rpc.h" #include "loc_api_rpcgen_common_rpc.h" #include #ifdef __cplusplus extern "C" { #endif struct rpc_loc_event_cb_f_type_args { rpc_uint32 cb_id; rpc_loc_client_handle_type loc_handle; rpc_loc_event_mask_type loc_event; rpc_loc_event_payload_u_type *loc_event_payload; }; typedef struct rpc_loc_event_cb_f_type_args rpc_loc_event_cb_f_type_args; struct rpc_loc_event_cb_f_type_rets { rpc_int32 loc_event_cb_f_type_result; }; typedef struct rpc_loc_event_cb_f_type_rets rpc_loc_event_cb_f_type_rets; #define LOC_APICBVERS 0x00050006 #define LOC_APICBPROG 0x3100008C #define LOC_APICBVERS_0001 0x00050001 #if defined(__STDC__) || defined(__cplusplus) #define rpc_loc_event_cb_f_type 1 extern enum clnt_stat rpc_loc_event_cb_f_type_0x00050001(rpc_loc_event_cb_f_type_args *, rpc_loc_event_cb_f_type_rets *, CLIENT *); extern bool_t rpc_loc_event_cb_f_type_0x00050001_svc(rpc_loc_event_cb_f_type_args *, rpc_loc_event_cb_f_type_rets *, struct svc_req *); extern int loc_apicbprog_0x00050001_freeresult (SVCXPRT *, xdrproc_t, caddr_t); #else /* K&R C */ #define rpc_loc_event_cb_f_type 1 extern enum clnt_stat rpc_loc_event_cb_f_type_0x00050001(); extern bool_t rpc_loc_event_cb_f_type_0x00050001_svc(); extern int loc_apicbprog_0x00050001_freeresult (); #endif /* K&R C */ #define LOC_APICBVERS_0002 0x00050002 #if defined(__STDC__) || defined(__cplusplus) #define rpc_loc_api_cb_null 0xffffff00 extern enum clnt_stat rpc_loc_api_cb_null_0x00050002(void *, int *, CLIENT *); extern bool_t rpc_loc_api_cb_null_0x00050002_svc(void *, int *, struct svc_req *); extern int loc_apicbprog_0x00050002_freeresult (SVCXPRT *, xdrproc_t, caddr_t); #else /* K&R C */ #define rpc_loc_api_cb_null 0xffffff00 extern enum clnt_stat rpc_loc_api_cb_null_0x00050002(); extern bool_t rpc_loc_api_cb_null_0x00050002_svc(); extern int loc_apicbprog_0x00050002_freeresult (); #endif /* K&R C */ #define LOC_APICBVERS_0003 0x00050003 #if defined(__STDC__) || defined(__cplusplus) extern enum clnt_stat rpc_loc_api_cb_null_0x00050003(void *, int *, CLIENT *); extern bool_t rpc_loc_api_cb_null_0x00050003_svc(void *, int *, struct svc_req *); extern int loc_apicbprog_0x00050003_freeresult (SVCXPRT *, xdrproc_t, caddr_t); #else /* K&R C */ extern enum clnt_stat rpc_loc_api_cb_null_0x00050003(); extern bool_t rpc_loc_api_cb_null_0x00050003_svc(); extern int loc_apicbprog_0x00050003_freeresult (); #endif /* K&R C */ #define LOC_APICBVERS_0004 0x00050004 #if defined(__STDC__) || defined(__cplusplus) extern enum clnt_stat rpc_loc_api_cb_null_0x00050004(void *, int *, CLIENT *); extern bool_t rpc_loc_api_cb_null_0x00050004_svc(void *, int *, struct svc_req *); extern int loc_apicbprog_0x00050004_freeresult (SVCXPRT *, xdrproc_t, caddr_t); #else /* K&R C */ extern enum clnt_stat rpc_loc_api_cb_null_0x00050004(); extern bool_t rpc_loc_api_cb_null_0x00050004_svc(); extern int loc_apicbprog_0x00050004_freeresult (); #endif /* K&R C */ #define LOC_APICBVERS_0005 0x00050005 #if defined(__STDC__) || defined(__cplusplus) extern enum clnt_stat rpc_loc_api_cb_null_0x00050005(void *, int *, CLIENT *); extern bool_t rpc_loc_api_cb_null_0x00050005_svc(void *, int *, struct svc_req *); extern int loc_apicbprog_0x00050005_freeresult (SVCXPRT *, xdrproc_t, caddr_t); #else /* K&R C */ extern enum clnt_stat rpc_loc_api_cb_null_0x00050005(); extern bool_t rpc_loc_api_cb_null_0x00050005_svc(); extern int loc_apicbprog_0x00050005_freeresult (); #endif /* K&R C */ #define LOC_APICBVERS_0006 0x00050006 #if defined(__STDC__) || defined(__cplusplus) extern enum clnt_stat rpc_loc_api_cb_null_0x00050006(void *, int *, CLIENT *); extern bool_t rpc_loc_api_cb_null_0x00050006_svc(void *, int *, struct svc_req *); extern int loc_apicbprog_0x00050006_freeresult (SVCXPRT *, xdrproc_t, caddr_t); #else /* K&R C */ extern enum clnt_stat rpc_loc_api_cb_null_0x00050006(); extern bool_t rpc_loc_api_cb_null_0x00050006_svc(); extern int loc_apicbprog_0x00050006_freeresult (); #endif /* K&R C */ /* the xdr functions */ #if defined(__STDC__) || defined(__cplusplus) extern bool_t xdr_rpc_loc_event_cb_f_type_args (XDR *, rpc_loc_event_cb_f_type_args*); extern bool_t xdr_rpc_loc_event_cb_f_type_rets (XDR *, rpc_loc_event_cb_f_type_rets*); #else /* K&R C */ extern bool_t xdr_rpc_loc_event_cb_f_type_args (); extern bool_t xdr_rpc_loc_event_cb_f_type_rets (); #endif /* K&R C */ #ifdef __cplusplus } #endif #endif /* !_LOC_API_CB_RPC_H_RPCGEN */ ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/libloc_api-rpc-stub/inc/loc_api_rpcgen_common_rpc.h ================================================ /* Copyright (c) 2011, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /* * Please do not edit this file. * It was generated using rpcgen. */ #ifndef _LOC_API_COMMON_RPC_H_RPCGEN #define _LOC_API_COMMON_RPC_H_RPCGEN #include "librpc.h" #include "commondefs_rpcgen_rpc.h" #include #ifdef __cplusplus extern "C" { #endif #define LOC_API_TOOLVERS 0x00040030 #define LOC_API_FEATURES 0x00000001 #define RPC_LOC_EVENT_STATUS_REPORT 0x00000100 #define RPC_LOC_EVENT_ASSISTANCE_DATA_REQUEST 0x00000020 #define RPC_LOC_EVENT_WPS_NEEDED_REQUEST 0x00000200 #define RPC_LOC_EVENT_SATELLITE_REPORT 0x00000002 #define RPC_LOC_EVENT_PARSED_POSITION_REPORT 0x00000001 #define RPC_LOC_EVENT_RESERVED 0x8000000000000000 #define RPC_LOC_EVENT_LOCATION_SERVER_REQUEST 0x00000040 #define RPC_LOC_EVENT_NMEA_POSITION_REPORT 0x00000008 #define RPC_LOC_EVENT_IOCTL_REPORT 0x00000080 #define RPC_LOC_EVENT_NMEA_1HZ_REPORT 0x00000004 #define RPC_LOC_EVENT_NI_NOTIFY_VERIFY_REQUEST 0x00000010 #define RPC_LOC_API_CB_NULL_VERSION 0x00050002 #define RPC_LOC_EVENT_CB_F_TYPE_VERSION 0x00050001 #define RPC_LOC_API_API_VERSIONS_VERSION 0x00050001 #define RPC_LOC_STOP_FIX_VERSION 0x00050001 #define RPC_LOC_START_FIX_VERSION 0x00050001 #define RPC_LOC_IOCTL_VERSION 0x00050001 #define RPC_LOC_CLOSE_VERSION 0x00050001 #define RPC_LOC_API_RPC_GLUE_CODE_INFO_REMOTE_VERSION 0x00050001 #define RPC_LOC_OPEN_VERSION 0x00050001 #define RPC_LOC_API_NULL_VERSION 0x00050001 #define RPC_LOC_API_API_MAJOR_NUM 0x0005 #define RPC_LOC_APIAPI_VERSION_IS_HASHKEY 0 typedef rpc_int32 rpc_loc_client_handle_type; typedef rpc_uint64 rpc_loc_event_mask_type; typedef rpc_uint64 rpc_loc_position_valid_mask_type; typedef rpc_uint32 rpc_loc_pos_technology_mask_type; enum rpc_loc_session_status_e_type { RPC_LOC_SESS_STATUS_SUCCESS = 0, RPC_LOC_SESS_STATUS_IN_PROGESS = 1, RPC_LOC_SESS_STATUS_GENERAL_FAILURE = 2, RPC_LOC_SESS_STATUS_TIMEOUT = 3, RPC_LOC_SESS_STATUS_USER_END = 4, RPC_LOC_SESS_STATUS_BAD_PARAMETER = 5, RPC_LOC_SESS_STATUS_PHONE_OFFLINE = 6, RPC_LOC_SESS_STATUS_ENGINE_LOCKED = 7, RPC_LOC_SESS_STATUS_MAX = 268435456, }; typedef enum rpc_loc_session_status_e_type rpc_loc_session_status_e_type; struct rpc_loc_calendar_time_s_type { rpc_uint16 year; u_char month; u_char day_of_week; u_char day; u_char hour; u_char minute; u_char second; rpc_uint16 millisecond; }; typedef struct rpc_loc_calendar_time_s_type rpc_loc_calendar_time_s_type; struct rpc_loc_parsed_position_s_type { rpc_loc_position_valid_mask_type valid_mask; rpc_loc_session_status_e_type session_status; rpc_loc_calendar_time_s_type timestamp_calendar; rpc_uint64 timestamp_utc; rpc_uint8 leap_seconds; float time_unc; double latitude; double longitude; float altitude_wrt_ellipsoid; float altitude_wrt_mean_sea_level; float speed_horizontal; float speed_vertical; float heading; float hor_unc_circular; float hor_unc_ellipse_semi_major; float hor_unc_ellipse_semi_minor; float hor_unc_ellipse_orient_azimuth; float vert_unc; float speed_unc; float heading_unc; u_char confidence_horizontal; u_char confidence_vertical; float magnetic_deviation; rpc_loc_pos_technology_mask_type technology_mask; }; typedef struct rpc_loc_parsed_position_s_type rpc_loc_parsed_position_s_type; enum rpc_loc_sv_system_e_type { RPC_LOC_SV_SYSTEM_GPS = 1, RPC_LOC_SV_SYSTEM_GALILEO = 2, RPC_LOC_SV_SYSTEM_SBAS = 3, RPC_LOC_SV_SYSTEM_COMPASS = 4, RPC_LOC_SV_SYSTEM_GLONASS = 5, RPC_LOC_SV_SYSTEM_MAX = 268435456, }; typedef enum rpc_loc_sv_system_e_type rpc_loc_sv_system_e_type; enum rpc_loc_sv_status_e_type { RPC_LOC_SV_STATUS_IDLE = 1, RPC_LOC_SV_STATUS_SEARCH = 2, RPC_LOC_SV_STATUS_TRACK = 3, RPC_LOC_SV_STATUS_MAX = 268435456, }; typedef enum rpc_loc_sv_status_e_type rpc_loc_sv_status_e_type; typedef rpc_uint32 rpc_loc_sv_info_valid_mask_type; struct rpc_loc_sv_info_s_type { rpc_loc_sv_info_valid_mask_type valid_mask; rpc_loc_sv_system_e_type system; rpc_uint8 prn; rpc_uint8 health_status; rpc_loc_sv_status_e_type process_status; rpc_boolean has_eph; rpc_boolean has_alm; float elevation; float azimuth; float snr; }; typedef struct rpc_loc_sv_info_s_type rpc_loc_sv_info_s_type; typedef rpc_uint32 rpc_loc_gnss_info_valid_mask_type; struct rpc_loc_gnss_info_s_type { rpc_loc_gnss_info_valid_mask_type valid_mask; float position_dop; float horizontal_dop; float vertical_dop; rpc_boolean altitude_assumed; rpc_uint16 sv_count; struct { u_int sv_list_len; rpc_loc_sv_info_s_type *sv_list_val; } sv_list; }; typedef struct rpc_loc_gnss_info_s_type rpc_loc_gnss_info_s_type; struct rpc_loc_nmea_report_s_type { rpc_uint16 length; char nmea_sentences[200]; }; typedef struct rpc_loc_nmea_report_s_type rpc_loc_nmea_report_s_type; enum rpc_loc_status_event_e_type { RPC_LOC_STATUS_EVENT_ENGINE_STATE = 1, RPC_LOC_STATUS_EVENT_FIX_SESSION_STATE = 2, RPC_LOC_STATUS_EVENT_MAX = 268435456, }; typedef enum rpc_loc_status_event_e_type rpc_loc_status_event_e_type; enum rpc_loc_engine_state_e_type { RPC_LOC_ENGINE_STATE_ON = 1, RPC_LOC_ENGINE_STATE_OFF = 2, RPC_LOC_ENGINE_STATE_MAX = 268435456, }; typedef enum rpc_loc_engine_state_e_type rpc_loc_engine_state_e_type; enum rpc_loc_fix_session_state_e_type { RPC_LOC_FIX_SESSION_STATE_BEGIN = 1, RPC_LOC_FIX_SESSION_STATE_END = 2, RPC_LOC_FIX_SESSION_STATE_MAX = 268435456, }; typedef enum rpc_loc_fix_session_state_e_type rpc_loc_fix_session_state_e_type; struct rpc_loc_status_event_payload_u_type { rpc_loc_status_event_e_type disc; union { rpc_loc_engine_state_e_type engine_state; rpc_loc_fix_session_state_e_type fix_session_state; } rpc_loc_status_event_payload_u_type_u; }; typedef struct rpc_loc_status_event_payload_u_type rpc_loc_status_event_payload_u_type; struct rpc_loc_status_event_s_type { rpc_loc_status_event_e_type event; rpc_loc_status_event_payload_u_type payload; }; typedef struct rpc_loc_status_event_s_type rpc_loc_status_event_s_type; enum rpc_loc_server_addr_e_type { RPC_LOC_SERVER_ADDR_IPV4 = 1, RPC_LOC_SERVER_ADDR_URL = 2, RPC_LOC_SERVER_ADDR_IPV6 = 3, RPC_LOC_SERVER_ADDR_MAX = 268435456, }; typedef enum rpc_loc_server_addr_e_type rpc_loc_server_addr_e_type; struct rpc_loc_server_addr_ipv4_type { rpc_uint32 addr; rpc_uint16 port; }; typedef struct rpc_loc_server_addr_ipv4_type rpc_loc_server_addr_ipv4_type; struct rpc_loc_server_addr_url_type { rpc_uint16 length; char addr[256]; }; typedef struct rpc_loc_server_addr_url_type rpc_loc_server_addr_url_type; struct rpc_loc_server_addr_ipv6_type { rpc_uint16 addr[8]; rpc_uint32 port; }; typedef struct rpc_loc_server_addr_ipv6_type rpc_loc_server_addr_ipv6_type; struct rpc_loc_server_addr_u_type { rpc_loc_server_addr_e_type disc; union { rpc_loc_server_addr_ipv4_type ipv4; rpc_loc_server_addr_url_type url; rpc_loc_server_addr_ipv6_type ipv6; } rpc_loc_server_addr_u_type_u; }; typedef struct rpc_loc_server_addr_u_type rpc_loc_server_addr_u_type; struct rpc_loc_server_info_s_type { rpc_loc_server_addr_e_type addr_type; rpc_loc_server_addr_u_type addr_info; }; typedef struct rpc_loc_server_info_s_type rpc_loc_server_info_s_type; enum rpc_loc_ni_notify_verify_e_type { RPC_LOC_NI_USER_NO_NOTIFY_NO_VERIFY = 1, RPC_LOC_NI_USER_NOTIFY_ONLY = 2, RPC_LOC_NI_USER_NOTIFY_VERIFY_ALLOW_NO_RESP = 3, RPC_LOC_NI_USER_NOTIFY_VERIFY_NOT_ALLOW_NO_RESP = 4, RPC_LOC_NI_USER_PRIVACY_OVERRIDE = 5, RPC_LOC_NI_USER_NOTIFY_VERITY_TYPE_MAX = 268435456, }; typedef enum rpc_loc_ni_notify_verify_e_type rpc_loc_ni_notify_verify_e_type; enum rpc_loc_ni_event_e_type { RPC_LOC_NI_EVENT_VX_NOTIFY_VERIFY_REQ = 1, RPC_LOC_NI_EVENT_SUPL_NOTIFY_VERIFY_REQ = 2, RPC_LOC_NI_EVENT_UMTS_CP_NOTIFY_VERIFY_REQ = 3, RPC_LOC_NI_EVENT_VX_SERVICE_INTERACTION_REQ = 4, RPC_LOC_NI_EVENT_MAX = 268435456, }; typedef enum rpc_loc_ni_event_e_type rpc_loc_ni_event_e_type; enum rpc_loc_ni_datacoding_scheme_e_type { RPC_LOC_NI_PRESUPL_ISO646IRV = 0, RPC_LOC_NI_PRESUPL_ISO8859 = 1, RPC_LOC_NI_PRESUPL_UTF8 = 2, RPC_LOC_NI_PRESUPL_UTF16 = 3, RPC_LOC_NI_PRESUPL_UCS2 = 4, RPC_LOC_NI_PRESUPL_GSM_DEFAULT = 5, RPC_LOC_NI_PRESUPL_SHIFT_JIS = 6, RPC_LOC_NI_PRESUPL_JIS = 7, RPC_LOC_NI_PRESUPL_EUC = 8, RPC_LOC_NI_PRESUPL_GB2312 = 9, RPC_LOC_NI_PRESUPL_CNS11643 = 10, RPC_LOC_NI_PRESUPL_KSC1001 = 11, RPC_LOC_NI_PRESUPL_ENCODING_UNKNOWN = 2147483647, RPC_LOC_NI_SS_GERMAN = 12, RPC_LOC_NI_SS_ENGLISH = 13, RPC_LOC_NI_SS_ITALIAN = 14, RPC_LOC_NI_SS_FRENCH = 15, RPC_LOC_NI_SS_SPANISH = 16, RPC_LOC_NI_SS_DUTCH = 17, RPC_LOC_NI_SS_SWEDISH = 18, RPC_LOC_NI_SS_DANISH = 19, RPC_LOC_NI_SS_PORTUGUESE = 20, RPC_LOC_NI_SS_FINNISH = 21, RPC_LOC_NI_SS_NORWEGIAN = 22, RPC_LOC_NI_SS_GREEK = 23, RPC_LOC_NI_SS_TURKISH = 24, RPC_LOC_NI_SS_HUNGARIAN = 25, RPC_LOC_NI_SS_POLISH = 26, RPC_LOC_NI_SS_LANGUAGE_UNSPEC = 27, RPC_LOC_NI_SUPL_UTF8 = 28, RPC_LOC_NI_SUPL_UCS2 = 29, RPC_LOC_NI_SUPL_GSM_DEFAULT = 30, RPC_LOC_NI_SUPL_ENCODING_UNKNOWN = 2147483647, }; typedef enum rpc_loc_ni_datacoding_scheme_e_type rpc_loc_ni_datacoding_scheme_e_type; enum rpc_loc_ni_vx_requester_id_encoding_scheme_e_type { RPC_LOC_NI_VX_OCTET = 0, RPC_LOC_NI_VX_EXN_PROTOCOL_MSG = 1, RPC_LOC_NI_VX_ASCII = 2, RPC_LOC_NI_VX_IA5 = 3, RPC_LOC_NI_VX_UNICODE = 4, RPC_LOC_NI_VX_SHIFT_JIS = 5, RPC_LOC_NI_VX_KOREAN = 6, RPC_LOC_NI_VX_LATIN_HEBREW = 7, RPC_LOC_NI_VX_LATIN = 8, RPC_LOC_NI_VX_GSM = 9, RPC_LOC_NI_VX_ENCODING_TYPE_MAX = 268435456, }; typedef enum rpc_loc_ni_vx_requester_id_encoding_scheme_e_type rpc_loc_ni_vx_requester_id_encoding_scheme_e_type; enum rpc_loc_ni_vx_pos_mode_e_type { RPC_LOC_VX_MS_ASSISTED_ONLY = 1, RPC_LOC_VX_MS_BASED_ONLY = 2, RPC_LOC_VX_MS_ASSISTED_PREF_MSBASED_ALLWD = 3, RPC_LOC_VX_MS_BASED_PREF_ASSISTED_ALLWD = 4, RPC_LOC_VX_POS_MODE_MAX = 268435456, }; typedef enum rpc_loc_ni_vx_pos_mode_e_type rpc_loc_ni_vx_pos_mode_e_type; struct rpc_loc_ni_vx_requester_id_s_type { u_char requester_id_length; char requester_id[200]; }; typedef struct rpc_loc_ni_vx_requester_id_s_type rpc_loc_ni_vx_requester_id_s_type; struct rpc_loc_ni_vx_notify_verify_req_s_type { rpc_loc_ni_notify_verify_e_type notification_priv_type; u_char pos_qos_incl; u_char pos_qos; rpc_uint32 num_fixes; rpc_uint32 tbf; rpc_loc_ni_vx_pos_mode_e_type pos_mode; rpc_loc_ni_vx_requester_id_encoding_scheme_e_type encoding_scheme; rpc_loc_ni_vx_requester_id_s_type requester_id; rpc_uint16 user_resp_timer_val; }; typedef struct rpc_loc_ni_vx_notify_verify_req_s_type rpc_loc_ni_vx_notify_verify_req_s_type; enum rpc_loc_ni_supl_pos_method_e_type { RPC_LOC_NI_POSMETHOD_AGPS_SETASSISTED = 1, RPC_LOC_NI_POSMETHOD_AGPS_SETBASED = 2, RPC_LOC_NI_POSMETHOD_AGPS_SETASSISTED_PREF = 3, RPC_LOC_NI_POSMETHOD_AGPS_SETBASED_PREF = 4, RPC_LOC_NI_POSMETHOD_AUTONOMOUS_GPS = 5, RPC_LOC_NI_POSMETHOD_AFLT = 6, RPC_LOC_NI_POSMETHOD_ECID = 7, RPC_LOC_NI_POSMETHOD_EOTD = 8, RPC_LOC_NI_POSMETHOD_OTDOA = 9, RPC_LOC_NI_POSMETHOD_NO_POSITION = 10, RPC_LOC_NI_POSMETHOD_MAX = 268435456, }; typedef enum rpc_loc_ni_supl_pos_method_e_type rpc_loc_ni_supl_pos_method_e_type; struct rpc_loc_ni_supl_slp_session_id_s_type { u_char presence; char session_id[4]; rpc_loc_server_info_s_type slp_address; }; typedef struct rpc_loc_ni_supl_slp_session_id_s_type rpc_loc_ni_supl_slp_session_id_s_type; struct rpc_loc_ni_requestor_id_s_type { u_char data_coding_scheme; char requestor_id_string[200]; u_char string_len; }; typedef struct rpc_loc_ni_requestor_id_s_type rpc_loc_ni_requestor_id_s_type; struct rpc_loc_ni_supl_client_name_s_type { u_char data_coding_scheme; char client_name_string[64]; u_char string_len; }; typedef struct rpc_loc_ni_supl_client_name_s_type rpc_loc_ni_supl_client_name_s_type; struct rpc_loc_ni_supl_qop_s_type { u_char bit_mask; u_char horacc; u_char veracc; rpc_uint16 maxLocAge; u_char delay; }; typedef struct rpc_loc_ni_supl_qop_s_type rpc_loc_ni_supl_qop_s_type; struct rpc_loc_ni_supl_notify_verify_req_s_type { rpc_loc_ni_notify_verify_e_type notification_priv_type; rpc_uint16 flags; rpc_loc_ni_supl_slp_session_id_s_type supl_slp_session_id; char supl_hash[8]; rpc_loc_ni_datacoding_scheme_e_type datacoding_scheme; rpc_loc_ni_supl_pos_method_e_type pos_method; rpc_loc_ni_requestor_id_s_type requestor_id; rpc_loc_ni_supl_client_name_s_type client_name; rpc_loc_ni_supl_qop_s_type supl_qop; rpc_uint16 user_response_timer; }; typedef struct rpc_loc_ni_supl_notify_verify_req_s_type rpc_loc_ni_supl_notify_verify_req_s_type; struct rpc_loc_ni_ext_client_address_s_type { u_char ext_client_address_len; char ext_client_address[20]; }; typedef struct rpc_loc_ni_ext_client_address_s_type rpc_loc_ni_ext_client_address_s_type; enum rpc_loc_ni_location_type_e_type { RPC_LOC_NI_LOCATIONTYPE_CURRENT_LOCATION = 1, RPC_LOC_NI_LOCATIONTYPE_CURRENT_OR_LAST_KNOWN_LOCATION = 2, RPC_LOC_NI_LOCATIONTYPE_INITIAL_LOCATION = 3, RPC_LOC_NI_LOCATIONTYPE_MAX = 268435456, }; typedef enum rpc_loc_ni_location_type_e_type rpc_loc_ni_location_type_e_type; struct rpc_loc_ni_deferred_location_s_type { u_char unused_bits; u_char ms_available; }; typedef struct rpc_loc_ni_deferred_location_s_type rpc_loc_ni_deferred_location_s_type; struct rpc_loc_ni_codeword_string_s_type { u_char data_coding_scheme; char lcs_codeword_string[20]; u_char string_len; }; typedef struct rpc_loc_ni_codeword_string_s_type rpc_loc_ni_codeword_string_s_type; struct rpc_loc_ni_service_type_id_s_type { u_char lcs_service_type_id; }; typedef struct rpc_loc_ni_service_type_id_s_type rpc_loc_ni_service_type_id_s_type; struct rpc_loc_ni_umts_cp_notify_verify_req_s_type { rpc_loc_ni_notify_verify_e_type notification_priv_type; u_char invoke_id; rpc_uint16 flags; u_char notification_length; char notification_text[64]; rpc_loc_ni_datacoding_scheme_e_type datacoding_scheme; rpc_loc_ni_ext_client_address_s_type ext_client_address_data; rpc_loc_ni_location_type_e_type location_type; rpc_loc_ni_deferred_location_s_type deferred_location; rpc_loc_ni_requestor_id_s_type requestor_id; rpc_loc_ni_codeword_string_s_type codeword_string; rpc_loc_ni_service_type_id_s_type service_type_id; rpc_uint16 user_response_timer; }; typedef struct rpc_loc_ni_umts_cp_notify_verify_req_s_type rpc_loc_ni_umts_cp_notify_verify_req_s_type; enum rpc_loc_ni_service_interaction_e_type { RPC_LOC_NI_SERVICE_INTERACTION_ONGOING_NI_INCOMING_MO = 1, RPC_LOC_NI_SERVICE_INTERACTION_MAX = 268435456, }; typedef enum rpc_loc_ni_service_interaction_e_type rpc_loc_ni_service_interaction_e_type; struct rpc_loc_ni_vx_service_interaction_req_s_type { rpc_loc_ni_vx_notify_verify_req_s_type ni_vx_req; rpc_loc_ni_service_interaction_e_type service_interation_type; }; typedef struct rpc_loc_ni_vx_service_interaction_req_s_type rpc_loc_ni_vx_service_interaction_req_s_type; struct rpc_loc_ni_event_payload_u_type { rpc_loc_ni_event_e_type disc; union { rpc_loc_ni_vx_notify_verify_req_s_type vx_req; rpc_loc_ni_supl_notify_verify_req_s_type supl_req; rpc_loc_ni_umts_cp_notify_verify_req_s_type umts_cp_req; rpc_loc_ni_vx_service_interaction_req_s_type service_interaction_req; } rpc_loc_ni_event_payload_u_type_u; }; typedef struct rpc_loc_ni_event_payload_u_type rpc_loc_ni_event_payload_u_type; struct rpc_loc_ni_event_s_type { rpc_loc_ni_event_e_type event; rpc_loc_ni_event_payload_u_type payload; }; typedef struct rpc_loc_ni_event_s_type rpc_loc_ni_event_s_type; enum rpc_loc_assist_data_request_e_type { RPC_LOC_ASSIST_DATA_TIME_REQ = 1, RPC_LOC_ASSIST_DATA_PREDICTED_ORBITS_REQ = 2, RPC_LOC_ASSIST_DATA_POSITION_INJECTION_REQ = 3, RPC_LOC_ASSIST_DATA_MAX = 268435456, }; typedef enum rpc_loc_assist_data_request_e_type rpc_loc_assist_data_request_e_type; typedef char *rpc_struct_loc_time_download_source_s_type_servers_ptr; typedef rpc_struct_loc_time_download_source_s_type_servers_ptr rpc_struct_loc_time_download_source_s_type_servers[3]; struct rpc_loc_time_download_source_s_type { rpc_uint32 delay_threshold; rpc_struct_loc_time_download_source_s_type_servers servers; }; typedef struct rpc_loc_time_download_source_s_type rpc_loc_time_download_source_s_type; typedef char *rpc_struct_loc_predicted_orbits_data_source_s_type_servers_ptr; typedef rpc_struct_loc_predicted_orbits_data_source_s_type_servers_ptr rpc_struct_loc_predicted_orbits_data_source_s_type_servers[3]; struct rpc_loc_predicted_orbits_data_source_s_type { rpc_uint32 max_file_size; rpc_uint32 max_part_size; rpc_struct_loc_predicted_orbits_data_source_s_type_servers servers; }; typedef struct rpc_loc_predicted_orbits_data_source_s_type rpc_loc_predicted_orbits_data_source_s_type; struct rpc_loc_pos_inj_request_s_type { rpc_uint32 flags; double latitude; double longitude; rpc_uint32 position_uncertainty; rpc_uint64 timestamp; }; typedef struct rpc_loc_pos_inj_request_s_type rpc_loc_pos_inj_request_s_type; struct rpc_loc_assist_data_request_payload_u_type { rpc_loc_assist_data_request_e_type disc; union { rpc_loc_time_download_source_s_type time_download; rpc_loc_predicted_orbits_data_source_s_type data_download; rpc_loc_pos_inj_request_s_type pos_injection; } rpc_loc_assist_data_request_payload_u_type_u; }; typedef struct rpc_loc_assist_data_request_payload_u_type rpc_loc_assist_data_request_payload_u_type; struct rpc_loc_assist_data_request_s_type { rpc_loc_assist_data_request_e_type event; rpc_loc_assist_data_request_payload_u_type payload; }; typedef struct rpc_loc_assist_data_request_s_type rpc_loc_assist_data_request_s_type; typedef rpc_uint32 rpc_loc_server_connection_handle; enum rpc_loc_server_protocol_e_type { RPC_LOC_SERVER_PROTOCOL_DEFAULT = 0, RPC_LOC_SERVER_PROTOCOL_SUPL = 1, RPC_LOC_SERVER_PROTOCOL_VX_MPC = 2, RPC_LOC_SERVER_PROTOCOL_VX_PDE = 3, RPC_LOC_SERVER_PROTOCOL_MAX = 16777216, }; typedef enum rpc_loc_server_protocol_e_type rpc_loc_server_protocol_e_type; enum rpc_loc_server_connection_e_type { RPC_LOC_SERVER_CONNECTION_LBS = 0, RPC_LOC_SERVER_CONNECTION_WWAN_INTERNET = 0 + 1, RPC_LOC_SERVER_CONNECTION_MAX = 16777216, }; typedef enum rpc_loc_server_connection_e_type rpc_loc_server_connection_e_type; enum rpc_loc_server_request_e_type { RPC_LOC_SERVER_REQUEST_OPEN = 1, RPC_LOC_SERVER_REQUEST_CLOSE = 2, RPC_LOC_SERVER_REQUEST_MULTI_OPEN = 3, RPC_LOC_SERVER_REQUEST_MAX = 268435456, }; typedef enum rpc_loc_server_request_e_type rpc_loc_server_request_e_type; struct rpc_loc_server_open_req_s_type { rpc_loc_server_connection_handle conn_handle; rpc_loc_server_protocol_e_type protocol; }; typedef struct rpc_loc_server_open_req_s_type rpc_loc_server_open_req_s_type; struct rpc_loc_server_multi_open_req_s_type { rpc_loc_server_connection_handle conn_handle; rpc_loc_server_protocol_e_type protocol; rpc_loc_server_connection_e_type connection_type; }; typedef struct rpc_loc_server_multi_open_req_s_type rpc_loc_server_multi_open_req_s_type; struct rpc_loc_server_close_req_s_type { rpc_loc_server_connection_handle conn_handle; }; typedef struct rpc_loc_server_close_req_s_type rpc_loc_server_close_req_s_type; struct rpc_loc_server_request_u_type { rpc_loc_server_request_e_type disc; union { rpc_loc_server_open_req_s_type open_req; rpc_loc_server_close_req_s_type close_req; rpc_loc_server_multi_open_req_s_type multi_open_req; } rpc_loc_server_request_u_type_u; }; typedef struct rpc_loc_server_request_u_type rpc_loc_server_request_u_type; struct rpc_loc_server_request_s_type { rpc_loc_server_request_e_type event; rpc_loc_server_request_u_type payload; }; typedef struct rpc_loc_server_request_s_type rpc_loc_server_request_s_type; enum rpc_loc_qwip_request_e_type { RPC_LOC_QWIP_START_PERIODIC_HI_FREQ_FIXES = 0, RPC_LOC_QWIP_START_PERIODIC_KEEP_WARM = 0 + 1, RPC_LOC_QWIP_STOP_PERIODIC_FIXES = 0 + 2, RPC_LOC_QWIP_SUSPEND = 0 + 3, RPC_LOC_QWIP_REQUEST_MAX = 268435456, }; typedef enum rpc_loc_qwip_request_e_type rpc_loc_qwip_request_e_type; struct rpc_loc_qwip_request_s_type { rpc_loc_qwip_request_e_type request_type; rpc_uint16 tbf_ms; }; typedef struct rpc_loc_qwip_request_s_type rpc_loc_qwip_request_s_type; struct rpc_loc_reserved_payload_s_type { rpc_uint16 data_size; struct { u_int data_len; char *data_val; } data; }; typedef struct rpc_loc_reserved_payload_s_type rpc_loc_reserved_payload_s_type; enum rpc_loc_ioctl_e_type { RPC_LOC_IOCTL_GET_API_VERSION = 1, RPC_LOC_IOCTL_SET_FIX_CRITERIA = 2, RPC_LOC_IOCTL_GET_FIX_CRITERIA = 3, RPC_LOC_IOCTL_SERVICE_START_INDEX = 400, RPC_LOC_IOCTL_INFORM_NI_USER_RESPONSE = 400, RPC_LOC_IOCTL_INJECT_PREDICTED_ORBITS_DATA = 401, RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_VALIDITY = 402, RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_SOURCE = 403, RPC_LOC_IOCTL_SET_PREDICTED_ORBITS_DATA_AUTO_DOWNLOAD = 404, RPC_LOC_IOCTL_INJECT_UTC_TIME = 405, RPC_LOC_IOCTL_INJECT_RTC_VALUE = 406, RPC_LOC_IOCTL_INJECT_POSITION = 407, RPC_LOC_IOCTL_QUERY_ENGINE_STATE = 408, RPC_LOC_IOCTL_INFORM_SERVER_OPEN_STATUS = 409, RPC_LOC_IOCTL_INFORM_SERVER_CLOSE_STATUS = 410, RPC_LOC_IOCTL_SEND_WIPER_POSITION_REPORT = 411, RPC_LOC_IOCTL_NOTIFY_WIPER_STATUS = 412, RPC_LOC_IOCTL_ACCESS_EFS_DATA = 413, RPC_LOC_IOCTL_ERROR_ESTIMATE_CONFIG = 414, RPC_LOC_IOCTL_INFORM_SERVER_MULTI_OPEN_STATUS = 415, RPC_LOC_IOCTL_NV_SETTINGS_START_INDEX = 800, RPC_LOC_IOCTL_SET_ENGINE_LOCK = 800, RPC_LOC_IOCTL_GET_ENGINE_LOCK = 801, RPC_LOC_IOCTL_SET_SBAS_CONFIG = 802, RPC_LOC_IOCTL_GET_SBAS_CONFIG = 803, RPC_LOC_IOCTL_SET_NMEA_TYPES = 804, RPC_LOC_IOCTL_GET_NMEA_TYPES = 805, RPC_LOC_IOCTL_SET_CDMA_PDE_SERVER_ADDR = 806, RPC_LOC_IOCTL_GET_CDMA_PDE_SERVER_ADDR = 807, RPC_LOC_IOCTL_SET_CDMA_MPC_SERVER_ADDR = 808, RPC_LOC_IOCTL_GET_CDMA_MPC_SERVER_ADDR = 809, RPC_LOC_IOCTL_SET_UMTS_SLP_SERVER_ADDR = 810, RPC_LOC_IOCTL_GET_UMTS_SLP_SERVER_ADDR = 811, RPC_LOC_IOCTL_SET_ON_DEMAND_LPM = 812, RPC_LOC_IOCTL_GET_ON_DEMAND_LPM = 813, RPC_LOC_IOCTL_SET_XTRA_T_SESSION_CONTROL = 814, RPC_LOC_IOCTL_GET_XTRA_T_SESSION_CONTROL = 815, RPC_LOC_IOCTL_SET_LBS_APN_PROFILE = 816, RPC_LOC_IOCTL_GET_LBS_APN_PROFILE = 817, RPC_LOC_IOCTL_SET_XTRA_APN_PROFILE = 818, RPC_LOC_IOCTL_GET_XTRA_APN_PROFILE = 819, RPC_LOC_IOCTL_SET_DATA_ENABLE = 820, RPC_LOC_IOCTL_SET_SUPL_VERSION = 821, RPC_LOC_IOCTL_GET_SUPL_VERSION = 822, RPC_LOC_IOCTL_PROPRIETARY_START_INDEX = 1000, RPC_LOC_IOCTL_DELETE_ASSIST_DATA = 1000, RPC_LOC_IOCTL_SET_CUSTOM_PDE_SERVER_ADDR = 1001, RPC_LOC_IOCTL_GET_CUSTOM_PDE_SERVER_ADDR = 1002, RPC_LOC_IOCTL_RESERVED_CMD = 8000, RPC_LOC_IOCTL_THIRD_PARTY_START_INDEX = 1073741824, }; typedef enum rpc_loc_ioctl_e_type rpc_loc_ioctl_e_type; struct rpc_loc_api_version_s_type { u_char major; u_char minor; }; typedef struct rpc_loc_api_version_s_type rpc_loc_api_version_s_type; enum rpc_loc_fix_recurrence_e_type { RPC_LOC_PERIODIC_FIX = 1, RPC_LOC_SINGLE_FIX = 2, RPC_LOC_FIX_SESSION_TYPE_MAX = 268435456, }; typedef enum rpc_loc_fix_recurrence_e_type rpc_loc_fix_recurrence_e_type; enum rpc_loc_operation_mode_e_type { RPC_LOC_OPER_MODE_DEFAULT = 1, RPC_LOC_OPER_MODE_MSB = 2, RPC_LOC_OPER_MODE_MSA = 3, RPC_LOC_OPER_MODE_STANDALONE = 4, RPC_LOC_OPER_MODE_SPEED_OPTIMAL = 5, RPC_LOC_OPER_MODE_ACCURACY_OPTIMAL = 6, RPC_LOC_OPER_MODE_DATA_OPTIMAL = 7, RPC_LOC_OPER_MODE_CELL_ID = 8, RPC_LOC_OPER_MODE_MAX = 268435456, }; typedef enum rpc_loc_operation_mode_e_type rpc_loc_operation_mode_e_type; enum rpc_loc_notify_e_type { RPC_LOC_NOTIFY_ON_INTERVAL = 1, RPC_LOC_NOTIFY_ON_DISTANCE = 2, RPC_LOC_NOTIFY_ON_ANY = 3, RPC_LOC_NOTIFY_ON_ALL = 4, RPC_LOC_NOTIFY_TYPE_MAX = 268435456, }; typedef enum rpc_loc_notify_e_type rpc_loc_notify_e_type; struct rpc_loc_fix_criteria_s_type { rpc_uint32 valid_mask; rpc_loc_fix_recurrence_e_type recurrence_type; rpc_loc_operation_mode_e_type preferred_operation_mode; rpc_uint32 preferred_accuracy; rpc_uint32 preferred_response_time; rpc_boolean intermediate_pos_report_enabled; rpc_loc_notify_e_type notify_type; rpc_uint32 min_interval; float min_distance; rpc_uint32 min_dist_sample_interval; }; typedef struct rpc_loc_fix_criteria_s_type rpc_loc_fix_criteria_s_type; enum rpc_loc_ni_user_resp_e_type { RPC_LOC_NI_LCS_NOTIFY_VERIFY_ACCEPT = 1, RPC_LOC_NI_LCS_NOTIFY_VERIFY_DENY = 2, RPC_LOC_NI_LCS_NOTIFY_VERIFY_NORESP = 3, RPC_LOC_NI_LCS_NOTIFY_VERIFY_MAX = 268435456, }; typedef enum rpc_loc_ni_user_resp_e_type rpc_loc_ni_user_resp_e_type; struct rpc_loc_user_verify_s_type { rpc_loc_ni_user_resp_e_type user_resp; rpc_loc_ni_event_s_type ni_event_pass_back; }; typedef struct rpc_loc_user_verify_s_type rpc_loc_user_verify_s_type; enum rpc_loc_predicted_orbits_data_format_e_type { RPC_LOC_PREDICTED_ORBITS_XTRA = 0, RPC_LOC_PREDICTED_ORBITS_FORMAT_MAX = 268435456, }; typedef enum rpc_loc_predicted_orbits_data_format_e_type rpc_loc_predicted_orbits_data_format_e_type; struct rpc_loc_predicted_orbits_data_s_type { rpc_loc_predicted_orbits_data_format_e_type format_type; rpc_uint32 total_size; rpc_uint8 total_parts; rpc_uint8 part; rpc_uint16 part_len; struct { u_int data_ptr_len; char *data_ptr_val; } data_ptr; }; typedef struct rpc_loc_predicted_orbits_data_s_type rpc_loc_predicted_orbits_data_s_type; struct rpc_loc_predicted_orbits_data_validity_report_s_type { rpc_uint64 start_time_utc; rpc_uint16 valid_duration_hrs; }; typedef struct rpc_loc_predicted_orbits_data_validity_report_s_type rpc_loc_predicted_orbits_data_validity_report_s_type; struct rpc_loc_predicted_orbits_auto_download_config_s_type { rpc_boolean enable; u_char auto_check_every_hrs; }; typedef struct rpc_loc_predicted_orbits_auto_download_config_s_type rpc_loc_predicted_orbits_auto_download_config_s_type; struct rpc_loc_assist_data_time_s_type { rpc_uint64 time_utc; rpc_uint32 uncertainty; }; typedef struct rpc_loc_assist_data_time_s_type rpc_loc_assist_data_time_s_type; typedef rpc_uint64 rpc_loc_assist_pos_valid_mask_type; struct rpc_loc_assist_data_pos_s_type { rpc_loc_assist_pos_valid_mask_type valid_mask; rpc_uint64 timestamp_utc; double latitude; double longitude; float altitude_wrt_ellipsoid; float altitude_wrt_mean_sea_level; float hor_unc_circular; float vert_unc; u_char confidence_horizontal; u_char confidence_vertical; rpc_int32 timestamp_age; }; typedef struct rpc_loc_assist_data_pos_s_type rpc_loc_assist_data_pos_s_type; enum rpc_loc_server_open_status_e_type { RPC_LOC_SERVER_OPEN_SUCCESS = 1, RPC_LOC_SERVER_OPEN_FAIL = 2, RPC_LOC_SERVER_OPEN_STATUS_MAX = 268435456, }; typedef enum rpc_loc_server_open_status_e_type rpc_loc_server_open_status_e_type; enum rpc_loc_server_pdp_type_e_type { RPC_LOC_SERVER_PDP_IP = 0, RPC_LOC_SERVER_PDP_PPP = 0 + 1, RPC_LOC_SERVER_PDP_IPV6 = 0 + 2, RPC_LOC_SERVER_PDP_IPV4V6 = 0 + 3, RPC_LOC_SERVER_PDP_MAX = 268435456, }; typedef enum rpc_loc_server_pdp_type_e_type rpc_loc_server_pdp_type_e_type; struct rpc_loc_server_open_status_s_type { rpc_loc_server_connection_handle conn_handle; rpc_loc_server_open_status_e_type open_status; char apn_name[100]; }; typedef struct rpc_loc_server_open_status_s_type rpc_loc_server_open_status_s_type; struct rpc_loc_server_multi_open_status_s_type { rpc_loc_server_connection_handle conn_handle; rpc_loc_server_open_status_e_type open_status; rpc_loc_server_pdp_type_e_type pdp_type; char apn_name[100]; }; typedef struct rpc_loc_server_multi_open_status_s_type rpc_loc_server_multi_open_status_s_type; enum rpc_loc_server_close_status_e_type { RPC_LOC_SERVER_CLOSE_SUCCESS = 1, RPC_LOC_SERVER_CLOSE_FAIL = 2, RPC_LOC_SERVER_CLOSE_STATUS_MAX = 268435456, }; typedef enum rpc_loc_server_close_status_e_type rpc_loc_server_close_status_e_type; struct rpc_loc_server_close_status_s_type { rpc_loc_server_connection_handle conn_handle; rpc_loc_server_close_status_e_type close_status; }; typedef struct rpc_loc_server_close_status_s_type rpc_loc_server_close_status_s_type; struct rpc_loc_wiper_fix_time_s_type { rpc_uint32 slow_clock_count; }; typedef struct rpc_loc_wiper_fix_time_s_type rpc_loc_wiper_fix_time_s_type; struct rpc_loc_wiper_fix_pos_s_type { rpc_int32 lat; rpc_int32 lon; rpc_uint16 HEPE; rpc_uint8 num_of_aps_used; rpc_uint8 fix_error_code; }; typedef struct rpc_loc_wiper_fix_pos_s_type rpc_loc_wiper_fix_pos_s_type; struct rpc_loc_wiper_ap_info_s_type { char mac_addr[6]; rpc_int32 rssi; rpc_uint16 channel; rpc_uint8 ap_qualifier; }; typedef struct rpc_loc_wiper_ap_info_s_type rpc_loc_wiper_ap_info_s_type; struct rpc_loc_wiper_ap_set_s_type { rpc_uint8 num_of_aps; rpc_loc_wiper_ap_info_s_type ap_info[50]; }; typedef struct rpc_loc_wiper_ap_set_s_type rpc_loc_wiper_ap_set_s_type; struct rpc_loc_wiper_position_report_s_type { rpc_uint8 wiper_valid_info_flag; rpc_loc_wiper_fix_time_s_type wiper_fix_time; rpc_loc_wiper_fix_pos_s_type wiper_fix_position; rpc_loc_wiper_ap_set_s_type wiper_ap_set; }; typedef struct rpc_loc_wiper_position_report_s_type rpc_loc_wiper_position_report_s_type; enum rpc_loc_wiper_status_e_type { RPC_LOC_WIPER_STATUS_AVAILABLE = 1, RPC_LOC_WIPER_STATUS_UNAVAILABLE = 2, RPC_LOC_WIPER_STATUS_E_SIZE = 268435456, }; typedef enum rpc_loc_wiper_status_e_type rpc_loc_wiper_status_e_type; enum rpc_loc_fs_operation_e_type { RPC_LOC_FS_CREATE_WRITE_FILE = 1, RPC_LOC_FS_APPEND_FILE = 2, RPC_LOC_FS_DELETE_FILE = 3, RPC_LOC_FS_READ_FILE = 4, RPC_LOC_FS_MAX = 268435456, }; typedef enum rpc_loc_fs_operation_e_type rpc_loc_fs_operation_e_type; struct rpc_loc_efs_data_s_type { char filename[64]; rpc_loc_fs_operation_e_type operation; rpc_uint32 total_size; struct { u_int data_ptr_len; char *data_ptr_val; } data_ptr; rpc_uint32 part_len; rpc_uint8 part; rpc_uint8 total_parts; rpc_uint32 reserved; }; typedef struct rpc_loc_efs_data_s_type rpc_loc_efs_data_s_type; enum rpc_loc_error_estimate_config_e_type { RPC_LOC_ERROR_ESTIMATE_CONFIG_SET = 1, RPC_LOC_ERROR_ESTIMATE_CONFIG_CLEAR = 2, RPC_LOC_ERROR_ESTIMATE_MAX = 268435456, }; typedef enum rpc_loc_error_estimate_config_e_type rpc_loc_error_estimate_config_e_type; struct rpc_loc_apn_profiles_type { rpc_uint32 srv_system_type; rpc_uint32 pdp_type; rpc_uint32 reserved; char apn_name[100]; }; typedef struct rpc_loc_apn_profiles_type rpc_loc_apn_profiles_type; enum rpc_loc_lock_e_type { RPC_LOC_LOCK_NONE = 1, RPC_LOC_LOCK_MI = 2, RPC_LOC_LOCK_MT = 3, RPC_LOC_LOCK_ALL = 4, RPC_LOC_LOCK_MAX = 268435456, }; typedef enum rpc_loc_lock_e_type rpc_loc_lock_e_type; typedef rpc_uint32 rpc_loc_nmea_sentence_type; typedef rpc_uint32 rpc_loc_assist_data_type; struct rpc_loc_assist_data_delete_s_type { rpc_loc_assist_data_type type; rpc_uint32 reserved[8]; }; typedef struct rpc_loc_assist_data_delete_s_type rpc_loc_assist_data_delete_s_type; struct rpc_loc_ioctl_data_u_type { rpc_loc_ioctl_e_type disc; union { rpc_loc_fix_criteria_s_type fix_criteria; rpc_loc_user_verify_s_type user_verify_resp; rpc_loc_predicted_orbits_data_s_type predicted_orbits_data; rpc_loc_predicted_orbits_auto_download_config_s_type predicted_orbits_auto_download; rpc_loc_assist_data_time_s_type assistance_data_time; rpc_loc_assist_data_pos_s_type assistance_data_position; rpc_loc_server_open_status_s_type conn_open_status; rpc_loc_server_close_status_s_type conn_close_status; rpc_loc_wiper_position_report_s_type wiper_pos; rpc_loc_wiper_status_e_type wiper_status; rpc_loc_lock_e_type engine_lock; rpc_boolean sbas_mode; rpc_loc_nmea_sentence_type nmea_types; rpc_boolean on_demand_lpm; rpc_loc_server_info_s_type server_addr; rpc_loc_assist_data_delete_s_type assist_data_delete; rpc_loc_efs_data_s_type efs_data; rpc_loc_error_estimate_config_e_type error_estimate_config; rpc_uint8 xtra_t_session_control; rpc_loc_apn_profiles_type apn_profiles[6]; rpc_boolean data_enable; rpc_uint32 supl_version; rpc_loc_server_multi_open_status_s_type multi_conn_open_status; rpc_loc_reserved_payload_s_type reserved; } rpc_loc_ioctl_data_u_type_u; }; typedef struct rpc_loc_ioctl_data_u_type rpc_loc_ioctl_data_u_type; struct rpc_loc_ioctl_callback_data_u_type { rpc_loc_ioctl_e_type disc; union { rpc_loc_api_version_s_type api_version; rpc_loc_fix_criteria_s_type fix_criteria; rpc_loc_lock_e_type engine_lock; rpc_boolean sbas_mode; rpc_loc_nmea_sentence_type nmea_types; rpc_boolean on_demand_lpm; rpc_loc_server_info_s_type server_addr; rpc_loc_predicted_orbits_data_source_s_type predicted_orbits_data_source; rpc_loc_predicted_orbits_data_validity_report_s_type predicted_orbits_data_validity; rpc_uint8 xtra_t_session_control; rpc_loc_apn_profiles_type apn_profiles[6]; rpc_uint32 supl_version; } rpc_loc_ioctl_callback_data_u_type_u; }; typedef struct rpc_loc_ioctl_callback_data_u_type rpc_loc_ioctl_callback_data_u_type; struct rpc_loc_ioctl_callback_s_type { rpc_loc_ioctl_e_type type; rpc_int32 status; rpc_loc_ioctl_callback_data_u_type data; }; typedef struct rpc_loc_ioctl_callback_s_type rpc_loc_ioctl_callback_s_type; struct rpc_loc_event_payload_u_type { u_quad_t disc; union { rpc_loc_parsed_position_s_type parsed_location_report; rpc_loc_gnss_info_s_type gnss_report; rpc_loc_nmea_report_s_type nmea_report; rpc_loc_ni_event_s_type ni_request; rpc_loc_assist_data_request_s_type assist_data_request; rpc_loc_server_request_s_type loc_server_request; rpc_loc_ioctl_callback_s_type ioctl_report; rpc_loc_status_event_s_type status_report; rpc_loc_qwip_request_s_type qwip_request; rpc_loc_reserved_payload_s_type reserved; } rpc_loc_event_payload_u_type_u; }; typedef struct rpc_loc_event_payload_u_type rpc_loc_event_payload_u_type; /* the xdr functions */ #if defined(__STDC__) || defined(__cplusplus) extern bool_t xdr_rpc_loc_client_handle_type (XDR *, rpc_loc_client_handle_type*); extern bool_t xdr_rpc_loc_event_mask_type (XDR *, rpc_loc_event_mask_type*); extern bool_t xdr_rpc_loc_position_valid_mask_type (XDR *, rpc_loc_position_valid_mask_type*); extern bool_t xdr_rpc_loc_pos_technology_mask_type (XDR *, rpc_loc_pos_technology_mask_type*); extern bool_t xdr_rpc_loc_session_status_e_type (XDR *, rpc_loc_session_status_e_type*); extern bool_t xdr_rpc_loc_calendar_time_s_type (XDR *, rpc_loc_calendar_time_s_type*); extern bool_t xdr_rpc_loc_parsed_position_s_type (XDR *, rpc_loc_parsed_position_s_type*); extern bool_t xdr_rpc_loc_sv_system_e_type (XDR *, rpc_loc_sv_system_e_type*); extern bool_t xdr_rpc_loc_sv_status_e_type (XDR *, rpc_loc_sv_status_e_type*); extern bool_t xdr_rpc_loc_sv_info_valid_mask_type (XDR *, rpc_loc_sv_info_valid_mask_type*); extern bool_t xdr_rpc_loc_sv_info_s_type (XDR *, rpc_loc_sv_info_s_type*); extern bool_t xdr_rpc_loc_gnss_info_valid_mask_type (XDR *, rpc_loc_gnss_info_valid_mask_type*); extern bool_t xdr_rpc_loc_gnss_info_s_type (XDR *, rpc_loc_gnss_info_s_type*); extern bool_t xdr_rpc_loc_nmea_report_s_type (XDR *, rpc_loc_nmea_report_s_type*); extern bool_t xdr_rpc_loc_status_event_e_type (XDR *, rpc_loc_status_event_e_type*); extern bool_t xdr_rpc_loc_engine_state_e_type (XDR *, rpc_loc_engine_state_e_type*); extern bool_t xdr_rpc_loc_fix_session_state_e_type (XDR *, rpc_loc_fix_session_state_e_type*); extern bool_t xdr_rpc_loc_status_event_payload_u_type (XDR *, rpc_loc_status_event_payload_u_type*); extern bool_t xdr_rpc_loc_status_event_s_type (XDR *, rpc_loc_status_event_s_type*); extern bool_t xdr_rpc_loc_server_addr_e_type (XDR *, rpc_loc_server_addr_e_type*); extern bool_t xdr_rpc_loc_server_addr_ipv4_type (XDR *, rpc_loc_server_addr_ipv4_type*); extern bool_t xdr_rpc_loc_server_addr_url_type (XDR *, rpc_loc_server_addr_url_type*); extern bool_t xdr_rpc_loc_server_addr_ipv6_type (XDR *, rpc_loc_server_addr_ipv6_type*); extern bool_t xdr_rpc_loc_server_addr_u_type (XDR *, rpc_loc_server_addr_u_type*); extern bool_t xdr_rpc_loc_server_info_s_type (XDR *, rpc_loc_server_info_s_type*); extern bool_t xdr_rpc_loc_ni_notify_verify_e_type (XDR *, rpc_loc_ni_notify_verify_e_type*); extern bool_t xdr_rpc_loc_ni_event_e_type (XDR *, rpc_loc_ni_event_e_type*); extern bool_t xdr_rpc_loc_ni_datacoding_scheme_e_type (XDR *, rpc_loc_ni_datacoding_scheme_e_type*); extern bool_t xdr_rpc_loc_ni_vx_requester_id_encoding_scheme_e_type (XDR *, rpc_loc_ni_vx_requester_id_encoding_scheme_e_type*); extern bool_t xdr_rpc_loc_ni_vx_pos_mode_e_type (XDR *, rpc_loc_ni_vx_pos_mode_e_type*); extern bool_t xdr_rpc_loc_ni_vx_requester_id_s_type (XDR *, rpc_loc_ni_vx_requester_id_s_type*); extern bool_t xdr_rpc_loc_ni_vx_notify_verify_req_s_type (XDR *, rpc_loc_ni_vx_notify_verify_req_s_type*); extern bool_t xdr_rpc_loc_ni_supl_pos_method_e_type (XDR *, rpc_loc_ni_supl_pos_method_e_type*); extern bool_t xdr_rpc_loc_ni_supl_slp_session_id_s_type (XDR *, rpc_loc_ni_supl_slp_session_id_s_type*); extern bool_t xdr_rpc_loc_ni_requestor_id_s_type (XDR *, rpc_loc_ni_requestor_id_s_type*); extern bool_t xdr_rpc_loc_ni_supl_client_name_s_type (XDR *, rpc_loc_ni_supl_client_name_s_type*); extern bool_t xdr_rpc_loc_ni_supl_qop_s_type (XDR *, rpc_loc_ni_supl_qop_s_type*); extern bool_t xdr_rpc_loc_ni_supl_notify_verify_req_s_type (XDR *, rpc_loc_ni_supl_notify_verify_req_s_type*); extern bool_t xdr_rpc_loc_ni_ext_client_address_s_type (XDR *, rpc_loc_ni_ext_client_address_s_type*); extern bool_t xdr_rpc_loc_ni_location_type_e_type (XDR *, rpc_loc_ni_location_type_e_type*); extern bool_t xdr_rpc_loc_ni_deferred_location_s_type (XDR *, rpc_loc_ni_deferred_location_s_type*); extern bool_t xdr_rpc_loc_ni_codeword_string_s_type (XDR *, rpc_loc_ni_codeword_string_s_type*); extern bool_t xdr_rpc_loc_ni_service_type_id_s_type (XDR *, rpc_loc_ni_service_type_id_s_type*); extern bool_t xdr_rpc_loc_ni_umts_cp_notify_verify_req_s_type (XDR *, rpc_loc_ni_umts_cp_notify_verify_req_s_type*); extern bool_t xdr_rpc_loc_ni_service_interaction_e_type (XDR *, rpc_loc_ni_service_interaction_e_type*); extern bool_t xdr_rpc_loc_ni_vx_service_interaction_req_s_type (XDR *, rpc_loc_ni_vx_service_interaction_req_s_type*); extern bool_t xdr_rpc_loc_ni_event_payload_u_type (XDR *, rpc_loc_ni_event_payload_u_type*); extern bool_t xdr_rpc_loc_ni_event_s_type (XDR *, rpc_loc_ni_event_s_type*); extern bool_t xdr_rpc_loc_assist_data_request_e_type (XDR *, rpc_loc_assist_data_request_e_type*); extern bool_t xdr_rpc_struct_loc_time_download_source_s_type_servers_ptr (XDR *, rpc_struct_loc_time_download_source_s_type_servers_ptr*); extern bool_t xdr_rpc_struct_loc_time_download_source_s_type_servers (XDR *, rpc_struct_loc_time_download_source_s_type_servers); extern bool_t xdr_rpc_loc_time_download_source_s_type (XDR *, rpc_loc_time_download_source_s_type*); extern bool_t xdr_rpc_struct_loc_predicted_orbits_data_source_s_type_servers_ptr (XDR *, rpc_struct_loc_predicted_orbits_data_source_s_type_servers_ptr*); extern bool_t xdr_rpc_struct_loc_predicted_orbits_data_source_s_type_servers (XDR *, rpc_struct_loc_predicted_orbits_data_source_s_type_servers); extern bool_t xdr_rpc_loc_predicted_orbits_data_source_s_type (XDR *, rpc_loc_predicted_orbits_data_source_s_type*); extern bool_t xdr_rpc_loc_pos_inj_request_s_type (XDR *, rpc_loc_pos_inj_request_s_type*); extern bool_t xdr_rpc_loc_assist_data_request_payload_u_type (XDR *, rpc_loc_assist_data_request_payload_u_type*); extern bool_t xdr_rpc_loc_assist_data_request_s_type (XDR *, rpc_loc_assist_data_request_s_type*); extern bool_t xdr_rpc_loc_server_connection_handle (XDR *, rpc_loc_server_connection_handle*); extern bool_t xdr_rpc_loc_server_protocol_e_type (XDR *, rpc_loc_server_protocol_e_type*); extern bool_t xdr_rpc_loc_server_connection_e_type (XDR *, rpc_loc_server_connection_e_type*); extern bool_t xdr_rpc_loc_server_request_e_type (XDR *, rpc_loc_server_request_e_type*); extern bool_t xdr_rpc_loc_server_open_req_s_type (XDR *, rpc_loc_server_open_req_s_type*); extern bool_t xdr_rpc_loc_server_multi_open_req_s_type (XDR *, rpc_loc_server_multi_open_req_s_type*); extern bool_t xdr_rpc_loc_server_close_req_s_type (XDR *, rpc_loc_server_close_req_s_type*); extern bool_t xdr_rpc_loc_server_request_u_type (XDR *, rpc_loc_server_request_u_type*); extern bool_t xdr_rpc_loc_server_request_s_type (XDR *, rpc_loc_server_request_s_type*); extern bool_t xdr_rpc_loc_qwip_request_e_type (XDR *, rpc_loc_qwip_request_e_type*); extern bool_t xdr_rpc_loc_qwip_request_s_type (XDR *, rpc_loc_qwip_request_s_type*); extern bool_t xdr_rpc_loc_reserved_payload_s_type (XDR *, rpc_loc_reserved_payload_s_type*); extern bool_t xdr_rpc_loc_ioctl_e_type (XDR *, rpc_loc_ioctl_e_type*); extern bool_t xdr_rpc_loc_api_version_s_type (XDR *, rpc_loc_api_version_s_type*); extern bool_t xdr_rpc_loc_fix_recurrence_e_type (XDR *, rpc_loc_fix_recurrence_e_type*); extern bool_t xdr_rpc_loc_operation_mode_e_type (XDR *, rpc_loc_operation_mode_e_type*); extern bool_t xdr_rpc_loc_notify_e_type (XDR *, rpc_loc_notify_e_type*); extern bool_t xdr_rpc_loc_fix_criteria_s_type (XDR *, rpc_loc_fix_criteria_s_type*); extern bool_t xdr_rpc_loc_ni_user_resp_e_type (XDR *, rpc_loc_ni_user_resp_e_type*); extern bool_t xdr_rpc_loc_user_verify_s_type (XDR *, rpc_loc_user_verify_s_type*); extern bool_t xdr_rpc_loc_predicted_orbits_data_format_e_type (XDR *, rpc_loc_predicted_orbits_data_format_e_type*); extern bool_t xdr_rpc_loc_predicted_orbits_data_s_type (XDR *, rpc_loc_predicted_orbits_data_s_type*); extern bool_t xdr_rpc_loc_predicted_orbits_data_validity_report_s_type (XDR *, rpc_loc_predicted_orbits_data_validity_report_s_type*); extern bool_t xdr_rpc_loc_predicted_orbits_auto_download_config_s_type (XDR *, rpc_loc_predicted_orbits_auto_download_config_s_type*); extern bool_t xdr_rpc_loc_assist_data_time_s_type (XDR *, rpc_loc_assist_data_time_s_type*); extern bool_t xdr_rpc_loc_assist_pos_valid_mask_type (XDR *, rpc_loc_assist_pos_valid_mask_type*); extern bool_t xdr_rpc_loc_assist_data_pos_s_type (XDR *, rpc_loc_assist_data_pos_s_type*); extern bool_t xdr_rpc_loc_server_open_status_e_type (XDR *, rpc_loc_server_open_status_e_type*); extern bool_t xdr_rpc_loc_server_pdp_type_e_type (XDR *, rpc_loc_server_pdp_type_e_type*); extern bool_t xdr_rpc_loc_server_open_status_s_type (XDR *, rpc_loc_server_open_status_s_type*); extern bool_t xdr_rpc_loc_server_multi_open_status_s_type (XDR *, rpc_loc_server_multi_open_status_s_type*); extern bool_t xdr_rpc_loc_server_close_status_e_type (XDR *, rpc_loc_server_close_status_e_type*); extern bool_t xdr_rpc_loc_server_close_status_s_type (XDR *, rpc_loc_server_close_status_s_type*); extern bool_t xdr_rpc_loc_wiper_fix_time_s_type (XDR *, rpc_loc_wiper_fix_time_s_type*); extern bool_t xdr_rpc_loc_wiper_fix_pos_s_type (XDR *, rpc_loc_wiper_fix_pos_s_type*); extern bool_t xdr_rpc_loc_wiper_ap_info_s_type (XDR *, rpc_loc_wiper_ap_info_s_type*); extern bool_t xdr_rpc_loc_wiper_ap_set_s_type (XDR *, rpc_loc_wiper_ap_set_s_type*); extern bool_t xdr_rpc_loc_wiper_position_report_s_type (XDR *, rpc_loc_wiper_position_report_s_type*); extern bool_t xdr_rpc_loc_wiper_status_e_type (XDR *, rpc_loc_wiper_status_e_type*); extern bool_t xdr_rpc_loc_fs_operation_e_type (XDR *, rpc_loc_fs_operation_e_type*); extern bool_t xdr_rpc_loc_efs_data_s_type (XDR *, rpc_loc_efs_data_s_type*); extern bool_t xdr_rpc_loc_error_estimate_config_e_type (XDR *, rpc_loc_error_estimate_config_e_type*); extern bool_t xdr_rpc_loc_apn_profiles_type (XDR *, rpc_loc_apn_profiles_type*); extern bool_t xdr_rpc_loc_lock_e_type (XDR *, rpc_loc_lock_e_type*); extern bool_t xdr_rpc_loc_nmea_sentence_type (XDR *, rpc_loc_nmea_sentence_type*); extern bool_t xdr_rpc_loc_assist_data_type (XDR *, rpc_loc_assist_data_type*); extern bool_t xdr_rpc_loc_assist_data_delete_s_type (XDR *, rpc_loc_assist_data_delete_s_type*); extern bool_t xdr_rpc_loc_ioctl_data_u_type (XDR *, rpc_loc_ioctl_data_u_type*); extern bool_t xdr_rpc_loc_ioctl_callback_data_u_type (XDR *, rpc_loc_ioctl_callback_data_u_type*); extern bool_t xdr_rpc_loc_ioctl_callback_s_type (XDR *, rpc_loc_ioctl_callback_s_type*); extern bool_t xdr_rpc_loc_event_payload_u_type (XDR *, rpc_loc_event_payload_u_type*); #else /* K&R C */ extern bool_t xdr_rpc_loc_client_handle_type (); extern bool_t xdr_rpc_loc_event_mask_type (); extern bool_t xdr_rpc_loc_position_valid_mask_type (); extern bool_t xdr_rpc_loc_pos_technology_mask_type (); extern bool_t xdr_rpc_loc_session_status_e_type (); extern bool_t xdr_rpc_loc_calendar_time_s_type (); extern bool_t xdr_rpc_loc_parsed_position_s_type (); extern bool_t xdr_rpc_loc_sv_system_e_type (); extern bool_t xdr_rpc_loc_sv_status_e_type (); extern bool_t xdr_rpc_loc_sv_info_valid_mask_type (); extern bool_t xdr_rpc_loc_sv_info_s_type (); extern bool_t xdr_rpc_loc_gnss_info_valid_mask_type (); extern bool_t xdr_rpc_loc_gnss_info_s_type (); extern bool_t xdr_rpc_loc_nmea_report_s_type (); extern bool_t xdr_rpc_loc_status_event_e_type (); extern bool_t xdr_rpc_loc_engine_state_e_type (); extern bool_t xdr_rpc_loc_fix_session_state_e_type (); extern bool_t xdr_rpc_loc_status_event_payload_u_type (); extern bool_t xdr_rpc_loc_status_event_s_type (); extern bool_t xdr_rpc_loc_server_addr_e_type (); extern bool_t xdr_rpc_loc_server_addr_ipv4_type (); extern bool_t xdr_rpc_loc_server_addr_url_type (); extern bool_t xdr_rpc_loc_server_addr_ipv6_type (); extern bool_t xdr_rpc_loc_server_addr_u_type (); extern bool_t xdr_rpc_loc_server_info_s_type (); extern bool_t xdr_rpc_loc_ni_notify_verify_e_type (); extern bool_t xdr_rpc_loc_ni_event_e_type (); extern bool_t xdr_rpc_loc_ni_datacoding_scheme_e_type (); extern bool_t xdr_rpc_loc_ni_vx_requester_id_encoding_scheme_e_type (); extern bool_t xdr_rpc_loc_ni_vx_pos_mode_e_type (); extern bool_t xdr_rpc_loc_ni_vx_requester_id_s_type (); extern bool_t xdr_rpc_loc_ni_vx_notify_verify_req_s_type (); extern bool_t xdr_rpc_loc_ni_supl_pos_method_e_type (); extern bool_t xdr_rpc_loc_ni_supl_slp_session_id_s_type (); extern bool_t xdr_rpc_loc_ni_requestor_id_s_type (); extern bool_t xdr_rpc_loc_ni_supl_client_name_s_type (); extern bool_t xdr_rpc_loc_ni_supl_qop_s_type (); extern bool_t xdr_rpc_loc_ni_supl_notify_verify_req_s_type (); extern bool_t xdr_rpc_loc_ni_ext_client_address_s_type (); extern bool_t xdr_rpc_loc_ni_location_type_e_type (); extern bool_t xdr_rpc_loc_ni_deferred_location_s_type (); extern bool_t xdr_rpc_loc_ni_codeword_string_s_type (); extern bool_t xdr_rpc_loc_ni_service_type_id_s_type (); extern bool_t xdr_rpc_loc_ni_umts_cp_notify_verify_req_s_type (); extern bool_t xdr_rpc_loc_ni_service_interaction_e_type (); extern bool_t xdr_rpc_loc_ni_vx_service_interaction_req_s_type (); extern bool_t xdr_rpc_loc_ni_event_payload_u_type (); extern bool_t xdr_rpc_loc_ni_event_s_type (); extern bool_t xdr_rpc_loc_assist_data_request_e_type (); extern bool_t xdr_rpc_struct_loc_time_download_source_s_type_servers_ptr (); extern bool_t xdr_rpc_struct_loc_time_download_source_s_type_servers (); extern bool_t xdr_rpc_loc_time_download_source_s_type (); extern bool_t xdr_rpc_struct_loc_predicted_orbits_data_source_s_type_servers_ptr (); extern bool_t xdr_rpc_struct_loc_predicted_orbits_data_source_s_type_servers (); extern bool_t xdr_rpc_loc_predicted_orbits_data_source_s_type (); extern bool_t xdr_rpc_loc_pos_inj_request_s_type (); extern bool_t xdr_rpc_loc_assist_data_request_payload_u_type (); extern bool_t xdr_rpc_loc_assist_data_request_s_type (); extern bool_t xdr_rpc_loc_server_connection_handle (); extern bool_t xdr_rpc_loc_server_protocol_e_type (); extern bool_t xdr_rpc_loc_server_connection_e_type (); extern bool_t xdr_rpc_loc_server_request_e_type (); extern bool_t xdr_rpc_loc_server_open_req_s_type (); extern bool_t xdr_rpc_loc_server_multi_open_req_s_type (); extern bool_t xdr_rpc_loc_server_close_req_s_type (); extern bool_t xdr_rpc_loc_server_request_u_type (); extern bool_t xdr_rpc_loc_server_request_s_type (); extern bool_t xdr_rpc_loc_qwip_request_e_type (); extern bool_t xdr_rpc_loc_qwip_request_s_type (); extern bool_t xdr_rpc_loc_reserved_payload_s_type (); extern bool_t xdr_rpc_loc_ioctl_e_type (); extern bool_t xdr_rpc_loc_api_version_s_type (); extern bool_t xdr_rpc_loc_fix_recurrence_e_type (); extern bool_t xdr_rpc_loc_operation_mode_e_type (); extern bool_t xdr_rpc_loc_notify_e_type (); extern bool_t xdr_rpc_loc_fix_criteria_s_type (); extern bool_t xdr_rpc_loc_ni_user_resp_e_type (); extern bool_t xdr_rpc_loc_user_verify_s_type (); extern bool_t xdr_rpc_loc_predicted_orbits_data_format_e_type (); extern bool_t xdr_rpc_loc_predicted_orbits_data_s_type (); extern bool_t xdr_rpc_loc_predicted_orbits_data_validity_report_s_type (); extern bool_t xdr_rpc_loc_predicted_orbits_auto_download_config_s_type (); extern bool_t xdr_rpc_loc_assist_data_time_s_type (); extern bool_t xdr_rpc_loc_assist_pos_valid_mask_type (); extern bool_t xdr_rpc_loc_assist_data_pos_s_type (); extern bool_t xdr_rpc_loc_server_open_status_e_type (); extern bool_t xdr_rpc_loc_server_pdp_type_e_type (); extern bool_t xdr_rpc_loc_server_open_status_s_type (); extern bool_t xdr_rpc_loc_server_multi_open_status_s_type (); extern bool_t xdr_rpc_loc_server_close_status_e_type (); extern bool_t xdr_rpc_loc_server_close_status_s_type (); extern bool_t xdr_rpc_loc_wiper_fix_time_s_type (); extern bool_t xdr_rpc_loc_wiper_fix_pos_s_type (); extern bool_t xdr_rpc_loc_wiper_ap_info_s_type (); extern bool_t xdr_rpc_loc_wiper_ap_set_s_type (); extern bool_t xdr_rpc_loc_wiper_position_report_s_type (); extern bool_t xdr_rpc_loc_wiper_status_e_type (); extern bool_t xdr_rpc_loc_fs_operation_e_type (); extern bool_t xdr_rpc_loc_efs_data_s_type (); extern bool_t xdr_rpc_loc_error_estimate_config_e_type (); extern bool_t xdr_rpc_loc_apn_profiles_type (); extern bool_t xdr_rpc_loc_lock_e_type (); extern bool_t xdr_rpc_loc_nmea_sentence_type (); extern bool_t xdr_rpc_loc_assist_data_type (); extern bool_t xdr_rpc_loc_assist_data_delete_s_type (); extern bool_t xdr_rpc_loc_ioctl_data_u_type (); extern bool_t xdr_rpc_loc_ioctl_callback_data_u_type (); extern bool_t xdr_rpc_loc_ioctl_callback_s_type (); extern bool_t xdr_rpc_loc_event_payload_u_type (); #endif /* K&R C */ #ifdef __cplusplus } #endif #endif /* !_LOC_API_COMMON_RPC_H_RPCGEN */ ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/libloc_api-rpc-stub/inc/loc_api_rpcgen_rpc.h ================================================ /* Copyright (c) 2011, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /* * Please do not edit this file. * It was generated using rpcgen. */ #ifndef _LOC_API_RPC_H_RPCGEN #define _LOC_API_RPC_H_RPCGEN #include "librpc.h" #include "commondefs_rpcgen_rpc.h" #include "loc_api_rpcgen_common_rpc.h" #include #ifdef __cplusplus extern "C" { #endif typedef struct { u_int rpc_loc_api_api_versions_return_type_len; rpc_uint32 *rpc_loc_api_api_versions_return_type_val; } rpc_loc_api_api_versions_return_type; typedef rpc_uint32 rpc_loc_event_cb_f_type; struct rpc_loc_open_args { rpc_loc_event_mask_type event_reg_mask; rpc_loc_event_cb_f_type event_callback; }; typedef struct rpc_loc_open_args rpc_loc_open_args; struct rpc_loc_close_args { rpc_loc_client_handle_type handle; }; typedef struct rpc_loc_close_args rpc_loc_close_args; struct rpc_loc_start_fix_args { rpc_loc_client_handle_type handle; }; typedef struct rpc_loc_start_fix_args rpc_loc_start_fix_args; struct rpc_loc_stop_fix_args { rpc_loc_client_handle_type handle; }; typedef struct rpc_loc_stop_fix_args rpc_loc_stop_fix_args; struct rpc_loc_ioctl_args { rpc_loc_client_handle_type handle; rpc_loc_ioctl_e_type ioctl_type; rpc_loc_ioctl_data_u_type *ioctl_data; }; typedef struct rpc_loc_ioctl_args rpc_loc_ioctl_args; struct rpc_loc_api_api_version_s_args { rpc_boolean len_not_null; }; typedef struct rpc_loc_api_api_version_s_args rpc_loc_api_api_version_s_args; struct rpc_loc_api_rpc_glue_code_info_remote_rets { rpc_uint32 toolvers; rpc_uint32 features; rpc_uint32 proghash; rpc_uint32 cbproghash; }; typedef struct rpc_loc_api_rpc_glue_code_info_remote_rets rpc_loc_api_rpc_glue_code_info_remote_rets; struct rpc_loc_open_rets { rpc_loc_client_handle_type loc_open_result; }; typedef struct rpc_loc_open_rets rpc_loc_open_rets; struct rpc_loc_close_rets { rpc_int32 loc_close_result; }; typedef struct rpc_loc_close_rets rpc_loc_close_rets; struct rpc_loc_start_fix_rets { rpc_int32 loc_start_fix_result; }; typedef struct rpc_loc_start_fix_rets rpc_loc_start_fix_rets; struct rpc_loc_stop_fix_rets { rpc_int32 loc_stop_fix_result; }; typedef struct rpc_loc_stop_fix_rets rpc_loc_stop_fix_rets; struct rpc_loc_ioctl_rets { rpc_int32 loc_ioctl_result; }; typedef struct rpc_loc_ioctl_rets rpc_loc_ioctl_rets; struct rpc_loc_api_api_versions_rets { rpc_loc_api_api_versions_return_type loc_api_api_versions_result; rpc_uint32 *len; }; typedef struct rpc_loc_api_api_versions_rets rpc_loc_api_api_versions_rets; #define LOC_APIVERS 0x00050006 #define LOC_APIPROG 0x3000008C #define LOC_APIVERS_0001 0x00050001 #if defined(__STDC__) || defined(__cplusplus) #define rpc_loc_api_null 0 extern enum clnt_stat rpc_loc_api_null_0x00050001(void *, void *, CLIENT *); extern bool_t rpc_loc_api_null_0x00050001_svc(void *, void *, struct svc_req *); #define rpc_loc_api_rpc_glue_code_info_remote 1 extern enum clnt_stat rpc_loc_api_rpc_glue_code_info_remote_0x00050001(void *, rpc_loc_api_rpc_glue_code_info_remote_rets *, CLIENT *); extern bool_t rpc_loc_api_rpc_glue_code_info_remote_0x00050001_svc(void *, rpc_loc_api_rpc_glue_code_info_remote_rets *, struct svc_req *); #define rpc_loc_open 2 extern enum clnt_stat rpc_loc_open_0x00050001(rpc_loc_open_args *, rpc_loc_open_rets *, CLIENT *); extern bool_t rpc_loc_open_0x00050001_svc(rpc_loc_open_args *, rpc_loc_open_rets *, struct svc_req *); #define rpc_loc_close 3 extern enum clnt_stat rpc_loc_close_0x00050001(rpc_loc_close_args *, rpc_loc_close_rets *, CLIENT *); extern bool_t rpc_loc_close_0x00050001_svc(rpc_loc_close_args *, rpc_loc_close_rets *, struct svc_req *); #define rpc_loc_start_fix 4 extern enum clnt_stat rpc_loc_start_fix_0x00050001(rpc_loc_start_fix_args *, rpc_loc_start_fix_rets *, CLIENT *); extern bool_t rpc_loc_start_fix_0x00050001_svc(rpc_loc_start_fix_args *, rpc_loc_start_fix_rets *, struct svc_req *); #define rpc_loc_stop_fix 5 extern enum clnt_stat rpc_loc_stop_fix_0x00050001(rpc_loc_stop_fix_args *, rpc_loc_stop_fix_rets *, CLIENT *); extern bool_t rpc_loc_stop_fix_0x00050001_svc(rpc_loc_stop_fix_args *, rpc_loc_stop_fix_rets *, struct svc_req *); #define rpc_loc_ioctl 6 extern enum clnt_stat rpc_loc_ioctl_0x00050001(rpc_loc_ioctl_args *, rpc_loc_ioctl_rets *, CLIENT *); extern bool_t rpc_loc_ioctl_0x00050001_svc(rpc_loc_ioctl_args *, rpc_loc_ioctl_rets *, struct svc_req *); #define rpc_loc_api_api_versions 0xFFFFFFFF extern enum clnt_stat rpc_loc_api_api_versions_0x00050001(void *, rpc_loc_api_api_versions_rets *, CLIENT *); extern bool_t rpc_loc_api_api_versions_0x00050001_svc(void *, rpc_loc_api_api_versions_rets *, struct svc_req *); extern int loc_apiprog_0x00050001_freeresult (SVCXPRT *, xdrproc_t, caddr_t); #else /* K&R C */ #define rpc_loc_api_null 0 extern enum clnt_stat rpc_loc_api_null_0x00050001(); extern bool_t rpc_loc_api_null_0x00050001_svc(); #define rpc_loc_api_rpc_glue_code_info_remote 1 extern enum clnt_stat rpc_loc_api_rpc_glue_code_info_remote_0x00050001(); extern bool_t rpc_loc_api_rpc_glue_code_info_remote_0x00050001_svc(); #define rpc_loc_open 2 extern enum clnt_stat rpc_loc_open_0x00050001(); extern bool_t rpc_loc_open_0x00050001_svc(); #define rpc_loc_close 3 extern enum clnt_stat rpc_loc_close_0x00050001(); extern bool_t rpc_loc_close_0x00050001_svc(); #define rpc_loc_start_fix 4 extern enum clnt_stat rpc_loc_start_fix_0x00050001(); extern bool_t rpc_loc_start_fix_0x00050001_svc(); #define rpc_loc_stop_fix 5 extern enum clnt_stat rpc_loc_stop_fix_0x00050001(); extern bool_t rpc_loc_stop_fix_0x00050001_svc(); #define rpc_loc_ioctl 6 extern enum clnt_stat rpc_loc_ioctl_0x00050001(); extern bool_t rpc_loc_ioctl_0x00050001_svc(); #define rpc_loc_api_api_versions 0xFFFFFFFF extern enum clnt_stat rpc_loc_api_api_versions_0x00050001(); extern bool_t rpc_loc_api_api_versions_0x00050001_svc(); extern int loc_apiprog_0x00050001_freeresult (); #endif /* K&R C */ #define LOC_APIVERS_0002 0x00050002 #if defined(__STDC__) || defined(__cplusplus) extern enum clnt_stat rpc_loc_api_null_0x00050002(void *, void *, CLIENT *); extern bool_t rpc_loc_api_null_0x00050002_svc(void *, void *, struct svc_req *); extern int loc_apiprog_0x00050002_freeresult (SVCXPRT *, xdrproc_t, caddr_t); #else /* K&R C */ extern enum clnt_stat rpc_loc_api_null_0x00050002(); extern bool_t rpc_loc_api_null_0x00050002_svc(); extern int loc_apiprog_0x00050002_freeresult (); #endif /* K&R C */ #define LOC_APIVERS_0003 0x00050003 #if defined(__STDC__) || defined(__cplusplus) extern enum clnt_stat rpc_loc_api_null_0x00050003(void *, void *, CLIENT *); extern bool_t rpc_loc_api_null_0x00050003_svc(void *, void *, struct svc_req *); extern int loc_apiprog_0x00050003_freeresult (SVCXPRT *, xdrproc_t, caddr_t); #else /* K&R C */ extern enum clnt_stat rpc_loc_api_null_0x00050003(); extern bool_t rpc_loc_api_null_0x00050003_svc(); extern int loc_apiprog_0x00050003_freeresult (); #endif /* K&R C */ #define LOC_APIVERS_0004 0x00050004 #if defined(__STDC__) || defined(__cplusplus) extern enum clnt_stat rpc_loc_api_null_0x00050004(void *, void *, CLIENT *); extern bool_t rpc_loc_api_null_0x00050004_svc(void *, void *, struct svc_req *); extern int loc_apiprog_0x00050004_freeresult (SVCXPRT *, xdrproc_t, caddr_t); #else /* K&R C */ extern enum clnt_stat rpc_loc_api_null_0x00050004(); extern bool_t rpc_loc_api_null_0x00050004_svc(); extern int loc_apiprog_0x00050004_freeresult (); #endif /* K&R C */ #define LOC_APIVERS_0005 0x00050005 #if defined(__STDC__) || defined(__cplusplus) extern enum clnt_stat rpc_loc_api_null_0x00050005(void *, void *, CLIENT *); extern bool_t rpc_loc_api_null_0x00050005_svc(void *, void *, struct svc_req *); extern int loc_apiprog_0x00050005_freeresult (SVCXPRT *, xdrproc_t, caddr_t); #else /* K&R C */ extern enum clnt_stat rpc_loc_api_null_0x00050005(); extern bool_t rpc_loc_api_null_0x00050005_svc(); extern int loc_apiprog_0x00050005_freeresult (); #endif /* K&R C */ #define LOC_APIVERS_0006 0x00050006 #if defined(__STDC__) || defined(__cplusplus) extern enum clnt_stat rpc_loc_api_null_0x00050006(void *, void *, CLIENT *); extern bool_t rpc_loc_api_null_0x00050006_svc(void *, void *, struct svc_req *); extern int loc_apiprog_0x00050006_freeresult (SVCXPRT *, xdrproc_t, caddr_t); #else /* K&R C */ extern enum clnt_stat rpc_loc_api_null_0x00050006(); extern bool_t rpc_loc_api_null_0x00050006_svc(); extern int loc_apiprog_0x00050006_freeresult (); #endif /* K&R C */ /* the xdr functions */ #if defined(__STDC__) || defined(__cplusplus) extern bool_t xdr_rpc_loc_api_api_versions_return_type (XDR *, rpc_loc_api_api_versions_return_type*); extern bool_t xdr_rpc_loc_event_cb_f_type (XDR *, rpc_loc_event_cb_f_type*); extern bool_t xdr_rpc_loc_open_args (XDR *, rpc_loc_open_args*); extern bool_t xdr_rpc_loc_close_args (XDR *, rpc_loc_close_args*); extern bool_t xdr_rpc_loc_start_fix_args (XDR *, rpc_loc_start_fix_args*); extern bool_t xdr_rpc_loc_stop_fix_args (XDR *, rpc_loc_stop_fix_args*); extern bool_t xdr_rpc_loc_ioctl_args (XDR *, rpc_loc_ioctl_args*); extern bool_t xdr_rpc_loc_api_api_version_s_args (XDR *, rpc_loc_api_api_version_s_args*); extern bool_t xdr_rpc_loc_api_rpc_glue_code_info_remote_rets (XDR *, rpc_loc_api_rpc_glue_code_info_remote_rets*); extern bool_t xdr_rpc_loc_open_rets (XDR *, rpc_loc_open_rets*); extern bool_t xdr_rpc_loc_close_rets (XDR *, rpc_loc_close_rets*); extern bool_t xdr_rpc_loc_start_fix_rets (XDR *, rpc_loc_start_fix_rets*); extern bool_t xdr_rpc_loc_stop_fix_rets (XDR *, rpc_loc_stop_fix_rets*); extern bool_t xdr_rpc_loc_ioctl_rets (XDR *, rpc_loc_ioctl_rets*); extern bool_t xdr_rpc_loc_api_api_versions_rets (XDR *, rpc_loc_api_api_versions_rets*); #else /* K&R C */ extern bool_t xdr_rpc_loc_api_api_versions_return_type (); extern bool_t xdr_rpc_loc_event_cb_f_type (); extern bool_t xdr_rpc_loc_open_args (); extern bool_t xdr_rpc_loc_close_args (); extern bool_t xdr_rpc_loc_start_fix_args (); extern bool_t xdr_rpc_loc_stop_fix_args (); extern bool_t xdr_rpc_loc_ioctl_args (); extern bool_t xdr_rpc_loc_api_api_version_s_args (); extern bool_t xdr_rpc_loc_api_rpc_glue_code_info_remote_rets (); extern bool_t xdr_rpc_loc_open_rets (); extern bool_t xdr_rpc_loc_close_rets (); extern bool_t xdr_rpc_loc_start_fix_rets (); extern bool_t xdr_rpc_loc_stop_fix_rets (); extern bool_t xdr_rpc_loc_ioctl_rets (); extern bool_t xdr_rpc_loc_api_api_versions_rets (); #endif /* K&R C */ #ifdef __cplusplus } #endif #endif /* !_LOC_API_RPC_H_RPCGEN */ ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/libloc_api-rpc-stub/inc/loc_apicb_appinit.h ================================================ /* Copyright (c) 2011, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /* Initialization function for callbacks */ int loc_apicb_app_init(); void loc_apicb_app_deinit(); ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/libloc_api-rpc-stub/src/loc_api_rpcgen_cb_svc.c ================================================ /* Copyright (c) 2011, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /* * Please do not edit this file. * It was generated using rpcgen. */ #include "loc_api_rpcgen_cb_rpc.h" #include #include #include #include #include #include #include #ifndef SIG_PF #define SIG_PF void(*)(int) #endif void loc_apicbprog_0x00050001(struct svc_req *rqstp, register SVCXPRT *transp) { union { rpc_loc_event_cb_f_type_args rpc_loc_event_cb_f_type_0x00050001_arg; } argument; union { rpc_loc_event_cb_f_type_rets rpc_loc_event_cb_f_type_0x00050001_res; } result; bool_t retval; xdrproc_t _xdr_argument, _xdr_result; bool_t (*local)(char *, void *, struct svc_req *); switch (rqstp->rq_proc) { case NULLPROC: (void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL); return; case rpc_loc_event_cb_f_type: _xdr_argument = (xdrproc_t) xdr_rpc_loc_event_cb_f_type_args; _xdr_result = (xdrproc_t) xdr_rpc_loc_event_cb_f_type_rets; local = (bool_t (*) (char *, void *, struct svc_req *))rpc_loc_event_cb_f_type_0x00050001_svc; break; default: svcerr_noproc (transp); return; } memset ((char *)&argument, 0, sizeof (argument)); if (!svc_getargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) { svcerr_decode (transp); return; } retval = (bool_t) (*local)((char *)&argument, (void *)&result, rqstp); if (retval > 0 && !svc_sendreply(transp, (xdrproc_t) _xdr_result, (char *)&result)) { svcerr_systemerr (transp); } if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) { fprintf (stderr, "%s", "unable to free arguments"); exit (1); } if (!loc_apicbprog_0x00050001_freeresult (transp, _xdr_result, (caddr_t) &result)) fprintf (stderr, "%s", "unable to free results"); return; } void loc_apicbprog_0x00050002(struct svc_req *rqstp, register SVCXPRT *transp) { union { int fill; } argument; union { int rpc_loc_api_cb_null_0x00050002_res; } result; bool_t retval; xdrproc_t _xdr_argument, _xdr_result; bool_t (*local)(char *, void *, struct svc_req *); switch (rqstp->rq_proc) { case NULLPROC: (void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL); return; case rpc_loc_api_cb_null: _xdr_argument = (xdrproc_t) xdr_void; _xdr_result = (xdrproc_t) xdr_int; local = (bool_t (*) (char *, void *, struct svc_req *))rpc_loc_api_cb_null_0x00050002_svc; break; default: svcerr_noproc (transp); return; } memset ((char *)&argument, 0, sizeof (argument)); if (!svc_getargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) { svcerr_decode (transp); return; } retval = (bool_t) (*local)((char *)&argument, (void *)&result, rqstp); if (retval > 0 && !svc_sendreply(transp, (xdrproc_t) _xdr_result, (char *)&result)) { svcerr_systemerr (transp); } if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) { fprintf (stderr, "%s", "unable to free arguments"); exit (1); } if (!loc_apicbprog_0x00050002_freeresult (transp, _xdr_result, (caddr_t) &result)) fprintf (stderr, "%s", "unable to free results"); return; } void loc_apicbprog_0x00050003(struct svc_req *rqstp, register SVCXPRT *transp) { union { int fill; } argument; union { int rpc_loc_api_cb_null_0x00050003_res; } result; bool_t retval; xdrproc_t _xdr_argument, _xdr_result; bool_t (*local)(char *, void *, struct svc_req *); switch (rqstp->rq_proc) { case NULLPROC: (void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL); return; case rpc_loc_api_cb_null: _xdr_argument = (xdrproc_t) xdr_void; _xdr_result = (xdrproc_t) xdr_int; local = (bool_t (*) (char *, void *, struct svc_req *))rpc_loc_api_cb_null_0x00050003_svc; break; default: svcerr_noproc (transp); return; } memset ((char *)&argument, 0, sizeof (argument)); if (!svc_getargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) { svcerr_decode (transp); return; } retval = (bool_t) (*local)((char *)&argument, (void *)&result, rqstp); if (retval > 0 && !svc_sendreply(transp, (xdrproc_t) _xdr_result, (char *)&result)) { svcerr_systemerr (transp); } if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) { fprintf (stderr, "%s", "unable to free arguments"); exit (1); } if (!loc_apicbprog_0x00050003_freeresult (transp, _xdr_result, (caddr_t) &result)) fprintf (stderr, "%s", "unable to free results"); return; } void loc_apicbprog_0x00050004(struct svc_req *rqstp, register SVCXPRT *transp) { union { int fill; } argument; union { int rpc_loc_api_cb_null_0x00050004_res; } result; bool_t retval; xdrproc_t _xdr_argument, _xdr_result; bool_t (*local)(char *, void *, struct svc_req *); switch (rqstp->rq_proc) { case NULLPROC: (void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL); return; case rpc_loc_api_cb_null: _xdr_argument = (xdrproc_t) xdr_void; _xdr_result = (xdrproc_t) xdr_int; local = (bool_t (*) (char *, void *, struct svc_req *))rpc_loc_api_cb_null_0x00050004_svc; break; default: svcerr_noproc (transp); return; } memset ((char *)&argument, 0, sizeof (argument)); if (!svc_getargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) { svcerr_decode (transp); return; } retval = (bool_t) (*local)((char *)&argument, (void *)&result, rqstp); if (retval > 0 && !svc_sendreply(transp, (xdrproc_t) _xdr_result, (char *)&result)) { svcerr_systemerr (transp); } if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) { fprintf (stderr, "%s", "unable to free arguments"); exit (1); } if (!loc_apicbprog_0x00050004_freeresult (transp, _xdr_result, (caddr_t) &result)) fprintf (stderr, "%s", "unable to free results"); return; } void loc_apicbprog_0x00050005(struct svc_req *rqstp, register SVCXPRT *transp) { union { int fill; } argument; union { int rpc_loc_api_cb_null_0x00050005_res; } result; bool_t retval; xdrproc_t _xdr_argument, _xdr_result; bool_t (*local)(char *, void *, struct svc_req *); switch (rqstp->rq_proc) { case NULLPROC: (void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL); return; case rpc_loc_api_cb_null: _xdr_argument = (xdrproc_t) xdr_void; _xdr_result = (xdrproc_t) xdr_int; local = (bool_t (*) (char *, void *, struct svc_req *))rpc_loc_api_cb_null_0x00050005_svc; break; default: svcerr_noproc (transp); return; } memset ((char *)&argument, 0, sizeof (argument)); if (!svc_getargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) { svcerr_decode (transp); return; } retval = (bool_t) (*local)((char *)&argument, (void *)&result, rqstp); if (retval > 0 && !svc_sendreply(transp, (xdrproc_t) _xdr_result, (char *)&result)) { svcerr_systemerr (transp); } if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) { fprintf (stderr, "%s", "unable to free arguments"); exit (1); } if (!loc_apicbprog_0x00050005_freeresult (transp, _xdr_result, (caddr_t) &result)) fprintf (stderr, "%s", "unable to free results"); return; } void loc_apicbprog_0x00050006(struct svc_req *rqstp, register SVCXPRT *transp) { union { int fill; } argument; union { int rpc_loc_api_cb_null_0x00050006_res; } result; bool_t retval; xdrproc_t _xdr_argument, _xdr_result; bool_t (*local)(char *, void *, struct svc_req *); switch (rqstp->rq_proc) { case NULLPROC: (void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL); return; case rpc_loc_api_cb_null: _xdr_argument = (xdrproc_t) xdr_void; _xdr_result = (xdrproc_t) xdr_int; local = (bool_t (*) (char *, void *, struct svc_req *))rpc_loc_api_cb_null_0x00050006_svc; break; default: svcerr_noproc (transp); return; } memset ((char *)&argument, 0, sizeof (argument)); if (!svc_getargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) { svcerr_decode (transp); return; } retval = (bool_t) (*local)((char *)&argument, (void *)&result, rqstp); if (retval > 0 && !svc_sendreply(transp, (xdrproc_t) _xdr_result, (char *)&result)) { svcerr_systemerr (transp); } if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) { fprintf (stderr, "%s", "unable to free arguments"); exit (1); } if (!loc_apicbprog_0x00050006_freeresult (transp, _xdr_result, (caddr_t) &result)) fprintf (stderr, "%s", "unable to free results"); return; } ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/libloc_api-rpc-stub/src/loc_api_rpcgen_cb_xdr.c ================================================ /* Copyright (c) 2011, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /* * Please do not edit this file. * It was generated using rpcgen. */ #include "loc_api_rpcgen_cb_rpc.h" bool_t xdr_rpc_loc_event_cb_f_type_args (XDR *xdrs, rpc_loc_event_cb_f_type_args *objp) { ; if (!xdr_rpc_uint32 (xdrs, &objp->cb_id)) return FALSE; if (!xdr_rpc_loc_client_handle_type (xdrs, &objp->loc_handle)) return FALSE; if (!xdr_rpc_loc_event_mask_type (xdrs, &objp->loc_event)) return FALSE; if (!xdr_pointer (xdrs, (char **)&objp->loc_event_payload, sizeof (rpc_loc_event_payload_u_type), (xdrproc_t) xdr_rpc_loc_event_payload_u_type)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_event_cb_f_type_rets (XDR *xdrs, rpc_loc_event_cb_f_type_rets *objp) { ; if (!xdr_rpc_int32 (xdrs, &objp->loc_event_cb_f_type_result)) return FALSE; return TRUE; } ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/libloc_api-rpc-stub/src/loc_api_rpcgen_clnt.c ================================================ /* Copyright (c) 2011, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /* * Please do not edit this file. * It was generated using rpcgen. */ #include /* for memset */ #include "loc_api_rpcgen_rpc.h" /* Default timeout can be changed using clnt_control() */ static struct timeval TIMEOUT = { 25, 0 }; enum clnt_stat rpc_loc_api_null_0x00050001(void *argp, void *clnt_res, CLIENT *clnt) { return (clnt_call(clnt, rpc_loc_api_null, (xdrproc_t) xdr_void, (caddr_t) argp, (xdrproc_t) xdr_void, (caddr_t) clnt_res, TIMEOUT)); } enum clnt_stat rpc_loc_api_rpc_glue_code_info_remote_0x00050001(void *argp, rpc_loc_api_rpc_glue_code_info_remote_rets *clnt_res, CLIENT *clnt) { return (clnt_call(clnt, rpc_loc_api_rpc_glue_code_info_remote, (xdrproc_t) xdr_void, (caddr_t) argp, (xdrproc_t) xdr_rpc_loc_api_rpc_glue_code_info_remote_rets, (caddr_t) clnt_res, TIMEOUT)); } enum clnt_stat rpc_loc_open_0x00050001(rpc_loc_open_args *argp, rpc_loc_open_rets *clnt_res, CLIENT *clnt) { return (clnt_call(clnt, rpc_loc_open, (xdrproc_t) xdr_rpc_loc_open_args, (caddr_t) argp, (xdrproc_t) xdr_rpc_loc_open_rets, (caddr_t) clnt_res, TIMEOUT)); } enum clnt_stat rpc_loc_close_0x00050001(rpc_loc_close_args *argp, rpc_loc_close_rets *clnt_res, CLIENT *clnt) { return (clnt_call(clnt, rpc_loc_close, (xdrproc_t) xdr_rpc_loc_close_args, (caddr_t) argp, (xdrproc_t) xdr_rpc_loc_close_rets, (caddr_t) clnt_res, TIMEOUT)); } enum clnt_stat rpc_loc_start_fix_0x00050001(rpc_loc_start_fix_args *argp, rpc_loc_start_fix_rets *clnt_res, CLIENT *clnt) { return (clnt_call(clnt, rpc_loc_start_fix, (xdrproc_t) xdr_rpc_loc_start_fix_args, (caddr_t) argp, (xdrproc_t) xdr_rpc_loc_start_fix_rets, (caddr_t) clnt_res, TIMEOUT)); } enum clnt_stat rpc_loc_stop_fix_0x00050001(rpc_loc_stop_fix_args *argp, rpc_loc_stop_fix_rets *clnt_res, CLIENT *clnt) { return (clnt_call(clnt, rpc_loc_stop_fix, (xdrproc_t) xdr_rpc_loc_stop_fix_args, (caddr_t) argp, (xdrproc_t) xdr_rpc_loc_stop_fix_rets, (caddr_t) clnt_res, TIMEOUT)); } enum clnt_stat rpc_loc_ioctl_0x00050001(rpc_loc_ioctl_args *argp, rpc_loc_ioctl_rets *clnt_res, CLIENT *clnt) { return (clnt_call(clnt, rpc_loc_ioctl, (xdrproc_t) xdr_rpc_loc_ioctl_args, (caddr_t) argp, (xdrproc_t) xdr_rpc_loc_ioctl_rets, (caddr_t) clnt_res, TIMEOUT)); } enum clnt_stat rpc_loc_api_api_versions_0x00050001(void *argp, rpc_loc_api_api_versions_rets *clnt_res, CLIENT *clnt) { return (clnt_call(clnt, rpc_loc_api_api_versions, (xdrproc_t) xdr_void, (caddr_t) argp, (xdrproc_t) xdr_rpc_loc_api_api_versions_rets, (caddr_t) clnt_res, TIMEOUT)); } enum clnt_stat rpc_loc_api_null_0x00050002(void *argp, void *clnt_res, CLIENT *clnt) { return (clnt_call(clnt, rpc_loc_api_null, (xdrproc_t) xdr_void, (caddr_t) argp, (xdrproc_t) xdr_void, (caddr_t) clnt_res, TIMEOUT)); } enum clnt_stat rpc_loc_api_null_0x00050003(void *argp, void *clnt_res, CLIENT *clnt) { return (clnt_call(clnt, rpc_loc_api_null, (xdrproc_t) xdr_void, (caddr_t) argp, (xdrproc_t) xdr_void, (caddr_t) clnt_res, TIMEOUT)); } enum clnt_stat rpc_loc_api_null_0x00050004(void *argp, void *clnt_res, CLIENT *clnt) { return (clnt_call(clnt, rpc_loc_api_null, (xdrproc_t) xdr_void, (caddr_t) argp, (xdrproc_t) xdr_void, (caddr_t) clnt_res, TIMEOUT)); } enum clnt_stat rpc_loc_api_null_0x00050005(void *argp, void *clnt_res, CLIENT *clnt) { return (clnt_call(clnt, rpc_loc_api_null, (xdrproc_t) xdr_void, (caddr_t) argp, (xdrproc_t) xdr_void, (caddr_t) clnt_res, TIMEOUT)); } enum clnt_stat rpc_loc_api_null_0x00050006(void *argp, void *clnt_res, CLIENT *clnt) { return (clnt_call(clnt, rpc_loc_api_null, (xdrproc_t) xdr_void, (caddr_t) argp, (xdrproc_t) xdr_void, (caddr_t) clnt_res, TIMEOUT)); } ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/libloc_api-rpc-stub/src/loc_api_rpcgen_common_xdr.c ================================================ /* Copyright (c) 2011, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /* * Please do not edit this file. * It was generated using rpcgen. */ #include "loc_api_rpcgen_common_rpc.h" bool_t xdr_rpc_loc_client_handle_type (XDR *xdrs, rpc_loc_client_handle_type *objp) { register int32_t *buf; if (!xdr_rpc_int32 (xdrs, objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_event_mask_type (XDR *xdrs, rpc_loc_event_mask_type *objp) { register int32_t *buf; if (!xdr_rpc_uint64 (xdrs, objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_position_valid_mask_type (XDR *xdrs, rpc_loc_position_valid_mask_type *objp) { register int32_t *buf; if (!xdr_rpc_uint64 (xdrs, objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_pos_technology_mask_type (XDR *xdrs, rpc_loc_pos_technology_mask_type *objp) { register int32_t *buf; if (!xdr_rpc_uint32 (xdrs, objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_session_status_e_type (XDR *xdrs, rpc_loc_session_status_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_calendar_time_s_type (XDR *xdrs, rpc_loc_calendar_time_s_type *objp) { register int32_t *buf; if (!xdr_rpc_uint16 (xdrs, &objp->year)) return FALSE; if (!xdr_u_char (xdrs, &objp->month)) return FALSE; if (!xdr_u_char (xdrs, &objp->day_of_week)) return FALSE; if (!xdr_u_char (xdrs, &objp->day)) return FALSE; if (!xdr_u_char (xdrs, &objp->hour)) return FALSE; if (!xdr_u_char (xdrs, &objp->minute)) return FALSE; if (!xdr_u_char (xdrs, &objp->second)) return FALSE; if (!xdr_rpc_uint16 (xdrs, &objp->millisecond)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_parsed_position_s_type (XDR *xdrs, rpc_loc_parsed_position_s_type *objp) { register int32_t *buf; if (!xdr_rpc_loc_position_valid_mask_type (xdrs, &objp->valid_mask)) return FALSE; if (!xdr_rpc_loc_session_status_e_type (xdrs, &objp->session_status)) return FALSE; if (!xdr_rpc_loc_calendar_time_s_type (xdrs, &objp->timestamp_calendar)) return FALSE; if (!xdr_rpc_uint64 (xdrs, &objp->timestamp_utc)) return FALSE; if (!xdr_rpc_uint8 (xdrs, &objp->leap_seconds)) return FALSE; if (!xdr_float (xdrs, &objp->time_unc)) return FALSE; if (!xdr_double (xdrs, &objp->latitude)) return FALSE; if (!xdr_double (xdrs, &objp->longitude)) return FALSE; if (!xdr_float (xdrs, &objp->altitude_wrt_ellipsoid)) return FALSE; if (!xdr_float (xdrs, &objp->altitude_wrt_mean_sea_level)) return FALSE; if (!xdr_float (xdrs, &objp->speed_horizontal)) return FALSE; if (!xdr_float (xdrs, &objp->speed_vertical)) return FALSE; if (!xdr_float (xdrs, &objp->heading)) return FALSE; if (!xdr_float (xdrs, &objp->hor_unc_circular)) return FALSE; if (!xdr_float (xdrs, &objp->hor_unc_ellipse_semi_major)) return FALSE; if (!xdr_float (xdrs, &objp->hor_unc_ellipse_semi_minor)) return FALSE; if (!xdr_float (xdrs, &objp->hor_unc_ellipse_orient_azimuth)) return FALSE; if (!xdr_float (xdrs, &objp->vert_unc)) return FALSE; if (!xdr_float (xdrs, &objp->speed_unc)) return FALSE; if (!xdr_float (xdrs, &objp->heading_unc)) return FALSE; if (!xdr_u_char (xdrs, &objp->confidence_horizontal)) return FALSE; if (!xdr_u_char (xdrs, &objp->confidence_vertical)) return FALSE; if (!xdr_float (xdrs, &objp->magnetic_deviation)) return FALSE; if (!xdr_rpc_loc_pos_technology_mask_type (xdrs, &objp->technology_mask)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_sv_system_e_type (XDR *xdrs, rpc_loc_sv_system_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_sv_status_e_type (XDR *xdrs, rpc_loc_sv_status_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_sv_info_valid_mask_type (XDR *xdrs, rpc_loc_sv_info_valid_mask_type *objp) { register int32_t *buf; if (!xdr_rpc_uint32 (xdrs, objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_sv_info_s_type (XDR *xdrs, rpc_loc_sv_info_s_type *objp) { register int32_t *buf; if (!xdr_rpc_loc_sv_info_valid_mask_type (xdrs, &objp->valid_mask)) return FALSE; if (!xdr_rpc_loc_sv_system_e_type (xdrs, &objp->system)) return FALSE; if (!xdr_rpc_uint8 (xdrs, &objp->prn)) return FALSE; if (!xdr_rpc_uint8 (xdrs, &objp->health_status)) return FALSE; if (!xdr_rpc_loc_sv_status_e_type (xdrs, &objp->process_status)) return FALSE; if (!xdr_rpc_boolean (xdrs, &objp->has_eph)) return FALSE; if (!xdr_rpc_boolean (xdrs, &objp->has_alm)) return FALSE; if (!xdr_float (xdrs, &objp->elevation)) return FALSE; if (!xdr_float (xdrs, &objp->azimuth)) return FALSE; if (!xdr_float (xdrs, &objp->snr)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_gnss_info_valid_mask_type (XDR *xdrs, rpc_loc_gnss_info_valid_mask_type *objp) { register int32_t *buf; if (!xdr_rpc_uint32 (xdrs, objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_gnss_info_s_type (XDR *xdrs, rpc_loc_gnss_info_s_type *objp) { register int32_t *buf; if (!xdr_rpc_loc_gnss_info_valid_mask_type (xdrs, &objp->valid_mask)) return FALSE; if (!xdr_float (xdrs, &objp->position_dop)) return FALSE; if (!xdr_float (xdrs, &objp->horizontal_dop)) return FALSE; if (!xdr_float (xdrs, &objp->vertical_dop)) return FALSE; if (!xdr_rpc_boolean (xdrs, &objp->altitude_assumed)) return FALSE; if (!xdr_rpc_uint16 (xdrs, &objp->sv_count)) return FALSE; if (!xdr_array (xdrs, (char **)&objp->sv_list.sv_list_val, (u_int *) &objp->sv_list.sv_list_len, 80, sizeof (rpc_loc_sv_info_s_type), (xdrproc_t) xdr_rpc_loc_sv_info_s_type)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_nmea_report_s_type (XDR *xdrs, rpc_loc_nmea_report_s_type *objp) { register int32_t *buf; int i; if (!xdr_rpc_uint16 (xdrs, &objp->length)) return FALSE; if (!xdr_opaque (xdrs, objp->nmea_sentences, 200)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_status_event_e_type (XDR *xdrs, rpc_loc_status_event_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_engine_state_e_type (XDR *xdrs, rpc_loc_engine_state_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_fix_session_state_e_type (XDR *xdrs, rpc_loc_fix_session_state_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_status_event_payload_u_type (XDR *xdrs, rpc_loc_status_event_payload_u_type *objp) { register int32_t *buf; if (!xdr_rpc_loc_status_event_e_type (xdrs, &objp->disc)) return FALSE; switch (objp->disc) { case RPC_LOC_STATUS_EVENT_ENGINE_STATE: if (!xdr_rpc_loc_engine_state_e_type (xdrs, &objp->rpc_loc_status_event_payload_u_type_u.engine_state)) return FALSE; break; case RPC_LOC_STATUS_EVENT_FIX_SESSION_STATE: if (!xdr_rpc_loc_fix_session_state_e_type (xdrs, &objp->rpc_loc_status_event_payload_u_type_u.fix_session_state)) return FALSE; break; default: break; } return TRUE; } bool_t xdr_rpc_loc_status_event_s_type (XDR *xdrs, rpc_loc_status_event_s_type *objp) { register int32_t *buf; if (!xdr_rpc_loc_status_event_e_type (xdrs, &objp->event)) return FALSE; if (!xdr_rpc_loc_status_event_payload_u_type (xdrs, &objp->payload)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_server_addr_e_type (XDR *xdrs, rpc_loc_server_addr_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_server_addr_ipv4_type (XDR *xdrs, rpc_loc_server_addr_ipv4_type *objp) { register int32_t *buf; if (!xdr_rpc_uint32 (xdrs, &objp->addr)) return FALSE; if (!xdr_rpc_uint16 (xdrs, &objp->port)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_server_addr_url_type (XDR *xdrs, rpc_loc_server_addr_url_type *objp) { register int32_t *buf; int i; if (!xdr_rpc_uint16 (xdrs, &objp->length)) return FALSE; if (!xdr_opaque (xdrs, objp->addr, 256)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_server_addr_ipv6_type (XDR *xdrs, rpc_loc_server_addr_ipv6_type *objp) { register int32_t *buf; int i; if (!xdr_vector (xdrs, (char *)objp->addr, 8, sizeof (rpc_uint16), (xdrproc_t) xdr_rpc_uint16)) return FALSE; if (!xdr_rpc_uint32 (xdrs, &objp->port)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_server_addr_u_type (XDR *xdrs, rpc_loc_server_addr_u_type *objp) { register int32_t *buf; if (!xdr_rpc_loc_server_addr_e_type (xdrs, &objp->disc)) return FALSE; switch (objp->disc) { case RPC_LOC_SERVER_ADDR_IPV4: if (!xdr_rpc_loc_server_addr_ipv4_type (xdrs, &objp->rpc_loc_server_addr_u_type_u.ipv4)) return FALSE; break; case RPC_LOC_SERVER_ADDR_URL: if (!xdr_rpc_loc_server_addr_url_type (xdrs, &objp->rpc_loc_server_addr_u_type_u.url)) return FALSE; break; case RPC_LOC_SERVER_ADDR_IPV6: if (!xdr_rpc_loc_server_addr_ipv6_type (xdrs, &objp->rpc_loc_server_addr_u_type_u.ipv6)) return FALSE; break; default: break; } return TRUE; } bool_t xdr_rpc_loc_server_info_s_type (XDR *xdrs, rpc_loc_server_info_s_type *objp) { register int32_t *buf; if (!xdr_rpc_loc_server_addr_e_type (xdrs, &objp->addr_type)) return FALSE; if (!xdr_rpc_loc_server_addr_u_type (xdrs, &objp->addr_info)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_ni_notify_verify_e_type (XDR *xdrs, rpc_loc_ni_notify_verify_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_ni_event_e_type (XDR *xdrs, rpc_loc_ni_event_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_ni_datacoding_scheme_e_type (XDR *xdrs, rpc_loc_ni_datacoding_scheme_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_ni_vx_requester_id_encoding_scheme_e_type (XDR *xdrs, rpc_loc_ni_vx_requester_id_encoding_scheme_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_ni_vx_pos_mode_e_type (XDR *xdrs, rpc_loc_ni_vx_pos_mode_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_ni_vx_requester_id_s_type (XDR *xdrs, rpc_loc_ni_vx_requester_id_s_type *objp) { register int32_t *buf; int i; if (!xdr_u_char (xdrs, &objp->requester_id_length)) return FALSE; if (!xdr_opaque (xdrs, objp->requester_id, 200)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_ni_vx_notify_verify_req_s_type (XDR *xdrs, rpc_loc_ni_vx_notify_verify_req_s_type *objp) { register int32_t *buf; if (!xdr_rpc_loc_ni_notify_verify_e_type (xdrs, &objp->notification_priv_type)) return FALSE; if (!xdr_u_char (xdrs, &objp->pos_qos_incl)) return FALSE; if (!xdr_u_char (xdrs, &objp->pos_qos)) return FALSE; if (!xdr_rpc_uint32 (xdrs, &objp->num_fixes)) return FALSE; if (!xdr_rpc_uint32 (xdrs, &objp->tbf)) return FALSE; if (!xdr_rpc_loc_ni_vx_pos_mode_e_type (xdrs, &objp->pos_mode)) return FALSE; if (!xdr_rpc_loc_ni_vx_requester_id_encoding_scheme_e_type (xdrs, &objp->encoding_scheme)) return FALSE; if (!xdr_rpc_loc_ni_vx_requester_id_s_type (xdrs, &objp->requester_id)) return FALSE; if (!xdr_rpc_uint16 (xdrs, &objp->user_resp_timer_val)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_ni_supl_pos_method_e_type (XDR *xdrs, rpc_loc_ni_supl_pos_method_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_ni_supl_slp_session_id_s_type (XDR *xdrs, rpc_loc_ni_supl_slp_session_id_s_type *objp) { register int32_t *buf; int i; if (!xdr_u_char (xdrs, &objp->presence)) return FALSE; if (!xdr_opaque (xdrs, objp->session_id, 4)) return FALSE; if (!xdr_rpc_loc_server_info_s_type (xdrs, &objp->slp_address)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_ni_requestor_id_s_type (XDR *xdrs, rpc_loc_ni_requestor_id_s_type *objp) { register int32_t *buf; int i; if (!xdr_u_char (xdrs, &objp->data_coding_scheme)) return FALSE; if (!xdr_opaque (xdrs, objp->requestor_id_string, 200)) return FALSE; if (!xdr_u_char (xdrs, &objp->string_len)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_ni_supl_client_name_s_type (XDR *xdrs, rpc_loc_ni_supl_client_name_s_type *objp) { register int32_t *buf; int i; if (!xdr_u_char (xdrs, &objp->data_coding_scheme)) return FALSE; if (!xdr_opaque (xdrs, objp->client_name_string, 64)) return FALSE; if (!xdr_u_char (xdrs, &objp->string_len)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_ni_supl_qop_s_type (XDR *xdrs, rpc_loc_ni_supl_qop_s_type *objp) { register int32_t *buf; if (!xdr_u_char (xdrs, &objp->bit_mask)) return FALSE; if (!xdr_u_char (xdrs, &objp->horacc)) return FALSE; if (!xdr_u_char (xdrs, &objp->veracc)) return FALSE; if (!xdr_rpc_uint16 (xdrs, &objp->maxLocAge)) return FALSE; if (!xdr_u_char (xdrs, &objp->delay)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_ni_supl_notify_verify_req_s_type (XDR *xdrs, rpc_loc_ni_supl_notify_verify_req_s_type *objp) { register int32_t *buf; int i; if (!xdr_rpc_loc_ni_notify_verify_e_type (xdrs, &objp->notification_priv_type)) return FALSE; if (!xdr_rpc_uint16 (xdrs, &objp->flags)) return FALSE; if (!xdr_rpc_loc_ni_supl_slp_session_id_s_type (xdrs, &objp->supl_slp_session_id)) return FALSE; if (!xdr_opaque (xdrs, objp->supl_hash, 8)) return FALSE; if (!xdr_rpc_loc_ni_datacoding_scheme_e_type (xdrs, &objp->datacoding_scheme)) return FALSE; if (!xdr_rpc_loc_ni_supl_pos_method_e_type (xdrs, &objp->pos_method)) return FALSE; if (!xdr_rpc_loc_ni_requestor_id_s_type (xdrs, &objp->requestor_id)) return FALSE; if (!xdr_rpc_loc_ni_supl_client_name_s_type (xdrs, &objp->client_name)) return FALSE; if (!xdr_rpc_loc_ni_supl_qop_s_type (xdrs, &objp->supl_qop)) return FALSE; if (!xdr_rpc_uint16 (xdrs, &objp->user_response_timer)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_ni_ext_client_address_s_type (XDR *xdrs, rpc_loc_ni_ext_client_address_s_type *objp) { register int32_t *buf; int i; if (!xdr_u_char (xdrs, &objp->ext_client_address_len)) return FALSE; if (!xdr_opaque (xdrs, objp->ext_client_address, 20)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_ni_location_type_e_type (XDR *xdrs, rpc_loc_ni_location_type_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_ni_deferred_location_s_type (XDR *xdrs, rpc_loc_ni_deferred_location_s_type *objp) { register int32_t *buf; if (!xdr_u_char (xdrs, &objp->unused_bits)) return FALSE; if (!xdr_u_char (xdrs, &objp->ms_available)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_ni_codeword_string_s_type (XDR *xdrs, rpc_loc_ni_codeword_string_s_type *objp) { register int32_t *buf; int i; if (!xdr_u_char (xdrs, &objp->data_coding_scheme)) return FALSE; if (!xdr_opaque (xdrs, objp->lcs_codeword_string, 20)) return FALSE; if (!xdr_u_char (xdrs, &objp->string_len)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_ni_service_type_id_s_type (XDR *xdrs, rpc_loc_ni_service_type_id_s_type *objp) { register int32_t *buf; if (!xdr_u_char (xdrs, &objp->lcs_service_type_id)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_ni_umts_cp_notify_verify_req_s_type (XDR *xdrs, rpc_loc_ni_umts_cp_notify_verify_req_s_type *objp) { register int32_t *buf; int i; if (!xdr_rpc_loc_ni_notify_verify_e_type (xdrs, &objp->notification_priv_type)) return FALSE; if (!xdr_u_char (xdrs, &objp->invoke_id)) return FALSE; if (!xdr_rpc_uint16 (xdrs, &objp->flags)) return FALSE; if (!xdr_u_char (xdrs, &objp->notification_length)) return FALSE; if (!xdr_opaque (xdrs, objp->notification_text, 64)) return FALSE; if (!xdr_rpc_loc_ni_datacoding_scheme_e_type (xdrs, &objp->datacoding_scheme)) return FALSE; if (!xdr_rpc_loc_ni_ext_client_address_s_type (xdrs, &objp->ext_client_address_data)) return FALSE; if (!xdr_rpc_loc_ni_location_type_e_type (xdrs, &objp->location_type)) return FALSE; if (!xdr_rpc_loc_ni_deferred_location_s_type (xdrs, &objp->deferred_location)) return FALSE; if (!xdr_rpc_loc_ni_requestor_id_s_type (xdrs, &objp->requestor_id)) return FALSE; if (!xdr_rpc_loc_ni_codeword_string_s_type (xdrs, &objp->codeword_string)) return FALSE; if (!xdr_rpc_loc_ni_service_type_id_s_type (xdrs, &objp->service_type_id)) return FALSE; if (!xdr_rpc_uint16 (xdrs, &objp->user_response_timer)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_ni_service_interaction_e_type (XDR *xdrs, rpc_loc_ni_service_interaction_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_ni_vx_service_interaction_req_s_type (XDR *xdrs, rpc_loc_ni_vx_service_interaction_req_s_type *objp) { register int32_t *buf; if (!xdr_rpc_loc_ni_vx_notify_verify_req_s_type (xdrs, &objp->ni_vx_req)) return FALSE; if (!xdr_rpc_loc_ni_service_interaction_e_type (xdrs, &objp->service_interation_type)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_ni_event_payload_u_type (XDR *xdrs, rpc_loc_ni_event_payload_u_type *objp) { register int32_t *buf; if (!xdr_rpc_loc_ni_event_e_type (xdrs, &objp->disc)) return FALSE; switch (objp->disc) { case RPC_LOC_NI_EVENT_VX_NOTIFY_VERIFY_REQ: if (!xdr_rpc_loc_ni_vx_notify_verify_req_s_type (xdrs, &objp->rpc_loc_ni_event_payload_u_type_u.vx_req)) return FALSE; break; case RPC_LOC_NI_EVENT_SUPL_NOTIFY_VERIFY_REQ: if (!xdr_rpc_loc_ni_supl_notify_verify_req_s_type (xdrs, &objp->rpc_loc_ni_event_payload_u_type_u.supl_req)) return FALSE; break; case RPC_LOC_NI_EVENT_UMTS_CP_NOTIFY_VERIFY_REQ: if (!xdr_rpc_loc_ni_umts_cp_notify_verify_req_s_type (xdrs, &objp->rpc_loc_ni_event_payload_u_type_u.umts_cp_req)) return FALSE; break; case RPC_LOC_NI_EVENT_VX_SERVICE_INTERACTION_REQ: if (!xdr_rpc_loc_ni_vx_service_interaction_req_s_type (xdrs, &objp->rpc_loc_ni_event_payload_u_type_u.service_interaction_req)) return FALSE; break; default: break; } return TRUE; } bool_t xdr_rpc_loc_ni_event_s_type (XDR *xdrs, rpc_loc_ni_event_s_type *objp) { register int32_t *buf; if (!xdr_rpc_loc_ni_event_e_type (xdrs, &objp->event)) return FALSE; if (!xdr_rpc_loc_ni_event_payload_u_type (xdrs, &objp->payload)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_assist_data_request_e_type (XDR *xdrs, rpc_loc_assist_data_request_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_struct_loc_time_download_source_s_type_servers_ptr (XDR *xdrs, rpc_struct_loc_time_download_source_s_type_servers_ptr *objp) { register int32_t *buf; if (!xdr_string (xdrs, objp, 256)) return FALSE; return TRUE; } bool_t xdr_rpc_struct_loc_time_download_source_s_type_servers (XDR *xdrs, rpc_struct_loc_time_download_source_s_type_servers objp) { register int32_t *buf; if (!xdr_vector (xdrs, (char *)objp, 3, sizeof (rpc_struct_loc_time_download_source_s_type_servers_ptr), (xdrproc_t) xdr_rpc_struct_loc_time_download_source_s_type_servers_ptr)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_time_download_source_s_type (XDR *xdrs, rpc_loc_time_download_source_s_type *objp) { register int32_t *buf; if (!xdr_rpc_uint32 (xdrs, &objp->delay_threshold)) return FALSE; if (!xdr_rpc_struct_loc_time_download_source_s_type_servers (xdrs, objp->servers)) return FALSE; return TRUE; } bool_t xdr_rpc_struct_loc_predicted_orbits_data_source_s_type_servers_ptr (XDR *xdrs, rpc_struct_loc_predicted_orbits_data_source_s_type_servers_ptr *objp) { register int32_t *buf; if (!xdr_string (xdrs, objp, 256)) return FALSE; return TRUE; } bool_t xdr_rpc_struct_loc_predicted_orbits_data_source_s_type_servers (XDR *xdrs, rpc_struct_loc_predicted_orbits_data_source_s_type_servers objp) { register int32_t *buf; if (!xdr_vector (xdrs, (char *)objp, 3, sizeof (rpc_struct_loc_predicted_orbits_data_source_s_type_servers_ptr), (xdrproc_t) xdr_rpc_struct_loc_predicted_orbits_data_source_s_type_servers_ptr)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_predicted_orbits_data_source_s_type (XDR *xdrs, rpc_loc_predicted_orbits_data_source_s_type *objp) { register int32_t *buf; if (!xdr_rpc_uint32 (xdrs, &objp->max_file_size)) return FALSE; if (!xdr_rpc_uint32 (xdrs, &objp->max_part_size)) return FALSE; if (!xdr_rpc_struct_loc_predicted_orbits_data_source_s_type_servers (xdrs, objp->servers)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_pos_inj_request_s_type (XDR *xdrs, rpc_loc_pos_inj_request_s_type *objp) { register int32_t *buf; if (!xdr_rpc_uint32 (xdrs, &objp->flags)) return FALSE; if (!xdr_double (xdrs, &objp->latitude)) return FALSE; if (!xdr_double (xdrs, &objp->longitude)) return FALSE; if (!xdr_rpc_uint32 (xdrs, &objp->position_uncertainty)) return FALSE; if (!xdr_rpc_uint64 (xdrs, &objp->timestamp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_assist_data_request_payload_u_type (XDR *xdrs, rpc_loc_assist_data_request_payload_u_type *objp) { register int32_t *buf; if (!xdr_rpc_loc_assist_data_request_e_type (xdrs, &objp->disc)) return FALSE; switch (objp->disc) { case RPC_LOC_ASSIST_DATA_TIME_REQ: if (!xdr_rpc_loc_time_download_source_s_type (xdrs, &objp->rpc_loc_assist_data_request_payload_u_type_u.time_download)) return FALSE; break; case RPC_LOC_ASSIST_DATA_PREDICTED_ORBITS_REQ: if (!xdr_rpc_loc_predicted_orbits_data_source_s_type (xdrs, &objp->rpc_loc_assist_data_request_payload_u_type_u.data_download)) return FALSE; break; case RPC_LOC_ASSIST_DATA_POSITION_INJECTION_REQ: if (!xdr_rpc_loc_pos_inj_request_s_type (xdrs, &objp->rpc_loc_assist_data_request_payload_u_type_u.pos_injection)) return FALSE; break; default: break; } return TRUE; } bool_t xdr_rpc_loc_assist_data_request_s_type (XDR *xdrs, rpc_loc_assist_data_request_s_type *objp) { register int32_t *buf; if (!xdr_rpc_loc_assist_data_request_e_type (xdrs, &objp->event)) return FALSE; if (!xdr_rpc_loc_assist_data_request_payload_u_type (xdrs, &objp->payload)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_server_connection_handle (XDR *xdrs, rpc_loc_server_connection_handle *objp) { register int32_t *buf; if (!xdr_rpc_uint32 (xdrs, objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_server_protocol_e_type (XDR *xdrs, rpc_loc_server_protocol_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_server_connection_e_type (XDR *xdrs, rpc_loc_server_connection_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_server_request_e_type (XDR *xdrs, rpc_loc_server_request_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_server_open_req_s_type (XDR *xdrs, rpc_loc_server_open_req_s_type *objp) { register int32_t *buf; if (!xdr_rpc_loc_server_connection_handle (xdrs, &objp->conn_handle)) return FALSE; if (!xdr_rpc_loc_server_protocol_e_type (xdrs, &objp->protocol)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_server_multi_open_req_s_type (XDR *xdrs, rpc_loc_server_multi_open_req_s_type *objp) { register int32_t *buf; if (!xdr_rpc_loc_server_connection_handle (xdrs, &objp->conn_handle)) return FALSE; if (!xdr_rpc_loc_server_protocol_e_type (xdrs, &objp->protocol)) return FALSE; if (!xdr_rpc_loc_server_connection_e_type (xdrs, &objp->connection_type)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_server_close_req_s_type (XDR *xdrs, rpc_loc_server_close_req_s_type *objp) { register int32_t *buf; if (!xdr_rpc_loc_server_connection_handle (xdrs, &objp->conn_handle)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_server_request_u_type (XDR *xdrs, rpc_loc_server_request_u_type *objp) { register int32_t *buf; if (!xdr_rpc_loc_server_request_e_type (xdrs, &objp->disc)) return FALSE; switch (objp->disc) { case RPC_LOC_SERVER_REQUEST_OPEN: if (!xdr_rpc_loc_server_open_req_s_type (xdrs, &objp->rpc_loc_server_request_u_type_u.open_req)) return FALSE; break; case RPC_LOC_SERVER_REQUEST_CLOSE: if (!xdr_rpc_loc_server_close_req_s_type (xdrs, &objp->rpc_loc_server_request_u_type_u.close_req)) return FALSE; break; case RPC_LOC_SERVER_REQUEST_MULTI_OPEN: if (!xdr_rpc_loc_server_multi_open_req_s_type (xdrs, &objp->rpc_loc_server_request_u_type_u.multi_open_req)) return FALSE; break; default: break; } return TRUE; } bool_t xdr_rpc_loc_server_request_s_type (XDR *xdrs, rpc_loc_server_request_s_type *objp) { register int32_t *buf; if (!xdr_rpc_loc_server_request_e_type (xdrs, &objp->event)) return FALSE; if (!xdr_rpc_loc_server_request_u_type (xdrs, &objp->payload)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_qwip_request_e_type (XDR *xdrs, rpc_loc_qwip_request_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_qwip_request_s_type (XDR *xdrs, rpc_loc_qwip_request_s_type *objp) { register int32_t *buf; if (!xdr_rpc_loc_qwip_request_e_type (xdrs, &objp->request_type)) return FALSE; if (!xdr_rpc_uint16 (xdrs, &objp->tbf_ms)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_reserved_payload_s_type (XDR *xdrs, rpc_loc_reserved_payload_s_type *objp) { register int32_t *buf; if (!xdr_rpc_uint16 (xdrs, &objp->data_size)) return FALSE; if (!xdr_bytes (xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, ~0)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_ioctl_e_type (XDR *xdrs, rpc_loc_ioctl_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_api_version_s_type (XDR *xdrs, rpc_loc_api_version_s_type *objp) { register int32_t *buf; if (!xdr_u_char (xdrs, &objp->major)) return FALSE; if (!xdr_u_char (xdrs, &objp->minor)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_fix_recurrence_e_type (XDR *xdrs, rpc_loc_fix_recurrence_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_operation_mode_e_type (XDR *xdrs, rpc_loc_operation_mode_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_notify_e_type (XDR *xdrs, rpc_loc_notify_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_fix_criteria_s_type (XDR *xdrs, rpc_loc_fix_criteria_s_type *objp) { register int32_t *buf; if (!xdr_rpc_uint32 (xdrs, &objp->valid_mask)) return FALSE; if (!xdr_rpc_loc_fix_recurrence_e_type (xdrs, &objp->recurrence_type)) return FALSE; if (!xdr_rpc_loc_operation_mode_e_type (xdrs, &objp->preferred_operation_mode)) return FALSE; if (!xdr_rpc_uint32 (xdrs, &objp->preferred_accuracy)) return FALSE; if (!xdr_rpc_uint32 (xdrs, &objp->preferred_response_time)) return FALSE; if (!xdr_rpc_boolean (xdrs, &objp->intermediate_pos_report_enabled)) return FALSE; if (!xdr_rpc_loc_notify_e_type (xdrs, &objp->notify_type)) return FALSE; if (!xdr_rpc_uint32 (xdrs, &objp->min_interval)) return FALSE; if (!xdr_float (xdrs, &objp->min_distance)) return FALSE; if (!xdr_rpc_uint32 (xdrs, &objp->min_dist_sample_interval)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_ni_user_resp_e_type (XDR *xdrs, rpc_loc_ni_user_resp_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_user_verify_s_type (XDR *xdrs, rpc_loc_user_verify_s_type *objp) { register int32_t *buf; if (!xdr_rpc_loc_ni_user_resp_e_type (xdrs, &objp->user_resp)) return FALSE; if (!xdr_rpc_loc_ni_event_s_type (xdrs, &objp->ni_event_pass_back)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_predicted_orbits_data_format_e_type (XDR *xdrs, rpc_loc_predicted_orbits_data_format_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_predicted_orbits_data_s_type (XDR *xdrs, rpc_loc_predicted_orbits_data_s_type *objp) { register int32_t *buf; if (!xdr_rpc_loc_predicted_orbits_data_format_e_type (xdrs, &objp->format_type)) return FALSE; if (!xdr_rpc_uint32 (xdrs, &objp->total_size)) return FALSE; if (!xdr_rpc_uint8 (xdrs, &objp->total_parts)) return FALSE; if (!xdr_rpc_uint8 (xdrs, &objp->part)) return FALSE; if (!xdr_rpc_uint16 (xdrs, &objp->part_len)) return FALSE; if (!xdr_bytes (xdrs, (char **)&objp->data_ptr.data_ptr_val, (u_int *) &objp->data_ptr.data_ptr_len, ~0)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_predicted_orbits_data_validity_report_s_type (XDR *xdrs, rpc_loc_predicted_orbits_data_validity_report_s_type *objp) { register int32_t *buf; if (!xdr_rpc_uint64 (xdrs, &objp->start_time_utc)) return FALSE; if (!xdr_rpc_uint16 (xdrs, &objp->valid_duration_hrs)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_predicted_orbits_auto_download_config_s_type (XDR *xdrs, rpc_loc_predicted_orbits_auto_download_config_s_type *objp) { register int32_t *buf; if (!xdr_rpc_boolean (xdrs, &objp->enable)) return FALSE; if (!xdr_u_char (xdrs, &objp->auto_check_every_hrs)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_assist_data_time_s_type (XDR *xdrs, rpc_loc_assist_data_time_s_type *objp) { register int32_t *buf; if (!xdr_rpc_uint64 (xdrs, &objp->time_utc)) return FALSE; if (!xdr_rpc_uint32 (xdrs, &objp->uncertainty)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_assist_pos_valid_mask_type (XDR *xdrs, rpc_loc_assist_pos_valid_mask_type *objp) { register int32_t *buf; if (!xdr_rpc_uint64 (xdrs, objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_assist_data_pos_s_type (XDR *xdrs, rpc_loc_assist_data_pos_s_type *objp) { register int32_t *buf; if (!xdr_rpc_loc_assist_pos_valid_mask_type (xdrs, &objp->valid_mask)) return FALSE; if (!xdr_rpc_uint64 (xdrs, &objp->timestamp_utc)) return FALSE; if (!xdr_double (xdrs, &objp->latitude)) return FALSE; if (!xdr_double (xdrs, &objp->longitude)) return FALSE; if (!xdr_float (xdrs, &objp->altitude_wrt_ellipsoid)) return FALSE; if (!xdr_float (xdrs, &objp->altitude_wrt_mean_sea_level)) return FALSE; if (!xdr_float (xdrs, &objp->hor_unc_circular)) return FALSE; if (!xdr_float (xdrs, &objp->vert_unc)) return FALSE; if (!xdr_u_char (xdrs, &objp->confidence_horizontal)) return FALSE; if (!xdr_u_char (xdrs, &objp->confidence_vertical)) return FALSE; if (!xdr_rpc_int32 (xdrs, &objp->timestamp_age)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_server_open_status_e_type (XDR *xdrs, rpc_loc_server_open_status_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_server_pdp_type_e_type (XDR *xdrs, rpc_loc_server_pdp_type_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_server_open_status_s_type (XDR *xdrs, rpc_loc_server_open_status_s_type *objp) { register int32_t *buf; int i; if (!xdr_rpc_loc_server_connection_handle (xdrs, &objp->conn_handle)) return FALSE; if (!xdr_rpc_loc_server_open_status_e_type (xdrs, &objp->open_status)) return FALSE; if (!xdr_opaque (xdrs, objp->apn_name, 100)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_server_multi_open_status_s_type (XDR *xdrs, rpc_loc_server_multi_open_status_s_type *objp) { register int32_t *buf; int i; if (!xdr_rpc_loc_server_connection_handle (xdrs, &objp->conn_handle)) return FALSE; if (!xdr_rpc_loc_server_open_status_e_type (xdrs, &objp->open_status)) return FALSE; if (!xdr_rpc_loc_server_pdp_type_e_type (xdrs, &objp->pdp_type)) return FALSE; if (!xdr_opaque (xdrs, objp->apn_name, 100)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_server_close_status_e_type (XDR *xdrs, rpc_loc_server_close_status_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_server_close_status_s_type (XDR *xdrs, rpc_loc_server_close_status_s_type *objp) { register int32_t *buf; if (!xdr_rpc_loc_server_connection_handle (xdrs, &objp->conn_handle)) return FALSE; if (!xdr_rpc_loc_server_close_status_e_type (xdrs, &objp->close_status)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_wiper_fix_time_s_type (XDR *xdrs, rpc_loc_wiper_fix_time_s_type *objp) { register int32_t *buf; if (!xdr_rpc_uint32 (xdrs, &objp->slow_clock_count)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_wiper_fix_pos_s_type (XDR *xdrs, rpc_loc_wiper_fix_pos_s_type *objp) { register int32_t *buf; if (!xdr_rpc_int32 (xdrs, &objp->lat)) return FALSE; if (!xdr_rpc_int32 (xdrs, &objp->lon)) return FALSE; if (!xdr_rpc_uint16 (xdrs, &objp->HEPE)) return FALSE; if (!xdr_rpc_uint8 (xdrs, &objp->num_of_aps_used)) return FALSE; if (!xdr_rpc_uint8 (xdrs, &objp->fix_error_code)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_wiper_ap_info_s_type (XDR *xdrs, rpc_loc_wiper_ap_info_s_type *objp) { register int32_t *buf; int i; if (!xdr_opaque (xdrs, objp->mac_addr, 6)) return FALSE; if (!xdr_rpc_int32 (xdrs, &objp->rssi)) return FALSE; if (!xdr_rpc_uint16 (xdrs, &objp->channel)) return FALSE; if (!xdr_rpc_uint8 (xdrs, &objp->ap_qualifier)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_wiper_ap_set_s_type (XDR *xdrs, rpc_loc_wiper_ap_set_s_type *objp) { register int32_t *buf; int i; if (!xdr_rpc_uint8 (xdrs, &objp->num_of_aps)) return FALSE; if (!xdr_vector (xdrs, (char *)objp->ap_info, 50, sizeof (rpc_loc_wiper_ap_info_s_type), (xdrproc_t) xdr_rpc_loc_wiper_ap_info_s_type)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_wiper_position_report_s_type (XDR *xdrs, rpc_loc_wiper_position_report_s_type *objp) { register int32_t *buf; if (!xdr_rpc_uint8 (xdrs, &objp->wiper_valid_info_flag)) return FALSE; if (!xdr_rpc_loc_wiper_fix_time_s_type (xdrs, &objp->wiper_fix_time)) return FALSE; if (!xdr_rpc_loc_wiper_fix_pos_s_type (xdrs, &objp->wiper_fix_position)) return FALSE; if (!xdr_rpc_loc_wiper_ap_set_s_type (xdrs, &objp->wiper_ap_set)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_wiper_status_e_type (XDR *xdrs, rpc_loc_wiper_status_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_fs_operation_e_type (XDR *xdrs, rpc_loc_fs_operation_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_efs_data_s_type (XDR *xdrs, rpc_loc_efs_data_s_type *objp) { register int32_t *buf; int i; if (!xdr_opaque (xdrs, objp->filename, 64)) return FALSE; if (!xdr_rpc_loc_fs_operation_e_type (xdrs, &objp->operation)) return FALSE; if (!xdr_rpc_uint32 (xdrs, &objp->total_size)) return FALSE; if (!xdr_bytes (xdrs, (char **)&objp->data_ptr.data_ptr_val, (u_int *) &objp->data_ptr.data_ptr_len, ~0)) return FALSE; if (!xdr_rpc_uint32 (xdrs, &objp->part_len)) return FALSE; if (!xdr_rpc_uint8 (xdrs, &objp->part)) return FALSE; if (!xdr_rpc_uint8 (xdrs, &objp->total_parts)) return FALSE; if (!xdr_rpc_uint32 (xdrs, &objp->reserved)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_error_estimate_config_e_type (XDR *xdrs, rpc_loc_error_estimate_config_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_apn_profiles_type (XDR *xdrs, rpc_loc_apn_profiles_type *objp) { register int32_t *buf; int i; if (!xdr_rpc_uint32 (xdrs, &objp->srv_system_type)) return FALSE; if (!xdr_rpc_uint32 (xdrs, &objp->pdp_type)) return FALSE; if (!xdr_rpc_uint32 (xdrs, &objp->reserved)) return FALSE; if (!xdr_opaque (xdrs, objp->apn_name, 100)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_lock_e_type (XDR *xdrs, rpc_loc_lock_e_type *objp) { register int32_t *buf; if (!xdr_enum (xdrs, (enum_t *) objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_nmea_sentence_type (XDR *xdrs, rpc_loc_nmea_sentence_type *objp) { register int32_t *buf; if (!xdr_rpc_uint32 (xdrs, objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_assist_data_type (XDR *xdrs, rpc_loc_assist_data_type *objp) { register int32_t *buf; if (!xdr_rpc_uint32 (xdrs, objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_assist_data_delete_s_type (XDR *xdrs, rpc_loc_assist_data_delete_s_type *objp) { register int32_t *buf; int i; if (!xdr_rpc_loc_assist_data_type (xdrs, &objp->type)) return FALSE; if (!xdr_vector (xdrs, (char *)objp->reserved, 8, sizeof (rpc_uint32), (xdrproc_t) xdr_rpc_uint32)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_ioctl_data_u_type (XDR *xdrs, rpc_loc_ioctl_data_u_type *objp) { register int32_t *buf; if (!xdr_rpc_loc_ioctl_e_type (xdrs, &objp->disc)) return FALSE; switch (objp->disc) { case RPC_LOC_IOCTL_SET_FIX_CRITERIA: if (!xdr_rpc_loc_fix_criteria_s_type (xdrs, &objp->rpc_loc_ioctl_data_u_type_u.fix_criteria)) return FALSE; break; case RPC_LOC_IOCTL_INFORM_NI_USER_RESPONSE: if (!xdr_rpc_loc_user_verify_s_type (xdrs, &objp->rpc_loc_ioctl_data_u_type_u.user_verify_resp)) return FALSE; break; case RPC_LOC_IOCTL_INJECT_PREDICTED_ORBITS_DATA: if (!xdr_rpc_loc_predicted_orbits_data_s_type (xdrs, &objp->rpc_loc_ioctl_data_u_type_u.predicted_orbits_data)) return FALSE; break; case RPC_LOC_IOCTL_SET_PREDICTED_ORBITS_DATA_AUTO_DOWNLOAD: if (!xdr_rpc_loc_predicted_orbits_auto_download_config_s_type (xdrs, &objp->rpc_loc_ioctl_data_u_type_u.predicted_orbits_auto_download)) return FALSE; break; case RPC_LOC_IOCTL_INJECT_UTC_TIME: if (!xdr_rpc_loc_assist_data_time_s_type (xdrs, &objp->rpc_loc_ioctl_data_u_type_u.assistance_data_time)) return FALSE; break; case RPC_LOC_IOCTL_INJECT_POSITION: if (!xdr_rpc_loc_assist_data_pos_s_type (xdrs, &objp->rpc_loc_ioctl_data_u_type_u.assistance_data_position)) return FALSE; break; case RPC_LOC_IOCTL_INFORM_SERVER_OPEN_STATUS: if (!xdr_rpc_loc_server_open_status_s_type (xdrs, &objp->rpc_loc_ioctl_data_u_type_u.conn_open_status)) return FALSE; break; case RPC_LOC_IOCTL_INFORM_SERVER_CLOSE_STATUS: if (!xdr_rpc_loc_server_close_status_s_type (xdrs, &objp->rpc_loc_ioctl_data_u_type_u.conn_close_status)) return FALSE; break; case RPC_LOC_IOCTL_SEND_WIPER_POSITION_REPORT: if (!xdr_rpc_loc_wiper_position_report_s_type (xdrs, &objp->rpc_loc_ioctl_data_u_type_u.wiper_pos)) return FALSE; break; case RPC_LOC_IOCTL_NOTIFY_WIPER_STATUS: if (!xdr_rpc_loc_wiper_status_e_type (xdrs, &objp->rpc_loc_ioctl_data_u_type_u.wiper_status)) return FALSE; break; case RPC_LOC_IOCTL_SET_ENGINE_LOCK: if (!xdr_rpc_loc_lock_e_type (xdrs, &objp->rpc_loc_ioctl_data_u_type_u.engine_lock)) return FALSE; break; case RPC_LOC_IOCTL_SET_SBAS_CONFIG: if (!xdr_rpc_boolean (xdrs, &objp->rpc_loc_ioctl_data_u_type_u.sbas_mode)) return FALSE; break; case RPC_LOC_IOCTL_SET_NMEA_TYPES: if (!xdr_rpc_loc_nmea_sentence_type (xdrs, &objp->rpc_loc_ioctl_data_u_type_u.nmea_types)) return FALSE; break; case RPC_LOC_IOCTL_SET_ON_DEMAND_LPM: if (!xdr_rpc_boolean (xdrs, &objp->rpc_loc_ioctl_data_u_type_u.on_demand_lpm)) return FALSE; break; case RPC_LOC_IOCTL_SET_CDMA_PDE_SERVER_ADDR: case RPC_LOC_IOCTL_SET_CDMA_MPC_SERVER_ADDR: case RPC_LOC_IOCTL_SET_UMTS_SLP_SERVER_ADDR: case RPC_LOC_IOCTL_SET_CUSTOM_PDE_SERVER_ADDR: if (!xdr_rpc_loc_server_info_s_type (xdrs, &objp->rpc_loc_ioctl_data_u_type_u.server_addr)) return FALSE; break; case RPC_LOC_IOCTL_DELETE_ASSIST_DATA: if (!xdr_rpc_loc_assist_data_delete_s_type (xdrs, &objp->rpc_loc_ioctl_data_u_type_u.assist_data_delete)) return FALSE; break; case RPC_LOC_IOCTL_ACCESS_EFS_DATA: if (!xdr_rpc_loc_efs_data_s_type (xdrs, &objp->rpc_loc_ioctl_data_u_type_u.efs_data)) return FALSE; break; case RPC_LOC_IOCTL_ERROR_ESTIMATE_CONFIG: if (!xdr_rpc_loc_error_estimate_config_e_type (xdrs, &objp->rpc_loc_ioctl_data_u_type_u.error_estimate_config)) return FALSE; break; case RPC_LOC_IOCTL_SET_XTRA_T_SESSION_CONTROL: if (!xdr_rpc_uint8 (xdrs, &objp->rpc_loc_ioctl_data_u_type_u.xtra_t_session_control)) return FALSE; break; case RPC_LOC_IOCTL_SET_LBS_APN_PROFILE: case RPC_LOC_IOCTL_SET_XTRA_APN_PROFILE: if (!xdr_vector (xdrs, (char *)objp->rpc_loc_ioctl_data_u_type_u.apn_profiles, 6, sizeof (rpc_loc_apn_profiles_type), (xdrproc_t) xdr_rpc_loc_apn_profiles_type)) return FALSE; break; case RPC_LOC_IOCTL_SET_DATA_ENABLE: if (!xdr_rpc_boolean (xdrs, &objp->rpc_loc_ioctl_data_u_type_u.data_enable)) return FALSE; break; case RPC_LOC_IOCTL_SET_SUPL_VERSION: if (!xdr_rpc_uint32 (xdrs, &objp->rpc_loc_ioctl_data_u_type_u.supl_version)) return FALSE; break; case RPC_LOC_IOCTL_INFORM_SERVER_MULTI_OPEN_STATUS: if (!xdr_rpc_loc_server_multi_open_status_s_type (xdrs, &objp->rpc_loc_ioctl_data_u_type_u.multi_conn_open_status)) return FALSE; break; case RPC_LOC_IOCTL_RESERVED_CMD: if (!xdr_rpc_loc_reserved_payload_s_type (xdrs, &objp->rpc_loc_ioctl_data_u_type_u.reserved)) return FALSE; break; default: break; } return TRUE; } bool_t xdr_rpc_loc_ioctl_callback_data_u_type (XDR *xdrs, rpc_loc_ioctl_callback_data_u_type *objp) { register int32_t *buf; if (!xdr_rpc_loc_ioctl_e_type (xdrs, &objp->disc)) return FALSE; switch (objp->disc) { case RPC_LOC_IOCTL_GET_API_VERSION: if (!xdr_rpc_loc_api_version_s_type (xdrs, &objp->rpc_loc_ioctl_callback_data_u_type_u.api_version)) return FALSE; break; case RPC_LOC_IOCTL_GET_FIX_CRITERIA: if (!xdr_rpc_loc_fix_criteria_s_type (xdrs, &objp->rpc_loc_ioctl_callback_data_u_type_u.fix_criteria)) return FALSE; break; case RPC_LOC_IOCTL_GET_ENGINE_LOCK: if (!xdr_rpc_loc_lock_e_type (xdrs, &objp->rpc_loc_ioctl_callback_data_u_type_u.engine_lock)) return FALSE; break; case RPC_LOC_IOCTL_GET_SBAS_CONFIG: if (!xdr_rpc_boolean (xdrs, &objp->rpc_loc_ioctl_callback_data_u_type_u.sbas_mode)) return FALSE; break; case RPC_LOC_IOCTL_GET_NMEA_TYPES: if (!xdr_rpc_loc_nmea_sentence_type (xdrs, &objp->rpc_loc_ioctl_callback_data_u_type_u.nmea_types)) return FALSE; break; case RPC_LOC_IOCTL_GET_ON_DEMAND_LPM: if (!xdr_rpc_boolean (xdrs, &objp->rpc_loc_ioctl_callback_data_u_type_u.on_demand_lpm)) return FALSE; break; case RPC_LOC_IOCTL_GET_CDMA_PDE_SERVER_ADDR: case RPC_LOC_IOCTL_GET_CDMA_MPC_SERVER_ADDR: case RPC_LOC_IOCTL_GET_UMTS_SLP_SERVER_ADDR: case RPC_LOC_IOCTL_GET_CUSTOM_PDE_SERVER_ADDR: if (!xdr_rpc_loc_server_info_s_type (xdrs, &objp->rpc_loc_ioctl_callback_data_u_type_u.server_addr)) return FALSE; break; case RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_SOURCE: if (!xdr_rpc_loc_predicted_orbits_data_source_s_type (xdrs, &objp->rpc_loc_ioctl_callback_data_u_type_u.predicted_orbits_data_source)) return FALSE; break; case RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_VALIDITY: if (!xdr_rpc_loc_predicted_orbits_data_validity_report_s_type (xdrs, &objp->rpc_loc_ioctl_callback_data_u_type_u.predicted_orbits_data_validity)) return FALSE; break; case RPC_LOC_IOCTL_GET_XTRA_T_SESSION_CONTROL: if (!xdr_rpc_uint8 (xdrs, &objp->rpc_loc_ioctl_callback_data_u_type_u.xtra_t_session_control)) return FALSE; break; case RPC_LOC_IOCTL_GET_LBS_APN_PROFILE: case RPC_LOC_IOCTL_GET_XTRA_APN_PROFILE: if (!xdr_vector (xdrs, (char *)objp->rpc_loc_ioctl_callback_data_u_type_u.apn_profiles, 6, sizeof (rpc_loc_apn_profiles_type), (xdrproc_t) xdr_rpc_loc_apn_profiles_type)) return FALSE; break; case RPC_LOC_IOCTL_GET_SUPL_VERSION: if (!xdr_rpc_uint32 (xdrs, &objp->rpc_loc_ioctl_callback_data_u_type_u.supl_version)) return FALSE; break; default: break; } return TRUE; } bool_t xdr_rpc_loc_ioctl_callback_s_type (XDR *xdrs, rpc_loc_ioctl_callback_s_type *objp) { register int32_t *buf; if (!xdr_rpc_loc_ioctl_e_type (xdrs, &objp->type)) return FALSE; if (!xdr_rpc_int32 (xdrs, &objp->status)) return FALSE; if (!xdr_rpc_loc_ioctl_callback_data_u_type (xdrs, &objp->data)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_event_payload_u_type (XDR *xdrs, rpc_loc_event_payload_u_type *objp) { register int32_t *buf; if (!xdr_u_quad_t (xdrs, &objp->disc)) return FALSE; switch (objp->disc) { case RPC_LOC_EVENT_PARSED_POSITION_REPORT: if (!xdr_rpc_loc_parsed_position_s_type (xdrs, &objp->rpc_loc_event_payload_u_type_u.parsed_location_report)) return FALSE; break; case RPC_LOC_EVENT_SATELLITE_REPORT: if (!xdr_rpc_loc_gnss_info_s_type (xdrs, &objp->rpc_loc_event_payload_u_type_u.gnss_report)) return FALSE; break; case RPC_LOC_EVENT_NMEA_POSITION_REPORT: case RPC_LOC_EVENT_NMEA_1HZ_REPORT: if (!xdr_rpc_loc_nmea_report_s_type (xdrs, &objp->rpc_loc_event_payload_u_type_u.nmea_report)) return FALSE; break; case RPC_LOC_EVENT_NI_NOTIFY_VERIFY_REQUEST: if (!xdr_rpc_loc_ni_event_s_type (xdrs, &objp->rpc_loc_event_payload_u_type_u.ni_request)) return FALSE; break; case RPC_LOC_EVENT_ASSISTANCE_DATA_REQUEST: if (!xdr_rpc_loc_assist_data_request_s_type (xdrs, &objp->rpc_loc_event_payload_u_type_u.assist_data_request)) return FALSE; break; case RPC_LOC_EVENT_LOCATION_SERVER_REQUEST: if (!xdr_rpc_loc_server_request_s_type (xdrs, &objp->rpc_loc_event_payload_u_type_u.loc_server_request)) return FALSE; break; case RPC_LOC_EVENT_IOCTL_REPORT: if (!xdr_rpc_loc_ioctl_callback_s_type (xdrs, &objp->rpc_loc_event_payload_u_type_u.ioctl_report)) return FALSE; break; case RPC_LOC_EVENT_STATUS_REPORT: if (!xdr_rpc_loc_status_event_s_type (xdrs, &objp->rpc_loc_event_payload_u_type_u.status_report)) return FALSE; break; case RPC_LOC_EVENT_WPS_NEEDED_REQUEST: if (!xdr_rpc_loc_qwip_request_s_type (xdrs, &objp->rpc_loc_event_payload_u_type_u.qwip_request)) return FALSE; break; case RPC_LOC_EVENT_RESERVED: if (!xdr_rpc_loc_reserved_payload_s_type (xdrs, &objp->rpc_loc_event_payload_u_type_u.reserved)) return FALSE; break; default: break; } return TRUE; } ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/libloc_api-rpc-stub/src/loc_api_rpcgen_xdr.c ================================================ /* Copyright (c) 2011, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /* * Please do not edit this file. * It was generated using rpcgen. */ #include "loc_api_rpcgen_rpc.h" bool_t xdr_rpc_loc_api_api_versions_return_type (XDR *xdrs, rpc_loc_api_api_versions_return_type *objp) { ; if (!xdr_array (xdrs, (char **)&objp->rpc_loc_api_api_versions_return_type_val, (u_int *) &objp->rpc_loc_api_api_versions_return_type_len, ~0, sizeof (rpc_uint32), (xdrproc_t) xdr_rpc_uint32)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_event_cb_f_type (XDR *xdrs, rpc_loc_event_cb_f_type *objp) { ; if (!xdr_rpc_uint32 (xdrs, objp)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_open_args (XDR *xdrs, rpc_loc_open_args *objp) { ; if (!xdr_rpc_loc_event_mask_type (xdrs, &objp->event_reg_mask)) return FALSE; if (!xdr_rpc_loc_event_cb_f_type (xdrs, &objp->event_callback)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_close_args (XDR *xdrs, rpc_loc_close_args *objp) { ; if (!xdr_rpc_loc_client_handle_type (xdrs, &objp->handle)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_start_fix_args (XDR *xdrs, rpc_loc_start_fix_args *objp) { ; if (!xdr_rpc_loc_client_handle_type (xdrs, &objp->handle)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_stop_fix_args (XDR *xdrs, rpc_loc_stop_fix_args *objp) { ; if (!xdr_rpc_loc_client_handle_type (xdrs, &objp->handle)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_ioctl_args (XDR *xdrs, rpc_loc_ioctl_args *objp) { ; if (!xdr_rpc_loc_client_handle_type (xdrs, &objp->handle)) return FALSE; if (!xdr_rpc_loc_ioctl_e_type (xdrs, &objp->ioctl_type)) return FALSE; if (!xdr_pointer (xdrs, (char **)&objp->ioctl_data, sizeof (rpc_loc_ioctl_data_u_type), (xdrproc_t) xdr_rpc_loc_ioctl_data_u_type)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_api_api_version_s_args (XDR *xdrs, rpc_loc_api_api_version_s_args *objp) { ; if (!xdr_rpc_boolean (xdrs, &objp->len_not_null)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_api_rpc_glue_code_info_remote_rets (XDR *xdrs, rpc_loc_api_rpc_glue_code_info_remote_rets *objp) { ; if (!xdr_rpc_uint32 (xdrs, &objp->toolvers)) return FALSE; if (!xdr_rpc_uint32 (xdrs, &objp->features)) return FALSE; if (!xdr_rpc_uint32 (xdrs, &objp->proghash)) return FALSE; if (!xdr_rpc_uint32 (xdrs, &objp->cbproghash)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_open_rets (XDR *xdrs, rpc_loc_open_rets *objp) { ; if (!xdr_rpc_loc_client_handle_type (xdrs, &objp->loc_open_result)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_close_rets (XDR *xdrs, rpc_loc_close_rets *objp) { ; if (!xdr_rpc_int32 (xdrs, &objp->loc_close_result)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_start_fix_rets (XDR *xdrs, rpc_loc_start_fix_rets *objp) { ; if (!xdr_rpc_int32 (xdrs, &objp->loc_start_fix_result)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_stop_fix_rets (XDR *xdrs, rpc_loc_stop_fix_rets *objp) { ; if (!xdr_rpc_int32 (xdrs, &objp->loc_stop_fix_result)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_ioctl_rets (XDR *xdrs, rpc_loc_ioctl_rets *objp) { ; if (!xdr_rpc_int32 (xdrs, &objp->loc_ioctl_result)) return FALSE; return TRUE; } bool_t xdr_rpc_loc_api_api_versions_rets (XDR *xdrs, rpc_loc_api_api_versions_rets *objp) { ; if (!xdr_rpc_loc_api_api_versions_return_type (xdrs, &objp->loc_api_api_versions_result)) return FALSE; if (!xdr_pointer (xdrs, (char **)&objp->len, sizeof (rpc_uint32), (xdrproc_t) xdr_rpc_uint32)) return FALSE; return TRUE; } ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/libloc_api-rpc-stub/src/loc_apicb_appinit.c ================================================ /* Copyright (c) 2011, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include "librpc.h" #include "loc_api_rpcgen_rpc.h" #include "loc_api_rpcgen_cb_rpc.h" #define RPC_FUNC_VERSION_BASE(a,b) a ## b #define RPC_CB_FUNC_VERS(a,b) RPC_FUNC_VERSION_BASE(a,b) static SVCXPRT* svrPort = NULL; extern void RPC_CB_FUNC_VERS(loc_apicbprog_,LOC_APICBVERS_0001)(struct svc_req *rqstp, register SVCXPRT *transp); int loc_apicb_app_init(void) { /* Register a callback server to use the loc_apicbprog_0x00010001 */ if (svrPort == NULL) { svrPort = svcrtr_create(); } if (!svrPort) return -1; xprt_register(svrPort); if(svc_register(svrPort, LOC_APICBPROG,LOC_APICBVERS_0001, RPC_CB_FUNC_VERS(loc_apicbprog_,LOC_APICBVERS_0001),0)) { return 0; } else { return -1; } } void loc_apicb_app_deinit(void) { if (svrPort == NULL) { return; } svc_unregister(svrPort, LOC_APICBPROG,LOC_APICBVERS_0001); } ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/libloc_api-rpc-stub/xdr/loc_api.xdr ================================================ /* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /* LOC_API TOOL VERSION: 4.48 */ /* GENERATED: TUE JUN 14 2011 */ /*============================================================================= L O C _ A P I . X D R GENERAL DESCRIPTION This is an AUTO GENERATED file that provides an xdr compatible definition of the loc_api API. --------------------------------------------------------------------------- --------------------------------------------------------------------------- =============================================================================*/ /*============================================================================= Edit History AUTO GENERATED Generated by following versions of Htorpc modules: Id: //source/qcom/qct/core/mproc/tools/rel/2h09/htorpc/htorpc.pl#1 Id: //source/qcom/qct/core/mproc/tools/rel/2h09/htorpc/lib/Htorpc/Start.pm#1 Id: //source/qcom/qct/core/mproc/tools/rel/2h09/htorpc/lib/Htorpc/Htoxdr.pm#1 Id: //source/qcom/qct/core/mproc/tools/rel/2h09/htorpc/lib/Htorpc/XDR.pm#3 Id: //source/qcom/qct/core/mproc/tools/rel/2h09/htorpc/lib/Htorpc/Output.pm#5 Id: //source/qcom/qct/core/mproc/tools/rel/2h09/htorpc/lib/Htorpc/Parser.pm#1 Id: //source/qcom/qct/core/mproc/tools/rel/2h09/htorpc/lib/Htorpc/Metacomments.pm#1 Id: //source/qcom/qct/core/mproc/tools/rel/2h09/htorpc/lib/Htorpc/SymbolTable.pm#1 loc_api Definition File(s): Id: //source/qcom/qct/modem/api/gps/main/latest/loc_api.h#24 =============================================================================*/ /*============================================================================= $Header$ =============================================================================*/ typedef rpc_uint32 rpc_loc_api_api_versions_return_type<>; /* * Declare an rpc_uint32 type for each callback type in the API */ typedef rpc_uint32 rpc_loc_event_cb_f_type; /* * These are struct declarations for the function arguments */ struct rpc_loc_open_args { rpc_loc_event_mask_type event_reg_mask; rpc_loc_event_cb_f_type event_callback; }; struct rpc_loc_close_args { rpc_loc_client_handle_type handle; }; struct rpc_loc_start_fix_args { rpc_loc_client_handle_type handle; }; struct rpc_loc_stop_fix_args { rpc_loc_client_handle_type handle; }; struct rpc_loc_ioctl_args { rpc_loc_client_handle_type handle; rpc_loc_ioctl_e_type ioctl_type; rpc_loc_ioctl_data_u_type *ioctl_data; }; struct rpc_loc_api_api_version_s_args { rpc_boolean len_not_null; }; /* * These are struct declarations for the function results */ struct rpc_loc_api_rpc_glue_code_info_remote_rets { rpc_uint32 toolvers; /* Tool version */ rpc_uint32 features; /* Features turned on in the code. * 0x00000001 ONCRPC Server Cleanup Support */ rpc_uint32 proghash; /* Unique hash value for the API XDR definition */ rpc_uint32 cbproghash; /* Unique hash value for the Callbacks' XDR definition */ }; struct rpc_loc_open_rets { rpc_loc_client_handle_type loc_open_result; }; struct rpc_loc_close_rets { rpc_int32 loc_close_result; }; struct rpc_loc_start_fix_rets { rpc_int32 loc_start_fix_result; }; struct rpc_loc_stop_fix_rets { rpc_int32 loc_stop_fix_result; }; struct rpc_loc_ioctl_rets { rpc_int32 loc_ioctl_result; }; struct rpc_loc_api_api_versions_rets { rpc_loc_api_api_versions_return_type loc_api_api_versions_result; rpc_uint32 *len; }; /* * XDR definition of the LOC_API program ( vers. 0x00050006 ) */ program LOC_APIPROG { version LOC_APIVERS_0001 { void rpc_loc_api_null( void ) = 0; rpc_loc_api_rpc_glue_code_info_remote_rets rpc_loc_api_rpc_glue_code_info_remote( void ) = 1; rpc_loc_open_rets rpc_loc_open( rpc_loc_open_args ) = 2; rpc_loc_close_rets rpc_loc_close( rpc_loc_close_args ) = 3; rpc_loc_start_fix_rets rpc_loc_start_fix( rpc_loc_start_fix_args ) = 4; rpc_loc_stop_fix_rets rpc_loc_stop_fix( rpc_loc_stop_fix_args ) = 5; rpc_loc_ioctl_rets rpc_loc_ioctl( rpc_loc_ioctl_args ) = 6; rpc_loc_api_api_versions_rets rpc_loc_api_api_versions( void ) = 0xFFFFFFFF; } = 0x00050001; version LOC_APIVERS_0002 { /* Following elements added in enum rpc_loc_assist_data_request_e_type in 0x00050002 RPC_LOC_ASSIST_DATA_POSITION_INJECTION_REQ */ /* Following elements added in enum rpc_loc_ioctl_e_type in 0x00050002 RPC_LOC_IOCTL_GET_XTRA_T_SESSION_CONTROL RPC_LOC_IOCTL_RESERVED_CMD RPC_LOC_IOCTL_SET_XTRA_T_SESSION_CONTROL */ void rpc_loc_api_null( void ) = 0; } = 0x00050002; version LOC_APIVERS_0003 { /* Following elements added in enum rpc_loc_ioctl_e_type in 0x00050003 RPC_LOC_IOCTL_SET_DATA_ENABLE RPC_LOC_IOCTL_SET_LBS_APN_PROFILE RPC_LOC_IOCTL_GET_XTRA_APN_PROFILE RPC_LOC_IOCTL_GET_LBS_APN_PROFILE RPC_LOC_IOCTL_SET_XTRA_APN_PROFILE */ void rpc_loc_api_null( void ) = 0; } = 0x00050003; version LOC_APIVERS_0004 { /* Following elements added in enum rpc_loc_ioctl_e_type in 0x00050004 RPC_LOC_IOCTL_GET_SUPL_VERSION RPC_LOC_IOCTL_SET_SUPL_VERSION */ void rpc_loc_api_null( void ) = 0; } = 0x00050004; version LOC_APIVERS_0005 { /* Following elements added in enum rpc_loc_server_addr_e_type in 0x00050005 RPC_LOC_SERVER_ADDR_IPV6 */ /* Following elements added in enum rpc_loc_ioctl_e_type in 0x00050005 RPC_LOC_IOCTL_ERROR_ESTIMATE_CONFIG */ void rpc_loc_api_null( void ) = 0; } = 0x00050005; version LOC_APIVERS_0006 { /* Following elements added in enum rpc_loc_ioctl_e_type in 0x00050006 RPC_LOC_IOCTL_INFORM_SERVER_MULTI_OPEN_STATUS */ /* Following elements added in enum rpc_loc_server_request_e_type in 0x00050006 RPC_LOC_SERVER_REQUEST_MULTI_OPEN */ void rpc_loc_api_null( void ) = 0; } = 0x00050006; } = 0x3000008C; const LOC_APIVERS = 0x00050006; ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/libloc_api-rpc-stub/xdr/loc_api_cb.xdr ================================================ /* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /* LOC_API TOOL VERSION: 4.48 */ /* GENERATED: TUE JUN 14 2011 */ /*============================================================================= L O C _ A P I _ C B . X D R GENERAL DESCRIPTION This is an AUTO GENERATED file that provides an xdr compatible definition of an api that represents the grouping of the different callback functions the loc_api API supports. --------------------------------------------------------------------------- --------------------------------------------------------------------------- =============================================================================*/ /*============================================================================= Edit History AUTO GENERATED Generated by following versions of Htorpc modules: Id: //source/qcom/qct/core/mproc/tools/rel/2h09/htorpc/htorpc.pl#1 Id: //source/qcom/qct/core/mproc/tools/rel/2h09/htorpc/lib/Htorpc/Start.pm#1 Id: //source/qcom/qct/core/mproc/tools/rel/2h09/htorpc/lib/Htorpc/Htoxdr.pm#1 Id: //source/qcom/qct/core/mproc/tools/rel/2h09/htorpc/lib/Htorpc/XDR.pm#3 Id: //source/qcom/qct/core/mproc/tools/rel/2h09/htorpc/lib/Htorpc/Output.pm#5 Id: //source/qcom/qct/core/mproc/tools/rel/2h09/htorpc/lib/Htorpc/Parser.pm#1 Id: //source/qcom/qct/core/mproc/tools/rel/2h09/htorpc/lib/Htorpc/Metacomments.pm#1 Id: //source/qcom/qct/core/mproc/tools/rel/2h09/htorpc/lib/Htorpc/SymbolTable.pm#1 loc_api Definition File(s): Id: //source/qcom/qct/modem/api/gps/main/latest/loc_api.h#24 =============================================================================*/ /*============================================================================= $Header$ =============================================================================*/ /* * These are struct declarations for the function arguments */ struct rpc_loc_event_cb_f_type_args { rpc_uint32 cb_id; rpc_loc_client_handle_type loc_handle; rpc_loc_event_mask_type loc_event; rpc_loc_event_payload_u_type *loc_event_payload; }; /* * These are struct declaratios for the function results */ struct rpc_loc_event_cb_f_type_rets { rpc_int32 loc_event_cb_f_type_result; }; /* * XDR definition of the LOC_API callback program ( vers. 0x00050006 ) */ program LOC_APICBPROG { version LOC_APICBVERS_0001 { rpc_loc_event_cb_f_type_rets rpc_loc_event_cb_f_type( rpc_loc_event_cb_f_type_args ) = 1; } = 0x00050001; version LOC_APICBVERS_0002 { /* Following elements added in enum rpc_loc_assist_data_request_e_type in 0x00050002 RPC_LOC_ASSIST_DATA_POSITION_INJECTION_REQ */ /* Following elements added in enum rpc_loc_ioctl_e_type in 0x00050002 RPC_LOC_IOCTL_GET_XTRA_T_SESSION_CONTROL RPC_LOC_IOCTL_RESERVED_CMD RPC_LOC_IOCTL_SET_XTRA_T_SESSION_CONTROL */ int rpc_loc_api_cb_null( void ) = 0xffffff00; } = 0x00050002; version LOC_APICBVERS_0003 { /* Following elements added in enum rpc_loc_ioctl_e_type in 0x00050003 RPC_LOC_IOCTL_SET_DATA_ENABLE RPC_LOC_IOCTL_SET_LBS_APN_PROFILE RPC_LOC_IOCTL_GET_XTRA_APN_PROFILE RPC_LOC_IOCTL_GET_LBS_APN_PROFILE RPC_LOC_IOCTL_SET_XTRA_APN_PROFILE */ int rpc_loc_api_cb_null( void ) = 0xffffff00; } = 0x00050003; version LOC_APICBVERS_0004 { /* Following elements added in enum rpc_loc_ioctl_e_type in 0x00050004 RPC_LOC_IOCTL_GET_SUPL_VERSION RPC_LOC_IOCTL_SET_SUPL_VERSION */ int rpc_loc_api_cb_null( void ) = 0xffffff00; } = 0x00050004; version LOC_APICBVERS_0005 { /* Following elements added in enum rpc_loc_server_addr_e_type in 0x00050005 RPC_LOC_SERVER_ADDR_IPV6 */ /* Following elements added in enum rpc_loc_ioctl_e_type in 0x00050005 RPC_LOC_IOCTL_ERROR_ESTIMATE_CONFIG */ int rpc_loc_api_cb_null( void ) = 0xffffff00; } = 0x00050005; version LOC_APICBVERS_0006 { /* Following elements added in enum rpc_loc_ioctl_e_type in 0x00050006 RPC_LOC_IOCTL_INFORM_SERVER_MULTI_OPEN_STATUS */ /* Following elements added in enum rpc_loc_server_request_e_type in 0x00050006 RPC_LOC_SERVER_REQUEST_MULTI_OPEN */ int rpc_loc_api_cb_null( void ) = 0xffffff00; } = 0x00050006; } = 0x3100008C; const LOC_APICBVERS = 0x00050006; ================================================ FILE: gps/loc_api/libloc_api-rpc-50001/libloc_api-rpc-stub/xdr/loc_api_common.xdr ================================================ /* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /* LOC_API TOOL VERSION: 4.48 */ /* GENERATED: TUE JUN 14 2011 */ /*============================================================================= L O C _ A P I _ C O M M O N . X D R GENERAL DESCRIPTION This is an AUTO GENERATED file that provides an xdr compatible definition of an api that represents the grouping of the different callback functions the loc_api API supports. --------------------------------------------------------------------------- --------------------------------------------------------------------------- =============================================================================*/ /*============================================================================= Edit History AUTO GENERATED Generated by following versions of Htorpc modules: Id: //source/qcom/qct/core/mproc/tools/rel/2h09/htorpc/htorpc.pl#1 Id: //source/qcom/qct/core/mproc/tools/rel/2h09/htorpc/lib/Htorpc/Start.pm#1 Id: //source/qcom/qct/core/mproc/tools/rel/2h09/htorpc/lib/Htorpc/Htoxdr.pm#1 Id: //source/qcom/qct/core/mproc/tools/rel/2h09/htorpc/lib/Htorpc/XDR.pm#3 Id: //source/qcom/qct/core/mproc/tools/rel/2h09/htorpc/lib/Htorpc/Output.pm#5 Id: //source/qcom/qct/core/mproc/tools/rel/2h09/htorpc/lib/Htorpc/Parser.pm#1 Id: //source/qcom/qct/core/mproc/tools/rel/2h09/htorpc/lib/Htorpc/Metacomments.pm#1 Id: //source/qcom/qct/core/mproc/tools/rel/2h09/htorpc/lib/Htorpc/SymbolTable.pm#1 loc_api Definition File(s): Id: //source/qcom/qct/modem/api/gps/main/latest/loc_api.h#24 =============================================================================*/ /*============================================================================= $Header$ =============================================================================*/ const LOC_API_TOOLVERS = 0x00040030; const LOC_API_FEATURES = 0x00000001; const RPC_LOC_EVENT_STATUS_REPORT = 0x00000100; const RPC_LOC_EVENT_ASSISTANCE_DATA_REQUEST = 0x00000020; const RPC_LOC_EVENT_WPS_NEEDED_REQUEST = 0x00000200; const RPC_LOC_EVENT_SATELLITE_REPORT = 0x00000002; const RPC_LOC_EVENT_PARSED_POSITION_REPORT = 0x00000001; const RPC_LOC_EVENT_RESERVED = 0x8000000000000000; const RPC_LOC_EVENT_LOCATION_SERVER_REQUEST = 0x00000040; const RPC_LOC_EVENT_NMEA_POSITION_REPORT = 0x00000008; const RPC_LOC_EVENT_IOCTL_REPORT = 0x00000080; const RPC_LOC_EVENT_NMEA_1HZ_REPORT = 0x00000004; const RPC_LOC_EVENT_NI_NOTIFY_VERIFY_REQUEST = 0x00000010; const RPC_LOC_API_CB_NULL_VERSION = 0x00050002; const RPC_LOC_EVENT_CB_F_TYPE_VERSION = 0x00050001; const RPC_LOC_API_API_VERSIONS_VERSION = 0x00050001; const RPC_LOC_STOP_FIX_VERSION = 0x00050001; const RPC_LOC_START_FIX_VERSION = 0x00050001; const RPC_LOC_IOCTL_VERSION = 0x00050001; const RPC_LOC_CLOSE_VERSION = 0x00050001; const RPC_LOC_API_RPC_GLUE_CODE_INFO_REMOTE_VERSION = 0x00050001; const RPC_LOC_OPEN_VERSION = 0x00050001; const RPC_LOC_API_NULL_VERSION = 0x00050001; const RPC_LOC_API_API_MAJOR_NUM = 0x0005; const RPC_LOC_APIAPI_VERSION_IS_HASHKEY = 0; typedef rpc_int32 rpc_loc_client_handle_type; typedef rpc_uint64 rpc_loc_event_mask_type; typedef rpc_uint64 rpc_loc_position_valid_mask_type; typedef rpc_uint32 rpc_loc_pos_technology_mask_type; enum rpc_loc_session_status_e_type { RPC_LOC_SESS_STATUS_SUCCESS = 0, RPC_LOC_SESS_STATUS_IN_PROGESS = 1, RPC_LOC_SESS_STATUS_GENERAL_FAILURE = 2, RPC_LOC_SESS_STATUS_TIMEOUT = 3, RPC_LOC_SESS_STATUS_USER_END = 4, RPC_LOC_SESS_STATUS_BAD_PARAMETER = 5, RPC_LOC_SESS_STATUS_PHONE_OFFLINE = 6, RPC_LOC_SESS_STATUS_ENGINE_LOCKED = 7, RPC_LOC_SESS_STATUS_MAX = 268435456 }; struct rpc_loc_calendar_time_s_type { rpc_uint16 year; unsigned char month; unsigned char day_of_week; unsigned char day; unsigned char hour; unsigned char minute; unsigned char second; rpc_uint16 millisecond; }; struct rpc_loc_parsed_position_s_type { rpc_loc_position_valid_mask_type valid_mask; rpc_loc_session_status_e_type session_status; rpc_loc_calendar_time_s_type timestamp_calendar; rpc_uint64 timestamp_utc; rpc_uint8 leap_seconds; float time_unc; double latitude; double longitude; float altitude_wrt_ellipsoid; float altitude_wrt_mean_sea_level; float speed_horizontal; float speed_vertical; float heading; float hor_unc_circular; float hor_unc_ellipse_semi_major; float hor_unc_ellipse_semi_minor; float hor_unc_ellipse_orient_azimuth; float vert_unc; float speed_unc; float heading_unc; unsigned char confidence_horizontal; unsigned char confidence_vertical; float magnetic_deviation; rpc_loc_pos_technology_mask_type technology_mask; }; enum rpc_loc_sv_system_e_type { RPC_LOC_SV_SYSTEM_GPS = 1, RPC_LOC_SV_SYSTEM_GALILEO = 2, RPC_LOC_SV_SYSTEM_SBAS = 3, RPC_LOC_SV_SYSTEM_COMPASS = 4, RPC_LOC_SV_SYSTEM_GLONASS = 5, RPC_LOC_SV_SYSTEM_MAX = 268435456 }; enum rpc_loc_sv_status_e_type { RPC_LOC_SV_STATUS_IDLE = 1, RPC_LOC_SV_STATUS_SEARCH = 2, RPC_LOC_SV_STATUS_TRACK = 3, RPC_LOC_SV_STATUS_MAX = 268435456 }; typedef rpc_uint32 rpc_loc_sv_info_valid_mask_type; struct rpc_loc_sv_info_s_type { rpc_loc_sv_info_valid_mask_type valid_mask; rpc_loc_sv_system_e_type system; rpc_uint8 prn; rpc_uint8 health_status; rpc_loc_sv_status_e_type process_status; rpc_boolean has_eph; rpc_boolean has_alm; float elevation; float azimuth; float snr; }; typedef rpc_uint32 rpc_loc_gnss_info_valid_mask_type; struct rpc_loc_gnss_info_s_type { rpc_loc_gnss_info_valid_mask_type valid_mask; float position_dop; float horizontal_dop; float vertical_dop; rpc_boolean altitude_assumed; rpc_uint16 sv_count; rpc_loc_sv_info_s_type sv_list<80>; /* EVAL:[LOC_API_MAX_SV_COUNT]*/ }; struct rpc_loc_nmea_report_s_type { rpc_uint16 length; opaque nmea_sentences[200]; }; enum rpc_loc_status_event_e_type { RPC_LOC_STATUS_EVENT_ENGINE_STATE = 1, RPC_LOC_STATUS_EVENT_FIX_SESSION_STATE = 2, RPC_LOC_STATUS_EVENT_MAX = 268435456 }; enum rpc_loc_engine_state_e_type { RPC_LOC_ENGINE_STATE_ON = 1, RPC_LOC_ENGINE_STATE_OFF = 2, RPC_LOC_ENGINE_STATE_MAX = 268435456 }; enum rpc_loc_fix_session_state_e_type { RPC_LOC_FIX_SESSION_STATE_BEGIN = 1, RPC_LOC_FIX_SESSION_STATE_END = 2, RPC_LOC_FIX_SESSION_STATE_MAX = 268435456 }; union rpc_loc_status_event_payload_u_type switch (rpc_loc_status_event_e_type disc) { case RPC_LOC_STATUS_EVENT_ENGINE_STATE: rpc_loc_engine_state_e_type engine_state; case RPC_LOC_STATUS_EVENT_FIX_SESSION_STATE: rpc_loc_fix_session_state_e_type fix_session_state; default: void; }; struct rpc_loc_status_event_s_type { rpc_loc_status_event_e_type event; rpc_loc_status_event_payload_u_type payload; }; enum rpc_loc_server_addr_e_type { RPC_LOC_SERVER_ADDR_IPV4 = 1, RPC_LOC_SERVER_ADDR_URL = 2, RPC_LOC_SERVER_ADDR_IPV6 = 3, RPC_LOC_SERVER_ADDR_MAX = 268435456 }; struct rpc_loc_server_addr_ipv4_type { rpc_uint32 addr; rpc_uint16 port; }; struct rpc_loc_server_addr_url_type { rpc_uint16 length; opaque addr[256]; }; struct rpc_loc_server_addr_ipv6_type { rpc_uint16 addr[8]; rpc_uint32 port; }; union rpc_loc_server_addr_u_type switch (rpc_loc_server_addr_e_type disc) { case RPC_LOC_SERVER_ADDR_IPV4: rpc_loc_server_addr_ipv4_type ipv4; case RPC_LOC_SERVER_ADDR_URL: rpc_loc_server_addr_url_type url; case RPC_LOC_SERVER_ADDR_IPV6: rpc_loc_server_addr_ipv6_type ipv6; default: void; }; struct rpc_loc_server_info_s_type { rpc_loc_server_addr_e_type addr_type; rpc_loc_server_addr_u_type addr_info; }; enum rpc_loc_ni_notify_verify_e_type { RPC_LOC_NI_USER_NO_NOTIFY_NO_VERIFY = 1, RPC_LOC_NI_USER_NOTIFY_ONLY = 2, RPC_LOC_NI_USER_NOTIFY_VERIFY_ALLOW_NO_RESP = 3, RPC_LOC_NI_USER_NOTIFY_VERIFY_NOT_ALLOW_NO_RESP = 4, RPC_LOC_NI_USER_PRIVACY_OVERRIDE = 5, RPC_LOC_NI_USER_NOTIFY_VERITY_TYPE_MAX = 268435456 }; enum rpc_loc_ni_event_e_type { RPC_LOC_NI_EVENT_VX_NOTIFY_VERIFY_REQ = 1, RPC_LOC_NI_EVENT_SUPL_NOTIFY_VERIFY_REQ = 2, RPC_LOC_NI_EVENT_UMTS_CP_NOTIFY_VERIFY_REQ = 3, RPC_LOC_NI_EVENT_VX_SERVICE_INTERACTION_REQ = 4, RPC_LOC_NI_EVENT_MAX = 268435456 }; enum rpc_loc_ni_datacoding_scheme_e_type { RPC_LOC_NI_PRESUPL_ISO646IRV = 0, RPC_LOC_NI_PRESUPL_ISO8859 = 1, RPC_LOC_NI_PRESUPL_UTF8 = 2, RPC_LOC_NI_PRESUPL_UTF16 = 3, RPC_LOC_NI_PRESUPL_UCS2 = 4, RPC_LOC_NI_PRESUPL_GSM_DEFAULT = 5, RPC_LOC_NI_PRESUPL_SHIFT_JIS = 6, RPC_LOC_NI_PRESUPL_JIS = 7, RPC_LOC_NI_PRESUPL_EUC = 8, RPC_LOC_NI_PRESUPL_GB2312 = 9, RPC_LOC_NI_PRESUPL_CNS11643 = 10, RPC_LOC_NI_PRESUPL_KSC1001 = 11, RPC_LOC_NI_PRESUPL_ENCODING_UNKNOWN = 2147483647, RPC_LOC_NI_SS_GERMAN = 12, RPC_LOC_NI_SS_ENGLISH = 13, RPC_LOC_NI_SS_ITALIAN = 14, RPC_LOC_NI_SS_FRENCH = 15, RPC_LOC_NI_SS_SPANISH = 16, RPC_LOC_NI_SS_DUTCH = 17, RPC_LOC_NI_SS_SWEDISH = 18, RPC_LOC_NI_SS_DANISH = 19, RPC_LOC_NI_SS_PORTUGUESE = 20, RPC_LOC_NI_SS_FINNISH = 21, RPC_LOC_NI_SS_NORWEGIAN = 22, RPC_LOC_NI_SS_GREEK = 23, RPC_LOC_NI_SS_TURKISH = 24, RPC_LOC_NI_SS_HUNGARIAN = 25, RPC_LOC_NI_SS_POLISH = 26, RPC_LOC_NI_SS_LANGUAGE_UNSPEC = 27, RPC_LOC_NI_SUPL_UTF8 = 28, RPC_LOC_NI_SUPL_UCS2 = 29, RPC_LOC_NI_SUPL_GSM_DEFAULT = 30, RPC_LOC_NI_SUPL_ENCODING_UNKNOWN = 2147483647 }; enum rpc_loc_ni_vx_requester_id_encoding_scheme_e_type { RPC_LOC_NI_VX_OCTET = 0, RPC_LOC_NI_VX_EXN_PROTOCOL_MSG = 1, RPC_LOC_NI_VX_ASCII = 2, RPC_LOC_NI_VX_IA5 = 3, RPC_LOC_NI_VX_UNICODE = 4, RPC_LOC_NI_VX_SHIFT_JIS = 5, RPC_LOC_NI_VX_KOREAN = 6, RPC_LOC_NI_VX_LATIN_HEBREW = 7, RPC_LOC_NI_VX_LATIN = 8, RPC_LOC_NI_VX_GSM = 9, RPC_LOC_NI_VX_ENCODING_TYPE_MAX = 268435456 }; enum rpc_loc_ni_vx_pos_mode_e_type { RPC_LOC_VX_MS_ASSISTED_ONLY = 1, RPC_LOC_VX_MS_BASED_ONLY = 2, RPC_LOC_VX_MS_ASSISTED_PREF_MSBASED_ALLWD = 3, RPC_LOC_VX_MS_BASED_PREF_ASSISTED_ALLWD = 4, RPC_LOC_VX_POS_MODE_MAX = 268435456 }; struct rpc_loc_ni_vx_requester_id_s_type { unsigned char requester_id_length; opaque requester_id[200]; }; struct rpc_loc_ni_vx_notify_verify_req_s_type { rpc_loc_ni_notify_verify_e_type notification_priv_type; unsigned char pos_qos_incl; unsigned char pos_qos; rpc_uint32 num_fixes; rpc_uint32 tbf; rpc_loc_ni_vx_pos_mode_e_type pos_mode; rpc_loc_ni_vx_requester_id_encoding_scheme_e_type encoding_scheme; rpc_loc_ni_vx_requester_id_s_type requester_id; rpc_uint16 user_resp_timer_val; }; enum rpc_loc_ni_supl_pos_method_e_type { RPC_LOC_NI_POSMETHOD_AGPS_SETASSISTED = 1, RPC_LOC_NI_POSMETHOD_AGPS_SETBASED = 2, RPC_LOC_NI_POSMETHOD_AGPS_SETASSISTED_PREF = 3, RPC_LOC_NI_POSMETHOD_AGPS_SETBASED_PREF = 4, RPC_LOC_NI_POSMETHOD_AUTONOMOUS_GPS = 5, RPC_LOC_NI_POSMETHOD_AFLT = 6, RPC_LOC_NI_POSMETHOD_ECID = 7, RPC_LOC_NI_POSMETHOD_EOTD = 8, RPC_LOC_NI_POSMETHOD_OTDOA = 9, RPC_LOC_NI_POSMETHOD_NO_POSITION = 10, RPC_LOC_NI_POSMETHOD_MAX = 268435456 }; struct rpc_loc_ni_supl_slp_session_id_s_type { unsigned char presence; opaque session_id[4]; rpc_loc_server_info_s_type slp_address; }; struct rpc_loc_ni_requestor_id_s_type { unsigned char data_coding_scheme; opaque requestor_id_string[200]; unsigned char string_len; }; struct rpc_loc_ni_supl_client_name_s_type { unsigned char data_coding_scheme; opaque client_name_string[64]; unsigned char string_len; }; struct rpc_loc_ni_supl_qop_s_type { unsigned char bit_mask; unsigned char horacc; unsigned char veracc; rpc_uint16 maxLocAge; unsigned char delay; }; struct rpc_loc_ni_supl_notify_verify_req_s_type { rpc_loc_ni_notify_verify_e_type notification_priv_type; rpc_uint16 flags; rpc_loc_ni_supl_slp_session_id_s_type supl_slp_session_id; opaque supl_hash[8]; rpc_loc_ni_datacoding_scheme_e_type datacoding_scheme; rpc_loc_ni_supl_pos_method_e_type pos_method; rpc_loc_ni_requestor_id_s_type requestor_id; rpc_loc_ni_supl_client_name_s_type client_name; rpc_loc_ni_supl_qop_s_type supl_qop; rpc_uint16 user_response_timer; }; struct rpc_loc_ni_ext_client_address_s_type { unsigned char ext_client_address_len; opaque ext_client_address[20]; }; enum rpc_loc_ni_location_type_e_type { RPC_LOC_NI_LOCATIONTYPE_CURRENT_LOCATION = 1, RPC_LOC_NI_LOCATIONTYPE_CURRENT_OR_LAST_KNOWN_LOCATION = 2, RPC_LOC_NI_LOCATIONTYPE_INITIAL_LOCATION = 3, RPC_LOC_NI_LOCATIONTYPE_MAX = 268435456 }; struct rpc_loc_ni_deferred_location_s_type { unsigned char unused_bits; unsigned char ms_available; }; struct rpc_loc_ni_codeword_string_s_type { unsigned char data_coding_scheme; opaque lcs_codeword_string[20]; unsigned char string_len; }; struct rpc_loc_ni_service_type_id_s_type { unsigned char lcs_service_type_id; }; struct rpc_loc_ni_umts_cp_notify_verify_req_s_type { rpc_loc_ni_notify_verify_e_type notification_priv_type; unsigned char invoke_id; rpc_uint16 flags; unsigned char notification_length; opaque notification_text[64]; rpc_loc_ni_datacoding_scheme_e_type datacoding_scheme; rpc_loc_ni_ext_client_address_s_type ext_client_address_data; rpc_loc_ni_location_type_e_type location_type; rpc_loc_ni_deferred_location_s_type deferred_location; rpc_loc_ni_requestor_id_s_type requestor_id; rpc_loc_ni_codeword_string_s_type codeword_string; rpc_loc_ni_service_type_id_s_type service_type_id; rpc_uint16 user_response_timer; }; enum rpc_loc_ni_service_interaction_e_type { RPC_LOC_NI_SERVICE_INTERACTION_ONGOING_NI_INCOMING_MO = 1, RPC_LOC_NI_SERVICE_INTERACTION_MAX = 268435456 }; struct rpc_loc_ni_vx_service_interaction_req_s_type { rpc_loc_ni_vx_notify_verify_req_s_type ni_vx_req; rpc_loc_ni_service_interaction_e_type service_interation_type; }; union rpc_loc_ni_event_payload_u_type switch (rpc_loc_ni_event_e_type disc) { case RPC_LOC_NI_EVENT_VX_NOTIFY_VERIFY_REQ: rpc_loc_ni_vx_notify_verify_req_s_type vx_req; case RPC_LOC_NI_EVENT_SUPL_NOTIFY_VERIFY_REQ: rpc_loc_ni_supl_notify_verify_req_s_type supl_req; case RPC_LOC_NI_EVENT_UMTS_CP_NOTIFY_VERIFY_REQ: rpc_loc_ni_umts_cp_notify_verify_req_s_type umts_cp_req; case RPC_LOC_NI_EVENT_VX_SERVICE_INTERACTION_REQ: rpc_loc_ni_vx_service_interaction_req_s_type service_interaction_req; default: void; }; struct rpc_loc_ni_event_s_type { rpc_loc_ni_event_e_type event; rpc_loc_ni_event_payload_u_type payload; }; enum rpc_loc_assist_data_request_e_type { RPC_LOC_ASSIST_DATA_TIME_REQ = 1, RPC_LOC_ASSIST_DATA_PREDICTED_ORBITS_REQ = 2, RPC_LOC_ASSIST_DATA_POSITION_INJECTION_REQ = 3, RPC_LOC_ASSIST_DATA_MAX = 268435456 }; typedef string rpc_struct_loc_time_download_source_s_type_servers_ptr<256>; /* EVAL:[LOC_API_MAX_SERVER_ADDR_LENGTH]*/ typedef rpc_struct_loc_time_download_source_s_type_servers_ptr rpc_struct_loc_time_download_source_s_type_servers[3]; struct rpc_loc_time_download_source_s_type { rpc_uint32 delay_threshold; rpc_struct_loc_time_download_source_s_type_servers servers; }; typedef string rpc_struct_loc_predicted_orbits_data_source_s_type_servers_ptr; typedef rpc_struct_loc_predicted_orbits_data_source_s_type_servers_ptr rpc_struct_loc_predicted_orbits_data_source_s_type_servers[3]; struct rpc_loc_predicted_orbits_data_source_s_type { rpc_uint32 max_file_size; rpc_uint32 max_part_size; rpc_struct_loc_predicted_orbits_data_source_s_type_servers servers; }; struct rpc_loc_pos_inj_request_s_type { rpc_uint32 flags; double latitude; double longitude; rpc_uint32 position_uncertainty; rpc_uint64 timestamp; }; union rpc_loc_assist_data_request_payload_u_type switch (rpc_loc_assist_data_request_e_type disc) { case RPC_LOC_ASSIST_DATA_TIME_REQ: rpc_loc_time_download_source_s_type time_download; case RPC_LOC_ASSIST_DATA_PREDICTED_ORBITS_REQ: rpc_loc_predicted_orbits_data_source_s_type data_download; case RPC_LOC_ASSIST_DATA_POSITION_INJECTION_REQ: rpc_loc_pos_inj_request_s_type pos_injection; default: void; }; struct rpc_loc_assist_data_request_s_type { rpc_loc_assist_data_request_e_type event; rpc_loc_assist_data_request_payload_u_type payload; }; typedef rpc_uint32 rpc_loc_server_connection_handle; enum rpc_loc_server_protocol_e_type { RPC_LOC_SERVER_PROTOCOL_DEFAULT = 0, RPC_LOC_SERVER_PROTOCOL_SUPL = 1, RPC_LOC_SERVER_PROTOCOL_VX_MPC = 2, RPC_LOC_SERVER_PROTOCOL_VX_PDE = 3, RPC_LOC_SERVER_PROTOCOL_MAX = 16777216 }; enum rpc_loc_server_connection_e_type { RPC_LOC_SERVER_CONNECTION_LBS = 0, RPC_LOC_SERVER_CONNECTION_WWAN_INTERNET, RPC_LOC_SERVER_CONNECTION_MAX = 16777216 }; enum rpc_loc_server_request_e_type { RPC_LOC_SERVER_REQUEST_OPEN = 1, RPC_LOC_SERVER_REQUEST_CLOSE = 2, RPC_LOC_SERVER_REQUEST_MULTI_OPEN = 3, RPC_LOC_SERVER_REQUEST_MAX = 268435456 }; struct rpc_loc_server_open_req_s_type { rpc_loc_server_connection_handle conn_handle; rpc_loc_server_protocol_e_type protocol; }; struct rpc_loc_server_multi_open_req_s_type { rpc_loc_server_connection_handle conn_handle; rpc_loc_server_protocol_e_type protocol; rpc_loc_server_connection_e_type connection_type; }; struct rpc_loc_server_close_req_s_type { rpc_loc_server_connection_handle conn_handle; }; union rpc_loc_server_request_u_type switch (rpc_loc_server_request_e_type disc) { case RPC_LOC_SERVER_REQUEST_OPEN: rpc_loc_server_open_req_s_type open_req; case RPC_LOC_SERVER_REQUEST_CLOSE: rpc_loc_server_close_req_s_type close_req; case RPC_LOC_SERVER_REQUEST_MULTI_OPEN: rpc_loc_server_multi_open_req_s_type multi_open_req; default: void; }; struct rpc_loc_server_request_s_type { rpc_loc_server_request_e_type event; rpc_loc_server_request_u_type payload; }; enum rpc_loc_qwip_request_e_type { RPC_LOC_QWIP_START_PERIODIC_HI_FREQ_FIXES = 0, RPC_LOC_QWIP_START_PERIODIC_KEEP_WARM, RPC_LOC_QWIP_STOP_PERIODIC_FIXES, RPC_LOC_QWIP_SUSPEND, RPC_LOC_QWIP_REQUEST_MAX = 268435456 }; struct rpc_loc_qwip_request_s_type { rpc_loc_qwip_request_e_type request_type; rpc_uint16 tbf_ms; }; struct rpc_loc_reserved_payload_s_type { rpc_uint16 data_size; opaque data<>; }; enum rpc_loc_ioctl_e_type { RPC_LOC_IOCTL_GET_API_VERSION = 1, RPC_LOC_IOCTL_SET_FIX_CRITERIA = 2, RPC_LOC_IOCTL_GET_FIX_CRITERIA = 3, RPC_LOC_IOCTL_SERVICE_START_INDEX = 400, RPC_LOC_IOCTL_INFORM_NI_USER_RESPONSE = 400, RPC_LOC_IOCTL_INJECT_PREDICTED_ORBITS_DATA = 401, RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_VALIDITY = 402, RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_SOURCE = 403, RPC_LOC_IOCTL_SET_PREDICTED_ORBITS_DATA_AUTO_DOWNLOAD = 404, RPC_LOC_IOCTL_INJECT_UTC_TIME = 405, RPC_LOC_IOCTL_INJECT_RTC_VALUE = 406, RPC_LOC_IOCTL_INJECT_POSITION = 407, RPC_LOC_IOCTL_QUERY_ENGINE_STATE = 408, RPC_LOC_IOCTL_INFORM_SERVER_OPEN_STATUS = 409, RPC_LOC_IOCTL_INFORM_SERVER_CLOSE_STATUS = 410, RPC_LOC_IOCTL_SEND_WIPER_POSITION_REPORT = 411, RPC_LOC_IOCTL_NOTIFY_WIPER_STATUS = 412, RPC_LOC_IOCTL_ACCESS_EFS_DATA = 413, RPC_LOC_IOCTL_ERROR_ESTIMATE_CONFIG = 414, RPC_LOC_IOCTL_INFORM_SERVER_MULTI_OPEN_STATUS = 415, RPC_LOC_IOCTL_NV_SETTINGS_START_INDEX = 800, RPC_LOC_IOCTL_SET_ENGINE_LOCK = 800, RPC_LOC_IOCTL_GET_ENGINE_LOCK = 801, RPC_LOC_IOCTL_SET_SBAS_CONFIG = 802, RPC_LOC_IOCTL_GET_SBAS_CONFIG = 803, RPC_LOC_IOCTL_SET_NMEA_TYPES = 804, RPC_LOC_IOCTL_GET_NMEA_TYPES = 805, RPC_LOC_IOCTL_SET_CDMA_PDE_SERVER_ADDR = 806, RPC_LOC_IOCTL_GET_CDMA_PDE_SERVER_ADDR = 807, RPC_LOC_IOCTL_SET_CDMA_MPC_SERVER_ADDR = 808, RPC_LOC_IOCTL_GET_CDMA_MPC_SERVER_ADDR = 809, RPC_LOC_IOCTL_SET_UMTS_SLP_SERVER_ADDR = 810, RPC_LOC_IOCTL_GET_UMTS_SLP_SERVER_ADDR = 811, RPC_LOC_IOCTL_SET_ON_DEMAND_LPM = 812, RPC_LOC_IOCTL_GET_ON_DEMAND_LPM = 813, RPC_LOC_IOCTL_SET_XTRA_T_SESSION_CONTROL = 814, RPC_LOC_IOCTL_GET_XTRA_T_SESSION_CONTROL = 815, RPC_LOC_IOCTL_SET_LBS_APN_PROFILE = 816, RPC_LOC_IOCTL_GET_LBS_APN_PROFILE = 817, RPC_LOC_IOCTL_SET_XTRA_APN_PROFILE = 818, RPC_LOC_IOCTL_GET_XTRA_APN_PROFILE = 819, RPC_LOC_IOCTL_SET_DATA_ENABLE = 820, RPC_LOC_IOCTL_SET_SUPL_VERSION = 821, RPC_LOC_IOCTL_GET_SUPL_VERSION = 822, RPC_LOC_IOCTL_PROPRIETARY_START_INDEX = 1000, RPC_LOC_IOCTL_DELETE_ASSIST_DATA = 1000, RPC_LOC_IOCTL_SET_CUSTOM_PDE_SERVER_ADDR = 1001, RPC_LOC_IOCTL_GET_CUSTOM_PDE_SERVER_ADDR = 1002, RPC_LOC_IOCTL_RESERVED_CMD = 8000, RPC_LOC_IOCTL_THIRD_PARTY_START_INDEX = 1073741824 }; struct rpc_loc_api_version_s_type { unsigned char major; unsigned char minor; }; enum rpc_loc_fix_recurrence_e_type { RPC_LOC_PERIODIC_FIX = 1, RPC_LOC_SINGLE_FIX = 2, RPC_LOC_FIX_SESSION_TYPE_MAX = 268435456 }; enum rpc_loc_operation_mode_e_type { RPC_LOC_OPER_MODE_DEFAULT = 1, RPC_LOC_OPER_MODE_MSB = 2, RPC_LOC_OPER_MODE_MSA = 3, RPC_LOC_OPER_MODE_STANDALONE = 4, RPC_LOC_OPER_MODE_SPEED_OPTIMAL = 5, RPC_LOC_OPER_MODE_ACCURACY_OPTIMAL = 6, RPC_LOC_OPER_MODE_DATA_OPTIMAL = 7, RPC_LOC_OPER_MODE_CELL_ID = 8, RPC_LOC_OPER_MODE_MAX = 268435456 }; enum rpc_loc_notify_e_type { RPC_LOC_NOTIFY_ON_INTERVAL = 1, RPC_LOC_NOTIFY_ON_DISTANCE = 2, RPC_LOC_NOTIFY_ON_ANY = 3, RPC_LOC_NOTIFY_ON_ALL = 4, RPC_LOC_NOTIFY_TYPE_MAX = 268435456 }; struct rpc_loc_fix_criteria_s_type { rpc_uint32 valid_mask; rpc_loc_fix_recurrence_e_type recurrence_type; rpc_loc_operation_mode_e_type preferred_operation_mode; rpc_uint32 preferred_accuracy; rpc_uint32 preferred_response_time; rpc_boolean intermediate_pos_report_enabled; rpc_loc_notify_e_type notify_type; rpc_uint32 min_interval; float min_distance; rpc_uint32 min_dist_sample_interval; }; enum rpc_loc_ni_user_resp_e_type { RPC_LOC_NI_LCS_NOTIFY_VERIFY_ACCEPT = 1, RPC_LOC_NI_LCS_NOTIFY_VERIFY_DENY = 2, RPC_LOC_NI_LCS_NOTIFY_VERIFY_NORESP = 3, RPC_LOC_NI_LCS_NOTIFY_VERIFY_MAX = 268435456 }; struct rpc_loc_user_verify_s_type { rpc_loc_ni_user_resp_e_type user_resp; rpc_loc_ni_event_s_type ni_event_pass_back; }; enum rpc_loc_predicted_orbits_data_format_e_type { RPC_LOC_PREDICTED_ORBITS_XTRA = 0, RPC_LOC_PREDICTED_ORBITS_FORMAT_MAX = 268435456 }; struct rpc_loc_predicted_orbits_data_s_type { rpc_loc_predicted_orbits_data_format_e_type format_type; rpc_uint32 total_size; rpc_uint8 total_parts; rpc_uint8 part; rpc_uint16 part_len; opaque data_ptr<>; }; struct rpc_loc_predicted_orbits_data_validity_report_s_type { rpc_uint64 start_time_utc; rpc_uint16 valid_duration_hrs; }; struct rpc_loc_predicted_orbits_auto_download_config_s_type { rpc_boolean enable; unsigned char auto_check_every_hrs; }; struct rpc_loc_assist_data_time_s_type { rpc_uint64 time_utc; rpc_uint32 uncertainty; }; typedef rpc_uint64 rpc_loc_assist_pos_valid_mask_type; struct rpc_loc_assist_data_pos_s_type { rpc_loc_assist_pos_valid_mask_type valid_mask; rpc_uint64 timestamp_utc; double latitude; double longitude; float altitude_wrt_ellipsoid; float altitude_wrt_mean_sea_level; float hor_unc_circular; float vert_unc; unsigned char confidence_horizontal; unsigned char confidence_vertical; rpc_int32 timestamp_age; }; enum rpc_loc_server_open_status_e_type { RPC_LOC_SERVER_OPEN_SUCCESS = 1, RPC_LOC_SERVER_OPEN_FAIL = 2, RPC_LOC_SERVER_OPEN_STATUS_MAX = 268435456 }; enum rpc_loc_server_pdp_type_e_type { RPC_LOC_SERVER_PDP_IP = 0, RPC_LOC_SERVER_PDP_PPP, RPC_LOC_SERVER_PDP_IPV6, RPC_LOC_SERVER_PDP_IPV4V6, RPC_LOC_SERVER_PDP_MAX = 268435456 }; struct rpc_loc_server_open_status_s_type { rpc_loc_server_connection_handle conn_handle; rpc_loc_server_open_status_e_type open_status; opaque apn_name[100]; }; struct rpc_loc_server_multi_open_status_s_type { rpc_loc_server_connection_handle conn_handle; rpc_loc_server_open_status_e_type open_status; rpc_loc_server_pdp_type_e_type pdp_type; opaque apn_name[100]; }; enum rpc_loc_server_close_status_e_type { RPC_LOC_SERVER_CLOSE_SUCCESS = 1, RPC_LOC_SERVER_CLOSE_FAIL = 2, RPC_LOC_SERVER_CLOSE_STATUS_MAX = 268435456 }; struct rpc_loc_server_close_status_s_type { rpc_loc_server_connection_handle conn_handle; rpc_loc_server_close_status_e_type close_status; }; struct rpc_loc_wiper_fix_time_s_type { rpc_uint32 slow_clock_count; }; struct rpc_loc_wiper_fix_pos_s_type { rpc_int32 lat; rpc_int32 lon; rpc_uint16 HEPE; rpc_uint8 num_of_aps_used; rpc_uint8 fix_error_code; }; struct rpc_loc_wiper_ap_info_s_type { opaque mac_addr[6]; rpc_int32 rssi; rpc_uint16 channel; rpc_uint8 ap_qualifier; }; struct rpc_loc_wiper_ap_set_s_type { rpc_uint8 num_of_aps; rpc_loc_wiper_ap_info_s_type ap_info[50]; }; struct rpc_loc_wiper_position_report_s_type { rpc_uint8 wiper_valid_info_flag; rpc_loc_wiper_fix_time_s_type wiper_fix_time; rpc_loc_wiper_fix_pos_s_type wiper_fix_position; rpc_loc_wiper_ap_set_s_type wiper_ap_set; }; enum rpc_loc_wiper_status_e_type { RPC_LOC_WIPER_STATUS_AVAILABLE = 1, RPC_LOC_WIPER_STATUS_UNAVAILABLE = 2, RPC_LOC_WIPER_STATUS_E_SIZE = 268435456 }; enum rpc_loc_fs_operation_e_type { RPC_LOC_FS_CREATE_WRITE_FILE = 1, RPC_LOC_FS_APPEND_FILE = 2, RPC_LOC_FS_DELETE_FILE = 3, RPC_LOC_FS_READ_FILE = 4, RPC_LOC_FS_MAX = 268435456 }; struct rpc_loc_efs_data_s_type { opaque filename[64]; rpc_loc_fs_operation_e_type operation; rpc_uint32 total_size; opaque data_ptr<>; rpc_uint32 part_len; rpc_uint8 part; rpc_uint8 total_parts; rpc_uint32 reserved; }; enum rpc_loc_error_estimate_config_e_type { RPC_LOC_ERROR_ESTIMATE_CONFIG_SET = 1, RPC_LOC_ERROR_ESTIMATE_CONFIG_CLEAR = 2, RPC_LOC_ERROR_ESTIMATE_MAX = 268435456 }; struct rpc_loc_apn_profiles_type { rpc_uint32 srv_system_type; rpc_uint32 pdp_type; rpc_uint32 reserved; opaque apn_name[100]; }; enum rpc_loc_lock_e_type { RPC_LOC_LOCK_NONE = 1, RPC_LOC_LOCK_MI = 2, RPC_LOC_LOCK_MT = 3, RPC_LOC_LOCK_ALL = 4, RPC_LOC_LOCK_MAX = 268435456 }; typedef rpc_uint32 rpc_loc_nmea_sentence_type; typedef rpc_uint32 rpc_loc_assist_data_type; struct rpc_loc_assist_data_delete_s_type { rpc_loc_assist_data_type type; rpc_uint32 reserved[8]; }; union rpc_loc_ioctl_data_u_type switch (rpc_loc_ioctl_e_type disc) { case RPC_LOC_IOCTL_SET_FIX_CRITERIA: rpc_loc_fix_criteria_s_type fix_criteria; case RPC_LOC_IOCTL_INFORM_NI_USER_RESPONSE: rpc_loc_user_verify_s_type user_verify_resp; case RPC_LOC_IOCTL_INJECT_PREDICTED_ORBITS_DATA: rpc_loc_predicted_orbits_data_s_type predicted_orbits_data; case RPC_LOC_IOCTL_SET_PREDICTED_ORBITS_DATA_AUTO_DOWNLOAD: rpc_loc_predicted_orbits_auto_download_config_s_type predicted_orbits_auto_download; case RPC_LOC_IOCTL_INJECT_UTC_TIME: rpc_loc_assist_data_time_s_type assistance_data_time; case RPC_LOC_IOCTL_INJECT_POSITION: rpc_loc_assist_data_pos_s_type assistance_data_position; case RPC_LOC_IOCTL_INFORM_SERVER_OPEN_STATUS: rpc_loc_server_open_status_s_type conn_open_status; case RPC_LOC_IOCTL_INFORM_SERVER_CLOSE_STATUS: rpc_loc_server_close_status_s_type conn_close_status; case RPC_LOC_IOCTL_SEND_WIPER_POSITION_REPORT: rpc_loc_wiper_position_report_s_type wiper_pos; case RPC_LOC_IOCTL_NOTIFY_WIPER_STATUS: rpc_loc_wiper_status_e_type wiper_status; case RPC_LOC_IOCTL_SET_ENGINE_LOCK: rpc_loc_lock_e_type engine_lock; case RPC_LOC_IOCTL_SET_SBAS_CONFIG: rpc_boolean sbas_mode; case RPC_LOC_IOCTL_SET_NMEA_TYPES: rpc_loc_nmea_sentence_type nmea_types; case RPC_LOC_IOCTL_SET_ON_DEMAND_LPM: rpc_boolean on_demand_lpm; case RPC_LOC_IOCTL_SET_CDMA_PDE_SERVER_ADDR: case RPC_LOC_IOCTL_SET_CDMA_MPC_SERVER_ADDR: case RPC_LOC_IOCTL_SET_UMTS_SLP_SERVER_ADDR: case RPC_LOC_IOCTL_SET_CUSTOM_PDE_SERVER_ADDR: rpc_loc_server_info_s_type server_addr; case RPC_LOC_IOCTL_DELETE_ASSIST_DATA: rpc_loc_assist_data_delete_s_type assist_data_delete; case RPC_LOC_IOCTL_ACCESS_EFS_DATA: rpc_loc_efs_data_s_type efs_data; case RPC_LOC_IOCTL_ERROR_ESTIMATE_CONFIG: rpc_loc_error_estimate_config_e_type error_estimate_config; case RPC_LOC_IOCTL_SET_XTRA_T_SESSION_CONTROL: rpc_uint8 xtra_t_session_control; case RPC_LOC_IOCTL_SET_LBS_APN_PROFILE: case RPC_LOC_IOCTL_SET_XTRA_APN_PROFILE: rpc_loc_apn_profiles_type apn_profiles[6]; case RPC_LOC_IOCTL_SET_DATA_ENABLE: rpc_boolean data_enable; case RPC_LOC_IOCTL_SET_SUPL_VERSION: rpc_uint32 supl_version; case RPC_LOC_IOCTL_INFORM_SERVER_MULTI_OPEN_STATUS: rpc_loc_server_multi_open_status_s_type multi_conn_open_status; case RPC_LOC_IOCTL_RESERVED_CMD: rpc_loc_reserved_payload_s_type reserved; default: void; }; union rpc_loc_ioctl_callback_data_u_type switch (rpc_loc_ioctl_e_type disc) { case RPC_LOC_IOCTL_GET_API_VERSION: rpc_loc_api_version_s_type api_version; case RPC_LOC_IOCTL_GET_FIX_CRITERIA: rpc_loc_fix_criteria_s_type fix_criteria; case RPC_LOC_IOCTL_GET_ENGINE_LOCK: rpc_loc_lock_e_type engine_lock; case RPC_LOC_IOCTL_GET_SBAS_CONFIG: rpc_boolean sbas_mode; case RPC_LOC_IOCTL_GET_NMEA_TYPES: rpc_loc_nmea_sentence_type nmea_types; case RPC_LOC_IOCTL_GET_ON_DEMAND_LPM: rpc_boolean on_demand_lpm; case RPC_LOC_IOCTL_GET_CDMA_PDE_SERVER_ADDR: case RPC_LOC_IOCTL_GET_CDMA_MPC_SERVER_ADDR: case RPC_LOC_IOCTL_GET_UMTS_SLP_SERVER_ADDR: case RPC_LOC_IOCTL_GET_CUSTOM_PDE_SERVER_ADDR: rpc_loc_server_info_s_type server_addr; case RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_SOURCE: rpc_loc_predicted_orbits_data_source_s_type predicted_orbits_data_source; case RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_VALIDITY: rpc_loc_predicted_orbits_data_validity_report_s_type predicted_orbits_data_validity; case RPC_LOC_IOCTL_GET_XTRA_T_SESSION_CONTROL: rpc_uint8 xtra_t_session_control; case RPC_LOC_IOCTL_GET_LBS_APN_PROFILE: case RPC_LOC_IOCTL_GET_XTRA_APN_PROFILE: rpc_loc_apn_profiles_type apn_profiles[6]; case RPC_LOC_IOCTL_GET_SUPL_VERSION: rpc_uint32 supl_version; default: void; }; struct rpc_loc_ioctl_callback_s_type { rpc_loc_ioctl_e_type type; rpc_int32 status; rpc_loc_ioctl_callback_data_u_type data; }; union rpc_loc_event_payload_u_type switch (unsigned hyper disc) { case RPC_LOC_EVENT_PARSED_POSITION_REPORT: rpc_loc_parsed_position_s_type parsed_location_report; case RPC_LOC_EVENT_SATELLITE_REPORT: rpc_loc_gnss_info_s_type gnss_report; case RPC_LOC_EVENT_NMEA_POSITION_REPORT: case RPC_LOC_EVENT_NMEA_1HZ_REPORT: rpc_loc_nmea_report_s_type nmea_report; case RPC_LOC_EVENT_NI_NOTIFY_VERIFY_REQUEST: rpc_loc_ni_event_s_type ni_request; case RPC_LOC_EVENT_ASSISTANCE_DATA_REQUEST: rpc_loc_assist_data_request_s_type assist_data_request; case RPC_LOC_EVENT_LOCATION_SERVER_REQUEST: rpc_loc_server_request_s_type loc_server_request; case RPC_LOC_EVENT_IOCTL_REPORT: rpc_loc_ioctl_callback_s_type ioctl_report; case RPC_LOC_EVENT_STATUS_REPORT: rpc_loc_status_event_s_type status_report; case RPC_LOC_EVENT_WPS_NEEDED_REQUEST: rpc_loc_qwip_request_s_type qwip_request; case RPC_LOC_EVENT_RESERVED: rpc_loc_reserved_payload_s_type reserved; default: void; }; ================================================ FILE: gps/loc_api/libloc_api_50001/Android.mk ================================================ ifneq ($(BUILD_TINY_ANDROID),true) #Compile this library only for builds with the latest modem image LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := libloc_eng LOCAL_MODULE_OWNER := qcom LOCAL_MODULE_TAGS := optional LOCAL_SHARED_LIBRARIES := \ libutils \ libcutils \ libdl \ liblog \ libloc_core \ libgps.utils LOCAL_SRC_FILES += \ loc_eng.cpp \ loc_eng_agps.cpp \ loc_eng_xtra.cpp \ loc_eng_ni.cpp \ loc_eng_log.cpp \ loc_eng_nmea.cpp \ LocEngAdapter.cpp LOCAL_SRC_FILES += \ loc_eng_dmn_conn.cpp \ loc_eng_dmn_conn_handler.cpp \ loc_eng_dmn_conn_thread_helper.c \ loc_eng_dmn_conn_glue_msg.c \ loc_eng_dmn_conn_glue_pipe.c LOCAL_CFLAGS += \ -fno-short-enums \ -D_ANDROID_ LOCAL_C_INCLUDES:= \ $(TARGET_OUT_HEADERS)/gps.utils \ $(TARGET_OUT_HEADERS)/libloc_core \ $(LOCAL_PATH) \ $(TARGET_OUT_HEADERS)/libflp LOCAL_COPY_HEADERS_TO:= libloc_eng/ LOCAL_COPY_HEADERS:= \ LocEngAdapter.h \ loc.h \ loc_eng.h \ loc_eng_xtra.h \ loc_eng_ni.h \ loc_eng_agps.h \ loc_eng_msg.h \ loc_eng_log.h LOCAL_PRELINK_MODULE := false include $(BUILD_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := gps.$(TARGET_BOARD_PLATFORM) LOCAL_MODULE_OWNER := qcom LOCAL_MODULE_TAGS := optional ## Libs LOCAL_SHARED_LIBRARIES := \ libutils \ libcutils \ liblog \ libloc_eng \ libloc_core \ libgps.utils \ libdl ifneq ($(filter $(TARGET_DEVICE), apq8084 msm8960), false) endif LOCAL_SRC_FILES += \ loc.cpp \ gps.c LOCAL_CFLAGS += \ -fno-short-enums \ -D_ANDROID_ \ ifeq ($(TARGET_USES_QCOM_BSP), true) LOCAL_CFLAGS += -DTARGET_USES_QCOM_BSP endif ## Includes LOCAL_C_INCLUDES:= \ $(TARGET_OUT_HEADERS)/gps.utils \ $(TARGET_OUT_HEADERS)/libloc_core \ $(TARGET_OUT_HEADERS)/libflp LOCAL_PRELINK_MODULE := false LOCAL_MODULE_RELATIVE_PATH := hw include $(BUILD_SHARED_LIBRARY) endif # not BUILD_TINY_ANDROID ================================================ FILE: gps/loc_api/libloc_api_50001/LocEngAdapter.cpp ================================================ /* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #define LOG_NDDEBUG 0 #define LOG_TAG "LocSvc_EngAdapter" #include #include #include #include #include #include "loc_eng_msg.h" #include "loc_log.h" #define CHIPSET_SERIAL_NUMBER_MAX_LEN 16 #define USER_AGENT_MAX_LEN 512 using namespace loc_core; LocInternalAdapter::LocInternalAdapter(LocEngAdapter* adapter) : LocAdapterBase(adapter->getMsgTask()), mLocEngAdapter(adapter) { } void LocInternalAdapter::setPositionModeInt(LocPosMode& posMode) { sendMsg(new LocEngPositionMode(mLocEngAdapter, posMode)); } void LocInternalAdapter::startFixInt() { sendMsg(new LocEngStartFix(mLocEngAdapter)); } void LocInternalAdapter::stopFixInt() { sendMsg(new LocEngStopFix(mLocEngAdapter)); } void LocInternalAdapter::getZppInt() { sendMsg(new LocEngGetZpp(mLocEngAdapter)); } LocEngAdapter::LocEngAdapter(LOC_API_ADAPTER_EVENT_MASK_T mask, void* owner, ContextBase* context, LocThread::tCreate tCreator) : LocAdapterBase(mask, //Get the AFW context if VzW context has not already been intialized in //loc_ext context == NULL? LocDualContext::getLocFgContext(tCreator, NULL, LocDualContext::mLocationHalName, false) :context), mOwner(owner), mInternalAdapter(new LocInternalAdapter(this)), mUlp(new UlpProxyBase()), mNavigating(false), mSupportsAgpsRequests(false), mSupportsPositionInjection(false), mSupportsTimeInjection(false), mPowerVote(0) { memset(&mFixCriteria, 0, sizeof(mFixCriteria)); mFixCriteria.mode = LOC_POSITION_MODE_INVALID; LOC_LOGD("LocEngAdapter created"); } inline LocEngAdapter::~LocEngAdapter() { delete mInternalAdapter; LOC_LOGV("LocEngAdapter deleted"); } void LocEngAdapter::setXtraUserAgent() { struct LocSetXtraUserAgent : public LocMsg { const ContextBase* const mContext; inline LocSetXtraUserAgent(ContextBase* context) : LocMsg(), mContext(context) { } virtual void proc() const { char release[PROPERTY_VALUE_MAX]; char manufacture[PROPERTY_VALUE_MAX]; char model[PROPERTY_VALUE_MAX]; char carrier[PROPERTY_VALUE_MAX]; char board[PROPERTY_VALUE_MAX]; char brand[PROPERTY_VALUE_MAX]; char chipsetsn[CHIPSET_SERIAL_NUMBER_MAX_LEN]; char userAgent[USER_AGENT_MAX_LEN]; const char defVal[] = "-"; property_get("ro.build.version.release", release, defVal); property_get("ro.product.manufacturer", manufacture, defVal); property_get("ro.product.model", model, defVal); property_get("ro.carrier", carrier, defVal); property_get("ro.product.board", board, defVal); property_get("ro.product.brand", brand, defVal); getChipsetSerialNo(chipsetsn, sizeof(chipsetsn), defVal); snprintf(userAgent, sizeof(userAgent), "A/%s/%s/%s/%s/%s/QCX3/s%u/-/%s/-/%s/-/-/-", release, manufacture, model, board, carrier, mContext->getIzatDevId(), chipsetsn, brand); for (int i = 0; i < sizeof(userAgent) && userAgent[i]; i++) { if (' ' == userAgent[i]) userAgent[i] = '#'; } saveUserAgentString(userAgent, strlen(userAgent)); LOC_LOGV("%s] UserAgent %s", __func__, userAgent); } void saveUserAgentString(const char* data, const int len) const { const char XTRA_FOLDER[] = "/data/misc/location/xtra"; const char USER_AGENT_FILE[] = "/data/misc/location/xtra/useragent.txt"; if (data == NULL || len < 1) { LOC_LOGE("%s:%d]: invalid input data = %p len = %d", __func__, __LINE__, data, len); return; } struct stat s; int err = stat(XTRA_FOLDER, &s); if (err < 0) { if (ENOENT == errno) { if (mkdir(XTRA_FOLDER, 0700) < 0) { LOC_LOGE("%s:%d]: make XTRA_FOLDER failed", __func__, __LINE__); return; } } else { LOC_LOGE("%s:%d]: XTRA_FOLDER invalid", __func__, __LINE__); return; } } FILE* file = fopen(USER_AGENT_FILE, "wt"); if (file == NULL) { LOC_LOGE("%s:%d]: open USER_AGENT_FILE failed", __func__, __LINE__); return; } size_t written = fwrite(data, 1, len, file); fclose(file); file = NULL; // set file permission chmod(USER_AGENT_FILE, 0600); if (written != len) { LOC_LOGE("%s:%d]: write USER_AGENT_FILE failed", __func__, __LINE__); } } void getChipsetSerialNo(char buf[], int buflen, const char def[]) const { const char SOC_SERIAL_NUMBER[] = "/sys/devices/soc0/serial_number"; FILE* file = fopen(SOC_SERIAL_NUMBER, "rt"); if (file == NULL) { // use default upon unreadable file strlcpy(buf, def, buflen); } else { size_t size = fread(buf, 1, buflen - 1, file); if (size == 0) { // use default upon empty file strlcpy(buf, def, buflen); } else { buf[size] = '\0'; } fclose(file); // remove trailing spaces size_t len = strlen(buf); while (--len >= 0 && isspace(buf[len])) { buf[len] = '\0'; } } return; } }; sendMsg(new LocSetXtraUserAgent(mContext)); } void LocInternalAdapter::setUlpProxy(UlpProxyBase* ulp) { struct LocSetUlpProxy : public LocMsg { LocAdapterBase* mAdapter; UlpProxyBase* mUlp; inline LocSetUlpProxy(LocAdapterBase* adapter, UlpProxyBase* ulp) : LocMsg(), mAdapter(adapter), mUlp(ulp) { } virtual void proc() const { LOC_LOGV("%s] ulp %p adapter %p", __func__, mUlp, mAdapter); mAdapter->setUlpProxy(mUlp); } }; sendMsg(new LocSetUlpProxy(mLocEngAdapter, ulp)); } void LocEngAdapter::setUlpProxy(UlpProxyBase* ulp) { if (ulp == mUlp) { //This takes care of the case when double initalization happens //and we get the same object back for UlpProxyBase . Do nothing return; } LOC_LOGV("%s] %p", __func__, ulp); if (NULL == ulp) { LOC_LOGE("%s:%d]: ulp pointer is NULL", __func__, __LINE__); ulp = new UlpProxyBase(); } if (LOC_POSITION_MODE_INVALID != mUlp->mPosMode.mode) { // need to send this mode and start msg to ULP ulp->sendFixMode(mUlp->mPosMode); } if(mUlp->mFixSet) { ulp->sendStartFix(); } delete mUlp; mUlp = ulp; } int LocEngAdapter::setGpsLockMsg(LOC_GPS_LOCK_MASK lockMask) { struct LocEngAdapterGpsLock : public LocMsg { LocEngAdapter* mAdapter; LOC_GPS_LOCK_MASK mLockMask; inline LocEngAdapterGpsLock(LocEngAdapter* adapter, LOC_GPS_LOCK_MASK lockMask) : LocMsg(), mAdapter(adapter), mLockMask(lockMask) { locallog(); } inline virtual void proc() const { mAdapter->setGpsLock(mLockMask); } inline void locallog() const { LOC_LOGV("LocEngAdapterGpsLock - mLockMask: %x", mLockMask); } inline virtual void log() const { locallog(); } }; sendMsg(new LocEngAdapterGpsLock(this, lockMask)); return 0; } void LocEngAdapter::requestPowerVote() { if (getPowerVoteRight()) { /* Power voting without engine lock: * 101: vote down, 102-104 - vote up * These codes are used not to confuse with actual engine lock * functionality, that can't be used in SSR scenario, as it * conflicts with initialization sequence. */ bool powerUp = getPowerVote(); LOC_LOGV("LocEngAdapterVotePower - Vote Power: %d", (int)powerUp); setGpsLock(powerUp ? 103 : 101); } } void LocInternalAdapter::reportPosition(UlpLocation &location, GpsLocationExtended &locationExtended, void* locationExt, enum loc_sess_status status, LocPosTechMask loc_technology_mask) { sendMsg(new LocEngReportPosition(mLocEngAdapter, location, locationExtended, locationExt, status, loc_technology_mask)); } void LocEngAdapter::reportPosition(UlpLocation &location, GpsLocationExtended &locationExtended, void* locationExt, enum loc_sess_status status, LocPosTechMask loc_technology_mask) { if (! mUlp->reportPosition(location, locationExtended, locationExt, status, loc_technology_mask )) { mInternalAdapter->reportPosition(location, locationExtended, locationExt, status, loc_technology_mask); } } void LocInternalAdapter::reportSv(QcomSvStatus &svStatus, GpsLocationExtended &locationExtended, void* svExt){ sendMsg(new LocEngReportSv(mLocEngAdapter, svStatus, locationExtended, svExt)); } void LocEngAdapter::reportSv(QcomSvStatus &svStatus, GpsLocationExtended &locationExtended, void* svExt) { // We want to send SV info to ULP to help it in determining GNSS // signal strength ULP will forward the SV reports to HAL without // any modifications if (! mUlp->reportSv(svStatus, locationExtended, svExt)) { mInternalAdapter->reportSv(svStatus, locationExtended, svExt); } } void LocEngAdapter::setInSession(bool inSession) { mNavigating = inSession; mLocApi->setInSession(inSession); if (!mNavigating) { mFixCriteria.mode = LOC_POSITION_MODE_INVALID; } } void LocInternalAdapter::reportStatus(GpsStatusValue status) { sendMsg(new LocEngReportStatus(mLocEngAdapter, status)); } void LocEngAdapter::reportStatus(GpsStatusValue status) { if (!mUlp->reportStatus(status)) { mInternalAdapter->reportStatus(status); } } inline void LocEngAdapter::reportNmea(const char* nmea, int length) { sendMsg(new LocEngReportNmea(mOwner, nmea, length)); } inline bool LocEngAdapter::reportXtraServer(const char* url1, const char* url2, const char* url3, const int maxlength) { if (mSupportsAgpsRequests) { sendMsg(new LocEngReportXtraServer(mOwner, url1, url2, url3, maxlength)); } return mSupportsAgpsRequests; } inline bool LocEngAdapter::requestATL(int connHandle, AGpsType agps_type) { if (mSupportsAgpsRequests) { sendMsg(new LocEngRequestATL(mOwner, connHandle, agps_type)); } return mSupportsAgpsRequests; } inline bool LocEngAdapter::releaseATL(int connHandle) { if (mSupportsAgpsRequests) { sendMsg(new LocEngReleaseATL(mOwner, connHandle)); } return mSupportsAgpsRequests; } inline bool LocEngAdapter::requestXtraData() { if (mSupportsAgpsRequests) { sendMsg(new LocEngRequestXtra(mOwner)); } return mSupportsAgpsRequests; } inline bool LocEngAdapter::requestTime() { if (mSupportsAgpsRequests) { sendMsg(new LocEngRequestTime(mOwner)); } return mSupportsAgpsRequests; } inline bool LocEngAdapter::requestNiNotify(GpsNiNotification ¬if, const void* data) { if (mSupportsAgpsRequests) { notif.size = sizeof(notif); notif.timeout = LOC_NI_NO_RESPONSE_TIME; sendMsg(new LocEngRequestNi(mOwner, notif, data)); } return mSupportsAgpsRequests; } inline bool LocEngAdapter::requestSuplES(int connHandle) { if (mSupportsAgpsRequests) sendMsg(new LocEngRequestSuplEs(mOwner, connHandle)); return mSupportsAgpsRequests; } inline bool LocEngAdapter::reportDataCallOpened() { if(mSupportsAgpsRequests) sendMsg(new LocEngSuplEsOpened(mOwner)); return mSupportsAgpsRequests; } inline bool LocEngAdapter::reportDataCallClosed() { if(mSupportsAgpsRequests) sendMsg(new LocEngSuplEsClosed(mOwner)); return mSupportsAgpsRequests; } inline void LocEngAdapter::handleEngineDownEvent() { sendMsg(new LocEngDown(mOwner)); } inline void LocEngAdapter::handleEngineUpEvent() { sendMsg(new LocEngUp(mOwner)); } enum loc_api_adapter_err LocEngAdapter::setTime(GpsUtcTime time, int64_t timeReference, int uncertainty) { loc_api_adapter_err result = LOC_API_ADAPTER_ERR_SUCCESS; LOC_LOGD("%s:%d]: mSupportsTimeInjection is %d", __func__, __LINE__, mSupportsTimeInjection); if (mSupportsTimeInjection) { LOC_LOGD("%s:%d]: Injecting time", __func__, __LINE__); result = mLocApi->setTime(time, timeReference, uncertainty); } else { mSupportsTimeInjection = true; } return result; } enum loc_api_adapter_err LocEngAdapter::setXtraVersionCheck(int check) { enum loc_api_adapter_err ret; ENTRY_LOG(); enum xtra_version_check eCheck; switch (check) { case 0: eCheck = DISABLED; break; case 1: eCheck = AUTO; break; case 2: eCheck = XTRA2; break; case 3: eCheck = XTRA3; break; default: eCheck = DISABLED; } ret = mLocApi->setXtraVersionCheck(eCheck); EXIT_LOG(%d, ret); return ret; } void LocEngAdapter::reportGpsMeasurementData(GpsData &gpsMeasurementData) { sendMsg(new LocEngReportGpsMeasurement(mOwner, gpsMeasurementData)); } /* Update Registration Mask */ void LocEngAdapter::updateRegistrationMask(LOC_API_ADAPTER_EVENT_MASK_T event, loc_registration_mask_status isEnabled) { LOC_LOGD("entering %s", __func__); int result = LOC_API_ADAPTER_ERR_FAILURE; result = mLocApi->updateRegistrationMask(event, isEnabled); if (result == LOC_API_ADAPTER_ERR_SUCCESS) { LOC_LOGD("%s] update registration mask succeed.", __func__); } else { LOC_LOGE("%s] update registration mask failed.", __func__); } } /* Set Gnss Constellation Config */ bool LocEngAdapter::gnssConstellationConfig() { LOC_LOGD("entering %s", __func__); bool result = false; result = mLocApi->gnssConstellationConfig(); return result; } ================================================ FILE: gps/loc_api/libloc_api_50001/LocEngAdapter.h ================================================ /* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef LOC_API_ENG_ADAPTER_H #define LOC_API_ENG_ADAPTER_H #include #include #include #include #include #include #include #include #include #define MAX_URL_LEN 256 using namespace loc_core; class LocEngAdapter; class LocInternalAdapter : public LocAdapterBase { LocEngAdapter* mLocEngAdapter; public: LocInternalAdapter(LocEngAdapter* adapter); virtual void reportPosition(UlpLocation &location, GpsLocationExtended &locationExtended, void* locationExt, enum loc_sess_status status, LocPosTechMask loc_technology_mask); virtual void reportSv(QcomSvStatus &svStatus, GpsLocationExtended &locationExtended, void* svExt); virtual void reportStatus(GpsStatusValue status); virtual void setPositionModeInt(LocPosMode& posMode); virtual void startFixInt(); virtual void stopFixInt(); virtual void getZppInt(); virtual void setUlpProxy(UlpProxyBase* ulp); }; typedef void (*loc_msg_sender)(void* loc_eng_data_p, void* msgp); class LocEngAdapter : public LocAdapterBase { void* mOwner; LocInternalAdapter* mInternalAdapter; UlpProxyBase* mUlp; LocPosMode mFixCriteria; bool mNavigating; // mPowerVote is encoded as // mPowerVote & 0x20 -- powerVoteRight // mPowerVote & 0x10 -- power On / Off unsigned int mPowerVote; static const unsigned int POWER_VOTE_RIGHT = 0x20; static const unsigned int POWER_VOTE_VALUE = 0x10; public: bool mSupportsAgpsRequests; bool mSupportsPositionInjection; bool mSupportsTimeInjection; LocEngAdapter(LOC_API_ADAPTER_EVENT_MASK_T mask, void* owner, ContextBase* context, LocThread::tCreate tCreator); virtual ~LocEngAdapter(); virtual void setUlpProxy(UlpProxyBase* ulp); void setXtraUserAgent(); inline void requestUlp(unsigned long capabilities) { mContext->requestUlp(mInternalAdapter, capabilities); } inline LocInternalAdapter* getInternalAdapter() { return mInternalAdapter; } inline UlpProxyBase* getUlpProxy() { return mUlp; } inline void* getOwner() { return mOwner; } inline bool hasAgpsExtendedCapabilities() { return mContext->hasAgpsExtendedCapabilities(); } inline bool hasCPIExtendedCapabilities() { return mContext->hasCPIExtendedCapabilities(); } inline const MsgTask* getMsgTask() { return mMsgTask; } inline enum loc_api_adapter_err startFix() { return mLocApi->startFix(mFixCriteria); } inline enum loc_api_adapter_err stopFix() { return mLocApi->stopFix(); } inline enum loc_api_adapter_err deleteAidingData(GpsAidingData f) { return mLocApi->deleteAidingData(f); } inline enum loc_api_adapter_err enableData(int enable) { return mLocApi->enableData(enable); } inline enum loc_api_adapter_err setAPN(char* apn, int len) { return mLocApi->setAPN(apn, len); } inline enum loc_api_adapter_err injectPosition(double latitude, double longitude, float accuracy) { return mLocApi->injectPosition(latitude, longitude, accuracy); } inline enum loc_api_adapter_err setXtraData(char* data, int length) { return mLocApi->setXtraData(data, length); } inline enum loc_api_adapter_err requestXtraServer() { return mLocApi->requestXtraServer(); } inline enum loc_api_adapter_err atlOpenStatus(int handle, int is_succ, char* apn, AGpsBearerType bearer, AGpsType agpsType) { return mLocApi->atlOpenStatus(handle, is_succ, apn, bearer, agpsType); } inline enum loc_api_adapter_err atlCloseStatus(int handle, int is_succ) { return mLocApi->atlCloseStatus(handle, is_succ); } inline enum loc_api_adapter_err setPositionMode(const LocPosMode *posMode) { if (NULL != posMode) { mFixCriteria = *posMode; } return mLocApi->setPositionMode(mFixCriteria); } inline enum loc_api_adapter_err setServer(const char* url, int len) { return mLocApi->setServer(url, len); } inline enum loc_api_adapter_err setServer(unsigned int ip, int port, LocServerType type) { return mLocApi->setServer(ip, port, type); } inline enum loc_api_adapter_err informNiResponse(GpsUserResponseType userResponse, const void* passThroughData) { return mLocApi->informNiResponse(userResponse, passThroughData); } inline enum loc_api_adapter_err setSUPLVersion(uint32_t version) { return mLocApi->setSUPLVersion(version); } inline enum loc_api_adapter_err setLPPConfig(uint32_t profile) { return mLocApi->setLPPConfig(profile); } inline enum loc_api_adapter_err setSensorControlConfig(int sensorUsage, int sensorProvider) { return mLocApi->setSensorControlConfig(sensorUsage, sensorProvider); } inline enum loc_api_adapter_err setSensorProperties(bool gyroBiasVarianceRandomWalk_valid, float gyroBiasVarianceRandomWalk, bool accelBiasVarianceRandomWalk_valid, float accelBiasVarianceRandomWalk, bool angleBiasVarianceRandomWalk_valid, float angleBiasVarianceRandomWalk, bool rateBiasVarianceRandomWalk_valid, float rateBiasVarianceRandomWalk, bool velocityBiasVarianceRandomWalk_valid, float velocityBiasVarianceRandomWalk) { return mLocApi->setSensorProperties(gyroBiasVarianceRandomWalk_valid, gyroBiasVarianceRandomWalk, accelBiasVarianceRandomWalk_valid, accelBiasVarianceRandomWalk, angleBiasVarianceRandomWalk_valid, angleBiasVarianceRandomWalk, rateBiasVarianceRandomWalk_valid, rateBiasVarianceRandomWalk, velocityBiasVarianceRandomWalk_valid, velocityBiasVarianceRandomWalk); } inline virtual enum loc_api_adapter_err setSensorPerfControlConfig(int controlMode, int accelSamplesPerBatch, int accelBatchesPerSec, int gyroSamplesPerBatch, int gyroBatchesPerSec, int accelSamplesPerBatchHigh, int accelBatchesPerSecHigh, int gyroSamplesPerBatchHigh, int gyroBatchesPerSecHigh, int algorithmConfig) { return mLocApi->setSensorPerfControlConfig(controlMode, accelSamplesPerBatch, accelBatchesPerSec, gyroSamplesPerBatch, gyroBatchesPerSec, accelSamplesPerBatchHigh, accelBatchesPerSecHigh, gyroSamplesPerBatchHigh, gyroBatchesPerSecHigh, algorithmConfig); } inline virtual enum loc_api_adapter_err setExtPowerConfig(int isBatteryCharging) { return mLocApi->setExtPowerConfig(isBatteryCharging); } inline virtual enum loc_api_adapter_err setAGLONASSProtocol(unsigned long aGlonassProtocol) { return mLocApi->setAGLONASSProtocol(aGlonassProtocol); } inline virtual int initDataServiceClient() { return mLocApi->initDataServiceClient(); } inline virtual int openAndStartDataCall() { return mLocApi->openAndStartDataCall(); } inline virtual void stopDataCall() { mLocApi->stopDataCall(); } inline virtual void closeDataCall() { mLocApi->closeDataCall(); } inline enum loc_api_adapter_err getZpp(GpsLocation &zppLoc, LocPosTechMask &tech_mask) { return mLocApi->getBestAvailableZppFix(zppLoc, tech_mask); } enum loc_api_adapter_err setTime(GpsUtcTime time, int64_t timeReference, int uncertainty); enum loc_api_adapter_err setXtraVersionCheck(int check); inline virtual void installAGpsCert(const DerEncodedCertificate* pData, size_t length, uint32_t slotBitMask) { mLocApi->installAGpsCert(pData, length, slotBitMask); } virtual void handleEngineDownEvent(); virtual void handleEngineUpEvent(); virtual void reportPosition(UlpLocation &location, GpsLocationExtended &locationExtended, void* locationExt, enum loc_sess_status status, LocPosTechMask loc_technology_mask); virtual void reportSv(QcomSvStatus &svStatus, GpsLocationExtended &locationExtended, void* svExt); virtual void reportStatus(GpsStatusValue status); virtual void reportNmea(const char* nmea, int length); virtual bool reportXtraServer(const char* url1, const char* url2, const char* url3, const int maxlength); virtual bool requestXtraData(); virtual bool requestTime(); virtual bool requestATL(int connHandle, AGpsType agps_type); virtual bool releaseATL(int connHandle); virtual bool requestNiNotify(GpsNiNotification ¬ify, const void* data); virtual bool requestSuplES(int connHandle); virtual bool reportDataCallOpened(); virtual bool reportDataCallClosed(); virtual void reportGpsMeasurementData(GpsData &gpsMeasurementData); inline const LocPosMode& getPositionMode() const {return mFixCriteria;} inline virtual bool isInSession() { return mNavigating; } void setInSession(bool inSession); // Permit/prohibit power voting inline void setPowerVoteRight(bool powerVoteRight) { mPowerVote = powerVoteRight ? (mPowerVote | POWER_VOTE_RIGHT) : (mPowerVote & ~POWER_VOTE_RIGHT); } inline bool getPowerVoteRight() const { return (mPowerVote & POWER_VOTE_RIGHT) != 0 ; } // Set the power voting up/down and do actual operation if permitted inline void setPowerVote(bool powerOn) { mPowerVote = powerOn ? (mPowerVote | POWER_VOTE_VALUE) : (mPowerVote & ~POWER_VOTE_VALUE); requestPowerVote(); mContext->modemPowerVote(powerOn); } inline bool getPowerVote() const { return (mPowerVote & POWER_VOTE_VALUE) != 0 ; } // Do power voting according to last settings if permitted void requestPowerVote(); /*Values for lock 1 = Do not lock any position sessions 2 = Lock MI position sessions 3 = Lock MT position sessions 4 = Lock all position sessions */ inline int setGpsLock(LOC_GPS_LOCK_MASK lock) { return mLocApi->setGpsLock(lock); } int setGpsLockMsg(LOC_GPS_LOCK_MASK lock); /* Returns Current value of GPS lock on success -1 on failure */ inline int getGpsLock() { return mLocApi->getGpsLock(); } /* Update Registration Mask */ void updateRegistrationMask(LOC_API_ADAPTER_EVENT_MASK_T event, loc_registration_mask_status isEnabled); /* Set Gnss Constellation Config */ bool gnssConstellationConfig(); }; #endif //LOC_API_ENG_ADAPTER_H ================================================ FILE: gps/loc_api/libloc_api_50001/Makefile.am ================================================ AM_CFLAGS = \ -I../../utils \ -I../../platform_lib_abstractions \ -fno-short-enums \ -DFEATURE_GNSS_BIT_API libloc_adapter_so_la_SOURCES = loc_eng_log.cpp LocEngAdapter.cpp if USE_GLIB libloc_adapter_so_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@ libloc_adapter_so_la_LDFLAGS = -lstdc++ -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0 libloc_adapter_so_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@ else libloc_adapter_so_la_CFLAGS = $(AM_CFLAGS) libloc_adapter_so_la_LDFLAGS = -lpthread -shared -version-info 1:0:0 libloc_adapter_so_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS) endif libloc_adapter_so_la_LIBADD = -lstdc++ -lcutils ../../utils/libgps_utils_so.la libloc_eng_so_la_SOURCES = \ loc_eng.cpp \ loc_eng_agps.cpp \ loc_eng_xtra.cpp \ loc_eng_ni.cpp \ loc_eng_log.cpp \ loc_eng_dmn_conn.cpp \ loc_eng_dmn_conn_handler.cpp \ loc_eng_dmn_conn_thread_helper.c \ loc_eng_dmn_conn_glue_msg.c \ loc_eng_dmn_conn_glue_pipe.c if USE_GLIB libloc_eng_so_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@ libloc_eng_so_la_LDFLAGS = -lstdc++ -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0 libloc_eng_so_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@ else libloc_eng_so_la_CFLAGS = $(AM_CFLAGS) libloc_eng_so_la_LDFLAGS = -lpthread -shared -version-info 1:0:0 libloc_eng_so_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS) endif libloc_eng_so_la_LIBADD = -lstdc++ -lcutils -ldl ../../utils/libgps_utils_so.la libloc_adapter_so.la libgps_default_so_la_SOURCES = \ loc.cpp \ gps.c if USE_GLIB libgps_default_so_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@ libgps_default_so_la_LDFLAGS = -lstdc++ -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0 libgps_default_so_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@ else libgps_default_so_la_CFLAGS = $(AM_CFLAGS) libgps_default_so_la_LDFLAGS = -lpthread -shared -version-info 1:0:0 libgps_default_so_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS) endif libgps_default_so_la_LIBADD = -lstdc++ -lcutils ../../utils/libgps_utils_so.la -ldl libloc_eng_so.la library_include_HEADERS = \ LocEngAdapter.h \ loc.h \ loc_eng.h \ loc_eng_xtra.h \ loc_eng_ni.h \ loc_eng_agps.h \ loc_eng_msg.h \ loc_eng_log.h library_includedir = $(pkgincludedir)/libloc_api_50001 #Create and Install libraries lib_LTLIBRARIES = libloc_adapter_so.la libloc_eng_so.la libgps_default_so.la ================================================ FILE: gps/loc_api/libloc_api_50001/gps.c ================================================ /* Copyright (c) 2011,2015 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include extern const GpsInterface* get_gps_interface(); const GpsInterface* gps__get_gps_interface(struct gps_device_t* dev) { return get_gps_interface(); } static int open_gps(const struct hw_module_t* module, char const* name, struct hw_device_t** device) { struct gps_device_t *dev = (struct gps_device_t *) malloc(sizeof(struct gps_device_t)); if(dev == NULL) return -1; memset(dev, 0, sizeof(*dev)); dev->common.tag = HARDWARE_DEVICE_TAG; dev->common.version = 0; dev->common.module = (struct hw_module_t*)module; dev->get_gps_interface = gps__get_gps_interface; *device = (struct hw_device_t*)dev; return 0; } static struct hw_module_methods_t gps_module_methods = { .open = open_gps }; struct hw_module_t HAL_MODULE_INFO_SYM = { .tag = HARDWARE_MODULE_TAG, .module_api_version = 1, .hal_api_version = 0, .id = GPS_HARDWARE_MODULE_ID, .name = "loc_api GPS Module", .author = "Qualcomm USA, Inc.", .methods = &gps_module_methods, }; ================================================ FILE: gps/loc_api/libloc_api_50001/loc.cpp ================================================ /* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #define LOG_NDDEBUG 0 #define LOG_TAG "LocSvc_afw" #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace loc_core; #define LOC_PM_CLIENT_NAME "GPS" //Globals defns static gps_location_callback gps_loc_cb = NULL; static gps_sv_status_callback gps_sv_cb = NULL; static void local_loc_cb(UlpLocation* location, void* locExt); static void local_sv_cb(GpsSvStatus* sv_status, void* svExt); static const GpsGeofencingInterface* get_geofence_interface(void); // Function declarations for sLocEngInterface static int loc_init(GpsCallbacks* callbacks); static int loc_start(); static int loc_stop(); static void loc_cleanup(); static int loc_inject_time(GpsUtcTime time, int64_t timeReference, int uncertainty); static int loc_inject_location(double latitude, double longitude, float accuracy); static void loc_delete_aiding_data(GpsAidingData f); static int loc_set_position_mode(GpsPositionMode mode, GpsPositionRecurrence recurrence, uint32_t min_interval, uint32_t preferred_accuracy, uint32_t preferred_time); static const void* loc_get_extension(const char* name); // Defines the GpsInterface in gps.h static const GpsInterface sLocEngInterface = { sizeof(GpsInterface), loc_init, loc_start, loc_stop, loc_cleanup, loc_inject_time, loc_inject_location, loc_delete_aiding_data, loc_set_position_mode, loc_get_extension }; // Function declarations for sLocEngAGpsInterface static void loc_agps_init(AGpsCallbacks* callbacks); static int loc_agps_open(const char* apn); static int loc_agps_closed(); static int loc_agps_open_failed(); static int loc_agps_set_server(AGpsType type, const char *hostname, int port); static int loc_agps_open_with_apniptype( const char* apn, ApnIpType apnIpType); static const AGpsInterface sLocEngAGpsInterface = { sizeof(AGpsInterface), loc_agps_init, loc_agps_open, loc_agps_closed, loc_agps_open_failed, loc_agps_set_server, loc_agps_open_with_apniptype }; static int loc_xtra_init(GpsXtraCallbacks* callbacks); static int loc_xtra_inject_data(char* data, int length); static const GpsXtraInterface sLocEngXTRAInterface = { sizeof(GpsXtraInterface), loc_xtra_init, loc_xtra_inject_data }; static void loc_ni_init(GpsNiCallbacks *callbacks); static void loc_ni_respond(int notif_id, GpsUserResponseType user_response); static const GpsNiInterface sLocEngNiInterface = { sizeof(GpsNiInterface), loc_ni_init, loc_ni_respond, }; static int loc_gps_measurement_init(GpsMeasurementCallbacks* callbacks); static void loc_gps_measurement_close(); static const GpsMeasurementInterface sLocEngGpsMeasurementInterface = { sizeof(GpsMeasurementInterface), loc_gps_measurement_init, loc_gps_measurement_close }; static void loc_agps_ril_init( AGpsRilCallbacks* callbacks ); static void loc_agps_ril_set_ref_location(const AGpsRefLocation *agps_reflocation, size_t sz_struct); static void loc_agps_ril_set_set_id(AGpsSetIDType type, const char* setid); static void loc_agps_ril_ni_message(uint8_t *msg, size_t len); static void loc_agps_ril_update_network_state(int connected, int type, int roaming, const char* extra_info); static void loc_agps_ril_update_network_availability(int avaiable, const char* apn); static const AGpsRilInterface sLocEngAGpsRilInterface = { sizeof(AGpsRilInterface), loc_agps_ril_init, loc_agps_ril_set_ref_location, loc_agps_ril_set_set_id, loc_agps_ril_ni_message, loc_agps_ril_update_network_state, loc_agps_ril_update_network_availability }; static int loc_agps_install_certificates(const DerEncodedCertificate* certificates, size_t length); static int loc_agps_revoke_certificates(const Sha1CertificateFingerprint* fingerprints, size_t length); static const SuplCertificateInterface sLocEngAGpsCertInterface = { sizeof(SuplCertificateInterface), loc_agps_install_certificates, loc_agps_revoke_certificates }; static void loc_configuration_update(const char* config_data, int32_t length); static const GnssConfigurationInterface sLocEngConfigInterface = { sizeof(GnssConfigurationInterface), loc_configuration_update }; static loc_eng_data_s_type loc_afw_data; static int gss_fd = -1; static int sGnssType = GNSS_UNKNOWN; /*=========================================================================== FUNCTION gps_get_hardware_interface DESCRIPTION Returns the GPS hardware interaface based on LOC API if GPS is enabled. DEPENDENCIES None RETURN VALUE 0: success SIDE EFFECTS N/A ===========================================================================*/ const GpsInterface* gps_get_hardware_interface () { ENTRY_LOG_CALLFLOW(); const GpsInterface* ret_val; char propBuf[PROPERTY_VALUE_MAX]; loc_eng_read_config(); // check to see if GPS should be disabled property_get("gps.disable", propBuf, ""); if (propBuf[0] == '1') { LOC_LOGD("gps_get_interface returning NULL because gps.disable=1\n"); ret_val = NULL; } else { ret_val = &sLocEngInterface; } loc_eng_read_config(); EXIT_LOG(%p, ret_val); return ret_val; } // for gps.c extern "C" const GpsInterface* get_gps_interface() { unsigned int target = TARGET_DEFAULT; loc_eng_read_config(); target = loc_get_target(); LOC_LOGD("Target name check returned %s", loc_get_target_name(target)); sGnssType = getTargetGnssType(target); switch (sGnssType) { case GNSS_GSS: case GNSS_AUTO: //APQ8064 gps_conf.CAPABILITIES &= ~(GPS_CAPABILITY_MSA | GPS_CAPABILITY_MSB); gss_fd = open("/dev/gss", O_RDONLY); if (gss_fd < 0) { LOC_LOGE("GSS open failed: %s\n", strerror(errno)); } else { LOC_LOGD("GSS open success! CAPABILITIES %0lx\n", gps_conf.CAPABILITIES); } break; case GNSS_NONE: //MPQ8064 LOC_LOGE("No GPS HW on this target. Not returning interface."); return NULL; case GNSS_QCA1530: // qca1530 chip is present gps_conf.CAPABILITIES &= ~(GPS_CAPABILITY_MSA | GPS_CAPABILITY_MSB); LOC_LOGD("qca1530 present: CAPABILITIES %0lx\n", gps_conf.CAPABILITIES); break; } return &sLocEngInterface; } /*=========================================================================== FUNCTION loc_init DESCRIPTION Initialize the location engine, this include setting up global datas and registers location engien with loc api service. DEPENDENCIES None RETURN VALUE 0: success SIDE EFFECTS N/Ax ===========================================================================*/ static int loc_init(GpsCallbacks* callbacks) { int retVal = -1; ENTRY_LOG(); LOC_API_ADAPTER_EVENT_MASK_T event; if (NULL == callbacks) { LOC_LOGE("loc_init failed. cb = NULL\n"); EXIT_LOG(%d, retVal); return retVal; } event = LOC_API_ADAPTER_BIT_PARSED_POSITION_REPORT | LOC_API_ADAPTER_BIT_SATELLITE_REPORT | LOC_API_ADAPTER_BIT_LOCATION_SERVER_REQUEST | LOC_API_ADAPTER_BIT_ASSISTANCE_DATA_REQUEST | LOC_API_ADAPTER_BIT_IOCTL_REPORT | LOC_API_ADAPTER_BIT_STATUS_REPORT | LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT | LOC_API_ADAPTER_BIT_NI_NOTIFY_VERIFY_REQUEST; LocCallbacks clientCallbacks = {local_loc_cb, /* location_cb */ callbacks->status_cb, /* status_cb */ local_sv_cb, /* sv_status_cb */ callbacks->nmea_cb, /* nmea_cb */ callbacks->set_capabilities_cb, /* set_capabilities_cb */ callbacks->acquire_wakelock_cb, /* acquire_wakelock_cb */ callbacks->release_wakelock_cb, /* release_wakelock_cb */ callbacks->create_thread_cb, /* create_thread_cb */ NULL, /* location_ext_parser */ NULL, /* sv_ext_parser */ callbacks->request_utc_time_cb, /* request_utc_time_cb */ }; gps_loc_cb = callbacks->location_cb; gps_sv_cb = callbacks->sv_status_cb; retVal = loc_eng_init(loc_afw_data, &clientCallbacks, event, NULL); loc_afw_data.adapter->mSupportsAgpsRequests = !loc_afw_data.adapter->hasAgpsExtendedCapabilities(); loc_afw_data.adapter->mSupportsPositionInjection = !loc_afw_data.adapter->hasCPIExtendedCapabilities(); loc_afw_data.adapter->mSupportsTimeInjection = !loc_afw_data.adapter->hasCPIExtendedCapabilities(); loc_afw_data.adapter->setGpsLockMsg(0); loc_afw_data.adapter->requestUlp(getCarrierCapabilities()); loc_afw_data.adapter->setXtraUserAgent(); if(retVal) { LOC_LOGE("loc_eng_init() fail!"); goto err; } loc_afw_data.adapter->setPowerVoteRight(loc_get_target() == TARGET_QCA1530); loc_afw_data.adapter->setPowerVote(true); LOC_LOGD("loc_eng_init() success!"); err: EXIT_LOG(%d, retVal); return retVal; } /*=========================================================================== FUNCTION loc_cleanup DESCRIPTION Cleans location engine. The location client handle will be released. DEPENDENCIES None RETURN VALUE None SIDE EFFECTS N/A ===========================================================================*/ static void loc_cleanup() { ENTRY_LOG(); loc_afw_data.adapter->setPowerVote(false); loc_afw_data.adapter->setGpsLockMsg(gps_conf.GPS_LOCK); loc_eng_cleanup(loc_afw_data); gps_loc_cb = NULL; gps_sv_cb = NULL; EXIT_LOG(%s, VOID_RET); } /*=========================================================================== FUNCTION loc_start DESCRIPTION Starts the tracking session DEPENDENCIES None RETURN VALUE 0: success SIDE EFFECTS N/A ===========================================================================*/ static int loc_start() { ENTRY_LOG(); int ret_val = loc_eng_start(loc_afw_data); EXIT_LOG(%d, ret_val); return ret_val; } /*=========================================================================== FUNCTION loc_stop DESCRIPTION Stops the tracking session DEPENDENCIES None RETURN VALUE 0: success SIDE EFFECTS N/A ===========================================================================*/ static int loc_stop() { ENTRY_LOG(); int ret_val = -1; ret_val = loc_eng_stop(loc_afw_data); EXIT_LOG(%d, ret_val); return ret_val; } /*=========================================================================== FUNCTION loc_set_position_mode DESCRIPTION Sets the mode and fix frequency for the tracking session. DEPENDENCIES None RETURN VALUE 0: success SIDE EFFECTS N/A ===========================================================================*/ static int loc_set_position_mode(GpsPositionMode mode, GpsPositionRecurrence recurrence, uint32_t min_interval, uint32_t preferred_accuracy, uint32_t preferred_time) { ENTRY_LOG(); int ret_val = -1; LocPositionMode locMode; switch (mode) { case GPS_POSITION_MODE_MS_BASED: locMode = LOC_POSITION_MODE_MS_BASED; break; case GPS_POSITION_MODE_MS_ASSISTED: locMode = LOC_POSITION_MODE_MS_ASSISTED; break; default: locMode = LOC_POSITION_MODE_STANDALONE; break; } LocPosMode params(locMode, recurrence, min_interval, preferred_accuracy, preferred_time, NULL, NULL); ret_val = loc_eng_set_position_mode(loc_afw_data, params); EXIT_LOG(%d, ret_val); return ret_val; } /*=========================================================================== FUNCTION loc_inject_time DESCRIPTION This is used by Java native function to do time injection. DEPENDENCIES None RETURN VALUE 0 SIDE EFFECTS N/A ===========================================================================*/ static int loc_inject_time(GpsUtcTime time, int64_t timeReference, int uncertainty) { ENTRY_LOG(); int ret_val = 0; ret_val = loc_eng_inject_time(loc_afw_data, time, timeReference, uncertainty); EXIT_LOG(%d, ret_val); return ret_val; } /*=========================================================================== FUNCTION loc_inject_location DESCRIPTION This is used by Java native function to do location injection. DEPENDENCIES None RETURN VALUE 0 : Successful error code : Failure SIDE EFFECTS N/A ===========================================================================*/ static int loc_inject_location(double latitude, double longitude, float accuracy) { ENTRY_LOG(); int ret_val = 0; ret_val = loc_eng_inject_location(loc_afw_data, latitude, longitude, accuracy); EXIT_LOG(%d, ret_val); return ret_val; } /*=========================================================================== FUNCTION loc_delete_aiding_data DESCRIPTION This is used by Java native function to delete the aiding data. The function updates the global variable for the aiding data to be deleted. If the GPS engine is off, the aiding data will be deleted. Otherwise, the actual action will happen when gps engine is turned off. DEPENDENCIES Assumes the aiding data type specified in GpsAidingData matches with LOC API specification. RETURN VALUE None SIDE EFFECTS N/A ===========================================================================*/ static void loc_delete_aiding_data(GpsAidingData f) { ENTRY_LOG(); loc_eng_delete_aiding_data(loc_afw_data, f); EXIT_LOG(%s, VOID_RET); } const GpsGeofencingInterface* get_geofence_interface(void) { ENTRY_LOG(); void *handle; const char *error; typedef const GpsGeofencingInterface* (*get_gps_geofence_interface_function) (void); get_gps_geofence_interface_function get_gps_geofence_interface; static const GpsGeofencingInterface* geofence_interface = NULL; dlerror(); /* Clear any existing error */ handle = dlopen ("libgeofence.so", RTLD_NOW); if (!handle) { if ((error = dlerror()) != NULL) { LOC_LOGE ("%s, dlopen for libgeofence.so failed, error = %s\n", __func__, error); } goto exit; } dlerror(); /* Clear any existing error */ get_gps_geofence_interface = (get_gps_geofence_interface_function)dlsym(handle, "gps_geofence_get_interface"); if ((error = dlerror()) != NULL || NULL == get_gps_geofence_interface) { LOC_LOGE ("%s, dlsym for get_gps_geofence_interface failed, error = %s\n", __func__, error); goto exit; } geofence_interface = get_gps_geofence_interface(); exit: EXIT_LOG(%d, geofence_interface == NULL); return geofence_interface; } /*=========================================================================== FUNCTION loc_get_extension DESCRIPTION Get the gps extension to support XTRA. DEPENDENCIES N/A RETURN VALUE The GPS extension interface. SIDE EFFECTS N/A ===========================================================================*/ const void* loc_get_extension(const char* name) { ENTRY_LOG(); const void* ret_val = NULL; LOC_LOGD("%s:%d] For Interface = %s\n",__func__, __LINE__, name); if (strcmp(name, GPS_XTRA_INTERFACE) == 0) { ret_val = &sLocEngXTRAInterface; } else if (strcmp(name, AGPS_INTERFACE) == 0) { ret_val = &sLocEngAGpsInterface; } else if (strcmp(name, GPS_NI_INTERFACE) == 0) { ret_val = &sLocEngNiInterface; } else if (strcmp(name, AGPS_RIL_INTERFACE) == 0) { char baseband[PROPERTY_VALUE_MAX]; property_get("ro.baseband", baseband, "msm"); if (strcmp(baseband, "csfb") == 0) { ret_val = &sLocEngAGpsRilInterface; } } else if (strcmp(name, GPS_GEOFENCING_INTERFACE) == 0) { if ((gps_conf.CAPABILITIES | GPS_CAPABILITY_GEOFENCING) == gps_conf.CAPABILITIES ){ ret_val = get_geofence_interface(); } } else if (strcmp(name, SUPL_CERTIFICATE_INTERFACE) == 0) { ret_val = &sLocEngAGpsCertInterface; } else if (strcmp(name, GNSS_CONFIGURATION_INTERFACE) == 0) { ret_val = &sLocEngConfigInterface; } else if (strcmp(name, GPS_MEASUREMENT_INTERFACE) == 0) { ret_val = &sLocEngGpsMeasurementInterface; } else { LOC_LOGE ("get_extension: Invalid interface passed in\n"); } EXIT_LOG(%p, ret_val); return ret_val; } /*=========================================================================== FUNCTION loc_agps_init DESCRIPTION Initialize the AGps interface. DEPENDENCIES NONE RETURN VALUE 0 SIDE EFFECTS N/A ===========================================================================*/ static void loc_agps_init(AGpsCallbacks* callbacks) { ENTRY_LOG(); loc_eng_agps_init(loc_afw_data, (AGpsExtCallbacks*)callbacks); EXIT_LOG(%s, VOID_RET); } /*=========================================================================== FUNCTION loc_agps_open DESCRIPTION This function is called when on-demand data connection opening is successful. It should inform ARM 9 about the data open result. DEPENDENCIES NONE RETURN VALUE 0 SIDE EFFECTS N/A ===========================================================================*/ static int loc_agps_open(const char* apn) { ENTRY_LOG(); AGpsType agpsType = AGPS_TYPE_SUPL; AGpsBearerType bearerType = AGPS_APN_BEARER_IPV4; int ret_val = loc_eng_agps_open(loc_afw_data, agpsType, apn, bearerType); EXIT_LOG(%d, ret_val); return ret_val; } /*=========================================================================== FUNCTION loc_agps_open_with_apniptype DESCRIPTION This function is called when on-demand data connection opening is successful. It should inform ARM 9 about the data open result. DEPENDENCIES NONE RETURN VALUE 0 SIDE EFFECTS N/A ===========================================================================*/ static int loc_agps_open_with_apniptype(const char* apn, ApnIpType apnIpType) { ENTRY_LOG(); AGpsType agpsType = AGPS_TYPE_SUPL; AGpsBearerType bearerType; switch (apnIpType) { case APN_IP_IPV4: bearerType = AGPS_APN_BEARER_IPV4; break; case APN_IP_IPV6: bearerType = AGPS_APN_BEARER_IPV6; break; case APN_IP_IPV4V6: bearerType = AGPS_APN_BEARER_IPV4V6; break; default: bearerType = AGPS_APN_BEARER_INVALID; break; } int ret_val = loc_eng_agps_open(loc_afw_data, agpsType, apn, bearerType); EXIT_LOG(%d, ret_val); return ret_val; } /*=========================================================================== FUNCTION loc_agps_closed DESCRIPTION This function is called when on-demand data connection closing is done. It should inform ARM 9 about the data close result. DEPENDENCIES NONE RETURN VALUE 0 SIDE EFFECTS N/A ===========================================================================*/ static int loc_agps_closed() { ENTRY_LOG(); AGpsType agpsType = AGPS_TYPE_SUPL; int ret_val = loc_eng_agps_closed(loc_afw_data, agpsType); EXIT_LOG(%d, ret_val); return ret_val; } /*=========================================================================== FUNCTION loc_agps_open_failed DESCRIPTION This function is called when on-demand data connection opening has failed. It should inform ARM 9 about the data open result. DEPENDENCIES NONE RETURN VALUE 0 SIDE EFFECTS N/A ===========================================================================*/ int loc_agps_open_failed() { ENTRY_LOG(); AGpsType agpsType = AGPS_TYPE_SUPL; int ret_val = loc_eng_agps_open_failed(loc_afw_data, agpsType); EXIT_LOG(%d, ret_val); return ret_val; } /*=========================================================================== FUNCTION loc_agps_set_server DESCRIPTION If loc_eng_set_server is called before loc_eng_init, it doesn't work. This proxy buffers server settings and calls loc_eng_set_server when the client is open. DEPENDENCIES NONE RETURN VALUE 0 SIDE EFFECTS N/A ===========================================================================*/ static int loc_agps_set_server(AGpsType type, const char* hostname, int port) { ENTRY_LOG(); LocServerType serverType; switch (type) { case AGPS_TYPE_SUPL: serverType = LOC_AGPS_SUPL_SERVER; break; case AGPS_TYPE_C2K: serverType = LOC_AGPS_CDMA_PDE_SERVER; break; default: serverType = LOC_AGPS_SUPL_SERVER; } int ret_val = loc_eng_set_server_proxy(loc_afw_data, serverType, hostname, port); EXIT_LOG(%d, ret_val); return ret_val; } /*=========================================================================== FUNCTIONf571 loc_xtra_init DESCRIPTION Initialize XTRA module. DEPENDENCIES None RETURN VALUE 0: success SIDE EFFECTS N/A ===========================================================================*/ static int loc_xtra_init(GpsXtraCallbacks* callbacks) { ENTRY_LOG(); GpsXtraExtCallbacks extCallbacks; memset(&extCallbacks, 0, sizeof(extCallbacks)); extCallbacks.download_request_cb = callbacks->download_request_cb; int ret_val = loc_eng_xtra_init(loc_afw_data, &extCallbacks); EXIT_LOG(%d, ret_val); return ret_val; } /*=========================================================================== FUNCTION loc_xtra_inject_data DESCRIPTION Initialize XTRA module. DEPENDENCIES None RETURN VALUE 0: success SIDE EFFECTS N/A ===========================================================================*/ static int loc_xtra_inject_data(char* data, int length) { ENTRY_LOG(); int ret_val = -1; if( (data != NULL) && ((unsigned int)length <= XTRA_DATA_MAX_SIZE)) ret_val = loc_eng_xtra_inject_data(loc_afw_data, data, length); else LOC_LOGE("%s, Could not inject XTRA data. Buffer address: %p, length: %d", __func__, data, length); EXIT_LOG(%d, ret_val); return ret_val; } /*=========================================================================== FUNCTION loc_gps_measurement_init DESCRIPTION This function initializes the gps measurement interface DEPENDENCIES NONE RETURN VALUE None SIDE EFFECTS N/A ===========================================================================*/ static int loc_gps_measurement_init(GpsMeasurementCallbacks* callbacks) { ENTRY_LOG(); int ret_val = loc_eng_gps_measurement_init(loc_afw_data, callbacks); EXIT_LOG(%d, ret_val); return ret_val; } /*=========================================================================== FUNCTION loc_gps_measurement_close DESCRIPTION This function closes the gps measurement interface DEPENDENCIES NONE RETURN VALUE None SIDE EFFECTS N/A ===========================================================================*/ static void loc_gps_measurement_close() { ENTRY_LOG(); loc_eng_gps_measurement_close(loc_afw_data); EXIT_LOG(%s, VOID_RET); } /*=========================================================================== FUNCTION loc_ni_init DESCRIPTION This function initializes the NI interface DEPENDENCIES NONE RETURN VALUE None SIDE EFFECTS N/A ===========================================================================*/ void loc_ni_init(GpsNiCallbacks *callbacks) { ENTRY_LOG(); loc_eng_ni_init(loc_afw_data,(GpsNiExtCallbacks*) callbacks); EXIT_LOG(%s, VOID_RET); } /*=========================================================================== FUNCTION loc_ni_respond DESCRIPTION This function sends an NI respond to the modem processor DEPENDENCIES NONE RETURN VALUE None SIDE EFFECTS N/A ===========================================================================*/ void loc_ni_respond(int notif_id, GpsUserResponseType user_response) { ENTRY_LOG(); loc_eng_ni_respond(loc_afw_data, notif_id, user_response); EXIT_LOG(%s, VOID_RET); } // Below stub functions are members of sLocEngAGpsRilInterface static void loc_agps_ril_init( AGpsRilCallbacks* callbacks ) {} static void loc_agps_ril_set_ref_location(const AGpsRefLocation *agps_reflocation, size_t sz_struct) {} static void loc_agps_ril_set_set_id(AGpsSetIDType type, const char* setid) {} static void loc_agps_ril_ni_message(uint8_t *msg, size_t len) {} static void loc_agps_ril_update_network_state(int connected, int type, int roaming, const char* extra_info) {} /*=========================================================================== FUNCTION loc_agps_ril_update_network_availability DESCRIPTION Sets data call allow vs disallow flag to modem This is the only member of sLocEngAGpsRilInterface implemented. DEPENDENCIES None RETURN VALUE 0: success SIDE EFFECTS N/A ===========================================================================*/ static void loc_agps_ril_update_network_availability(int available, const char* apn) { ENTRY_LOG(); loc_eng_agps_ril_update_network_availability(loc_afw_data, available, apn); EXIT_LOG(%s, VOID_RET); } static int loc_agps_install_certificates(const DerEncodedCertificate* certificates, size_t length) { ENTRY_LOG(); int ret_val = loc_eng_agps_install_certificates(loc_afw_data, certificates, length); EXIT_LOG(%d, ret_val); return ret_val; } static int loc_agps_revoke_certificates(const Sha1CertificateFingerprint* fingerprints, size_t length) { ENTRY_LOG(); LOC_LOGE("%s:%d]: agps_revoke_certificates not supported"); int ret_val = AGPS_CERTIFICATE_ERROR_GENERIC; EXIT_LOG(%d, ret_val); return ret_val; } static void loc_configuration_update(const char* config_data, int32_t length) { ENTRY_LOG(); loc_eng_configuration_update(loc_afw_data, config_data, length); switch (sGnssType) { case GNSS_GSS: case GNSS_AUTO: case GNSS_QCA1530: //APQ gps_conf.CAPABILITIES &= ~(GPS_CAPABILITY_MSA | GPS_CAPABILITY_MSB); break; } EXIT_LOG(%s, VOID_RET); } static void local_loc_cb(UlpLocation* location, void* locExt) { ENTRY_LOG(); if (NULL != location) { CALLBACK_LOG_CALLFLOW("location_cb - from", %d, location->position_source); if (NULL != gps_loc_cb) { gps_loc_cb(&location->gpsLocation); } } EXIT_LOG(%s, VOID_RET); } static void local_sv_cb(GpsSvStatus* sv_status, void* svExt) { ENTRY_LOG(); if (NULL != gps_sv_cb) { CALLBACK_LOG_CALLFLOW("sv_status_cb -", %d, sv_status->num_svs); gps_sv_cb(sv_status); } EXIT_LOG(%s, VOID_RET); } ================================================ FILE: gps/loc_api/libloc_api_50001/loc.h ================================================ /* Copyright (c) 2011,2014 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef __LOC_H__ #define __LOC_H__ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #include #include #include #include #define XTRA_DATA_MAX_SIZE 100000 /*bytes*/ typedef void (*loc_location_cb_ext) (UlpLocation* location, void* locExt); typedef void (*loc_sv_status_cb_ext) (GpsSvStatus* sv_status, void* svExt); typedef void* (*loc_ext_parser)(void* data); typedef struct { loc_location_cb_ext location_cb; gps_status_callback status_cb; loc_sv_status_cb_ext sv_status_cb; gps_nmea_callback nmea_cb; gps_set_capabilities set_capabilities_cb; gps_acquire_wakelock acquire_wakelock_cb; gps_release_wakelock release_wakelock_cb; gps_create_thread create_thread_cb; loc_ext_parser location_ext_parser; loc_ext_parser sv_ext_parser; gps_request_utc_time request_utc_time_cb; } LocCallbacks; #ifdef __cplusplus } #endif /* __cplusplus */ #endif //__LOC_H__ ================================================ FILE: gps/loc_api/libloc_api_50001/loc_eng.cpp ================================================ /* Copyright (c) 2009-2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #define LOG_NDDEBUG 0 #define LOG_TAG "LocSvc_eng" #include #include #include #include #include #include #include #include #include #include /* struct sockaddr_in */ #include #include #include #include #include #include #include #ifndef USE_GLIB #include #include #endif /* USE_GLIB */ #ifdef USE_GLIB #include #include #endif /* USE_GLIB */ #include #include #include #include #include #include #include #include #include #include "log_util.h" #include "platform_lib_includes.h" #include "loc_core_log.h" #include "loc_eng_log.h" #define SUCCESS TRUE #define FAILURE FALSE #ifndef GPS_CONF_FILE #define GPS_CONF_FILE "/etc/gps.conf" //??? platform independent #endif #ifndef SAP_CONF_FILE #define SAP_CONF_FILE "/etc/sap.conf" #endif #define XTRA1_GPSONEXTRA "xtra1.gpsonextra.net" using namespace loc_core; boolean configAlreadyRead = false; unsigned int agpsStatus = 0; loc_gps_cfg_s_type gps_conf; loc_sap_cfg_s_type sap_conf; /* Parameter spec table */ static loc_param_s_type gps_conf_table[] = { {"GPS_LOCK", &gps_conf.GPS_LOCK, NULL, 'n'}, {"SUPL_VER", &gps_conf.SUPL_VER, NULL, 'n'}, {"LPP_PROFILE", &gps_conf.LPP_PROFILE, NULL, 'n'}, {"A_GLONASS_POS_PROTOCOL_SELECT", &gps_conf.A_GLONASS_POS_PROTOCOL_SELECT, NULL, 'n'}, {"AGPS_CERT_WRITABLE_MASK", &gps_conf.AGPS_CERT_WRITABLE_MASK, NULL, 'n'}, {"SUPL_MODE", &gps_conf.SUPL_MODE, NULL, 'n'}, {"INTERMEDIATE_POS", &gps_conf.INTERMEDIATE_POS, NULL, 'n'}, {"ACCURACY_THRES", &gps_conf.ACCURACY_THRES, NULL, 'n'}, {"NMEA_PROVIDER", &gps_conf.NMEA_PROVIDER, NULL, 'n'}, {"CAPABILITIES", &gps_conf.CAPABILITIES, NULL, 'n'}, {"XTRA_VERSION_CHECK", &gps_conf.XTRA_VERSION_CHECK, NULL, 'n'}, {"XTRA_SERVER_1", &gps_conf.XTRA_SERVER_1, NULL, 's'}, {"XTRA_SERVER_2", &gps_conf.XTRA_SERVER_2, NULL, 's'}, {"XTRA_SERVER_3", &gps_conf.XTRA_SERVER_3, NULL, 's'}, {"USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL", &gps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL, NULL, 'n'}, }; static loc_param_s_type sap_conf_table[] = { {"GYRO_BIAS_RANDOM_WALK", &sap_conf.GYRO_BIAS_RANDOM_WALK, &sap_conf.GYRO_BIAS_RANDOM_WALK_VALID, 'f'}, {"ACCEL_RANDOM_WALK_SPECTRAL_DENSITY", &sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY, &sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'}, {"ANGLE_RANDOM_WALK_SPECTRAL_DENSITY", &sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY, &sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'}, {"RATE_RANDOM_WALK_SPECTRAL_DENSITY", &sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY, &sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'}, {"VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY", &sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY, &sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID, 'f'}, {"SENSOR_ACCEL_BATCHES_PER_SEC", &sap_conf.SENSOR_ACCEL_BATCHES_PER_SEC, NULL, 'n'}, {"SENSOR_ACCEL_SAMPLES_PER_BATCH", &sap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH, NULL, 'n'}, {"SENSOR_GYRO_BATCHES_PER_SEC", &sap_conf.SENSOR_GYRO_BATCHES_PER_SEC, NULL, 'n'}, {"SENSOR_GYRO_SAMPLES_PER_BATCH", &sap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH, NULL, 'n'}, {"SENSOR_ACCEL_BATCHES_PER_SEC_HIGH", &sap_conf.SENSOR_ACCEL_BATCHES_PER_SEC_HIGH, NULL, 'n'}, {"SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH", &sap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH, NULL, 'n'}, {"SENSOR_GYRO_BATCHES_PER_SEC_HIGH", &sap_conf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH, NULL, 'n'}, {"SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH", &sap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH, NULL, 'n'}, {"SENSOR_CONTROL_MODE", &sap_conf.SENSOR_CONTROL_MODE, NULL, 'n'}, {"SENSOR_USAGE", &sap_conf.SENSOR_USAGE, NULL, 'n'}, {"SENSOR_ALGORITHM_CONFIG_MASK", &sap_conf.SENSOR_ALGORITHM_CONFIG_MASK, NULL, 'n'}, {"SENSOR_PROVIDER", &sap_conf.SENSOR_PROVIDER, NULL, 'n'} }; static void loc_default_parameters(void) { /*Defaults for gps.conf*/ gps_conf.INTERMEDIATE_POS = 0; gps_conf.ACCURACY_THRES = 0; gps_conf.NMEA_PROVIDER = 0; gps_conf.GPS_LOCK = 0; gps_conf.SUPL_VER = 0x10000; gps_conf.SUPL_MODE = 0x3; gps_conf.CAPABILITIES = 0x7; /* LTE Positioning Profile configuration is disable by default*/ gps_conf.LPP_PROFILE = 0; /*By default no positioning protocol is selected on A-GLONASS system*/ gps_conf.A_GLONASS_POS_PROTOCOL_SELECT = 0; /*XTRA version check is disabled by default*/ gps_conf.XTRA_VERSION_CHECK=0; /*Use emergency PDN by default*/ gps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL = 1; /*Defaults for sap.conf*/ sap_conf.GYRO_BIAS_RANDOM_WALK = 0; sap_conf.SENSOR_ACCEL_BATCHES_PER_SEC = 2; sap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH = 5; sap_conf.SENSOR_GYRO_BATCHES_PER_SEC = 2; sap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH = 5; sap_conf.SENSOR_ACCEL_BATCHES_PER_SEC_HIGH = 4; sap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH = 25; sap_conf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH = 4; sap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH = 25; sap_conf.SENSOR_CONTROL_MODE = 0; /* AUTO */ sap_conf.SENSOR_USAGE = 0; /* Enabled */ sap_conf.SENSOR_ALGORITHM_CONFIG_MASK = 0; /* INS Disabled = FALSE*/ /* Values MUST be set by OEMs in configuration for sensor-assisted navigation to work. There are NO default values */ sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY = 0; sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY = 0; sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY = 0; sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY = 0; sap_conf.GYRO_BIAS_RANDOM_WALK_VALID = 0; sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0; sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0; sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0; sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0; /* default provider is SSC */ sap_conf.SENSOR_PROVIDER = 1; /* None of the 10 slots for agps certificates are writable by default */ gps_conf.AGPS_CERT_WRITABLE_MASK = 0; } // 2nd half of init(), singled out for // modem restart to use. static int loc_eng_reinit(loc_eng_data_s_type &loc_eng_data); static void loc_eng_agps_reinit(loc_eng_data_s_type &loc_eng_data); static int loc_eng_set_server(loc_eng_data_s_type &loc_eng_data, LocServerType type, const char *hostname, int port); // Internal functions static void loc_inform_gps_status(loc_eng_data_s_type &loc_eng_data, GpsStatusValue status); static void loc_eng_report_status(loc_eng_data_s_type &loc_eng_data, GpsStatusValue status); static void loc_eng_process_conn_request(loc_eng_data_s_type &loc_eng_data, int connHandle, AGpsType agps_type); static void loc_eng_agps_close_status(loc_eng_data_s_type &loc_eng_data, int is_succ); static void loc_eng_handle_engine_down(loc_eng_data_s_type &loc_eng_data) ; static void loc_eng_handle_engine_up(loc_eng_data_s_type &loc_eng_data) ; static int loc_eng_start_handler(loc_eng_data_s_type &loc_eng_data); static int loc_eng_stop_handler(loc_eng_data_s_type &loc_eng_data); static int loc_eng_get_zpp_handler(loc_eng_data_s_type &loc_eng_data); static void deleteAidingData(loc_eng_data_s_type &logEng); static AgpsStateMachine* getAgpsStateMachine(loc_eng_data_s_type& logEng, AGpsExtType agpsType); static int dataCallCb(void *cb_data); static void update_aiding_data_for_deletion(loc_eng_data_s_type& loc_eng_data) { if (loc_eng_data.engine_status != GPS_STATUS_ENGINE_ON && loc_eng_data.aiding_data_for_deletion != 0) { loc_eng_data.adapter->deleteAidingData(loc_eng_data.aiding_data_for_deletion); loc_eng_data.aiding_data_for_deletion = 0; } } static void* noProc(void* data) { return NULL; } /********************************************************************* * definitions of the static messages used in the file *********************************************************************/ // case LOC_ENG_MSG_REQUEST_NI: LocEngRequestNi::LocEngRequestNi(void* locEng, GpsNiNotification ¬if, const void* data) : LocMsg(), mLocEng(locEng), mNotify(notif), mPayload(data) { locallog(); } void LocEngRequestNi::proc() const { loc_eng_ni_request_handler(*((loc_eng_data_s_type*)mLocEng), &mNotify, mPayload); } void LocEngRequestNi::locallog() const { LOC_LOGV("id: %d\n type: %s\n flags: %d\n time out: %d\n " "default response: %s\n requestor id encoding: %s\n" " text encoding: %s\n passThroughData: %p", mNotify.notification_id, loc_get_ni_type_name(mNotify.ni_type), mNotify.notify_flags, mNotify.timeout, loc_get_ni_response_name(mNotify.default_response), loc_get_ni_encoding_name(mNotify.requestor_id_encoding), loc_get_ni_encoding_name(mNotify.text_encoding), mPayload); } inline void LocEngRequestNi::log() const { locallog(); } // case LOC_ENG_MSG_INFORM_NI_RESPONSE: // in loc_eng_ni.cpp // case LOC_ENG_MSG_START_FIX: LocEngStartFix::LocEngStartFix(LocEngAdapter* adapter) : LocMsg(), mAdapter(adapter) { locallog(); } inline void LocEngStartFix::proc() const { loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mAdapter->getOwner(); loc_eng_start_handler(*locEng); } inline void LocEngStartFix::locallog() const { LOC_LOGV("LocEngStartFix"); } inline void LocEngStartFix::log() const { locallog(); } void LocEngStartFix::send() const { mAdapter->sendMsg(this); } // case LOC_ENG_MSG_STOP_FIX: LocEngStopFix::LocEngStopFix(LocEngAdapter* adapter) : LocMsg(), mAdapter(adapter) { locallog(); } inline void LocEngStopFix::proc() const { loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mAdapter->getOwner(); loc_eng_stop_handler(*locEng); } inline void LocEngStopFix::locallog() const { LOC_LOGV("LocEngStopFix"); } inline void LocEngStopFix::log() const { locallog(); } void LocEngStopFix::send() const { mAdapter->sendMsg(this); } // case LOC_ENG_MSG_SET_POSITION_MODE: LocEngPositionMode::LocEngPositionMode(LocEngAdapter* adapter, LocPosMode &mode) : LocMsg(), mAdapter(adapter), mPosMode(mode) { mPosMode.logv(); } inline void LocEngPositionMode::proc() const { mAdapter->setPositionMode(&mPosMode); } inline void LocEngPositionMode::log() const { mPosMode.logv(); } void LocEngPositionMode::send() const { mAdapter->sendMsg(this); } LocEngGetZpp::LocEngGetZpp(LocEngAdapter* adapter) : LocMsg(), mAdapter(adapter) { locallog(); } inline void LocEngGetZpp::proc() const { loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mAdapter->getOwner(); loc_eng_get_zpp_handler(*locEng); } inline void LocEngGetZpp::locallog() const { LOC_LOGV("LocEngGetZpp"); } inline void LocEngGetZpp::log() const { locallog(); } void LocEngGetZpp::send() const { mAdapter->sendMsg(this); } struct LocEngSetTime : public LocMsg { LocEngAdapter* mAdapter; const GpsUtcTime mTime; const int64_t mTimeReference; const int mUncertainty; inline LocEngSetTime(LocEngAdapter* adapter, GpsUtcTime t, int64_t tf, int unc) : LocMsg(), mAdapter(adapter), mTime(t), mTimeReference(tf), mUncertainty(unc) { locallog(); } inline virtual void proc() const { mAdapter->setTime(mTime, mTimeReference, mUncertainty); } inline void locallog() const { LOC_LOGV("time: %lld\n timeReference: %lld\n uncertainty: %d", mTime, mTimeReference, mUncertainty); } inline virtual void log() const { locallog(); } }; // case LOC_ENG_MSG_INJECT_LOCATION: struct LocEngInjectLocation : public LocMsg { LocEngAdapter* mAdapter; const double mLatitude; const double mLongitude; const float mAccuracy; inline LocEngInjectLocation(LocEngAdapter* adapter, double lat, double lon, float accur) : LocMsg(), mAdapter(adapter), mLatitude(lat), mLongitude(lon), mAccuracy(accur) { locallog(); } inline virtual void proc() const { mAdapter->injectPosition(mLatitude, mLongitude, mAccuracy); } inline void locallog() const { LOC_LOGV("latitude: %f\n longitude: %f\n accuracy: %f", mLatitude, mLongitude, mAccuracy); } inline virtual void log() const { locallog(); } }; // case LOC_ENG_MSG_SET_SERVER_IPV4: struct LocEngSetServerIpv4 : public LocMsg { LocEngAdapter* mAdapter; const unsigned int mNlAddr; const int mPort; const LocServerType mServerType; inline LocEngSetServerIpv4(LocEngAdapter* adapter, unsigned int ip, int port, LocServerType type) : LocMsg(), mAdapter(adapter), mNlAddr(ip), mPort(port), mServerType(type) { locallog(); } inline virtual void proc() const { mAdapter->setServer(mNlAddr, mPort, mServerType); } inline void locallog() const { LOC_LOGV("LocEngSetServerIpv4 - addr: %x, port: %d, type: %s", mNlAddr, mPort, loc_get_server_type_name(mServerType)); } inline virtual void log() const { locallog(); } }; // case LOC_ENG_MSG_SET_SERVER_URL: struct LocEngSetServerUrl : public LocMsg { LocEngAdapter* mAdapter; const int mLen; char* mUrl; inline LocEngSetServerUrl(LocEngAdapter* adapter, char* urlString, int url_len) : LocMsg(), mAdapter(adapter), mLen(url_len), mUrl(new char[mLen+1]) { memcpy((void*)mUrl, (void*)urlString, url_len); mUrl[mLen] = 0; locallog(); } inline ~LocEngSetServerUrl() { delete[] mUrl; } inline virtual void proc() const { mAdapter->setServer(mUrl, mLen); } inline void locallog() const { LOC_LOGV("LocEngSetServerUrl - url: %s", mUrl); } inline virtual void log() const { locallog(); } }; // case LOC_ENG_MSG_A_GLONASS_PROTOCOL: struct LocEngAGlonassProtocol : public LocMsg { LocEngAdapter* mAdapter; const unsigned long mAGlonassProtocl; inline LocEngAGlonassProtocol(LocEngAdapter* adapter, unsigned long protocol) : LocMsg(), mAdapter(adapter), mAGlonassProtocl(protocol) { locallog(); } inline virtual void proc() const { mAdapter->setAGLONASSProtocol(mAGlonassProtocl); } inline void locallog() const { LOC_LOGV("A-GLONASS protocol: 0x%lx", mAGlonassProtocl); } inline virtual void log() const { locallog(); } }; // case LOC_ENG_MSG_SUPL_VERSION: struct LocEngSuplVer : public LocMsg { LocEngAdapter* mAdapter; const int mSuplVer; inline LocEngSuplVer(LocEngAdapter* adapter, int suplVer) : LocMsg(), mAdapter(adapter), mSuplVer(suplVer) { locallog(); } inline virtual void proc() const { mAdapter->setSUPLVersion(mSuplVer); } inline void locallog() const { LOC_LOGV("SUPL Version: %d", mSuplVer); } inline virtual void log() const { locallog(); } }; struct LocEngSuplMode : public LocMsg { UlpProxyBase* mUlp; inline LocEngSuplMode(UlpProxyBase* ulp) : LocMsg(), mUlp(ulp) { locallog(); } inline virtual void proc() const { mUlp->setCapabilities(getCarrierCapabilities()); } inline void locallog() const { } inline virtual void log() const { locallog(); } }; // case LOC_ENG_MSG_LPP_CONFIG: struct LocEngLppConfig : public LocMsg { LocEngAdapter* mAdapter; const int mLppConfig; inline LocEngLppConfig(LocEngAdapter* adapter, int lppConfig) : LocMsg(), mAdapter(adapter), mLppConfig(lppConfig) { locallog(); } inline virtual void proc() const { mAdapter->setLPPConfig(mLppConfig); } inline void locallog() const { LOC_LOGV("LocEngLppConfig - profile: %d", mLppConfig); } inline virtual void log() const { locallog(); } }; // case LOC_ENG_MSG_SET_SENSOR_CONTROL_CONFIG: struct LocEngSensorControlConfig : public LocMsg { LocEngAdapter* mAdapter; const int mSensorsDisabled; const int mSensorProvider; inline LocEngSensorControlConfig(LocEngAdapter* adapter, int sensorsDisabled, int sensorProvider) : LocMsg(), mAdapter(adapter), mSensorsDisabled(sensorsDisabled), mSensorProvider(sensorProvider) { locallog(); } inline virtual void proc() const { mAdapter->setSensorControlConfig(mSensorsDisabled, mSensorProvider); } inline void locallog() const { LOC_LOGV("LocEngSensorControlConfig - Sensors Disabled: %d, Sensor Provider: %d", mSensorsDisabled, mSensorProvider); } inline virtual void log() const { locallog(); } }; // case LOC_ENG_MSG_SET_SENSOR_PROPERTIES: struct LocEngSensorProperties : public LocMsg { LocEngAdapter* mAdapter; const bool mGyroBiasVarianceRandomWalkValid; const float mGyroBiasVarianceRandomWalk; const bool mAccelRandomWalkValid; const float mAccelRandomWalk; const bool mAngleRandomWalkValid; const float mAngleRandomWalk; const bool mRateRandomWalkValid; const float mRateRandomWalk; const bool mVelocityRandomWalkValid; const float mVelocityRandomWalk; inline LocEngSensorProperties(LocEngAdapter* adapter, bool gyroBiasRandomWalk_valid, float gyroBiasRandomWalk, bool accelRandomWalk_valid, float accelRandomWalk, bool angleRandomWalk_valid, float angleRandomWalk, bool rateRandomWalk_valid, float rateRandomWalk, bool velocityRandomWalk_valid, float velocityRandomWalk) : LocMsg(), mAdapter(adapter), mGyroBiasVarianceRandomWalkValid(gyroBiasRandomWalk_valid), mGyroBiasVarianceRandomWalk(gyroBiasRandomWalk), mAccelRandomWalkValid(accelRandomWalk_valid), mAccelRandomWalk(accelRandomWalk), mAngleRandomWalkValid(angleRandomWalk_valid), mAngleRandomWalk(angleRandomWalk), mRateRandomWalkValid(rateRandomWalk_valid), mRateRandomWalk(rateRandomWalk), mVelocityRandomWalkValid(velocityRandomWalk_valid), mVelocityRandomWalk(velocityRandomWalk) { locallog(); } inline virtual void proc() const { mAdapter->setSensorProperties(mGyroBiasVarianceRandomWalkValid, mGyroBiasVarianceRandomWalk, mAccelRandomWalkValid, mAccelRandomWalk, mAngleRandomWalkValid, mAngleRandomWalk, mRateRandomWalkValid, mRateRandomWalk, mVelocityRandomWalkValid, mVelocityRandomWalk); } inline void locallog() const { LOC_LOGV("Sensor properties validity, Gyro Random walk: %d " "Accel Random Walk: %d " "Angle Random Walk: %d Rate Random Walk: %d " "Velocity Random Walk: %d\n" "Sensor properties, Gyro Random walk: %f " "Accel Random Walk: %f " "Angle Random Walk: %f Rate Random Walk: %f " "Velocity Random Walk: %f", mGyroBiasVarianceRandomWalkValid, mAccelRandomWalkValid, mAngleRandomWalkValid, mRateRandomWalkValid, mVelocityRandomWalkValid, mGyroBiasVarianceRandomWalk, mAccelRandomWalk, mAngleRandomWalk, mRateRandomWalk, mVelocityRandomWalk ); } inline virtual void log() const { locallog(); } }; // case LOC_ENG_MSG_SET_SENSOR_PERF_CONTROL_CONFIG: struct LocEngSensorPerfControlConfig : public LocMsg { LocEngAdapter* mAdapter; const int mControlMode; const int mAccelSamplesPerBatch; const int mAccelBatchesPerSec; const int mGyroSamplesPerBatch; const int mGyroBatchesPerSec; const int mAccelSamplesPerBatchHigh; const int mAccelBatchesPerSecHigh; const int mGyroSamplesPerBatchHigh; const int mGyroBatchesPerSecHigh; const int mAlgorithmConfig; inline LocEngSensorPerfControlConfig(LocEngAdapter* adapter, int controlMode, int accelSamplesPerBatch, int accelBatchesPerSec, int gyroSamplesPerBatch, int gyroBatchesPerSec, int accelSamplesPerBatchHigh, int accelBatchesPerSecHigh, int gyroSamplesPerBatchHigh, int gyroBatchesPerSecHigh, int algorithmConfig) : LocMsg(), mAdapter(adapter), mControlMode(controlMode), mAccelSamplesPerBatch(accelSamplesPerBatch), mAccelBatchesPerSec(accelBatchesPerSec), mGyroSamplesPerBatch(gyroSamplesPerBatch), mGyroBatchesPerSec(gyroBatchesPerSec), mAccelSamplesPerBatchHigh(accelSamplesPerBatchHigh), mAccelBatchesPerSecHigh(accelBatchesPerSecHigh), mGyroSamplesPerBatchHigh(gyroSamplesPerBatchHigh), mGyroBatchesPerSecHigh(gyroBatchesPerSecHigh), mAlgorithmConfig(algorithmConfig) { locallog(); } inline virtual void proc() const { mAdapter->setSensorPerfControlConfig(mControlMode, mAccelSamplesPerBatch, mAccelBatchesPerSec, mGyroSamplesPerBatch, mGyroBatchesPerSec, mAccelSamplesPerBatchHigh, mAccelBatchesPerSecHigh, mGyroSamplesPerBatchHigh, mGyroBatchesPerSecHigh, mAlgorithmConfig); } inline void locallog() const { LOC_LOGV("Sensor Perf Control Config (performanceControlMode)(%u) " "accel(#smp,#batches) (%u,%u) " "gyro(#smp,#batches) (%u,%u), " "accel_high(#smp,#batches) (%u,%u) " "gyro_high(#smp,#batches) (%u,%u), " "algorithmConfig(%u)\n", mControlMode, mAccelSamplesPerBatch, mAccelBatchesPerSec, mGyroSamplesPerBatch, mGyroBatchesPerSec, mAccelSamplesPerBatchHigh, mAccelBatchesPerSecHigh, mGyroSamplesPerBatchHigh, mGyroBatchesPerSecHigh, mAlgorithmConfig); } inline virtual void log() const { locallog(); } }; // case LOC_ENG_MSG_EXT_POWER_CONFIG: struct LocEngExtPowerConfig : public LocMsg { LocEngAdapter* mAdapter; const int mIsBatteryCharging; inline LocEngExtPowerConfig(LocEngAdapter* adapter, int isBatteryCharging) : LocMsg(), mAdapter(adapter), mIsBatteryCharging(isBatteryCharging) { locallog(); } inline virtual void proc() const { mAdapter->setExtPowerConfig(mIsBatteryCharging); } inline void locallog() const { LOC_LOGV("LocEngExtPowerConfig - isBatteryCharging: %d", mIsBatteryCharging); } inline virtual void log() const { locallog(); } }; // case LOC_ENG_MSG_REPORT_POSITION: LocEngReportPosition::LocEngReportPosition(LocAdapterBase* adapter, UlpLocation &loc, GpsLocationExtended &locExtended, void* locExt, enum loc_sess_status st, LocPosTechMask technology) : LocMsg(), mAdapter(adapter), mLocation(loc), mLocationExtended(locExtended), mLocationExt(((loc_eng_data_s_type*) ((LocEngAdapter*) (mAdapter))->getOwner())->location_ext_parser(locExt)), mStatus(st), mTechMask(technology) { locallog(); } void LocEngReportPosition::proc() const { LocEngAdapter* adapter = (LocEngAdapter*)mAdapter; loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)adapter->getOwner(); if (locEng->mute_session_state != LOC_MUTE_SESS_IN_SESSION) { bool reported = false; if (locEng->location_cb != NULL) { if (LOC_SESS_FAILURE == mStatus) { // in case we want to handle the failure case locEng->location_cb(NULL, NULL); reported = true; } // what's in the else if is... (line by line) // 1. this is a final fix; and // 1.1 it is a Satellite fix; or // 1.2 it is a sensor fix // 2. (must be intermediate fix... implicit) // 2.1 we accepte intermediate; and // 2.2 it is NOT the case that // 2.2.1 there is inaccuracy; and // 2.2.2 we care about inaccuracy; and // 2.2.3 the inaccuracy exceeds our tolerance else if ((LOC_SESS_SUCCESS == mStatus && ((LOC_POS_TECH_MASK_SATELLITE | LOC_POS_TECH_MASK_SENSORS | LOC_POS_TECH_MASK_HYBRID) & mTechMask)) || (LOC_SESS_INTERMEDIATE == locEng->intermediateFix && !((mLocation.gpsLocation.flags & GPS_LOCATION_HAS_ACCURACY) && (gps_conf.ACCURACY_THRES != 0) && (mLocation.gpsLocation.accuracy > gps_conf.ACCURACY_THRES)))) { locEng->location_cb((UlpLocation*)&(mLocation), (void*)mLocationExt); reported = true; } } // if we have reported this fix if (reported && // and if this is a singleshot GPS_POSITION_RECURRENCE_SINGLE == locEng->adapter->getPositionMode().recurrence) { if (LOC_SESS_INTERMEDIATE == mStatus) { // modem could be still working for a final fix, // although we no longer need it. So stopFix(). locEng->adapter->stopFix(); } // turn off the session flag. locEng->adapter->setInSession(false); } LOC_LOGV("LocEngReportPosition::proc() - generateNmea: %d, position source: %d, " "engine_status: %d, isInSession: %d", locEng->generateNmea, mLocation.position_source, locEng->engine_status, locEng->adapter->isInSession()); if (locEng->generateNmea && locEng->adapter->isInSession()) { unsigned char generate_nmea = reported && (mStatus != LOC_SESS_FAILURE); loc_eng_nmea_generate_pos(locEng, mLocation, mLocationExtended, generate_nmea); } // Free the allocated memory for rawData UlpLocation* gp = (UlpLocation*)&(mLocation); if (gp != NULL && gp->rawData != NULL) { delete (char*)gp->rawData; gp->rawData = NULL; gp->rawDataSize = 0; } } } void LocEngReportPosition::locallog() const { LOC_LOGV("LocEngReportPosition"); } void LocEngReportPosition::log() const { locallog(); } void LocEngReportPosition::send() const { mAdapter->sendMsg(this); } // case LOC_ENG_MSG_REPORT_SV: LocEngReportSv::LocEngReportSv(LocAdapterBase* adapter, QcomSvStatus &sv, GpsLocationExtended &locExtended, void* svExt) : LocMsg(), mAdapter(adapter), mSvStatus(sv), mLocationExtended(locExtended), mSvExt(((loc_eng_data_s_type*) ((LocEngAdapter*) (mAdapter))->getOwner())->sv_ext_parser(svExt)) { locallog(); } void LocEngReportSv::proc() const { LocEngAdapter* adapter = (LocEngAdapter*)mAdapter; loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)adapter->getOwner(); if (locEng->mute_session_state != LOC_MUTE_SESS_IN_SESSION) { if (locEng->sv_status_cb != NULL) { locEng->sv_status_cb((GpsSvStatus*)&(mSvStatus), (void*)mSvExt); } if (locEng->generateNmea) { loc_eng_nmea_generate_sv(locEng, mSvStatus, mLocationExtended); } } } void LocEngReportSv::locallog() const { LOC_LOGV("%s:%d] LocEngReportSv",__func__, __LINE__); } inline void LocEngReportSv::log() const { locallog(); } void LocEngReportSv::send() const { mAdapter->sendMsg(this); } // case LOC_ENG_MSG_REPORT_STATUS: LocEngReportStatus::LocEngReportStatus(LocAdapterBase* adapter, GpsStatusValue engineStatus) : LocMsg(), mAdapter(adapter), mStatus(engineStatus) { locallog(); } inline void LocEngReportStatus::proc() const { LocEngAdapter* adapter = (LocEngAdapter*)mAdapter; loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)adapter->getOwner(); loc_eng_report_status(*locEng, mStatus); update_aiding_data_for_deletion(*locEng); } inline void LocEngReportStatus::locallog() const { LOC_LOGV("LocEngReportStatus"); } inline void LocEngReportStatus::log() const { locallog(); } // case LOC_ENG_MSG_REPORT_NMEA: LocEngReportNmea::LocEngReportNmea(void* locEng, const char* data, int len) : LocMsg(), mLocEng(locEng), mNmea(new char[len]), mLen(len) { memcpy((void*)mNmea, (void*)data, len); locallog(); } void LocEngReportNmea::proc() const { loc_eng_data_s_type* locEng = (loc_eng_data_s_type*) mLocEng; struct timeval tv; gettimeofday(&tv, (struct timezone *) NULL); int64_t now = tv.tv_sec * 1000LL + tv.tv_usec / 1000; CALLBACK_LOG_CALLFLOW("nmea_cb", %d, mLen); if (locEng->nmea_cb != NULL) locEng->nmea_cb(now, mNmea, mLen); } inline void LocEngReportNmea::locallog() const { LOC_LOGV("LocEngReportNmea"); } inline void LocEngReportNmea::log() const { locallog(); } // case LOC_ENG_MSG_REPORT_XTRA_SERVER: LocEngReportXtraServer::LocEngReportXtraServer(void* locEng, const char *url1, const char *url2, const char *url3, const int maxlength) : LocMsg(), mLocEng(locEng), mMaxLen(maxlength), mServers(new char[3*(mMaxLen+1)]) { char * cptr = mServers; memset(mServers, 0, 3*(mMaxLen+1)); // Override modem URLs with uncommented gps.conf urls if( gps_conf.XTRA_SERVER_1[0] != '\0' ) { url1 = &gps_conf.XTRA_SERVER_1[0]; } if( gps_conf.XTRA_SERVER_2[0] != '\0' ) { url2 = &gps_conf.XTRA_SERVER_2[0]; } if( gps_conf.XTRA_SERVER_3[0] != '\0' ) { url3 = &gps_conf.XTRA_SERVER_3[0]; } // copy non xtra1.gpsonextra.net URLs into the forwarding buffer. if( NULL == strcasestr(url1, XTRA1_GPSONEXTRA) ) { strlcpy(cptr, url1, mMaxLen + 1); cptr += mMaxLen + 1; } if( NULL == strcasestr(url2, XTRA1_GPSONEXTRA) ) { strlcpy(cptr, url2, mMaxLen + 1); cptr += mMaxLen + 1; } if( NULL == strcasestr(url3, XTRA1_GPSONEXTRA) ) { strlcpy(cptr, url3, mMaxLen + 1); } locallog(); } void LocEngReportXtraServer::proc() const { loc_eng_xtra_data_s_type* locEngXtra = &(((loc_eng_data_s_type*)mLocEng)->xtra_module_data); if (locEngXtra->report_xtra_server_cb != NULL) { CALLBACK_LOG_CALLFLOW("report_xtra_server_cb", %s, mServers); locEngXtra->report_xtra_server_cb(mServers, &(mServers[mMaxLen+1]), &(mServers[(mMaxLen+1)<<1])); } else { LOC_LOGE("Callback function for request xtra is NULL"); } } inline void LocEngReportXtraServer::locallog() const { LOC_LOGV("LocEngReportXtraServers: server1: %s\n server2: %s\n" " server3: %s\n", mServers, &mServers[mMaxLen+1], &mServers[(mMaxLen+1)<<1]); } inline void LocEngReportXtraServer::log() const { locallog(); } // case LOC_ENG_MSG_REQUEST_BIT: // case LOC_ENG_MSG_RELEASE_BIT: LocEngReqRelBIT::LocEngReqRelBIT(void* locEng, AGpsExtType type, int ipv4, char* ipv6, bool isReq) : LocMsg(), mLocEng(locEng), mType(type), mIPv4Addr(ipv4), mIPv6Addr(ipv6 ? new char[16] : NULL), mIsReq(isReq) { if (NULL != ipv6) memcpy(mIPv6Addr, ipv6, 16); locallog(); } inline LocEngReqRelBIT::~LocEngReqRelBIT() { if (mIPv6Addr) { delete[] mIPv6Addr; } } void LocEngReqRelBIT::proc() const { loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng; BITSubscriber s(getAgpsStateMachine(*locEng, mType), mIPv4Addr, mIPv6Addr); AgpsStateMachine* sm = (AgpsStateMachine*)s.mStateMachine; if (mIsReq) { sm->subscribeRsrc((Subscriber*)&s); } else { sm->unsubscribeRsrc((Subscriber*)&s); } } inline void LocEngReqRelBIT::locallog() const { LOC_LOGV("LocEngRequestBIT - ipv4: %d.%d.%d.%d, ipv6: %s", (unsigned char)mIPv4Addr, (unsigned char)(mIPv4Addr>>8), (unsigned char)(mIPv4Addr>>16), (unsigned char)(mIPv4Addr>>24), NULL != mIPv6Addr ? mIPv6Addr : ""); } inline void LocEngReqRelBIT::log() const { locallog(); } void LocEngReqRelBIT::send() const { loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng; locEng->adapter->sendMsg(this); } // case LOC_ENG_MSG_RELEASE_BIT: struct LocEngReleaseBIT : public LocMsg { const BITSubscriber mSubscriber; inline LocEngReleaseBIT(const AgpsStateMachine* stateMachine, unsigned int ipv4, char* ipv6) : LocMsg(), mSubscriber(stateMachine, ipv4, ipv6) { locallog(); } inline virtual void proc() const { AgpsStateMachine* sm = (AgpsStateMachine*)mSubscriber.mStateMachine; sm->unsubscribeRsrc((Subscriber*)&mSubscriber); } inline void locallog() const { LOC_LOGV("LocEngReleaseBIT - ipv4: %d.%d.%d.%d, ipv6: %s", (unsigned char)(mSubscriber.ID>>24), (unsigned char)(mSubscriber.ID>>16), (unsigned char)(mSubscriber.ID>>8), (unsigned char)mSubscriber.ID, NULL != mSubscriber.mIPv6Addr ? mSubscriber.mIPv6Addr : ""); } virtual void log() const { locallog(); } }; // LocEngSuplEsOpened LocEngSuplEsOpened::LocEngSuplEsOpened(void* locEng) : LocMsg(), mLocEng(locEng) { locallog(); } void LocEngSuplEsOpened::proc() const { loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng; if (locEng->ds_nif) { AgpsStateMachine* sm = locEng->ds_nif; sm->onRsrcEvent(RSRC_GRANTED); } } void LocEngSuplEsOpened::locallog() const { LOC_LOGV("LocEngSuplEsOpened"); } void LocEngSuplEsOpened::log() const { locallog(); } // LocEngSuplEsClosed LocEngSuplEsClosed::LocEngSuplEsClosed(void* locEng) : LocMsg(), mLocEng(locEng) { locallog(); } void LocEngSuplEsClosed::proc() const { loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng; if (locEng->ds_nif) { AgpsStateMachine* sm = locEng->ds_nif; sm->onRsrcEvent(RSRC_RELEASED); } } void LocEngSuplEsClosed::locallog() const { LOC_LOGV("LocEngSuplEsClosed"); } void LocEngSuplEsClosed::log() const { locallog(); } // case LOC_ENG_MSG_REQUEST_SUPL_ES: LocEngRequestSuplEs::LocEngRequestSuplEs(void* locEng, int id) : LocMsg(), mLocEng(locEng), mID(id) { locallog(); } void LocEngRequestSuplEs::proc() const { loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng; if (locEng->ds_nif) { AgpsStateMachine* sm = locEng->ds_nif; DSSubscriber s(sm, mID); sm->subscribeRsrc((Subscriber*)&s); } else if (locEng->agnss_nif) { AgpsStateMachine *sm = locEng->agnss_nif; ATLSubscriber s(mID, sm, locEng->adapter, false); sm->subscribeRsrc((Subscriber*)&s); LOC_LOGD("%s:%d]: Using regular ATL for SUPL ES", __func__, __LINE__); } else { locEng->adapter->atlOpenStatus(mID, 0, NULL, -1, -1); } } inline void LocEngRequestSuplEs::locallog() const { LOC_LOGV("LocEngRequestSuplEs"); } inline void LocEngRequestSuplEs::log() const { locallog(); } // case LOC_ENG_MSG_REQUEST_ATL: LocEngRequestATL::LocEngRequestATL(void* locEng, int id, AGpsExtType agps_type) : LocMsg(), mLocEng(locEng), mID(id), mType(agps_type) { locallog(); } void LocEngRequestATL::proc() const { loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng; AgpsStateMachine* sm = (AgpsStateMachine*) getAgpsStateMachine(*locEng, mType); if (sm) { ATLSubscriber s(mID, sm, locEng->adapter, AGPS_TYPE_INVALID == mType); sm->subscribeRsrc((Subscriber*)&s); } else { locEng->adapter->atlOpenStatus(mID, 0, NULL, -1, mType); } } inline void LocEngRequestATL::locallog() const { LOC_LOGV("LocEngRequestATL"); } inline void LocEngRequestATL::log() const { locallog(); } // case LOC_ENG_MSG_RELEASE_ATL: LocEngReleaseATL::LocEngReleaseATL(void* locEng, int id) : LocMsg(), mLocEng(locEng), mID(id) { locallog(); } void LocEngReleaseATL::proc() const { loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng; if (locEng->agnss_nif) { ATLSubscriber s1(mID, locEng->agnss_nif, locEng->adapter, false); if (locEng->agnss_nif->unsubscribeRsrc((Subscriber*)&s1)) { LOC_LOGD("%s:%d]: Unsubscribed from agnss_nif", __func__, __LINE__); return; } } if (locEng->internet_nif) { ATLSubscriber s2(mID, locEng->internet_nif, locEng->adapter, false); if (locEng->internet_nif->unsubscribeRsrc((Subscriber*)&s2)) { LOC_LOGD("%s:%d]: Unsubscribed from internet_nif", __func__, __LINE__); return; } } if (locEng->ds_nif) { DSSubscriber s3(locEng->ds_nif, mID); if (locEng->ds_nif->unsubscribeRsrc((Subscriber*)&s3)) { LOC_LOGD("%s:%d]: Unsubscribed from ds_nif", __func__, __LINE__); return; } } LOC_LOGW("%s:%d]: Could not release ATL. " "No subscribers found\n", __func__, __LINE__); locEng->adapter->atlCloseStatus(mID, 0); } inline void LocEngReleaseATL::locallog() const { LOC_LOGV("LocEngReleaseATL"); } inline void LocEngReleaseATL::log() const { locallog(); } // case LOC_ENG_MSG_REQUEST_WIFI: // case LOC_ENG_MSG_RELEASE_WIFI: LocEngReqRelWifi::LocEngReqRelWifi(void* locEng, AGpsExtType type, loc_if_req_sender_id_e_type sender_id, char* s, char* p, bool isReq) : LocMsg(), mLocEng(locEng), mType(type), mSenderId(sender_id), mSSID(NULL == s ? NULL : new char[SSID_BUF_SIZE]), mPassword(NULL == p ? NULL : new char[SSID_BUF_SIZE]), mIsReq(isReq) { if (NULL != s) strlcpy(mSSID, s, SSID_BUF_SIZE); if (NULL != p) strlcpy(mPassword, p, SSID_BUF_SIZE); locallog(); } LocEngReqRelWifi::~LocEngReqRelWifi() { if (NULL != mSSID) { delete[] mSSID; } if (NULL != mPassword) { delete[] mPassword; } } void LocEngReqRelWifi::proc() const { loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng; if (locEng->wifi_nif) { WIFISubscriber s(locEng->wifi_nif, mSSID, mPassword, mSenderId); if (mIsReq) { locEng->wifi_nif->subscribeRsrc((Subscriber*)&s); } else { locEng->wifi_nif->unsubscribeRsrc((Subscriber*)&s); } } else { locEng->adapter->atlOpenStatus(mSenderId, 0, NULL, -1, mType); } } inline void LocEngReqRelWifi::locallog() const { LOC_LOGV("%s - senderId: %d, ssid: %s, password: %s", mIsReq ? "LocEngRequestWifi" : "LocEngReleaseWifi", mSenderId, NULL != mSSID ? mSSID : "", NULL != mPassword ? mPassword : ""); } inline void LocEngReqRelWifi::log() const { locallog(); } void LocEngReqRelWifi::send() const { loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng; locEng->adapter->sendMsg(this); } // case LOC_ENG_MSG_REQUEST_XTRA_DATA: LocEngRequestXtra::LocEngRequestXtra(void* locEng) : mLocEng(locEng) { locallog(); } void LocEngRequestXtra::proc() const { loc_eng_xtra_data_s_type* locEngXtra = &(((loc_eng_data_s_type*)mLocEng)->xtra_module_data); if (locEngXtra->download_request_cb != NULL) { CALLBACK_LOG_CALLFLOW("download_request_cb", %p, mLocEng); locEngXtra->download_request_cb(); } else { LOC_LOGE("Callback function for request xtra is NULL"); } } inline void LocEngRequestXtra::locallog() const { LOC_LOGV("LocEngReqXtra"); } inline void LocEngRequestXtra::log() const { locallog(); } // case LOC_ENG_MSG_REQUEST_TIME: LocEngRequestTime::LocEngRequestTime(void* locEng) : LocMsg(), mLocEng(locEng) { locallog(); } void LocEngRequestTime::proc() const { loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng; if (gps_conf.CAPABILITIES & GPS_CAPABILITY_ON_DEMAND_TIME) { if (locEng->request_utc_time_cb != NULL) { locEng->request_utc_time_cb(); } else { LOC_LOGE("Callback function for request time is NULL"); } } } inline void LocEngRequestTime::locallog() const { LOC_LOGV("LocEngReqTime"); } inline void LocEngRequestTime::log() const { locallog(); } // case LOC_ENG_MSG_DELETE_AIDING_DATA: struct LocEngDelAidData : public LocMsg { loc_eng_data_s_type* mLocEng; const GpsAidingData mType; inline LocEngDelAidData(loc_eng_data_s_type* locEng, GpsAidingData f) : LocMsg(), mLocEng(locEng), mType(f) { locallog(); } inline virtual void proc() const { mLocEng->aiding_data_for_deletion = mType; update_aiding_data_for_deletion(*mLocEng); } inline void locallog() const { LOC_LOGV("aiding data msak %d", mType); } virtual void log() const { locallog(); } }; // case LOC_ENG_MSG_ENABLE_DATA: struct LocEngEnableData : public LocMsg { LocEngAdapter* mAdapter; const int mEnable; char* mAPN; const int mLen; inline LocEngEnableData(LocEngAdapter* adapter, const char* name, int len, int enable) : LocMsg(), mAdapter(adapter), mEnable(enable), mAPN(NULL), mLen(len) { if (NULL != name) { mAPN = new char[len+1]; memcpy((void*)mAPN, (void*)name, len); mAPN[len] = 0; } locallog(); } inline ~LocEngEnableData() { if (NULL != mAPN) { delete[] mAPN; } } inline virtual void proc() const { mAdapter->enableData(mEnable); if (NULL != mAPN) { mAdapter->setAPN(mAPN, mLen); } } inline void locallog() const { LOC_LOGV("apn: %s\n enable: %d", (NULL == mAPN) ? "NULL" : mAPN, mEnable); } inline virtual void log() const { locallog(); } }; // case LOC_ENG_MSG_INJECT_XTRA_DATA: // loc_eng_xtra.cpp // case LOC_ENG_MSG_SET_CAPABILITIES: struct LocEngSetCapabilities : public LocMsg { loc_eng_data_s_type* mLocEng; inline LocEngSetCapabilities(loc_eng_data_s_type* locEng) : LocMsg(), mLocEng(locEng) { locallog(); } inline virtual void proc() const { if (NULL != mLocEng->set_capabilities_cb) { LOC_LOGV("calling set_capabilities_cb 0x%x", gps_conf.CAPABILITIES); mLocEng->set_capabilities_cb(gps_conf.CAPABILITIES); } else { LOC_LOGV("set_capabilities_cb is NULL.\n"); } } inline void locallog() const { LOC_LOGV("LocEngSetCapabilities"); } inline virtual void log() const { locallog(); } }; // case LOC_ENG_MSG_LOC_INIT: struct LocEngInit : public LocMsg { loc_eng_data_s_type* mLocEng; inline LocEngInit(loc_eng_data_s_type* locEng) : LocMsg(), mLocEng(locEng) { locallog(); } inline virtual void proc() const { loc_eng_reinit(*mLocEng); // set the capabilities mLocEng->adapter->sendMsg(new LocEngSetCapabilities(mLocEng)); } inline void locallog() const { LOC_LOGV("LocEngInit"); } inline virtual void log() const { locallog(); } }; // case LOC_ENG_MSG_REQUEST_XTRA_SERVER: // loc_eng_xtra.cpp // case LOC_ENG_MSG_ATL_OPEN_SUCCESS: struct LocEngAtlOpenSuccess : public LocMsg { AgpsStateMachine* mStateMachine; const int mLen; char* mAPN; const AGpsBearerType mBearerType; inline LocEngAtlOpenSuccess(AgpsStateMachine* statemachine, const char* name, int len, AGpsBearerType btype) : LocMsg(), mStateMachine(statemachine), mLen(len), mAPN(new char[len+1]), mBearerType(btype) { memcpy((void*)mAPN, (void*)name, len); mAPN[len] = 0; locallog(); } inline ~LocEngAtlOpenSuccess() { delete[] mAPN; } inline virtual void proc() const { mStateMachine->setBearer(mBearerType); mStateMachine->setAPN(mAPN, mLen); mStateMachine->onRsrcEvent(RSRC_GRANTED); } inline void locallog() const { LOC_LOGV("LocEngAtlOpenSuccess agps type: %s\n apn: %s\n" " bearer type: %s", loc_get_agps_type_name(mStateMachine->getType()), mAPN, loc_get_agps_bear_name(mBearerType)); } inline virtual void log() const { locallog(); } }; // case LOC_ENG_MSG_ATL_CLOSED: struct LocEngAtlClosed : public LocMsg { AgpsStateMachine* mStateMachine; inline LocEngAtlClosed(AgpsStateMachine* statemachine) : LocMsg(), mStateMachine(statemachine) { locallog(); } inline virtual void proc() const { mStateMachine->onRsrcEvent(RSRC_RELEASED); } inline void locallog() const { LOC_LOGV("LocEngAtlClosed"); } inline virtual void log() const { locallog(); } }; // case LOC_ENG_MSG_ATL_OPEN_FAILED: struct LocEngAtlOpenFailed : public LocMsg { AgpsStateMachine* mStateMachine; inline LocEngAtlOpenFailed(AgpsStateMachine* statemachine) : LocMsg(), mStateMachine(statemachine) { locallog(); } inline virtual void proc() const { mStateMachine->onRsrcEvent(RSRC_DENIED); } inline void locallog() const { LOC_LOGV("LocEngAtlOpenFailed"); } inline virtual void log() const { locallog(); } }; // case LOC_ENG_MSG_ENGINE_DOWN: LocEngDown::LocEngDown(void* locEng) : LocMsg(), mLocEng(locEng) { locallog(); } inline void LocEngDown::proc() const { loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng; loc_eng_handle_engine_down(*locEng); } inline void LocEngDown::locallog() const { LOC_LOGV("LocEngDown"); } inline void LocEngDown::log() const { locallog(); } // case LOC_ENG_MSG_ENGINE_UP: LocEngUp::LocEngUp(void* locEng) : LocMsg(), mLocEng(locEng) { locallog(); } inline void LocEngUp::proc() const { loc_eng_data_s_type* locEng = (loc_eng_data_s_type*)mLocEng; loc_eng_handle_engine_up(*locEng); } inline void LocEngUp::locallog() const { LOC_LOGV("LocEngUp"); } inline void LocEngUp::log() const { locallog(); } struct LocEngDataClientInit : public LocMsg { loc_eng_data_s_type* mLocEng; inline LocEngDataClientInit(loc_eng_data_s_type* locEng) : LocMsg(), mLocEng(locEng) { locallog(); } virtual void proc() const { loc_eng_data_s_type *locEng = (loc_eng_data_s_type *)mLocEng; if(!locEng->adapter->initDataServiceClient()) { locEng->ds_nif = new DSStateMachine(servicerTypeExt, (void *)dataCallCb, locEng->adapter); } } void locallog() const { LOC_LOGV("LocEngDataClientInit\n"); } virtual void log() const { locallog(); } }; struct LocEngInstallAGpsCert : public LocMsg { LocEngAdapter* mpAdapter; const size_t mNumberOfCerts; const uint32_t mSlotBitMask; DerEncodedCertificate* mpData; inline LocEngInstallAGpsCert(LocEngAdapter* adapter, const DerEncodedCertificate* pData, size_t numberOfCerts, uint32_t slotBitMask) : LocMsg(), mpAdapter(adapter), mNumberOfCerts(numberOfCerts), mSlotBitMask(slotBitMask), mpData(new DerEncodedCertificate[mNumberOfCerts]) { for (int i=0; i < mNumberOfCerts; i++) { mpData[i].data = new u_char[pData[i].length]; if (mpData[i].data) { memcpy(mpData[i].data, (void*)pData[i].data, pData[i].length); mpData[i].length = pData[i].length; } else { LOC_LOGE("malloc failed for cert#%d", i); break; } } locallog(); } inline ~LocEngInstallAGpsCert() { for (int i=0; i < mNumberOfCerts; i++) { if (mpData[i].data) { delete[] mpData[i].data; } } delete[] mpData; } inline virtual void proc() const { mpAdapter->installAGpsCert(mpData, mNumberOfCerts, mSlotBitMask); } inline void locallog() const { LOC_LOGV("LocEngInstallAGpsCert - certs=%u mask=%u", mNumberOfCerts, mSlotBitMask); } inline virtual void log() const { locallog(); } }; struct LocEngUpdateRegistrationMask : public LocMsg { loc_eng_data_s_type* mLocEng; LOC_API_ADAPTER_EVENT_MASK_T mMask; loc_registration_mask_status mIsEnabled; inline LocEngUpdateRegistrationMask(loc_eng_data_s_type* locEng, LOC_API_ADAPTER_EVENT_MASK_T mask, loc_registration_mask_status isEnabled) : LocMsg(), mLocEng(locEng), mMask(mask), mIsEnabled(isEnabled) { locallog(); } inline virtual void proc() const { loc_eng_data_s_type *locEng = (loc_eng_data_s_type *)mLocEng; locEng->adapter->updateRegistrationMask(mMask, mIsEnabled); } void locallog() const { LOC_LOGV("LocEngUpdateRegistrationMask\n"); } virtual void log() const { locallog(); } }; struct LocEngGnssConstellationConfig : public LocMsg { LocEngAdapter* mAdapter; inline LocEngGnssConstellationConfig(LocEngAdapter* adapter) : LocMsg(), mAdapter(adapter) { locallog(); } inline virtual void proc() const { if (mAdapter->gnssConstellationConfig()) { LOC_LOGV("Modem supports GNSS measurements\n"); gps_conf.CAPABILITIES |= GPS_CAPABILITY_MEASUREMENTS; } else { LOC_LOGV("Modem does not support GNSS measurements\n"); } } void locallog() const { LOC_LOGV("LocEngGnssConstellationConfig\n"); } virtual void log() const { locallog(); } }; // case LOC_ENG_MSG_REPORT_GNSS_MEASUREMENT: LocEngReportGpsMeasurement::LocEngReportGpsMeasurement(void* locEng, GpsData &gpsData) : LocMsg(), mLocEng(locEng), mGpsData(gpsData) { locallog(); } void LocEngReportGpsMeasurement::proc() const { loc_eng_data_s_type* locEng = (loc_eng_data_s_type*) mLocEng; if (locEng->mute_session_state != LOC_MUTE_SESS_IN_SESSION) { if (locEng->gps_measurement_cb != NULL) { locEng->gps_measurement_cb((GpsData*)&(mGpsData)); } } } void LocEngReportGpsMeasurement::locallog() const { IF_LOC_LOGV { LOC_LOGV("%s:%d]: Received in GPS HAL." "GNSS Measurements count: %d \n", __func__, __LINE__, mGpsData.measurement_count); for (int i =0; i< mGpsData.measurement_count && i < GPS_MAX_SVS; i++) { LOC_LOGV(" GNSS measurement data in GPS HAL: \n" " GPS_HAL => Measurement ID | prn | time_offset_ns | state |" " received_gps_tow_ns| c_n0_dbhz | pseudorange_rate_mps |" " pseudorange_rate_uncertainty_mps |" " accumulated_delta_range_state | flags \n" " GPS_HAL => %d | %d | %f | %d | %lld | %f | %f | %f | %d | %d \n", i, mGpsData.measurements[i].prn, mGpsData.measurements[i].time_offset_ns, mGpsData.measurements[i].state, mGpsData.measurements[i].received_gps_tow_ns, mGpsData.measurements[i].c_n0_dbhz, mGpsData.measurements[i].pseudorange_rate_mps, mGpsData.measurements[i].pseudorange_rate_uncertainty_mps, mGpsData.measurements[i].accumulated_delta_range_state, mGpsData.measurements[i].flags); } LOC_LOGV(" GPS_HAL => Clocks Info: type | time_ns \n" " GPS_HAL => Clocks Info: %d | %lld", mGpsData.clock.type, mGpsData.clock.time_ns); } } inline void LocEngReportGpsMeasurement::log() const { locallog(); } /********************************************************************* * Initialization checking macros *********************************************************************/ #define STATE_CHECK(ctx, x, ret) \ if (!(ctx)) \ { \ /* Not intialized, abort */\ LOC_LOGE("%s: log_eng state error: %s", __func__, x); \ EXIT_LOG(%s, x); \ ret; \ } #define INIT_CHECK(ctx, ret) STATE_CHECK(ctx, "instance not initialized", ret) uint32_t getCarrierCapabilities() { #define carrierMSA (uint32_t)0x2 #define carrierMSB (uint32_t)0x1 #define gpsConfMSA (uint32_t)0x4 #define gpsConfMSB (uint32_t)0x2 uint32_t capabilities = gps_conf.CAPABILITIES; if ((gps_conf.SUPL_MODE & carrierMSA) != carrierMSA) { capabilities &= ~gpsConfMSA; } if ((gps_conf.SUPL_MODE & carrierMSB) != carrierMSB) { capabilities &= ~gpsConfMSB; } LOC_LOGV("getCarrierCapabilities: CAPABILITIES %x, SUPL_MODE %x, carrier capabilities %x", gps_conf.CAPABILITIES, gps_conf.SUPL_MODE, capabilities); return capabilities; } /*=========================================================================== FUNCTION loc_eng_init DESCRIPTION Initialize the location engine, this include setting up global datas and registers location engien with loc api service. DEPENDENCIES None RETURN VALUE 0: success SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_init(loc_eng_data_s_type &loc_eng_data, LocCallbacks* callbacks, LOC_API_ADAPTER_EVENT_MASK_T event, ContextBase* context) { int ret_val = 0; ENTRY_LOG_CALLFLOW(); if (NULL == callbacks || 0 == event) { LOC_LOGE("loc_eng_init: bad parameters cb %p eMask %d", callbacks, event); ret_val = -1; EXIT_LOG(%d, ret_val); return ret_val; } STATE_CHECK((NULL == loc_eng_data.adapter), "instance already initialized", return 0); memset(&loc_eng_data, 0, sizeof (loc_eng_data)); // Save callbacks loc_eng_data.location_cb = callbacks->location_cb; loc_eng_data.sv_status_cb = callbacks->sv_status_cb; loc_eng_data.status_cb = callbacks->status_cb; loc_eng_data.nmea_cb = callbacks->nmea_cb; loc_eng_data.set_capabilities_cb = callbacks->set_capabilities_cb; loc_eng_data.acquire_wakelock_cb = callbacks->acquire_wakelock_cb; loc_eng_data.release_wakelock_cb = callbacks->release_wakelock_cb; loc_eng_data.request_utc_time_cb = callbacks->request_utc_time_cb; loc_eng_data.location_ext_parser = callbacks->location_ext_parser ? callbacks->location_ext_parser : noProc; loc_eng_data.sv_ext_parser = callbacks->sv_ext_parser ? callbacks->sv_ext_parser : noProc; loc_eng_data.intermediateFix = gps_conf.INTERMEDIATE_POS; // initial states taken care of by the memset above // loc_eng_data.engine_status -- GPS_STATUS_NONE; // loc_eng_data.fix_session_status -- GPS_STATUS_NONE; // loc_eng_data.mute_session_state -- LOC_MUTE_SESS_NONE; if ((event & LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT) && (gps_conf.NMEA_PROVIDER == NMEA_PROVIDER_AP)) { event = event ^ LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT; // unregister for modem NMEA report loc_eng_data.generateNmea = true; } else { loc_eng_data.generateNmea = false; } loc_eng_data.adapter = new LocEngAdapter(event, &loc_eng_data, context, (LocThread::tCreate)callbacks->create_thread_cb); LOC_LOGD("loc_eng_init created client, id = %p\n", loc_eng_data.adapter); loc_eng_data.adapter->sendMsg(new LocEngInit(&loc_eng_data)); EXIT_LOG(%d, ret_val); return ret_val; } static int loc_eng_reinit(loc_eng_data_s_type &loc_eng_data) { ENTRY_LOG(); int ret_val = LOC_API_ADAPTER_ERR_SUCCESS; LocEngAdapter* adapter = loc_eng_data.adapter; adapter->sendMsg(new LocEngGnssConstellationConfig(adapter)); adapter->sendMsg(new LocEngSuplVer(adapter, gps_conf.SUPL_VER)); adapter->sendMsg(new LocEngLppConfig(adapter, gps_conf.LPP_PROFILE)); adapter->sendMsg(new LocEngSensorControlConfig(adapter, sap_conf.SENSOR_USAGE, sap_conf.SENSOR_PROVIDER)); adapter->sendMsg(new LocEngAGlonassProtocol(adapter, gps_conf.A_GLONASS_POS_PROTOCOL_SELECT)); /* Make sure at least one of the sensor property is specified by the user in the gps.conf file. */ if( sap_conf.GYRO_BIAS_RANDOM_WALK_VALID || sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID || sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID || sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID || sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID ) { adapter->sendMsg(new LocEngSensorProperties(adapter, sap_conf.GYRO_BIAS_RANDOM_WALK_VALID, sap_conf.GYRO_BIAS_RANDOM_WALK, sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID, sap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY, sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID, sap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY, sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID, sap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY, sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID, sap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY)); } adapter->sendMsg(new LocEngSensorPerfControlConfig(adapter, sap_conf.SENSOR_CONTROL_MODE, sap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH, sap_conf.SENSOR_ACCEL_BATCHES_PER_SEC, sap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH, sap_conf.SENSOR_GYRO_BATCHES_PER_SEC, sap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH, sap_conf.SENSOR_ACCEL_BATCHES_PER_SEC_HIGH, sap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH, sap_conf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH, sap_conf.SENSOR_ALGORITHM_CONFIG_MASK)); adapter->sendMsg(new LocEngEnableData(adapter, NULL, 0, (agpsStatus ? 1:0))); loc_eng_xtra_version_check(loc_eng_data, gps_conf.XTRA_VERSION_CHECK); LOC_LOGD("loc_eng_reinit reinit() successful"); EXIT_LOG(%d, ret_val); return ret_val; } /*=========================================================================== FUNCTION loc_eng_cleanup DESCRIPTION Cleans location engine. The location client handle will be released. DEPENDENCIES None RETURN VALUE None SIDE EFFECTS N/A ===========================================================================*/ void loc_eng_cleanup(loc_eng_data_s_type &loc_eng_data) { ENTRY_LOG_CALLFLOW(); INIT_CHECK(loc_eng_data.adapter, return); // XTRA has no state, so we are fine with it. // we need to check and clear NI #if 0 // we need to check and clear ATL if (NULL != loc_eng_data.agnss_nif) { delete loc_eng_data.agnss_nif; loc_eng_data.agnss_nif = NULL; } if (NULL != loc_eng_data.internet_nif) { delete loc_eng_data.internet_nif; loc_eng_data.internet_nif = NULL; } #endif if (loc_eng_data.adapter->isInSession()) { LOC_LOGD("loc_eng_cleanup: fix not stopped. stop it now."); loc_eng_stop(loc_eng_data); } #if 0 // can't afford to actually clean up, for many reason. LOC_LOGD("loc_eng_init: client opened. close it now."); delete loc_eng_data.adapter; loc_eng_data.adapter = NULL; loc_eng_dmn_conn_loc_api_server_unblock(); loc_eng_dmn_conn_loc_api_server_join(); #endif EXIT_LOG(%s, VOID_RET); } /*=========================================================================== FUNCTION loc_eng_start DESCRIPTION Starts the tracking session DEPENDENCIES None RETURN VALUE 0: success SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_start(loc_eng_data_s_type &loc_eng_data) { ENTRY_LOG_CALLFLOW(); INIT_CHECK(loc_eng_data.adapter, return -1); if(! loc_eng_data.adapter->getUlpProxy()->sendStartFix()) { loc_eng_data.adapter->sendMsg(new LocEngStartFix(loc_eng_data.adapter)); } EXIT_LOG(%d, 0); return 0; } static int loc_eng_start_handler(loc_eng_data_s_type &loc_eng_data) { ENTRY_LOG(); int ret_val = LOC_API_ADAPTER_ERR_SUCCESS; if (!loc_eng_data.adapter->isInSession()) { ret_val = loc_eng_data.adapter->startFix(); if (ret_val == LOC_API_ADAPTER_ERR_SUCCESS || ret_val == LOC_API_ADAPTER_ERR_ENGINE_DOWN || ret_val == LOC_API_ADAPTER_ERR_PHONE_OFFLINE || ret_val == LOC_API_ADAPTER_ERR_INTERNAL) { loc_eng_data.adapter->setInSession(TRUE); } } EXIT_LOG(%d, ret_val); return ret_val; } /*=========================================================================== FUNCTION loc_eng_stop_wrapper DESCRIPTION Stops the tracking session DEPENDENCIES None RETURN VALUE 0: success SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_stop(loc_eng_data_s_type &loc_eng_data) { ENTRY_LOG_CALLFLOW(); INIT_CHECK(loc_eng_data.adapter, return -1); if(! loc_eng_data.adapter->getUlpProxy()->sendStopFix()) { loc_eng_data.adapter->sendMsg(new LocEngStopFix(loc_eng_data.adapter)); } EXIT_LOG(%d, 0); return 0; } static int loc_eng_stop_handler(loc_eng_data_s_type &loc_eng_data) { ENTRY_LOG(); int ret_val = LOC_API_ADAPTER_ERR_SUCCESS; if (loc_eng_data.adapter->isInSession()) { ret_val = loc_eng_data.adapter->stopFix(); loc_eng_data.adapter->setInSession(FALSE); } EXIT_LOG(%d, ret_val); return ret_val; } /*=========================================================================== FUNCTION loc_eng_mute_one_session DESCRIPTION Mutes one session DEPENDENCIES None RETURN VALUE 0: Success SIDE EFFECTS N/A ===========================================================================*/ void loc_eng_mute_one_session(loc_eng_data_s_type &loc_eng_data) { ENTRY_LOG(); loc_eng_data.mute_session_state = LOC_MUTE_SESS_WAIT; EXIT_LOG(%s, VOID_RET); } /*=========================================================================== FUNCTION loc_eng_set_position_mode DESCRIPTION Sets the mode and fix frequency for the tracking session. DEPENDENCIES None RETURN VALUE 0: success SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_set_position_mode(loc_eng_data_s_type &loc_eng_data, LocPosMode ¶ms) { ENTRY_LOG_CALLFLOW(); INIT_CHECK(loc_eng_data.adapter, return -1); // The position mode for AUTO/GSS/QCA1530 can only be standalone if (!(gps_conf.CAPABILITIES & GPS_CAPABILITY_MSB) && !(gps_conf.CAPABILITIES & GPS_CAPABILITY_MSA) && (params.mode != LOC_POSITION_MODE_STANDALONE)) { params.mode = LOC_POSITION_MODE_STANDALONE; LOC_LOGD("Position mode changed to standalone for target with AUTO/GSS/qca1530."); } if(! loc_eng_data.adapter->getUlpProxy()->sendFixMode(params)) { LocEngAdapter* adapter = loc_eng_data.adapter; adapter->sendMsg(new LocEngPositionMode(adapter, params)); } EXIT_LOG(%d, 0); return 0; } /*=========================================================================== FUNCTION loc_eng_inject_time DESCRIPTION This is used by Java native function to do time injection. DEPENDENCIES None RETURN VALUE 0 SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_inject_time(loc_eng_data_s_type &loc_eng_data, GpsUtcTime time, int64_t timeReference, int uncertainty) { ENTRY_LOG_CALLFLOW(); INIT_CHECK(loc_eng_data.adapter, return -1); LocEngAdapter* adapter = loc_eng_data.adapter; adapter->sendMsg(new LocEngSetTime(adapter, time, timeReference, uncertainty)); EXIT_LOG(%d, 0); return 0; } /*=========================================================================== FUNCTION loc_eng_inject_location DESCRIPTION This is used by Java native function to do location injection. DEPENDENCIES None RETURN VALUE 0 : Successful error code : Failure SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_inject_location(loc_eng_data_s_type &loc_eng_data, double latitude, double longitude, float accuracy) { ENTRY_LOG_CALLFLOW(); INIT_CHECK(loc_eng_data.adapter, return -1); LocEngAdapter* adapter = loc_eng_data.adapter; if(adapter->mSupportsPositionInjection) { adapter->sendMsg(new LocEngInjectLocation(adapter, latitude, longitude, accuracy)); } EXIT_LOG(%d, 0); return 0; } /*=========================================================================== FUNCTION loc_eng_delete_aiding_data DESCRIPTION This is used by Java native function to delete the aiding data. The function updates the global variable for the aiding data to be deleted. If the GPS engine is off, the aiding data will be deleted. Otherwise, the actual action will happen when gps engine is turned off. DEPENDENCIES Assumes the aiding data type specified in GpsAidingData matches with LOC API specification. RETURN VALUE None SIDE EFFECTS N/A ===========================================================================*/ void loc_eng_delete_aiding_data(loc_eng_data_s_type &loc_eng_data, GpsAidingData f) { ENTRY_LOG_CALLFLOW(); INIT_CHECK(loc_eng_data.adapter, return); loc_eng_data.adapter->sendMsg(new LocEngDelAidData(&loc_eng_data, f)); EXIT_LOG(%s, VOID_RET); } /*=========================================================================== FUNCTION loc_inform_gps_state DESCRIPTION Informs the GPS Provider about the GPS status DEPENDENCIES None RETURN VALUE None SIDE EFFECTS N/A ===========================================================================*/ static void loc_inform_gps_status(loc_eng_data_s_type &loc_eng_data, GpsStatusValue status) { ENTRY_LOG(); if (loc_eng_data.status_cb) { GpsStatus gs = { sizeof(gs),status }; CALLBACK_LOG_CALLFLOW("status_cb", %s, loc_get_gps_status_name(gs.status)); loc_eng_data.status_cb(&gs); } EXIT_LOG(%s, VOID_RET); } static int loc_eng_get_zpp_handler(loc_eng_data_s_type &loc_eng_data) { ENTRY_LOG(); int ret_val = LOC_API_ADAPTER_ERR_SUCCESS; UlpLocation location; LocPosTechMask tech_mask = LOC_POS_TECH_MASK_DEFAULT; GpsLocationExtended locationExtended; memset(&locationExtended, 0, sizeof (GpsLocationExtended)); locationExtended.size = sizeof(locationExtended); ret_val = loc_eng_data.adapter->getZpp(location.gpsLocation, tech_mask); //Mark the location source as from ZPP location.gpsLocation.flags |= LOCATION_HAS_SOURCE_INFO; location.position_source = ULP_LOCATION_IS_FROM_ZPP; loc_eng_data.adapter->getUlpProxy()->reportPosition(location, locationExtended, NULL, LOC_SESS_SUCCESS, tech_mask); EXIT_LOG(%d, ret_val); return ret_val; } /* Callback function passed to Data Services State Machine This becomes part of the state machine's servicer and is used to send requests to the data services client */ static int dataCallCb(void *cb_data) { LOC_LOGD("Enter dataCallCb\n"); int ret=0; if(cb_data != NULL) { dsCbData *cbData = (dsCbData *)cb_data; LocEngAdapter *locAdapter = (LocEngAdapter *)cbData->mAdapter; if(cbData->action == GPS_REQUEST_AGPS_DATA_CONN) { LOC_LOGD("dataCallCb GPS_REQUEST_AGPS_DATA_CONN\n"); ret = locAdapter->openAndStartDataCall(); } else if(cbData->action == GPS_RELEASE_AGPS_DATA_CONN) { LOC_LOGD("dataCallCb GPS_RELEASE_AGPS_DATA_CONN\n"); locAdapter->stopDataCall(); } } else { LOC_LOGE("NULL argument received. Failing.\n"); ret = -1; goto err; } err: LOC_LOGD("Exit dataCallCb ret = %d\n", ret); return ret; } /*=========================================================================== FUNCTION loc_eng_agps_reinit DESCRIPTION 2nd half of loc_eng_agps_init(), singled out for modem restart to use. DEPENDENCIES NONE RETURN VALUE 0 SIDE EFFECTS N/A ===========================================================================*/ static void loc_eng_agps_reinit(loc_eng_data_s_type &loc_eng_data) { ENTRY_LOG(); // Set server addresses which came before init if (loc_eng_data.supl_host_set) { loc_eng_set_server(loc_eng_data, LOC_AGPS_SUPL_SERVER, loc_eng_data.supl_host_buf, loc_eng_data.supl_port_buf); } if (loc_eng_data.c2k_host_set) { loc_eng_set_server(loc_eng_data, LOC_AGPS_CDMA_PDE_SERVER, loc_eng_data.c2k_host_buf, loc_eng_data.c2k_port_buf); } EXIT_LOG(%s, VOID_RET); } /*=========================================================================== FUNCTION loc_eng_agps_init DESCRIPTION Initialize the AGps interface. DEPENDENCIES NONE RETURN VALUE 0 SIDE EFFECTS N/A ===========================================================================*/ void loc_eng_agps_init(loc_eng_data_s_type &loc_eng_data, AGpsExtCallbacks* callbacks) { ENTRY_LOG_CALLFLOW(); INIT_CHECK(loc_eng_data.adapter, return); STATE_CHECK((NULL == loc_eng_data.agps_status_cb), "agps instance already initialized", return); if (callbacks == NULL) { LOC_LOGE("loc_eng_agps_init: bad parameters cb %p", callbacks); EXIT_LOG(%s, VOID_RET); return; } LocEngAdapter* adapter = loc_eng_data.adapter; loc_eng_data.agps_status_cb = callbacks->status_cb; loc_eng_data.internet_nif = new AgpsStateMachine(servicerTypeAgps, (void *)loc_eng_data.agps_status_cb, AGPS_TYPE_WWAN_ANY, false); loc_eng_data.wifi_nif = new AgpsStateMachine(servicerTypeAgps, (void *)loc_eng_data.agps_status_cb, AGPS_TYPE_WIFI, true); if ((gps_conf.CAPABILITIES & GPS_CAPABILITY_MSA) || (gps_conf.CAPABILITIES & GPS_CAPABILITY_MSB)) { loc_eng_data.agnss_nif = new AgpsStateMachine(servicerTypeAgps, (void *)loc_eng_data.agps_status_cb, AGPS_TYPE_SUPL, false); if (adapter->mSupportsAgpsRequests) { if(gps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL) { loc_eng_data.adapter->sendMsg(new LocEngDataClientInit(&loc_eng_data)); } loc_eng_dmn_conn_loc_api_server_launch(callbacks->create_thread_cb, NULL, NULL, &loc_eng_data); } loc_eng_agps_reinit(loc_eng_data); } EXIT_LOG(%s, VOID_RET); } static void deleteAidingData(loc_eng_data_s_type &logEng) { if (logEng.engine_status != GPS_STATUS_ENGINE_ON && logEng.aiding_data_for_deletion != 0) { logEng.adapter->deleteAidingData(logEng.aiding_data_for_deletion); logEng.aiding_data_for_deletion = 0; } } static AgpsStateMachine* getAgpsStateMachine(loc_eng_data_s_type &locEng, AGpsExtType agpsType) { AgpsStateMachine* stateMachine; switch (agpsType) { case AGPS_TYPE_WIFI: { stateMachine = locEng.wifi_nif; break; } case AGPS_TYPE_INVALID: case AGPS_TYPE_SUPL: { stateMachine = locEng.agnss_nif; break; } case AGPS_TYPE_SUPL_ES: { locEng.ds_nif ? stateMachine = locEng.ds_nif: stateMachine = locEng.agnss_nif; break; } default: stateMachine = locEng.internet_nif; } return stateMachine; } /*=========================================================================== FUNCTION loc_eng_agps_open DESCRIPTION This function is called when on-demand data connection opening is successful. It should inform engine about the data open result. DEPENDENCIES NONE RETURN VALUE 0 SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_agps_open(loc_eng_data_s_type &loc_eng_data, AGpsExtType agpsType, const char* apn, AGpsBearerType bearerType) { ENTRY_LOG_CALLFLOW(); INIT_CHECK(loc_eng_data.adapter && loc_eng_data.agps_status_cb, return -1); if (apn == NULL) { LOC_LOGE("APN Name NULL\n"); return 0; } LOC_LOGD("loc_eng_agps_open APN name = [%s]", apn); int apn_len = smaller_of(strlen (apn), MAX_APN_LEN); AgpsStateMachine* sm = getAgpsStateMachine(loc_eng_data, agpsType); loc_eng_data.adapter->sendMsg( new LocEngAtlOpenSuccess(sm, apn, apn_len, bearerType)); EXIT_LOG(%d, 0); return 0; } /*=========================================================================== FUNCTION loc_eng_agps_closed DESCRIPTION This function is called when on-demand data connection closing is done. It should inform engine about the data close result. DEPENDENCIES NONE RETURN VALUE 0 SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_agps_closed(loc_eng_data_s_type &loc_eng_data, AGpsExtType agpsType) { ENTRY_LOG_CALLFLOW(); INIT_CHECK(loc_eng_data.adapter && loc_eng_data.agps_status_cb, return -1); AgpsStateMachine* sm = getAgpsStateMachine(loc_eng_data, agpsType); loc_eng_data.adapter->sendMsg(new LocEngAtlClosed(sm)); EXIT_LOG(%d, 0); return 0; } /*=========================================================================== FUNCTION loc_eng_agps_open_failed DESCRIPTION This function is called when on-demand data connection opening has failed. It should inform engine about the data open result. DEPENDENCIES NONE RETURN VALUE 0 SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_agps_open_failed(loc_eng_data_s_type &loc_eng_data, AGpsExtType agpsType) { ENTRY_LOG_CALLFLOW(); INIT_CHECK(loc_eng_data.adapter && loc_eng_data.agps_status_cb, return -1); AgpsStateMachine* sm = getAgpsStateMachine(loc_eng_data, agpsType); loc_eng_data.adapter->sendMsg(new LocEngAtlOpenFailed(sm)); EXIT_LOG(%d, 0); return 0; } /*=========================================================================== FUNCTION resolve_in_addr DESCRIPTION Translates a hostname to in_addr struct DEPENDENCIES n/a RETURN VALUE TRUE if successful SIDE EFFECTS n/a ===========================================================================*/ static boolean resolve_in_addr(const char *host_addr, struct in_addr *in_addr_ptr) { ENTRY_LOG(); boolean ret_val = TRUE; struct hostent *hp; hp = gethostbyname(host_addr); if (hp != NULL) /* DNS OK */ { memcpy(in_addr_ptr, hp->h_addr_list[0], hp->h_length); } else { /* Try IP representation */ if (inet_aton(host_addr, in_addr_ptr) == 0) { /* IP not valid */ LOC_LOGE("DNS query on '%s' failed\n", host_addr); ret_val = FALSE; } } EXIT_LOG(%s, loc_logger_boolStr[ret_val!=0]); return ret_val; } /*=========================================================================== FUNCTION loc_eng_set_server DESCRIPTION This is used to set the default AGPS server. Server address is obtained from gps.conf. DEPENDENCIES NONE RETURN VALUE 0 SIDE EFFECTS N/A ===========================================================================*/ static int loc_eng_set_server(loc_eng_data_s_type &loc_eng_data, LocServerType type, const char* hostname, int port) { ENTRY_LOG(); int ret = 0; LocEngAdapter* adapter = loc_eng_data.adapter; if (LOC_AGPS_SUPL_SERVER == type) { char url[MAX_URL_LEN]; unsigned int len = 0; const char nohost[] = "NONE"; if (hostname == NULL || strncasecmp(nohost, hostname, sizeof(nohost)) == 0) { url[0] = NULL; } else { len = snprintf(url, sizeof(url), "%s:%u", hostname, (unsigned) port); } if (sizeof(url) > len) { adapter->sendMsg(new LocEngSetServerUrl(adapter, url, len)); } } else if (LOC_AGPS_CDMA_PDE_SERVER == type || LOC_AGPS_CUSTOM_PDE_SERVER == type || LOC_AGPS_MPC_SERVER == type) { struct in_addr addr; if (!resolve_in_addr(hostname, &addr)) { LOC_LOGE("loc_eng_set_server, hostname %s cannot be resolved.\n", hostname); ret = -2; } else { unsigned int ip = htonl(addr.s_addr); adapter->sendMsg(new LocEngSetServerIpv4(adapter, ip, port, type)); } } else { LOC_LOGE("loc_eng_set_server, type %d cannot be resolved.\n", type); } EXIT_LOG(%d, ret); return ret; } /*=========================================================================== FUNCTION loc_eng_set_server_proxy DESCRIPTION If loc_eng_set_server is called before loc_eng_init, it doesn't work. This proxy buffers server settings and calls loc_eng_set_server when the client is open. DEPENDENCIES NONE RETURN VALUE 0 SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_set_server_proxy(loc_eng_data_s_type &loc_eng_data, LocServerType type, const char* hostname, int port) { ENTRY_LOG_CALLFLOW(); int ret_val = 0; LOC_LOGV("save the address, type: %d, hostname: %s, port: %d", (int) type, hostname, port); switch (type) { case LOC_AGPS_SUPL_SERVER: strlcpy(loc_eng_data.supl_host_buf, hostname, sizeof(loc_eng_data.supl_host_buf)); loc_eng_data.supl_port_buf = port; loc_eng_data.supl_host_set = 1; break; case LOC_AGPS_CDMA_PDE_SERVER: strlcpy(loc_eng_data.c2k_host_buf, hostname, sizeof(loc_eng_data.c2k_host_buf)); loc_eng_data.c2k_port_buf = port; loc_eng_data.c2k_host_set = 1; break; default: LOC_LOGE("loc_eng_set_server_proxy, unknown server type = %d", (int) type); } if (NULL != loc_eng_data.adapter) { ret_val = loc_eng_set_server(loc_eng_data, type, hostname, port); } EXIT_LOG(%d, ret_val); return ret_val; } /*=========================================================================== FUNCTION loc_eng_agps_ril_update_network_availability DESCRIPTION Sets data call allow vs disallow flag to modem This is the only member of sLocEngAGpsRilInterface implemented. DEPENDENCIES None RETURN VALUE 0: success SIDE EFFECTS N/A ===========================================================================*/ void loc_eng_agps_ril_update_network_availability(loc_eng_data_s_type &loc_eng_data, int available, const char* apn) { ENTRY_LOG_CALLFLOW(); //This is to store the status of data availability over the network. //If GPS is not enabled, the INIT_CHECK will fail and the modem will //not be updated with the network's availability. Since the data status //can change before GPS is enabled the, storing the status will enable //us to inform the modem after GPS is enabled agpsStatus = available; INIT_CHECK(loc_eng_data.adapter, return); if (apn != NULL) { LOC_LOGD("loc_eng_agps_ril_update_network_availability: APN Name = [%s]\n", apn); int apn_len = smaller_of(strlen (apn), MAX_APN_LEN); LocEngAdapter* adapter = loc_eng_data.adapter; adapter->sendMsg(new LocEngEnableData(adapter, apn, apn_len, available)); } EXIT_LOG(%s, VOID_RET); } int loc_eng_agps_install_certificates(loc_eng_data_s_type &loc_eng_data, const DerEncodedCertificate* certificates, size_t numberOfCerts) { ENTRY_LOG_CALLFLOW(); int ret_val = AGPS_CERTIFICATE_OPERATION_SUCCESS; uint32_t slotBitMask = gps_conf.AGPS_CERT_WRITABLE_MASK; uint32_t slotCount = 0; for (uint32_t slotBitMaskCounter=slotBitMask; slotBitMaskCounter; slotCount++) { slotBitMaskCounter &= slotBitMaskCounter - 1; } LOC_LOGD("SlotBitMask=%u SlotCount=%u NumberOfCerts=%u", slotBitMask, slotCount, numberOfCerts); LocEngAdapter* adapter = loc_eng_data.adapter; if (numberOfCerts == 0) { LOC_LOGE("No certs to install, since numberOfCerts is zero"); ret_val = AGPS_CERTIFICATE_OPERATION_SUCCESS; } else if (!adapter) { LOC_LOGE("adapter is null!"); ret_val = AGPS_CERTIFICATE_ERROR_GENERIC; } else if (slotCount < numberOfCerts) { LOC_LOGE("Not enough cert slots (%u) to install %u certs!", slotCount, numberOfCerts); ret_val = AGPS_CERTIFICATE_ERROR_TOO_MANY_CERTIFICATES; } else { for (int i=0; i < numberOfCerts; ++i) { if (certificates[i].length > AGPS_CERTIFICATE_MAX_LENGTH) { LOC_LOGE("cert#(%u) length of %u is too big! greater than %u", certificates[i].length, AGPS_CERTIFICATE_MAX_LENGTH); ret_val = AGPS_CERTIFICATE_ERROR_GENERIC; break; } } if (ret_val == AGPS_CERTIFICATE_OPERATION_SUCCESS) { adapter->sendMsg(new LocEngInstallAGpsCert(adapter, certificates, numberOfCerts, slotBitMask)); } } EXIT_LOG(%d, ret_val); return ret_val; } void loc_eng_configuration_update (loc_eng_data_s_type &loc_eng_data, const char* config_data, int32_t length) { ENTRY_LOG_CALLFLOW(); if (config_data && length > 0) { loc_gps_cfg_s_type gps_conf_tmp = gps_conf; UTIL_UPDATE_CONF(config_data, length, gps_conf_table); LocEngAdapter* adapter = loc_eng_data.adapter; // it is possible that HAL is not init'ed at this time if (adapter) { if (gps_conf_tmp.SUPL_VER != gps_conf.SUPL_VER) { adapter->sendMsg(new LocEngSuplVer(adapter, gps_conf.SUPL_VER)); } if (gps_conf_tmp.LPP_PROFILE != gps_conf.LPP_PROFILE) { adapter->sendMsg(new LocEngLppConfig(adapter, gps_conf.LPP_PROFILE)); } if (gps_conf_tmp.A_GLONASS_POS_PROTOCOL_SELECT != gps_conf.A_GLONASS_POS_PROTOCOL_SELECT) { adapter->sendMsg(new LocEngAGlonassProtocol(adapter, gps_conf.A_GLONASS_POS_PROTOCOL_SELECT)); } if (gps_conf_tmp.SUPL_MODE != gps_conf.SUPL_MODE) { adapter->sendMsg(new LocEngSuplMode(adapter->getUlpProxy())); } } gps_conf_tmp.SUPL_VER = gps_conf.SUPL_VER; gps_conf_tmp.LPP_PROFILE = gps_conf.LPP_PROFILE; gps_conf_tmp.A_GLONASS_POS_PROTOCOL_SELECT = gps_conf.A_GLONASS_POS_PROTOCOL_SELECT; gps_conf_tmp.GPS_LOCK = gps_conf.GPS_LOCK; gps_conf = gps_conf_tmp; } EXIT_LOG(%s, VOID_RET); } /*=========================================================================== FUNCTION loc_eng_report_status DESCRIPTION Reports GPS engine state to Java layer. DEPENDENCIES N/A RETURN VALUE N/A SIDE EFFECTS N/A ===========================================================================*/ static void loc_eng_report_status (loc_eng_data_s_type &loc_eng_data, GpsStatusValue status) { ENTRY_LOG(); // Switch from WAIT to MUTE, for "engine on" or "session begin" event if (status == GPS_STATUS_SESSION_BEGIN || status == GPS_STATUS_ENGINE_ON) { if (loc_eng_data.mute_session_state == LOC_MUTE_SESS_WAIT) { LOC_LOGD("loc_eng_report_status: mute_session_state changed from WAIT to IN SESSION"); loc_eng_data.mute_session_state = LOC_MUTE_SESS_IN_SESSION; } } // Switch off MUTE session if (loc_eng_data.mute_session_state == LOC_MUTE_SESS_IN_SESSION && (status == GPS_STATUS_SESSION_END || status == GPS_STATUS_ENGINE_OFF)) { LOC_LOGD("loc_eng_report_status: mute_session_state changed from IN SESSION to NONE"); loc_eng_data.mute_session_state = LOC_MUTE_SESS_NONE; } // Session End is not reported during Android navigating state boolean navigating = loc_eng_data.adapter->isInSession(); if (status != GPS_STATUS_NONE && !(status == GPS_STATUS_SESSION_END && navigating) && !(status == GPS_STATUS_SESSION_BEGIN && !navigating)) { if (loc_eng_data.mute_session_state != LOC_MUTE_SESS_IN_SESSION) { // Inform GpsLocationProvider about mNavigating status loc_inform_gps_status(loc_eng_data, status); } else { LOC_LOGD("loc_eng_report_status: muting the status report."); } } // Only keeps ENGINE ON/OFF in engine_status if (status == GPS_STATUS_ENGINE_ON || status == GPS_STATUS_ENGINE_OFF) { loc_eng_data.engine_status = status; } // Only keeps SESSION BEGIN/END in fix_session_status if (status == GPS_STATUS_SESSION_BEGIN || status == GPS_STATUS_SESSION_END) { loc_eng_data.fix_session_status = status; } EXIT_LOG(%s, VOID_RET); } /*=========================================================================== FUNCTION loc_eng_handle_engine_down loc_eng_handle_engine_up DESCRIPTION Calls this function when it is detected that modem restart is happening. Either we detected the modem is down or received modem up event. This must be called from the deferred thread to avoid race condition. DEPENDENCIES None RETURN VALUE None SIDE EFFECTS N/A ===========================================================================*/ void loc_eng_handle_engine_down(loc_eng_data_s_type &loc_eng_data) { ENTRY_LOG(); loc_eng_ni_reset_on_engine_restart(loc_eng_data); loc_eng_report_status(loc_eng_data, GPS_STATUS_ENGINE_OFF); EXIT_LOG(%s, VOID_RET); } void loc_eng_handle_engine_up(loc_eng_data_s_type &loc_eng_data) { ENTRY_LOG(); loc_eng_reinit(loc_eng_data); loc_eng_data.adapter->requestPowerVote(); if (loc_eng_data.agps_status_cb != NULL) { if (loc_eng_data.agnss_nif) loc_eng_data.agnss_nif->dropAllSubscribers(); if (loc_eng_data.internet_nif) loc_eng_data.internet_nif->dropAllSubscribers(); loc_eng_agps_reinit(loc_eng_data); } // modem is back up. If we crashed in the middle of navigating, we restart. if (loc_eng_data.adapter->isInSession()) { // This sets the copy in adapter to modem loc_eng_data.adapter->setInSession(false); loc_eng_data.adapter->sendMsg(new LocEngStartFix(loc_eng_data.adapter)); } EXIT_LOG(%s, VOID_RET); } #ifdef USE_GLIB /*=========================================================================== FUNCTION set_sched_policy DESCRIPTION Local copy of this function which bypasses android set_sched_policy DEPENDENCIES None RETURN VALUE 0 SIDE EFFECTS N/A ===========================================================================*/ static int set_sched_policy(int tid, SchedPolicy policy) { return 0; } #endif /* USE_GLIB */ /*=========================================================================== FUNCTION loc_eng_read_config DESCRIPTION Initiates the reading of the gps config file stored in /etc dir DEPENDENCIES None RETURN VALUE 0: success SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_read_config(void) { ENTRY_LOG_CALLFLOW(); if(configAlreadyRead == false) { // Initialize our defaults before reading of configuration file overwrites them. loc_default_parameters(); // We only want to parse the conf file once. This is a good place to ensure that. // In fact one day the conf file should go into context. UTIL_READ_CONF(GPS_CONF_FILE, gps_conf_table); UTIL_READ_CONF(SAP_CONF_FILE, sap_conf_table); configAlreadyRead = true; } else { LOC_LOGV("GPS Config file has already been read\n"); } EXIT_LOG(%d, 0); return 0; } /*=========================================================================== FUNCTION loc_eng_gps_measurement_init DESCRIPTION Initialize gps measurement module. DEPENDENCIES N/A RETURN VALUE 0: success SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_gps_measurement_init(loc_eng_data_s_type &loc_eng_data, GpsMeasurementCallbacks* callbacks) { ENTRY_LOG_CALLFLOW(); STATE_CHECK((NULL == loc_eng_data.gps_measurement_cb), "gps measurement already initialized", return GPS_MEASUREMENT_ERROR_ALREADY_INIT); STATE_CHECK((callbacks != NULL), "callbacks can not be NULL", return GPS_MEASUREMENT_ERROR_GENERIC); STATE_CHECK(loc_eng_data.adapter, "GpsInterface must be initialized first", return GPS_MEASUREMENT_ERROR_GENERIC); // updated the mask LOC_API_ADAPTER_EVENT_MASK_T event = LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT; loc_eng_data.adapter->sendMsg(new LocEngUpdateRegistrationMask( &loc_eng_data, event, LOC_REGISTRATION_MASK_ENABLED)); // set up the callback loc_eng_data.gps_measurement_cb = callbacks->measurement_callback; LOC_LOGD ("%s, event masks updated successfully", __func__); return GPS_MEASUREMENT_OPERATION_SUCCESS; } /*=========================================================================== FUNCTION loc_eng_gps_measurement_close DESCRIPTION Close gps measurement module. DEPENDENCIES N/A RETURN VALUE N/A SIDE EFFECTS N/A ===========================================================================*/ void loc_eng_gps_measurement_close(loc_eng_data_s_type &loc_eng_data) { ENTRY_LOG_CALLFLOW(); INIT_CHECK(loc_eng_data.adapter, return); // updated the mask LOC_API_ADAPTER_EVENT_MASK_T event = LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT; loc_eng_data.adapter->sendMsg(new LocEngUpdateRegistrationMask( &loc_eng_data, event, LOC_REGISTRATION_MASK_DISABLED)); // set up the callback loc_eng_data.gps_measurement_cb = NULL; EXIT_LOG(%d, 0); } ================================================ FILE: gps/loc_api/libloc_api_50001/loc_eng.h ================================================ /* Copyright (c) 2009-2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef LOC_ENG_H #define LOC_ENG_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ // Uncomment to keep all LOG messages (LOGD, LOGI, LOGV, etc.) #define MAX_NUM_ATL_CONNECTIONS 2 // Define boolean type to be used by libgps on loc api module typedef unsigned char boolean; #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #include #include #include #include #include #include #include #include #include // The data connection minimal open time #define DATA_OPEN_MIN_TIME 1 /* sec */ // The system sees GPS engine turns off after inactive for this period of time #define GPS_AUTO_OFF_TIME 2 /* secs */ #define SUCCESS TRUE #define FAILURE FALSE #define INVALID_ATL_CONNECTION_HANDLE -1 #define MAX_XTRA_SERVER_URL_LENGTH 256 enum loc_nmea_provider_e_type { NMEA_PROVIDER_AP = 0, // Application Processor Provider of NMEA NMEA_PROVIDER_MP // Modem Processor Provider of NMEA }; enum loc_mute_session_e_type { LOC_MUTE_SESS_NONE = 0, LOC_MUTE_SESS_WAIT, LOC_MUTE_SESS_IN_SESSION }; // Module data typedef struct loc_eng_data_s { LocEngAdapter *adapter; loc_location_cb_ext location_cb; gps_status_callback status_cb; loc_sv_status_cb_ext sv_status_cb; agps_status_extended agps_status_cb; gps_nmea_callback nmea_cb; gps_ni_notify_callback ni_notify_cb; gps_set_capabilities set_capabilities_cb; gps_acquire_wakelock acquire_wakelock_cb; gps_release_wakelock release_wakelock_cb; gps_request_utc_time request_utc_time_cb; gps_measurement_callback gps_measurement_cb; boolean intermediateFix; AGpsStatusValue agps_status; loc_eng_xtra_data_s_type xtra_module_data; loc_eng_ni_data_s_type loc_eng_ni_data; // AGPS state machines AgpsStateMachine* agnss_nif; AgpsStateMachine* internet_nif; AgpsStateMachine* wifi_nif; //State machine for Data Services AgpsStateMachine* ds_nif; // GPS engine status GpsStatusValue engine_status; GpsStatusValue fix_session_status; // Aiding data information to be deleted, aiding data can only be deleted when GPS engine is off GpsAidingData aiding_data_for_deletion; // For muting session broadcast loc_mute_session_e_type mute_session_state; // For nmea generation boolean generateNmea; uint32_t sv_used_mask; float hdop; float pdop; float vdop; // Address buffers, for addressing setting before init int supl_host_set; char supl_host_buf[101]; int supl_port_buf; int c2k_host_set; char c2k_host_buf[101]; int c2k_port_buf; int mpc_host_set; char mpc_host_buf[101]; int mpc_port_buf; loc_ext_parser location_ext_parser; loc_ext_parser sv_ext_parser; } loc_eng_data_s_type; /* GPS.conf support */ /* NOTE: the implementaiton of the parser casts number fields to 32 bit. To ensure all 'n' fields working, they must all be 32 bit fields. */ typedef struct loc_gps_cfg_s { uint32_t INTERMEDIATE_POS; uint32_t ACCURACY_THRES; uint32_t SUPL_VER; uint32_t SUPL_MODE; uint32_t CAPABILITIES; uint32_t LPP_PROFILE; uint32_t XTRA_VERSION_CHECK; char XTRA_SERVER_1[MAX_XTRA_SERVER_URL_LENGTH]; char XTRA_SERVER_2[MAX_XTRA_SERVER_URL_LENGTH]; char XTRA_SERVER_3[MAX_XTRA_SERVER_URL_LENGTH]; uint32_t USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL; uint32_t NMEA_PROVIDER; uint32_t GPS_LOCK; uint32_t A_GLONASS_POS_PROTOCOL_SELECT; uint32_t AGPS_CERT_WRITABLE_MASK; } loc_gps_cfg_s_type; /* NOTE: the implementaiton of the parser casts number fields to 32 bit. To ensure all 'n' fields working, they must all be 32 bit fields. */ /* Meanwhile, *_valid fields are 8 bit fields, and 'f' fields are double. Rigid as they are, it is the the status quo, until the parsing mechanism is change, that is. */ typedef struct { uint8_t GYRO_BIAS_RANDOM_WALK_VALID; double GYRO_BIAS_RANDOM_WALK; uint32_t SENSOR_ACCEL_BATCHES_PER_SEC; uint32_t SENSOR_ACCEL_SAMPLES_PER_BATCH; uint32_t SENSOR_GYRO_BATCHES_PER_SEC; uint32_t SENSOR_GYRO_SAMPLES_PER_BATCH; uint32_t SENSOR_ACCEL_BATCHES_PER_SEC_HIGH; uint32_t SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH; uint32_t SENSOR_GYRO_BATCHES_PER_SEC_HIGH; uint32_t SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH; uint32_t SENSOR_CONTROL_MODE; uint32_t SENSOR_USAGE; uint32_t SENSOR_ALGORITHM_CONFIG_MASK; uint8_t ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID; double ACCEL_RANDOM_WALK_SPECTRAL_DENSITY; uint8_t ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID; double ANGLE_RANDOM_WALK_SPECTRAL_DENSITY; uint8_t RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID; double RATE_RANDOM_WALK_SPECTRAL_DENSITY; uint8_t VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID; double VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY; uint32_t SENSOR_PROVIDER; } loc_sap_cfg_s_type; extern loc_gps_cfg_s_type gps_conf; extern loc_sap_cfg_s_type sap_conf; uint32_t getCarrierCapabilities(); //loc_eng functions int loc_eng_init(loc_eng_data_s_type &loc_eng_data, LocCallbacks* callbacks, LOC_API_ADAPTER_EVENT_MASK_T event, ContextBase* context); int loc_eng_start(loc_eng_data_s_type &loc_eng_data); int loc_eng_stop(loc_eng_data_s_type &loc_eng_data); void loc_eng_cleanup(loc_eng_data_s_type &loc_eng_data); int loc_eng_inject_time(loc_eng_data_s_type &loc_eng_data, GpsUtcTime time, int64_t timeReference, int uncertainty); int loc_eng_inject_location(loc_eng_data_s_type &loc_eng_data, double latitude, double longitude, float accuracy); void loc_eng_delete_aiding_data(loc_eng_data_s_type &loc_eng_data, GpsAidingData f); int loc_eng_set_position_mode(loc_eng_data_s_type &loc_eng_data, LocPosMode ¶ms); const void* loc_eng_get_extension(loc_eng_data_s_type &loc_eng_data, const char* name); int loc_eng_set_server_proxy(loc_eng_data_s_type &loc_eng_data, LocServerType type, const char *hostname, int port); void loc_eng_mute_one_session(loc_eng_data_s_type &loc_eng_data); int loc_eng_read_config(void); //loc_eng_agps functions void loc_eng_agps_init(loc_eng_data_s_type &loc_eng_data, AGpsExtCallbacks* callbacks); int loc_eng_agps_open(loc_eng_data_s_type &loc_eng_data, AGpsExtType agpsType, const char* apn, AGpsBearerType bearerType); int loc_eng_agps_closed(loc_eng_data_s_type &loc_eng_data, AGpsExtType agpsType); int loc_eng_agps_open_failed(loc_eng_data_s_type &loc_eng_data, AGpsExtType agpsType); void loc_eng_agps_ril_update_network_availability(loc_eng_data_s_type &loc_eng_data, int avaiable, const char* apn); int loc_eng_agps_install_certificates(loc_eng_data_s_type &loc_eng_data, const DerEncodedCertificate* certificates, size_t length); //loc_eng_xtra functions int loc_eng_xtra_init (loc_eng_data_s_type &loc_eng_data, GpsXtraExtCallbacks* callbacks); int loc_eng_xtra_inject_data(loc_eng_data_s_type &loc_eng_data, char* data, int length); int loc_eng_xtra_request_server(loc_eng_data_s_type &loc_eng_data); void loc_eng_xtra_version_check(loc_eng_data_s_type &loc_eng_data, int check); //loc_eng_ni functions extern void loc_eng_ni_init(loc_eng_data_s_type &loc_eng_data, GpsNiExtCallbacks *callbacks); extern void loc_eng_ni_respond(loc_eng_data_s_type &loc_eng_data, int notif_id, GpsUserResponseType user_response); extern void loc_eng_ni_request_handler(loc_eng_data_s_type &loc_eng_data, const GpsNiNotification *notif, const void* passThrough); extern void loc_eng_ni_reset_on_engine_restart(loc_eng_data_s_type &loc_eng_data); void loc_eng_configuration_update (loc_eng_data_s_type &loc_eng_data, const char* config_data, int32_t length); int loc_eng_gps_measurement_init(loc_eng_data_s_type &loc_eng_data, GpsMeasurementCallbacks* callbacks); void loc_eng_gps_measurement_close(loc_eng_data_s_type &loc_eng_data); #ifdef __cplusplus } #endif /* __cplusplus */ #endif // LOC_ENG_H ================================================ FILE: gps/loc_api/libloc_api_50001/loc_eng_agps.cpp ================================================ /* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #define LOG_NDDEBUG 0 #define LOG_TAG "LocSvc_eng" #include #include #include #include #include #include #include //====================================================================== // C callbacks //====================================================================== // This is given to linked_list_add as the dealloc callback // data -- an instance of Subscriber static void deleteObj(void* data) { delete (Subscriber*)data; } // This is given to linked_list_search() as the comparison callback // when the state manchine needs to process for particular subscriber // fromCaller -- caller provides this obj // fromList -- linked_list_search() function take this one from list static bool hasSubscriber(void* fromCaller, void* fromList) { Notification* notification = (Notification*)fromCaller; Subscriber* s1 = (Subscriber*)fromList; return s1->forMe(*notification); } // This is gvien to linked_list_search() to notify subscriber objs // when the state machine needs to inform all subscribers of resource // status changes, e.g. when resource is GRANTED. // fromCaller -- caller provides this ptr to a Notification obj. // fromList -- linked_list_search() function take this one from list static bool notifySubscriber(void* fromCaller, void* fromList) { Notification* notification = (Notification*)fromCaller; Subscriber* s1 = (Subscriber*)fromList; // we notify every subscriber indiscriminatively // each subscriber decides if this notification is interesting. return s1->notifyRsrcStatus(*notification) && // if we do not want to delete the subscriber from the // the list, we must set this to false so this function // returns false notification->postNotifyDelete; } //====================================================================== // Notification //====================================================================== const int Notification::BROADCAST_ALL = 0x80000000; const int Notification::BROADCAST_ACTIVE = 0x80000001; const int Notification::BROADCAST_INACTIVE = 0x80000002; const unsigned char DSStateMachine::MAX_START_DATA_CALL_RETRIES = 4; const unsigned int DSStateMachine::DATA_CALL_RETRY_DELAY_MSEC = 500; //====================================================================== // Subscriber: BITSubscriber / ATLSubscriber / WIFISubscriber //====================================================================== bool Subscriber::forMe(Notification ¬ification) { if (NULL != notification.rcver) { return equals(notification.rcver); } else { return Notification::BROADCAST_ALL == notification.groupID || (Notification::BROADCAST_ACTIVE == notification.groupID && !isInactive()) || (Notification::BROADCAST_INACTIVE == notification.groupID && isInactive()); } } bool BITSubscriber::equals(const Subscriber *s) const { BITSubscriber* bitS = (BITSubscriber*)s; return (ID == bitS->ID && (INADDR_NONE != (unsigned int)ID || 0 == strncmp(mIPv6Addr, bitS->mIPv6Addr, sizeof(mIPv6Addr)))); } bool BITSubscriber::notifyRsrcStatus(Notification ¬ification) { bool notify = forMe(notification); if (notify) { switch(notification.rsrcStatus) { case RSRC_UNSUBSCRIBE: case RSRC_RELEASED: loc_eng_dmn_conn_loc_api_server_data_conn( LOC_ENG_IF_REQUEST_SENDER_ID_GPSONE_DAEMON, GPSONE_LOC_API_IF_RELEASE_SUCCESS); break; case RSRC_DENIED: loc_eng_dmn_conn_loc_api_server_data_conn( LOC_ENG_IF_REQUEST_SENDER_ID_GPSONE_DAEMON, GPSONE_LOC_API_IF_FAILURE); break; case RSRC_GRANTED: loc_eng_dmn_conn_loc_api_server_data_conn( LOC_ENG_IF_REQUEST_SENDER_ID_GPSONE_DAEMON, GPSONE_LOC_API_IF_REQUEST_SUCCESS); break; default: notify = false; } } return notify; } bool ATLSubscriber::notifyRsrcStatus(Notification ¬ification) { bool notify = forMe(notification); if (notify) { switch(notification.rsrcStatus) { case RSRC_UNSUBSCRIBE: case RSRC_RELEASED: ((LocEngAdapter*)mLocAdapter)->atlCloseStatus(ID, 1); break; case RSRC_DENIED: { AGpsExtType type = mBackwardCompatibleMode ? AGPS_TYPE_INVALID : mStateMachine->getType(); ((LocEngAdapter*)mLocAdapter)->atlOpenStatus(ID, 0, (char*)mStateMachine->getAPN(), mStateMachine->getBearer(), type); } break; case RSRC_GRANTED: { AGpsExtType type = mBackwardCompatibleMode ? AGPS_TYPE_INVALID : mStateMachine->getType(); ((LocEngAdapter*)mLocAdapter)->atlOpenStatus(ID, 1, (char*)mStateMachine->getAPN(), mStateMachine->getBearer(), type); } break; default: notify = false; } } return notify; } bool WIFISubscriber::notifyRsrcStatus(Notification ¬ification) { bool notify = forMe(notification); if (notify) { switch(notification.rsrcStatus) { case RSRC_UNSUBSCRIBE: break; case RSRC_RELEASED: loc_eng_dmn_conn_loc_api_server_data_conn( senderId, GPSONE_LOC_API_IF_RELEASE_SUCCESS); break; case RSRC_DENIED: loc_eng_dmn_conn_loc_api_server_data_conn( senderId, GPSONE_LOC_API_IF_FAILURE); break; case RSRC_GRANTED: loc_eng_dmn_conn_loc_api_server_data_conn( senderId, GPSONE_LOC_API_IF_REQUEST_SUCCESS); break; default: notify = false; } } return notify; } bool DSSubscriber::notifyRsrcStatus(Notification ¬ification) { bool notify = forMe(notification); LOC_LOGD("DSSubscriber::notifyRsrcStatus. notify:%d \n",(int)(notify)); if(notify) { switch(notification.rsrcStatus) { case RSRC_UNSUBSCRIBE: case RSRC_RELEASED: case RSRC_DENIED: case RSRC_GRANTED: ((DSStateMachine *)mStateMachine)->informStatus(notification.rsrcStatus, ID); break; default: notify = false; } } return notify; } void DSSubscriber :: setInactive() { mIsInactive = true; ((DSStateMachine *)mStateMachine)->informStatus(RSRC_UNSUBSCRIBE, ID); } //====================================================================== // AgpsState: AgpsReleasedState / AgpsPendingState / AgpsAcquiredState //====================================================================== // AgpsReleasedState class AgpsReleasedState : public AgpsState { friend class AgpsStateMachine; inline AgpsReleasedState(AgpsStateMachine* stateMachine) : AgpsState(stateMachine) { mReleasedState = this; } inline ~AgpsReleasedState() {} public: virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data); inline virtual char* whoami() {return (char*)"AgpsReleasedState";} }; AgpsState* AgpsReleasedState::onRsrcEvent(AgpsRsrcStatus event, void* data) { LOC_LOGD("AgpsReleasedState::onRsrcEvent; event:%d\n", (int)event); if (mStateMachine->hasSubscribers()) { LOC_LOGE("Error: %s subscriber list not empty!!!", whoami()); // I don't know how to recover from it. I am adding this rather // for debugging purpose. } AgpsState* nextState = this; switch (event) { case RSRC_SUBSCRIBE: { // no notification until we get RSRC_GRANTED // but we need to add subscriber to the list mStateMachine->addSubscriber((Subscriber*)data); // request from connecivity service for NIF //The if condition is added so that if the data call setup fails //for DS State Machine, we want to retry in released state. //for AGps State Machine, sendRsrcRequest() will always return success if(!mStateMachine->sendRsrcRequest(GPS_REQUEST_AGPS_DATA_CONN)) { // move the state to PENDING nextState = mPendingState; } } break; case RSRC_UNSUBSCRIBE: { // the list should really be empty, nothing to remove. // but we might as well just tell the client it is // unsubscribed. False tolerance, right? Subscriber* subscriber = (Subscriber*) data; Notification notification(subscriber, event, false); subscriber->notifyRsrcStatus(notification); } // break; case RSRC_GRANTED: case RSRC_RELEASED: case RSRC_DENIED: default: LOC_LOGW("%s: unrecognized event %d", whoami(), event); // no state change. break; } LOC_LOGD("onRsrcEvent, old state %s, new state %s, event %d", whoami(), nextState->whoami(), event); return nextState; } // AgpsPendingState class AgpsPendingState : public AgpsState { friend class AgpsStateMachine; inline AgpsPendingState(AgpsStateMachine* stateMachine) : AgpsState(stateMachine) { mPendingState = this; } inline ~AgpsPendingState() {} public: virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data); inline virtual char* whoami() {return (char*)"AgpsPendingState";} }; AgpsState* AgpsPendingState::onRsrcEvent(AgpsRsrcStatus event, void* data) { AgpsState* nextState = this;; LOC_LOGD("AgpsPendingState::onRsrcEvent; event:%d\n", (int)event); switch (event) { case RSRC_SUBSCRIBE: { // already requested for NIF resource, // do nothing until we get RSRC_GRANTED indication // but we need to add subscriber to the list mStateMachine->addSubscriber((Subscriber*)data); // no state change. } break; case RSRC_UNSUBSCRIBE: { Subscriber* subscriber = (Subscriber*) data; if (subscriber->waitForCloseComplete()) { subscriber->setInactive(); } else { // auto notify this subscriber of the unsubscribe Notification notification(subscriber, event, true); mStateMachine->notifySubscribers(notification); } // now check if there is any subscribers left if (!mStateMachine->hasSubscribers()) { // no more subscribers, move to RELEASED state nextState = mReleasedState; // tell connecivity service we can release NIF mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN); } else if (!mStateMachine->hasActiveSubscribers()) { // only inactive subscribers, move to RELEASING state nextState = mReleasingState; // tell connecivity service we can release NIF mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN); } } break; case RSRC_GRANTED: { nextState = mAcquiredState; Notification notification(Notification::BROADCAST_ACTIVE, event, false); // notify all subscribers NIF resource GRANTED // by setting false, we keep subscribers on the linked list mStateMachine->notifySubscribers(notification); } break; case RSRC_RELEASED: // no state change. // we are expecting either GRANTED or DENIED. Handling RELEASED // may like break our state machine in race conditions. break; case RSRC_DENIED: { nextState = mReleasedState; Notification notification(Notification::BROADCAST_ALL, event, true); // notify all subscribers NIF resource RELEASED or DENIED // by setting true, we remove subscribers from the linked list mStateMachine->notifySubscribers(notification); } break; default: LOC_LOGE("%s: unrecognized event %d", whoami(), event); // no state change. } LOC_LOGD("onRsrcEvent, old state %s, new state %s, event %d", whoami(), nextState->whoami(), event); return nextState; } class AgpsAcquiredState : public AgpsState { friend class AgpsStateMachine; inline AgpsAcquiredState(AgpsStateMachine* stateMachine) : AgpsState(stateMachine) { mAcquiredState = this; } inline ~AgpsAcquiredState() {} public: virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data); inline virtual char* whoami() { return (char*)"AgpsAcquiredState"; } }; AgpsState* AgpsAcquiredState::onRsrcEvent(AgpsRsrcStatus event, void* data) { AgpsState* nextState = this; LOC_LOGD("AgpsAcquiredState::onRsrcEvent; event:%d\n", (int)event); switch (event) { case RSRC_SUBSCRIBE: { // we already have the NIF resource, simply notify subscriber Subscriber* subscriber = (Subscriber*) data; // we have rsrc in hand, so grant it right away Notification notification(subscriber, RSRC_GRANTED, false); subscriber->notifyRsrcStatus(notification); // add subscriber to the list mStateMachine->addSubscriber(subscriber); // no state change. } break; case RSRC_UNSUBSCRIBE: { Subscriber* subscriber = (Subscriber*) data; if (subscriber->waitForCloseComplete()) { subscriber->setInactive(); } else { // auto notify this subscriber of the unsubscribe Notification notification(subscriber, event, true); mStateMachine->notifySubscribers(notification); } // now check if there is any subscribers left if (!mStateMachine->hasSubscribers()) { // no more subscribers, move to RELEASED state nextState = mReleasedState; // tell connecivity service we can release NIF mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN); } else if (!mStateMachine->hasActiveSubscribers()) { // only inactive subscribers, move to RELEASING state nextState = mReleasingState; // tell connecivity service we can release NIF mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN); } } break; case RSRC_GRANTED: LOC_LOGW("%s: %d, RSRC_GRANTED already received", whoami(), event); // no state change. break; case RSRC_RELEASED: { LOC_LOGW("%s: %d, a force rsrc release", whoami(), event); nextState = mReleasedState; Notification notification(Notification::BROADCAST_ALL, event, true); // by setting true, we remove subscribers from the linked list mStateMachine->notifySubscribers(notification); } break; case RSRC_DENIED: // no state change. // we are expecting RELEASED. Handling DENIED // may like break our state machine in race conditions. break; default: LOC_LOGE("%s: unrecognized event %d", whoami(), event); // no state change. } LOC_LOGD("onRsrcEvent, old state %s, new state %s, event %d", whoami(), nextState->whoami(), event); return nextState; } // AgpsPendingState class AgpsReleasingState : public AgpsState { friend class AgpsStateMachine; inline AgpsReleasingState(AgpsStateMachine* stateMachine) : AgpsState(stateMachine) { mReleasingState = this; } inline ~AgpsReleasingState() {} public: virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data); inline virtual char* whoami() {return (char*)"AgpsReleasingState";} }; AgpsState* AgpsReleasingState::onRsrcEvent(AgpsRsrcStatus event, void* data) { AgpsState* nextState = this;; LOC_LOGD("AgpsReleasingState::onRsrcEvent; event:%d\n", (int)event); switch (event) { case RSRC_SUBSCRIBE: { // already requested for NIF resource, // do nothing until we get RSRC_GRANTED indication // but we need to add subscriber to the list mStateMachine->addSubscriber((Subscriber*)data); // no state change. } break; case RSRC_UNSUBSCRIBE: { Subscriber* subscriber = (Subscriber*) data; if (subscriber->waitForCloseComplete()) { subscriber->setInactive(); } else { // auto notify this subscriber of the unsubscribe Notification notification(subscriber, event, true); mStateMachine->notifySubscribers(notification); } // now check if there is any subscribers left if (!mStateMachine->hasSubscribers()) { // no more subscribers, move to RELEASED state nextState = mReleasedState; } } break; case RSRC_DENIED: // A race condition subscriber unsubscribes before AFW denies resource. case RSRC_RELEASED: { nextState = mAcquiredState; Notification notification(Notification::BROADCAST_INACTIVE, event, true); // notify all subscribers that are active NIF resource RELEASE // by setting false, we keep subscribers on the linked list mStateMachine->notifySubscribers(notification); if (mStateMachine->hasActiveSubscribers()) { nextState = mPendingState; // request from connecivity service for NIF mStateMachine->sendRsrcRequest(GPS_REQUEST_AGPS_DATA_CONN); } else { nextState = mReleasedState; } } break; case RSRC_GRANTED: default: LOC_LOGE("%s: unrecognized event %d", whoami(), event); // no state change. } LOC_LOGD("onRsrcEvent, old state %s, new state %s, event %d", whoami(), nextState->whoami(), event); return nextState; } //====================================================================== //Servicer //====================================================================== Servicer* Servicer :: getServicer(servicerType type, void *cb_func) { LOC_LOGD(" Enter getServicer type:%d\n", (int)type); switch(type) { case servicerTypeNoCbParam: return (new Servicer(cb_func)); case servicerTypeExt: return (new ExtServicer(cb_func)); case servicerTypeAgps: return (new AGpsServicer(cb_func)); default: return NULL; } } int Servicer :: requestRsrc(void *cb_data) { callback(); return 0; } int ExtServicer :: requestRsrc(void *cb_data) { int ret=-1; LOC_LOGD("Enter ExtServicer :: requestRsrc\n"); ret = callbackExt(cb_data); LOC_LOGD("Exit ExtServicer :: requestRsrc\n"); return(ret); } int AGpsServicer :: requestRsrc(void *cb_data) { callbackAGps((AGpsStatus *)cb_data); return 0; } //====================================================================== // AgpsStateMachine //====================================================================== AgpsStateMachine::AgpsStateMachine(servicerType servType, void *cb_func, AGpsExtType type, bool enforceSingleSubscriber) : mStatePtr(new AgpsReleasedState(this)),mType(type), mAPN(NULL), mAPNLen(0), mBearer(AGPS_APN_BEARER_INVALID), mEnforceSingleSubscriber(enforceSingleSubscriber), mServicer(Servicer :: getServicer(servType, (void *)cb_func)) { linked_list_init(&mSubscribers); // setting up mReleasedState mStatePtr->mPendingState = new AgpsPendingState(this); mStatePtr->mAcquiredState = new AgpsAcquiredState(this); mStatePtr->mReleasingState = new AgpsReleasingState(this); // setting up mAcquiredState mStatePtr->mAcquiredState->mReleasedState = mStatePtr; mStatePtr->mAcquiredState->mPendingState = mStatePtr->mPendingState; mStatePtr->mAcquiredState->mReleasingState = mStatePtr->mReleasingState; // setting up mPendingState mStatePtr->mPendingState->mAcquiredState = mStatePtr->mAcquiredState; mStatePtr->mPendingState->mReleasedState = mStatePtr; mStatePtr->mPendingState->mReleasingState = mStatePtr->mReleasingState; // setting up mReleasingState mStatePtr->mReleasingState->mReleasedState = mStatePtr; mStatePtr->mReleasingState->mPendingState = mStatePtr->mPendingState; mStatePtr->mReleasingState->mAcquiredState = mStatePtr->mAcquiredState; } AgpsStateMachine::~AgpsStateMachine() { dropAllSubscribers(); // free the 3 states. We must read out all 3 pointers first. // Otherwise we run the risk of getting pointers from already // freed memory. AgpsState* acquiredState = mStatePtr->mAcquiredState; AgpsState* releasedState = mStatePtr->mReleasedState; AgpsState* pendindState = mStatePtr->mPendingState; AgpsState* releasingState = mStatePtr->mReleasingState; delete acquiredState; delete releasedState; delete pendindState; delete releasingState; delete mServicer; linked_list_destroy(&mSubscribers); if (NULL != mAPN) { delete[] mAPN; mAPN = NULL; } } void AgpsStateMachine::setAPN(const char* apn, unsigned int len) { if (NULL != mAPN) { delete mAPN; } if (NULL != apn) { mAPN = new char[len+1]; memcpy(mAPN, apn, len); mAPN[len] = NULL; mAPNLen = len; } else { mAPN = NULL; mAPNLen = 0; } } void AgpsStateMachine::onRsrcEvent(AgpsRsrcStatus event) { switch (event) { case RSRC_GRANTED: case RSRC_RELEASED: case RSRC_DENIED: mStatePtr = mStatePtr->onRsrcEvent(event, NULL); break; default: LOC_LOGW("AgpsStateMachine: unrecognized event %d", event); break; } } void AgpsStateMachine::notifySubscribers(Notification& notification) const { if (notification.postNotifyDelete) { // just any non NULL value to get started Subscriber* s = (Subscriber*)~0; while (NULL != s) { s = NULL; // if the last param sets to true, _search will delete // the node from the list for us. But the problem is // once that is done, _search returns, leaving the // rest of the list unprocessed. So we need a loop. linked_list_search(mSubscribers, (void**)&s, notifySubscriber, (void*)¬ification, true); delete s; } } else { // no loop needed if it the last param sets to false, which // mean nothing gets deleted from the list. linked_list_search(mSubscribers, NULL, notifySubscriber, (void*)¬ification, false); } } void AgpsStateMachine::addSubscriber(Subscriber* subscriber) const { Subscriber* s = NULL; Notification notification((const Subscriber*)subscriber); linked_list_search(mSubscribers, (void**)&s, hasSubscriber, (void*)¬ification, false); if (NULL == s) { linked_list_add(mSubscribers, subscriber->clone(), deleteObj); } } int AgpsStateMachine::sendRsrcRequest(AGpsStatusValue action) const { Subscriber* s = NULL; Notification notification(Notification::BROADCAST_ACTIVE); linked_list_search(mSubscribers, (void**)&s, hasSubscriber, (void*)¬ification, false); if ((NULL == s) == (GPS_RELEASE_AGPS_DATA_CONN == action)) { AGpsExtStatus nifRequest; nifRequest.size = sizeof(nifRequest); nifRequest.type = mType; nifRequest.status = action; if (s == NULL) { nifRequest.ipv4_addr = INADDR_NONE; memset(&nifRequest.addr, 0, sizeof(nifRequest.addr)); nifRequest.ssid[0] = '\0'; nifRequest.password[0] = '\0'; } else { s->setIPAddresses(nifRequest.addr); s->setWifiInfo(nifRequest.ssid, nifRequest.password); } CALLBACK_LOG_CALLFLOW("agps_cb", %s, loc_get_agps_status_name(action)); mServicer->requestRsrc((void *)&nifRequest); } return 0; } void AgpsStateMachine::subscribeRsrc(Subscriber *subscriber) { if (mEnforceSingleSubscriber && hasSubscribers()) { Notification notification(Notification::BROADCAST_ALL, RSRC_DENIED, true); notifySubscriber(¬ification, subscriber); } else { mStatePtr = mStatePtr->onRsrcEvent(RSRC_SUBSCRIBE, (void*)subscriber); } } bool AgpsStateMachine::unsubscribeRsrc(Subscriber *subscriber) { Subscriber* s = NULL; Notification notification((const Subscriber*)subscriber); linked_list_search(mSubscribers, (void**)&s, hasSubscriber, (void*)¬ification, false); if (NULL != s) { mStatePtr = mStatePtr->onRsrcEvent(RSRC_UNSUBSCRIBE, (void*)s); return true; } return false; } bool AgpsStateMachine::hasActiveSubscribers() const { Subscriber* s = NULL; Notification notification(Notification::BROADCAST_ACTIVE); linked_list_search(mSubscribers, (void**)&s, hasSubscriber, (void*)¬ification, false); return NULL != s; } //====================================================================== // DSStateMachine //====================================================================== void delay_callback(void *callbackData, int result) { if(callbackData) { DSStateMachine *DSSMInstance = (DSStateMachine *)callbackData; DSSMInstance->retryCallback(); } else { LOC_LOGE(" NULL argument received. Failing.\n"); goto err; } err: return; } DSStateMachine :: DSStateMachine(servicerType type, void *cb_func, LocEngAdapter* adapterHandle): AgpsStateMachine(type, cb_func, AGPS_TYPE_INVALID,false), mLocAdapter(adapterHandle) { LOC_LOGD("%s:%d]: New DSStateMachine\n", __func__, __LINE__); mRetries = 0; } void DSStateMachine :: retryCallback(void) { DSSubscriber *subscriber = NULL; Notification notification(Notification::BROADCAST_ACTIVE); linked_list_search(mSubscribers, (void**)&subscriber, hasSubscriber, (void*)¬ification, false); if(subscriber) mLocAdapter->requestSuplES(subscriber->ID); else LOC_LOGE("DSStateMachine :: retryCallback: No subscriber found." \ "Cannot retry data call\n"); return; } int DSStateMachine :: sendRsrcRequest(AGpsStatusValue action) const { DSSubscriber* s = NULL; dsCbData cbData; int ret=-1; int connHandle=-1; LOC_LOGD("Enter DSStateMachine :: sendRsrcRequest\n"); Notification notification(Notification::BROADCAST_ACTIVE); linked_list_search(mSubscribers, (void**)&s, hasSubscriber, (void*)¬ification, false); if(s) { connHandle = s->ID; LOC_LOGD("DSStateMachine :: sendRsrcRequest - subscriber found\n"); } else LOC_LOGD("DSStateMachine :: sendRsrcRequest - No subscriber found\n"); cbData.action = action; cbData.mAdapter = mLocAdapter; ret = mServicer->requestRsrc((void *)&cbData); //Only the request to start data call returns a success/failure //The request to stop data call will always succeed //Hence, the below block will only be executed when the //request to start the data call fails switch(ret) { case LOC_API_ADAPTER_ERR_ENGINE_BUSY: LOC_LOGD("DSStateMachine :: sendRsrcRequest - Failure returned: %d\n",ret); ((DSStateMachine *)this)->incRetries(); if(mRetries > MAX_START_DATA_CALL_RETRIES) { LOC_LOGE(" Failed to start Data call. Fallback to normal ATL SUPL\n"); informStatus(RSRC_DENIED, connHandle); } else { if(loc_timer_start(DATA_CALL_RETRY_DELAY_MSEC, delay_callback, (void *)this)) { LOC_LOGE("Error: Could not start delay thread\n"); ret = -1; goto err; } } break; case LOC_API_ADAPTER_ERR_UNSUPPORTED: LOC_LOGE("No profile found for emergency call. Fallback to normal SUPL ATL\n"); informStatus(RSRC_DENIED, connHandle); break; case LOC_API_ADAPTER_ERR_SUCCESS: LOC_LOGD("%s:%d]: Request to start data call sent\n", __func__, __LINE__); break; case -1: //One of the ways this case can be encountered is if the callback function //receives a null argument, it just exits with -1 error LOC_LOGE("Error: Something went wrong somewhere. Falling back to normal SUPL ATL\n"); informStatus(RSRC_DENIED, connHandle); break; default: LOC_LOGE("%s:%d]: Unrecognized return value\n", __func__, __LINE__); } err: LOC_LOGD("EXIT DSStateMachine :: sendRsrcRequest; ret = %d\n", ret); return ret; } void DSStateMachine :: onRsrcEvent(AgpsRsrcStatus event) { void* currState = (void *)mStatePtr; LOC_LOGD("Enter DSStateMachine :: onRsrcEvent. event = %d\n", (int)event); switch (event) { case RSRC_GRANTED: LOC_LOGD("DSStateMachine :: onRsrcEvent RSRC_GRANTED\n"); mStatePtr = mStatePtr->onRsrcEvent(event, NULL); break; case RSRC_RELEASED: LOC_LOGD("DSStateMachine :: onRsrcEvent RSRC_RELEASED\n"); mStatePtr = mStatePtr->onRsrcEvent(event, NULL); //To handle the case where we get a RSRC_RELEASED in //pending state, we translate that to a RSRC_DENIED state //since the callback from DSI is either RSRC_GRANTED or RSRC_RELEASED //for when the call is connected or disconnected respectively. if((void *)mStatePtr != currState) break; else { event = RSRC_DENIED; LOC_LOGE(" Switching event to RSRC_DENIED\n"); } case RSRC_DENIED: mStatePtr = mStatePtr->onRsrcEvent(event, NULL); break; default: LOC_LOGW("AgpsStateMachine: unrecognized event %d", event); break; } LOC_LOGD("Exit DSStateMachine :: onRsrcEvent. event = %d\n", (int)event); } void DSStateMachine :: informStatus(AgpsRsrcStatus status, int ID) const { LOC_LOGD("DSStateMachine :: informStatus. Status=%d\n",(int)status); switch(status) { case RSRC_UNSUBSCRIBE: mLocAdapter->atlCloseStatus(ID, 1); break; case RSRC_RELEASED: mLocAdapter->closeDataCall(); break; case RSRC_DENIED: ((DSStateMachine *)this)->mRetries = 0; mLocAdapter->requestATL(ID, AGPS_TYPE_SUPL); break; case RSRC_GRANTED: mLocAdapter->atlOpenStatus(ID, 1, NULL, AGPS_APN_BEARER_INVALID, AGPS_TYPE_INVALID); break; default: LOC_LOGW("DSStateMachine :: informStatus - unknown status"); } return; } ================================================ FILE: gps/loc_api/libloc_api_50001/loc_eng_agps.h ================================================ /* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef __LOC_ENG_AGPS_H__ #define __LOC_ENG_AGPS_H__ #include #include #include #include #include #include #include #include #include #include // forward declaration class AgpsStateMachine; class Subscriber; // NIF resource events typedef enum { RSRC_SUBSCRIBE, RSRC_UNSUBSCRIBE, RSRC_GRANTED, RSRC_RELEASED, RSRC_DENIED, RSRC_STATUS_MAX } AgpsRsrcStatus; typedef enum { servicerTypeNoCbParam, servicerTypeAgps, servicerTypeExt }servicerType; //DS Callback struct typedef struct { LocEngAdapter *mAdapter; AGpsStatusValue action; }dsCbData; // information bundle for subscribers struct Notification { // goes to every subscriber static const int BROADCAST_ALL; // goes to every ACTIVE subscriber static const int BROADCAST_ACTIVE; // goes to every INACTIVE subscriber static const int BROADCAST_INACTIVE; // go to a specific subscriber const Subscriber* rcver; // broadcast const int groupID; // the new resource status event const AgpsRsrcStatus rsrcStatus; // should the subscriber be deleted after the notification const bool postNotifyDelete; // convenient constructor inline Notification(const int broadcast, const AgpsRsrcStatus status, const bool deleteAfterwards) : rcver(NULL), groupID(broadcast), rsrcStatus(status), postNotifyDelete(deleteAfterwards) {} // convenient constructor inline Notification(const Subscriber* subscriber, const AgpsRsrcStatus status, const bool deleteAfterwards) : rcver(subscriber), groupID(-1), rsrcStatus(status), postNotifyDelete(deleteAfterwards) {} // convenient constructor inline Notification(const int broadcast) : rcver(NULL), groupID(broadcast), rsrcStatus(RSRC_STATUS_MAX), postNotifyDelete(false) {} // convenient constructor inline Notification(const Subscriber* subscriber) : rcver(subscriber), groupID(-1), rsrcStatus(RSRC_STATUS_MAX), postNotifyDelete(false) {} }; class AgpsState { // allows AgpsStateMachine to access private data // no class members are public. We don't want // anyone but state machine to use state. friend class AgpsStateMachine; friend class DSStateMachine; // state transitions are done here. // Each state implements its own transitions (of course). inline virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data) = 0; protected: // handle back to state machine const AgpsStateMachine* mStateMachine; // each state has pointers to all 3 states // one of which is to itself. AgpsState* mReleasedState; AgpsState* mAcquiredState; AgpsState* mPendingState; AgpsState* mReleasingState; inline AgpsState(const AgpsStateMachine *stateMachine) : mStateMachine(stateMachine), mReleasedState(NULL), mAcquiredState(NULL), mPendingState(NULL), mReleasingState(NULL) {} virtual ~AgpsState() {} public: // for logging purpose inline virtual char* whoami() = 0; }; class Servicer { void (*callback)(void); public: static Servicer* getServicer(servicerType type, void *cb_func); virtual int requestRsrc(void *cb_data); Servicer() {} Servicer(void *cb_func) { callback = (void(*)(void))(cb_func); } virtual ~Servicer(){} inline virtual char *whoami() {return (char*)"Servicer";} }; class ExtServicer : public Servicer { int (*callbackExt)(void *cb_data); public: int requestRsrc(void *cb_data); ExtServicer() {} ExtServicer(void *cb_func) { callbackExt = (int(*)(void *))(cb_func); } virtual ~ExtServicer(){} inline virtual char *whoami() {return (char*)"ExtServicer";} }; class AGpsServicer : public Servicer { void (*callbackAGps)(AGpsStatus* status); public: int requestRsrc(void *cb_data); AGpsServicer() {} AGpsServicer(void *cb_func) { callbackAGps = (void(*)(AGpsStatus *))(cb_func); } virtual ~AGpsServicer(){} inline virtual char *whoami() {return (char*)"AGpsServicer";} }; class AgpsStateMachine { protected: // a linked list of subscribers. void* mSubscribers; //handle to whoever provides the service Servicer *mServicer; // allows AgpsState to access private data // each state is really internal data to the // state machine, so it should be able to // access anything within the state machine. friend class AgpsState; // pointer to the current state. AgpsState* mStatePtr; private: // NIF type: AGNSS or INTERNET. const AGpsExtType mType; // apn to the NIF. Each state machine tracks // resource state of a particular NIF. For each // NIF, there is also an active APN. char* mAPN; // for convenience, we don't do strlen each time. unsigned int mAPNLen; // bear AGpsBearerType mBearer; // ipv4 address for routing bool mEnforceSingleSubscriber; public: AgpsStateMachine(servicerType servType, void *cb_func, AGpsExtType type, bool enforceSingleSubscriber); virtual ~AgpsStateMachine(); // self explanatory methods below void setAPN(const char* apn, unsigned int len); inline const char* getAPN() const { return (const char*)mAPN; } inline void setBearer(AGpsBearerType bearer) { mBearer = bearer; } inline AGpsBearerType getBearer() const { return mBearer; } inline AGpsExtType getType() const { return (AGpsExtType)mType; } // someone, a ATL client or BIT, is asking for NIF void subscribeRsrc(Subscriber *subscriber); // someone, a ATL client or BIT, is done with NIF bool unsubscribeRsrc(Subscriber *subscriber); // add a subscriber in the linked list, if not already there. void addSubscriber(Subscriber* subscriber) const; virtual void onRsrcEvent(AgpsRsrcStatus event); // put the data together and send the FW virtual int sendRsrcRequest(AGpsStatusValue action) const; //if list is empty, linked_list_empty returns 1 //else if list is not empty, returns 0 //so hasSubscribers() returns 1 if list is not empty //and returns 0 if list is empty inline bool hasSubscribers() const { return !linked_list_empty(mSubscribers); } bool hasActiveSubscribers() const; inline void dropAllSubscribers() const { linked_list_flush(mSubscribers); } // private. Only a state gets to call this. void notifySubscribers(Notification& notification) const; }; class DSStateMachine : public AgpsStateMachine { static const unsigned char MAX_START_DATA_CALL_RETRIES; static const unsigned int DATA_CALL_RETRY_DELAY_MSEC; LocEngAdapter* mLocAdapter; unsigned char mRetries; public: DSStateMachine(servicerType type, void *cb_func, LocEngAdapter* adapterHandle); int sendRsrcRequest(AGpsStatusValue action) const; void onRsrcEvent(AgpsRsrcStatus event); void retryCallback(); void informStatus(AgpsRsrcStatus status, int ID) const; inline void incRetries() {mRetries++;} inline virtual char *whoami() {return (char*)"DSStateMachine";} }; // each subscriber is a AGPS client. In the case of ATL, there could be // multiple clients from modem. In the case of BIT, there is only one // cilent from BIT daemon. struct Subscriber { const uint32_t ID; const AgpsStateMachine* mStateMachine; inline Subscriber(const int id, const AgpsStateMachine* stateMachine) : ID(id), mStateMachine(stateMachine) {} inline virtual ~Subscriber() {} virtual void setIPAddresses(uint32_t &v4, char* v6) = 0; virtual void setIPAddresses(struct sockaddr_storage& addr) = 0; inline virtual void setWifiInfo(char* ssid, char* password) { ssid[0] = 0; password[0] = 0; } inline virtual bool equals(const Subscriber *s) const { return ID == s->ID; } // notifies a subscriber a new NIF resource status, usually // either GRANTE, DENIED, or RELEASED virtual bool notifyRsrcStatus(Notification ¬ification) = 0; virtual bool waitForCloseComplete() { return false; } virtual void setInactive() {} virtual bool isInactive() { return false; } virtual Subscriber* clone() = 0; // checks if this notification is for me, i.e. // either has my id, or has a broadcast id. bool forMe(Notification ¬ification); }; // BITSubscriber, created with requests from BIT daemon struct BITSubscriber : public Subscriber { char mIPv6Addr[16]; inline BITSubscriber(const AgpsStateMachine* stateMachine, unsigned int ipv4, char* ipv6) : Subscriber(ipv4, stateMachine) { if (NULL == ipv6) { mIPv6Addr[0] = 0; } else { memcpy(mIPv6Addr, ipv6, sizeof(mIPv6Addr)); } } virtual bool notifyRsrcStatus(Notification ¬ification); inline virtual void setIPAddresses(uint32_t &v4, char* v6) { v4 = ID; memcpy(v6, mIPv6Addr, sizeof(mIPv6Addr)); } inline virtual void setIPAddresses(struct sockaddr_storage& addr) { addr.ss_family = AF_INET6;/*todo: convert mIPv6Addr into addr */ } virtual Subscriber* clone() { return new BITSubscriber(mStateMachine, ID, mIPv6Addr); } virtual bool equals(const Subscriber *s) const; inline virtual ~BITSubscriber(){} }; // ATLSubscriber, created with requests from ATL struct ATLSubscriber : public Subscriber { const LocEngAdapter* mLocAdapter; const bool mBackwardCompatibleMode; inline ATLSubscriber(const int id, const AgpsStateMachine* stateMachine, const LocEngAdapter* adapter, const bool compatibleMode) : Subscriber(id, stateMachine), mLocAdapter(adapter), mBackwardCompatibleMode(compatibleMode){} virtual bool notifyRsrcStatus(Notification ¬ification); inline virtual void setIPAddresses(uint32_t &v4, char* v6) { v4 = INADDR_NONE; v6[0] = 0; } inline virtual void setIPAddresses(struct sockaddr_storage& addr) { addr.ss_family = AF_INET6; } inline virtual Subscriber* clone() { return new ATLSubscriber(ID, mStateMachine, mLocAdapter, mBackwardCompatibleMode); } inline virtual ~ATLSubscriber(){} }; // WIFISubscriber, created with requests from MSAPM or QuIPC struct WIFISubscriber : public Subscriber { char * mSSID; char * mPassword; loc_if_req_sender_id_e_type senderId; bool mIsInactive; inline WIFISubscriber(const AgpsStateMachine* stateMachine, char * ssid, char * password, loc_if_req_sender_id_e_type sender_id) : Subscriber(sender_id, stateMachine), mSSID(NULL == ssid ? NULL : new char[SSID_BUF_SIZE]), mPassword(NULL == password ? NULL : new char[SSID_BUF_SIZE]), senderId(sender_id) { if (NULL != mSSID) strlcpy(mSSID, ssid, SSID_BUF_SIZE); if (NULL != mPassword) strlcpy(mPassword, password, SSID_BUF_SIZE); mIsInactive = false; } virtual bool notifyRsrcStatus(Notification ¬ification); inline virtual void setIPAddresses(uint32_t &v4, char* v6) {} inline virtual void setIPAddresses(struct sockaddr_storage& addr) { addr.ss_family = AF_INET6; } inline virtual void setWifiInfo(char* ssid, char* password) { if (NULL != mSSID) strlcpy(ssid, mSSID, SSID_BUF_SIZE); else ssid[0] = '\0'; if (NULL != mPassword) strlcpy(password, mPassword, SSID_BUF_SIZE); else password[0] = '\0'; } inline virtual bool waitForCloseComplete() { return true; } inline virtual void setInactive() { mIsInactive = true; } inline virtual bool isInactive() { return mIsInactive; } virtual Subscriber* clone() { return new WIFISubscriber(mStateMachine, mSSID, mPassword, senderId); } inline virtual ~WIFISubscriber(){} }; struct DSSubscriber : public Subscriber { bool mIsInactive; inline DSSubscriber(const AgpsStateMachine *stateMachine, const int id) : Subscriber(id, stateMachine) { mIsInactive = false; } inline virtual void setIPAddresses(uint32_t &v4, char* v6) {} inline virtual void setIPAddresses(struct sockaddr_storage& addr) { addr.ss_family = AF_INET6; } virtual Subscriber* clone() {return new DSSubscriber(mStateMachine, ID);} virtual bool notifyRsrcStatus(Notification ¬ification); inline virtual bool waitForCloseComplete() { return true; } virtual void setInactive(); inline virtual bool isInactive() { return mIsInactive; } inline virtual ~DSSubscriber(){} inline virtual char *whoami() {return (char*)"DSSubscriber";} }; #endif //__LOC_ENG_AGPS_H__ ================================================ FILE: gps/loc_api/libloc_api_50001/loc_eng_dmn_conn.cpp ================================================ /* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include #include #include #include #include #include #include #include "log_util.h" #include "platform_lib_includes.h" #include "loc_eng_dmn_conn_glue_msg.h" #include "loc_eng_dmn_conn_handler.h" #include "loc_eng_dmn_conn.h" #include "loc_eng_msg.h" static int loc_api_server_msgqid; static int loc_api_resp_msgqid; static int quipc_msgqid; static int msapm_msgqid; static int msapu_msgqid; static const char * global_loc_api_q_path = GPSONE_LOC_API_Q_PATH; static const char * global_loc_api_resp_q_path = GPSONE_LOC_API_RESP_Q_PATH; static const char * global_quipc_ctrl_q_path = QUIPC_CTRL_Q_PATH; static const char * global_msapm_ctrl_q_path = MSAPM_CTRL_Q_PATH; static const char * global_msapu_ctrl_q_path = MSAPU_CTRL_Q_PATH; static int loc_api_server_proc_init(void *context) { loc_api_server_msgqid = loc_eng_dmn_conn_glue_msgget(global_loc_api_q_path, O_RDWR); //change mode/group for the global_loc_api_q_path pipe int result = chmod (global_loc_api_q_path, 0660); if (result != 0) { LOC_LOGE("failed to change mode for %s, error = %s\n", global_loc_api_q_path, strerror(errno)); } struct group * gps_group = getgrnam("gps"); if (gps_group != NULL) { result = chown (global_loc_api_q_path, -1, gps_group->gr_gid); if (result != 0) { LOC_LOGE("chown for pipe failed, pipe %s, gid = %d, result = %d, error = %s\n", global_loc_api_q_path, gps_group->gr_gid, result, strerror(errno)); } } else { LOC_LOGE("getgrnam for gps failed, error code = %d\n", errno); } loc_api_resp_msgqid = loc_eng_dmn_conn_glue_msgget(global_loc_api_resp_q_path, O_RDWR); //change mode/group for the global_loc_api_resp_q_path pipe result = chmod (global_loc_api_resp_q_path, 0660); if (result != 0) { LOC_LOGE("failed to change mode for %s, error = %s\n", global_loc_api_resp_q_path, strerror(errno)); } if (gps_group != NULL) { result = chown (global_loc_api_resp_q_path, -1, gps_group->gr_gid); if (result != 0) { LOC_LOGE("chown for pipe failed, pipe %s, gid = %d, result = %d, error = %s\n", global_loc_api_resp_q_path, gps_group->gr_gid, result, strerror(errno)); } } quipc_msgqid = loc_eng_dmn_conn_glue_msgget(global_quipc_ctrl_q_path, O_RDWR); msapm_msgqid = loc_eng_dmn_conn_glue_msgget(global_msapm_ctrl_q_path , O_RDWR); msapu_msgqid = loc_eng_dmn_conn_glue_msgget(global_msapu_ctrl_q_path , O_RDWR); LOC_LOGD("%s:%d] loc_api_server_msgqid = %d\n", __func__, __LINE__, loc_api_server_msgqid); return 0; } static int loc_api_server_proc_pre(void *context) { return 0; } static int loc_api_server_proc(void *context) { int length, sz; int result = 0; static int cnt = 0; struct ctrl_msgbuf * p_cmsgbuf; struct ctrl_msgbuf cmsg_resp; sz = sizeof(struct ctrl_msgbuf) + 256; p_cmsgbuf = (struct ctrl_msgbuf *) malloc(sz); if (!p_cmsgbuf) { LOC_LOGE("%s:%d] Out of memory\n", __func__, __LINE__); return -1; } cnt ++; LOC_LOGD("%s:%d] %d listening on %s...\n", __func__, __LINE__, cnt, (char *) context); length = loc_eng_dmn_conn_glue_msgrcv(loc_api_server_msgqid, p_cmsgbuf, sz); if (length <= 0) { free(p_cmsgbuf); LOC_LOGE("%s:%d] fail receiving msg from gpsone_daemon, retry later\n", __func__, __LINE__); usleep(1000); return -1; } LOC_LOGD("%s:%d] received ctrl_type = %d\n", __func__, __LINE__, p_cmsgbuf->ctrl_type); switch(p_cmsgbuf->ctrl_type) { case GPSONE_LOC_API_IF_REQUEST: result = loc_eng_dmn_conn_loc_api_server_if_request_handler(p_cmsgbuf, length); break; case GPSONE_LOC_API_IF_RELEASE: result = loc_eng_dmn_conn_loc_api_server_if_release_handler(p_cmsgbuf, length); break; case GPSONE_UNBLOCK: LOC_LOGD("%s:%d] GPSONE_UNBLOCK\n", __func__, __LINE__); break; default: LOC_LOGE("%s:%d] unsupported ctrl_type = %d\n", __func__, __LINE__, p_cmsgbuf->ctrl_type); break; } free(p_cmsgbuf); return 0; } static int loc_api_server_proc_post(void *context) { LOC_LOGD("%s:%d]\n", __func__, __LINE__); loc_eng_dmn_conn_glue_msgremove( global_loc_api_q_path, loc_api_server_msgqid); loc_eng_dmn_conn_glue_msgremove( global_loc_api_resp_q_path, loc_api_resp_msgqid); loc_eng_dmn_conn_glue_msgremove( global_quipc_ctrl_q_path, quipc_msgqid); loc_eng_dmn_conn_glue_msgremove( global_msapm_ctrl_q_path, msapm_msgqid); loc_eng_dmn_conn_glue_msgremove( global_msapu_ctrl_q_path, msapu_msgqid); return 0; } static int loc_eng_dmn_conn_unblock_proc(void) { struct ctrl_msgbuf cmsgbuf; cmsgbuf.ctrl_type = GPSONE_UNBLOCK; LOC_LOGD("%s:%d]\n", __func__, __LINE__); loc_eng_dmn_conn_glue_msgsnd(loc_api_server_msgqid, & cmsgbuf, sizeof(cmsgbuf)); return 0; } static struct loc_eng_dmn_conn_thelper thelper; int loc_eng_dmn_conn_loc_api_server_launch(thelper_create_thread create_thread_cb, const char * loc_api_q_path, const char * resp_q_path, void *agps_handle) { int result; loc_api_handle = agps_handle; if (loc_api_q_path) global_loc_api_q_path = loc_api_q_path; if (resp_q_path) global_loc_api_resp_q_path = resp_q_path; result = loc_eng_dmn_conn_launch_thelper( &thelper, loc_api_server_proc_init, loc_api_server_proc_pre, loc_api_server_proc, loc_api_server_proc_post, create_thread_cb, (char *) global_loc_api_q_path); if (result != 0) { LOC_LOGE("%s:%d]\n", __func__, __LINE__); return -1; } return 0; } int loc_eng_dmn_conn_loc_api_server_unblock(void) { loc_eng_dmn_conn_unblock_thelper(&thelper); loc_eng_dmn_conn_unblock_proc(); return 0; } int loc_eng_dmn_conn_loc_api_server_join(void) { loc_eng_dmn_conn_join_thelper(&thelper); return 0; } int loc_eng_dmn_conn_loc_api_server_data_conn(int sender_id, int status) { struct ctrl_msgbuf cmsgbuf; LOC_LOGD("%s:%d] quipc_msgqid = %d\n", __func__, __LINE__, quipc_msgqid); cmsgbuf.ctrl_type = GPSONE_LOC_API_RESPONSE; cmsgbuf.cmsg.cmsg_response.result = status; switch (sender_id) { case LOC_ENG_IF_REQUEST_SENDER_ID_QUIPC: { LOC_LOGD("%s:%d] sender_id = LOC_ENG_IF_REQUEST_SENDER_ID_QUIPC", __func__, __LINE__); if (loc_eng_dmn_conn_glue_msgsnd(quipc_msgqid, & cmsgbuf, sizeof(struct ctrl_msgbuf)) < 0) { LOC_LOGD("%s:%d] error! conn_glue_msgsnd failed\n", __func__, __LINE__); return -1; } break; } case LOC_ENG_IF_REQUEST_SENDER_ID_MSAPM: { LOC_LOGD("%s:%d] sender_id = LOC_ENG_IF_REQUEST_SENDER_ID_MSAPM", __func__, __LINE__); if (loc_eng_dmn_conn_glue_msgsnd(msapm_msgqid, & cmsgbuf, sizeof(struct ctrl_msgbuf)) < 0) { LOC_LOGD("%s:%d] error! conn_glue_msgsnd failed\n", __func__, __LINE__); return -1; } break; } case LOC_ENG_IF_REQUEST_SENDER_ID_MSAPU: { LOC_LOGD("%s:%d] sender_id = LOC_ENG_IF_REQUEST_SENDER_ID_MSAPU", __func__, __LINE__); if (loc_eng_dmn_conn_glue_msgsnd(msapu_msgqid, & cmsgbuf, sizeof(struct ctrl_msgbuf)) < 0) { LOC_LOGD("%s:%d] error! conn_glue_msgsnd failed\n", __func__, __LINE__); return -1; } break; } case LOC_ENG_IF_REQUEST_SENDER_ID_GPSONE_DAEMON: { LOC_LOGD("%s:%d] sender_id = LOC_ENG_IF_REQUEST_SENDER_ID_GPSONE_DAEMON", __func__, __LINE__); if (loc_eng_dmn_conn_glue_msgsnd(loc_api_resp_msgqid, & cmsgbuf, sizeof(struct ctrl_msgbuf)) < 0) { LOC_LOGD("%s:%d] error! conn_glue_msgsnd failed\n", __func__, __LINE__); return -1; } break; } default: { LOC_LOGD("%s:%d] invalid sender ID!", __func__, __LINE__); } } return 0; } ================================================ FILE: gps/loc_api/libloc_api_50001/loc_eng_dmn_conn.h ================================================ /* Copyright (c) 2011-2012,2014 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef LOC_ENG_DATA_SERVER_H #define LOC_ENG_DATA_SERVER_H #include "loc_eng_dmn_conn_thread_helper.h" #ifdef _ANDROID_ #define GPSONE_LOC_API_Q_PATH "/data/misc/location/gpsone_d/gpsone_loc_api_q" #define GPSONE_LOC_API_RESP_Q_PATH "/data/misc/location/gpsone_d/gpsone_loc_api_resp_q" #define QUIPC_CTRL_Q_PATH "/data/misc/location/gpsone_d/quipc_ctrl_q" #define MSAPM_CTRL_Q_PATH "/data/misc/location/gpsone_d/msapm_ctrl_q" #define MSAPU_CTRL_Q_PATH "/data/misc/location/gpsone_d/msapu_ctrl_q" #else #define GPSONE_LOC_API_Q_PATH "/tmp/gpsone_loc_api_q" #define GPSONE_LOC_API_RESP_Q_PATH "/tmp/gpsone_loc_api_resp_q" #define QUIPC_CTRL_Q_PATH "/tmp/quipc_ctrl_q" #define MSAPM_CTRL_Q_PATH "/tmp/msapm_ctrl_q" #define MSAPU_CTRL_Q_PATH "/tmp/msapu_ctrl_q" #endif int loc_eng_dmn_conn_loc_api_server_launch(thelper_create_thread create_thread_cb, const char * loc_api_q_path, const char * ctrl_q_path, void *agps_handle); int loc_eng_dmn_conn_loc_api_server_unblock(void); int loc_eng_dmn_conn_loc_api_server_join(void); int loc_eng_dmn_conn_loc_api_server_data_conn(int, int); #endif /* LOC_ENG_DATA_SERVER_H */ ================================================ FILE: gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_glue_msg.c ================================================ /* Copyright (c) 2011, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include #include "log_util.h" #include "platform_lib_includes.h" #include "loc_eng_dmn_conn_glue_msg.h" #include "loc_eng_dmn_conn_handler.h" /*=========================================================================== FUNCTION loc_eng_dmn_conn_glue_msgget DESCRIPTION This function get a message queue q_path - name path of the message queue mode - DEPENDENCIES None RETURN VALUE message queue id SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_dmn_conn_glue_msgget(const char * q_path, int mode) { int msgqid; msgqid = loc_eng_dmn_conn_glue_pipeget(q_path, mode); return msgqid; } /*=========================================================================== FUNCTION loc_eng_dmn_conn_glue_msgremove DESCRIPTION remove a message queue q_path - name path of the message queue msgqid - message queue id DEPENDENCIES None RETURN VALUE 0: success or negative value for failure SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_dmn_conn_glue_msgremove(const char * q_path, int msgqid) { int result; result = loc_eng_dmn_conn_glue_piperemove(q_path, msgqid); return result; } /*=========================================================================== FUNCTION loc_eng_dmn_conn_glue_msgsnd DESCRIPTION Send a message msgqid - message queue id msgp - pointer to the message to be sent msgsz - size of the message DEPENDENCIES None RETURN VALUE number of bytes sent out or negative value for failure SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_dmn_conn_glue_msgsnd(int msgqid, const void * msgp, size_t msgsz) { int result; struct ctrl_msgbuf *pmsg = (struct ctrl_msgbuf *) msgp; pmsg->msgsz = msgsz; result = loc_eng_dmn_conn_glue_pipewrite(msgqid, msgp, msgsz); if (result != (int) msgsz) { LOC_LOGE("%s:%d] pipe broken %d, msgsz = %d\n", __func__, __LINE__, result, (int) msgsz); return -1; } return result; } /*=========================================================================== FUNCTION loc_eng_dmn_conn_glue_msgrcv DESCRIPTION receive a message msgqid - message queue id msgp - pointer to the buffer to hold the message msgsz - size of the buffer DEPENDENCIES None RETURN VALUE number of bytes received or negative value for failure SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_dmn_conn_glue_msgrcv(int msgqid, void *msgp, size_t msgbufsz) { int result; struct ctrl_msgbuf *pmsg = (struct ctrl_msgbuf *) msgp; result = loc_eng_dmn_conn_glue_piperead(msgqid, &(pmsg->msgsz), sizeof(pmsg->msgsz)); if (result != sizeof(pmsg->msgsz)) { LOC_LOGE("%s:%d] pipe broken %d\n", __func__, __LINE__, result); return -1; } if (msgbufsz < pmsg->msgsz) { LOC_LOGE("%s:%d] msgbuf is too small %d < %d\n", __func__, __LINE__, (int) msgbufsz, (int) pmsg->msgsz); return -1; } result = loc_eng_dmn_conn_glue_piperead(msgqid, (uint8_t *) msgp + sizeof(pmsg->msgsz), pmsg->msgsz - sizeof(pmsg->msgsz)); if (result != (int) (pmsg->msgsz - sizeof(pmsg->msgsz))) { LOC_LOGE("%s:%d] pipe broken %d, msgsz = %d\n", __func__, __LINE__, result, (int) pmsg->msgsz); return -1; } return pmsg->msgsz; } /*=========================================================================== FUNCTION loc_eng_dmn_conn_glue_msgunblock DESCRIPTION unblock a message queue msgqid - message queue id DEPENDENCIES None RETURN VALUE 0: success SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_dmn_conn_glue_msgunblock(int msgqid) { return loc_eng_dmn_conn_glue_pipeunblock(msgqid); } /*=========================================================================== FUNCTION loc_eng_dmn_conn_glue_msgflush DESCRIPTION flush out the message in a queue msgqid - message queue id DEPENDENCIES None RETURN VALUE number of bytes that are flushed out. SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_dmn_conn_glue_msgflush(int msgqid) { int length; char buf[128]; do { length = loc_eng_dmn_conn_glue_piperead(msgqid, buf, 128); LOC_LOGD("%s:%d] %s\n", __func__, __LINE__, buf); } while(length); return length; } ================================================ FILE: gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_glue_msg.h ================================================ /* Copyright (c) 2011, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef LOC_ENG_DMN_CONN_GLUE_MSG_H #define LOC_ENG_DMN_CONN_GLUE_MSG_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #include #include "loc_eng_dmn_conn_glue_pipe.h" int loc_eng_dmn_conn_glue_msgget(const char * q_path, int mode); int loc_eng_dmn_conn_glue_msgremove(const char * q_path, int msgqid); int loc_eng_dmn_conn_glue_msgsnd(int msgqid, const void * msgp, size_t msgsz); int loc_eng_dmn_conn_glue_msgrcv(int msgqid, void *msgp, size_t msgsz); int loc_eng_dmn_conn_glue_msgflush(int msgqid); int loc_eng_dmn_conn_glue_msgunblock(int msgqid); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* LOC_ENG_DMN_CONN_GLUE_MSG_H */ ================================================ FILE: gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_glue_pipe.c ================================================ /* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include // #include #include // #include #include #include #include "loc_eng_dmn_conn_glue_pipe.h" #include "log_util.h" #include "platform_lib_includes.h" /*=========================================================================== FUNCTION loc_eng_dmn_conn_glue_pipeget DESCRIPTION create a named pipe. pipe_name - pipe name path mode - mode DEPENDENCIES None RETURN VALUE 0: success or negative value for failure SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_dmn_conn_glue_pipeget(const char * pipe_name, int mode) { int fd; int result; LOC_LOGD("%s, mode = %d\n", pipe_name, mode); result = mkfifo(pipe_name, 0660); if ((result == -1) && (errno != EEXIST)) { LOC_LOGE("failed: %s\n", strerror(errno)); return result; } // The mode in mkfifo is not honoured and does not provide the // group permissions. Doing chmod to add group permissions. result = chmod (pipe_name, 0660); if (result != 0){ LOC_LOGE ("%s failed to change mode for %s, error = %s\n", __func__, pipe_name, strerror(errno)); } fd = open(pipe_name, mode); if (fd <= 0) { LOC_LOGE("failed: %s\n", strerror(errno)); } LOC_LOGD("fd = %d, %s\n", fd, pipe_name); return fd; } /*=========================================================================== FUNCTION loc_eng_dmn_conn_glue_piperemove DESCRIPTION remove a pipe pipe_name - pipe name path fd - fd for the pipe DEPENDENCIES None RETURN VALUE 0: success SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_dmn_conn_glue_piperemove(const char * pipe_name, int fd) { close(fd); if (pipe_name) unlink(pipe_name); LOC_LOGD("fd = %d, %s\n", fd, pipe_name); return 0; } /*=========================================================================== FUNCTION loc_eng_dmn_conn_glue_pipewrite DESCRIPTION write to a pipe fd - fd of a pipe buf - buffer for the data to write sz - size of the data in buffer DEPENDENCIES None RETURN VALUE number of bytes written or negative value for failure SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_dmn_conn_glue_pipewrite(int fd, const void * buf, size_t sz) { int result; result = write(fd, buf, sz); /* @todo check for non EINTR & EAGAIN, shall not do select again, select_tut Law 7) */ /* LOC_LOGD("fd = %d, buf = 0x%lx, size = %d, result = %d\n", fd, (long) buf, (int) sz, (int) result); */ return result; } /*=========================================================================== FUNCTION loc_eng_dmn_conn_glue_piperead DESCRIPTION read from a pipe fd - fd for the pipe buf - buffer to hold the data read from pipe sz - size of the buffer DEPENDENCIES None RETURN VALUE number of bytes read from pipe or negative value for failure SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_dmn_conn_glue_piperead(int fd, void * buf, size_t sz) { int len; len = read(fd, buf, sz); /* @todo check for non EINTR & EAGAIN, shall not do select again, select_tut Law 7) */ /* LOC_LOGD("fd = %d, buf = 0x%lx, size = %d, len = %d\n", fd, (long) buf, (int) sz, len); */ return len; } /*=========================================================================== FUNCTION loc_eng_dmn_conn_glue_pipeunblock DESCRIPTION unblock a pipe fd - fd for the pipe DEPENDENCIES None RETURN VALUE 0 for success or negative value for failure SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_dmn_conn_glue_pipeunblock(int fd) { int result; struct flock flock_v; LOC_LOGD("\n"); // result = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NDELAY); flock_v.l_type = F_UNLCK; flock_v.l_len = 32; result = fcntl(fd, F_SETLK, &flock_v); if (result < 0) { LOC_LOGE("fcntl failure, %s\n", strerror(errno)); } return result; } ================================================ FILE: gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_glue_pipe.h ================================================ /* Copyright (c) 2011, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef LOC_ENG_DMN_CONN_GLUE_PIPE_H #define LOC_ENG_DMN_CONN_GLUE_PIPE_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #include int loc_eng_dmn_conn_glue_pipeget(const char * pipe_name, int mode); int loc_eng_dmn_conn_glue_piperemove(const char * pipe_name, int fd); int loc_eng_dmn_conn_glue_pipewrite(int fd, const void * buf, size_t sz); int loc_eng_dmn_conn_glue_piperead(int fd, void * buf, size_t sz); int loc_eng_dmn_conn_glue_pipeflush(int fd); int loc_eng_dmn_conn_glue_pipeunblock(int fd); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* LOC_ENG_DMN_CONN_GLUE_PIPE_H */ ================================================ FILE: gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_handler.cpp ================================================ /* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include #include #include "log_util.h" #include "platform_lib_includes.h" #include "loc_eng_msg.h" #include "loc_eng_dmn_conn.h" #include "loc_eng_dmn_conn_handler.h" void* loc_api_handle = NULL; int loc_eng_dmn_conn_loc_api_server_if_request_handler(struct ctrl_msgbuf *pmsg, int len) { LOC_LOGD("%s:%d]\n", __func__, __LINE__); #ifndef DEBUG_DMN_LOC_API if (NULL == loc_api_handle) { LOC_LOGE("%s:%d] NO agps data handle\n", __func__, __LINE__); return 1; } if (NULL != loc_api_handle) { AGpsExtType type; switch (pmsg->cmsg.cmsg_if_request.type) { case IF_REQUEST_TYPE_SUPL: { LOC_LOGD("IF_REQUEST_TYPE_SUPL"); type = AGPS_TYPE_SUPL; break; } case IF_REQUEST_TYPE_WIFI: { LOC_LOGD("IF_REQUEST_TYPE_WIFI"); type = AGPS_TYPE_WIFI; break; } case IF_REQUEST_TYPE_ANY: { LOC_LOGD("IF_REQUEST_TYPE_ANY"); type = AGPS_TYPE_ANY; break; } default: { LOC_LOGD("invalid IF_REQUEST_TYPE!"); return -1; } } switch (pmsg->cmsg.cmsg_if_request.sender_id) { case IF_REQUEST_SENDER_ID_QUIPC: { LOC_LOGD("IF_REQUEST_SENDER_ID_QUIPC"); LocEngReqRelWifi* msg = new LocEngReqRelWifi(loc_api_handle, type, LOC_ENG_IF_REQUEST_SENDER_ID_QUIPC, (char*)pmsg->cmsg.cmsg_if_request.ssid, (char*)pmsg->cmsg.cmsg_if_request.password, true); msg->send(); break; } case IF_REQUEST_SENDER_ID_MSAPM: { LOC_LOGD("IF_REQUEST_SENDER_ID_MSAPM"); LocEngReqRelWifi* msg = new LocEngReqRelWifi(loc_api_handle, type, LOC_ENG_IF_REQUEST_SENDER_ID_MSAPM, (char*)pmsg->cmsg.cmsg_if_request.ssid, (char*)pmsg->cmsg.cmsg_if_request.password, true); msg->send(); break; } case IF_REQUEST_SENDER_ID_MSAPU: { LOC_LOGD("IF_REQUEST_SENDER_ID_MSAPU"); LocEngReqRelWifi* msg = new LocEngReqRelWifi(loc_api_handle, type, LOC_ENG_IF_REQUEST_SENDER_ID_MSAPU, (char*)pmsg->cmsg.cmsg_if_request.ssid, (char*)pmsg->cmsg.cmsg_if_request.password, true); msg->send(); break; } case IF_REQUEST_SENDER_ID_GPSONE_DAEMON: { LOC_LOGD("IF_REQUEST_SENDER_ID_GPSONE_DAEMON"); LocEngReqRelBIT* msg = new LocEngReqRelBIT(loc_api_handle, type, pmsg->cmsg.cmsg_if_request.ipv4_addr, (char*)pmsg->cmsg.cmsg_if_request.ipv6_addr, true); msg->send(); break; } default: { LOC_LOGD("invalid IF_REQUEST_SENDER_ID!"); return -1; } } } #else loc_eng_dmn_conn_loc_api_server_data_conn(LOC_ENG_IF_REQUEST_SENDER_ID_GPSONE_DAEMON, GPSONE_LOC_API_IF_REQUEST_SUCCESS); #endif return 0; } int loc_eng_dmn_conn_loc_api_server_if_release_handler(struct ctrl_msgbuf *pmsg, int len) { LOC_LOGD("%s:%d]\n", __func__, __LINE__); #ifndef DEBUG_DMN_LOC_API AGpsExtType type; switch (pmsg->cmsg.cmsg_if_request.type) { case IF_REQUEST_TYPE_SUPL: { LOC_LOGD("IF_REQUEST_TYPE_SUPL"); type = AGPS_TYPE_SUPL; break; } case IF_REQUEST_TYPE_WIFI: { LOC_LOGD("IF_REQUEST_TYPE_WIFI"); type = AGPS_TYPE_WIFI; break; } case IF_REQUEST_TYPE_ANY: { LOC_LOGD("IF_REQUEST_TYPE_ANY"); type = AGPS_TYPE_ANY; break; } default: { LOC_LOGD("invalid IF_REQUEST_TYPE!"); return -1; } } switch (pmsg->cmsg.cmsg_if_request.sender_id) { case IF_REQUEST_SENDER_ID_QUIPC: { LOC_LOGD("IF_REQUEST_SENDER_ID_QUIPC"); LocEngReqRelWifi* msg = new LocEngReqRelWifi(loc_api_handle, type, LOC_ENG_IF_REQUEST_SENDER_ID_QUIPC, (char*)pmsg->cmsg.cmsg_if_request.ssid, (char*)pmsg->cmsg.cmsg_if_request.password, false); msg->send(); break; } case IF_REQUEST_SENDER_ID_MSAPM: { LOC_LOGD("IF_REQUEST_SENDER_ID_MSAPM"); LocEngReqRelWifi* msg = new LocEngReqRelWifi(loc_api_handle, type, LOC_ENG_IF_REQUEST_SENDER_ID_MSAPM, (char*)pmsg->cmsg.cmsg_if_request.ssid, (char*)pmsg->cmsg.cmsg_if_request.password, false); msg->send(); break; } case IF_REQUEST_SENDER_ID_MSAPU: { LOC_LOGD("IF_REQUEST_SENDER_ID_MSAPU"); LocEngReqRelWifi* msg = new LocEngReqRelWifi(loc_api_handle, type, LOC_ENG_IF_REQUEST_SENDER_ID_MSAPU, (char*)pmsg->cmsg.cmsg_if_request.ssid, (char*)pmsg->cmsg.cmsg_if_request.password, false); msg->send(); break; } case IF_REQUEST_SENDER_ID_GPSONE_DAEMON: { LOC_LOGD("IF_REQUEST_SENDER_ID_GPSONE_DAEMON"); LocEngReqRelBIT* msg = new LocEngReqRelBIT(loc_api_handle, type, pmsg->cmsg.cmsg_if_request.ipv4_addr, (char*)pmsg->cmsg.cmsg_if_request.ipv6_addr, false); msg->send(); break; } default: { LOC_LOGD("invalid IF_REQUEST_SENDER_ID!"); return -1; } } #else loc_eng_dmn_conn_loc_api_server_data_conn(LOC_ENG_IF_REQUEST_SENDER_ID_GPSONE_DAEMON, GPSONE_LOC_API_IF_RELEASE_SUCCESS); #endif return 0; } ================================================ FILE: gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_handler.h ================================================ /* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef LOC_ENG_DATA_SERVER_HANDLER #define LOC_ENG_DATA_SERVER_HANDLER #include #include //for SSID_BUF_SIZE #include #ifndef SSID_BUF_SIZE #define SSID_BUF_SIZE (32+1) #endif enum { /* 0x0 - 0xEF is reserved for daemon internal */ GPSONE_LOC_API_IF_REQUEST = 0xF0, GPSONE_LOC_API_IF_RELEASE, GPSONE_LOC_API_RESPONSE, GPSONE_UNBLOCK, }; enum { GPSONE_LOC_API_IF_REQUEST_SUCCESS = 0xF0, GPSONE_LOC_API_IF_RELEASE_SUCCESS, GPSONE_LOC_API_IF_FAILURE, }; struct ctrl_msg_response { int result; }; struct ctrl_msg_unblock { int reserved; }; typedef enum { IF_REQUEST_TYPE_SUPL = 0, IF_REQUEST_TYPE_WIFI, IF_REQUEST_TYPE_ANY } ctrl_if_req_type_e_type; typedef enum { IF_REQUEST_SENDER_ID_QUIPC = 0, IF_REQUEST_SENDER_ID_MSAPM, IF_REQUEST_SENDER_ID_MSAPU, IF_REQUEST_SENDER_ID_GPSONE_DAEMON, IF_REQUEST_SENDER_ID_MODEM } ctrl_if_req_sender_id_e_type; struct ctrl_msg_if_request { ctrl_if_req_type_e_type type; ctrl_if_req_sender_id_e_type sender_id; unsigned long ipv4_addr; unsigned char ipv6_addr[16]; char ssid[SSID_BUF_SIZE]; char password[SSID_BUF_SIZE]; }; /* do not change this structure */ struct ctrl_msgbuf { size_t msgsz; uint16_t reserved1; uint32_t reserved2; uint8_t ctrl_type; union { struct ctrl_msg_response cmsg_response; struct ctrl_msg_unblock cmsg_unblock; struct ctrl_msg_if_request cmsg_if_request; } cmsg; }; extern void* loc_api_handle; int loc_eng_dmn_conn_loc_api_server_if_request_handler(struct ctrl_msgbuf *pmsg, int len); int loc_eng_dmn_conn_loc_api_server_if_release_handler(struct ctrl_msgbuf *pmsg, int len); #endif /* LOC_ENG_DATA_SERVER_HANDLER */ ================================================ FILE: gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_thread_helper.c ================================================ /* Copyright (c) 2011, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include #include "log_util.h" #include "platform_lib_includes.h" #include "loc_eng_dmn_conn_thread_helper.h" /*=========================================================================== FUNCTION thelper_signal_init DESCRIPTION This function will initialize the conditional variable resources. thelper - thelper instance DEPENDENCIES None RETURN VALUE 0: success or negative value for failure SIDE EFFECTS N/A ===========================================================================*/ int thelper_signal_init(struct loc_eng_dmn_conn_thelper * thelper) { int result; thelper->thread_exit = 0; thelper->thread_ready = 0; result = pthread_cond_init( &thelper->thread_cond, NULL); if (result) { return result; } result = pthread_mutex_init(&thelper->thread_mutex, NULL); if (result) { pthread_cond_destroy(&thelper->thread_cond); } return result; } /*=========================================================================== FUNCTION DESCRIPTION This function will destroy the conditional variable resources thelper - pointer to thelper instance DEPENDENCIES None RETURN VALUE 0: success or negative value for failure SIDE EFFECTS N/A ===========================================================================*/ int thelper_signal_destroy(struct loc_eng_dmn_conn_thelper * thelper) { int result, ret_result = 0; result = pthread_cond_destroy( &thelper->thread_cond); if (result) { ret_result = result; } result = pthread_mutex_destroy(&thelper->thread_mutex); if (result) { ret_result = result; } return ret_result; } /*=========================================================================== FUNCTION thelper_signal_wait DESCRIPTION This function will be blocked on the conditional variable until thelper_signal_ready is called thelper - pointer to thelper instance DEPENDENCIES None RETURN VALUE 0: success or negative value for failure SIDE EFFECTS N/A ===========================================================================*/ int thelper_signal_wait(struct loc_eng_dmn_conn_thelper * thelper) { int result = 0; pthread_mutex_lock(&thelper->thread_mutex); if (!thelper->thread_ready && !thelper->thread_exit) { result = pthread_cond_wait(&thelper->thread_cond, &thelper->thread_mutex); } if (thelper->thread_exit) { result = -1; } pthread_mutex_unlock(&thelper->thread_mutex); return result; } /*=========================================================================== FUNCTION thelper_signal_ready DESCRIPTION This function will wake up the conditional variable thelper - pointer to thelper instance DEPENDENCIES None RETURN VALUE 0: success or negative value for failure SIDE EFFECTS N/A ===========================================================================*/ int thelper_signal_ready(struct loc_eng_dmn_conn_thelper * thelper) { int result; LOC_LOGD("%s:%d] 0x%lx\n", __func__, __LINE__, (long) thelper); pthread_mutex_lock(&thelper->thread_mutex); thelper->thread_ready = 1; result = pthread_cond_signal(&thelper->thread_cond); pthread_mutex_unlock(&thelper->thread_mutex); return result; } /*=========================================================================== FUNCTION thelper_signal_block DESCRIPTION This function will set the thread ready to 0 to block the thelper_signal_wait thelper - pointer to thelper instance DEPENDENCIES None RETURN VALUE if thread_ready is set SIDE EFFECTS N/A ===========================================================================*/ int thelper_signal_block(struct loc_eng_dmn_conn_thelper * thelper) { int result = thelper->thread_ready; LOC_LOGD("%s:%d] 0x%lx\n", __func__, __LINE__, (long) thelper); pthread_mutex_lock(&thelper->thread_mutex); thelper->thread_ready = 0; pthread_mutex_unlock(&thelper->thread_mutex); return result; } /*=========================================================================== FUNCTION thelper_main DESCRIPTION This function is the main thread. It will be launched as a child thread data - pointer to the instance DEPENDENCIES None RETURN VALUE NULL SIDE EFFECTS N/A ===========================================================================*/ static void * thelper_main(void *data) { int result = 0; struct loc_eng_dmn_conn_thelper * thelper = (struct loc_eng_dmn_conn_thelper *) data; if (thelper->thread_proc_init) { result = thelper->thread_proc_init(thelper->thread_context); if (result < 0) { thelper->thread_exit = 1; thelper_signal_ready(thelper); LOC_LOGE("%s:%d] error: 0x%lx\n", __func__, __LINE__, (long) thelper); return NULL; } } thelper_signal_ready(thelper); if (thelper->thread_proc_pre) { result = thelper->thread_proc_pre(thelper->thread_context); if (result < 0) { thelper->thread_exit = 1; LOC_LOGE("%s:%d] error: 0x%lx\n", __func__, __LINE__, (long) thelper); return NULL; } } do { if (thelper->thread_proc) { result = thelper->thread_proc(thelper->thread_context); if (result < 0) { thelper->thread_exit = 1; LOC_LOGE("%s:%d] error: 0x%lx\n", __func__, __LINE__, (long) thelper); } } } while (thelper->thread_exit == 0); if (thelper->thread_proc_post) { result = thelper->thread_proc_post(thelper->thread_context); } if (result != 0) { LOC_LOGE("%s:%d] error: 0x%lx\n", __func__, __LINE__, (long) thelper); } return NULL; } static void thelper_main_2(void *data) { thelper_main(data); return; } /*=========================================================================== FUNCTION loc_eng_dmn_conn_launch_thelper DESCRIPTION This function will initialize the thread context and launch the thelper_main thelper - pointer to thelper instance thread_proc_init - The initialization function pointer thread_proc_pre - The function to call before task loop and after initialization thread_proc - The task loop thread_proc_post - The function to call after the task loop context - the context for the above four functions DEPENDENCIES None RETURN VALUE 0: success or negative value for failure SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_dmn_conn_launch_thelper(struct loc_eng_dmn_conn_thelper * thelper, int (*thread_proc_init) (void * context), int (*thread_proc_pre) (void * context), int (*thread_proc) (void * context), int (*thread_proc_post) (void * context), thelper_create_thread create_thread_cb, void * context) { int result; thelper_signal_init(thelper); if (context) { thelper->thread_context = context; } thelper->thread_proc_init = thread_proc_init; thelper->thread_proc_pre = thread_proc_pre; thelper->thread_proc = thread_proc; thelper->thread_proc_post = thread_proc_post; LOC_LOGD("%s:%d] 0x%lx call pthread_create\n", __func__, __LINE__, (long) thelper); if (create_thread_cb) { result = 0; thelper->thread_id = create_thread_cb("loc_eng_dmn_conn", thelper_main_2, (void *)thelper); } else { result = pthread_create(&thelper->thread_id, NULL, thelper_main, (void *)thelper); } if (result != 0) { LOC_LOGE("%s:%d] 0x%lx\n", __func__, __LINE__, (long) thelper); return -1; } LOC_LOGD("%s:%d] 0x%lx pthread_create done\n", __func__, __LINE__, (long) thelper); thelper_signal_wait(thelper); LOC_LOGD("%s:%d] 0x%lx pthread ready\n", __func__, __LINE__, (long) thelper); return thelper->thread_exit; } /*=========================================================================== FUNCTION loc_eng_dmn_conn_unblock_thelper DESCRIPTION This function unblocks thelper_main to release the thread thelper - pointer to thelper instance DEPENDENCIES None RETURN VALUE 0: success SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_dmn_conn_unblock_thelper(struct loc_eng_dmn_conn_thelper * thelper) { LOC_LOGD("%s:%d] 0x%lx\n", __func__, __LINE__, (long) thelper); thelper->thread_exit = 1; return 0; } /*=========================================================================== FUNCTION loc_eng_dmn_conn_join_thelper thelper - pointer to thelper instance DESCRIPTION This function will wait for the thread of thelper_main to finish DEPENDENCIES None RETURN VALUE 0: success or negative value for failure SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_dmn_conn_join_thelper(struct loc_eng_dmn_conn_thelper * thelper) { int result; LOC_LOGD("%s:%d] 0x%lx\n", __func__, __LINE__, (long) thelper); result = pthread_join(thelper->thread_id, NULL); if (result != 0) { LOC_LOGE("%s:%d] 0x%lx\n", __func__, __LINE__, (long) thelper); } LOC_LOGD("%s:%d] 0x%lx\n", __func__, __LINE__, (long) thelper); thelper_signal_destroy(thelper); return result; } ================================================ FILE: gps/loc_api/libloc_api_50001/loc_eng_dmn_conn_thread_helper.h ================================================ /* Copyright (c) 2011, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef __LOC_ENG_DMN_CONN_THREAD_HELPER_H__ #define __LOC_ENG_DMN_CONN_THREAD_HELPER_H__ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #include struct loc_eng_dmn_conn_thelper { unsigned char thread_exit; unsigned char thread_ready; pthread_cond_t thread_cond; pthread_mutex_t thread_mutex; pthread_t thread_id; void * thread_context; int (*thread_proc_init) (void * context); int (*thread_proc_pre) (void * context); int (*thread_proc) (void * context); int (*thread_proc_post) (void * context); }; typedef pthread_t (* thelper_create_thread)(const char* name, void (*start)(void *), void* arg); int loc_eng_dmn_conn_launch_thelper(struct loc_eng_dmn_conn_thelper * thelper, int (*thread_proc_init) (void * context), int (*thread_proc_pre) (void * context), int (*thread_proc) (void * context), int (*thread_proc_post) (void * context), thelper_create_thread create_thread_cb, void * context); int loc_eng_dmn_conn_unblock_thelper(struct loc_eng_dmn_conn_thelper * thelper); int loc_eng_dmn_conn_join_thelper(struct loc_eng_dmn_conn_thelper * thelper); /* if only need to use signal */ int thelper_signal_init(struct loc_eng_dmn_conn_thelper * thelper); int thelper_signal_destroy(struct loc_eng_dmn_conn_thelper * thelper); int thelper_signal_wait(struct loc_eng_dmn_conn_thelper * thelper); int thelper_signal_ready(struct loc_eng_dmn_conn_thelper * thelper); int thelper_signal_block(struct loc_eng_dmn_conn_thelper * thelper); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* __LOC_ENG_DMN_CONN_THREAD_HELPER_H__ */ ================================================ FILE: gps/loc_api/libloc_api_50001/loc_eng_log.cpp ================================================ /* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #define LOG_NDDEBUG 0 #define LOG_TAG "LocSvc_eng" #include "loc_log.h" #include "loc_eng_log.h" ================================================ FILE: gps/loc_api/libloc_api_50001/loc_eng_log.h ================================================ /* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef LOC_ENG_LOG_H #define LOC_ENG_LOG_H #ifdef __cplusplus extern "C" { #endif #include #ifdef __cplusplus } #endif #endif /* LOC_ENG_LOG_H */ ================================================ FILE: gps/loc_api/libloc_api_50001/loc_eng_msg.h ================================================ /* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef LOC_ENG_MSG_H #define LOC_ENG_MSG_H #include #include #include #include #include #include #include #include #include #ifndef SSID_BUF_SIZE #define SSID_BUF_SIZE (32+1) #endif #ifdef USE_GLIB #include #endif /* USE_GLIB */ #include "platform_lib_includes.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ using namespace loc_core; struct LocEngPositionMode : public LocMsg { LocEngAdapter* mAdapter; const LocPosMode mPosMode; LocEngPositionMode(LocEngAdapter* adapter, LocPosMode &mode); virtual void proc() const; virtual void log() const; void send() const; }; struct LocEngStartFix : public LocMsg { LocEngAdapter* mAdapter; LocEngStartFix(LocEngAdapter* adapter); virtual void proc() const; void locallog() const; virtual void log() const; void send() const; }; struct LocEngStopFix : public LocMsg { LocEngAdapter* mAdapter; LocEngStopFix(LocEngAdapter* adapter); virtual void proc() const; void locallog() const; virtual void log() const; void send() const; }; struct LocEngReportPosition : public LocMsg { LocAdapterBase* mAdapter; const UlpLocation mLocation; const GpsLocationExtended mLocationExtended; const void* mLocationExt; const enum loc_sess_status mStatus; const LocPosTechMask mTechMask; LocEngReportPosition(LocAdapterBase* adapter, UlpLocation &loc, GpsLocationExtended &locExtended, void* locExt, enum loc_sess_status st, LocPosTechMask technology); virtual void proc() const; void locallog() const; virtual void log() const; void send() const; }; struct LocEngReportSv : public LocMsg { LocAdapterBase* mAdapter; const QcomSvStatus mSvStatus; const GpsLocationExtended mLocationExtended; const void* mSvExt; LocEngReportSv(LocAdapterBase* adapter, QcomSvStatus &sv, GpsLocationExtended &locExtended, void* svExtended); virtual void proc() const; void locallog() const; virtual void log() const; void send() const; }; struct LocEngReportStatus : public LocMsg { LocAdapterBase* mAdapter; const GpsStatusValue mStatus; LocEngReportStatus(LocAdapterBase* adapter, GpsStatusValue engineStatus); virtual void proc() const; void locallog() const; virtual void log() const; }; struct LocEngReportNmea : public LocMsg { void* mLocEng; char* const mNmea; const int mLen; LocEngReportNmea(void* locEng, const char* data, int len); inline virtual ~LocEngReportNmea() { delete[] mNmea; } virtual void proc() const; void locallog() const; virtual void log() const; }; struct LocEngReportXtraServer : public LocMsg { void* mLocEng; int mMaxLen; char *mServers; LocEngReportXtraServer(void* locEng, const char *url1, const char *url2, const char *url3, const int maxlength); inline virtual ~LocEngReportXtraServer() { delete[] mServers; } virtual void proc() const; void locallog() const; virtual void log() const; }; struct LocEngSuplEsOpened : public LocMsg { void* mLocEng; LocEngSuplEsOpened(void* locEng); virtual void proc() const; void locallog() const; virtual void log() const; }; struct LocEngSuplEsClosed : public LocMsg { void* mLocEng; LocEngSuplEsClosed(void* locEng); virtual void proc() const; void locallog() const; virtual void log() const; }; struct LocEngRequestSuplEs : public LocMsg { void* mLocEng; const int mID; LocEngRequestSuplEs(void* locEng, int id); virtual void proc() const; void locallog() const; virtual void log() const; }; struct LocEngRequestATL : public LocMsg { void* mLocEng; const int mID; const AGpsExtType mType; LocEngRequestATL(void* locEng, int id, AGpsExtType agps_type); virtual void proc() const; void locallog() const; virtual void log() const; }; struct LocEngReleaseATL : public LocMsg { void* mLocEng; const int mID; LocEngReleaseATL(void* locEng, int id); virtual void proc() const; void locallog() const; virtual void log() const; }; struct LocEngReqRelBIT : public LocMsg { void* mLocEng; const AGpsExtType mType; const int mIPv4Addr; char* const mIPv6Addr; const bool mIsReq; LocEngReqRelBIT(void* instance, AGpsExtType type, int ipv4, char* ipv6, bool isReq); virtual ~LocEngReqRelBIT(); virtual void proc() const; void locallog() const; virtual void log() const; void send() const; }; struct LocEngReqRelWifi : public LocMsg { void* mLocEng; const AGpsExtType mType; const loc_if_req_sender_id_e_type mSenderId; char* const mSSID; char* const mPassword; const bool mIsReq; LocEngReqRelWifi(void* locEng, AGpsExtType type, loc_if_req_sender_id_e_type sender_id, char* s, char* p, bool isReq); virtual ~LocEngReqRelWifi(); virtual void proc() const; void locallog() const; virtual void log() const; void send() const; }; struct LocEngRequestXtra : public LocMsg { void* mLocEng; LocEngRequestXtra(void* locEng); virtual void proc() const; void locallog() const; virtual void log() const; }; struct LocEngRequestTime : public LocMsg { void* mLocEng; LocEngRequestTime(void* locEng); virtual void proc() const; void locallog() const; virtual void log() const; }; struct LocEngRequestNi : public LocMsg { void* mLocEng; const GpsNiNotification mNotify; const void *mPayload; LocEngRequestNi(void* locEng, GpsNiNotification ¬if, const void* data); virtual void proc() const; void locallog() const; virtual void log() const; }; struct LocEngDown : public LocMsg { void* mLocEng; LocEngDown(void* locEng); virtual void proc() const; void locallog() const; virtual void log() const; }; struct LocEngUp : public LocMsg { void* mLocEng; LocEngUp(void* locEng); virtual void proc() const; void locallog() const; virtual void log() const; }; struct LocEngGetZpp : public LocMsg { LocEngAdapter* mAdapter; LocEngGetZpp(LocEngAdapter* adapter); virtual void proc() const; void locallog() const; virtual void log() const; void send() const; }; struct LocEngReportGpsMeasurement : public LocMsg { void* mLocEng; const GpsData mGpsData; LocEngReportGpsMeasurement(void* locEng, GpsData &gpsData); virtual void proc() const; void locallog() const; virtual void log() const; }; #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* LOC_ENG_MSG_H */ ================================================ FILE: gps/loc_api/libloc_api_50001/loc_eng_ni.cpp ================================================ /* Copyright (c) 2009-2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #define LOG_NDDEBUG 0 #define LOG_TAG "LocSvc_eng" #include #include #include #include #include #include #include #include #include #include #include #include "log_util.h" #include "platform_lib_includes.h" using namespace loc_core; /*============================================================================= * * DATA DECLARATION * *============================================================================*/ /*============================================================================= * * FUNCTION DECLARATIONS * *============================================================================*/ static void* ni_thread_proc(void *args); struct LocEngInformNiResponse : public LocMsg { LocEngAdapter* mAdapter; const GpsUserResponseType mResponse; const void *mPayload; inline LocEngInformNiResponse(LocEngAdapter* adapter, GpsUserResponseType resp, const void* data) : LocMsg(), mAdapter(adapter), mResponse(resp), mPayload(data) { locallog(); } inline ~LocEngInformNiResponse() { // this is a bit weird since mPayload is not // allocated by this class. But there is no better way. // mPayload actually won't be NULL here. free((void*)mPayload); } inline virtual void proc() const { mAdapter->informNiResponse(mResponse, mPayload); } inline void locallog() const { LOC_LOGV("LocEngInformNiResponse - " "response: %s\n mPayload: %p", loc_get_ni_response_name(mResponse), mPayload); } inline virtual void log() const { locallog(); } }; /*=========================================================================== FUNCTION loc_eng_ni_request_handler DESCRIPTION Displays the NI request and awaits user input. If a previous request is in session, it is ignored. RETURN VALUE none ===========================================================================*/ void loc_eng_ni_request_handler(loc_eng_data_s_type &loc_eng_data, const GpsNiNotification *notif, const void* passThrough) { ENTRY_LOG(); char lcs_addr[32]; // Decoded LCS address for UMTS CP NI loc_eng_ni_data_s_type* loc_eng_ni_data_p = &loc_eng_data.loc_eng_ni_data; loc_eng_ni_session_s_type* pSession = NULL; if (NULL == loc_eng_data.ni_notify_cb) { EXIT_LOG(%s, "loc_eng_ni_init hasn't happened yet."); return; } if (notif->ni_type == GPS_NI_TYPE_EMERGENCY_SUPL) { if (NULL != loc_eng_ni_data_p->sessionEs.rawRequest) { LOC_LOGW("loc_eng_ni_request_handler, supl es NI in progress, new supl es NI ignored, type: %d", notif->ni_type); if (NULL != passThrough) { free((void*)passThrough); } } else { pSession = &loc_eng_ni_data_p->sessionEs; } } else { if (NULL != loc_eng_ni_data_p->session.rawRequest || NULL != loc_eng_ni_data_p->sessionEs.rawRequest) { LOC_LOGW("loc_eng_ni_request_handler, supl NI in progress, new supl NI ignored, type: %d", notif->ni_type); if (NULL != passThrough) { free((void*)passThrough); } } else { pSession = &loc_eng_ni_data_p->session; } } if (pSession) { /* Save request */ pSession->rawRequest = (void*)passThrough; pSession->reqID = ++loc_eng_ni_data_p->reqIDCounter; pSession->adapter = loc_eng_data.adapter; /* Fill in notification */ ((GpsNiNotification*)notif)->notification_id = pSession->reqID; if (notif->notify_flags == GPS_NI_PRIVACY_OVERRIDE) { loc_eng_mute_one_session(loc_eng_data); } /* Log requestor ID and text for debugging */ LOC_LOGI("Notification: notif_type: %d, timeout: %d, default_resp: %d", notif->ni_type, notif->timeout, notif->default_response); LOC_LOGI(" requestor_id: %s (encoding: %d)", notif->requestor_id, notif->requestor_id_encoding); LOC_LOGI(" text: %s text (encoding: %d)", notif->text, notif->text_encoding); if (notif->extras[0]) { LOC_LOGI(" extras: %s", notif->extras); } /* For robustness, spawn a thread at this point to timeout to clear up the notification status, even though * the OEM layer in java does not do so. **/ pSession->respTimeLeft = 5 + (notif->timeout != 0 ? notif->timeout : LOC_NI_NO_RESPONSE_TIME); LOC_LOGI("Automatically sends 'no response' in %d seconds (to clear status)\n", pSession->respTimeLeft); int rc = 0; rc = pthread_create(&pSession->thread, NULL, ni_thread_proc, pSession); if (rc) { LOC_LOGE("Loc NI thread is not created.\n"); } rc = pthread_detach(pSession->thread); if (rc) { LOC_LOGE("Loc NI thread is not detached.\n"); } CALLBACK_LOG_CALLFLOW("ni_notify_cb - id", %d, notif->notification_id); loc_eng_data.ni_notify_cb((GpsNiNotification*)notif); } EXIT_LOG(%s, VOID_RET); } /*=========================================================================== FUNCTION ni_thread_proc ===========================================================================*/ static void* ni_thread_proc(void *args) { ENTRY_LOG(); loc_eng_ni_session_s_type* pSession = (loc_eng_ni_session_s_type*)args; int rc = 0; /* return code from pthread calls */ struct timeval present_time; struct timespec expire_time; LOC_LOGD("Starting Loc NI thread...\n"); pthread_mutex_lock(&pSession->tLock); /* Calculate absolute expire time */ gettimeofday(&present_time, NULL); expire_time.tv_sec = present_time.tv_sec + pSession->respTimeLeft; expire_time.tv_nsec = present_time.tv_usec * 1000; LOC_LOGD("ni_thread_proc-Time out set for abs time %ld with delay %d sec\n", (long) expire_time.tv_sec, pSession->respTimeLeft ); while (!pSession->respRecvd) { rc = pthread_cond_timedwait(&pSession->tCond, &pSession->tLock, &expire_time); if (rc == ETIMEDOUT) { pSession->resp = GPS_NI_RESPONSE_NORESP; LOC_LOGD("ni_thread_proc-Thread time out after valting for specified time. Ret Val %d\n",rc ); break; } } LOC_LOGD("ni_thread_proc-Java layer has sent us a user response and return value from " "pthread_cond_timedwait = %d\n",rc ); pSession->respRecvd = FALSE; /* Reset the user response flag for the next session*/ LOC_LOGD("pSession->resp is %d\n",pSession->resp); // adding this check to support modem restart, in which case, we need the thread // to exit without calling sending data. We made sure that rawRequest is NULL in // loc_eng_ni_reset_on_engine_restart() LocEngAdapter* adapter = pSession->adapter; LocEngInformNiResponse *msg = NULL; if (NULL != pSession->rawRequest) { if (pSession->resp != GPS_NI_RESPONSE_IGNORE) { LOC_LOGD("pSession->resp != GPS_NI_RESPONSE_IGNORE \n"); msg = new LocEngInformNiResponse(adapter, pSession->resp, pSession->rawRequest); } else { LOC_LOGD("this is the ignore reply for SUPL ES\n"); free(pSession->rawRequest); } pSession->rawRequest = NULL; } pthread_mutex_unlock(&pSession->tLock); pSession->respTimeLeft = 0; pSession->reqID = 0; if (NULL != msg) { LOC_LOGD("ni_thread_proc: adapter->sendMsg(msg)\n"); adapter->sendMsg(msg); } EXIT_LOG(%s, VOID_RET); return NULL; } void loc_eng_ni_reset_on_engine_restart(loc_eng_data_s_type &loc_eng_data) { ENTRY_LOG(); loc_eng_ni_data_s_type* loc_eng_ni_data_p = &loc_eng_data.loc_eng_ni_data; if (NULL == loc_eng_data.ni_notify_cb) { EXIT_LOG(%s, "loc_eng_ni_init hasn't happened yet."); return; } // only if modem has requested but then died. if (NULL != loc_eng_ni_data_p->sessionEs.rawRequest) { free(loc_eng_ni_data_p->sessionEs.rawRequest); loc_eng_ni_data_p->sessionEs.rawRequest = NULL; pthread_mutex_lock(&loc_eng_ni_data_p->sessionEs.tLock); // the goal is to wake up ni_thread_proc // and let it exit. loc_eng_ni_data_p->sessionEs.respRecvd = TRUE; pthread_cond_signal(&loc_eng_ni_data_p->sessionEs.tCond); pthread_mutex_unlock(&loc_eng_ni_data_p->sessionEs.tLock); } if (NULL != loc_eng_ni_data_p->session.rawRequest) { free(loc_eng_ni_data_p->session.rawRequest); loc_eng_ni_data_p->session.rawRequest = NULL; pthread_mutex_lock(&loc_eng_ni_data_p->session.tLock); // the goal is to wake up ni_thread_proc // and let it exit. loc_eng_ni_data_p->session.respRecvd = TRUE; pthread_cond_signal(&loc_eng_ni_data_p->session.tCond); pthread_mutex_unlock(&loc_eng_ni_data_p->session.tLock); } EXIT_LOG(%s, VOID_RET); } /*=========================================================================== FUNCTION loc_eng_ni_init DESCRIPTION This function initializes the NI interface DEPENDENCIES NONE RETURN VALUE None SIDE EFFECTS N/A ===========================================================================*/ void loc_eng_ni_init(loc_eng_data_s_type &loc_eng_data, GpsNiExtCallbacks *callbacks) { ENTRY_LOG_CALLFLOW(); if(callbacks == NULL) EXIT_LOG(%s, "loc_eng_ni_init: failed, cb is NULL"); else if (NULL == callbacks->notify_cb) { EXIT_LOG(%s, "loc_eng_ni_init: failed, no cb."); } else if (NULL != loc_eng_data.ni_notify_cb) { EXIT_LOG(%s, "loc_eng_ni_init: already inited."); } else { loc_eng_ni_data_s_type* loc_eng_ni_data_p = &loc_eng_data.loc_eng_ni_data; loc_eng_ni_data_p->sessionEs.respTimeLeft = 0; loc_eng_ni_data_p->sessionEs.respRecvd = FALSE; loc_eng_ni_data_p->sessionEs.rawRequest = NULL; loc_eng_ni_data_p->sessionEs.reqID = 0; pthread_cond_init(&loc_eng_ni_data_p->sessionEs.tCond, NULL); pthread_mutex_init(&loc_eng_ni_data_p->sessionEs.tLock, NULL); loc_eng_ni_data_p->session.respTimeLeft = 0; loc_eng_ni_data_p->session.respRecvd = FALSE; loc_eng_ni_data_p->session.rawRequest = NULL; loc_eng_ni_data_p->session.reqID = 0; pthread_cond_init(&loc_eng_ni_data_p->session.tCond, NULL); pthread_mutex_init(&loc_eng_ni_data_p->session.tLock, NULL); loc_eng_data.ni_notify_cb = callbacks->notify_cb; EXIT_LOG(%s, VOID_RET); } } /*=========================================================================== FUNCTION loc_eng_ni_respond DESCRIPTION This function receives user response from upper layer framework DEPENDENCIES NONE RETURN VALUE None SIDE EFFECTS N/A ===========================================================================*/ void loc_eng_ni_respond(loc_eng_data_s_type &loc_eng_data, int notif_id, GpsUserResponseType user_response) { ENTRY_LOG_CALLFLOW(); loc_eng_ni_data_s_type* loc_eng_ni_data_p = &loc_eng_data.loc_eng_ni_data; loc_eng_ni_session_s_type* pSession = NULL; if (NULL == loc_eng_data.ni_notify_cb) { EXIT_LOG(%s, "loc_eng_ni_init hasn't happened yet."); return; } if (notif_id == loc_eng_ni_data_p->sessionEs.reqID && NULL != loc_eng_ni_data_p->sessionEs.rawRequest) { pSession = &loc_eng_ni_data_p->sessionEs; // ignore any SUPL NI non-Es session if a SUPL NI ES is accepted if (user_response == GPS_NI_RESPONSE_ACCEPT && NULL != loc_eng_ni_data_p->session.rawRequest) { pthread_mutex_lock(&loc_eng_ni_data_p->session.tLock); loc_eng_ni_data_p->session.resp = GPS_NI_RESPONSE_IGNORE; loc_eng_ni_data_p->session.respRecvd = TRUE; pthread_cond_signal(&loc_eng_ni_data_p->session.tCond); pthread_mutex_unlock(&loc_eng_ni_data_p->session.tLock); } } else if (notif_id == loc_eng_ni_data_p->session.reqID && NULL != loc_eng_ni_data_p->session.rawRequest) { pSession = &loc_eng_ni_data_p->session; } if (pSession) { LOC_LOGI("loc_eng_ni_respond: send user response %d for notif %d", user_response, notif_id); pthread_mutex_lock(&pSession->tLock); pSession->resp = user_response; pSession->respRecvd = TRUE; pthread_cond_signal(&pSession->tCond); pthread_mutex_unlock(&pSession->tLock); } else { LOC_LOGE("loc_eng_ni_respond: notif_id %d not an active session", notif_id); } EXIT_LOG(%s, VOID_RET); } ================================================ FILE: gps/loc_api/libloc_api_50001/loc_eng_ni.h ================================================ /* Copyright (c) 2009,2011,2014 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef LOC_ENG_NI_H #define LOC_ENG_NI_H #include #include #define LOC_NI_NO_RESPONSE_TIME 20 /* secs */ #define LOC_NI_NOTIF_KEY_ADDRESS "Address" #define GPS_NI_RESPONSE_IGNORE 4 typedef struct { pthread_t thread; /* NI thread */ int respTimeLeft; /* examine time for NI response */ bool respRecvd; /* NI User reponse received or not from Java layer*/ void* rawRequest; int reqID; /* ID to check against response */ GpsUserResponseType resp; pthread_cond_t tCond; pthread_mutex_t tLock; LocEngAdapter* adapter; } loc_eng_ni_session_s_type; typedef struct { loc_eng_ni_session_s_type session; /* SUPL NI Session */ loc_eng_ni_session_s_type sessionEs; /* Emergency SUPL NI Session */ int reqIDCounter; } loc_eng_ni_data_s_type; #endif /* LOC_ENG_NI_H */ ================================================ FILE: gps/loc_api/libloc_api_50001/loc_eng_nmea.cpp ================================================ /* Copyright (c) 2012, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #define LOG_NDDEBUG 0 #define LOG_TAG "LocSvc_eng_nmea" #define GPS_PRN_START 1 #define GPS_PRN_END 32 #define GLONASS_PRN_START 65 #define GLONASS_PRN_END 96 #include #include #include #include "log_util.h" /*=========================================================================== FUNCTION loc_eng_nmea_send DESCRIPTION send out NMEA sentence DEPENDENCIES NONE RETURN VALUE Total length of the nmea sentence SIDE EFFECTS N/A ===========================================================================*/ void loc_eng_nmea_send(char *pNmea, int length, loc_eng_data_s_type *loc_eng_data_p) { struct timeval tv; gettimeofday(&tv, (struct timezone *) NULL); int64_t now = tv.tv_sec * 1000LL + tv.tv_usec / 1000; CALLBACK_LOG_CALLFLOW("nmea_cb", %p, pNmea); if (loc_eng_data_p->nmea_cb != NULL) loc_eng_data_p->nmea_cb(now, pNmea, length); LOC_LOGD("NMEA <%s", pNmea); } /*=========================================================================== FUNCTION loc_eng_nmea_put_checksum DESCRIPTION Generate NMEA sentences generated based on position report DEPENDENCIES NONE RETURN VALUE Total length of the nmea sentence SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_nmea_put_checksum(char *pNmea, int maxSize) { uint8_t checksum = 0; int length = 0; pNmea++; //skip the $ while (*pNmea != '\0') { checksum ^= *pNmea++; length++; } int checksumLength = snprintf(pNmea,(maxSize-length-1),"*%02X\r\n", checksum); return (length + checksumLength); } /*=========================================================================== FUNCTION loc_eng_nmea_generate_pos DESCRIPTION Generate NMEA sentences generated based on position report DEPENDENCIES NONE RETURN VALUE 0 SIDE EFFECTS N/A ===========================================================================*/ void loc_eng_nmea_generate_pos(loc_eng_data_s_type *loc_eng_data_p, const UlpLocation &location, const GpsLocationExtended &locationExtended, unsigned char generate_nmea) { ENTRY_LOG(); time_t utcTime(location.gpsLocation.timestamp/1000); tm * pTm = gmtime(&utcTime); if (NULL == pTm) { LOC_LOGE("gmtime failed"); return; } char sentence[NMEA_SENTENCE_MAX_LENGTH] = {0}; char* pMarker = sentence; int lengthRemaining = sizeof(sentence); int length = 0; int utcYear = pTm->tm_year % 100; // 2 digit year int utcMonth = pTm->tm_mon + 1; // tm_mon starts at zero int utcDay = pTm->tm_mday; int utcHours = pTm->tm_hour; int utcMinutes = pTm->tm_min; int utcSeconds = pTm->tm_sec; if (generate_nmea) { // ------------------ // ------$GPGSA------ // ------------------ uint32_t svUsedCount = 0; uint32_t svUsedList[32] = {0}; uint32_t mask = loc_eng_data_p->sv_used_mask; for (uint8_t i = 1; mask > 0 && svUsedCount < 32; i++) { if (mask & 1) svUsedList[svUsedCount++] = i; mask = mask >> 1; } // clear the cache so they can't be used again loc_eng_data_p->sv_used_mask = 0; char fixType; if (svUsedCount == 0) fixType = '1'; // no fix else if (svUsedCount <= 3) fixType = '2'; // 2D fix else fixType = '3'; // 3D fix length = snprintf(pMarker, lengthRemaining, "$GPGSA,A,%c,", fixType); if (length < 0 || length >= lengthRemaining) { LOC_LOGE("NMEA Error in string formatting"); return; } pMarker += length; lengthRemaining -= length; for (uint8_t i = 0; i < 12; i++) // only the first 12 sv go in sentence { if (i < svUsedCount) length = snprintf(pMarker, lengthRemaining, "%02d,", svUsedList[i]); else length = snprintf(pMarker, lengthRemaining, ","); if (length < 0 || length >= lengthRemaining) { LOC_LOGE("NMEA Error in string formatting"); return; } pMarker += length; lengthRemaining -= length; } if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_DOP) { // dop is in locationExtended, (QMI) length = snprintf(pMarker, lengthRemaining, "%.1f,%.1f,%.1f", locationExtended.pdop, locationExtended.hdop, locationExtended.vdop); } else if (loc_eng_data_p->pdop > 0 && loc_eng_data_p->hdop > 0 && loc_eng_data_p->vdop > 0) { // dop was cached from sv report (RPC) length = snprintf(pMarker, lengthRemaining, "%.1f,%.1f,%.1f", loc_eng_data_p->pdop, loc_eng_data_p->hdop, loc_eng_data_p->vdop); } else { // no dop length = snprintf(pMarker, lengthRemaining, ",,"); } length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence)); loc_eng_nmea_send(sentence, length, loc_eng_data_p); // ------------------ // ------$GPVTG------ // ------------------ pMarker = sentence; lengthRemaining = sizeof(sentence); if (location.gpsLocation.flags & GPS_LOCATION_HAS_BEARING) { float magTrack = location.gpsLocation.bearing; if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_MAG_DEV) { float magTrack = location.gpsLocation.bearing - locationExtended.magneticDeviation; if (magTrack < 0.0) magTrack += 360.0; else if (magTrack > 360.0) magTrack -= 360.0; } length = snprintf(pMarker, lengthRemaining, "$GPVTG,%.1lf,T,%.1lf,M,", location.gpsLocation.bearing, magTrack); } else { length = snprintf(pMarker, lengthRemaining, "$GPVTG,,T,,M,"); } if (length < 0 || length >= lengthRemaining) { LOC_LOGE("NMEA Error in string formatting"); return; } pMarker += length; lengthRemaining -= length; if (location.gpsLocation.flags & GPS_LOCATION_HAS_SPEED) { float speedKnots = location.gpsLocation.speed * (3600.0/1852.0); float speedKmPerHour = location.gpsLocation.speed * 3.6; length = snprintf(pMarker, lengthRemaining, "%.1lf,N,%.1lf,K,", speedKnots, speedKmPerHour); } else { length = snprintf(pMarker, lengthRemaining, ",N,,K,"); } if (length < 0 || length >= lengthRemaining) { LOC_LOGE("NMEA Error in string formatting"); return; } pMarker += length; lengthRemaining -= length; if (!(location.gpsLocation.flags & GPS_LOCATION_HAS_LAT_LONG)) length = snprintf(pMarker, lengthRemaining, "%c", 'N'); // N means no fix else if (LOC_POSITION_MODE_STANDALONE == loc_eng_data_p->adapter->getPositionMode().mode) length = snprintf(pMarker, lengthRemaining, "%c", 'A'); // A means autonomous else length = snprintf(pMarker, lengthRemaining, "%c", 'D'); // D means differential length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence)); loc_eng_nmea_send(sentence, length, loc_eng_data_p); // ------------------ // ------$GPRMC------ // ------------------ pMarker = sentence; lengthRemaining = sizeof(sentence); length = snprintf(pMarker, lengthRemaining, "$GPRMC,%02d%02d%02d,A," , utcHours, utcMinutes, utcSeconds); if (length < 0 || length >= lengthRemaining) { LOC_LOGE("NMEA Error in string formatting"); return; } pMarker += length; lengthRemaining -= length; if (location.gpsLocation.flags & GPS_LOCATION_HAS_LAT_LONG) { double latitude = location.gpsLocation.latitude; double longitude = location.gpsLocation.longitude; char latHemisphere; char lonHemisphere; double latMinutes; double lonMinutes; if (latitude > 0) { latHemisphere = 'N'; } else { latHemisphere = 'S'; latitude *= -1.0; } if (longitude < 0) { lonHemisphere = 'W'; longitude *= -1.0; } else { lonHemisphere = 'E'; } latMinutes = fmod(latitude * 60.0 , 60.0); lonMinutes = fmod(longitude * 60.0 , 60.0); length = snprintf(pMarker, lengthRemaining, "%02d%09.6lf,%c,%03d%09.6lf,%c,", (uint8_t)floor(latitude), latMinutes, latHemisphere, (uint8_t)floor(longitude),lonMinutes, lonHemisphere); } else { length = snprintf(pMarker, lengthRemaining,",,,,"); } if (length < 0 || length >= lengthRemaining) { LOC_LOGE("NMEA Error in string formatting"); return; } pMarker += length; lengthRemaining -= length; if (location.gpsLocation.flags & GPS_LOCATION_HAS_SPEED) { float speedKnots = location.gpsLocation.speed * (3600.0/1852.0); length = snprintf(pMarker, lengthRemaining, "%.1lf,", speedKnots); } else { length = snprintf(pMarker, lengthRemaining, ","); } if (length < 0 || length >= lengthRemaining) { LOC_LOGE("NMEA Error in string formatting"); return; } pMarker += length; lengthRemaining -= length; if (location.gpsLocation.flags & GPS_LOCATION_HAS_BEARING) { length = snprintf(pMarker, lengthRemaining, "%.1lf,", location.gpsLocation.bearing); } else { length = snprintf(pMarker, lengthRemaining, ","); } if (length < 0 || length >= lengthRemaining) { LOC_LOGE("NMEA Error in string formatting"); return; } pMarker += length; lengthRemaining -= length; length = snprintf(pMarker, lengthRemaining, "%2.2d%2.2d%2.2d,", utcDay, utcMonth, utcYear); if (length < 0 || length >= lengthRemaining) { LOC_LOGE("NMEA Error in string formatting"); return; } pMarker += length; lengthRemaining -= length; if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_MAG_DEV) { float magneticVariation = locationExtended.magneticDeviation; char direction; if (magneticVariation < 0.0) { direction = 'W'; magneticVariation *= -1.0; } else { direction = 'E'; } length = snprintf(pMarker, lengthRemaining, "%.1lf,%c,", magneticVariation, direction); } else { length = snprintf(pMarker, lengthRemaining, ",,"); } if (length < 0 || length >= lengthRemaining) { LOC_LOGE("NMEA Error in string formatting"); return; } pMarker += length; lengthRemaining -= length; if (!(location.gpsLocation.flags & GPS_LOCATION_HAS_LAT_LONG)) length = snprintf(pMarker, lengthRemaining, "%c", 'N'); // N means no fix else if (LOC_POSITION_MODE_STANDALONE == loc_eng_data_p->adapter->getPositionMode().mode) length = snprintf(pMarker, lengthRemaining, "%c", 'A'); // A means autonomous else length = snprintf(pMarker, lengthRemaining, "%c", 'D'); // D means differential length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence)); loc_eng_nmea_send(sentence, length, loc_eng_data_p); // ------------------ // ------$GPGGA------ // ------------------ pMarker = sentence; lengthRemaining = sizeof(sentence); length = snprintf(pMarker, lengthRemaining, "$GPGGA,%02d%02d%02d," , utcHours, utcMinutes, utcSeconds); if (length < 0 || length >= lengthRemaining) { LOC_LOGE("NMEA Error in string formatting"); return; } pMarker += length; lengthRemaining -= length; if (location.gpsLocation.flags & GPS_LOCATION_HAS_LAT_LONG) { double latitude = location.gpsLocation.latitude; double longitude = location.gpsLocation.longitude; char latHemisphere; char lonHemisphere; double latMinutes; double lonMinutes; if (latitude > 0) { latHemisphere = 'N'; } else { latHemisphere = 'S'; latitude *= -1.0; } if (longitude < 0) { lonHemisphere = 'W'; longitude *= -1.0; } else { lonHemisphere = 'E'; } latMinutes = fmod(latitude * 60.0 , 60.0); lonMinutes = fmod(longitude * 60.0 , 60.0); length = snprintf(pMarker, lengthRemaining, "%02d%09.6lf,%c,%03d%09.6lf,%c,", (uint8_t)floor(latitude), latMinutes, latHemisphere, (uint8_t)floor(longitude),lonMinutes, lonHemisphere); } else { length = snprintf(pMarker, lengthRemaining,",,,,"); } if (length < 0 || length >= lengthRemaining) { LOC_LOGE("NMEA Error in string formatting"); return; } pMarker += length; lengthRemaining -= length; char gpsQuality; if (!(location.gpsLocation.flags & GPS_LOCATION_HAS_LAT_LONG)) gpsQuality = '0'; // 0 means no fix else if (LOC_POSITION_MODE_STANDALONE == loc_eng_data_p->adapter->getPositionMode().mode) gpsQuality = '1'; // 1 means GPS fix else gpsQuality = '2'; // 2 means DGPS fix if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_DOP) { // dop is in locationExtended, (QMI) length = snprintf(pMarker, lengthRemaining, "%c,%02d,%.1f,", gpsQuality, svUsedCount, locationExtended.hdop); } else if (loc_eng_data_p->pdop > 0 && loc_eng_data_p->hdop > 0 && loc_eng_data_p->vdop > 0) { // dop was cached from sv report (RPC) length = snprintf(pMarker, lengthRemaining, "%c,%02d,%.1f,", gpsQuality, svUsedCount, loc_eng_data_p->hdop); } else { // no hdop length = snprintf(pMarker, lengthRemaining, "%c,%02d,,", gpsQuality, svUsedCount); } if (length < 0 || length >= lengthRemaining) { LOC_LOGE("NMEA Error in string formatting"); return; } pMarker += length; lengthRemaining -= length; if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL) { length = snprintf(pMarker, lengthRemaining, "%.1lf,M,", locationExtended.altitudeMeanSeaLevel); } else { length = snprintf(pMarker, lengthRemaining,",,"); } if (length < 0 || length >= lengthRemaining) { LOC_LOGE("NMEA Error in string formatting"); return; } pMarker += length; lengthRemaining -= length; if ((location.gpsLocation.flags & GPS_LOCATION_HAS_ALTITUDE) && (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL)) { length = snprintf(pMarker, lengthRemaining, "%.1lf,M,,", location.gpsLocation.altitude - locationExtended.altitudeMeanSeaLevel); } else { length = snprintf(pMarker, lengthRemaining,",,,"); } length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence)); loc_eng_nmea_send(sentence, length, loc_eng_data_p); } //Send blank NMEA reports for non-final fixes else { strlcpy(sentence, "$GPGSA,A,1,,,,,,,,,,,,,,,", sizeof(sentence)); length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence)); loc_eng_nmea_send(sentence, length, loc_eng_data_p); strlcpy(sentence, "$GPVTG,,T,,M,,N,,K,N", sizeof(sentence)); length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence)); loc_eng_nmea_send(sentence, length, loc_eng_data_p); strlcpy(sentence, "$GPRMC,,V,,,,,,,,,,N", sizeof(sentence)); length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence)); loc_eng_nmea_send(sentence, length, loc_eng_data_p); strlcpy(sentence, "$GPGGA,,,,,,0,,,,,,,,", sizeof(sentence)); length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence)); loc_eng_nmea_send(sentence, length, loc_eng_data_p); } // clear the dop cache so they can't be used again loc_eng_data_p->pdop = 0; loc_eng_data_p->hdop = 0; loc_eng_data_p->vdop = 0; EXIT_LOG(%d, 0); } /*=========================================================================== FUNCTION loc_eng_nmea_generate_sv DESCRIPTION Generate NMEA sentences generated based on sv report DEPENDENCIES NONE RETURN VALUE 0 SIDE EFFECTS N/A ===========================================================================*/ void loc_eng_nmea_generate_sv(loc_eng_data_s_type *loc_eng_data_p, const QcomSvStatus &svStatus, const GpsLocationExtended &locationExtended) { ENTRY_LOG(); char sentence[NMEA_SENTENCE_MAX_LENGTH] = {0}; char* pMarker = sentence; int lengthRemaining = sizeof(sentence); int length = 0; int svCount = svStatus.num_svs; int sentenceCount = 0; int sentenceNumber = 1; int svNumber = 1; int gpsCount = 0; int glnCount = 0; //Count GPS SVs for saparating GPS from GLONASS and throw others for(svNumber=1; svNumber <= svCount; svNumber++) { if( (svStatus.sv_list[svNumber-1].prn >= GPS_PRN_START)&& (svStatus.sv_list[svNumber-1].prn <= GPS_PRN_END) ) { gpsCount++; } else if( (svStatus.sv_list[svNumber-1].prn >= GLONASS_PRN_START) && (svStatus.sv_list[svNumber-1].prn <= GLONASS_PRN_END) ) { glnCount++; } } // ------------------ // ------$GPGSV------ // ------------------ if (gpsCount <= 0) { // no svs in view, so just send a blank $GPGSV sentence strlcpy(sentence, "$GPGSV,1,1,0,", sizeof(sentence)); length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence)); loc_eng_nmea_send(sentence, length, loc_eng_data_p); } else { svNumber = 1; sentenceNumber = 1; sentenceCount = gpsCount/4 + (gpsCount % 4 != 0); while (sentenceNumber <= sentenceCount) { pMarker = sentence; lengthRemaining = sizeof(sentence); length = snprintf(pMarker, lengthRemaining, "$GPGSV,%d,%d,%02d", sentenceCount, sentenceNumber, gpsCount); if (length < 0 || length >= lengthRemaining) { LOC_LOGE("NMEA Error in string formatting"); return; } pMarker += length; lengthRemaining -= length; for (int i=0; (svNumber <= svCount) && (i < 4); svNumber++) { if( (svStatus.sv_list[svNumber-1].prn >= GPS_PRN_START) && (svStatus.sv_list[svNumber-1].prn <= GPS_PRN_END) ) { length = snprintf(pMarker, lengthRemaining,",%02d,%02d,%03d,", svStatus.sv_list[svNumber-1].prn, (int)(0.5 + svStatus.sv_list[svNumber-1].elevation), //float to int (int)(0.5 + svStatus.sv_list[svNumber-1].azimuth)); //float to int if (length < 0 || length >= lengthRemaining) { LOC_LOGE("NMEA Error in string formatting"); return; } pMarker += length; lengthRemaining -= length; if (svStatus.sv_list[svNumber-1].snr > 0) { length = snprintf(pMarker, lengthRemaining,"%02d", (int)(0.5 + svStatus.sv_list[svNumber-1].snr)); //float to int if (length < 0 || length >= lengthRemaining) { LOC_LOGE("NMEA Error in string formatting"); return; } pMarker += length; lengthRemaining -= length; } i++; } } length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence)); loc_eng_nmea_send(sentence, length, loc_eng_data_p); sentenceNumber++; } //while } //if // ------------------ // ------$GLGSV------ // ------------------ if (glnCount <= 0) { // no svs in view, so just send a blank $GLGSV sentence strlcpy(sentence, "$GLGSV,1,1,0,", sizeof(sentence)); length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence)); loc_eng_nmea_send(sentence, length, loc_eng_data_p); } else { svNumber = 1; sentenceNumber = 1; sentenceCount = glnCount/4 + (glnCount % 4 != 0); while (sentenceNumber <= sentenceCount) { pMarker = sentence; lengthRemaining = sizeof(sentence); length = snprintf(pMarker, lengthRemaining, "$GLGSV,%d,%d,%02d", sentenceCount, sentenceNumber, glnCount); if (length < 0 || length >= lengthRemaining) { LOC_LOGE("NMEA Error in string formatting"); return; } pMarker += length; lengthRemaining -= length; for (int i=0; (svNumber <= svCount) && (i < 4); svNumber++) { if( (svStatus.sv_list[svNumber-1].prn >= GLONASS_PRN_START) && (svStatus.sv_list[svNumber-1].prn <= GLONASS_PRN_END) ) { length = snprintf(pMarker, lengthRemaining,",%02d,%02d,%03d,", svStatus.sv_list[svNumber-1].prn, (int)(0.5 + svStatus.sv_list[svNumber-1].elevation), //float to int (int)(0.5 + svStatus.sv_list[svNumber-1].azimuth)); //float to int if (length < 0 || length >= lengthRemaining) { LOC_LOGE("NMEA Error in string formatting"); return; } pMarker += length; lengthRemaining -= length; if (svStatus.sv_list[svNumber-1].snr > 0) { length = snprintf(pMarker, lengthRemaining,"%02d", (int)(0.5 + svStatus.sv_list[svNumber-1].snr)); //float to int if (length < 0 || length >= lengthRemaining) { LOC_LOGE("NMEA Error in string formatting"); return; } pMarker += length; lengthRemaining -= length; } i++; } } length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence)); loc_eng_nmea_send(sentence, length, loc_eng_data_p); sentenceNumber++; } //while }//if // cache the used in fix mask, as it will be needed to send $GPGSA // during the position report loc_eng_data_p->sv_used_mask = svStatus.gps_used_in_fix_mask; // For RPC, the DOP are sent during sv report, so cache them // now to be sent during position report. // For QMI, the DOP will be in position report. if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_DOP) { loc_eng_data_p->pdop = locationExtended.pdop; loc_eng_data_p->hdop = locationExtended.hdop; loc_eng_data_p->vdop = locationExtended.vdop; } else { loc_eng_data_p->pdop = 0; loc_eng_data_p->hdop = 0; loc_eng_data_p->vdop = 0; } EXIT_LOG(%d, 0); } ================================================ FILE: gps/loc_api/libloc_api_50001/loc_eng_nmea.h ================================================ /* Copyright (c) 2012, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef LOC_ENG_NMEA_H #define LOC_ENG_NMEA_H #include #include #define NMEA_SENTENCE_MAX_LENGTH 200 void loc_eng_nmea_send(char *pNmea, int length, loc_eng_data_s_type *loc_eng_data_p); int loc_eng_nmea_put_checksum(char *pNmea, int maxSize); void loc_eng_nmea_generate_sv(loc_eng_data_s_type *loc_eng_data_p, const QcomSvStatus &svStatus, const GpsLocationExtended &locationExtended); void loc_eng_nmea_generate_pos(loc_eng_data_s_type *loc_eng_data_p, const UlpLocation &location, const GpsLocationExtended &locationExtended, unsigned char generate_nmea); #endif // LOC_ENG_NMEA_H ================================================ FILE: gps/loc_api/libloc_api_50001/loc_eng_xtra.cpp ================================================ /* Copyright (c) 2009-2013, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #define LOG_NDDEBUG 0 #define LOG_TAG "LocSvc_eng" #include #include #include "log_util.h" #include "platform_lib_includes.h" using namespace loc_core; struct LocEngRequestXtraServer : public LocMsg { LocEngAdapter* mAdapter; inline LocEngRequestXtraServer(LocEngAdapter* adapter) : LocMsg(), mAdapter(adapter) { locallog(); } inline virtual void proc() const { mAdapter->requestXtraServer(); } inline void locallog() const { LOC_LOGV("LocEngRequestXtraServer"); } inline virtual void log() const { locallog(); } }; struct LocEngInjectXtraData : public LocMsg { LocEngAdapter* mAdapter; char* mData; const int mLen; inline LocEngInjectXtraData(LocEngAdapter* adapter, char* data, int len): LocMsg(), mAdapter(adapter), mData(new char[len]), mLen(len) { memcpy((void*)mData, (void*)data, len); locallog(); } inline ~LocEngInjectXtraData() { delete[] mData; } inline virtual void proc() const { mAdapter->setXtraData(mData, mLen); } inline void locallog() const { LOC_LOGV("length: %d\n data: %p", mLen, mData); } inline virtual void log() const { locallog(); } }; struct LocEngSetXtraVersionCheck : public LocMsg { LocEngAdapter *mAdapter; int mCheck; inline LocEngSetXtraVersionCheck(LocEngAdapter* adapter, int check): mAdapter(adapter), mCheck(check) {} inline virtual void proc() const { locallog(); mAdapter->setXtraVersionCheck(mCheck); } inline void locallog() const { LOC_LOGD("%s:%d]: mCheck: %d", __func__, __LINE__, mCheck); } inline virtual void log() const { locallog(); } }; /*=========================================================================== FUNCTION loc_eng_xtra_init DESCRIPTION Initialize XTRA module. DEPENDENCIES N/A RETURN VALUE 0: success SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_xtra_init (loc_eng_data_s_type &loc_eng_data, GpsXtraExtCallbacks* callbacks) { int ret_val = -1; loc_eng_xtra_data_s_type *xtra_module_data_ptr; ENTRY_LOG(); if(callbacks == NULL) { LOC_LOGE("loc_eng_xtra_init: failed, cb is NULL"); } else { xtra_module_data_ptr = &loc_eng_data.xtra_module_data; xtra_module_data_ptr->download_request_cb = callbacks->download_request_cb; xtra_module_data_ptr->report_xtra_server_cb = callbacks->report_xtra_server_cb; ret_val = 0; } EXIT_LOG(%d, ret_val); return ret_val; } /*=========================================================================== FUNCTION loc_eng_xtra_inject_data DESCRIPTION Injects XTRA file into the engine but buffers the data if engine is busy. DEPENDENCIES N/A RETURN VALUE 0 SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_xtra_inject_data(loc_eng_data_s_type &loc_eng_data, char* data, int length) { ENTRY_LOG(); LocEngAdapter* adapter = loc_eng_data.adapter; adapter->sendMsg(new LocEngInjectXtraData(adapter, data, length)); EXIT_LOG(%d, 0); return 0; } /*=========================================================================== FUNCTION loc_eng_xtra_request_server DESCRIPTION Request the Xtra server url from the modem DEPENDENCIES N/A RETURN VALUE 0 SIDE EFFECTS N/A ===========================================================================*/ int loc_eng_xtra_request_server(loc_eng_data_s_type &loc_eng_data) { ENTRY_LOG(); LocEngAdapter* adapter = loc_eng_data.adapter; adapter->sendMsg(new LocEngRequestXtraServer(adapter)); EXIT_LOG(%d, 0); return 0; } /*=========================================================================== FUNCTION loc_eng_xtra_version_check DESCRIPTION Injects the enable/disable value for checking XTRA version that is specified in gps.conf DEPENDENCIES N/A RETURN VALUE none SIDE EFFECTS N/A ===========================================================================*/ void loc_eng_xtra_version_check(loc_eng_data_s_type &loc_eng_data, int check) { ENTRY_LOG(); LocEngAdapter *adapter = loc_eng_data.adapter; adapter->sendMsg(new LocEngSetXtraVersionCheck(adapter, check)); EXIT_LOG(%d, 0); } ================================================ FILE: gps/loc_api/libloc_api_50001/loc_eng_xtra.h ================================================ /* Copyright (c) 2009,2011 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef LOC_ENG_XTRA_H #define LOC_ENG_XTRA_H #include // Module data typedef struct { // loc_eng_ioctl_cb_data_s_type ioctl_cb_data; gps_xtra_download_request download_request_cb; report_xtra_server report_xtra_server_cb; // XTRA data buffer char *xtra_data_for_injection; // NULL if no pending data int xtra_data_len; } loc_eng_xtra_data_s_type; #endif // LOC_ENG_XTRA_H ================================================ FILE: gps/utils/Android.mk ================================================ ifneq ($(BUILD_TINY_ANDROID),true) #Compile this library only for builds with the latest modem image LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) ## Libs LOCAL_SHARED_LIBRARIES := \ libutils \ libcutils \ liblog LOCAL_SRC_FILES += \ loc_log.cpp \ loc_cfg.cpp \ msg_q.c \ linked_list.c \ loc_target.cpp \ platform_lib_abstractions/elapsed_millis_since_boot.cpp \ LocHeap.cpp \ LocTimer.cpp \ LocThread.cpp \ MsgTask.cpp \ loc_misc_utils.cpp LOCAL_CFLAGS += \ -fno-short-enums \ -D_ANDROID_ \ -std=c++11 ifeq ($(TARGET_BUILD_VARIANT),user) LOCAL_CFLAGS += -DTARGET_BUILD_VARIANT_USER endif LOCAL_LDFLAGS += -Wl,--export-dynamic ## Includes LOCAL_C_INCLUDES:= \ $(LOCAL_PATH)/platform_lib_abstractions LOCAL_COPY_HEADERS_TO:= gps.utils/ LOCAL_COPY_HEADERS:= \ loc_log.h \ loc_cfg.h \ log_util.h \ linked_list.h \ msg_q.h \ MsgTask.h \ LocHeap.h \ LocThread.h \ LocTimer.h \ loc_target.h \ loc_timer.h \ LocSharedLock.h \ platform_lib_abstractions/platform_lib_includes.h \ platform_lib_abstractions/platform_lib_time.h \ platform_lib_abstractions/platform_lib_macros.h \ loc_misc_utils.h LOCAL_MODULE := libgps.utils LOCAL_CLANG := false LOCAL_MODULE_TAGS := optional LOCAL_PRELINK_MODULE := false include $(BUILD_SHARED_LIBRARY) endif # not BUILD_TINY_ANDROID ================================================ FILE: gps/utils/LocHeap.cpp ================================================ /* Copyright (c) 2015, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include class LocHeapNode { friend class LocHeap; // size of of the subtree, excluding self, 1 if no subtree int mSize; LocHeapNode* mLeft; LocHeapNode* mRight; LocRankable* mData; public: inline LocHeapNode(LocRankable& data) : mSize(1), mLeft(NULL), mRight(NULL), mData(&data) {} ~LocHeapNode(); // this only swaps the data of the two nodes, so no // detach / re-attached is necessary void swap(LocHeapNode& node); LocRankable* detachData(); // push a node into the tree stucture, keeping sorted by rank void push(LocHeapNode& node); // pop the head node out of the tree stucture. keeping sorted by rank static LocHeapNode* pop(LocHeapNode*& top); // remove a specific node from the tree // returns the pointer to the node removed, which would be either the // same as input (if successfully removed); or NULL (if failed). static LocHeapNode* remove(LocHeapNode*& top, LocRankable& data); // convenience method to compare data ranking inline bool outRanks(LocHeapNode& node) { return mData->outRanks(*node.mData); } inline bool outRanks(LocRankable& data) { return mData->outRanks(data); } // checks if mSize is correct, AND this node is the highest ranking // of the entire subtree bool checkNodes(); inline int getSize() { return mSize; } }; inline LocHeapNode::~LocHeapNode() { if (mLeft) { delete mLeft; mLeft = NULL; } if (mRight) { delete mRight; mRight = NULL; } if (mData) { mData = NULL; } } inline void LocHeapNode::swap(LocHeapNode& node) { LocRankable* tmpData = node.mData; node.mData = mData; mData = tmpData; } inline LocRankable* LocHeapNode::detachData() { LocRankable* data = mData; mData = NULL; return data; } // push keeps the tree sorted by rank, it also tries to balance the // tree by adding the new node to the smaller of the subtrees. // The pointer to the tree and internal links never change. If the // mData of tree top ranks lower than that of the incoming node, // mData will be swapped with that of the incoming node to ensure // ranking, no restructuring the container nodes. void LocHeapNode::push(LocHeapNode& node) { // ensure the current node ranks higher than in the incoming one if (node.outRanks(*this)) { swap(node); } // now drop the new node (ensured lower than *this) into a subtree if (NULL == mLeft) { mLeft = &node; } else if (NULL == mRight) { mRight = &node; } else if (mLeft->mSize <= mRight->mSize) { mLeft->push(node); } else { mRight->push(node); } mSize++; } // pop keeps the tree sorted by rank, but it does not try to balance // the tree. It recursively swaps with the higher ranked top of the // subtrees. // The return is a popped out node from leaf level, that has the data // swapped all the way down from the top. The pinter to the tree and // internal links will not be changed or restructured, except for the // node that is popped out. // If the return pointer == this, this the last node in the tree. LocHeapNode* LocHeapNode::pop(LocHeapNode*& top) { // we know the top has the highest ranking at this point, else // the tree is broken. This top will be popped out. But we need // a node from the left or right child, whichever ranks higher, // to replace the current top. This then will need to be done // recursively to the leaf level. So we swap the mData of the // current top node all the way down to the leaf level. LocHeapNode* poppedNode = top; // top is losing a node in its subtree top->mSize--; if (top->mLeft || top->mRight) { // if mLeft is NULL, mRight for sure is NOT NULL, take that; // else if mRight is NULL, mLeft for sure is NOT, take that; // else we take the address of whatever has higher ranking mData LocHeapNode*& subTop = (NULL == top->mLeft) ? top->mRight : ((NULL == top->mRight) ? top->mLeft : (top->mLeft->outRanks(*(top->mRight)) ? top->mLeft : top->mRight)); // swap mData, the tree top gets updated with the new data. top->swap(*subTop); // pop out from the subtree poppedNode = pop(subTop); } else { // if the top has only single node // detach the poppedNode from the tree // subTop is the reference of ether mLeft or mRight // NOT a local stack pointer. so it MUST be NULL'ed here. top = NULL; } return poppedNode; } // navigating through the tree and find the node that hass the input // data. Since this is a heap, we do recursive linear search. // returns the pointer to the node removed, which would be either the // same as input (if successfully removed); or NULL (if failed). LocHeapNode* LocHeapNode::remove(LocHeapNode*& top, LocRankable& data) { LocHeapNode* removedNode = NULL; // this is the node, by address if (&data == (LocRankable*)(top->mData)) { // pop this node out removedNode = pop(top); } else if (!data.outRanks(*top->mData)) { // subtrees might have this node if (top->mLeft) { removedNode = remove(top->mLeft, data); } // if we did not find in mLeft, and mRight is not empty if (!removedNode && top->mRight) { removedNode = remove(top->mRight, data); } // top lost a node in its subtree if (removedNode) { top->mSize--; } } return removedNode; } // checks if mSize is correct, AND this node is the highest ranking // of the entire subtree bool LocHeapNode::checkNodes() { // size of the current subtree int totalSize = mSize; if (mLeft) { // check the consistency of left subtree if (mLeft->outRanks(*this) || !mLeft->checkNodes()) { return false; } // subtract the size of left subtree (with subtree head) totalSize -= mLeft->mSize; } if (mRight) { // check the consistency of right subtree if (mRight->outRanks(*this) || !mRight->checkNodes()) { return false; } // subtract the size of right subtree (with subtree head) totalSize -= mRight->mSize; } // for the tree nodes to consistent, totalSize must be 1 now return totalSize == 1; } LocHeap::~LocHeap() { if (mTree) { delete mTree; } } void LocHeap::push(LocRankable& node) { LocHeapNode* heapNode = new LocHeapNode(node); if (!mTree) { mTree = heapNode; } else { mTree->push(*heapNode); } } LocRankable* LocHeap::peek() { LocRankable* top = NULL; if (mTree) { top = mTree->mData; } return top; } LocRankable* LocHeap::pop() { LocRankable* locNode = NULL; if (mTree) { // mTree may become NULL after this call LocHeapNode* heapNode = LocHeapNode::pop(mTree); locNode = heapNode->detachData(); delete heapNode; } return locNode; } LocRankable* LocHeap::remove(LocRankable& rankable) { LocRankable* locNode = NULL; if (mTree) { // mTree may become NULL after this call LocHeapNode* heapNode = LocHeapNode::remove(mTree, rankable); if (heapNode) { locNode = heapNode->detachData(); delete heapNode; } } return locNode; } #ifdef __LOC_UNIT_TEST__ bool LocHeap::checkTree() { return ((NULL == mTree) || mTree->checkNodes()); } uint32_t LocHeap::getTreeSize() { return (NULL == mTree) ? 0 : mTree->getSize(); } #endif #ifdef __LOC_DEBUG__ #include #include #include class LocHeapDebug : public LocHeap { public: bool checkTree() { return ((NULL == mTree) || mTree->checkNodes()); } uint32_t getTreeSize() { return (NULL == mTree) ? 0 : (mTree->getSize()); } }; class LocHeapDebugData : public LocRankable { const int mID; public: LocHeapDebugData(int id) : mID(id) {} inline virtual int ranks(LocRankable& rankable) { LocHeapDebugData* testData = dynamic_cast(&rankable); return testData->mID - mID; } }; // For Linux command line testing: // compilation: g++ -D__LOC_HOST_DEBUG__ -D__LOC_DEBUG__ -g -I. -I../../../../vendor/qcom/proprietary/gps-internal/unit-tests/fakes_for_host -I../../../../system/core/include LocHeap.cpp // test: valgrind --leak-check=full ./a.out 100 int main(int argc, char** argv) { srand(time(NULL)); int tries = atoi(argv[1]); int checks = tries >> 3; LocHeapDebug heap; int treeSize = 0; for (int i = 0; i < tries; i++) { if (i % checks == 0 && !heap.checkTree()) { printf("tree check failed before %dth op\n", i); } int r = rand(); if (r & 1) { LocHeapDebugData* data = new LocHeapDebugData(r >> 1); heap.push(dynamic_cast(*data)); treeSize++; } else { LocRankable* rankable = heap.pop(); if (rankable) { delete rankable; } treeSize ? treeSize-- : 0; } printf("%s: %d == %d\n", (r&1)?"push":"pop", treeSize, heap.getTreeSize()); if (treeSize != heap.getTreeSize()) { printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); tries = i+1; break; } } if (!heap.checkTree()) { printf("!!!!!!!!!!tree check failed at the end after %d ops!!!!!!!\n", tries); } else { printf("success!\n"); } for (LocRankable* data = heap.pop(); NULL != data; data = heap.pop()) { delete data; } return 0; } #endif ================================================ FILE: gps/utils/LocHeap.h ================================================ /* Copyright (c) 2015, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef __LOC_HEAP__ #define __LOC_HEAP__ #include #include // abstract class to be implemented by client to provide a rankable class class LocRankable { public: virtual inline ~LocRankable() {} // method to rank objects of such type for sorting purposes. // The pointer of the input node would be stored in the heap. // >0 if ranks higher than the input; // ==0 if equally ranks with the input; // <0 if ranks lower than the input virtual int ranks(LocRankable& rankable) = 0; // convenient method to rank objects of such type for sorting purposes. inline bool outRanks(LocRankable& rankable) { return ranks(rankable) > 0; } }; // opaque class to provide service implementation. class LocHeapNode; // a heap whose left and right children are not sorted. It is sorted only vertically, // i.e. parent always ranks higher than children, if they exist. Ranking algorithm is // implemented in Rankable. The reason that there is no sort between children is to // help beter balance the tree with lower cost. When a node is pushed to the tree, // it is guaranteed that the subtree that is smaller gets to have the new node. class LocHeap { protected: LocHeapNode* mTree; public: inline LocHeap() : mTree(NULL) {} ~LocHeap(); // push keeps the tree sorted by rank, it also tries to balance the // tree by adding the new node to the smaller of the subtrees. // node is reference to an obj that is managed by client, that client // creates and destroyes. The destroy should happen after the // node is popped out from the heap. void push(LocRankable& node); // Peeks the node data on tree top, which has currently the highest ranking // There is no change the tree structure with this operation // Returns NULL if the tree is empty, otherwise pointer to the node data of // the tree top. LocRankable* peek(); // pop keeps the tree sorted by rank, but it does not try to balance // the tree. // Return - pointer to the node popped out, or NULL if heap is already empty LocRankable* pop(); // navigating through the tree and find the node that ranks the same // as the input data, then remove it from the tree. Rank is implemented // by rankable obj. // returns the pointer to the node removed; or NULL (if failed). LocRankable* remove(LocRankable& rankable); #ifdef __LOC_UNIT_TEST__ bool checkTree(); uint32_t getTreeSize(); #endif }; #endif //__LOC_HEAP__ ================================================ FILE: gps/utils/LocSharedLock.h ================================================ /* Copyright (c) 2015, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef __LOC_SHARED_LOCK__ #define __LOC_SHARED_LOCK__ #include #include // This is a utility created for use cases such that there are more than // one client who need to share the same lock, but it is not predictable // which of these clients is to last to go away. This shared lock deletes // itself when the last client calls its drop() method. To add a cient, // this share lock's share() method has to be called, so that the obj // can maintain an accurate client count. class LocSharedLock { uint32_t mRef; pthread_mutex_t mMutex; inline ~LocSharedLock() { pthread_mutex_destroy(&mMutex); } public: // first client to create this LockSharedLock inline LocSharedLock() : mRef(1) { pthread_mutex_init(&mMutex, NULL); } // following client(s) are to *share()* this lock created by the first client inline LocSharedLock* share() { mRef++; return this; } // whe a client no longer needs this shared lock, drop() shall be called. inline void drop() { if (0 == --mRef) delete this; } // locking the lock to enter critical section inline void lock() { pthread_mutex_lock(&mMutex); } // unlocking the lock to leave the critical section inline void unlock() { pthread_mutex_unlock(&mMutex); } }; #endif //__LOC_SHARED_LOCK__ ================================================ FILE: gps/utils/LocThread.cpp ================================================ /* Copyright (c) 2015, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include class LocThreadDelegate { LocRunnable* mRunnable; bool mJoinable; pthread_t mThandle; pthread_mutex_t mMutex; int mRefCount; ~LocThreadDelegate(); LocThreadDelegate(LocThread::tCreate creator, const char* threadName, LocRunnable* runnable, bool joinable); void destroy(); public: static LocThreadDelegate* create(LocThread::tCreate creator, const char* threadName, LocRunnable* runnable, bool joinable); void stop(); // bye() is for the parent thread to go away. if joinable, // parent must stop the spawned thread, join, and then // destroy(); if detached, the parent can go straight // ahead to destroy() inline void bye() { mJoinable ? stop() : destroy(); } inline bool isRunning() { return (NULL != mRunnable); } static void* threadMain(void* arg); }; // it is important to note that internal members must be // initialized to values as if pthread_create succeeds. // This is to avoid the race condition between the threads, // once the thread is created, some of these values will // be check in the spawned thread, and must set correctly // then and there. // However, upon pthread_create failure, the data members // must be set to indicate failure, e.g. mRunnable, and // threashold approprietly for destroy(), e.g. mRefCount. LocThreadDelegate::LocThreadDelegate(LocThread::tCreate creator, const char* threadName, LocRunnable* runnable, bool joinable) : mRunnable(runnable), mJoinable(joinable), mThandle(NULL), mMutex(PTHREAD_MUTEX_INITIALIZER), mRefCount(2) { // set up thread name, if nothing is passed in if (!threadName) { threadName = "LocThread"; } // create the thread here, then if successful // and a name is given, we set the thread name if (creator) { mThandle = creator(threadName, threadMain, this); } else if (pthread_create(&mThandle, NULL, threadMain, this)) { // pthread_create() failed mThandle = NULL; } if (mThandle) { // set thread name char lname[16]; int len = sizeof(lname) - 1; memcpy(lname, threadName, len); lname[len] = 0; // set the thread name here pthread_setname_np(mThandle, lname); // detach, if not joinable if (!joinable) { pthread_detach(mThandle); } } else { // must set these values upon failure mRunnable = NULL; mJoinable = false; mRefCount = 1; } } inline LocThreadDelegate::~LocThreadDelegate() { // at this point nothing should need done any more } // factory method so that we could return NULL upon failure LocThreadDelegate* LocThreadDelegate::create(LocThread::tCreate creator, const char* threadName, LocRunnable* runnable, bool joinable) { LocThreadDelegate* thread = NULL; if (runnable) { thread = new LocThreadDelegate(creator, threadName, runnable, joinable); if (thread && !thread->isRunning()) { thread->destroy(); thread = NULL; } } return thread; } // The order is importang // NULLing mRunnalbe stops the while loop in threadMain() // join() if mJoinble must come before destroy() call, as // the obj must remain alive at this time so that mThandle // remains valud. void LocThreadDelegate::stop() { // mRunnable and mJoinable are reset on different triggers. // mRunnable may get nulled on the spawned thread's way out; // or here. // mJouinable (if ever been true) gets falsed when client // thread triggers stop, with either a stop() // call or the client releases thread obj handle. if (mRunnable) { mRunnable = NULL; } if (mJoinable) { mJoinable = false; pthread_join(mThandle, NULL); } // call destroy() to possibly delete the obj destroy(); } // method for clients to call to release the obj // when it is a detached thread, the client thread // and the spawned thread can both try to destroy() // asynchronously. And we delete this obj when // mRefCount becomes 0. void LocThreadDelegate::destroy() { // else case shouldn't happen, unless there is a // leaking obj. But only our code here has such // obj, so if we test our code well, else case // will never happen if (mRefCount > 0) { // we need a flag on the stack bool callDelete = false; // critical section between threads pthread_mutex_lock(&mMutex); // last destroy() call callDelete = (1 == mRefCount--); pthread_mutex_unlock(&mMutex); // upon last destroy() call we delete this obj if (callDelete) { delete this; } } } void* LocThreadDelegate::threadMain(void* arg) { LocThreadDelegate* locThread = (LocThreadDelegate*)(arg); if (locThread) { LocRunnable* runnable = locThread->mRunnable; if (runnable) { if (locThread->isRunning()) { runnable->prerun(); } while (locThread->isRunning() && runnable->run()); if (locThread->isRunning()) { runnable->postrun(); } // at this time, locThread->mRunnable may or may not be NULL // NULL it just to be safe and clean, as we want the field // in the released memory slot to be NULL. locThread->mRunnable = NULL; delete runnable; } locThread->destroy(); } return NULL; } LocThread::~LocThread() { if (mThread) { mThread->bye(); mThread = NULL; } } bool LocThread::start(tCreate creator, const char* threadName, LocRunnable* runnable, bool joinable) { bool success = false; if (!mThread) { mThread = LocThreadDelegate::create(creator, threadName, runnable, joinable); // true only if thread is created successfully success = (NULL != mThread); } return success; } void LocThread::stop() { if (mThread) { mThread->stop(); mThread = NULL; } } #ifdef __LOC_DEBUG__ #include #include #include class LocRunnableTest1 : public LocRunnable { int mID; public: LocRunnableTest1(int id) : LocRunnable(), mID(id) {} virtual bool run() { printf("LocRunnableTest1: %d\n", mID++); sleep(1); return true; } }; // on linux command line: // compile: g++ -D__LOC_HOST_DEBUG__ -D__LOC_DEBUG__ -g -std=c++0x -I. -I../../../../vendor/qcom/proprietary/gps-internal/unit-tests/fakes_for_host -I../../../../system/core/include -lpthread LocThread.cpp // test detached thread: valgrind ./a.out 0 // test joinable thread: valgrind ./a.out 1 int main(int argc, char** argv) { LocRunnableTest1 test(10); LocThread thread; thread.start("LocThreadTest", test, atoi(argv[1])); sleep(10); thread.stop(); sleep(5); return 0; } #endif ================================================ FILE: gps/utils/LocThread.h ================================================ /* Copyright (c) 2015, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef __LOC_THREAD__ #define __LOC_THREAD__ #include #include // abstract class to be implemented by client to provide a runnable class // which gets scheduled by LocThread class LocRunnable { public: inline LocRunnable() {} inline virtual ~LocRunnable() {} // The method to be implemented by thread clients // and be scheduled by LocThread // This method will be repeated called until it returns false; or // until thread is stopped. virtual bool run() = 0; // The method to be run before thread loop (conditionally repeatedly) // calls run() inline virtual void prerun() {} // The method to be run after thread loop (conditionally repeatedly) // calls run() inline virtual void postrun() {} }; // opaque class to provide service implementation. class LocThreadDelegate; // A utility class to create a thread and run LocRunnable // caller passes in. class LocThread { LocThreadDelegate* mThread; public: inline LocThread() : mThread(NULL) {} virtual ~LocThread(); typedef pthread_t (*tCreate)(const char* name, void* (*start)(void*), void* arg); // client starts thread with a runnable, which implements // the logics to fun in the created thread context. // The thread could be either joinable or detached. // runnable is an obj managed by client. Client creates and // frees it (but must be after stop() is called, or // this LocThread obj is deleted). // The obj will be deleted by LocThread if start() // returns true. Else it is client's responsibility // to delete the object // Returns 0 if success; false if failure. bool start(tCreate creator, const char* threadName, LocRunnable* runnable, bool joinable = true); inline bool start(const char* threadName, LocRunnable* runnable, bool joinable = true) { return start(NULL, threadName, runnable, joinable); } // NOTE: if this is a joinable thread, this stop may block // for a while until the thread is joined. void stop(); // thread status check inline bool isRunning() { return NULL != mThread; } }; #endif //__LOC_THREAD__ ================================================ FILE: gps/utils/LocTimer.cpp ================================================ /* Copyright (c) 2015, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include #include #include #include #include #include #include #include #include #include #ifdef __HOST_UNIT_TEST__ #define EPOLLWAKEUP 0 #define CLOCK_BOOTTIME CLOCK_MONOTONIC #define CLOCK_BOOTTIME_ALARM CLOCK_MONOTONIC #endif /* There are implementations of 5 classes in this file: LocTimer, LocTimerDelegate, LocTimerContainer, LocTimerPollTask, LocTimerWrapper LocTimer - client front end, interface for client to start / stop timers, also to provide a callback. LocTimerDelegate - an internal timer entity, which also is a LocRankable obj. Its life cycle is different than that of LocTimer. It gets created when LocTimer::start() is called, and gets deleted when it expires or clients calls the hosting LocTimer obj's stop() method. When a LocTimerDelegate obj is ticking, it stays in the corresponding LocTimerContainer. When expired or stopped, the obj is removed from the container. Since it is also a LocRankable obj, and LocTimerContainer also is a heap, its ranks() implementation decides where it is placed in the heap. LocTimerContainer - core of the timer service. It is a container (derived from LocHeap) for LocTimerDelegate (implements LocRankable) objs. There are 2 of such containers, one for sw timers (or Linux timers) one for hw timers (or Linux alarms). It adds one of each (those that expire the soonest) to kernel via services provided by LocTimerPollTask. All the heap management on the LocTimerDelegate objs are done in the MsgTask context, such that synchronization is ensured. LocTimerPollTask - is a class that wraps timerfd and epoll POXIS APIs. It also both implements LocRunnalbe with epoll_wait() in the run() method. It is also a LocThread client, so as to loop the run method. LocTimerWrapper - a LocTimer client itself, to implement the existing C API with APIs, loc_timer_start() and loc_timer_stop(). */ class LocTimerPollTask; // This is a multi-functaional class that: // * extends the LocHeap class for the detection of head update upon add / remove // events. When that happens, soonest time out changes, so timerfd needs update. // * contains the timers, and add / remove them into the heap // * provides and maps 2 of such containers, one for timers (or mSwTimers), one // for alarms (or mHwTimers); // * provides a polling thread; // * provides a MsgTask thread for synchronized add / remove / timer client callback. class LocTimerContainer : public LocHeap { // mutex to synchronize getters of static members static pthread_mutex_t mMutex; // Container of timers static LocTimerContainer* mSwTimers; // Container of alarms static LocTimerContainer* mHwTimers; // Msg task to provider msg Q, sender and reader. static MsgTask* mMsgTask; // Poll task to provide epoll call and threading to poll. static LocTimerPollTask* mPollTask; // timer / alarm fd int mDevFd; // ctor LocTimerContainer(bool wakeOnExpire); // dtor ~LocTimerContainer(); static MsgTask* getMsgTaskLocked(); static LocTimerPollTask* getPollTaskLocked(); // extend LocHeap and pop if the top outRanks input LocTimerDelegate* popIfOutRanks(LocTimerDelegate& timer); // update the timer POSIX calls with updated soonest timer spec void updateSoonestTime(LocTimerDelegate* priorTop); public: // factory method to control the creation of mSwTimers / mHwTimers static LocTimerContainer* get(bool wakeOnExpire); LocTimerDelegate* getSoonestTimer(); int getTimerFd(); // add a timer / alarm obj into the container void add(LocTimerDelegate& timer); // remove a timer / alarm obj from the container void remove(LocTimerDelegate& timer); // handling of timer / alarm expiration void expire(); }; // This class implements the polling thread that epolls imer / alarm fds. // The LocRunnable::run() contains the actual polling. The other methods // will be run in the caller's thread context to add / remove timer / alarm // fds the kernel, while the polling is blocked on epoll_wait() call. // Since the design is that we have maximally 2 polls, one for all the // timers; one for all the alarms, we will poll at most on 2 fds. But it // is possile that all we have are only timers or alarms at one time, so we // allow dynamically add / remove fds we poll on. The design decision of // having 1 fd per container of timer / alarm is such that, we may not need // to make a system call each time a timer / alarm is added / removed, unless // that changes the "soonest" time out of that of all the timers / alarms. class LocTimerPollTask : public LocRunnable { // the epoll fd const int mFd; // the thread that calls run() method LocThread* mThread; friend class LocThreadDelegate; // dtor ~LocTimerPollTask(); public: // ctor LocTimerPollTask(); // this obj will be deleted once thread is deleted void destroy(); // add a container of timers. Each contain has a unique device fd, i.e. // either timer or alarm fd, and a heap of timers / alarms. It is expected // that container would have written to the device fd with the soonest // time out value in the heap at the time of calling this method. So all // this method does is to add the fd of the input container to the poll // and also add the pointer of the container to the event data ptr, such // when poll_wait wakes up on events, we know who is the owner of the fd. void addPoll(LocTimerContainer& timerContainer); // remove a fd that is assciated with a container. The expectation is that // the atual timer would have been removed from the container. void removePoll(LocTimerContainer& timerContainer); // The polling thread context will call this method. This is where // epoll_wait() is blocking and waiting for events.. virtual bool run(); }; // Internal class of timer obj. It gets born when client calls LocTimer::start(); // and gets deleted when client calls LocTimer::stop() or when the it expire()'s. // This class implements LocRankable::ranks() so that when an obj is added into // the container (of LocHeap), it gets placed in sorted order. class LocTimerDelegate : public LocRankable { friend class LocTimerContainer; friend class LocTimer; LocTimer* mClient; LocSharedLock* mLock; struct timespec mFutureTime; LocTimerContainer* mContainer; // not a complete obj, just ctor for LocRankable comparisons inline LocTimerDelegate(struct timespec& delay) : mClient(NULL), mLock(NULL), mFutureTime(delay), mContainer(NULL) {} inline ~LocTimerDelegate() { if (mLock) { mLock->drop(); mLock = NULL; } } public: LocTimerDelegate(LocTimer& client, struct timespec& futureTime, bool wakeOnExpire); void destroyLocked(); // LocRankable virtual method virtual int ranks(LocRankable& rankable); void expire(); inline struct timespec getFutureTime() { return mFutureTime; } }; /***************************LocTimerContainer methods***************************/ // Most of these static recources are created on demand. They however are never // destoyed. The theory is that there are processes that link to this util lib // but never use timer, then these resources would never need to be created. // For those processes that do use timer, it will likely also need to every // once in a while. It might be cheaper keeping them around. pthread_mutex_t LocTimerContainer::mMutex = PTHREAD_MUTEX_INITIALIZER; LocTimerContainer* LocTimerContainer::mSwTimers = NULL; LocTimerContainer* LocTimerContainer::mHwTimers = NULL; MsgTask* LocTimerContainer::mMsgTask = NULL; LocTimerPollTask* LocTimerContainer::mPollTask = NULL; // ctor - initialize timer heaps // A container for swTimer (timer) is created, when wakeOnExpire is true; or // HwTimer (alarm), when wakeOnExpire is false. LocTimerContainer::LocTimerContainer(bool wakeOnExpire) : mDevFd(timerfd_create(wakeOnExpire ? CLOCK_BOOTTIME_ALARM : CLOCK_BOOTTIME, 0)) { if ((-1 == mDevFd) && (errno == EINVAL)) { LOC_LOGW("%s: timerfd_create failure, fallback to CLOCK_MONOTONIC - %s", __FUNCTION__, strerror(errno)); mDevFd = timerfd_create(CLOCK_MONOTONIC, 0); } if (-1 != mDevFd) { // ensure we have the necessary resources created LocTimerContainer::getPollTaskLocked(); LocTimerContainer::getMsgTaskLocked(); } else { LOC_LOGE("%s: timerfd_create failure - %s", __FUNCTION__, strerror(errno)); } } // dtor // we do not ever destroy the static resources. inline LocTimerContainer::~LocTimerContainer() { close(mDevFd); } LocTimerContainer* LocTimerContainer::get(bool wakeOnExpire) { // get the reference of either mHwTimer or mSwTimers per wakeOnExpire LocTimerContainer*& container = wakeOnExpire ? mHwTimers : mSwTimers; // it is cheap to check pointer first than locking mutext unconditionally if (!container) { pthread_mutex_lock(&mMutex); // let's check one more time to be safe if (!container) { container = new LocTimerContainer(wakeOnExpire); // timerfd_create failure if (-1 == container->getTimerFd()) { delete container; container = NULL; } } pthread_mutex_unlock(&mMutex); } return container; } MsgTask* LocTimerContainer::getMsgTaskLocked() { // it is cheap to check pointer first than locking mutext unconditionally if (!mMsgTask) { mMsgTask = new MsgTask("LocTimerMsgTask", false); } return mMsgTask; } LocTimerPollTask* LocTimerContainer::getPollTaskLocked() { // it is cheap to check pointer first than locking mutext unconditionally if (!mPollTask) { mPollTask = new LocTimerPollTask(); } return mPollTask; } inline LocTimerDelegate* LocTimerContainer::getSoonestTimer() { return (LocTimerDelegate*)(peek()); } inline int LocTimerContainer::getTimerFd() { return mDevFd; } void LocTimerContainer::updateSoonestTime(LocTimerDelegate* priorTop) { LocTimerDelegate* curTop = getSoonestTimer(); // check if top has changed if (curTop != priorTop) { struct itimerspec delay = {0}; bool toSetTime = false; // if tree is empty now, we remove poll and disarm timer if (!curTop) { mPollTask->removePoll(*this); // setting the values to disarm timer delay.it_value.tv_sec = 0; delay.it_value.tv_nsec = 0; toSetTime = true; } else if (!priorTop || curTop->outRanks(*priorTop)) { // do this first to avoid race condition, in case settime is called // with too small an interval mPollTask->addPoll(*this); delay.it_value = curTop->getFutureTime(); toSetTime = true; } if (toSetTime) { timerfd_settime(getTimerFd(), TFD_TIMER_ABSTIME, &delay, NULL); } } } // all the heap management is done in the MsgTask context. inline void LocTimerContainer::add(LocTimerDelegate& timer) { struct MsgTimerPush : public LocMsg { LocTimerContainer* mTimerContainer; LocHeapNode* mTree; LocTimerDelegate* mTimer; inline MsgTimerPush(LocTimerContainer& container, LocTimerDelegate& timer) : LocMsg(), mTimerContainer(&container), mTimer(&timer) {} inline virtual void proc() const { LocTimerDelegate* priorTop = mTimerContainer->getSoonestTimer(); mTimerContainer->push((LocRankable&)(*mTimer)); mTimerContainer->updateSoonestTime(priorTop); } }; mMsgTask->sendMsg(new MsgTimerPush(*this, timer)); } // all the heap management is done in the MsgTask context. void LocTimerContainer::remove(LocTimerDelegate& timer) { struct MsgTimerRemove : public LocMsg { LocTimerContainer* mTimerContainer; LocTimerDelegate* mTimer; inline MsgTimerRemove(LocTimerContainer& container, LocTimerDelegate& timer) : LocMsg(), mTimerContainer(&container), mTimer(&timer) {} inline virtual void proc() const { LocTimerDelegate* priorTop = mTimerContainer->getSoonestTimer(); // update soonest timer only if mTimer is actually removed from // mTimerContainer AND mTimer is not priorTop. if (priorTop == ((LocHeap*)mTimerContainer)->remove((LocRankable&)*mTimer)) { // if passing in NULL, we tell updateSoonestTime to update // kernel with the current top timer interval. mTimerContainer->updateSoonestTime(NULL); } // all timers are deleted here, and only here. delete mTimer; } }; mMsgTask->sendMsg(new MsgTimerRemove(*this, timer)); } // all the heap management is done in the MsgTask context. // Upon expire, we check and continuously pop the heap until // the top node's timeout is in the future. void LocTimerContainer::expire() { struct MsgTimerExpire : public LocMsg { LocTimerContainer* mTimerContainer; inline MsgTimerExpire(LocTimerContainer& container) : LocMsg(), mTimerContainer(&container) {} inline virtual void proc() const { struct timespec now; // get time spec of now clock_gettime(CLOCK_BOOTTIME, &now); LocTimerDelegate timerOfNow(now); // pop everything in the heap that outRanks now, i.e. has time older than now // and then call expire() on that timer. for (LocTimerDelegate* timer = (LocTimerDelegate*)mTimerContainer->pop(); NULL != timer; timer = mTimerContainer->popIfOutRanks(timerOfNow)) { // the timer delegate obj will be deleted before the return of this call timer->expire(); } mTimerContainer->updateSoonestTime(NULL); } }; struct itimerspec delay = {0}; timerfd_settime(getTimerFd(), TFD_TIMER_ABSTIME, &delay, NULL); mPollTask->removePoll(*this); mMsgTask->sendMsg(new MsgTimerExpire(*this)); } LocTimerDelegate* LocTimerContainer::popIfOutRanks(LocTimerDelegate& timer) { LocTimerDelegate* poppedNode = NULL; if (mTree && !timer.outRanks(*peek())) { poppedNode = (LocTimerDelegate*)(pop()); } return poppedNode; } /***************************LocTimerPollTask methods***************************/ inline LocTimerPollTask::LocTimerPollTask() : mFd(epoll_create(2)), mThread(new LocThread()) { // before a next call returens, a thread will be created. The run() method // could already be running in parallel. Also, since each of the objs // creates a thread, the container will make sure that there will be only // one of such obj for our timer implementation. if (!mThread->start("LocTimerPollTask", this)) { delete mThread; mThread = NULL; } } inline LocTimerPollTask::~LocTimerPollTask() { // when fs is closed, epoll_wait() should fail run() should return false // and the spawned thread should exit. close(mFd); } void LocTimerPollTask::destroy() { if (mThread) { LocThread* thread = mThread; mThread = NULL; delete thread; } else { delete this; } } void LocTimerPollTask::addPoll(LocTimerContainer& timerContainer) { struct epoll_event ev; memset(&ev, 0, sizeof(ev)); ev.events = EPOLLIN | EPOLLWAKEUP; ev.data.fd = timerContainer.getTimerFd(); // it is important that we set this context pointer with the input // timer container this is how we know which container should handle // which expiration. ev.data.ptr = &timerContainer; epoll_ctl(mFd, EPOLL_CTL_ADD, timerContainer.getTimerFd(), &ev); } inline void LocTimerPollTask::removePoll(LocTimerContainer& timerContainer) { epoll_ctl(mFd, EPOLL_CTL_DEL, timerContainer.getTimerFd(), NULL); } // The polling thread context will call this method. If run() method needs to // be repetitvely called, it must return true from the previous call. bool LocTimerPollTask::run() { struct epoll_event ev[2]; // we have max 2 descriptors to poll from int fds = epoll_wait(mFd, ev, 2, -1); // we pretty much want to continually poll until the fd is closed bool rerun = (fds > 0) || (errno == EINTR); if (fds > 0) { // we may have 2 events for (int i = 0; i < fds; i++) { // each fd has a context pointer associated with the right timer container LocTimerContainer* container = (LocTimerContainer*)(ev[i].data.ptr); if (container) { container->expire(); } else { epoll_ctl(mFd, EPOLL_CTL_DEL, ev[i].data.fd, NULL); } } } // if rerun is true, we are requesting to be scheduled again return rerun; } /***************************LocTimerDelegate methods***************************/ inline LocTimerDelegate::LocTimerDelegate(LocTimer& client, struct timespec& futureTime, bool wakeOnExpire) : mClient(&client), mLock(mClient->mLock->share()), mFutureTime(futureTime), mContainer(LocTimerContainer::get(wakeOnExpire)) { // adding the timer into the container mContainer->add(*this); } inline void LocTimerDelegate::destroyLocked() { // client handle will likely be deleted soon after this // method returns. Nulling this handle so that expire() // won't call the callback on the dead handle any more. mClient = NULL; if (mContainer) { LocTimerContainer* container = mContainer; mContainer = NULL; if (container) { container->remove(*this); } } // else we do not do anything. No such *this* can be // created and reached here with mContainer ever been // a non NULL. So *this* must have reached the if clause // once, and we want it reach there only once. } int LocTimerDelegate::ranks(LocRankable& rankable) { int rank = -1; LocTimerDelegate* timer = (LocTimerDelegate*)(&rankable); if (timer) { // larger time ranks lower!!! // IOW, if input obj has bigger tv_sec, this obj outRanks higher rank = timer->mFutureTime.tv_sec - mFutureTime.tv_sec; } return rank; } inline void LocTimerDelegate::expire() { // keeping a copy of client pointer to be safe // when timeOutCallback() is called at the end of this // method, *this* obj may be already deleted. LocTimer* client = mClient; // force a stop, which will lead to delete of this obj if (client && client->stop()) { // calling client callback with a pointer save on the stack // only if stop() returns true, i.e. it hasn't been stopped // already. client->timeOutCallback(); } } /***************************LocTimer methods***************************/ LocTimer::LocTimer() : mTimer(NULL), mLock(new LocSharedLock()) { } LocTimer::~LocTimer() { stop(); if (mLock) { mLock->drop(); mLock = NULL; } } bool LocTimer::start(unsigned int timeOutInMs, bool wakeOnExpire) { bool success = false; mLock->lock(); if (!mTimer) { struct timespec futureTime; clock_gettime(CLOCK_BOOTTIME, &futureTime); futureTime.tv_sec += timeOutInMs / 1000; futureTime.tv_nsec += (timeOutInMs % 1000) * 1000000; if (futureTime.tv_nsec >= 1000000000) { futureTime.tv_sec += futureTime.tv_nsec / 1000000000; futureTime.tv_nsec %= 1000000000; } mTimer = new LocTimerDelegate(*this, futureTime, wakeOnExpire); // if mTimer is non 0, success should be 0; or vice versa success = (NULL != mTimer); } mLock->unlock(); return success; } bool LocTimer::stop() { bool success = false; mLock->lock(); if (mTimer) { LocTimerDelegate* timer = mTimer; mTimer = NULL; if (timer) { timer->destroyLocked(); success = true; } } mLock->unlock(); return success; } /***************************LocTimerWrapper methods***************************/ ////////////////////////////////////////////////////////////////////////// // This section below wraps for the C style APIs ////////////////////////////////////////////////////////////////////////// class LocTimerWrapper : public LocTimer { loc_timer_callback mCb; void* mCallerData; LocTimerWrapper* mMe; static pthread_mutex_t mMutex; inline ~LocTimerWrapper() { mCb = NULL; mMe = NULL; } public: inline LocTimerWrapper(loc_timer_callback cb, void* callerData) : mCb(cb), mCallerData(callerData), mMe(this) { } void destroy() { pthread_mutex_lock(&mMutex); if (NULL != mCb && this == mMe) { delete this; } pthread_mutex_unlock(&mMutex); } virtual void timeOutCallback() { loc_timer_callback cb = mCb; void* callerData = mCallerData; if (cb) { cb(callerData, 0); } destroy(); } }; pthread_mutex_t LocTimerWrapper::mMutex = PTHREAD_MUTEX_INITIALIZER; void* loc_timer_start(uint64_t msec, loc_timer_callback cb_func, void *caller_data, bool wake_on_expire) { LocTimerWrapper* locTimerWrapper = NULL; if (cb_func) { locTimerWrapper = new LocTimerWrapper(cb_func, caller_data); if (locTimerWrapper) { locTimerWrapper->start(msec, wake_on_expire); } } return locTimerWrapper; } void loc_timer_stop(void*& handle) { if (handle) { LocTimerWrapper* locTimerWrapper = (LocTimerWrapper*)(handle); locTimerWrapper->destroy(); handle = NULL; } } ////////////////////////////////////////////////////////////////////////// // This section above wraps for the C style APIs ////////////////////////////////////////////////////////////////////////// #ifdef __LOC_DEBUG__ double getDeltaSeconds(struct timespec from, struct timespec to) { return (double)to.tv_sec + (double)to.tv_nsec / 1000000000 - from.tv_sec - (double)from.tv_nsec / 1000000000; } struct timespec getNow() { struct timespec now; clock_gettime(CLOCK_BOOTTIME, &now); return now; } class LocTimerTest : public LocTimer, public LocRankable { int mTimeOut; const struct timespec mTimeOfBirth; inline struct timespec getTimerWrapper(int timeout) { struct timespec now; clock_gettime(CLOCK_BOOTTIME, &now); now.tv_sec += timeout; return now; } public: inline LocTimerTest(int timeout) : LocTimer(), LocRankable(), mTimeOut(timeout), mTimeOfBirth(getTimerWrapper(0)) {} inline virtual int ranks(LocRankable& rankable) { LocTimerTest* timer = dynamic_cast(&rankable); return timer->mTimeOut - mTimeOut; } inline virtual void timeOutCallback() { printf("timeOutCallback() - "); deviation(); } double deviation() { struct timespec now = getTimerWrapper(0); double delta = getDeltaSeconds(mTimeOfBirth, now); printf("%lf: %lf\n", delta, delta * 100 / mTimeOut); return delta / mTimeOut; } }; // For Linux command line testing: // compilation: // g++ -D__LOC_HOST_DEBUG__ -D__LOC_DEBUG__ -g -I. -I../../../../system/core/include -o LocHeap.o LocHeap.cpp // g++ -D__LOC_HOST_DEBUG__ -D__LOC_DEBUG__ -g -std=c++0x -I. -I../../../../system/core/include -lpthread -o LocThread.o LocThread.cpp // g++ -D__LOC_HOST_DEBUG__ -D__LOC_DEBUG__ -g -I. -I../../../../system/core/include -o LocTimer.o LocTimer.cpp int main(int argc, char** argv) { struct timespec timeOfStart=getNow(); srand(time(NULL)); int tries = atoi(argv[1]); int checks = tries >> 3; LocTimerTest** timerArray = new LocTimerTest*[tries]; memset(timerArray, NULL, tries); for (int i = 0; i < tries; i++) { int r = rand() % tries; LocTimerTest* timer = new LocTimerTest(r); if (timerArray[r]) { if (!timer->stop()) { printf("%lf:\n", getDeltaSeconds(timeOfStart, getNow())); printf("ERRER: %dth timer, id %d, not running when it should be\n", i, r); exit(0); } else { printf("stop() - %d\n", r); delete timer; timerArray[r] = NULL; } } else { if (!timer->start(r, false)) { printf("%lf:\n", getDeltaSeconds(timeOfStart, getNow())); printf("ERRER: %dth timer, id %d, running when it should not be\n", i, r); exit(0); } else { printf("stop() - %d\n", r); timerArray[r] = timer; } } } for (int i = 0; i < tries; i++) { if (timerArray[i]) { if (!timerArray[i]->stop()) { printf("%lf:\n", getDeltaSeconds(timeOfStart, getNow())); printf("ERRER: %dth timer, not running when it should be\n", i); exit(0); } else { printf("stop() - %d\n", i); delete timerArray[i]; timerArray[i] = NULL; } } } delete[] timerArray; return 0; } #endif ================================================ FILE: gps/utils/LocTimer.h ================================================ /* Copyright (c) 2015, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef __LOC_TIMER_CPP_H__ #define __LOC_TIMER_CPP_H__ #include #include // opaque class to provide service implementation. class LocTimerDelegate; class LocSharedLock; // LocTimer client must extend this class and implementthe callback. // start() / stop() methods are to arm / disarm timer. class LocTimer { LocTimerDelegate* mTimer; LocSharedLock* mLock; // don't really want mLock to be manipulated by clients, yet LocTimer // has to have a reference to the lock so that the delete of LocTimer // and LocTimerDelegate can work together on their share resources. friend class LocTimerDelegate; public: LocTimer(); virtual ~LocTimer(); // timeOutInMs: timeout delay in ms // wakeOnExpire: true if to wake up CPU (if sleeping) upon timer // expiration and notify the client. // false if to wait until next time CPU wakes up (if // sleeping) and then notify the client. // return: true on success; // false on failure, e.g. timer is already running. bool start(uint32_t timeOutInMs, bool wakeOnExpire); // return: true on success; // false on failure, e.g. timer is not running. bool stop(); // LocTimer client Should implement this method. // This method is used for timeout calling back to client. This method // should be short enough (eg: send a message to your own thread). virtual void timeOutCallback() = 0; }; #endif //__LOC_DELAY_H__ ================================================ FILE: gps/utils/Makefile.am ================================================ AM_CFLAGS = -Wundef \ -MD \ -Wno-trigraphs \ -g -O0 \ -fno-inline \ -fno-short-enums \ -fpic \ -I../platform_lib_abstractions libgps_utils_so_la_h_sources = log_util.h \ msg_q.h \ linked_list.h \ loc_cfg.h \ loc_log.h \ ../platform_lib_abstractions/platform_lib_includes.h \ ../platform_lib_abstractions/platform_lib_time.h \ ../platform_lib_abstractions/platform_lib_macros.h libgps_utils_so_la_c_sources = linked_list.c \ msg_q.c \ loc_cfg.cpp \ loc_log.cpp \ ../platform_lib_abstractions/elapsed_millis_since_boot.cpp library_includedir = $(pkgincludedir)/utils library_include_HEADERS = $(libgps_utils_so_la_h_sources) libgps_utils_so_la_SOURCES = $(libgps_utils_so_la_c_sources) if USE_GLIB libgps_utils_so_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@ libgps_utils_so_la_LDFLAGS = -lstdc++ -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0 libgps_utils_so_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@ else libgps_utils_so_la_CFLAGS = $(AM_CFLAGS) libgps_utils_so_la_LDFLAGS = -lpthread -shared -version-info 1:0:0 libgps_utils_so_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS) endif libgps_utils_so_la_LIBADD = -lstdc++ -lcutils #Create and Install libraries lib_LTLIBRARIES = libgps_utils_so.la ================================================ FILE: gps/utils/MsgTask.cpp ================================================ /* Copyright (c) 2011-2013,2015 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #define LOG_NDDEBUG 0 #define LOG_TAG "LocSvc_MsgTask" #include #include #include #include #include #include static void LocMsgDestroy(void* msg) { delete (LocMsg*)msg; } MsgTask::MsgTask(LocThread::tCreate tCreator, const char* threadName, bool joinable) : mQ(msg_q_init2()), mThread(new LocThread()) { if (!mThread->start(tCreator, threadName, this, joinable)) { delete mThread; mThread = NULL; } } MsgTask::MsgTask(const char* threadName, bool joinable) : mQ(msg_q_init2()), mThread(new LocThread()) { if (!mThread->start(threadName, this, joinable)) { delete mThread; mThread = NULL; } } MsgTask::~MsgTask() { msg_q_flush((void*)mQ); msg_q_destroy((void**)&mQ); } void MsgTask::destroy() { msg_q_unblock((void*)mQ); if (mThread) { LocThread* thread = mThread; mThread = NULL; delete thread; } else { delete this; } } void MsgTask::sendMsg(const LocMsg* msg) const { msg_q_snd((void*)mQ, (void*)msg, LocMsgDestroy); } void MsgTask::prerun() { // make sure we do not run in background scheduling group set_sched_policy(gettid(), SP_FOREGROUND); } bool MsgTask::run() { LOC_LOGD("MsgTask::loop() listening ...\n"); LocMsg* msg; msq_q_err_type result = msg_q_rcv((void*)mQ, (void **)&msg); if (eMSG_Q_SUCCESS != result) { LOC_LOGE("%s:%d] fail receiving msg: %s\n", __func__, __LINE__, loc_get_msg_q_status(result)); return false; } msg->log(); // there is where each individual msg handling is invoked msg->proc(); delete msg; return true; } ================================================ FILE: gps/utils/MsgTask.h ================================================ /* Copyright (c) 2011-2013,2015 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef __MSG_TASK__ #define __MSG_TASK__ #include struct LocMsg { inline LocMsg() {} inline virtual ~LocMsg() {} virtual void proc() const = 0; inline virtual void log() const {} }; class MsgTask : public LocRunnable { const void* mQ; LocThread* mThread; friend class LocThreadDelegate; protected: virtual ~MsgTask(); public: MsgTask(LocThread::tCreate tCreator, const char* threadName = NULL, bool joinable = true); MsgTask(const char* threadName = NULL, bool joinable = true); // this obj will be deleted once thread is deleted void destroy(); void sendMsg(const LocMsg* msg) const; // Overrides of LocRunnable methods // This method will be repeated called until it returns false; or // until thread is stopped. virtual bool run(); // The method to be run before thread loop (conditionally repeatedly) // calls run() virtual void prerun(); // The method to be run after thread loop (conditionally repeatedly) // calls run() inline virtual void postrun() {} }; #endif //__MSG_TASK__ ================================================ FILE: gps/utils/linked_list.c ================================================ /* Copyright (c) 2011, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "linked_list.h" #include #include #define LOG_TAG "LocSvc_utils_ll" #include "log_util.h" #include "platform_lib_includes.h" #include #include typedef struct list_element { struct list_element* next; struct list_element* prev; void* data_ptr; void (*dealloc_func)(void*); }list_element; typedef struct list_state { list_element* p_head; list_element* p_tail; } list_state; /* ----------------------- END INTERNAL FUNCTIONS ---------------------------------------- */ /*=========================================================================== FUNCTION: linked_list_init ===========================================================================*/ linked_list_err_type linked_list_init(void** list_data) { if( list_data == NULL ) { LOC_LOGE("%s: Invalid list parameter!\n", __FUNCTION__); return eLINKED_LIST_INVALID_PARAMETER; } list_state* tmp_list; tmp_list = (list_state*)calloc(1, sizeof(list_state)); if( tmp_list == NULL ) { LOC_LOGE("%s: Unable to allocate space for list!\n", __FUNCTION__); return eLINKED_LIST_FAILURE_GENERAL; } tmp_list->p_head = NULL; tmp_list->p_tail = NULL; *list_data = tmp_list; return eLINKED_LIST_SUCCESS; } /*=========================================================================== FUNCTION: linked_list_destroy ===========================================================================*/ linked_list_err_type linked_list_destroy(void** list_data) { if( list_data == NULL ) { LOC_LOGE("%s: Invalid list parameter!\n", __FUNCTION__); return eLINKED_LIST_INVALID_HANDLE; } list_state* p_list = (list_state*)*list_data; linked_list_flush(p_list); free(*list_data); *list_data = NULL; return eLINKED_LIST_SUCCESS; } /*=========================================================================== FUNCTION: linked_list_add ===========================================================================*/ linked_list_err_type linked_list_add(void* list_data, void *data_obj, void (*dealloc)(void*)) { LOC_LOGD("%s: Adding to list data_obj = 0x%08X\n", __FUNCTION__, data_obj); if( list_data == NULL ) { LOC_LOGE("%s: Invalid list parameter!\n", __FUNCTION__); return eLINKED_LIST_INVALID_HANDLE; } if( data_obj == NULL ) { LOC_LOGE("%s: Invalid input parameter!\n", __FUNCTION__); return eLINKED_LIST_INVALID_PARAMETER; } list_state* p_list = (list_state*)list_data; list_element* elem = (list_element*)malloc(sizeof(list_element)); if( elem == NULL ) { LOC_LOGE("%s: Memory allocation failed\n", __FUNCTION__); return eLINKED_LIST_FAILURE_GENERAL; } /* Copy data to newly created element */ elem->data_ptr = data_obj; elem->next = NULL; elem->prev = NULL; elem->dealloc_func = dealloc; /* Replace head element */ list_element* tmp = p_list->p_head; p_list->p_head = elem; /* Point next to the previous head element */ p_list->p_head->next = tmp; if( tmp != NULL ) { tmp->prev = p_list->p_head; } else { p_list->p_tail = p_list->p_head; } return eLINKED_LIST_SUCCESS; } /*=========================================================================== FUNCTION: linked_list_remove ===========================================================================*/ linked_list_err_type linked_list_remove(void* list_data, void **data_obj) { LOC_LOGD("%s: Removing from list\n", __FUNCTION__); if( list_data == NULL ) { LOC_LOGE("%s: Invalid list parameter!\n", __FUNCTION__); return eLINKED_LIST_INVALID_HANDLE; } if( data_obj == NULL ) { LOC_LOGE("%s: Invalid input parameter!\n", __FUNCTION__); return eLINKED_LIST_INVALID_PARAMETER; } list_state* p_list = (list_state*)list_data; if( p_list->p_tail == NULL ) { return eLINKED_LIST_UNAVAILABLE_RESOURCE; } list_element* tmp = p_list->p_tail; /* Replace tail element */ p_list->p_tail = tmp->prev; if( p_list->p_tail != NULL ) { p_list->p_tail->next = NULL; } else { p_list->p_head = p_list->p_tail; } /* Copy data to output param */ *data_obj = tmp->data_ptr; /* Free allocated list element */ free(tmp); return eLINKED_LIST_SUCCESS; } /*=========================================================================== FUNCTION: linked_list_empty ===========================================================================*/ int linked_list_empty(void* list_data) { if( list_data == NULL ) { LOC_LOGE("%s: Invalid list parameter!\n", __FUNCTION__); return (int)eLINKED_LIST_INVALID_HANDLE; } else { list_state* p_list = (list_state*)list_data; return p_list->p_head == NULL ? 1 : 0; } } /*=========================================================================== FUNCTION: linked_list_flush ===========================================================================*/ linked_list_err_type linked_list_flush(void* list_data) { if( list_data == NULL ) { LOC_LOGE("%s: Invalid list parameter!\n", __FUNCTION__); return eLINKED_LIST_INVALID_HANDLE; } list_state* p_list = (list_state*)list_data; /* Remove all dynamically allocated elements */ while( p_list->p_head != NULL ) { list_element* tmp = p_list->p_head->next; /* Free data pointer if told to do so. */ if( p_list->p_head->dealloc_func != NULL ) { p_list->p_head->dealloc_func(p_list->p_head->data_ptr); } /* Free list element */ free(p_list->p_head); p_list->p_head = tmp; } p_list->p_tail = NULL; return eLINKED_LIST_SUCCESS; } /*=========================================================================== FUNCTION: linked_list_search ===========================================================================*/ linked_list_err_type linked_list_search(void* list_data, void **data_p, bool (*equal)(void* data_0, void* data), void* data_0, bool rm_if_found) { LOC_LOGD("%s: Search the list\n", __FUNCTION__); if( list_data == NULL || NULL == equal ) { LOC_LOGE("%s: Invalid list parameter! list_data %p equal %p\n", __FUNCTION__, list_data, equal); return eLINKED_LIST_INVALID_HANDLE; } list_state* p_list = (list_state*)list_data; if( p_list->p_tail == NULL ) { return eLINKED_LIST_UNAVAILABLE_RESOURCE; } list_element* tmp = p_list->p_head; if (NULL != data_p) { *data_p = NULL; } while (NULL != tmp) { if ((*equal)(data_0, tmp->data_ptr)) { if (NULL != data_p) { *data_p = tmp->data_ptr; } if (rm_if_found) { if (NULL == tmp->prev) { p_list->p_head = tmp->next; } else { tmp->prev->next = tmp->next; } if (NULL == tmp->next) { p_list->p_tail = tmp->prev; } else { tmp->next->prev = tmp->prev; } tmp->prev = tmp->next = NULL; // dealloc data if it is not copied out && caller // has given us a dealloc function pointer. if (NULL == data_p && NULL != tmp->dealloc_func) { tmp->dealloc_func(tmp->data_ptr); } free(tmp); } tmp = NULL; } else { tmp = tmp->next; } } return eLINKED_LIST_SUCCESS; } ================================================ FILE: gps/utils/linked_list.h ================================================ /* Copyright (c) 2011, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __LINKED_LIST_H__ #define __LINKED_LIST_H__ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #include #include /** Linked List Return Codes */ typedef enum { eLINKED_LIST_SUCCESS = 0, /**< Request was successful. */ eLINKED_LIST_FAILURE_GENERAL = -1, /**< Failed because of a general failure. */ eLINKED_LIST_INVALID_PARAMETER = -2, /**< Failed because the request contained invalid parameters. */ eLINKED_LIST_INVALID_HANDLE = -3, /**< Failed because an invalid handle was specified. */ eLINKED_LIST_UNAVAILABLE_RESOURCE = -4, /**< Failed because an there were not enough resources. */ eLINKED_LIST_INSUFFICIENT_BUFFER = -5, /**< Failed because an the supplied buffer was too small. */ }linked_list_err_type; /*=========================================================================== FUNCTION linked_list_init DESCRIPTION Initializes internal structures for linked list. list_data: State of list to be initialized. DEPENDENCIES N/A RETURN VALUE Look at error codes above. SIDE EFFECTS N/A ===========================================================================*/ linked_list_err_type linked_list_init(void** list_data); /*=========================================================================== FUNCTION linked_list_destroy DESCRIPTION Destroys internal structures for linked list. p_list_data: State of list to be destroyed. DEPENDENCIES N/A RETURN VALUE Look at error codes above. SIDE EFFECTS N/A ===========================================================================*/ linked_list_err_type linked_list_destroy(void** list_data); /*=========================================================================== FUNCTION linked_list_add DESCRIPTION Adds an element to the head of the linked list. The passed in data pointer is not modified or freed. Passed in data_obj is expected to live throughout the use of the linked_list (i.e. data is not allocated internally) p_list_data: List to add data to the head of. data_obj: Pointer to data to add into list dealloc: Function used to deallocate memory for this element. Pass NULL if you do not want data deallocated during a flush operation DEPENDENCIES N/A RETURN VALUE Look at error codes above. SIDE EFFECTS N/A ===========================================================================*/ linked_list_err_type linked_list_add(void* list_data, void *data_obj, void (*dealloc)(void*)); /*=========================================================================== FUNCTION linked_list_remove DESCRIPTION Retrieves data from the list tail. data_obj is the tail element from the list passed in by linked_list_add. p_list_data: List to remove the tail from. data_obj: Pointer to data removed from list DEPENDENCIES N/A RETURN VALUE Look at error codes above. SIDE EFFECTS N/A ===========================================================================*/ linked_list_err_type linked_list_remove(void* list_data, void **data_obj); /*=========================================================================== FUNCTION linked_list_empty DESCRIPTION Tells whether the list currently contains any elements p_list_data: List to check if empty. DEPENDENCIES N/A RETURN VALUE 0/FALSE : List contains elements 1/TRUE : List is Empty Otherwise look at error codes above. SIDE EFFECTS N/A ===========================================================================*/ int linked_list_empty(void* list_data); /*=========================================================================== FUNCTION linked_list_flush DESCRIPTION Removes all elements from the list and deallocates them using the provided dealloc function while adding elements. p_list_data: List to remove all elements from. DEPENDENCIES N/A RETURN VALUE Look at error codes above. SIDE EFFECTS N/A ===========================================================================*/ linked_list_err_type linked_list_flush(void* list_data); /*=========================================================================== FUNCTION linked_list_search DESCRIPTION Searches for an element in the linked list. p_list_data: List handle. data_p: to be stored with the data found; NUll if no match. if data_p passed in as NULL, then no write to it. equal: Function ptr takes in a list element, and returns indication if this the one looking for. data_0: The data being compared against. rm_if_found: Should data be removed if found? DEPENDENCIES N/A RETURN VALUE Look at error codes above. SIDE EFFECTS N/A ===========================================================================*/ linked_list_err_type linked_list_search(void* list_data, void **data_p, bool (*equal)(void* data_0, void* data), void* data_0, bool rm_if_found); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* __LINKED_LIST_H__ */ ================================================ FILE: gps/utils/loc_cfg.cpp ================================================ /* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #define LOG_NDDEBUG 0 #define LOG_TAG "LocSvc_utils_cfg" #include #include #include #include #include #include #include #include #include #include #ifdef USE_GLIB #include #endif #include "platform_lib_includes.h" /*============================================================================= * * GLOBAL DATA DECLARATION * *============================================================================*/ /* Parameter data */ static uint32_t DEBUG_LEVEL = 0xff; static uint32_t TIMESTAMP = 0; /* Parameter spec table */ static loc_param_s_type loc_param_table[] = { {"DEBUG_LEVEL", &DEBUG_LEVEL, NULL, 'n'}, {"TIMESTAMP", &TIMESTAMP, NULL, 'n'}, }; int loc_param_num = sizeof(loc_param_table) / sizeof(loc_param_s_type); typedef struct loc_param_v_type { char* param_name; char* param_str_value; int param_int_value; double param_double_value; }loc_param_v_type; /*=========================================================================== FUNCTION loc_set_config_entry DESCRIPTION Potentially sets a given configuration table entry based on the passed in configuration value. This is done by using a string comparison of the parameter names and those found in the configuration file. PARAMETERS: config_entry: configuration entry in the table to possibly set config_value: value to store in the entry if the parameter names match DEPENDENCIES N/A RETURN VALUE None SIDE EFFECTS N/A ===========================================================================*/ int loc_set_config_entry(loc_param_s_type* config_entry, loc_param_v_type* config_value) { int ret=-1; if(NULL == config_entry || NULL == config_value) { LOC_LOGE("%s: INVALID config entry or parameter", __FUNCTION__); return ret; } if (strcmp(config_entry->param_name, config_value->param_name) == 0 && config_entry->param_ptr) { switch (config_entry->param_type) { case 's': if (strcmp(config_value->param_str_value, "NULL") == 0) { *((char*)config_entry->param_ptr) = '\0'; } else { strlcpy((char*) config_entry->param_ptr, config_value->param_str_value, LOC_MAX_PARAM_STRING + 1); } /* Log INI values */ LOC_LOGD("%s: PARAM %s = %s", __FUNCTION__, config_entry->param_name, (char*)config_entry->param_ptr); if(NULL != config_entry->param_set) { *(config_entry->param_set) = 1; } ret = 0; break; case 'n': *((int *)config_entry->param_ptr) = config_value->param_int_value; /* Log INI values */ LOC_LOGD("%s: PARAM %s = %d", __FUNCTION__, config_entry->param_name, config_value->param_int_value); if(NULL != config_entry->param_set) { *(config_entry->param_set) = 1; } ret = 0; break; case 'f': *((double *)config_entry->param_ptr) = config_value->param_double_value; /* Log INI values */ LOC_LOGD("%s: PARAM %s = %f", __FUNCTION__, config_entry->param_name, config_value->param_double_value); if(NULL != config_entry->param_set) { *(config_entry->param_set) = 1; } ret = 0; break; default: LOC_LOGE("%s: PARAM %s parameter type must be n, f, or s", __FUNCTION__, config_entry->param_name); } } return ret; } /*=========================================================================== FUNCTION loc_fill_conf_item DESCRIPTION Takes a line of configuration item and sets defined values based on the passed in configuration table. This table maps strings to values to set along with the type of each of these values. PARAMETERS: input_buf : buffer contanis config item config_table: table definition of strings to places to store information table_length: length of the configuration table DEPENDENCIES N/A RETURN VALUE 0: Number of records in the config_table filled with input_buf SIDE EFFECTS N/A ===========================================================================*/ int loc_fill_conf_item(char* input_buf, loc_param_s_type* config_table, uint32_t table_length) { int ret = 0; if (input_buf && config_table) { char *lasts; loc_param_v_type config_value; memset(&config_value, 0, sizeof(config_value)); /* Separate variable and value */ config_value.param_name = strtok_r(input_buf, "=", &lasts); /* skip lines that do not contain "=" */ if (config_value.param_name) { config_value.param_str_value = strtok_r(NULL, "=", &lasts); /* skip lines that do not contain two operands */ if (config_value.param_str_value) { /* Trim leading and trailing spaces */ loc_util_trim_space(config_value.param_name); loc_util_trim_space(config_value.param_str_value); /* Parse numerical value */ if ((strlen(config_value.param_str_value) >=3) && (config_value.param_str_value[0] == '0') && (tolower(config_value.param_str_value[1]) == 'x')) { /* hex */ config_value.param_int_value = (int) strtol(&config_value.param_str_value[2], (char**) NULL, 16); } else { config_value.param_double_value = (double) atof(config_value.param_str_value); /* float */ config_value.param_int_value = atoi(config_value.param_str_value); /* dec */ } for(uint32_t i = 0; NULL != config_table && i < table_length; i++) { if(!loc_set_config_entry(&config_table[i], &config_value)) { ret += 1; } } } } } return ret; } /*=========================================================================== FUNCTION loc_read_conf_r (repetitive) DESCRIPTION Reads the specified configuration file and sets defined values based on the passed in configuration table. This table maps strings to values to set along with the type of each of these values. The difference between this and loc_read_conf is that this function returns the file pointer position at the end of filling a config table. Also, it reads a fixed number of parameters at a time which is equal to the length of the configuration table. This functionality enables the caller to repeatedly call the function to read data from the same file. PARAMETERS: conf_fp : file pointer config_table: table definition of strings to places to store information table_length: length of the configuration table DEPENDENCIES N/A RETURN VALUE 0: Table filled successfully 1: No more parameters to read -1: Error filling table SIDE EFFECTS N/A ===========================================================================*/ int loc_read_conf_r(FILE *conf_fp, loc_param_s_type* config_table, uint32_t table_length) { int ret=0; unsigned int num_params=table_length; if(conf_fp == NULL) { LOC_LOGE("%s:%d]: ERROR: File pointer is NULL\n", __func__, __LINE__); ret = -1; goto err; } /* Clear all validity bits */ for(uint32_t i = 0; NULL != config_table && i < table_length; i++) { if(NULL != config_table[i].param_set) { *(config_table[i].param_set) = 0; } } char input_buf[LOC_MAX_PARAM_LINE]; /* declare a char array */ LOC_LOGD("%s:%d]: num_params: %d\n", __func__, __LINE__, num_params); while(num_params) { if(!fgets(input_buf, LOC_MAX_PARAM_LINE, conf_fp)) { LOC_LOGD("%s:%d]: fgets returned NULL\n", __func__, __LINE__); break; } num_params -= loc_fill_conf_item(input_buf, config_table, table_length); } err: return ret; } /*=========================================================================== FUNCTION loc_udpate_conf DESCRIPTION Parses the passed in buffer for configuration items, and update the table that is also passed in. Reads the specified configuration file and sets defined values based on the passed in configuration table. This table maps strings to values to set along with the type of each of these values. PARAMETERS: conf_data: configuration items in bufferas a string length: strlen(conf_data) config_table: table definition of strings to places to store information table_length: length of the configuration table DEPENDENCIES N/A RETURN VALUE number of the records in the table that is updated at time of return. SIDE EFFECTS N/A ===========================================================================*/ int loc_update_conf(const char* conf_data, int32_t length, loc_param_s_type* config_table, uint32_t table_length) { int ret = -1; if (conf_data && length && config_table && table_length) { // make a copy, so we do not tokenize the original data char* conf_copy = (char*)malloc(length+1); if (conf_copy != NULL) { memcpy(conf_copy, conf_data, length); // we hard NULL the end of string to be safe conf_copy[length] = 0; // start with one record off uint32_t num_params = table_length - 1; char* saveptr = NULL; char* input_buf = strtok_r(conf_copy, "\n", &saveptr); ret = 0; LOC_LOGD("%s:%d]: num_params: %d\n", __func__, __LINE__, num_params); while(num_params && input_buf) { ret++; num_params -= loc_fill_conf_item(input_buf, config_table, table_length); input_buf = strtok_r(NULL, "\n", &saveptr); } free(conf_copy); } } return ret; } /*=========================================================================== FUNCTION loc_read_conf DESCRIPTION Reads the specified configuration file and sets defined values based on the passed in configuration table. This table maps strings to values to set along with the type of each of these values. PARAMETERS: conf_file_name: configuration file to read config_table: table definition of strings to places to store information table_length: length of the configuration table DEPENDENCIES N/A RETURN VALUE None SIDE EFFECTS N/A ===========================================================================*/ void loc_read_conf(const char* conf_file_name, loc_param_s_type* config_table, uint32_t table_length) { FILE *conf_fp = NULL; char *lasts; loc_param_v_type config_value; uint32_t i; if((conf_fp = fopen(conf_file_name, "r")) != NULL) { LOC_LOGD("%s: using %s", __FUNCTION__, conf_file_name); if(table_length && config_table) { loc_read_conf_r(conf_fp, config_table, table_length); rewind(conf_fp); } loc_read_conf_r(conf_fp, loc_param_table, loc_param_num); fclose(conf_fp); } /* Initialize logging mechanism with parsed data */ loc_logger_init(DEBUG_LEVEL, TIMESTAMP); } ================================================ FILE: gps/utils/loc_cfg.h ================================================ /* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef LOC_CFG_H #define LOC_CFG_H #include #include #define LOC_MAX_PARAM_NAME 80 #define LOC_MAX_PARAM_STRING 80 #define LOC_MAX_PARAM_LINE (LOC_MAX_PARAM_NAME + LOC_MAX_PARAM_STRING) #define UTIL_UPDATE_CONF(conf_data, len, config_table) \ loc_update_conf((conf_data), (len), (config_table), \ sizeof(config_table) / sizeof(config_table[0])) #define UTIL_READ_CONF_DEFAULT(filename) \ loc_read_conf((filename), NULL, 0); #define UTIL_READ_CONF(filename, config_table) \ loc_read_conf((filename), (config_table), sizeof(config_table) / sizeof(config_table[0])) /*============================================================================= * * MODULE TYPE DECLARATION * *============================================================================*/ typedef struct { char param_name[LOC_MAX_PARAM_NAME]; void *param_ptr; uint8_t *param_set; /* was this value set by config file? */ char param_type; /* 'n' for number, 's' for string, 'f' for float */ } loc_param_s_type; /*============================================================================= * * MODULE EXTERNAL DATA * *============================================================================*/ #ifdef __cplusplus extern "C" { #endif /*============================================================================= * * MODULE EXPORTED FUNCTIONS * *============================================================================*/ void loc_read_conf(const char* conf_file_name, loc_param_s_type* config_table, uint32_t table_length); int loc_read_conf_r(FILE *conf_fp, loc_param_s_type* config_table, uint32_t table_length); int loc_update_conf(const char* conf_data, int32_t length, loc_param_s_type* config_table, uint32_t table_length); #ifdef __cplusplus } #endif #endif /* LOC_CFG_H */ ================================================ FILE: gps/utils/loc_log.cpp ================================================ /* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #define LOG_NDDEBUG 0 #include #include #include #include "loc_log.h" #include "msg_q.h" #ifdef USE_GLIB #include #endif /* USE_GLIB */ #include "log_util.h" #include "platform_lib_includes.h" #define BUFFER_SIZE 120 // Logging Improvements const char *loc_logger_boolStr[]={"False","True"}; const char VOID_RET[] = "None"; const char FROM_AFW[] = "===>"; const char TO_MODEM[] = "--->"; const char FROM_MODEM[] = "<---"; const char TO_AFW[] = "<==="; const char EXIT_TAG[] = "Exiting"; const char ENTRY_TAG[] = "Entering"; const char EXIT_ERROR_TAG[] = "Exiting with error"; /* Logging Mechanism */ loc_logger_s_type loc_logger; /* Get names from value */ const char* loc_get_name_from_mask(loc_name_val_s_type table[], int table_size, long mask) { int i; for (i = 0; i < table_size; i++) { if (table[i].val & (long) mask) { return table[i].name; } } return UNKNOWN_STR; } /* Get names from value */ const char* loc_get_name_from_val(loc_name_val_s_type table[], int table_size, long value) { int i; for (i = 0; i < table_size; i++) { if (table[i].val == (long) value) { return table[i].name; } } return UNKNOWN_STR; } static loc_name_val_s_type loc_msg_q_status[] = { NAME_VAL( eMSG_Q_SUCCESS ), NAME_VAL( eMSG_Q_FAILURE_GENERAL ), NAME_VAL( eMSG_Q_INVALID_PARAMETER ), NAME_VAL( eMSG_Q_INVALID_HANDLE ), NAME_VAL( eMSG_Q_UNAVAILABLE_RESOURCE ), NAME_VAL( eMSG_Q_INSUFFICIENT_BUFFER ) }; static int loc_msg_q_status_num = sizeof(loc_msg_q_status) / sizeof(loc_name_val_s_type); /* Find msg_q status name */ const char* loc_get_msg_q_status(int status) { return loc_get_name_from_val(loc_msg_q_status, loc_msg_q_status_num, (long) status); } const char* log_succ_fail_string(int is_succ) { return is_succ? "successful" : "failed"; } //Target names loc_name_val_s_type target_name[] = { NAME_VAL(GNSS_NONE), NAME_VAL(GNSS_MSM), NAME_VAL(GNSS_GSS), NAME_VAL(GNSS_MDM), NAME_VAL(GNSS_QCA1530), NAME_VAL(GNSS_AUTO), NAME_VAL(GNSS_UNKNOWN) }; static int target_name_num = sizeof(target_name)/sizeof(loc_name_val_s_type); /*=========================================================================== FUNCTION loc_get_target_name DESCRIPTION Returns pointer to a string that contains name of the target XX:XX:XX.000\0 RETURN VALUE The target name string ===========================================================================*/ const char *loc_get_target_name(unsigned int target) { int index = 0; static char ret[BUFFER_SIZE]; index = getTargetGnssType(target); if( index >= target_name_num || index < 0) index = target_name_num - 1; if( (target & HAS_SSC) == HAS_SSC ) { snprintf(ret, sizeof(ret), " %s with SSC", loc_get_name_from_val(target_name, target_name_num, (long)index) ); } else { snprintf(ret, sizeof(ret), " %s without SSC", loc_get_name_from_val(target_name, target_name_num, (long)index) ); } return ret; } /*=========================================================================== FUNCTION loc_get_time DESCRIPTION Logs a callback event header. The pointer time_string should point to a buffer of at least 13 bytes: XX:XX:XX.000\0 RETURN VALUE The time string ===========================================================================*/ char *loc_get_time(char *time_string, unsigned long buf_size) { struct timeval now; /* sec and usec */ struct tm now_tm; /* broken-down time */ char hms_string[80]; /* HH:MM:SS */ gettimeofday(&now, NULL); localtime_r(&now.tv_sec, &now_tm); strftime(hms_string, sizeof hms_string, "%H:%M:%S", &now_tm); snprintf(time_string, buf_size, "%s.%03d", hms_string, (int) (now.tv_usec / 1000)); return time_string; } /*=========================================================================== FUNCTION loc_logger_init DESCRIPTION Initializes the state of DEBUG_LEVEL and TIMESTAMP DEPENDENCIES N/A RETURN VALUE None SIDE EFFECTS N/A ===========================================================================*/ void loc_logger_init(unsigned long debug, unsigned long timestamp) { loc_logger.DEBUG_LEVEL = debug; #ifdef TARGET_BUILD_VARIANT_USER // force user builds to 2 or less if (loc_logger.DEBUG_LEVEL > 2) { loc_logger.DEBUG_LEVEL = 2; } #endif loc_logger.TIMESTAMP = timestamp; } /*=========================================================================== FUNCTION get_timestamp DESCRIPTION Generates a timestamp using the current system time DEPENDENCIES N/A RETURN VALUE Char pointer to the parameter str SIDE EFFECTS N/A ===========================================================================*/ char * get_timestamp(char *str, unsigned long buf_size) { struct timeval tv; struct timezone tz; int hh, mm, ss; gettimeofday(&tv, &tz); hh = tv.tv_sec/3600%24; mm = (tv.tv_sec%3600)/60; ss = tv.tv_sec%60; snprintf(str, buf_size, "%02d:%02d:%02d.%06ld", hh, mm, ss, tv.tv_usec); return str; } ================================================ FILE: gps/utils/loc_log.h ================================================ /* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef LOC_LOG_H #define LOC_LOG_H #ifdef __cplusplus extern "C" { #endif #include #include "loc_target.h" typedef struct { char name[128]; long val; } loc_name_val_s_type; #define NAME_VAL(x) {"" #x "", x } #define UNKNOWN_STR "UNKNOWN" #define CHECK_MASK(type, value, mask_var, mask) \ ((mask_var & mask) ? (type) value : (type) (-1)) /* Get names from value */ const char* loc_get_name_from_mask(loc_name_val_s_type table[], int table_size, long mask); const char* loc_get_name_from_val(loc_name_val_s_type table[], int table_size, long value); const char* loc_get_msg_q_status(int status); const char* loc_get_target_name(unsigned int target); extern const char* log_succ_fail_string(int is_succ); extern char *loc_get_time(char *time_string, unsigned long buf_size); #ifdef __cplusplus } #endif #endif /* LOC_LOG_H */ ================================================ FILE: gps/utils/loc_misc_utils.cpp ================================================ /* Copyright (c) 2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include #include #include #define LOG_NDDEBUG 0 #define LOG_TAG "LocSvc_misc_utils" int loc_util_split_string(char *raw_string, char **split_strings_ptr, int max_num_substrings, char delimiter) { int raw_string_index=0; int num_split_strings=0; unsigned char end_string=0; int raw_string_length=0; if(!raw_string || !split_strings_ptr) { LOC_LOGE("%s:%d]: NULL parameters", __func__, __LINE__); num_split_strings = -1; goto err; } LOC_LOGD("%s:%d]: raw string: %s\n", __func__, __LINE__, raw_string); raw_string_length = strlen(raw_string) + 1; split_strings_ptr[num_split_strings] = &raw_string[raw_string_index]; for(raw_string_index=0; raw_string_index < raw_string_length; raw_string_index++) { if(raw_string[raw_string_index] == '\0') end_string=1; if((raw_string[raw_string_index] == delimiter) || end_string) { raw_string[raw_string_index] = '\0'; LOC_LOGD("%s:%d]: split string: %s\n", __func__, __LINE__, split_strings_ptr[num_split_strings]); num_split_strings++; if(((raw_string_index + 1) < raw_string_length) && (num_split_strings < max_num_substrings)) { split_strings_ptr[num_split_strings] = &raw_string[raw_string_index+1]; } else { break; } } if(end_string) break; } err: LOC_LOGD("%s:%d]: num_split_strings: %d\n", __func__, __LINE__, num_split_strings); return num_split_strings; } void loc_util_trim_space(char *org_string) { char *scan_ptr, *write_ptr; char *first_nonspace = NULL, *last_nonspace = NULL; if(org_string == NULL) { LOC_LOGE("%s:%d]: NULL parameter", __func__, __LINE__); goto err; } scan_ptr = write_ptr = org_string; while (*scan_ptr) { //Find the first non-space character if ( !isspace(*scan_ptr) && first_nonspace == NULL) { first_nonspace = scan_ptr; } //Once the first non-space character is found in the //above check, keep shifting the characters to the left //to replace the spaces if (first_nonspace != NULL) { *(write_ptr++) = *scan_ptr; //Keep track of which was the last non-space character //encountered //last_nonspace will not be updated in the case where //the string ends with spaces if ( !isspace(*scan_ptr)) { last_nonspace = write_ptr; } } scan_ptr++; } //Add NULL terminator after the last non-space character if (last_nonspace) { *last_nonspace = '\0'; } err: return; } ================================================ FILE: gps/utils/loc_misc_utils.h ================================================ /* Copyright (c) 2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef _LOC_MISC_UTILS_H_ #define _LOC_MISC_UTILS_H_ #ifdef __cplusplus extern "C" { #endif /*=========================================================================== FUNCTION loc_split_string DESCRIPTION: This function is used to split a delimiter separated string into sub-strings. This function does not allocate new memory to store the split strings. Instead, it places '\0' in places of delimiters and assings the starting address of the substring within the raw string as the string address The input raw_string no longer remains to be a collection of sub-strings after this function is executed. Please make a copy of the input string before calling this function if necessary PARAMETERS: char *raw_string: is the original string with delimiter separated substrings char **split_strings_ptr: is the arraw of pointers which will hold the addresses of individual substrings int max_num_substrings: is the maximum number of substrings that are expected by the caller. The array of pointers in the above parameter is usually this long char delimiter: is the delimiter that separates the substrings. Examples: ' ', ';' DEPENDENCIES N/A RETURN VALUE int Number of split strings SIDE EFFECTS The input raw_string no longer remains a delimiter separated single string. EXAMPLE delimiter = ' ' //space raw_string = "hello new user" //delimiter is space ' ' addresses = 0123456789abcd split_strings_ptr[0] = &raw_string[0]; //split_strings_ptr[0] contains "hello" split_strings_ptr[1] = &raw_string[6]; //split_strings_ptr[1] contains "new" split_strings_ptr[2] = &raw_string[a]; //split_strings_ptr[2] contains "user" ===========================================================================*/ int loc_util_split_string(char *raw_string, char **split_strings_ptr, int max_num_substrings, char delimiter); /*=========================================================================== FUNCTION trim_space DESCRIPTION Removes leading and trailing spaces of the string DEPENDENCIES N/A RETURN VALUE None SIDE EFFECTS N/A ===========================================================================*/ void loc_util_trim_space(char *org_string); #ifdef __cplusplus } #endif #endif //_LOC_MISC_UTILS_H_ ================================================ FILE: gps/utils/loc_target.cpp ================================================ /* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include #include #include #include #include #include #include #include "loc_target.h" #include "loc_log.h" #include "log_util.h" #define APQ8064_ID_1 "109" #define APQ8064_ID_2 "153" #define MPQ8064_ID_1 "130" #define MSM8930_ID_1 "142" #define MSM8930_ID_2 "116" #define APQ8030_ID_1 "157" #define APQ8074_ID_1 "184" #define LINE_LEN 100 #define STR_LIQUID "Liquid" #define STR_SURF "Surf" #define STR_MTP "MTP" #define STR_APQ "apq" #define STR_AUTO "auto" #define IS_STR_END(c) ((c) == '\0' || (c) == '\n' || (c) == '\r') #define LENGTH(s) (sizeof(s) - 1) #define GPS_CHECK_NO_ERROR 0 #define GPS_CHECK_NO_GPS_HW 1 /* When system server is started, it uses 20 seconds as ActivityManager * timeout. After that it sends SIGSTOP signal to process. */ #define QCA1530_DETECT_TIMEOUT 15 #define QCA1530_DETECT_PRESENT "yes" #define QCA1530_DETECT_PROGRESS "detect" static unsigned int gTarget = (unsigned int)-1; static int read_a_line(const char * file_path, char * line, int line_size) { FILE *fp; int result = 0; * line = '\0'; fp = fopen(file_path, "r" ); if( fp == NULL ) { LOC_LOGE("open failed: %s: %s\n", file_path, strerror(errno)); result = -1; } else { int len; fgets(line, line_size, fp); len = strlen(line); len = len < line_size - 1? len : line_size - 1; line[len] = '\0'; LOC_LOGD("cat %s: %s", file_path, line); fclose(fp); } return result; } /*! * \brief Checks if QCA1530 is avalable. * * Function verifies if qca1530 SoC is configured on the device. The test is * based on property value. For 1530 scenario, the value shall be one of the * following: "yes", "no", "detect". All other values are treated equally to * "no". When the value is "detect" the system waits for SoC detection to * finish before returning result. * * \retval true - QCA1530 is available. * \retval false - QCA1530 is not available. */ static bool is_qca1530(void) { static const char qca1530_property_name[] = "sys.qca1530"; bool res = false; int ret, i; char buf[PROPERTY_VALUE_MAX]; memset(buf, 0, sizeof(buf)); for (i = 0; i < QCA1530_DETECT_TIMEOUT; ++i) { ret = property_get(qca1530_property_name, buf, NULL); if (ret < 0) { LOC_LOGV( "qca1530: property %s is not accessible, ret=%d", qca1530_property_name, ret); break; } LOC_LOGV( "qca1530: property %s is set to %s", qca1530_property_name, buf); if (!memcmp(buf, QCA1530_DETECT_PRESENT, sizeof(QCA1530_DETECT_PRESENT))) { res = true; break; } if (!memcmp(buf, QCA1530_DETECT_PROGRESS, sizeof(QCA1530_DETECT_PROGRESS))) { LOC_LOGV("qca1530: SoC detection is in progress."); sleep(1); continue; } break; } LOC_LOGD("qca1530: detected=%s", res ? "true" : "false"); return res; } /*The character array passed to this function should have length of atleast PROPERTY_VALUE_MAX*/ void loc_get_target_baseband(char *baseband, int array_length) { if(baseband && (array_length >= PROPERTY_VALUE_MAX)) { property_get("ro.baseband", baseband, ""); LOC_LOGD("%s:%d]: Baseband: %s\n", __func__, __LINE__, baseband); } else { LOC_LOGE("%s:%d]: NULL parameter or array length less than PROPERTY_VALUE_MAX\n", __func__, __LINE__); } } /*The character array passed to this function should have length of atleast PROPERTY_VALUE_MAX*/ void loc_get_platform_name(char *platform_name, int array_length) { if(platform_name && (array_length >= PROPERTY_VALUE_MAX)) { property_get("ro.board.platform", platform_name, ""); LOC_LOGD("%s:%d]: Target name: %s\n", __func__, __LINE__, platform_name); } else { LOC_LOGE("%s:%d]: Null parameter or array length less than PROPERTY_VALUE_MAX\n", __func__, __LINE__); } } unsigned int loc_get_target(void) { if (gTarget != (unsigned int)-1) return gTarget; static const char hw_platform[] = "/sys/devices/soc0/hw_platform"; static const char id[] = "/sys/devices/soc0/soc_id"; static const char hw_platform_dep[] = "/sys/devices/system/soc/soc0/hw_platform"; static const char id_dep[] = "/sys/devices/system/soc/soc0/id"; static const char mdm[] = "/dev/mdm"; // No such file or directory char rd_hw_platform[LINE_LEN]; char rd_id[LINE_LEN]; char rd_mdm[LINE_LEN]; char baseband[LINE_LEN]; if (is_qca1530()) { gTarget = TARGET_QCA1530; goto detected; } loc_get_target_baseband(baseband, sizeof(baseband)); if (!access(hw_platform, F_OK)) { read_a_line(hw_platform, rd_hw_platform, LINE_LEN); } else { read_a_line(hw_platform_dep, rd_hw_platform, LINE_LEN); } if (!access(id, F_OK)) { read_a_line(id, rd_id, LINE_LEN); } else { read_a_line(id_dep, rd_id, LINE_LEN); } if( !memcmp(baseband, STR_AUTO, LENGTH(STR_AUTO)) ) { gTarget = TARGET_AUTO; goto detected; } if( !memcmp(baseband, STR_APQ, LENGTH(STR_APQ)) ){ if( !memcmp(rd_id, MPQ8064_ID_1, LENGTH(MPQ8064_ID_1)) && IS_STR_END(rd_id[LENGTH(MPQ8064_ID_1)]) ) gTarget = TARGET_MPQ; else gTarget = TARGET_APQ_SA; } else { if( (!memcmp(rd_hw_platform, STR_LIQUID, LENGTH(STR_LIQUID)) && IS_STR_END(rd_hw_platform[LENGTH(STR_LIQUID)])) || (!memcmp(rd_hw_platform, STR_SURF, LENGTH(STR_SURF)) && IS_STR_END(rd_hw_platform[LENGTH(STR_SURF)])) || (!memcmp(rd_hw_platform, STR_MTP, LENGTH(STR_MTP)) && IS_STR_END(rd_hw_platform[LENGTH(STR_MTP)]))) { if (!read_a_line( mdm, rd_mdm, LINE_LEN)) gTarget = TARGET_MDM; } else if( (!memcmp(rd_id, MSM8930_ID_1, LENGTH(MSM8930_ID_1)) && IS_STR_END(rd_id[LENGTH(MSM8930_ID_1)])) || (!memcmp(rd_id, MSM8930_ID_2, LENGTH(MSM8930_ID_2)) && IS_STR_END(rd_id[LENGTH(MSM8930_ID_2)])) ) gTarget = TARGET_MSM_NO_SSC; else gTarget = TARGET_UNKNOWN; } detected: LOC_LOGD("HAL: %s returned %d", __FUNCTION__, gTarget); return gTarget; } /*Reads the property ro.lean to identify if this is a lean target Returns: 0 if not a lean and mean target 1 if this is a lean and mean target */ int loc_identify_lean_target() { int ret = 0; char lean_target[PROPERTY_VALUE_MAX]; property_get("ro.lean", lean_target, ""); LOC_LOGD("%s:%d]: lean target: %s\n", __func__, __LINE__, lean_target); return !(strncmp(lean_target, "true", PROPERTY_VALUE_MAX)); } ================================================ FILE: gps/utils/loc_target.h ================================================ /* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef LOC_TARGET_H #define LOC_TARGET_H #define TARGET_SET(gnss,ssc) ( (gnss<<1)|ssc ) #define TARGET_DEFAULT TARGET_SET(GNSS_MSM, HAS_SSC) #define TARGET_MDM TARGET_SET(GNSS_MDM, HAS_SSC) #define TARGET_APQ_SA TARGET_SET(GNSS_GSS, NO_SSC) #define TARGET_MPQ TARGET_SET(GNSS_NONE,NO_SSC) #define TARGET_MSM_NO_SSC TARGET_SET(GNSS_MSM, NO_SSC) #define TARGET_QCA1530 TARGET_SET(GNSS_QCA1530, NO_SSC) #define TARGET_AUTO TARGET_SET(GNSS_AUTO, NO_SSC) #define TARGET_UNKNOWN TARGET_SET(GNSS_UNKNOWN, NO_SSC) #define getTargetGnssType(target) (target>>1) #ifdef __cplusplus extern "C" { #endif unsigned int loc_get_target(void); /*The character array passed to this function should have length of atleast PROPERTY_VALUE_MAX*/ void loc_get_target_baseband(char *baseband, int array_length); /*The character array passed to this function should have length of atleast PROPERTY_VALUE_MAX*/ void loc_get_platform_name(char *platform_name, int array_length); /*Reads the property ro.lean to identify if this is a lean target Returns: 0 if not a lean and mean target 1 if this is a lean and mean target*/ int loc_identify_lean_target(); /* Please remember to update 'target_name' in loc_log.cpp, if do any changes to this enum. */ typedef enum { GNSS_NONE = 0, GNSS_MSM, GNSS_GSS, GNSS_MDM, GNSS_QCA1530, GNSS_AUTO, GNSS_UNKNOWN }GNSS_TARGET; typedef enum { NO_SSC = 0, HAS_SSC }SSC_TYPE; #ifdef __cplusplus } #endif #endif /*LOC_TARGET_H*/ ================================================ FILE: gps/utils/loc_timer.h ================================================ /* Copyright (c) 2013,2015 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef __LOC_DELAY_H__ #define __LOC_DELAY_H__ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #include /* user_data: client context pointer, passthrough. Originally received from calling client when loc_timer_start() is called. result: 0 if timer successfully timed out; else timer failed. */ typedef void (*loc_timer_callback)(void *user_data, int32_t result); /* delay_msec: timeout value for the timer. cb_func: callback function pointer, implemented by client. Can not be NULL. user_data: client context pointer, passthrough. Will be returned when loc_timer_callback() is called. wakeOnExpire: true if to wake up CPU (if sleeping) upon timer expiration and notify the client. false if to wait until next time CPU wakes up (if sleeping) and then notify the client. Returns the handle, which can be used to stop the timer NULL, if timer start fails (e.g. if cb_func is NULL). */ void* loc_timer_start(uint64_t delay_msec, loc_timer_callback cb_func, void *user_data, bool wake_on_expire=false); /* handle becomes invalid upon the return of the callback */ void loc_timer_stop(void*& handle); #ifdef __cplusplus } #endif /* __cplusplus */ #endif //__LOC_DELAY_H__ ================================================ FILE: gps/utils/log_util.h ================================================ /* Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef __LOG_UTIL_H__ #define __LOG_UTIL_H__ #ifndef USE_GLIB #include #endif /* USE_GLIB */ #ifdef USE_GLIB #include #include #include #ifndef LOG_TAG #define LOG_TAG "GPS_UTILS" #endif // LOG_TAG #endif /* USE_GLIB */ #ifdef __cplusplus extern "C" { #endif /*============================================================================= * * LOC LOGGER TYPE DECLARATION * *============================================================================*/ /* LOC LOGGER */ typedef struct loc_logger_s { unsigned long DEBUG_LEVEL; unsigned long TIMESTAMP; } loc_logger_s_type; /*============================================================================= * * EXTERNAL DATA * *============================================================================*/ extern loc_logger_s_type loc_logger; // Logging Improvements extern const char *loc_logger_boolStr[]; extern const char *boolStr[]; extern const char VOID_RET[]; extern const char FROM_AFW[]; extern const char TO_MODEM[]; extern const char FROM_MODEM[]; extern const char TO_AFW[]; extern const char EXIT_TAG[]; extern const char ENTRY_TAG[]; extern const char EXIT_ERROR_TAG[]; /*============================================================================= * * MODULE EXPORTED FUNCTIONS * *============================================================================*/ extern void loc_logger_init(unsigned long debug, unsigned long timestamp); extern char* get_timestamp(char* str, unsigned long buf_size); #ifndef DEBUG_DMN_LOC_API /* LOGGING MACROS */ /*loc_logger.DEBUG_LEVEL is initialized to 0xff in loc_cfg.cpp if that value remains unchanged, it means gps.conf did not provide a value and we default to the initial value to use Android's logging levels*/ #define IF_LOC_LOGE if((loc_logger.DEBUG_LEVEL >= 1) && (loc_logger.DEBUG_LEVEL <= 5)) #define IF_LOC_LOGW if((loc_logger.DEBUG_LEVEL >= 2) && (loc_logger.DEBUG_LEVEL <= 5)) #define IF_LOC_LOGI if((loc_logger.DEBUG_LEVEL >= 3) && (loc_logger.DEBUG_LEVEL <= 5)) #define IF_LOC_LOGD if((loc_logger.DEBUG_LEVEL >= 4) && (loc_logger.DEBUG_LEVEL <= 5)) #define IF_LOC_LOGV if((loc_logger.DEBUG_LEVEL >= 5) && (loc_logger.DEBUG_LEVEL <= 5)) #define LOC_LOGE(...) \ IF_LOC_LOGE { ALOGE("E/" __VA_ARGS__); } \ else if (loc_logger.DEBUG_LEVEL == 0xff) { ALOGE("E/" __VA_ARGS__); } #define LOC_LOGW(...) \ IF_LOC_LOGW { ALOGE("W/" __VA_ARGS__); } \ else if (loc_logger.DEBUG_LEVEL == 0xff) { ALOGW("W/" __VA_ARGS__); } #define LOC_LOGI(...) \ IF_LOC_LOGI { ALOGE("I/" __VA_ARGS__); } \ else if (loc_logger.DEBUG_LEVEL == 0xff) { ALOGI("I/" __VA_ARGS__); } #define LOC_LOGD(...) \ IF_LOC_LOGD { ALOGE("D/" __VA_ARGS__); } \ else if (loc_logger.DEBUG_LEVEL == 0xff) { ALOGD("D/" __VA_ARGS__); } #define LOC_LOGV(...) \ IF_LOC_LOGV { ALOGE("V/" __VA_ARGS__); } \ else if (loc_logger.DEBUG_LEVEL == 0xff) { ALOGV("V/" __VA_ARGS__); } #else /* DEBUG_DMN_LOC_API */ #define LOC_LOGE(...) ALOGE("E/" __VA_ARGS__) #define LOC_LOGW(...) ALOGW("W/" __VA_ARGS__) #define LOC_LOGI(...) ALOGI("I/" __VA_ARGS__) #define LOC_LOGD(...) ALOGD("D/" __VA_ARGS__) #define LOC_LOGV(...) ALOGV("V/" __VA_ARGS__) #endif /* DEBUG_DMN_LOC_API */ /*============================================================================= * * LOGGING IMPROVEMENT MACROS * *============================================================================*/ #define LOG_(LOC_LOG, ID, WHAT, SPEC, VAL) \ do { \ if (loc_logger.TIMESTAMP) { \ char ts[32]; \ LOC_LOG("[%s] %s %s line %d " #SPEC, \ get_timestamp(ts, sizeof(ts)), ID, WHAT, __LINE__, VAL); \ } else { \ LOC_LOG("%s %s line %d " #SPEC, \ ID, WHAT, __LINE__, VAL); \ } \ } while(0) #define LOG_I(ID, WHAT, SPEC, VAL) LOG_(LOC_LOGI, ID, WHAT, SPEC, VAL) #define LOG_V(ID, WHAT, SPEC, VAL) LOG_(LOC_LOGV, ID, WHAT, SPEC, VAL) #define LOG_E(ID, WHAT, SPEC, VAL) LOG_(LOC_LOGE, ID, WHAT, SPEC, VAL) #define ENTRY_LOG() LOG_V(ENTRY_TAG, __func__, %s, "") #define EXIT_LOG(SPEC, VAL) LOG_V(EXIT_TAG, __func__, SPEC, VAL) #define EXIT_LOG_WITH_ERROR(SPEC, VAL) \ if (VAL != 0) { \ LOG_E(EXIT_ERROR_TAG, __func__, SPEC, VAL); \ } else { \ LOG_V(EXIT_TAG, __func__, SPEC, VAL); \ } // Used for logging callflow from Android Framework #define ENTRY_LOG_CALLFLOW() LOG_I(FROM_AFW, __func__, %s, "") // Used for logging callflow to Modem #define EXIT_LOG_CALLFLOW(SPEC, VAL) LOG_I(TO_MODEM, __func__, SPEC, VAL) // Used for logging callflow from Modem(TO_MODEM, __func__, %s, "") #define MODEM_LOG_CALLFLOW(SPEC, VAL) LOG_I(FROM_MODEM, __func__, SPEC, VAL) // Used for logging callflow to Android Framework #define CALLBACK_LOG_CALLFLOW(CB, SPEC, VAL) LOG_I(TO_AFW, CB, SPEC, VAL) #ifdef __cplusplus } #endif #endif // __LOG_UTIL_H__ ================================================ FILE: gps/utils/msg_q.c ================================================ /* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "msg_q.h" #define LOG_TAG "LocSvc_utils_q" #include "log_util.h" #include "platform_lib_includes.h" #include "linked_list.h" #include #include #include typedef struct msg_q { void* msg_list; /* Linked list to store information */ pthread_cond_t list_cond; /* Condition variable for waiting on msg queue */ pthread_mutex_t list_mutex; /* Mutex for exclusive access to message queue */ int unblocked; /* Has this message queue been unblocked? */ } msg_q; /*=========================================================================== FUNCTION convert_linked_list_err_type DESCRIPTION Converts from one set of enum values to another. linked_list_val: Value to convert to msg_q_enum_type DEPENDENCIES N/A RETURN VALUE Corresponding linked_list_enum_type in msg_q_enum_type SIDE EFFECTS N/A ===========================================================================*/ static msq_q_err_type convert_linked_list_err_type(linked_list_err_type linked_list_val) { switch( linked_list_val ) { case eLINKED_LIST_SUCCESS: return eMSG_Q_SUCCESS; case eLINKED_LIST_INVALID_PARAMETER: return eMSG_Q_INVALID_PARAMETER; case eLINKED_LIST_INVALID_HANDLE: return eMSG_Q_INVALID_HANDLE; case eLINKED_LIST_UNAVAILABLE_RESOURCE: return eMSG_Q_UNAVAILABLE_RESOURCE; case eLINKED_LIST_INSUFFICIENT_BUFFER: return eMSG_Q_INSUFFICIENT_BUFFER; case eLINKED_LIST_FAILURE_GENERAL: default: return eMSG_Q_FAILURE_GENERAL; } } /* ----------------------- END INTERNAL FUNCTIONS ---------------------------------------- */ /*=========================================================================== FUNCTION: msg_q_init ===========================================================================*/ msq_q_err_type msg_q_init(void** msg_q_data) { if( msg_q_data == NULL ) { LOC_LOGE("%s: Invalid msg_q_data parameter!\n", __FUNCTION__); return eMSG_Q_INVALID_PARAMETER; } msg_q* tmp_msg_q; tmp_msg_q = (msg_q*)calloc(1, sizeof(msg_q)); if( tmp_msg_q == NULL ) { LOC_LOGE("%s: Unable to allocate space for message queue!\n", __FUNCTION__); return eMSG_Q_FAILURE_GENERAL; } if( linked_list_init(&tmp_msg_q->msg_list) != 0 ) { LOC_LOGE("%s: Unable to initialize storage list!\n", __FUNCTION__); free(tmp_msg_q); return eMSG_Q_FAILURE_GENERAL; } if( pthread_mutex_init(&tmp_msg_q->list_mutex, NULL) != 0 ) { LOC_LOGE("%s: Unable to initialize list mutex!\n", __FUNCTION__); linked_list_destroy(&tmp_msg_q->msg_list); free(tmp_msg_q); return eMSG_Q_FAILURE_GENERAL; } if( pthread_cond_init(&tmp_msg_q->list_cond, NULL) != 0 ) { LOC_LOGE("%s: Unable to initialize msg q cond var!\n", __FUNCTION__); linked_list_destroy(&tmp_msg_q->msg_list); pthread_mutex_destroy(&tmp_msg_q->list_mutex); free(tmp_msg_q); return eMSG_Q_FAILURE_GENERAL; } tmp_msg_q->unblocked = 0; *msg_q_data = tmp_msg_q; return eMSG_Q_SUCCESS; } /*=========================================================================== FUNCTION: msg_q_init2 ===========================================================================*/ const void* msg_q_init2() { void* q = NULL; if (eMSG_Q_SUCCESS != msg_q_init(&q)) { q = NULL; } return q; } /*=========================================================================== FUNCTION: msg_q_destroy ===========================================================================*/ msq_q_err_type msg_q_destroy(void** msg_q_data) { if( msg_q_data == NULL ) { LOC_LOGE("%s: Invalid msg_q_data parameter!\n", __FUNCTION__); return eMSG_Q_INVALID_HANDLE; } msg_q* p_msg_q = (msg_q*)*msg_q_data; linked_list_destroy(&p_msg_q->msg_list); pthread_mutex_destroy(&p_msg_q->list_mutex); pthread_cond_destroy(&p_msg_q->list_cond); p_msg_q->unblocked = 0; free(*msg_q_data); *msg_q_data = NULL; return eMSG_Q_SUCCESS; } /*=========================================================================== FUNCTION: msg_q_snd ===========================================================================*/ msq_q_err_type msg_q_snd(void* msg_q_data, void* msg_obj, void (*dealloc)(void*)) { msq_q_err_type rv; if( msg_q_data == NULL ) { LOC_LOGE("%s: Invalid msg_q_data parameter!\n", __FUNCTION__); return eMSG_Q_INVALID_HANDLE; } if( msg_obj == NULL ) { LOC_LOGE("%s: Invalid msg_obj parameter!\n", __FUNCTION__); return eMSG_Q_INVALID_PARAMETER; } msg_q* p_msg_q = (msg_q*)msg_q_data; pthread_mutex_lock(&p_msg_q->list_mutex); LOC_LOGD("%s: Sending message with handle = 0x%08X\n", __FUNCTION__, msg_obj); if( p_msg_q->unblocked ) { LOC_LOGE("%s: Message queue has been unblocked.\n", __FUNCTION__); pthread_mutex_unlock(&p_msg_q->list_mutex); return eMSG_Q_UNAVAILABLE_RESOURCE; } rv = convert_linked_list_err_type(linked_list_add(p_msg_q->msg_list, msg_obj, dealloc)); /* Show data is in the message queue. */ pthread_cond_signal(&p_msg_q->list_cond); pthread_mutex_unlock(&p_msg_q->list_mutex); LOC_LOGD("%s: Finished Sending message with handle = 0x%08X\n", __FUNCTION__, msg_obj); return rv; } /*=========================================================================== FUNCTION: msg_q_rcv ===========================================================================*/ msq_q_err_type msg_q_rcv(void* msg_q_data, void** msg_obj) { msq_q_err_type rv; if( msg_q_data == NULL ) { LOC_LOGE("%s: Invalid msg_q_data parameter!\n", __FUNCTION__); return eMSG_Q_INVALID_HANDLE; } if( msg_obj == NULL ) { LOC_LOGE("%s: Invalid msg_obj parameter!\n", __FUNCTION__); return eMSG_Q_INVALID_PARAMETER; } msg_q* p_msg_q = (msg_q*)msg_q_data; LOC_LOGD("%s: Waiting on message\n", __FUNCTION__); pthread_mutex_lock(&p_msg_q->list_mutex); if( p_msg_q->unblocked ) { LOC_LOGE("%s: Message queue has been unblocked.\n", __FUNCTION__); pthread_mutex_unlock(&p_msg_q->list_mutex); return eMSG_Q_UNAVAILABLE_RESOURCE; } /* Wait for data in the message queue */ while( linked_list_empty(p_msg_q->msg_list) && !p_msg_q->unblocked ) { pthread_cond_wait(&p_msg_q->list_cond, &p_msg_q->list_mutex); } rv = convert_linked_list_err_type(linked_list_remove(p_msg_q->msg_list, msg_obj)); pthread_mutex_unlock(&p_msg_q->list_mutex); LOC_LOGD("%s: Received message 0x%08X rv = %d\n", __FUNCTION__, *msg_obj, rv); return rv; } /*=========================================================================== FUNCTION: msg_q_flush ===========================================================================*/ msq_q_err_type msg_q_flush(void* msg_q_data) { msq_q_err_type rv; if ( msg_q_data == NULL ) { LOC_LOGE("%s: Invalid msg_q_data parameter!\n", __FUNCTION__); return eMSG_Q_INVALID_HANDLE; } msg_q* p_msg_q = (msg_q*)msg_q_data; LOC_LOGD("%s: Flushing Message Queue\n", __FUNCTION__); pthread_mutex_lock(&p_msg_q->list_mutex); /* Remove all elements from the list */ rv = convert_linked_list_err_type(linked_list_flush(p_msg_q->msg_list)); pthread_mutex_unlock(&p_msg_q->list_mutex); LOC_LOGD("%s: Message Queue flushed\n", __FUNCTION__); return rv; } /*=========================================================================== FUNCTION: msg_q_unblock ===========================================================================*/ msq_q_err_type msg_q_unblock(void* msg_q_data) { if ( msg_q_data == NULL ) { LOC_LOGE("%s: Invalid msg_q_data parameter!\n", __FUNCTION__); return eMSG_Q_INVALID_HANDLE; } msg_q* p_msg_q = (msg_q*)msg_q_data; pthread_mutex_lock(&p_msg_q->list_mutex); if( p_msg_q->unblocked ) { LOC_LOGE("%s: Message queue has been unblocked.\n", __FUNCTION__); pthread_mutex_unlock(&p_msg_q->list_mutex); return eMSG_Q_UNAVAILABLE_RESOURCE; } LOC_LOGD("%s: Unblocking Message Queue\n", __FUNCTION__); /* Unblocking message queue */ p_msg_q->unblocked = 1; /* Allow all the waiters to wake up */ pthread_cond_broadcast(&p_msg_q->list_cond); pthread_mutex_unlock(&p_msg_q->list_mutex); LOC_LOGD("%s: Message Queue unblocked\n", __FUNCTION__); return eMSG_Q_SUCCESS; } ================================================ FILE: gps/utils/msg_q.h ================================================ /* Copyright (c) 2011, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __MSG_Q_H__ #define __MSG_Q_H__ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #include /** Linked List Return Codes */ typedef enum { eMSG_Q_SUCCESS = 0, /**< Request was successful. */ eMSG_Q_FAILURE_GENERAL = -1, /**< Failed because of a general failure. */ eMSG_Q_INVALID_PARAMETER = -2, /**< Failed because the request contained invalid parameters. */ eMSG_Q_INVALID_HANDLE = -3, /**< Failed because an invalid handle was specified. */ eMSG_Q_UNAVAILABLE_RESOURCE = -4, /**< Failed because an there were not enough resources. */ eMSG_Q_INSUFFICIENT_BUFFER = -5, /**< Failed because an the supplied buffer was too small. */ }msq_q_err_type; /*=========================================================================== FUNCTION msg_q_init DESCRIPTION Initializes internal structures for message queue. msg_q_data: pointer to an opaque Q handle to be returned; NULL if fails DEPENDENCIES N/A RETURN VALUE Look at error codes above. SIDE EFFECTS N/A ===========================================================================*/ msq_q_err_type msg_q_init(void** msg_q_data); /*=========================================================================== FUNCTION msg_q_init2 DESCRIPTION Initializes internal structures for message queue. DEPENDENCIES N/A RETURN VALUE opaque handle to the Q created; NULL if create fails SIDE EFFECTS N/A ===========================================================================*/ const void* msg_q_init2(); /*=========================================================================== FUNCTION msg_q_destroy DESCRIPTION Releases internal structures for message queue. msg_q_data: State of message queue to be released. DEPENDENCIES N/A RETURN VALUE Look at error codes above. SIDE EFFECTS N/A ===========================================================================*/ msq_q_err_type msg_q_destroy(void** msg_q_data); /*=========================================================================== FUNCTION msg_q_snd DESCRIPTION Sends data to the message queue. The passed in data pointer is not modified or freed. Passed in msg_obj is expected to live throughout the use of the msg_q (i.e. data is not allocated internally) msg_q_data: Message Queue to add the element to. msgp: Pointer to data to add into message queue. dealloc: Function used to deallocate memory for this element. Pass NULL if you do not want data deallocated during a flush operation DEPENDENCIES N/A RETURN VALUE Look at error codes above. SIDE EFFECTS N/A ===========================================================================*/ msq_q_err_type msg_q_snd(void* msg_q_data, void* msg_obj, void (*dealloc)(void*)); /*=========================================================================== FUNCTION msg_q_rcv DESCRIPTION Retrieves data from the message queue. msg_obj is the oldest message received and pointer is simply removed from message queue. msg_q_data: Message Queue to copy data from into msgp. msg_obj: Pointer to space to copy msg_q contents to. DEPENDENCIES N/A RETURN VALUE Look at error codes above. SIDE EFFECTS N/A ===========================================================================*/ msq_q_err_type msg_q_rcv(void* msg_q_data, void** msg_obj); /*=========================================================================== FUNCTION msg_q_flush DESCRIPTION Function removes all elements from the message queue. msg_q_data: Message Queue to remove elements from. DEPENDENCIES N/A RETURN VALUE Look at error codes above. SIDE EFFECTS N/A ===========================================================================*/ msq_q_err_type msg_q_flush(void* msg_q_data); /*=========================================================================== FUNCTION msg_q_unblock DESCRIPTION This function will stop use of the message queue. All waiters will wake up and likely receive nothing from the queue resulting in a negative return value. The message queue can no longer be used until it is destroyed and initialized again after calling this function. msg_q_data: Message queue to unblock. DEPENDENCIES N/A RETURN VALUE Look at error codes above. SIDE EFFECTS N/A ===========================================================================*/ msq_q_err_type msg_q_unblock(void* msg_q_data); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* __MSG_Q_H__ */ ================================================ FILE: gps/utils/platform_lib_abstractions/elapsed_millis_since_boot.cpp ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include "platform_lib_time.h" int64_t systemTime(int clock) { struct timeval t; t.tv_sec = t.tv_usec = 0; gettimeofday(&t, NULL); return t.tv_sec*1000000LL + t.tv_usec; } int64_t elapsedMillisSinceBoot() { int64_t t_us = systemTime(0); return (int64_t) t_us / 1000LL; } ================================================ FILE: gps/utils/platform_lib_abstractions/platform_lib_includes.h ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _PLATFORM_LIB_INCLUDES_H_ #define _PLATFORM_LIB_INCLUDES_H_ #include "platform_lib_time.h" #include "platform_lib_macros.h" #endif ================================================ FILE: gps/utils/platform_lib_abstractions/platform_lib_macros.h ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __PLATFORM_LIB_MACROS_H__ #define __PLATFORM_LIB_MACROS_H__ #include #define TS_PRINTF(format, x...) \ { \ struct timeval tv; \ struct timezone tz; \ int hh, mm, ss; \ gettimeofday(&tv, &tz); \ hh = tv.tv_sec/3600%24; \ mm = (tv.tv_sec%3600)/60; \ ss = tv.tv_sec%60; \ fprintf(stdout,"%02d:%02d:%02d.%06ld]" format "\n", hh, mm, ss, tv.tv_usec,##x); \ } #ifdef USE_GLIB #define strlcat g_strlcat #define strlcpy g_strlcpy #define ALOGE(format, x...) TS_PRINTF("E/%s (%d): " format , LOG_TAG, getpid(), ##x) #define ALOGW(format, x...) TS_PRINTF("W/%s (%d): " format , LOG_TAG, getpid(), ##x) #define ALOGI(format, x...) TS_PRINTF("I/%s (%d): " format , LOG_TAG, getpid(), ##x) #define ALOGD(format, x...) TS_PRINTF("D/%s (%d): " format , LOG_TAG, getpid(), ##x) #define ALOGV(format, x...) TS_PRINTF("V/%s (%d): " format , LOG_TAG, getpid(), ##x) #define GETTID_PLATFORM_LIB_ABSTRACTION (syscall(SYS_gettid)) #define LOC_EXT_CREATE_THREAD_CB_PLATFORM_LIB_ABSTRACTION createPthread #define ELAPSED_MILLIS_SINCE_BOOT_PLATFORM_LIB_ABSTRACTION (elapsedMillisSinceBoot()) #else #ifdef __cplusplus extern "C" { #endif pid_t gettid(void); #ifdef __cplusplus } #endif #define GETTID_PLATFORM_LIB_ABSTRACTION (gettid()) #define LOC_EXT_CREATE_THREAD_CB_PLATFORM_LIB_ABSTRACTION android::AndroidRuntime::createJavaThread #define ELAPSED_MILLIS_SINCE_BOOT_PLATFORM_LIB_ABSTRACTION (android::elapsedRealtime()) #endif #endif ================================================ FILE: gps/utils/platform_lib_abstractions/platform_lib_time.h ================================================ /* Copyright (c) 2013, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _PLATFORM_LIB_TIME_H_ #define _PLATFORM_LIB_TIME_H_ int64_t systemTime(int clock); int64_t elapsedMillisSinceBoot(); #endif ================================================ FILE: include/camera/CameraParametersExtra.h ================================================ /* * Copyright (C) 2016 The CyanogenMod Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define CAMERA_PARAMETERS_EXTRA_C \ const char CameraParameters::KEY_APP_MASK[] = "app-mask"; #define CAMERA_PARAMETERS_EXTRA_H \ static const char KEY_APP_MASK[]; ================================================ FILE: include/telephony/ril.h ================================================ /* * Copyright (C) 2006 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_RIL_H #define ANDROID_RIL_H 1 #include #include #include #include #include #ifndef FEATURE_UNIT_TEST #include #endif /* !FEATURE_UNIT_TEST */ #ifdef __cplusplus extern "C" { #endif #if defined(ANDROID_SIM_COUNT_2) #define SIM_COUNT 2 #elif defined(ANDROID_SIM_COUNT_3) #define SIM_COUNT 3 #elif defined(ANDROID_SIM_COUNT_4) #define SIM_COUNT 4 #else #define SIM_COUNT 1 #endif #ifndef ANDROID_MULTI_SIM #define SIM_COUNT 1 #endif /* * RIL version. * Value of RIL_VERSION should not be changed in future. Here onwards, * when a new change is supposed to be introduced which could involve new * schemes added like Wakelocks, data structures added/updated, etc, we would * just document RIL version associated with that change below. When OEM updates its * RIL with those changes, they would return that new RIL version during RIL_REGISTER. * We should make use of the returned version by vendor to identify appropriate scheme * or data structure version to use. * * Documentation of RIL version and associated changes * RIL_VERSION = 12 : This version corresponds to updated data structures namely * RIL_Data_Call_Response_v11, RIL_SIM_IO_v6, RIL_CardStatus_v6, * RIL_SimRefreshResponse_v7, RIL_CDMA_CallWaiting_v6, * RIL_LTE_SignalStrength_v8, RIL_SignalStrength_v10, RIL_CellIdentityGsm_v12 * RIL_CellIdentityWcdma_v12, RIL_CellIdentityLte_v12,RIL_CellInfoGsm_v12, * RIL_CellInfoWcdma_v12, RIL_CellInfoLte_v12, RIL_CellInfo_v12. * * RIL_VERSION = 13 : This version includes new wakelock semantics and as the first * strongly versioned version it enforces structure use. * RIL_VERSION = 14 : New data structures are added, namely RIL_CarrierMatchType, * RIL_Carrier, RIL_CarrierRestrictions and RIL_PCO_Data. * New commands added: RIL_REQUEST_SET_CARRIER_RESTRICTIONS, * RIL_REQUEST_SET_CARRIER_RESTRICTIONS and * RIL_UNSOL_PCO_DATA */ #if defined(USE_RIL_VERSION_10) #define RIL_VERSION 10 #define LAST_IMPRECISE_RIL_VERSION 10 #elif defined(USE_RIL_VERSION_11) #define RIL_VERSION 11 #define LAST_IMPRECISE_RIL_VERSION 11 #else #define RIL_VERSION 12 #define LAST_IMPRECISE_RIL_VERSION 12 // Better self-documented name #endif #define RIL_VERSION_MIN 6 /* Minimum RIL_VERSION supported */ #define CDMA_ALPHA_INFO_BUFFER_LENGTH 64 #define CDMA_NUMBER_INFO_BUFFER_LENGTH 81 #define MAX_RILDS 3 #define MAX_SOCKET_NAME_LENGTH 6 #define MAX_CLIENT_ID_LENGTH 2 #define MAX_DEBUG_SOCKET_NAME_LENGTH 12 #define MAX_QEMU_PIPE_NAME_LENGTH 11 #define MAX_UUID_LENGTH 64 typedef void * RIL_Token; typedef enum { RIL_SOCKET_1, #if (SIM_COUNT >= 2) RIL_SOCKET_2, #if (SIM_COUNT >= 3) RIL_SOCKET_3, #endif #if (SIM_COUNT >= 4) RIL_SOCKET_4, #endif #endif RIL_SOCKET_NUM } RIL_SOCKET_ID; typedef enum { RIL_E_SUCCESS = 0, RIL_E_RADIO_NOT_AVAILABLE = 1, /* If radio did not start or is resetting */ RIL_E_GENERIC_FAILURE = 2, RIL_E_PASSWORD_INCORRECT = 3, /* for PIN/PIN2 methods only! */ RIL_E_SIM_PIN2 = 4, /* Operation requires SIM PIN2 to be entered */ RIL_E_SIM_PUK2 = 5, /* Operation requires SIM PIN2 to be entered */ RIL_E_REQUEST_NOT_SUPPORTED = 6, RIL_E_CANCELLED = 7, RIL_E_OP_NOT_ALLOWED_DURING_VOICE_CALL = 8, /* data ops are not allowed during voice call on a Class C GPRS device */ RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW = 9, /* data ops are not allowed before device registers in network */ RIL_E_SMS_SEND_FAIL_RETRY = 10, /* fail to send sms and need retry */ RIL_E_SIM_ABSENT = 11, /* fail to set the location where CDMA subscription shall be retrieved because of SIM or RUIM card absent */ RIL_E_SUBSCRIPTION_NOT_AVAILABLE = 12, /* fail to find CDMA subscription from specified location */ RIL_E_MODE_NOT_SUPPORTED = 13, /* HW does not support preferred network type */ RIL_E_FDN_CHECK_FAILURE = 14, /* command failed because recipient is not on FDN list */ RIL_E_ILLEGAL_SIM_OR_ME = 15, /* network selection failed due to illegal SIM or ME */ RIL_E_MISSING_RESOURCE = 16, /* no logical channel available */ RIL_E_NO_SUCH_ELEMENT = 17, /* application not found on SIM */ RIL_E_DIAL_MODIFIED_TO_USSD = 18, /* DIAL request modified to USSD */ RIL_E_DIAL_MODIFIED_TO_SS = 19, /* DIAL request modified to SS */ RIL_E_DIAL_MODIFIED_TO_DIAL = 20, /* DIAL request modified to DIAL with different data */ RIL_E_USSD_MODIFIED_TO_DIAL = 21, /* USSD request modified to DIAL */ RIL_E_USSD_MODIFIED_TO_SS = 22, /* USSD request modified to SS */ RIL_E_USSD_MODIFIED_TO_USSD = 23, /* USSD request modified to different USSD request */ RIL_E_SS_MODIFIED_TO_DIAL = 24, /* SS request modified to DIAL */ RIL_E_SS_MODIFIED_TO_USSD = 25, /* SS request modified to USSD */ RIL_E_SUBSCRIPTION_NOT_SUPPORTED = 26, /* Subscription not supported by RIL */ RIL_E_SS_MODIFIED_TO_SS = 27, /* SS request modified to different SS request */ RIL_E_LCE_NOT_SUPPORTED = 36, /* LCE service not supported(36 in RILConstants.java) */ RIL_E_NO_MEMORY = 37, /* Not sufficient memory to process the request */ RIL_E_INTERNAL_ERR = 38, /* Hit unexpected vendor internal error scenario */ RIL_E_SYSTEM_ERR = 39, /* Hit platform or system error */ RIL_E_MODEM_ERR = 40, /* Hit unexpected modem error */ RIL_E_INVALID_STATE = 41, /* Unexpected request for the current state */ RIL_E_NO_RESOURCES = 42, /* Not sufficient resource to process the request */ RIL_E_SIM_ERR = 43, /* Received error from SIM card */ RIL_E_INVALID_ARGUMENTS = 44, /* Received invalid arguments in request */ RIL_E_INVALID_SIM_STATE = 45, /* Can not process the request in current SIM state */ RIL_E_INVALID_MODEM_STATE = 46, /* Can not process the request in current Modem state */ RIL_E_INVALID_CALL_ID = 47, /* Received invalid call id in request */ RIL_E_NO_SMS_TO_ACK = 48, /* ACK received when there is no SMS to ack */ RIL_E_NETWORK_ERR = 49, /* Received error from network */ RIL_E_REQUEST_RATE_LIMITED = 50, /* Operation denied due to overly-frequent requests */ RIL_E_SIM_BUSY = 51, /* SIM is busy */ RIL_E_SIM_FULL = 52, /* The target EF is full */ RIL_E_NETWORK_REJECT = 53, /* Request is rejected by network */ RIL_E_OPERATION_NOT_ALLOWED = 54, /* Not allowed the request now */ RIL_E_EMPTY_RECORD = 55, /* The request record is empty */ RIL_E_INVALID_SMS_FORMAT = 56, /* Invalid sms format */ RIL_E_ENCODING_ERR = 57, /* Message not encoded properly */ RIL_E_INVALID_SMSC_ADDRESS = 58, /* SMSC address specified is invalid */ RIL_E_NO_SUCH_ENTRY = 59, /* No such entry present to perform the request */ RIL_E_NETWORK_NOT_READY = 60, /* Network is not ready to perform the request */ RIL_E_NOT_PROVISIONED = 61, /* Device doesnot have this value provisioned */ RIL_E_NO_SUBSCRIPTION = 62, /* Device doesnot have subscription */ RIL_E_NO_NETWORK_FOUND = 63, /* Network cannot be found */ RIL_E_DEVICE_IN_USE = 64, /* Operation cannot be performed because the device is currently in use */ RIL_E_ABORTED = 65, /* Operation aborted */ // OEM specific error codes. To be used by OEM when they don't want to reveal // specific error codes which would be replaced by Generic failure. RIL_E_OEM_ERROR_1 = 501, RIL_E_OEM_ERROR_2 = 502, RIL_E_OEM_ERROR_3 = 503, RIL_E_OEM_ERROR_4 = 504, RIL_E_OEM_ERROR_5 = 505, RIL_E_OEM_ERROR_6 = 506, RIL_E_OEM_ERROR_7 = 507, RIL_E_OEM_ERROR_8 = 508, RIL_E_OEM_ERROR_9 = 509, RIL_E_OEM_ERROR_10 = 510, RIL_E_OEM_ERROR_11 = 511, RIL_E_OEM_ERROR_12 = 512, RIL_E_OEM_ERROR_13 = 513, RIL_E_OEM_ERROR_14 = 514, RIL_E_OEM_ERROR_15 = 515, RIL_E_OEM_ERROR_16 = 516, RIL_E_OEM_ERROR_17 = 517, RIL_E_OEM_ERROR_18 = 518, RIL_E_OEM_ERROR_19 = 519, RIL_E_OEM_ERROR_20 = 520, RIL_E_OEM_ERROR_21 = 521, RIL_E_OEM_ERROR_22 = 522, RIL_E_OEM_ERROR_23 = 523, RIL_E_OEM_ERROR_24 = 524, RIL_E_OEM_ERROR_25 = 525 } RIL_Errno; typedef enum { RIL_CALL_ACTIVE = 0, RIL_CALL_HOLDING = 1, RIL_CALL_DIALING = 2, /* MO call only */ RIL_CALL_ALERTING = 3, /* MO call only */ RIL_CALL_INCOMING = 4, /* MT call only */ RIL_CALL_WAITING = 5 /* MT call only */ } RIL_CallState; typedef enum { RADIO_STATE_OFF = 0, /* Radio explictly powered off (eg CFUN=0) */ RADIO_STATE_UNAVAILABLE = 1, /* Radio unavailable (eg, resetting or not booted) */ /* States 2-9 below are deprecated. Just leaving them here for backward compatibility. */ RADIO_STATE_SIM_NOT_READY = 2, /* Radio is on, but the SIM interface is not ready */ RADIO_STATE_SIM_LOCKED_OR_ABSENT = 3, /* SIM PIN locked, PUK required, network personalization locked, or SIM absent */ RADIO_STATE_SIM_READY = 4, /* Radio is on and SIM interface is available */ RADIO_STATE_RUIM_NOT_READY = 5, /* Radio is on, but the RUIM interface is not ready */ RADIO_STATE_RUIM_READY = 6, /* Radio is on and the RUIM interface is available */ RADIO_STATE_RUIM_LOCKED_OR_ABSENT = 7, /* RUIM PIN locked, PUK required, network personalization locked, or RUIM absent */ RADIO_STATE_NV_NOT_READY = 8, /* Radio is on, but the NV interface is not available */ RADIO_STATE_NV_READY = 9, /* Radio is on and the NV interface is available */ RADIO_STATE_ON = 10 /* Radio is on */ } RIL_RadioState; typedef enum { RADIO_TECH_UNKNOWN = 0, RADIO_TECH_GPRS = 1, RADIO_TECH_EDGE = 2, RADIO_TECH_UMTS = 3, RADIO_TECH_IS95A = 4, RADIO_TECH_IS95B = 5, RADIO_TECH_1xRTT = 6, RADIO_TECH_EVDO_0 = 7, RADIO_TECH_EVDO_A = 8, RADIO_TECH_HSDPA = 9, RADIO_TECH_HSUPA = 10, RADIO_TECH_HSPA = 11, RADIO_TECH_EVDO_B = 12, RADIO_TECH_EHRPD = 13, RADIO_TECH_LTE = 14, RADIO_TECH_HSPAP = 15, // HSPA+ RADIO_TECH_GSM = 16, // Only supports voice RADIO_TECH_TD_SCDMA = 17, RADIO_TECH_IWLAN = 18, RADIO_TECH_LTE_CA = 19 } RIL_RadioTechnology; typedef enum { RAF_UNKNOWN = (1 << RADIO_TECH_UNKNOWN), RAF_GPRS = (1 << RADIO_TECH_GPRS), RAF_EDGE = (1 << RADIO_TECH_EDGE), RAF_UMTS = (1 << RADIO_TECH_UMTS), RAF_IS95A = (1 << RADIO_TECH_IS95A), RAF_IS95B = (1 << RADIO_TECH_IS95B), RAF_1xRTT = (1 << RADIO_TECH_1xRTT), RAF_EVDO_0 = (1 << RADIO_TECH_EVDO_0), RAF_EVDO_A = (1 << RADIO_TECH_EVDO_A), RAF_HSDPA = (1 << RADIO_TECH_HSDPA), RAF_HSUPA = (1 << RADIO_TECH_HSUPA), RAF_HSPA = (1 << RADIO_TECH_HSPA), RAF_EVDO_B = (1 << RADIO_TECH_EVDO_B), RAF_EHRPD = (1 << RADIO_TECH_EHRPD), RAF_LTE = (1 << RADIO_TECH_LTE), RAF_HSPAP = (1 << RADIO_TECH_HSPAP), RAF_GSM = (1 << RADIO_TECH_GSM), RAF_TD_SCDMA = (1 << RADIO_TECH_TD_SCDMA), RAF_LTE_CA = (1 << RADIO_TECH_LTE_CA) } RIL_RadioAccessFamily; typedef enum { BAND_MODE_UNSPECIFIED = 0, //"unspecified" (selected by baseband automatically) BAND_MODE_EURO = 1, //"EURO band" (GSM-900 / DCS-1800 / WCDMA-IMT-2000) BAND_MODE_USA = 2, //"US band" (GSM-850 / PCS-1900 / WCDMA-850 / WCDMA-PCS-1900) BAND_MODE_JPN = 3, //"JPN band" (WCDMA-800 / WCDMA-IMT-2000) BAND_MODE_AUS = 4, //"AUS band" (GSM-900 / DCS-1800 / WCDMA-850 / WCDMA-IMT-2000) BAND_MODE_AUS_2 = 5, //"AUS band 2" (GSM-900 / DCS-1800 / WCDMA-850) BAND_MODE_CELL_800 = 6, //"Cellular" (800-MHz Band) BAND_MODE_PCS = 7, //"PCS" (1900-MHz Band) BAND_MODE_JTACS = 8, //"Band Class 3" (JTACS Band) BAND_MODE_KOREA_PCS = 9, //"Band Class 4" (Korean PCS Band) BAND_MODE_5_450M = 10, //"Band Class 5" (450-MHz Band) BAND_MODE_IMT2000 = 11, //"Band Class 6" (2-GMHz IMT2000 Band) BAND_MODE_7_700M_2 = 12, //"Band Class 7" (Upper 700-MHz Band) BAND_MODE_8_1800M = 13, //"Band Class 8" (1800-MHz Band) BAND_MODE_9_900M = 14, //"Band Class 9" (900-MHz Band) BAND_MODE_10_800M_2 = 15, //"Band Class 10" (Secondary 800-MHz Band) BAND_MODE_EURO_PAMR_400M = 16, //"Band Class 11" (400-MHz European PAMR Band) BAND_MODE_AWS = 17, //"Band Class 15" (AWS Band) BAND_MODE_USA_2500M = 18 //"Band Class 16" (US 2.5-GHz Band) } RIL_RadioBandMode; typedef enum { RC_PHASE_CONFIGURED = 0, // LM is configured is initial value and value after FINISH completes RC_PHASE_START = 1, // START is sent before Apply and indicates that an APPLY will be // forthcoming with these same parameters RC_PHASE_APPLY = 2, // APPLY is sent after all LM's receive START and returned // RIL_RadioCapability.status = 0, if any START's fail no // APPLY will be sent RC_PHASE_UNSOL_RSP = 3, // UNSOL_RSP is sent with RIL_UNSOL_RADIO_CAPABILITY RC_PHASE_FINISH = 4 // FINISH is sent after all commands have completed. If an error // occurs in any previous command the RIL_RadioAccessesFamily and // logicalModemUuid fields will be the prior configuration thus // restoring the configuration to the previous value. An error // returned by this command will generally be ignored or may // cause that logical modem to be removed from service. } RadioCapabilityPhase; typedef enum { RC_STATUS_NONE = 0, // This parameter has no meaning with RC_PHASE_START, // RC_PHASE_APPLY RC_STATUS_SUCCESS = 1, // Tell modem the action transaction of set radio // capability was success with RC_PHASE_FINISH RC_STATUS_FAIL = 2, // Tell modem the action transaction of set radio // capability is fail with RC_PHASE_FINISH. } RadioCapabilityStatus; #define RIL_RADIO_CAPABILITY_VERSION 1 typedef struct { int version; // Version of structure, RIL_RADIO_CAPABILITY_VERSION int session; // Unique session value defined by framework returned in all "responses/unsol" int phase; // CONFIGURED, START, APPLY, FINISH int rat; // RIL_RadioAccessFamily for the radio char logicalModemUuid[MAX_UUID_LENGTH]; // A UUID typically "com.xxxx.lmX where X is the logical modem. int status; // Return status and an input parameter for RC_PHASE_FINISH } RIL_RadioCapability; // Do we want to split Data from Voice and the use // RIL_RadioTechnology for get/setPreferredVoice/Data ? typedef enum { PREF_NET_TYPE_GSM_WCDMA = 0, /* GSM/WCDMA (WCDMA preferred) */ PREF_NET_TYPE_GSM_ONLY = 1, /* GSM only */ PREF_NET_TYPE_WCDMA = 2, /* WCDMA */ PREF_NET_TYPE_GSM_WCDMA_AUTO = 3, /* GSM/WCDMA (auto mode, according to PRL) */ PREF_NET_TYPE_CDMA_EVDO_AUTO = 4, /* CDMA and EvDo (auto mode, according to PRL) */ PREF_NET_TYPE_CDMA_ONLY = 5, /* CDMA only */ PREF_NET_TYPE_EVDO_ONLY = 6, /* EvDo only */ PREF_NET_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO = 7, /* GSM/WCDMA, CDMA, and EvDo (auto mode, according to PRL) */ PREF_NET_TYPE_LTE_CDMA_EVDO = 8, /* LTE, CDMA and EvDo */ PREF_NET_TYPE_LTE_GSM_WCDMA = 9, /* LTE, GSM/WCDMA */ PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA = 10, /* LTE, CDMA, EvDo, GSM/WCDMA */ PREF_NET_TYPE_LTE_ONLY = 11, /* LTE only */ PREF_NET_TYPE_LTE_WCDMA = 12, /* LTE/WCDMA */ PREF_NET_TYPE_TD_SCDMA_ONLY = 13, /* TD-SCDMA only */ PREF_NET_TYPE_TD_SCDMA_WCDMA = 14, /* TD-SCDMA and WCDMA */ PREF_NET_TYPE_TD_SCDMA_LTE = 15, /* TD-SCDMA and LTE */ PREF_NET_TYPE_TD_SCDMA_GSM = 16, /* TD-SCDMA and GSM */ PREF_NET_TYPE_TD_SCDMA_GSM_LTE = 17, /* TD-SCDMA,GSM and LTE */ PREF_NET_TYPE_TD_SCDMA_GSM_WCDMA = 18, /* TD-SCDMA, GSM/WCDMA */ PREF_NET_TYPE_TD_SCDMA_WCDMA_LTE = 19, /* TD-SCDMA, WCDMA and LTE */ PREF_NET_TYPE_TD_SCDMA_GSM_WCDMA_LTE = 20, /* TD-SCDMA, GSM/WCDMA and LTE */ PREF_NET_TYPE_TD_SCDMA_GSM_WCDMA_CDMA_EVDO_AUTO = 21, /* TD-SCDMA, GSM/WCDMA, CDMA and EvDo */ PREF_NET_TYPE_TD_SCDMA_LTE_CDMA_EVDO_GSM_WCDMA = 22 /* TD-SCDMA, LTE, CDMA, EvDo GSM/WCDMA */ } RIL_PreferredNetworkType; /* Source for cdma subscription */ typedef enum { CDMA_SUBSCRIPTION_SOURCE_RUIM_SIM = 0, CDMA_SUBSCRIPTION_SOURCE_NV = 1 } RIL_CdmaSubscriptionSource; /* User-to-User signaling Info activation types derived from 3GPP 23.087 v8.0 */ typedef enum { RIL_UUS_TYPE1_IMPLICIT = 0, RIL_UUS_TYPE1_REQUIRED = 1, RIL_UUS_TYPE1_NOT_REQUIRED = 2, RIL_UUS_TYPE2_REQUIRED = 3, RIL_UUS_TYPE2_NOT_REQUIRED = 4, RIL_UUS_TYPE3_REQUIRED = 5, RIL_UUS_TYPE3_NOT_REQUIRED = 6 } RIL_UUS_Type; /* User-to-User Signaling Information data coding schemes. Possible values for * Octet 3 (Protocol Discriminator field) in the UUIE. The values have been * specified in section 10.5.4.25 of 3GPP TS 24.008 */ typedef enum { RIL_UUS_DCS_USP = 0, /* User specified protocol */ RIL_UUS_DCS_OSIHLP = 1, /* OSI higher layer protocol */ RIL_UUS_DCS_X244 = 2, /* X.244 */ RIL_UUS_DCS_RMCF = 3, /* Reserved for system mangement convergence function */ RIL_UUS_DCS_IA5c = 4 /* IA5 characters */ } RIL_UUS_DCS; /* User-to-User Signaling Information defined in 3GPP 23.087 v8.0 * This data is passed in RIL_ExtensionRecord and rec contains this * structure when type is RIL_UUS_INFO_EXT_REC */ typedef struct { RIL_UUS_Type uusType; /* UUS Type */ RIL_UUS_DCS uusDcs; /* UUS Data Coding Scheme */ int uusLength; /* Length of UUS Data */ char * uusData; /* UUS Data */ } RIL_UUS_Info; /* CDMA Signal Information Record as defined in C.S0005 section 3.7.5.5 */ typedef struct { char isPresent; /* non-zero if signal information record is present */ char signalType; /* as defined 3.7.5.5-1 */ char alertPitch; /* as defined 3.7.5.5-2 */ char signal; /* as defined 3.7.5.5-3, 3.7.5.5-4 or 3.7.5.5-5 */ } RIL_CDMA_SignalInfoRecord; typedef struct { RIL_CallState state; int index; /* Connection Index for use with, eg, AT+CHLD */ int toa; /* type of address, eg 145 = intl */ char isMpty; /* nonzero if is mpty call */ char isMT; /* nonzero if call is mobile terminated */ char als; /* ALS line indicator if available (0 = line 1) */ char isVoice; /* nonzero if this is is a voice call */ char isVoicePrivacy; /* nonzero if CDMA voice privacy mode is active */ char * number; /* Remote party number */ int numberPresentation; /* 0=Allowed, 1=Restricted, 2=Not Specified/Unknown 3=Payphone */ char * name; /* Remote party name */ int namePresentation; /* 0=Allowed, 1=Restricted, 2=Not Specified/Unknown 3=Payphone */ RIL_UUS_Info * uusInfo; /* NULL or Pointer to User-User Signaling Information */ } RIL_Call; /* Deprecated, use RIL_Data_Call_Response_v6 */ typedef struct { int cid; /* Context ID, uniquely identifies this call */ int active; /* 0=inactive, 1=active/physical link down, 2=active/physical link up */ char * type; /* One of the PDP_type values in TS 27.007 section 10.1.1. For example, "IP", "IPV6", "IPV4V6", or "PPP". */ char * apn; /* ignored */ char * address; /* An address, e.g., "192.0.1.3" or "2001:db8::1". */ } RIL_Data_Call_Response_v4; /* * Returned by RIL_REQUEST_SETUP_DATA_CALL, RIL_REQUEST_DATA_CALL_LIST * and RIL_UNSOL_DATA_CALL_LIST_CHANGED, on error status != 0. */ typedef struct { int status; /* A RIL_DataCallFailCause, 0 which is PDP_FAIL_NONE if no error */ int suggestedRetryTime; /* If status != 0, this fields indicates the suggested retry back-off timer value RIL wants to override the one pre-configured in FW. The unit is miliseconds. The value < 0 means no value is suggested. The value 0 means retry should be done ASAP. The value of INT_MAX(0x7fffffff) means no retry. */ int cid; /* Context ID, uniquely identifies this call */ int active; /* 0=inactive, 1=active/physical link down, 2=active/physical link up */ char * type; /* One of the PDP_type values in TS 27.007 section 10.1.1. For example, "IP", "IPV6", "IPV4V6", or "PPP". If status is PDP_FAIL_ONLY_SINGLE_BEARER_ALLOWED this is the type supported such as "IP" or "IPV6" */ char * ifname; /* The network interface name */ char * addresses; /* A space-delimited list of addresses with optional "/" prefix length, e.g., "192.0.1.3" or "192.0.1.11/16 2001:db8::1/64". May not be empty, typically 1 IPv4 or 1 IPv6 or one of each. If the prefix length is absent the addresses are assumed to be point to point with IPv4 having a prefix length of 32 and IPv6 128. */ char * dnses; /* A space-delimited list of DNS server addresses, e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1". May be empty. */ char * gateways; /* A space-delimited list of default gateway addresses, e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1". May be empty in which case the addresses represent point to point connections. */ } RIL_Data_Call_Response_v6; typedef struct { int status; /* A RIL_DataCallFailCause, 0 which is PDP_FAIL_NONE if no error */ int suggestedRetryTime; /* If status != 0, this fields indicates the suggested retry back-off timer value RIL wants to override the one pre-configured in FW. The unit is miliseconds. The value < 0 means no value is suggested. The value 0 means retry should be done ASAP. The value of INT_MAX(0x7fffffff) means no retry. */ int cid; /* Context ID, uniquely identifies this call */ int active; /* 0=inactive, 1=active/physical link down, 2=active/physical link up */ char * type; /* One of the PDP_type values in TS 27.007 section 10.1.1. For example, "IP", "IPV6", "IPV4V6", or "PPP". If status is PDP_FAIL_ONLY_SINGLE_BEARER_ALLOWED this is the type supported such as "IP" or "IPV6" */ char * ifname; /* The network interface name */ char * addresses; /* A space-delimited list of addresses with optional "/" prefix length, e.g., "192.0.1.3" or "192.0.1.11/16 2001:db8::1/64". May not be empty, typically 1 IPv4 or 1 IPv6 or one of each. If the prefix length is absent the addresses are assumed to be point to point with IPv4 having a prefix length of 32 and IPv6 128. */ char * dnses; /* A space-delimited list of DNS server addresses, e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1". May be empty. */ char * gateways; /* A space-delimited list of default gateway addresses, e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1". May be empty in which case the addresses represent point to point connections. */ char * pcscf; /* the Proxy Call State Control Function address via PCO(Protocol Configuration Option) for IMS client. */ } RIL_Data_Call_Response_v9; typedef struct { int status; /* A RIL_DataCallFailCause, 0 which is PDP_FAIL_NONE if no error */ int suggestedRetryTime; /* If status != 0, this fields indicates the suggested retry back-off timer value RIL wants to override the one pre-configured in FW. The unit is miliseconds. The value < 0 means no value is suggested. The value 0 means retry should be done ASAP. The value of INT_MAX(0x7fffffff) means no retry. */ int cid; /* Context ID, uniquely identifies this call */ int active; /* 0=inactive, 1=active/physical link down, 2=active/physical link up */ char * type; /* One of the PDP_type values in TS 27.007 section 10.1.1. For example, "IP", "IPV6", "IPV4V6", or "PPP". If status is PDP_FAIL_ONLY_SINGLE_BEARER_ALLOWED this is the type supported such as "IP" or "IPV6" */ char * ifname; /* The network interface name */ char * addresses; /* A space-delimited list of addresses with optional "/" prefix length, e.g., "192.0.1.3" or "192.0.1.11/16 2001:db8::1/64". May not be empty, typically 1 IPv4 or 1 IPv6 or one of each. If the prefix length is absent the addresses are assumed to be point to point with IPv4 having a prefix length of 32 and IPv6 128. */ char * dnses; /* A space-delimited list of DNS server addresses, e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1". May be empty. */ char * gateways; /* A space-delimited list of default gateway addresses, e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1". May be empty in which case the addresses represent point to point connections. */ char * pcscf; /* the Proxy Call State Control Function address via PCO(Protocol Configuration Option) for IMS client. */ int mtu; /* MTU received from network Value <= 0 means network has either not sent a value or sent an invalid value */ } RIL_Data_Call_Response_v11; typedef enum { RADIO_TECH_3GPP = 1, /* 3GPP Technologies - GSM, WCDMA */ RADIO_TECH_3GPP2 = 2 /* 3GPP2 Technologies - CDMA */ } RIL_RadioTechnologyFamily; typedef struct { RIL_RadioTechnologyFamily tech; unsigned char retry; /* 0 == not retry, nonzero == retry */ int messageRef; /* Valid field if retry is set to nonzero. Contains messageRef from RIL_SMS_Response corresponding to failed MO SMS. */ union { /* Valid field if tech is RADIO_TECH_3GPP2. See RIL_REQUEST_CDMA_SEND_SMS */ RIL_CDMA_SMS_Message* cdmaMessage; /* Valid field if tech is RADIO_TECH_3GPP. See RIL_REQUEST_SEND_SMS */ char** gsmMessage; /* This is an array of pointers where pointers are contiguous but elements pointed by those pointers are not contiguous */ } message; } RIL_IMS_SMS_Message; typedef struct { int messageRef; /* TP-Message-Reference for GSM, and BearerData MessageId for CDMA (See 3GPP2 C.S0015-B, v2.0, table 4.5-1). */ char *ackPDU; /* or NULL if n/a */ int errorCode; /* See 3GPP 27.005, 3.2.5 for GSM/UMTS, 3GPP2 N.S0005 (IS-41C) Table 171 for CDMA, -1 if unknown or not applicable*/ } RIL_SMS_Response; /** Used by RIL_REQUEST_WRITE_SMS_TO_SIM */ typedef struct { int status; /* Status of message. See TS 27.005 3.1, "": */ /* 0 = "REC UNREAD" */ /* 1 = "REC READ" */ /* 2 = "STO UNSENT" */ /* 3 = "STO SENT" */ char * pdu; /* PDU of message to write, as an ASCII hex string less the SMSC address, the TP-layer length is "strlen(pdu)/2". */ char * smsc; /* SMSC address in GSM BCD format prefixed by a length byte (as expected by TS 27.005) or NULL for default SMSC */ } RIL_SMS_WriteArgs; /** Used by RIL_REQUEST_DIAL */ typedef struct { char * address; int clir; /* (same as 'n' paremeter in TS 27.007 7.7 "+CLIR" * clir == 0 on "use subscription default value" * clir == 1 on "CLIR invocation" (restrict CLI presentation) * clir == 2 on "CLIR suppression" (allow CLI presentation) */ RIL_UUS_Info * uusInfo; /* NULL or Pointer to User-User Signaling Information */ } RIL_Dial; typedef struct { int unknown; int command; /* one of the commands listed for TS 27.007 +CRSM*/ int fileid; /* EF id */ char *path; /* "pathid" from TS 27.007 +CRSM command. Path is in hex asciii format eg "7f205f70" Path must always be provided. */ int p1; int p2; int p3; char *data; /* May be NULL*/ char *pin2; /* May be NULL*/ } RIL_SIM_IO_v5; typedef struct { int unknown; int command; /* one of the commands listed for TS 27.007 +CRSM*/ int fileid; /* EF id */ char *path; /* "pathid" from TS 27.007 +CRSM command. Path is in hex asciii format eg "7f205f70" Path must always be provided. */ int p1; int p2; int p3; char *data; /* May be NULL*/ char *pin2; /* May be NULL*/ char *aidPtr; /* AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. */ } RIL_SIM_IO_v6; /* Used by RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL and * RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC. */ typedef struct { int sessionid; /* "sessionid" from TS 27.007 +CGLA command. Should be ignored for +CSIM command. */ /* Following fields are used to derive the APDU ("command" and "length" values in TS 27.007 +CSIM and +CGLA commands). */ int cla; int instruction; int p1; int p2; int p3; /* A negative P3 implies a 4 byte APDU. */ char *data; /* May be NULL. In hex string format. */ } RIL_SIM_APDU; typedef struct { int sw1; int sw2; char *simResponse; /* In hex string format ([a-fA-F0-9]*), except for SIM_AUTHENTICATION response for which it is in Base64 format, see 3GPP TS 31.102 7.1.2 */ } RIL_SIM_IO_Response; /* See also com.android.internal.telephony.gsm.CallForwardInfo */ typedef struct { int status; /* * For RIL_REQUEST_QUERY_CALL_FORWARD_STATUS * status 1 = active, 0 = not active * * For RIL_REQUEST_SET_CALL_FORWARD: * status is: * 0 = disable * 1 = enable * 2 = interrogate * 3 = registeration * 4 = erasure */ int reason; /* from TS 27.007 7.11 "reason" */ int serviceClass;/* From 27.007 +CCFC/+CLCK "class" See table for Android mapping from MMI service code 0 means user doesn't input class */ int toa; /* "type" from TS 27.007 7.11 */ char * number; /* "number" from TS 27.007 7.11. May be NULL */ int timeSeconds; /* for CF no reply only */ }RIL_CallForwardInfo; typedef struct { char * cid; /* Combination of LAC and Cell Id in 32 bits in GSM. * Upper 16 bits is LAC and lower 16 bits * is CID (as described in TS 27.005) * Primary Scrambling Code (as described in TS 25.331) * in 9 bits in UMTS * Valid values are hexadecimal 0x0000 - 0xffffffff. */ int rssi; /* Received RSSI in GSM, * Level index of CPICH Received Signal Code Power in UMTS */ } RIL_NeighboringCell; typedef struct { char lce_status; /* LCE service status: * -1 = not supported; * 0 = stopped; * 1 = active. */ unsigned int actual_interval_ms; /* actual LCE reporting interval, * meaningful only if LCEStatus = 1. */ } RIL_LceStatusInfo; typedef struct { unsigned int last_hop_capacity_kbps; /* last-hop cellular capacity: kilobits/second. */ unsigned char confidence_level; /* capacity estimate confidence: 0-100 */ unsigned char lce_suspended; /* LCE report going to be suspended? (e.g., radio * moves to inactive state or network type change) * 1 = suspended; * 0 = not suspended. */ } RIL_LceDataInfo; typedef enum { RIL_MATCH_ALL = 0, /* Apply to all carriers with the same mcc/mnc */ RIL_MATCH_SPN = 1, /* Use SPN and mcc/mnc to identify the carrier */ RIL_MATCH_IMSI_PREFIX = 2, /* Use IMSI prefix and mcc/mnc to identify the carrier */ RIL_MATCH_GID1 = 3, /* Use GID1 and mcc/mnc to identify the carrier */ RIL_MATCH_GID2 = 4, /* Use GID2 and mcc/mnc to identify the carrier */ } RIL_CarrierMatchType; typedef struct { const char * mcc; const char * mnc; RIL_CarrierMatchType match_type; /* Specify match type for the carrier. * If it’s RIL_MATCH_ALL, match_data is null; * otherwise, match_data is the value for the match type. */ const char * match_data; } RIL_Carrier; typedef struct { int32_t len_allowed_carriers; /* length of array allowed_carriers */ int32_t len_excluded_carriers; /* length of array excluded_carriers */ RIL_Carrier * allowed_carriers; /* whitelist for allowed carriers */ RIL_Carrier * excluded_carriers; /* blacklist for explicitly excluded carriers * which match allowed_carriers. Eg. allowed_carriers match * mcc/mnc, excluded_carriers has same mcc/mnc and gid1 * is ABCD. It means except the carrier whose gid1 is ABCD, * all carriers with the same mcc/mnc are allowed. */ } RIL_CarrierRestrictions; /* See RIL_REQUEST_LAST_CALL_FAIL_CAUSE */ typedef enum { CALL_FAIL_UNOBTAINABLE_NUMBER = 1, CALL_FAIL_NO_ROUTE_TO_DESTINATION = 3, CALL_FAIL_CHANNEL_UNACCEPTABLE = 6, CALL_FAIL_OPERATOR_DETERMINED_BARRING = 8, CALL_FAIL_NORMAL = 16, CALL_FAIL_BUSY = 17, CALL_FAIL_NO_USER_RESPONDING = 18, CALL_FAIL_NO_ANSWER_FROM_USER = 19, CALL_FAIL_CALL_REJECTED = 21, CALL_FAIL_NUMBER_CHANGED = 22, CALL_FAIL_PREEMPTION = 25, CALL_FAIL_DESTINATION_OUT_OF_ORDER = 27, CALL_FAIL_INVALID_NUMBER_FORMAT = 28, CALL_FAIL_FACILITY_REJECTED = 29, CALL_FAIL_RESP_TO_STATUS_ENQUIRY = 30, CALL_FAIL_NORMAL_UNSPECIFIED = 31, CALL_FAIL_CONGESTION = 34, CALL_FAIL_NETWORK_OUT_OF_ORDER = 38, CALL_FAIL_TEMPORARY_FAILURE = 41, CALL_FAIL_SWITCHING_EQUIPMENT_CONGESTION = 42, CALL_FAIL_ACCESS_INFORMATION_DISCARDED = 43, CALL_FAIL_REQUESTED_CIRCUIT_OR_CHANNEL_NOT_AVAILABLE = 44, CALL_FAIL_RESOURCES_UNAVAILABLE_OR_UNSPECIFIED = 47, CALL_FAIL_QOS_UNAVAILABLE = 49, CALL_FAIL_REQUESTED_FACILITY_NOT_SUBSCRIBED = 50, CALL_FAIL_INCOMING_CALLS_BARRED_WITHIN_CUG = 55, CALL_FAIL_BEARER_CAPABILITY_NOT_AUTHORIZED = 57, CALL_FAIL_BEARER_CAPABILITY_UNAVAILABLE = 58, CALL_FAIL_SERVICE_OPTION_NOT_AVAILABLE = 63, CALL_FAIL_BEARER_SERVICE_NOT_IMPLEMENTED = 65, CALL_FAIL_ACM_LIMIT_EXCEEDED = 68, CALL_FAIL_REQUESTED_FACILITY_NOT_IMPLEMENTED = 69, CALL_FAIL_ONLY_DIGITAL_INFORMATION_BEARER_AVAILABLE = 70, CALL_FAIL_SERVICE_OR_OPTION_NOT_IMPLEMENTED = 79, CALL_FAIL_INVALID_TRANSACTION_IDENTIFIER = 81, CALL_FAIL_USER_NOT_MEMBER_OF_CUG = 87, CALL_FAIL_INCOMPATIBLE_DESTINATION = 88, CALL_FAIL_INVALID_TRANSIT_NW_SELECTION = 91, CALL_FAIL_SEMANTICALLY_INCORRECT_MESSAGE = 95, CALL_FAIL_INVALID_MANDATORY_INFORMATION = 96, CALL_FAIL_MESSAGE_TYPE_NON_IMPLEMENTED = 97, CALL_FAIL_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 98, CALL_FAIL_INFORMATION_ELEMENT_NON_EXISTENT = 99, CALL_FAIL_CONDITIONAL_IE_ERROR = 100, CALL_FAIL_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 101, CALL_FAIL_RECOVERY_ON_TIMER_EXPIRED = 102, CALL_FAIL_PROTOCOL_ERROR_UNSPECIFIED = 111, CALL_FAIL_INTERWORKING_UNSPECIFIED = 127, CALL_FAIL_CALL_BARRED = 240, CALL_FAIL_FDN_BLOCKED = 241, CALL_FAIL_IMSI_UNKNOWN_IN_VLR = 242, CALL_FAIL_IMEI_NOT_ACCEPTED = 243, CALL_FAIL_DIAL_MODIFIED_TO_USSD = 244, /* STK Call Control */ CALL_FAIL_DIAL_MODIFIED_TO_SS = 245, CALL_FAIL_DIAL_MODIFIED_TO_DIAL = 246, CALL_FAIL_CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000, CALL_FAIL_CDMA_DROP = 1001, CALL_FAIL_CDMA_INTERCEPT = 1002, CALL_FAIL_CDMA_REORDER = 1003, CALL_FAIL_CDMA_SO_REJECT = 1004, CALL_FAIL_CDMA_RETRY_ORDER = 1005, CALL_FAIL_CDMA_ACCESS_FAILURE = 1006, CALL_FAIL_CDMA_PREEMPTED = 1007, CALL_FAIL_CDMA_NOT_EMERGENCY = 1008, /* For non-emergency number dialed during emergency callback mode */ CALL_FAIL_CDMA_ACCESS_BLOCKED = 1009, /* CDMA network access probes blocked */ CALL_FAIL_ERROR_UNSPECIFIED = 0xffff /* This error will be deprecated soon, vendor code should make sure to map error code to specific error */ } RIL_LastCallFailCause; typedef struct { RIL_LastCallFailCause cause_code; char * vendor_cause; } RIL_LastCallFailCauseInfo; /* See RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE */ typedef enum { PDP_FAIL_NONE = 0, /* No error, connection ok */ /* an integer cause code defined in TS 24.008 section 6.1.3.1.3 or TS 24.301 Release 8+ Annex B. If the implementation does not have access to the exact cause codes, then it should return one of the following values, as the UI layer needs to distinguish these cases for error notification and potential retries. */ PDP_FAIL_OPERATOR_BARRED = 0x08, /* no retry */ PDP_FAIL_NAS_SIGNALLING = 0x0E, PDP_FAIL_LLC_SNDCP = 0x19, PDP_FAIL_INSUFFICIENT_RESOURCES = 0x1A, PDP_FAIL_MISSING_UKNOWN_APN = 0x1B, /* no retry */ PDP_FAIL_UNKNOWN_PDP_ADDRESS_TYPE = 0x1C, /* no retry */ PDP_FAIL_USER_AUTHENTICATION = 0x1D, /* no retry */ PDP_FAIL_ACTIVATION_REJECT_GGSN = 0x1E, /* no retry */ PDP_FAIL_ACTIVATION_REJECT_UNSPECIFIED = 0x1F, PDP_FAIL_SERVICE_OPTION_NOT_SUPPORTED = 0x20, /* no retry */ PDP_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED = 0x21, /* no retry */ PDP_FAIL_SERVICE_OPTION_OUT_OF_ORDER = 0x22, PDP_FAIL_NSAPI_IN_USE = 0x23, /* no retry */ PDP_FAIL_REGULAR_DEACTIVATION = 0x24, /* possibly restart radio, based on framework config */ PDP_FAIL_QOS_NOT_ACCEPTED = 0x25, PDP_FAIL_NETWORK_FAILURE = 0x26, PDP_FAIL_UMTS_REACTIVATION_REQ = 0x27, PDP_FAIL_FEATURE_NOT_SUPP = 0x28, PDP_FAIL_TFT_SEMANTIC_ERROR = 0x29, PDP_FAIL_TFT_SYTAX_ERROR = 0x2A, PDP_FAIL_UNKNOWN_PDP_CONTEXT = 0x2B, PDP_FAIL_FILTER_SEMANTIC_ERROR = 0x2C, PDP_FAIL_FILTER_SYTAX_ERROR = 0x2D, PDP_FAIL_PDP_WITHOUT_ACTIVE_TFT = 0x2E, PDP_FAIL_ONLY_IPV4_ALLOWED = 0x32, /* no retry */ PDP_FAIL_ONLY_IPV6_ALLOWED = 0x33, /* no retry */ PDP_FAIL_ONLY_SINGLE_BEARER_ALLOWED = 0x34, PDP_FAIL_ESM_INFO_NOT_RECEIVED = 0x35, PDP_FAIL_PDN_CONN_DOES_NOT_EXIST = 0x36, PDP_FAIL_MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED = 0x37, PDP_FAIL_MAX_ACTIVE_PDP_CONTEXT_REACHED = 0x41, PDP_FAIL_UNSUPPORTED_APN_IN_CURRENT_PLMN = 0x42, PDP_FAIL_INVALID_TRANSACTION_ID = 0x51, PDP_FAIL_MESSAGE_INCORRECT_SEMANTIC = 0x5F, PDP_FAIL_INVALID_MANDATORY_INFO = 0x60, PDP_FAIL_MESSAGE_TYPE_UNSUPPORTED = 0x61, PDP_FAIL_MSG_TYPE_NONCOMPATIBLE_STATE = 0x62, PDP_FAIL_UNKNOWN_INFO_ELEMENT = 0x63, PDP_FAIL_CONDITIONAL_IE_ERROR = 0x64, PDP_FAIL_MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE = 0x65, PDP_FAIL_PROTOCOL_ERRORS = 0x6F, /* no retry */ PDP_FAIL_APN_TYPE_CONFLICT = 0x70, PDP_FAIL_INVALID_PCSCF_ADDR = 0x71, PDP_FAIL_INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN = 0x72, PDP_FAIL_EMM_ACCESS_BARRED = 0x73, PDP_FAIL_EMERGENCY_IFACE_ONLY = 0x74, PDP_FAIL_IFACE_MISMATCH = 0x75, PDP_FAIL_COMPANION_IFACE_IN_USE = 0x76, PDP_FAIL_IP_ADDRESS_MISMATCH = 0x77, PDP_FAIL_IFACE_AND_POL_FAMILY_MISMATCH = 0x78, PDP_FAIL_EMM_ACCESS_BARRED_INFINITE_RETRY = 0x79, PDP_FAIL_AUTH_FAILURE_ON_EMERGENCY_CALL = 0x7A, // OEM specific error codes. To be used by OEMs when they don't want to // reveal error code which would be replaced by PDP_FAIL_ERROR_UNSPECIFIED PDP_FAIL_OEM_DCFAILCAUSE_1 = 0x1001, PDP_FAIL_OEM_DCFAILCAUSE_2 = 0x1002, PDP_FAIL_OEM_DCFAILCAUSE_3 = 0x1003, PDP_FAIL_OEM_DCFAILCAUSE_4 = 0x1004, PDP_FAIL_OEM_DCFAILCAUSE_5 = 0x1005, PDP_FAIL_OEM_DCFAILCAUSE_6 = 0x1006, PDP_FAIL_OEM_DCFAILCAUSE_7 = 0x1007, PDP_FAIL_OEM_DCFAILCAUSE_8 = 0x1008, PDP_FAIL_OEM_DCFAILCAUSE_9 = 0x1009, PDP_FAIL_OEM_DCFAILCAUSE_10 = 0x100A, PDP_FAIL_OEM_DCFAILCAUSE_11 = 0x100B, PDP_FAIL_OEM_DCFAILCAUSE_12 = 0x100C, PDP_FAIL_OEM_DCFAILCAUSE_13 = 0x100D, PDP_FAIL_OEM_DCFAILCAUSE_14 = 0x100E, PDP_FAIL_OEM_DCFAILCAUSE_15 = 0x100F, /* Not mentioned in the specification */ PDP_FAIL_VOICE_REGISTRATION_FAIL = -1, PDP_FAIL_DATA_REGISTRATION_FAIL = -2, /* reasons for data call drop - network/modem disconnect */ PDP_FAIL_SIGNAL_LOST = -3, PDP_FAIL_PREF_RADIO_TECH_CHANGED = -4,/* preferred technology has changed, should retry with parameters appropriate for new technology */ PDP_FAIL_RADIO_POWER_OFF = -5, /* data call was disconnected because radio was resetting, powered off - no retry */ PDP_FAIL_TETHERED_CALL_ACTIVE = -6, /* data call was disconnected by modem because tethered mode was up on same APN/data profile - no retry until tethered call is off */ PDP_FAIL_ERROR_UNSPECIFIED = 0xffff, /* retry silently. Will be deprecated soon as new error codes are added making this unnecessary */ } RIL_DataCallFailCause; /* See RIL_REQUEST_SETUP_DATA_CALL */ typedef enum { RIL_DATA_PROFILE_DEFAULT = 0, RIL_DATA_PROFILE_TETHERED = 1, RIL_DATA_PROFILE_IMS = 2, RIL_DATA_PROFILE_FOTA = 3, RIL_DATA_PROFILE_CBS = 4, RIL_DATA_PROFILE_OEM_BASE = 1000, /* Start of OEM-specific profiles */ RIL_DATA_PROFILE_INVALID = 0xFFFFFFFF } RIL_DataProfile; /* Used by RIL_UNSOL_SUPP_SVC_NOTIFICATION */ typedef struct { int notificationType; /* * 0 = MO intermediate result code * 1 = MT unsolicited result code */ int code; /* See 27.007 7.17 "code1" for MO "code2" for MT. */ int index; /* CUG index. See 27.007 7.17. */ int type; /* "type" from 27.007 7.17 (MT only). */ char * number; /* "number" from 27.007 7.17 (MT only, may be NULL). */ } RIL_SuppSvcNotification; #define RIL_CARD_MAX_APPS 8 typedef enum { RIL_CARDSTATE_ABSENT = 0, RIL_CARDSTATE_PRESENT = 1, RIL_CARDSTATE_ERROR = 2, RIL_CARDSTATE_RESTRICTED = 3 /* card is present but not usable due to carrier restrictions.*/ } RIL_CardState; typedef enum { RIL_PERSOSUBSTATE_UNKNOWN = 0, /* initial state */ RIL_PERSOSUBSTATE_IN_PROGRESS = 1, /* in between each lock transition */ RIL_PERSOSUBSTATE_READY = 2, /* when either SIM or RUIM Perso is finished since each app can only have 1 active perso involved */ RIL_PERSOSUBSTATE_SIM_NETWORK = 3, RIL_PERSOSUBSTATE_SIM_NETWORK_SUBSET = 4, RIL_PERSOSUBSTATE_SIM_CORPORATE = 5, RIL_PERSOSUBSTATE_SIM_SERVICE_PROVIDER = 6, RIL_PERSOSUBSTATE_SIM_SIM = 7, RIL_PERSOSUBSTATE_SIM_NETWORK_PUK = 8, /* The corresponding perso lock is blocked */ RIL_PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK = 9, RIL_PERSOSUBSTATE_SIM_CORPORATE_PUK = 10, RIL_PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK = 11, RIL_PERSOSUBSTATE_SIM_SIM_PUK = 12, RIL_PERSOSUBSTATE_RUIM_NETWORK1 = 13, RIL_PERSOSUBSTATE_RUIM_NETWORK2 = 14, RIL_PERSOSUBSTATE_RUIM_HRPD = 15, RIL_PERSOSUBSTATE_RUIM_CORPORATE = 16, RIL_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER = 17, RIL_PERSOSUBSTATE_RUIM_RUIM = 18, RIL_PERSOSUBSTATE_RUIM_NETWORK1_PUK = 19, /* The corresponding perso lock is blocked */ RIL_PERSOSUBSTATE_RUIM_NETWORK2_PUK = 20, RIL_PERSOSUBSTATE_RUIM_HRPD_PUK = 21, RIL_PERSOSUBSTATE_RUIM_CORPORATE_PUK = 22, RIL_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK = 23, RIL_PERSOSUBSTATE_RUIM_RUIM_PUK = 24 } RIL_PersoSubstate; typedef enum { RIL_APPSTATE_UNKNOWN = 0, RIL_APPSTATE_DETECTED = 1, RIL_APPSTATE_PIN = 2, /* If PIN1 or UPin is required */ RIL_APPSTATE_PUK = 3, /* If PUK1 or Puk for UPin is required */ RIL_APPSTATE_SUBSCRIPTION_PERSO = 4, /* perso_substate should be look at when app_state is assigned to this value */ RIL_APPSTATE_READY = 5 } RIL_AppState; typedef enum { RIL_PINSTATE_UNKNOWN = 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED = 1, RIL_PINSTATE_ENABLED_VERIFIED = 2, RIL_PINSTATE_DISABLED = 3, RIL_PINSTATE_ENABLED_BLOCKED = 4, RIL_PINSTATE_ENABLED_PERM_BLOCKED = 5 } RIL_PinState; typedef enum { RIL_APPTYPE_UNKNOWN = 0, RIL_APPTYPE_SIM = 1, RIL_APPTYPE_USIM = 2, RIL_APPTYPE_RUIM = 3, RIL_APPTYPE_CSIM = 4, RIL_APPTYPE_ISIM = 5 } RIL_AppType; typedef struct { RIL_AppType app_type; RIL_AppState app_state; RIL_PersoSubstate perso_substate; /* applicable only if app_state == RIL_APPSTATE_SUBSCRIPTION_PERSO */ char *aid_ptr; /* null terminated string, e.g., from 0xA0, 0x00 -> 0x41, 0x30, 0x30, 0x30 */ char *app_label_ptr; /* null terminated string */ int pin1_replaced; /* applicable to USIM, CSIM & ISIM */ RIL_PinState pin1; RIL_PinState pin2; } RIL_AppStatus; /* Deprecated, use RIL_CardStatus_v6 */ typedef struct { RIL_CardState card_state; RIL_PinState universal_pin_state; /* applicable to USIM and CSIM: RIL_PINSTATE_xxx */ int gsm_umts_subscription_app_index; /* value < RIL_CARD_MAX_APPS, -1 if none */ int cdma_subscription_app_index; /* value < RIL_CARD_MAX_APPS, -1 if none */ int num_applications; /* value <= RIL_CARD_MAX_APPS */ RIL_AppStatus applications[RIL_CARD_MAX_APPS]; } RIL_CardStatus_v5; typedef struct { RIL_CardState card_state; RIL_PinState universal_pin_state; /* applicable to USIM and CSIM: RIL_PINSTATE_xxx */ int gsm_umts_subscription_app_index; /* value < RIL_CARD_MAX_APPS, -1 if none */ int cdma_subscription_app_index; /* value < RIL_CARD_MAX_APPS, -1 if none */ int ims_subscription_app_index; /* value < RIL_CARD_MAX_APPS, -1 if none */ int num_applications; /* value <= RIL_CARD_MAX_APPS */ RIL_AppStatus applications[RIL_CARD_MAX_APPS]; } RIL_CardStatus_v6; /** The result of a SIM refresh, returned in data[0] of RIL_UNSOL_SIM_REFRESH * or as part of RIL_SimRefreshResponse_v7 */ typedef enum { /* A file on SIM has been updated. data[1] contains the EFID. */ SIM_FILE_UPDATE = 0, /* SIM initialized. All files should be re-read. */ SIM_INIT = 1, /* SIM reset. SIM power required, SIM may be locked and all files should be re-read. */ SIM_RESET = 2 } RIL_SimRefreshResult; typedef struct { RIL_SimRefreshResult result; int ef_id; /* is the EFID of the updated file if the result is */ /* SIM_FILE_UPDATE or 0 for any other result. */ char * aid; /* is AID(application ID) of the card application */ /* See ETSI 102.221 8.1 and 101.220 4 */ /* For SIM_FILE_UPDATE result it can be set to AID of */ /* application in which updated EF resides or it can be */ /* NULL if EF is outside of an application. */ /* For SIM_INIT result this field is set to AID of */ /* application that caused REFRESH */ /* For SIM_RESET result it is NULL. */ } RIL_SimRefreshResponse_v7; /* Deprecated, use RIL_CDMA_CallWaiting_v6 */ typedef struct { char * number; /* Remote party number */ int numberPresentation; /* 0=Allowed, 1=Restricted, 2=Not Specified/Unknown */ char * name; /* Remote party name */ RIL_CDMA_SignalInfoRecord signalInfoRecord; } RIL_CDMA_CallWaiting_v5; typedef struct { char * number; /* Remote party number */ int numberPresentation; /* 0=Allowed, 1=Restricted, 2=Not Specified/Unknown */ char * name; /* Remote party name */ RIL_CDMA_SignalInfoRecord signalInfoRecord; /* Number type/Number plan required to support International Call Waiting */ int number_type; /* 0=Unknown, 1=International, 2=National, 3=Network specific, 4=subscriber */ int number_plan; /* 0=Unknown, 1=ISDN, 3=Data, 4=Telex, 8=Nat'l, 9=Private */ } RIL_CDMA_CallWaiting_v6; /** * Which types of Cell Broadcast Message (CBM) are to be received by the ME * * uFromServiceID - uToServiceID defines a range of CBM message identifiers * whose value is 0x0000 - 0xFFFF as defined in TS 23.041 9.4.1.2.2 for GMS * and 9.4.4.2.2 for UMTS. All other values can be treated as empty * CBM message ID. * * uFromCodeScheme - uToCodeScheme defines a range of CBM data coding schemes * whose value is 0x00 - 0xFF as defined in TS 23.041 9.4.1.2.3 for GMS * and 9.4.4.2.3 for UMTS. * All other values can be treated as empty CBM data coding scheme. * * selected 0 means message types specified in * and are not accepted, while 1 means accepted. * * Used by RIL_REQUEST_GSM_GET_BROADCAST_CONFIG and * RIL_REQUEST_GSM_SET_BROADCAST_CONFIG. */ typedef struct { int fromServiceId; int toServiceId; int fromCodeScheme; int toCodeScheme; unsigned char selected; } RIL_GSM_BroadcastSmsConfigInfo; /* No restriction at all including voice/SMS/USSD/SS/AV64 and packet data. */ #define RIL_RESTRICTED_STATE_NONE 0x00 /* Block emergency call due to restriction. But allow all normal voice/SMS/USSD/SS/AV64. */ #define RIL_RESTRICTED_STATE_CS_EMERGENCY 0x01 /* Block all normal voice/SMS/USSD/SS/AV64 due to restriction. Only Emergency call allowed. */ #define RIL_RESTRICTED_STATE_CS_NORMAL 0x02 /* Block all voice/SMS/USSD/SS/AV64 including emergency call due to restriction.*/ #define RIL_RESTRICTED_STATE_CS_ALL 0x04 /* Block packet data access due to restriction. */ #define RIL_RESTRICTED_STATE_PS_ALL 0x10 /* The status for an OTASP/OTAPA session */ typedef enum { CDMA_OTA_PROVISION_STATUS_SPL_UNLOCKED, CDMA_OTA_PROVISION_STATUS_SPC_RETRIES_EXCEEDED, CDMA_OTA_PROVISION_STATUS_A_KEY_EXCHANGED, CDMA_OTA_PROVISION_STATUS_SSD_UPDATED, CDMA_OTA_PROVISION_STATUS_NAM_DOWNLOADED, CDMA_OTA_PROVISION_STATUS_MDN_DOWNLOADED, CDMA_OTA_PROVISION_STATUS_IMSI_DOWNLOADED, CDMA_OTA_PROVISION_STATUS_PRL_DOWNLOADED, CDMA_OTA_PROVISION_STATUS_COMMITTED, CDMA_OTA_PROVISION_STATUS_OTAPA_STARTED, CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED, CDMA_OTA_PROVISION_STATUS_OTAPA_ABORTED } RIL_CDMA_OTA_ProvisionStatus; typedef struct { int signalStrength; /* Valid values are (0-31, 99) as defined in TS 27.007 8.5 */ int bitErrorRate; /* bit error rate (0-7, 99) as defined in TS 27.007 8.5 */ } RIL_GW_SignalStrength; typedef struct { int signalStrength; /* Valid values are (0-31, 99) as defined in TS 27.007 8.5 */ int bitErrorRate; /* bit error rate (0-7, 99) as defined in TS 27.007 8.5 */ int timingAdvance; /* Timing Advance in bit periods. 1 bit period = 48/13 us. * INT_MAX denotes invalid value */ } RIL_GSM_SignalStrength_v12; typedef struct { int signalStrength; /* Valid values are (0-31, 99) as defined in TS 27.007 8.5 */ int bitErrorRate; /* bit error rate (0-7, 99) as defined in TS 27.007 8.5 */ } RIL_SignalStrengthWcdma; typedef struct { int dbm; /* Valid values are positive integers. This value is the actual RSSI value * multiplied by -1. Example: If the actual RSSI is -75, then this response * value will be 75. */ int ecio; /* Valid values are positive integers. This value is the actual Ec/Io multiplied * by -10. Example: If the actual Ec/Io is -12.5 dB, then this response value * will be 125. */ } RIL_CDMA_SignalStrength; typedef struct { int dbm; /* Valid values are positive integers. This value is the actual RSSI value * multiplied by -1. Example: If the actual RSSI is -75, then this response * value will be 75. */ int ecio; /* Valid values are positive integers. This value is the actual Ec/Io multiplied * by -10. Example: If the actual Ec/Io is -12.5 dB, then this response value * will be 125. */ int signalNoiseRatio; /* Valid values are 0-8. 8 is the highest signal to noise ratio. */ } RIL_EVDO_SignalStrength; typedef struct { int signalStrength; /* Valid values are (0-31, 99) as defined in TS 27.007 8.5 */ int rsrp; /* The current Reference Signal Receive Power in dBm multipled by -1. * Range: 44 to 140 dBm * INT_MAX: 0x7FFFFFFF denotes invalid value. * Reference: 3GPP TS 36.133 9.1.4 */ int rsrq; /* The current Reference Signal Receive Quality in dB multiplied by -1. * Range: 20 to 3 dB. * INT_MAX: 0x7FFFFFFF denotes invalid value. * Reference: 3GPP TS 36.133 9.1.7 */ int rssnr; /* The current reference signal signal-to-noise ratio in 0.1 dB units. * Range: -200 to +300 (-200 = -20.0 dB, +300 = 30dB). * INT_MAX : 0x7FFFFFFF denotes invalid value. * Reference: 3GPP TS 36.101 8.1.1 */ int cqi; /* The current Channel Quality Indicator. * Range: 0 to 15. * INT_MAX : 0x7FFFFFFF denotes invalid value. * Reference: 3GPP TS 36.101 9.2, 9.3, A.4 */ } RIL_LTE_SignalStrength; typedef struct { int signalStrength; /* Valid values are (0-31, 99) as defined in TS 27.007 8.5 */ int rsrp; /* The current Reference Signal Receive Power in dBm multipled by -1. * Range: 44 to 140 dBm * INT_MAX: 0x7FFFFFFF denotes invalid value. * Reference: 3GPP TS 36.133 9.1.4 */ int rsrq; /* The current Reference Signal Receive Quality in dB multiplied by -1. * Range: 20 to 3 dB. * INT_MAX: 0x7FFFFFFF denotes invalid value. * Reference: 3GPP TS 36.133 9.1.7 */ int rssnr; /* The current reference signal signal-to-noise ratio in 0.1 dB units. * Range: -200 to +300 (-200 = -20.0 dB, +300 = 30dB). * INT_MAX : 0x7FFFFFFF denotes invalid value. * Reference: 3GPP TS 36.101 8.1.1 */ int cqi; /* The current Channel Quality Indicator. * Range: 0 to 15. * INT_MAX : 0x7FFFFFFF denotes invalid value. * Reference: 3GPP TS 36.101 9.2, 9.3, A.4 */ int timingAdvance; /* timing advance in micro seconds for a one way trip from cell to device. * Approximate distance can be calculated using 300m/us * timingAdvance. * Range: 0 to 0x7FFFFFFE * INT_MAX : 0x7FFFFFFF denotes invalid value. * Reference: 3GPP 36.321 section 6.1.3.5 * also: http://www.cellular-planningoptimization.com/2010/02/timing-advance-with-calculation.html */ } RIL_LTE_SignalStrength_v8; typedef struct { int rscp; /* The Received Signal Code Power in dBm multipled by -1. * Range : 25 to 120 * INT_MAX: 0x7FFFFFFF denotes invalid value. * Reference: 3GPP TS 25.123, section 9.1.1.1 */ } RIL_TD_SCDMA_SignalStrength; /* Deprecated, use RIL_SignalStrength_v6 */ typedef struct { RIL_GW_SignalStrength GW_SignalStrength; RIL_CDMA_SignalStrength CDMA_SignalStrength; RIL_EVDO_SignalStrength EVDO_SignalStrength; } RIL_SignalStrength_v5; typedef struct { RIL_GW_SignalStrength GW_SignalStrength; RIL_CDMA_SignalStrength CDMA_SignalStrength; RIL_EVDO_SignalStrength EVDO_SignalStrength; RIL_LTE_SignalStrength LTE_SignalStrength; } RIL_SignalStrength_v6; typedef struct { RIL_GW_SignalStrength GW_SignalStrength; RIL_CDMA_SignalStrength CDMA_SignalStrength; RIL_EVDO_SignalStrength EVDO_SignalStrength; RIL_LTE_SignalStrength_v8 LTE_SignalStrength; } RIL_SignalStrength_v8; typedef struct { RIL_GW_SignalStrength GW_SignalStrength; RIL_CDMA_SignalStrength CDMA_SignalStrength; RIL_EVDO_SignalStrength EVDO_SignalStrength; RIL_LTE_SignalStrength_v8 LTE_SignalStrength; RIL_TD_SCDMA_SignalStrength TD_SCDMA_SignalStrength; } RIL_SignalStrength_v10; typedef struct { int mcc; /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */ int mnc; /* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown */ int lac; /* 16-bit Location Area Code, 0..65535, INT_MAX if unknown */ int cid; /* 16-bit GSM Cell Identity described in TS 27.007, 0..65535, INT_MAX if unknown */ } RIL_CellIdentityGsm; typedef struct { int mcc; /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */ int mnc; /* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown */ int lac; /* 16-bit Location Area Code, 0..65535, INT_MAX if unknown */ int cid; /* 16-bit GSM Cell Identity described in TS 27.007, 0..65535, INT_MAX if unknown */ int arfcn; /* 16-bit GSM Absolute RF channel number, INT_MAX if unknown */ uint8_t bsic;/* 6-bit Base Station Identity Code, 0xFF if unknown */ } RIL_CellIdentityGsm_v12; typedef struct { int mcc; /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */ int mnc; /* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown */ int lac; /* 16-bit Location Area Code, 0..65535, INT_MAX if unknown */ int cid; /* 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, INT_MAX if unknown */ int psc; /* 9-bit UMTS Primary Scrambling Code described in TS 25.331, 0..511, INT_MAX if unknown */ } RIL_CellIdentityWcdma; typedef struct { int mcc; /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */ int mnc; /* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown */ int lac; /* 16-bit Location Area Code, 0..65535, INT_MAX if unknown */ int cid; /* 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, INT_MAX if unknown */ int psc; /* 9-bit UMTS Primary Scrambling Code described in TS 25.331, 0..511, INT_MAX if unknown */ int uarfcn; /* 16-bit UMTS Absolute RF Channel Number, INT_MAX if unknown */ } RIL_CellIdentityWcdma_v12; typedef struct { int networkId; /* Network Id 0..65535, INT_MAX if unknown */ int systemId; /* CDMA System Id 0..32767, INT_MAX if unknown */ int basestationId; /* Base Station Id 0..65535, INT_MAX if unknown */ int longitude; /* Longitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0. * It is represented in units of 0.25 seconds and ranges from -2592000 * to 2592000, both values inclusive (corresponding to a range of -180 * to +180 degrees). INT_MAX if unknown */ int latitude; /* Latitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0. * It is represented in units of 0.25 seconds and ranges from -1296000 * to 1296000, both values inclusive (corresponding to a range of -90 * to +90 degrees). INT_MAX if unknown */ } RIL_CellIdentityCdma; typedef struct { int mcc; /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */ int mnc; /* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown */ int ci; /* 28-bit Cell Identity described in TS ???, INT_MAX if unknown */ int pci; /* physical cell id 0..503, INT_MAX if unknown */ int tac; /* 16-bit tracking area code, INT_MAX if unknown */ } RIL_CellIdentityLte; typedef struct { int mcc; /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */ int mnc; /* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown */ int ci; /* 28-bit Cell Identity described in TS ???, INT_MAX if unknown */ int pci; /* physical cell id 0..503, INT_MAX if unknown */ int tac; /* 16-bit tracking area code, INT_MAX if unknown */ int earfcn; /* 18-bit LTE Absolute RC Channel Number, INT_MAX if unknown */ } RIL_CellIdentityLte_v12; typedef struct { int mcc; /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */ int mnc; /* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown */ int lac; /* 16-bit Location Area Code, 0..65535, INT_MAX if unknown */ int cid; /* 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, INT_MAX if unknown */ int cpid; /* 8-bit Cell Parameters ID described in TS 25.331, 0..127, INT_MAX if unknown */ } RIL_CellIdentityTdscdma; typedef struct { RIL_CellIdentityGsm cellIdentityGsm; RIL_GW_SignalStrength signalStrengthGsm; } RIL_CellInfoGsm; typedef struct { RIL_CellIdentityGsm_v12 cellIdentityGsm; RIL_GSM_SignalStrength_v12 signalStrengthGsm; } RIL_CellInfoGsm_v12; typedef struct { RIL_CellIdentityWcdma cellIdentityWcdma; RIL_SignalStrengthWcdma signalStrengthWcdma; } RIL_CellInfoWcdma; typedef struct { RIL_CellIdentityWcdma_v12 cellIdentityWcdma; RIL_SignalStrengthWcdma signalStrengthWcdma; } RIL_CellInfoWcdma_v12; typedef struct { RIL_CellIdentityCdma cellIdentityCdma; RIL_CDMA_SignalStrength signalStrengthCdma; RIL_EVDO_SignalStrength signalStrengthEvdo; } RIL_CellInfoCdma; typedef struct { RIL_CellIdentityLte cellIdentityLte; RIL_LTE_SignalStrength_v8 signalStrengthLte; } RIL_CellInfoLte; typedef struct { RIL_CellIdentityLte_v12 cellIdentityLte; RIL_LTE_SignalStrength_v8 signalStrengthLte; } RIL_CellInfoLte_v12; typedef struct { RIL_CellIdentityTdscdma cellIdentityTdscdma; RIL_TD_SCDMA_SignalStrength signalStrengthTdscdma; } RIL_CellInfoTdscdma; // Must be the same as CellInfo.TYPE_XXX typedef enum { RIL_CELL_INFO_TYPE_GSM = 1, RIL_CELL_INFO_TYPE_CDMA = 2, RIL_CELL_INFO_TYPE_LTE = 3, RIL_CELL_INFO_TYPE_WCDMA = 4, RIL_CELL_INFO_TYPE_TD_SCDMA = 5 } RIL_CellInfoType; // Must be the same as CellInfo.TIMESTAMP_TYPE_XXX typedef enum { RIL_TIMESTAMP_TYPE_UNKNOWN = 0, RIL_TIMESTAMP_TYPE_ANTENNA = 1, RIL_TIMESTAMP_TYPE_MODEM = 2, RIL_TIMESTAMP_TYPE_OEM_RIL = 3, RIL_TIMESTAMP_TYPE_JAVA_RIL = 4, } RIL_TimeStampType; typedef struct { RIL_CellInfoType cellInfoType; /* cell type for selecting from union CellInfo */ int registered; /* !0 if this cell is registered 0 if not registered */ RIL_TimeStampType timeStampType; /* type of time stamp represented by timeStamp */ uint64_t timeStamp; /* Time in nanos as returned by ril_nano_time */ union { RIL_CellInfoGsm gsm; RIL_CellInfoCdma cdma; RIL_CellInfoLte lte; RIL_CellInfoWcdma wcdma; RIL_CellInfoTdscdma tdscdma; } CellInfo; } RIL_CellInfo; typedef struct { RIL_CellInfoType cellInfoType; /* cell type for selecting from union CellInfo */ int registered; /* !0 if this cell is registered 0 if not registered */ RIL_TimeStampType timeStampType; /* type of time stamp represented by timeStamp */ uint64_t timeStamp; /* Time in nanos as returned by ril_nano_time */ union { RIL_CellInfoGsm_v12 gsm; RIL_CellInfoCdma cdma; RIL_CellInfoLte_v12 lte; RIL_CellInfoWcdma_v12 wcdma; RIL_CellInfoTdscdma tdscdma; } CellInfo; } RIL_CellInfo_v12; /* Names of the CDMA info records (C.S0005 section 3.7.5) */ typedef enum { RIL_CDMA_DISPLAY_INFO_REC, RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC, RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC, RIL_CDMA_CONNECTED_NUMBER_INFO_REC, RIL_CDMA_SIGNAL_INFO_REC, RIL_CDMA_REDIRECTING_NUMBER_INFO_REC, RIL_CDMA_LINE_CONTROL_INFO_REC, RIL_CDMA_EXTENDED_DISPLAY_INFO_REC, RIL_CDMA_T53_CLIR_INFO_REC, RIL_CDMA_T53_RELEASE_INFO_REC, RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC } RIL_CDMA_InfoRecName; /* Display Info Rec as defined in C.S0005 section 3.7.5.1 Extended Display Info Rec as defined in C.S0005 section 3.7.5.16 Note: the Extended Display info rec contains multiple records of the form: display_tag, display_len, and display_len occurrences of the chari field if the display_tag is not 10000000 or 10000001. To save space, the records are stored consecutively in a byte buffer. The display_tag, display_len and chari fields are all 1 byte. */ typedef struct { char alpha_len; char alpha_buf[CDMA_ALPHA_INFO_BUFFER_LENGTH]; } RIL_CDMA_DisplayInfoRecord; /* Called Party Number Info Rec as defined in C.S0005 section 3.7.5.2 Calling Party Number Info Rec as defined in C.S0005 section 3.7.5.3 Connected Number Info Rec as defined in C.S0005 section 3.7.5.4 */ typedef struct { char len; char buf[CDMA_NUMBER_INFO_BUFFER_LENGTH]; char number_type; char number_plan; char pi; char si; } RIL_CDMA_NumberInfoRecord; /* Redirecting Number Information Record as defined in C.S0005 section 3.7.5.11 */ typedef enum { RIL_REDIRECTING_REASON_UNKNOWN = 0, RIL_REDIRECTING_REASON_CALL_FORWARDING_BUSY = 1, RIL_REDIRECTING_REASON_CALL_FORWARDING_NO_REPLY = 2, RIL_REDIRECTING_REASON_CALLED_DTE_OUT_OF_ORDER = 9, RIL_REDIRECTING_REASON_CALL_FORWARDING_BY_THE_CALLED_DTE = 10, RIL_REDIRECTING_REASON_CALL_FORWARDING_UNCONDITIONAL = 15, RIL_REDIRECTING_REASON_RESERVED } RIL_CDMA_RedirectingReason; typedef struct { RIL_CDMA_NumberInfoRecord redirectingNumber; /* redirectingReason is set to RIL_REDIRECTING_REASON_UNKNOWN if not included */ RIL_CDMA_RedirectingReason redirectingReason; } RIL_CDMA_RedirectingNumberInfoRecord; /* Line Control Information Record as defined in C.S0005 section 3.7.5.15 */ typedef struct { char lineCtrlPolarityIncluded; char lineCtrlToggle; char lineCtrlReverse; char lineCtrlPowerDenial; } RIL_CDMA_LineControlInfoRecord; /* T53 CLIR Information Record */ typedef struct { char cause; } RIL_CDMA_T53_CLIRInfoRecord; /* T53 Audio Control Information Record */ typedef struct { char upLink; char downLink; } RIL_CDMA_T53_AudioControlInfoRecord; typedef struct { RIL_CDMA_InfoRecName name; union { /* Display and Extended Display Info Rec */ RIL_CDMA_DisplayInfoRecord display; /* Called Party Number, Calling Party Number, Connected Number Info Rec */ RIL_CDMA_NumberInfoRecord number; /* Signal Info Rec */ RIL_CDMA_SignalInfoRecord signal; /* Redirecting Number Info Rec */ RIL_CDMA_RedirectingNumberInfoRecord redir; /* Line Control Info Rec */ RIL_CDMA_LineControlInfoRecord lineCtrl; /* T53 CLIR Info Rec */ RIL_CDMA_T53_CLIRInfoRecord clir; /* T53 Audio Control Info Rec */ RIL_CDMA_T53_AudioControlInfoRecord audioCtrl; } rec; } RIL_CDMA_InformationRecord; #define RIL_CDMA_MAX_NUMBER_OF_INFO_RECS 10 typedef struct { char numberOfInfoRecs; RIL_CDMA_InformationRecord infoRec[RIL_CDMA_MAX_NUMBER_OF_INFO_RECS]; } RIL_CDMA_InformationRecords; /* See RIL_REQUEST_NV_READ_ITEM */ typedef struct { RIL_NV_Item itemID; } RIL_NV_ReadItem; /* See RIL_REQUEST_NV_WRITE_ITEM */ typedef struct { RIL_NV_Item itemID; char * value; } RIL_NV_WriteItem; typedef enum { HANDOVER_STARTED = 0, HANDOVER_COMPLETED = 1, HANDOVER_FAILED = 2, HANDOVER_CANCELED = 3 } RIL_SrvccState; /* hardware configuration reported to RILJ. */ typedef enum { RIL_HARDWARE_CONFIG_MODEM = 0, RIL_HARDWARE_CONFIG_SIM = 1, } RIL_HardwareConfig_Type; typedef enum { RIL_HARDWARE_CONFIG_STATE_ENABLED = 0, RIL_HARDWARE_CONFIG_STATE_STANDBY = 1, RIL_HARDWARE_CONFIG_STATE_DISABLED = 2, } RIL_HardwareConfig_State; typedef struct { int rilModel; uint32_t rat; /* bitset - ref. RIL_RadioTechnology. */ int maxVoice; int maxData; int maxStandby; } RIL_HardwareConfig_Modem; typedef struct { char modemUuid[MAX_UUID_LENGTH]; } RIL_HardwareConfig_Sim; typedef struct { RIL_HardwareConfig_Type type; char uuid[MAX_UUID_LENGTH]; RIL_HardwareConfig_State state; union { RIL_HardwareConfig_Modem modem; RIL_HardwareConfig_Sim sim; } cfg; } RIL_HardwareConfig; typedef enum { SS_CFU, SS_CF_BUSY, SS_CF_NO_REPLY, SS_CF_NOT_REACHABLE, SS_CF_ALL, SS_CF_ALL_CONDITIONAL, SS_CLIP, SS_CLIR, SS_COLP, SS_COLR, SS_WAIT, SS_BAOC, SS_BAOIC, SS_BAOIC_EXC_HOME, SS_BAIC, SS_BAIC_ROAMING, SS_ALL_BARRING, SS_OUTGOING_BARRING, SS_INCOMING_BARRING } RIL_SsServiceType; typedef enum { SS_ACTIVATION, SS_DEACTIVATION, SS_INTERROGATION, SS_REGISTRATION, SS_ERASURE } RIL_SsRequestType; typedef enum { SS_ALL_TELE_AND_BEARER_SERVICES, SS_ALL_TELESEVICES, SS_TELEPHONY, SS_ALL_DATA_TELESERVICES, SS_SMS_SERVICES, SS_ALL_TELESERVICES_EXCEPT_SMS } RIL_SsTeleserviceType; #define SS_INFO_MAX 4 #define NUM_SERVICE_CLASSES 7 typedef struct { int numValidIndexes; /* This gives the number of valid values in cfInfo. For example if voice is forwarded to one number and data is forwarded to a different one then numValidIndexes will be 2 indicating total number of valid values in cfInfo. Similarly if all the services are forwarded to the same number then the value of numValidIndexes will be 1. */ RIL_CallForwardInfo cfInfo[NUM_SERVICE_CLASSES]; /* This is the response data for SS request to query call forward status. see RIL_REQUEST_QUERY_CALL_FORWARD_STATUS */ } RIL_CfData; typedef struct { RIL_SsServiceType serviceType; RIL_SsRequestType requestType; RIL_SsTeleserviceType teleserviceType; int serviceClass; RIL_Errno result; union { int ssInfo[SS_INFO_MAX]; /* This is the response data for most of the SS GET/SET RIL requests. E.g. RIL_REQUSET_GET_CLIR returns two ints, so first two values of ssInfo[] will be used for response if serviceType is SS_CLIR and requestType is SS_INTERROGATION */ RIL_CfData cfData; }; } RIL_StkCcUnsolSsResponse; /** * Data connection power state */ typedef enum { RIL_DC_POWER_STATE_LOW = 1, // Low power state RIL_DC_POWER_STATE_MEDIUM = 2, // Medium power state RIL_DC_POWER_STATE_HIGH = 3, // High power state RIL_DC_POWER_STATE_UNKNOWN = INT32_MAX // Unknown state } RIL_DcPowerStates; /** * Data connection real time info */ typedef struct { uint64_t time; // Time in nanos as returned by ril_nano_time RIL_DcPowerStates powerState; // Current power state } RIL_DcRtInfo; /** * Data profile to modem */ typedef struct { /* id of the data profile */ int profileId; /* the APN to connect to */ char* apn; /** one of the PDP_type values in TS 27.007 section 10.1.1. * For example, "IP", "IPV6", "IPV4V6", or "PPP". */ char* protocol; /** authentication protocol used for this PDP context * (None: 0, PAP: 1, CHAP: 2, PAP&CHAP: 3) */ int authType; /* the username for APN, or NULL */ char* user; /* the password for APN, or NULL */ char* password; /* the profile type, TYPE_COMMON-0, TYPE_3GPP-1, TYPE_3GPP2-2 */ int type; /* the period in seconds to limit the maximum connections */ int maxConnsTime; /* the maximum connections during maxConnsTime */ int maxConns; /** the required wait time in seconds after a successful UE initiated * disconnect of a given PDN connection before the device can send * a new PDN connection request for that given PDN */ int waitTime; /* true to enable the profile, 0 to disable, 1 to enable */ int enabled; } RIL_DataProfileInfo; /* Tx Power Levels */ #define RIL_NUM_TX_POWER_LEVELS 5 typedef struct { /* period (in ms) when modem is power collapsed */ uint32_t sleep_mode_time_ms; /* period (in ms) when modem is awake and in idle mode*/ uint32_t idle_mode_time_ms; /* period (in ms) for which Tx is active */ uint32_t tx_mode_time_ms[RIL_NUM_TX_POWER_LEVELS]; /* period (in ms) for which Rx is active */ uint32_t rx_mode_time_ms; } RIL_ActivityStatsInfo; typedef struct { uint8_t p2; /* P2 parameter */ char * aidPtr; /* AID value, See ETSI 102.221 and 101.220*/ } RIL_CafOpenChannelParams; #define RIL_NUM_ADN_RECORDS 10 #define RIL_MAX_NUM_AD_COUNT 4 #define RIL_MAX_NUM_EMAIL_COUNT 2 typedef struct { int record_id; char* name; char* number; int email_elements; char* email[RIL_MAX_NUM_EMAIL_COUNT]; int anr_elements; char* ad_number[RIL_MAX_NUM_AD_COUNT]; } RIL_AdnRecordInfo; typedef struct { int record_elements; RIL_AdnRecordInfo adn_record_info[RIL_NUM_ADN_RECORDS]; } RIL_AdnRecord_v1; /** * RIL_REQUEST_GET_SIM_STATUS * * Requests status of the SIM interface and the SIM card * * "data" is NULL * * "response" is const RIL_CardStatus_v6 * * * Valid errors: * Must never fail */ #define RIL_REQUEST_GET_SIM_STATUS 1 /** * RIL_REQUEST_ENTER_SIM_PIN * * Supplies SIM PIN. Only called if RIL_CardStatus has RIL_APPSTATE_PIN state * * "data" is const char ** * ((const char **)data)[0] is PIN value * ((const char **)data)[1] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. * * "response" is int * * ((int *)response)[0] is the number of retries remaining, or -1 if unknown * * Valid errors: * * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * GENERIC_FAILURE * PASSWORD_INCORRECT */ #define RIL_REQUEST_ENTER_SIM_PIN 2 /** * RIL_REQUEST_ENTER_SIM_PUK * * Supplies SIM PUK and new PIN. * * "data" is const char ** * ((const char **)data)[0] is PUK value * ((const char **)data)[1] is new PIN value * ((const char **)data)[2] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. * * "response" is int * * ((int *)response)[0] is the number of retries remaining, or -1 if unknown * * Valid errors: * * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * GENERIC_FAILURE * PASSWORD_INCORRECT * (PUK is invalid) */ #define RIL_REQUEST_ENTER_SIM_PUK 3 /** * RIL_REQUEST_ENTER_SIM_PIN2 * * Supplies SIM PIN2. Only called following operation where SIM_PIN2 was * returned as a a failure from a previous operation. * * "data" is const char ** * ((const char **)data)[0] is PIN2 value * ((const char **)data)[1] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. * * "response" is int * * ((int *)response)[0] is the number of retries remaining, or -1 if unknown * * Valid errors: * * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * GENERIC_FAILURE * PASSWORD_INCORRECT */ #define RIL_REQUEST_ENTER_SIM_PIN2 4 /** * RIL_REQUEST_ENTER_SIM_PUK2 * * Supplies SIM PUK2 and new PIN2. * * "data" is const char ** * ((const char **)data)[0] is PUK2 value * ((const char **)data)[1] is new PIN2 value * ((const char **)data)[2] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. * * "response" is int * * ((int *)response)[0] is the number of retries remaining, or -1 if unknown * * Valid errors: * * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * GENERIC_FAILURE * PASSWORD_INCORRECT * (PUK2 is invalid) */ #define RIL_REQUEST_ENTER_SIM_PUK2 5 /** * RIL_REQUEST_CHANGE_SIM_PIN * * Supplies old SIM PIN and new PIN. * * "data" is const char ** * ((const char **)data)[0] is old PIN value * ((const char **)data)[1] is new PIN value * ((const char **)data)[2] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. * * "response" is int * * ((int *)response)[0] is the number of retries remaining, or -1 if unknown * * Valid errors: * * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * GENERIC_FAILURE * PASSWORD_INCORRECT * (old PIN is invalid) * */ #define RIL_REQUEST_CHANGE_SIM_PIN 6 /** * RIL_REQUEST_CHANGE_SIM_PIN2 * * Supplies old SIM PIN2 and new PIN2. * * "data" is const char ** * ((const char **)data)[0] is old PIN2 value * ((const char **)data)[1] is new PIN2 value * ((const char **)data)[2] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. * * "response" is int * * ((int *)response)[0] is the number of retries remaining, or -1 if unknown * * Valid errors: * * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * GENERIC_FAILURE * PASSWORD_INCORRECT * (old PIN2 is invalid) * */ #define RIL_REQUEST_CHANGE_SIM_PIN2 7 /** * RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION * * Requests that network personlization be deactivated * * "data" is const char ** * ((const char **)(data))[0]] is network depersonlization code * * "response" is int * * ((int *)response)[0] is the number of retries remaining, or -1 if unknown * * Valid errors: * * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * GENERIC_FAILURE * PASSWORD_INCORRECT * (code is invalid) */ #define RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION 8 /** * RIL_REQUEST_GET_CURRENT_CALLS * * Requests current call list * * "data" is NULL * * "response" must be a "const RIL_Call **" * * Valid errors: * * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * NO_MEMORY * GENERIC_FAILURE * (request will be made again in a few hundred msec) */ #define RIL_REQUEST_GET_CURRENT_CALLS 9 /** * RIL_REQUEST_DIAL * * Initiate voice call * * "data" is const RIL_Dial * * "response" is NULL * * This method is never used for supplementary service codes * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * DIAL_MODIFIED_TO_USSD * DIAL_MODIFIED_TO_SS * DIAL_MODIFIED_TO_DIAL * INVALID_ARGUMENTS * NO_MEMORY * INVALID_STATE * NO_RESOURCES * INTERNAL_ERR * FDN_CHECK_FAILURE * MODEM_ERR * NO_SUBSCRIPTION * NO_NETWORK_FOUND * INVALID_CALL_ID * DEVICE_IN_USE * MODE_NOT_SUPPORTED * ABORTED * GENERIC_FAILURE */ #define RIL_REQUEST_DIAL 10 /** * RIL_REQUEST_GET_IMSI * * Get the SIM IMSI * * Only valid when radio state is "RADIO_STATE_ON" * * "data" is const char ** * ((const char **)data)[0] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. * "response" is a const char * containing the IMSI * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * GENERIC_FAILURE */ #define RIL_REQUEST_GET_IMSI 11 /** * RIL_REQUEST_HANGUP * * Hang up a specific line (like AT+CHLD=1x) * * After this HANGUP request returns, RIL should show the connection is NOT * active anymore in next RIL_REQUEST_GET_CURRENT_CALLS query. * * "data" is an int * * (int *)data)[0] contains Connection index (value of 'x' in CHLD above) * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * INVALID_ARGUMENTS * NO_MEMORY * INVALID_STATE * MODEM_ERR * INTERNAL_ERR * NO_MEMORY * INVALID_CALL_ID * INVALID_ARGUMENTS * GENERIC_FAILURE */ #define RIL_REQUEST_HANGUP 12 /** * RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND * * Hang up waiting or held (like AT+CHLD=0) * * After this HANGUP request returns, RIL should show the connection is NOT * active anymore in next RIL_REQUEST_GET_CURRENT_CALLS query. * * "data" is NULL * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * INVALID_STATE * NO_MEMORY * MODEM_ERR * INTERNAL_ERR * NO_MEMORY * INVALID_CALL_ID * NO_RESOURCES * OPERATION_NOT_ALLOWED * INVALID_ARGUMENTS * GENERIC_FAILURE */ #define RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND 13 /** * RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND * * Hang up waiting or held (like AT+CHLD=1) * * After this HANGUP request returns, RIL should show the connection is NOT * active anymore in next RIL_REQUEST_GET_CURRENT_CALLS query. * * "data" is NULL * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * INVALID_STATE * NO_MEMORY * MODEM_ERR * INTERNAL_ERR * INVALID_CALL_ID * OPERATION_NOT_ALLOWED * INVALID_ARGUMENTS * NO_RESOURCES * GENERIC_FAILURE */ #define RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND 14 /** * RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE * * Switch waiting or holding call and active call (like AT+CHLD=2) * * State transitions should be is follows: * * If call 1 is waiting and call 2 is active, then if this re * * BEFORE AFTER * Call 1 Call 2 Call 1 Call 2 * ACTIVE HOLDING HOLDING ACTIVE * ACTIVE WAITING HOLDING ACTIVE * HOLDING WAITING HOLDING ACTIVE * ACTIVE IDLE HOLDING IDLE * IDLE IDLE IDLE IDLE * * "data" is NULL * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * INVALID_STATE * NO_MEMORY * MODEM_ERR * INTERNAL_ERR * INVALID_STATE * INVALID_ARGUMENTS * INVALID_CALL_ID * OPERATION_NOT_ALLOWED * GENERIC_FAILURE */ #define RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE 15 #define RIL_REQUEST_SWITCH_HOLDING_AND_ACTIVE 15 /** * RIL_REQUEST_CONFERENCE * * Conference holding and active (like AT+CHLD=3) * "data" is NULL * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * NO_MEMORY * MODEM_ERR * INTERNAL_ERR * INVALID_STATE * INVALID_CALL_ID * INVALID_ARGUMENTS * OPERATION_NOT_ALLOWED * GENERIC_FAILURE */ #define RIL_REQUEST_CONFERENCE 16 /** * RIL_REQUEST_UDUB * * Send UDUB (user determined used busy) to ringing or * waiting call answer)(RIL_BasicRequest r); * * "data" is NULL * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * INVALID_STATE * NO_RESOURCES * NO_MEMORY * MODEM_ERR * INTERNAL_ERR * INVALID_CALL_ID * OPERATION_NOT_ALLOWED * INVALID_ARGUMENTS * GENERIC_FAILURE */ #define RIL_REQUEST_UDUB 17 /** * RIL_REQUEST_LAST_CALL_FAIL_CAUSE * * Requests the failure cause code for the most recently terminated call * * "data" is NULL * "response" is a "int *" * ((int *)response)[0] is RIL_LastCallFailCause. GSM failure reasons are * mapped to cause codes defined in TS 24.008 Annex H where possible. CDMA * failure reasons are derived from the possible call failure scenarios * described in the "CDMA IS-2000 Release A (C.S0005-A v6.0)" standard. * * The implementation should return CALL_FAIL_ERROR_UNSPECIFIED for blocked * MO calls by restricted state (See RIL_UNSOL_RESTRICTED_STATE_CHANGED) * * If the implementation does not have access to the exact cause codes, * then it should return one of the values listed in RIL_LastCallFailCause, * as the UI layer needs to distinguish these cases for tone generation or * error notification. * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * NO_MEMORY * GENERIC_FAILURE * * See also: RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE */ #define RIL_REQUEST_LAST_CALL_FAIL_CAUSE 18 /** * RIL_REQUEST_SIGNAL_STRENGTH * * Requests current signal strength and associated information * * Must succeed if radio is on. * * "data" is NULL * * "response" is a const RIL_SignalStrength * * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE */ #define RIL_REQUEST_SIGNAL_STRENGTH 19 /** * RIL_REQUEST_VOICE_REGISTRATION_STATE * * Request current registration state * * "data" is NULL * "response" is a "char **" * ((const char **)response)[0] is registration state 0-6, * 0 - Not registered, MT is not currently searching * a new operator to register * 1 - Registered, home network * 2 - Not registered, but MT is currently searching * a new operator to register * 3 - Registration denied * 4 - Unknown * 5 - Registered, roaming * 10 - Same as 0, but indicates that emergency calls * are enabled. * 12 - Same as 2, but indicates that emergency calls * are enabled. * 13 - Same as 3, but indicates that emergency calls * are enabled. * 14 - Same as 4, but indicates that emergency calls * are enabled. * * ((const char **)response)[1] is LAC if registered on a GSM/WCDMA system or * NULL if not.Valid LAC are 0x0000 - 0xffff * ((const char **)response)[2] is CID if registered on a * GSM/WCDMA or * NULL if not. * Valid CID are 0x00000000 - 0xffffffff * In GSM, CID is Cell ID (see TS 27.007) * in 16 bits * In UMTS, CID is UMTS Cell Identity * (see TS 25.331) in 28 bits * ((const char **)response)[3] indicates the available voice radio technology, * valid values as defined by RIL_RadioTechnology. * ((const char **)response)[4] is Base Station ID if registered on a CDMA * system or NULL if not. Base Station ID in * decimal format * ((const char **)response)[5] is Base Station latitude if registered on a * CDMA system or NULL if not. Base Station * latitude is a decimal number as specified in * 3GPP2 C.S0005-A v6.0. It is represented in * units of 0.25 seconds and ranges from -1296000 * to 1296000, both values inclusive (corresponding * to a range of -90 to +90 degrees). * ((const char **)response)[6] is Base Station longitude if registered on a * CDMA system or NULL if not. Base Station * longitude is a decimal number as specified in * 3GPP2 C.S0005-A v6.0. It is represented in * units of 0.25 seconds and ranges from -2592000 * to 2592000, both values inclusive (corresponding * to a range of -180 to +180 degrees). * ((const char **)response)[7] is concurrent services support indicator if * registered on a CDMA system 0-1. * 0 - Concurrent services not supported, * 1 - Concurrent services supported * ((const char **)response)[8] is System ID if registered on a CDMA system or * NULL if not. Valid System ID are 0 - 32767 * ((const char **)response)[9] is Network ID if registered on a CDMA system or * NULL if not. Valid System ID are 0 - 65535 * ((const char **)response)[10] is the TSB-58 Roaming Indicator if registered * on a CDMA or EVDO system or NULL if not. Valid values * are 0-255. * ((const char **)response)[11] indicates whether the current system is in the * PRL if registered on a CDMA or EVDO system or NULL if * not. 0=not in the PRL, 1=in the PRL * ((const char **)response)[12] is the default Roaming Indicator from the PRL, * if registered on a CDMA or EVDO system or NULL if not. * Valid values are 0-255. * ((const char **)response)[13] if registration state is 3 (Registration * denied) this is an enumerated reason why * registration was denied. See 3GPP TS 24.008, * 10.5.3.6 and Annex G. * 0 - General * 1 - Authentication Failure * 2 - IMSI unknown in HLR * 3 - Illegal MS * 4 - Illegal ME * 5 - PLMN not allowed * 6 - Location area not allowed * 7 - Roaming not allowed * 8 - No Suitable Cells in this Location Area * 9 - Network failure * 10 - Persistent location update reject * 11 - PLMN not allowed * 12 - Location area not allowed * 13 - Roaming not allowed in this Location Area * 15 - No Suitable Cells in this Location Area * 17 - Network Failure * 20 - MAC Failure * 21 - Sync Failure * 22 - Congestion * 23 - GSM Authentication unacceptable * 25 - Not Authorized for this CSG * 32 - Service option not supported * 33 - Requested service option not subscribed * 34 - Service option temporarily out of order * 38 - Call cannot be identified * 48-63 - Retry upon entry into a new cell * 95 - Semantically incorrect message * 96 - Invalid mandatory information * 97 - Message type non-existent or not implemented * 98 - Message not compatible with protocol state * 99 - Information element non-existent or not implemented * 100 - Conditional IE error * 101 - Message not compatible with protocol state * 111 - Protocol error, unspecified * ((const char **)response)[14] is the Primary Scrambling Code of the current * cell as described in TS 25.331, in hexadecimal * format, or NULL if unknown or not registered * to a UMTS network. * * Please note that registration state 4 ("unknown") is treated * as "out of service" in the Android telephony system * * Registration state 3 can be returned if Location Update Reject * (with cause 17 - Network Failure) is received repeatedly from the network, * to facilitate "managed roaming" * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE */ #define RIL_REQUEST_VOICE_REGISTRATION_STATE 20 /** * RIL_REQUEST_DATA_REGISTRATION_STATE * * Request current DATA registration state * * "data" is NULL * "response" is a "char **" * ((const char **)response)[0] is registration state 0-5 from TS 27.007 10.1.20 AT+CGREG * ((const char **)response)[1] is LAC if registered or NULL if not * ((const char **)response)[2] is CID if registered or NULL if not * ((const char **)response)[3] indicates the available data radio technology, * valid values as defined by RIL_RadioTechnology. * ((const char **)response)[4] if registration state is 3 (Registration * denied) this is an enumerated reason why * registration was denied. See 3GPP TS 24.008, * Annex G.6 "Additonal cause codes for GMM". * 7 == GPRS services not allowed * 8 == GPRS services and non-GPRS services not allowed * 9 == MS identity cannot be derived by the network * 10 == Implicitly detached * 14 == GPRS services not allowed in this PLMN * 16 == MSC temporarily not reachable * 40 == No PDP context activated * ((const char **)response)[5] The maximum number of simultaneous Data Calls that can be * established using RIL_REQUEST_SETUP_DATA_CALL. * * The values at offsets 6..10 are optional LTE location information in decimal. * If a value is unknown that value may be NULL. If all values are NULL, * none need to be present. * ((const char **)response)[6] is TAC, a 16-bit Tracking Area Code. * ((const char **)response)[7] is CID, a 0-503 Physical Cell Identifier. * ((const char **)response)[8] is ECI, a 28-bit E-UTRAN Cell Identifier. * ((const char **)response)[9] is CSGID, a 27-bit Closed Subscriber Group Identity. * ((const char **)response)[10] is TADV, a 6-bit timing advance value. * * LAC and CID are in hexadecimal format. * valid LAC are 0x0000 - 0xffff * valid CID are 0x00000000 - 0x0fffffff * * Please note that registration state 4 ("unknown") is treated * as "out of service" in the Android telephony system * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE */ #define RIL_REQUEST_DATA_REGISTRATION_STATE 21 /** * RIL_REQUEST_OPERATOR * * Request current operator ONS or EONS * * "data" is NULL * "response" is a "const char **" * ((const char **)response)[0] is long alpha ONS or EONS * or NULL if unregistered * * ((const char **)response)[1] is short alpha ONS or EONS * or NULL if unregistered * ((const char **)response)[2] is 5 or 6 digit numeric code (MCC + MNC) * or NULL if unregistered * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE */ #define RIL_REQUEST_OPERATOR 22 /** * RIL_REQUEST_RADIO_POWER * * Toggle radio on and off (for "airplane" mode) * If the radio is is turned off/on the radio modem subsystem * is expected return to an initialized state. For instance, * any voice and data calls will be terminated and all associated * lists emptied. * * "data" is int * * ((int *)data)[0] is > 0 for "Radio On" * ((int *)data)[0] is == 0 for "Radio Off" * * "response" is NULL * * Turn radio on if "on" > 0 * Turn radio off if "on" == 0 * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * OPERATION_NOT_ALLOWED * GENERIC_FAILURE */ #define RIL_REQUEST_RADIO_POWER 23 /** * RIL_REQUEST_DTMF * * Send a DTMF tone * * If the implementation is currently playing a tone requested via * RIL_REQUEST_DTMF_START, that tone should be cancelled and the new tone * should be played instead * * "data" is a char * containing a single character with one of 12 values: 0-9,*,# * "response" is NULL * * FIXME should this block/mute microphone? * How does this interact with local DTMF feedback? * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * INVALID_ARGUMENTS * NO_RESOURCES * NO_MEMORY * MODEM_ERR * INTERNAL_ERR * INVALID_CALL_ID * GENERIC_FAILURE * * See also: RIL_REQUEST_DTMF_STOP, RIL_REQUEST_DTMF_START * */ #define RIL_REQUEST_DTMF 24 /** * RIL_REQUEST_SEND_SMS * * Send an SMS message * * "data" is const char ** * ((const char **)data)[0] is SMSC address in GSM BCD format prefixed * by a length byte (as expected by TS 27.005) or NULL for default SMSC * ((const char **)data)[1] is SMS in PDU format as an ASCII hex string * less the SMSC address * TP-Layer-Length is be "strlen(((const char **)data)[1])/2" * * "response" is a const RIL_SMS_Response * * * Based on the return error, caller decides to resend if sending sms * fails. SMS_SEND_FAIL_RETRY means retry (i.e. error cause is 332) * and GENERIC_FAILURE means no retry (i.e. error cause is 500) * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * SMS_SEND_FAIL_RETRY * FDN_CHECK_FAILURE * NETWORK_REJECT * INVALID_STATE * INVALID_ARGUMENTS * NO_MEMORY * REQUEST_RATE_LIMITED * INVALID_SMS_FORMAT * SYSTEM_ERR * ENCODING_ERR * INVALID_SMSC_ADDRESS * MODEM_ERR * NETWORK_ERR * MODE_NOT_SUPPORTED * GENERIC_FAILURE * * FIXME how do we specify TP-Message-Reference if we need to resend? */ #define RIL_REQUEST_SEND_SMS 25 /** * RIL_REQUEST_SEND_SMS_EXPECT_MORE * * Send an SMS message. Identical to RIL_REQUEST_SEND_SMS, * except that more messages are expected to be sent soon. If possible, * keep SMS relay protocol link open (eg TS 27.005 AT+CMMS command) * * "data" is const char ** * ((const char **)data)[0] is SMSC address in GSM BCD format prefixed * by a length byte (as expected by TS 27.005) or NULL for default SMSC * ((const char **)data)[1] is SMS in PDU format as an ASCII hex string * less the SMSC address * TP-Layer-Length is be "strlen(((const char **)data)[1])/2" * * "response" is a const RIL_SMS_Response * * * Based on the return error, caller decides to resend if sending sms * fails. SMS_SEND_FAIL_RETRY means retry (i.e. error cause is 332) * and GENERIC_FAILURE means no retry (i.e. error cause is 500) * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * SMS_SEND_FAIL_RETRY * NETWORK_REJECT * INVALID_STATE * INVALID_ARGUMENTS * NO_MEMORY * INVALID_SMS_FORMAT * SYSTEM_ERR * REQUEST_RATE_LIMITED * FDN_CHECK_FAILURE * MODEM_ERR * NETWORK_ERR * ENCODING_ERR * INVALID_SMSC_ADDRESS * MODE_NOT_SUPPORTED * GENERIC_FAILURE * */ #define RIL_REQUEST_SEND_SMS_EXPECT_MORE 26 /** * RIL_REQUEST_SETUP_DATA_CALL * * Setup a packet data connection. If RIL_Data_Call_Response_v6.status * return success it is added to the list of data calls and a * RIL_UNSOL_DATA_CALL_LIST_CHANGED is sent. The call remains in the * list until RIL_REQUEST_DEACTIVATE_DATA_CALL is issued or the * radio is powered off/on. This list is returned by RIL_REQUEST_DATA_CALL_LIST * and RIL_UNSOL_DATA_CALL_LIST_CHANGED. * * The RIL is expected to: * - Create one data call context. * - Create and configure a dedicated interface for the context * - The interface must be point to point. * - The interface is configured with one or more addresses and * is capable of sending and receiving packets. The prefix length * of the addresses must be /32 for IPv4 and /128 for IPv6. * - Must NOT change the linux routing table. * - Support up to RIL_REQUEST_DATA_REGISTRATION_STATE response[5] * number of simultaneous data call contexts. * * "data" is a const char ** * ((const char **)data)[0] Radio technology to use: 0-CDMA, 1-GSM/UMTS, 2... * for values above 2 this is RIL_RadioTechnology + 2. * ((const char **)data)[1] is a RIL_DataProfile (support is optional) * ((const char **)data)[2] is the APN to connect to if radio technology is GSM/UMTS. This APN will * override the one in the profile. NULL indicates no APN overrride. * ((const char **)data)[3] is the username for APN, or NULL * ((const char **)data)[4] is the password for APN, or NULL * ((const char **)data)[5] is the PAP / CHAP auth type. Values: * 0 => PAP and CHAP is never performed. * 1 => PAP may be performed; CHAP is never performed. * 2 => CHAP may be performed; PAP is never performed. * 3 => PAP / CHAP may be performed - baseband dependent. * ((const char **)data)[6] is the connection type to request must be one of the * PDP_type values in TS 27.007 section 10.1.1. * For example, "IP", "IPV6", "IPV4V6", or "PPP". * ((const char **)data)[7] Optional connection property parameters, format to be defined. * * "response" is a RIL_Data_Call_Response_v11 * * FIXME may need way to configure QoS settings * * Valid errors: * SUCCESS should be returned on both success and failure of setup with * the RIL_Data_Call_Response_v6.status containing the actual status. * For all other errors the RIL_Data_Call_Resonse_v6 is ignored. * * Other errors could include: * RADIO_NOT_AVAILABLE, GENERIC_FAILURE, OP_NOT_ALLOWED_BEFORE_REG_TO_NW, * OP_NOT_ALLOWED_DURING_VOICE_CALL and REQUEST_NOT_SUPPORTED. * * See also: RIL_REQUEST_DEACTIVATE_DATA_CALL */ #define RIL_REQUEST_SETUP_DATA_CALL 27 /** * RIL_REQUEST_SIM_IO * * Request SIM I/O operation. * This is similar to the TS 27.007 "restricted SIM" operation * where it assumes all of the EF selection will be done by the * callee. * * "data" is a const RIL_SIM_IO_v6 * * Please note that RIL_SIM_IO has a "PIN2" field which may be NULL, * or may specify a PIN2 for operations that require a PIN2 (eg * updating FDN records) * * "response" is a const RIL_SIM_IO_Response * * * Arguments and responses that are unused for certain * values of "command" should be ignored or set to NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE * SIM_PIN2 * SIM_PUK2 */ #define RIL_REQUEST_SIM_IO 28 /** * RIL_REQUEST_SEND_USSD * * Send a USSD message * * If a USSD session already exists, the message should be sent in the * context of that session. Otherwise, a new session should be created. * * The network reply should be reported via RIL_UNSOL_ON_USSD * * Only one USSD session may exist at a time, and the session is assumed * to exist until: * a) The android system invokes RIL_REQUEST_CANCEL_USSD * b) The implementation sends a RIL_UNSOL_ON_USSD with a type code * of "0" (USSD-Notify/no further action) or "2" (session terminated) * * "data" is a const char * containing the USSD request in UTF-8 format * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * FDN_CHECK_FAILURE * USSD_MODIFIED_TO_DIAL * USSD_MODIFIED_TO_SS * USSD_MODIFIED_TO_USSD * SIM_BUSY * OPERATION_NOT_ALLOWED * INVALID_ARGUMENTS * NO_MEMORY * MODEM_ERR * INTERNAL_ERR * ABORTED * SYSTEM_ERR * INVALID_STATE * GENERIC_FAILURE * * See also: RIL_REQUEST_CANCEL_USSD, RIL_UNSOL_ON_USSD */ #define RIL_REQUEST_SEND_USSD 29 /** * RIL_REQUEST_CANCEL_USSD * * Cancel the current USSD session if one exists * * "data" is null * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * SIM_BUSY * OPERATION_NOT_ALLOWED * MODEM_ERR * INTERNAL_ERR * NO_MEMORY * INVALID_STATE * GENERIC_FAILURE */ #define RIL_REQUEST_CANCEL_USSD 30 /** * RIL_REQUEST_GET_CLIR * * Gets current CLIR status * "data" is NULL * "response" is int * * ((int *)data)[0] is "n" parameter from TS 27.007 7.7 * ((int *)data)[1] is "m" parameter from TS 27.007 7.7 * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * SS_MODIFIED_TO_DIAL * SS_MODIFIED_TO_USSD * SS_MODIFIED_TO_SS * NO_MEMORY * MODEM_ERR * INTERNAL_ERR * FDN_CHECK_FAILURE * SYSTEM_ERR * GENERIC_FAILURE */ #define RIL_REQUEST_GET_CLIR 31 /** * RIL_REQUEST_SET_CLIR * * "data" is int * * ((int *)data)[0] is "n" parameter from TS 27.007 7.7 * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * SS_MODIFIED_TO_DIAL * SS_MODIFIED_TO_USSD * SS_MODIFIED_TO_SS * INVALID_ARGUMENTS * SYSTEM_ERR * GENERIC_FAILURE */ #define RIL_REQUEST_SET_CLIR 32 /** * RIL_REQUEST_QUERY_CALL_FORWARD_STATUS * * "data" is const RIL_CallForwardInfo * * * "response" is const RIL_CallForwardInfo ** * "response" points to an array of RIL_CallForwardInfo *'s, one for * each distinct registered phone number. * * For example, if data is forwarded to +18005551212 and voice is forwarded * to +18005559999, then two separate RIL_CallForwardInfo's should be returned * * If, however, both data and voice are forwarded to +18005551212, then * a single RIL_CallForwardInfo can be returned with the service class * set to "data + voice = 3") * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * SS_MODIFIED_TO_DIAL * SS_MODIFIED_TO_USSD * SS_MODIFIED_TO_SS * INVALID_ARGUMENTS * NO_MEMORY * SYSTEM_ERR * MODEM_ERR * INTERNAL_ERR * NO_MEMORY * FDN_CHECK_FAILURE * GENERIC_FAILURE */ #define RIL_REQUEST_QUERY_CALL_FORWARD_STATUS 33 /** * RIL_REQUEST_SET_CALL_FORWARD * * Configure call forward rule * * "data" is const RIL_CallForwardInfo * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * SS_MODIFIED_TO_DIAL * SS_MODIFIED_TO_USSD * SS_MODIFIED_TO_SS * INVALID_ARGUMENTS * NO_MEMORY * SYSTEM_ERR * MODEM_ERR * INTERNAL_ERR * INVALID_STATE * FDN_CHECK_FAILURE * GENERIC_FAILURE */ #define RIL_REQUEST_SET_CALL_FORWARD 34 /** * RIL_REQUEST_QUERY_CALL_WAITING * * Query current call waiting state * * "data" is const int * * ((const int *)data)[0] is the TS 27.007 service class to query. * "response" is a const int * * ((const int *)response)[0] is 0 for "disabled" and 1 for "enabled" * * If ((const int *)response)[0] is = 1, then ((const int *)response)[1] * must follow, with the TS 27.007 service class bit vector of services * for which call waiting is enabled. * * For example, if ((const int *)response)[0] is 1 and * ((const int *)response)[1] is 3, then call waiting is enabled for data * and voice and disabled for everything else * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * SS_MODIFIED_TO_DIAL * SS_MODIFIED_TO_USSD * SS_MODIFIED_TO_SS * NO_MEMORY * MODEM_ERR * INTERNAL_ERR * NO_MEMORY * FDN_CHECK_FAILURE * INVALID_ARGUMENTS * GENERIC_FAILURE */ #define RIL_REQUEST_QUERY_CALL_WAITING 35 /** * RIL_REQUEST_SET_CALL_WAITING * * Configure current call waiting state * * "data" is const int * * ((const int *)data)[0] is 0 for "disabled" and 1 for "enabled" * ((const int *)data)[1] is the TS 27.007 service class bit vector of * services to modify * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * SS_MODIFIED_TO_DIAL * SS_MODIFIED_TO_USSD * SS_MODIFIED_TO_SS * INVALID_ARGUMENTS * NO_MEMORY * MODEM_ERR * INTERNAL_ERR * INVALID_STATE * FDN_CHECK_FAILURE * GENERIC_FAILURE */ #define RIL_REQUEST_SET_CALL_WAITING 36 /** * RIL_REQUEST_SMS_ACKNOWLEDGE * * Acknowledge successful or failed receipt of SMS previously indicated * via RIL_UNSOL_RESPONSE_NEW_SMS * * "data" is int * * ((int *)data)[0] is 1 on successful receipt * (basically, AT+CNMA=1 from TS 27.005 * is 0 on failed receipt * (basically, AT+CNMA=2 from TS 27.005) * ((int *)data)[1] if data[0] is 0, this contains the failure cause as defined * in TS 23.040, 9.2.3.22. Currently only 0xD3 (memory * capacity exceeded) and 0xFF (unspecified error) are * reported. * * "response" is NULL * * FIXME would like request that specified RP-ACK/RP-ERROR PDU * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE */ #define RIL_REQUEST_SMS_ACKNOWLEDGE 37 /** * RIL_REQUEST_GET_IMEI - DEPRECATED * * Get the device IMEI, including check digit * * The request is DEPRECATED, use RIL_REQUEST_DEVICE_IDENTITY * Valid when RadioState is not RADIO_STATE_UNAVAILABLE * * "data" is NULL * "response" is a const char * containing the IMEI * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * GENERIC_FAILURE */ #define RIL_REQUEST_GET_IMEI 38 /** * RIL_REQUEST_GET_IMEISV - DEPRECATED * * Get the device IMEISV, which should be two decimal digits * * The request is DEPRECATED, use RIL_REQUEST_DEVICE_IDENTITY * Valid when RadioState is not RADIO_STATE_UNAVAILABLE * * "data" is NULL * "response" is a const char * containing the IMEISV * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * GENERIC_FAILURE */ #define RIL_REQUEST_GET_IMEISV 39 /** * RIL_REQUEST_ANSWER * * Answer incoming call * * Will not be called for WAITING calls. * RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE will be used in this case * instead * * "data" is NULL * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * INVALID_STATE * NO_MEMORY * SYSTEM_ERR * MODEM_ERR * INTERNAL_ERR * INVALID_CALL_ID * GENERIC_FAILURE */ #define RIL_REQUEST_ANSWER 40 /** * RIL_REQUEST_DEACTIVATE_DATA_CALL * * Deactivate packet data connection and remove from the * data call list if SUCCESS is returned. Any other return * values should also try to remove the call from the list, * but that may not be possible. In any event a * RIL_REQUEST_RADIO_POWER off/on must clear the list. An * RIL_UNSOL_DATA_CALL_LIST_CHANGED is not expected to be * issued because of an RIL_REQUEST_DEACTIVATE_DATA_CALL. * * "data" is const char ** * ((char**)data)[0] indicating CID * ((char**)data)[1] indicating Disconnect Reason * 0 => No specific reason specified * 1 => Radio shutdown requested * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE * * See also: RIL_REQUEST_SETUP_DATA_CALL */ #define RIL_REQUEST_DEACTIVATE_DATA_CALL 41 /** * RIL_REQUEST_QUERY_FACILITY_LOCK * * Query the status of a facility lock state * * "data" is const char ** * ((const char **)data)[0] is the facility string code from TS 27.007 7.4 * (eg "AO" for BAOC, "SC" for SIM lock) * ((const char **)data)[1] is the password, or "" if not required * ((const char **)data)[2] is the TS 27.007 service class bit vector of * services to query * ((const char **)data)[3] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. * This is only applicable in the case of Fixed Dialing Numbers * (FDN) requests. * * "response" is an int * * ((const int *)response) 0 is the TS 27.007 service class bit vector of * services for which the specified barring facility * is active. "0" means "disabled for all" * * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * SS_MODIFIED_TO_DIAL * SS_MODIFIED_TO_USSD * SS_MODIFIED_TO_SS * INVALID_ARGUMENTS * NO_MEMORY * INTERNAL_ERR * SYSTEM_ERR * MODEM_ERR * FDN_CHECK_FAILURE * GENERIC_FAILURE * */ #define RIL_REQUEST_QUERY_FACILITY_LOCK 42 /** * RIL_REQUEST_SET_FACILITY_LOCK * * Enable/disable one facility lock * * "data" is const char ** * * ((const char **)data)[0] = facility string code from TS 27.007 7.4 * (eg "AO" for BAOC) * ((const char **)data)[1] = "0" for "unlock" and "1" for "lock" * ((const char **)data)[2] = password * ((const char **)data)[3] = string representation of decimal TS 27.007 * service class bit vector. Eg, the string * "1" means "set this facility for voice services" * ((const char **)data)[4] = AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. * This is only applicable in the case of Fixed Dialing Numbers * (FDN) requests. * * "response" is int * * ((int *)response)[0] is the number of retries remaining, or -1 if unknown * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * SS_MODIFIED_TO_DIAL * SS_MODIFIED_TO_USSD * SS_MODIFIED_TO_SS * INVALID_ARGUMENTS * INTERNAL_ERR * NO_MEMORY * MODEM_ERR * INVALID_STATE * FDN_CHECK_FAILURE * GENERIC_FAILURE * */ #define RIL_REQUEST_SET_FACILITY_LOCK 43 /** * RIL_REQUEST_CHANGE_BARRING_PASSWORD * * Change call barring facility password * * "data" is const char ** * * ((const char **)data)[0] = facility string code from TS 27.007 7.4 * (eg "AO" for BAOC) * ((const char **)data)[1] = old password * ((const char **)data)[2] = new password * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * SS_MODIFIED_TO_DIAL * SS_MODIFIED_TO_USSD * SS_MODIFIED_TO_SS * INVALID_ARGUMENTS * NO_MEMORY * MODEM_ERR * INTERNAL_ERR * SYSTEM_ERR * FDN_CHECK_FAILURE * GENERIC_FAILURE * */ #define RIL_REQUEST_CHANGE_BARRING_PASSWORD 44 /** * RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE * * Query current network selectin mode * * "data" is NULL * * "response" is int * * ((const int *)response)[0] is * 0 for automatic selection * 1 for manual selection * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE * */ #define RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE 45 /** * RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC * * Specify that the network should be selected automatically * * "data" is NULL * "response" is NULL * * This request must not respond until the new operator is selected * and registered * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * ILLEGAL_SIM_OR_ME * OPERATION_NOT_ALLOWED * GENERIC_FAILURE * * Note: Returns ILLEGAL_SIM_OR_ME when the failure is permanent and * no retries needed, such as illegal SIM or ME. * Returns GENERIC_FAILURE for all other causes that might be * fixed by retries. * */ #define RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC 46 /** * RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL * * Manually select a specified network. * * "data" is const char * specifying MCCMNC of network to select (eg "310170") * "response" is NULL * * This request must not respond until the new operator is selected * and registered * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * ILLEGAL_SIM_OR_ME * OPERATION_NOT_ALLOWED * GENERIC_FAILURE * * Note: Returns ILLEGAL_SIM_OR_ME when the failure is permanent and * no retries needed, such as illegal SIM or ME. * Returns GENERIC_FAILURE for all other causes that might be * fixed by retries. * */ #define RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL 47 /** * RIL_REQUEST_QUERY_AVAILABLE_NETWORKS * * Scans for available networks * * "data" is NULL * "response" is const char ** that should be an array of n*4 strings, where * n is the number of available networks * For each available network: * * ((const char **)response)[n+0] is long alpha ONS or EONS * ((const char **)response)[n+1] is short alpha ONS or EONS * ((const char **)response)[n+2] is 5 or 6 digit numeric code (MCC + MNC) * ((const char **)response)[n+3] is a string value of the status: * "unknown" * "available" * "current" * "forbidden" * * This request must not respond until the new operator is selected * and registered * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * OPERATION_NOT_ALLOWED * GENERIC_FAILURE * */ #define RIL_REQUEST_QUERY_AVAILABLE_NETWORKS 48 /** * RIL_REQUEST_DTMF_START * * Start playing a DTMF tone. Continue playing DTMF tone until * RIL_REQUEST_DTMF_STOP is received * * If a RIL_REQUEST_DTMF_START is received while a tone is currently playing, * it should cancel the previous tone and play the new one. * * "data" is a char * * ((char *)data)[0] is a single character with one of 12 values: 0-9,*,# * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * INVALID_ARGUMENTS * NO_RESOURCES * NO_MEMORY * SYSTEM_ERR * MODEM_ERR * INTERNAL_ERR * INVALID_CALL_ID * GENERIC_FAILURE * * See also: RIL_REQUEST_DTMF, RIL_REQUEST_DTMF_STOP */ #define RIL_REQUEST_DTMF_START 49 /** * RIL_REQUEST_DTMF_STOP * * Stop playing a currently playing DTMF tone. * * "data" is NULL * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * OPERATION_NOT_ALLOWED * NO_RESOURCES * NO_MEMORY * INVALID_ARGUMENTS * SYSTEM_ERR * MODEM_ERR * INTERNAL_ERR * INVALID_CALL_ID * GENERIC_FAILURE * * See also: RIL_REQUEST_DTMF, RIL_REQUEST_DTMF_START */ #define RIL_REQUEST_DTMF_STOP 50 /** * RIL_REQUEST_BASEBAND_VERSION * * Return string value indicating baseband version, eg * response from AT+CGMR * * "data" is NULL * "response" is const char * containing version string for log reporting * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * EMPTY_RECORD * GENERIC_FAILURE * */ #define RIL_REQUEST_BASEBAND_VERSION 51 /** * RIL_REQUEST_SEPARATE_CONNECTION * * Separate a party from a multiparty call placing the multiparty call * (less the specified party) on hold and leaving the specified party * as the only other member of the current (active) call * * Like AT+CHLD=2x * * See TS 22.084 1.3.8.2 (iii) * TS 22.030 6.5.5 "Entering "2X followed by send" * TS 27.007 "AT+CHLD=2x" * * "data" is an int * * (int *)data)[0] contains Connection index (value of 'x' in CHLD above) "response" is NULL * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * INVALID_ARGUMENTS * INVALID_STATE * NO_RESOURCES * NO_MEMORY * SYSTEM_ERR * MODEM_ERR * INTERNAL_ERR * INVALID_CALL_ID * INVALID_STATE * OPERATION_NOT_ALLOWED * GENERIC_FAILURE */ #define RIL_REQUEST_SEPARATE_CONNECTION 52 /** * RIL_REQUEST_SET_MUTE * * Turn on or off uplink (microphone) mute. * * Will only be sent while voice call is active. * Will always be reset to "disable mute" when a new voice call is initiated * * "data" is an int * * (int *)data)[0] is 1 for "enable mute" and 0 for "disable mute" * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * INVALID_ARGUMENTS * NO_MEMORY * REQUEST_RATE_LIMITED * GENERIC_FAILURE */ #define RIL_REQUEST_SET_MUTE 53 /** * RIL_REQUEST_GET_MUTE * * Queries the current state of the uplink mute setting * * "data" is NULL * "response" is an int * * (int *)response)[0] is 1 for "mute enabled" and 0 for "mute disabled" * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * SS_MODIFIED_TO_DIAL * SS_MODIFIED_TO_USSD * SS_MODIFIED_TO_SS * NO_MEMORY * REQUEST_RATE_LIMITED * GENERIC_FAILURE */ #define RIL_REQUEST_GET_MUTE 54 /** * RIL_REQUEST_QUERY_CLIP * * Queries the status of the CLIP supplementary service * * (for MMI code "*#30#") * * "data" is NULL * "response" is an int * * (int *)response)[0] is 1 for "CLIP provisioned" * and 0 for "CLIP not provisioned" * and 2 for "unknown, e.g. no network etc" * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * NO_MEMORY * SYSTEM_ERR * MODEM_ERR * INTERNAL_ERR * FDN_CHECK_FAILURE * GENERIC_FAILURE */ #define RIL_REQUEST_QUERY_CLIP 55 /** * RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE - Deprecated use the status * field in RIL_Data_Call_Response_v6. * * Requests the failure cause code for the most recently failed PDP * context or CDMA data connection active * replaces RIL_REQUEST_LAST_PDP_FAIL_CAUSE * * "data" is NULL * * "response" is a "int *" * ((int *)response)[0] is an integer cause code defined in TS 24.008 * section 6.1.3.1.3 or close approximation * * If the implementation does not have access to the exact cause codes, * then it should return one of the values listed in * RIL_DataCallFailCause, as the UI layer needs to distinguish these * cases for error notification * and potential retries. * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE * * See also: RIL_REQUEST_LAST_CALL_FAIL_CAUSE * * Deprecated use the status field in RIL_Data_Call_Response_v6. */ #define RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE 56 /** * RIL_REQUEST_DATA_CALL_LIST * * Returns the data call list. An entry is added when a * RIL_REQUEST_SETUP_DATA_CALL is issued and removed on a * RIL_REQUEST_DEACTIVATE_DATA_CALL. The list is emptied * when RIL_REQUEST_RADIO_POWER off/on is issued. * * "data" is NULL * "response" is an array of RIL_Data_Call_Response_v6 * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * GENERIC_FAILURE * * See also: RIL_UNSOL_DATA_CALL_LIST_CHANGED */ #define RIL_REQUEST_DATA_CALL_LIST 57 /** * RIL_REQUEST_RESET_RADIO - DEPRECATED * * Request a radio reset. The RIL implementation may postpone * the reset until after this request is responded to if the baseband * is presently busy. * * The request is DEPRECATED, use RIL_REQUEST_RADIO_POWER * * "data" is NULL * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * GENERIC_FAILURE * REQUEST_NOT_SUPPORTED */ #define RIL_REQUEST_RESET_RADIO 58 /** * RIL_REQUEST_OEM_HOOK_RAW * * This request reserved for OEM-specific uses. It passes raw byte arrays * back and forth. * * It can be invoked on the Java side from * com.android.internal.telephony.Phone.invokeOemRilRequestRaw() * * "data" is a char * of bytes copied from the byte[] data argument in java * "response" is a char * of bytes that will returned via the * caller's "response" Message here: * (byte[])(((AsyncResult)response.obj).result) * * An error response here will result in * (((AsyncResult)response.obj).result) == null and * (((AsyncResult)response.obj).exception) being an instance of * com.android.internal.telephony.gsm.CommandException * * Valid errors: * All */ #define RIL_REQUEST_OEM_HOOK_RAW 59 /** * RIL_REQUEST_OEM_HOOK_STRINGS * * This request reserved for OEM-specific uses. It passes strings * back and forth. * * It can be invoked on the Java side from * com.android.internal.telephony.Phone.invokeOemRilRequestStrings() * * "data" is a const char **, representing an array of null-terminated UTF-8 * strings copied from the "String[] strings" argument to * invokeOemRilRequestStrings() * * "response" is a const char **, representing an array of null-terminated UTF-8 * stings that will be returned via the caller's response message here: * * (String[])(((AsyncResult)response.obj).result) * * An error response here will result in * (((AsyncResult)response.obj).result) == null and * (((AsyncResult)response.obj).exception) being an instance of * com.android.internal.telephony.gsm.CommandException * * Valid errors: * All */ #define RIL_REQUEST_OEM_HOOK_STRINGS 60 /** * RIL_REQUEST_SCREEN_STATE * * Indicates the current state of the screen. When the screen is off, the * RIL should notify the baseband to suppress certain notifications (eg, * signal strength and changes in LAC/CID or BID/SID/NID/latitude/longitude) * in an effort to conserve power. These notifications should resume when the * screen is on. * * "data" is int * * ((int *)data)[0] is == 1 for "Screen On" * ((int *)data)[0] is == 0 for "Screen Off" * * "response" is NULL * * Valid errors: * SUCCESS * GENERIC_FAILURE */ #define RIL_REQUEST_SCREEN_STATE 61 /** * RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION * * Enables/disables supplementary service related notifications * from the network. * * Notifications are reported via RIL_UNSOL_SUPP_SVC_NOTIFICATION. * * "data" is int * * ((int *)data)[0] is == 1 for notifications enabled * ((int *)data)[0] is == 0 for notifications disabled * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * SIM_BUSY * INVALID_ARGUMENTS * NO_MEMORY * SYSTEM_ERR * MODEM_ERR * INTERNAL_ERR * GENERIC_FAILURE * * See also: RIL_UNSOL_SUPP_SVC_NOTIFICATION. */ #define RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION 62 /** * RIL_REQUEST_WRITE_SMS_TO_SIM * * Stores a SMS message to SIM memory. * * "data" is RIL_SMS_WriteArgs * * * "response" is int * * ((const int *)response)[0] is the record index where the message is stored. * * Valid errors: * SUCCESS * SIM_FULL * INVALID_ARGUMENTS * INVALID_SMS_FORMAT * INTERNAL_ERR * MODEM_ERR * ENCODING_ERR * NO_MEMORY * NO_RESOURCES * INVALID_MODEM_STATE * MODE_NOT_SUPPORTED * INVALID_SMSC_ADDRESS * GENERIC_FAILURE * */ #define RIL_REQUEST_WRITE_SMS_TO_SIM 63 /** * RIL_REQUEST_DELETE_SMS_ON_SIM * * Deletes a SMS message from SIM memory. * * "data" is int * * ((int *)data)[0] is the record index of the message to delete. * * "response" is NULL * * Valid errors: * SUCCESS * SIM_FULL * INVALID_ARGUMENTS * NO_MEMORY * REQUEST_RATE_LIMITED * SYSTEM_ERR * MODEM_ERR * NO_SUCH_ENTRY * GENERIC_FAILURE * */ #define RIL_REQUEST_DELETE_SMS_ON_SIM 64 /** * RIL_REQUEST_SET_BAND_MODE * * Assign a specified band for RF configuration. * * "data" is int * * ((int *)data)[0] is a RIL_RadioBandMode * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * OPERATION_NOT_ALLOWED * GENERIC_FAILURE * * See also: RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE */ #define RIL_REQUEST_SET_BAND_MODE 65 /** * RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE * * Query the list of band mode supported by RF. * * "data" is NULL * * "response" is int * * "response" points to an array of int's, the int[0] is the size of array; * subsequent values are a list of RIL_RadioBandMode listing supported modes. * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE * * See also: RIL_REQUEST_SET_BAND_MODE */ #define RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE 66 /** * RIL_REQUEST_STK_GET_PROFILE * * Requests the profile of SIM tool kit. * The profile indicates the SAT/USAT features supported by ME. * The SAT/USAT features refer to 3GPP TS 11.14 and 3GPP TS 31.111 * * "data" is NULL * * "response" is a const char * containing SAT/USAT profile * in hexadecimal format string starting with first byte of terminal profile * * Valid errors: * RIL_E_SUCCESS * RIL_E_RADIO_NOT_AVAILABLE (radio resetting) * RIL_E_GENERIC_FAILURE */ #define RIL_REQUEST_STK_GET_PROFILE 67 /** * RIL_REQUEST_STK_SET_PROFILE * * Download the STK terminal profile as part of SIM initialization * procedure * * "data" is a const char * containing SAT/USAT profile * in hexadecimal format string starting with first byte of terminal profile * * "response" is NULL * * Valid errors: * RIL_E_SUCCESS * RIL_E_RADIO_NOT_AVAILABLE (radio resetting) * RIL_E_GENERIC_FAILURE */ #define RIL_REQUEST_STK_SET_PROFILE 68 /** * RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND * * Requests to send a SAT/USAT envelope command to SIM. * The SAT/USAT envelope command refers to 3GPP TS 11.14 and 3GPP TS 31.111 * * "data" is a const char * containing SAT/USAT command * in hexadecimal format string starting with command tag * * "response" is a const char * containing SAT/USAT response * in hexadecimal format string starting with first byte of response * (May be NULL) * * Valid errors: * RIL_E_SUCCESS * RIL_E_RADIO_NOT_AVAILABLE (radio resetting) * SIM_BUSY * OPERATION_NOT_ALLOWED * RIL_E_GENERIC_FAILURE */ #define RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND 69 /** * RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE * * Requests to send a terminal response to SIM for a received * proactive command * * "data" is a const char * containing SAT/USAT response * in hexadecimal format string starting with first byte of response data * * "response" is NULL * * Valid errors: * RIL_E_SUCCESS * RIL_E_RADIO_NOT_AVAILABLE (radio resetting) * RIL_E_OPERATION_NOT_ALLOWED * RIL_E_GENERIC_FAILURE */ #define RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE 70 /** * RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM * * When STK application gets RIL_UNSOL_STK_CALL_SETUP, the call actually has * been initialized by ME already. (We could see the call has been in the 'call * list') So, STK application needs to accept/reject the call according as user * operations. * * "data" is int * * ((int *)data)[0] is > 0 for "accept" the call setup * ((int *)data)[0] is == 0 for "reject" the call setup * * "response" is NULL * * Valid errors: * RIL_E_SUCCESS * RIL_E_RADIO_NOT_AVAILABLE (radio resetting) * RIL_E_OPERATION_NOT_ALLOWED * RIL_E_GENERIC_FAILURE */ #define RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM 71 /** * RIL_REQUEST_EXPLICIT_CALL_TRANSFER * * Connects the two calls and disconnects the subscriber from both calls. * * "data" is NULL * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * INVALID_STATE * NO_RESOURCES * NO_MEMORY * INVALID_ARGUMENTS * SYSTEM_ERR * MODEM_ERR * INTERNAL_ERR * INVALID_CALL_ID * INVALID_STATE * OPERATION_NOT_ALLOWED * GENERIC_FAILURE */ #define RIL_REQUEST_EXPLICIT_CALL_TRANSFER 72 /** * RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE * * Requests to set the preferred network type for searching and registering * (CS/PS domain, RAT, and operation mode) * * "data" is int * which is RIL_PreferredNetworkType * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * GENERIC_FAILURE * OPERATION_NOT_ALLOWED * MODE_NOT_SUPPORTED */ #define RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE 73 /** * RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE * * Query the preferred network type (CS/PS domain, RAT, and operation mode) * for searching and registering * * "data" is NULL * * "response" is int * * ((int *)reponse)[0] is == RIL_PreferredNetworkType * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE * * See also: RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE */ #define RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE 74 /** * RIL_REQUEST_NEIGHBORING_CELL_IDS * * Request neighboring cell id in GSM network * * "data" is NULL * "response" must be a " const RIL_NeighboringCell** " * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE */ #define RIL_REQUEST_GET_NEIGHBORING_CELL_IDS 75 /** * RIL_REQUEST_SET_LOCATION_UPDATES * * Enables/disables network state change notifications due to changes in * LAC and/or CID (for GSM) or BID/SID/NID/latitude/longitude (for CDMA). * Basically +CREG=2 vs. +CREG=1 (TS 27.007). * * Note: The RIL implementation should default to "updates enabled" * when the screen is on and "updates disabled" when the screen is off. * * "data" is int * * ((int *)data)[0] is == 1 for updates enabled (+CREG=2) * ((int *)data)[0] is == 0 for updates disabled (+CREG=1) * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE * * See also: RIL_REQUEST_SCREEN_STATE, RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED */ #define RIL_REQUEST_SET_LOCATION_UPDATES 76 /** * RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE * * Request to set the location where the CDMA subscription shall * be retrieved * * "data" is int * * ((int *)data)[0] is == RIL_CdmaSubscriptionSource * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE * SIM_ABSENT * SUBSCRIPTION_NOT_AVAILABLE * * See also: RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE */ #define RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE 77 /** * RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE * * Request to set the roaming preferences in CDMA * * "data" is int * * ((int *)data)[0] is == 0 for Home Networks only, as defined in PRL * ((int *)data)[0] is == 1 for Roaming on Affiliated networks, as defined in PRL * ((int *)data)[0] is == 2 for Roaming on Any Network, as defined in the PRL * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE */ #define RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE 78 /** * RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE * * Request the actual setting of the roaming preferences in CDMA in the modem * * "data" is NULL * * "response" is int * * ((int *)response)[0] is == 0 for Home Networks only, as defined in PRL * ((int *)response)[0] is == 1 for Roaming on Affiliated networks, as defined in PRL * ((int *)response)[0] is == 2 for Roaming on Any Network, as defined in the PRL * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE */ #define RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE 79 /** * RIL_REQUEST_SET_TTY_MODE * * Request to set the TTY mode * * "data" is int * * ((int *)data)[0] is == 0 for TTY off * ((int *)data)[0] is == 1 for TTY Full * ((int *)data)[0] is == 2 for TTY HCO (hearing carryover) * ((int *)data)[0] is == 3 for TTY VCO (voice carryover) * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * INVALID_ARGUMENTS * MODEM_ERR * INTERNAL_ERR * NO_MEMOR * INVALID_ARGUMENTS * MODEM_ERR * INTERNAL_ERR * NO_MEMORYY * GENERIC_FAILURE */ #define RIL_REQUEST_SET_TTY_MODE 80 /** * RIL_REQUEST_QUERY_TTY_MODE * * Request the setting of TTY mode * * "data" is NULL * * "response" is int * * ((int *)response)[0] is == 0 for TTY off * ((int *)response)[0] is == 1 for TTY Full * ((int *)response)[0] is == 2 for TTY HCO (hearing carryover) * ((int *)response)[0] is == 3 for TTY VCO (voice carryover) * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * MODEM_ERR * INTERNAL_ERR * NO_MEMORY * INVALID_ARGUMENTS * GENERIC_FAILURE */ #define RIL_REQUEST_QUERY_TTY_MODE 81 /** * RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE * * Request to set the preferred voice privacy mode used in voice * scrambling * * "data" is int * * ((int *)data)[0] is == 0 for Standard Privacy Mode (Public Long Code Mask) * ((int *)data)[0] is == 1 for Enhanced Privacy Mode (Private Long Code Mask) * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * INVALID_ARGUMENTS * SYSTEM_ERR * MODEM_ERR * INTERNAL_ERR * NO_MEMORY * INVALID_CALL_ID * GENERIC_FAILURE */ #define RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE 82 /** * RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE * * Request the setting of preferred voice privacy mode * * "data" is NULL * * "response" is int * * ((int *)response)[0] is == 0 for Standard Privacy Mode (Public Long Code Mask) * ((int *)response)[0] is == 1 for Enhanced Privacy Mode (Private Long Code Mask) * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * MODEM_ERR * INTERNAL_ERR * NO_MEMORY * INVALID_ARGUMENTS * GENERIC_FAILURE */ #define RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE 83 /** * RIL_REQUEST_CDMA_FLASH * * Send FLASH * * "data" is const char * * ((const char *)data)[0] is a FLASH string * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * INVALID_ARGUMENTS * NO_MEMORY * SYSTEM_ERR * MODEM_ERR * INTERNAL_ERR * INVALID_CALL_ID * INVALID_STATE * GENERIC_FAILURE * */ #define RIL_REQUEST_CDMA_FLASH 84 /** * RIL_REQUEST_CDMA_BURST_DTMF * * Send DTMF string * * "data" is const char ** * ((const char **)data)[0] is a DTMF string * ((const char **)data)[1] is the DTMF ON length in milliseconds, or 0 to use * default * ((const char **)data)[2] is the DTMF OFF length in milliseconds, or 0 to use * default * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * INVALID_ARGUMENTS * NO_MEMORY * SYSTEM_ERR * MODEM_ERR * INTERNAL_ERR * INVALID_CALL_ID * GENERIC_FAILURE * */ #define RIL_REQUEST_CDMA_BURST_DTMF 85 /** * RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY * * Takes a 26 digit string (20 digit AKEY + 6 digit checksum). * If the checksum is valid the 20 digit AKEY is written to NV, * replacing the existing AKEY no matter what it was before. * * "data" is const char * * ((const char *)data)[0] is a 26 digit string (ASCII digits '0'-'9') * where the last 6 digits are a checksum of the * first 20, as specified in TR45.AHAG * "Common Cryptographic Algorithms, Revision D.1 * Section 2.2" * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE * */ #define RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY 86 /** * RIL_REQUEST_CDMA_SEND_SMS * * Send a CDMA SMS message * * "data" is const RIL_CDMA_SMS_Message * * * "response" is a const RIL_SMS_Response * * * Based on the return error, caller decides to resend if sending sms * fails. The CDMA error class is derived as follows, * SUCCESS is error class 0 (no error) * SMS_SEND_FAIL_RETRY is error class 2 (temporary failure) * and GENERIC_FAILURE is error class 3 (permanent and no retry) * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * SMS_SEND_FAIL_RETRY * NETWORK_REJECT * INVALID_STATE * INVALID_ARGUMENTS * NO_MEMORY * REQUEST_RATE_LIMITED * INVALID_SMS_FORMAT * SYSTEM_ERR * FDN_CHECK_FAILURE * MODEM_ERR * NETWORK_ERR * ENCODING_ERR * INVALID_SMSC_ADDRESS * MODE_NOT_SUPPORTED * GENERIC_FAILURE * */ #define RIL_REQUEST_CDMA_SEND_SMS 87 /** * RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE * * Acknowledge the success or failure in the receipt of SMS * previously indicated via RIL_UNSOL_RESPONSE_CDMA_NEW_SMS * * "data" is const RIL_CDMA_SMS_Ack * * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * INVALID_ARGUMENTS * NO_SMS_TO_ACK * INVALID_STATE * NO_MEMORY * REQUEST_RATE_LIMITED * SYSTEM_ERR * MODEM_ERR * INVALID_STATE * MODE_NOT_SUPPORTED * NETWORK_NOT_READY * INVALID_MODEM_STATE * GENERIC_FAILURE * */ #define RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE 88 /** * RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG * * Request the setting of GSM/WCDMA Cell Broadcast SMS config. * * "data" is NULL * * "response" is a const RIL_GSM_BroadcastSmsConfigInfo ** * "responselen" is count * sizeof (RIL_GSM_BroadcastSmsConfigInfo *) * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * INVALID_STATE * NO_MEMORY * REQUEST_RATE_LIMITED * SYSTEM_ERR * NO_RESOURCES * MODEM_ERR * SYSTEM_ERR * GENERIC_FAILURE * */ #define RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG 89 /** * RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG * * Set GSM/WCDMA Cell Broadcast SMS config * * "data" is a const RIL_GSM_BroadcastSmsConfigInfo ** * "datalen" is count * sizeof(RIL_GSM_BroadcastSmsConfigInfo *) * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * INVALID_STATE * INVALID_ARGUMENTS * NO_MEMORY * SYSTEM_ERR * REQUEST_RATE_LIMITED * MODEM_ERR * SYSTEM_ERR * GENERIC_FAILURE * */ #define RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG 90 /** * RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION * * Enable or disable the reception of GSM/WCDMA Cell Broadcast SMS * * "data" is const int * * (const int *)data[0] indicates to activate or turn off the * reception of GSM/WCDMA Cell Broadcast SMS, 0-1, * 0 - Activate, 1 - Turn off * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * INVALID_STATE * INVALID_ARGUMENTS * NO_MEMORY * SYSTEM_ERR * REQUEST_RATE_LIMITED * MODEM_ERR * GENERIC_FAILURE * */ #define RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION 91 /** * RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG * * Request the setting of CDMA Broadcast SMS config * * "data" is NULL * * "response" is a const RIL_CDMA_BroadcastSmsConfigInfo ** * "responselen" is count * sizeof (RIL_CDMA_BroadcastSmsConfigInfo *) * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * INVALID_STATE * NO_MEMORY * REQUEST_RATE_LIMITED * SYSTEM_ERR * NO_RESOURCES * MODEM_ERR * SYSTEM_ERR * GENERIC_FAILURE * */ #define RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG 92 /** * RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG * * Set CDMA Broadcast SMS config * * "data" is an const RIL_CDMA_BroadcastSmsConfigInfo ** * "datalen" is count * sizeof(const RIL_CDMA_BroadcastSmsConfigInfo *) * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * INVALID_STATE * INVALID_ARGUMENTS * NO_MEMORY * SYSTEM_ERR * REQUEST_RATE_LIMITED * MODEM_ERR * SYSTEM_ERR * GENERIC_FAILURE * */ #define RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG 93 /** * RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION * * Enable or disable the reception of CDMA Broadcast SMS * * "data" is const int * * (const int *)data[0] indicates to activate or turn off the * reception of CDMA Broadcast SMS, 0-1, * 0 - Activate, 1 - Turn off * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * INVALID_STATE * INVALID_ARGUMENTS * NO_MEMORY * SYSTEM_ERR * REQUEST_RATE_LIMITED * MODEM_ERR * GENERIC_FAILURE * */ #define RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION 94 /** * RIL_REQUEST_CDMA_SUBSCRIPTION * * Request the device MDN / H_SID / H_NID. * * The request is only allowed when CDMA subscription is available. When CDMA * subscription is changed, application layer should re-issue the request to * update the subscription information. * * If a NULL value is returned for any of the device id, it means that error * accessing the device. * * "response" is const char ** * ((const char **)response)[0] is MDN if CDMA subscription is available * ((const char **)response)[1] is a comma separated list of H_SID (Home SID) if * CDMA subscription is available, in decimal format * ((const char **)response)[2] is a comma separated list of H_NID (Home NID) if * CDMA subscription is available, in decimal format * ((const char **)response)[3] is MIN (10 digits, MIN2+MIN1) if CDMA subscription is available * ((const char **)response)[4] is PRL version if CDMA subscription is available * * Valid errors: * SUCCESS * RIL_E_SUBSCRIPTION_NOT_AVAILABLE */ #define RIL_REQUEST_CDMA_SUBSCRIPTION 95 /** * RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM * * Stores a CDMA SMS message to RUIM memory. * * "data" is RIL_CDMA_SMS_WriteArgs * * * "response" is int * * ((const int *)response)[0] is the record index where the message is stored. * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * SIM_FULL * INVALID_ARGUMENTS * INVALID_SMS_FORMAT * INTERNAL_ERR * MODEM_ERR * ENCODING_ERR * NO_MEMORY * NO_RESOURCES * INVALID_MODEM_STATE * MODE_NOT_SUPPORTED * INVALID_SMSC_ADDRESS * GENERIC_FAILURE * */ #define RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM 96 /** * RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM * * Deletes a CDMA SMS message from RUIM memory. * * "data" is int * * ((int *)data)[0] is the record index of the message to delete. * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * INVALID_ARGUMENTS * NO_MEMORY * REQUEST_RATE_LIMITED * SYSTEM_ERR * MODEM_ERR * NO_SUCH_ENTRY * GENERIC_FAILURE * */ #define RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM 97 /** * RIL_REQUEST_DEVICE_IDENTITY * * Request the device ESN / MEID / IMEI / IMEISV. * * The request is always allowed and contains GSM and CDMA device identity; * it substitutes the deprecated requests RIL_REQUEST_GET_IMEI and * RIL_REQUEST_GET_IMEISV. * * If a NULL value is returned for any of the device id, it means that error * accessing the device. * * When CDMA subscription is changed the ESN/MEID may change. The application * layer should re-issue the request to update the device identity in this case. * * "response" is const char ** * ((const char **)response)[0] is IMEI if GSM subscription is available * ((const char **)response)[1] is IMEISV if GSM subscription is available * ((const char **)response)[2] is ESN if CDMA subscription is available * ((const char **)response)[3] is MEID if CDMA subscription is available * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE */ #define RIL_REQUEST_DEVICE_IDENTITY 98 /** * RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE * * Request the radio's system selection module to exit emergency * callback mode. RIL will not respond with SUCCESS until the modem has * completely exited from Emergency Callback Mode. * * "data" is NULL * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * OPERATION_NOT_ALLOWED * GENERIC_FAILURE * */ #define RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE 99 /** * RIL_REQUEST_GET_SMSC_ADDRESS * * Queries the default Short Message Service Center address on the device. * * "data" is NULL * * "response" is const char * containing the SMSC address. * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * NO_MEMORY * REQUEST_RATE_LIMITED * SYSTEM_ERR * INTERNAL_ERR * MODEM_ERR * INVALID_ARGUMENTS * INVALID_MODEM_STATE * NOT_PROVISIONED * GENERIC_FAILURE * */ #define RIL_REQUEST_GET_SMSC_ADDRESS 100 /** * RIL_REQUEST_SET_SMSC_ADDRESS * * Sets the default Short Message Service Center address on the device. * * "data" is const char * containing the SMSC address. * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * INVALID_ARGUMENTS * INVALID_SMS_FORMAT * NO_MEMORY * SYSTEM_ERR * REQUEST_RATE_LIMITED * MODEM_ERR * NO_RESOURCES * GENERIC_FAILURE * */ #define RIL_REQUEST_SET_SMSC_ADDRESS 101 /** * RIL_REQUEST_REPORT_SMS_MEMORY_STATUS * * Indicates whether there is storage available for new SMS messages. * * "data" is int * * ((int *)data)[0] is 1 if memory is available for storing new messages * is 0 if memory capacity is exceeded * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * INVALID_ARGUMENTS * NO_MEMORY * INVALID_STATE * SYSTEM_ERR * REQUEST_RATE_LIMITED * MODEM_ERR * GENERIC_FAILURE * */ #define RIL_REQUEST_REPORT_SMS_MEMORY_STATUS 102 /** * RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING * * Indicates that the StkSerivce is running and is * ready to receive RIL_UNSOL_STK_XXXXX commands. * * "data" is NULL * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE * */ #define RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING 103 /** * RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE * * Request to query the location where the CDMA subscription shall * be retrieved * * "data" is NULL * * "response" is int * * ((int *)data)[0] is == RIL_CdmaSubscriptionSource * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE * SUBSCRIPTION_NOT_AVAILABLE * * See also: RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE */ #define RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE 104 /** * RIL_REQUEST_ISIM_AUTHENTICATION * * Request the ISIM application on the UICC to perform AKA * challenge/response algorithm for IMS authentication * * "data" is a const char * containing the challenge string in Base64 format * "response" is a const char * containing the response in Base64 format * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE */ #define RIL_REQUEST_ISIM_AUTHENTICATION 105 /** * RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU * * Acknowledge successful or failed receipt of SMS previously indicated * via RIL_UNSOL_RESPONSE_NEW_SMS, including acknowledgement TPDU to send * as the RP-User-Data element of the RP-ACK or RP-ERROR PDU. * * "data" is const char ** * ((const char **)data)[0] is "1" on successful receipt (send RP-ACK) * is "0" on failed receipt (send RP-ERROR) * ((const char **)data)[1] is the acknowledgement TPDU in hexadecimal format * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE */ #define RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU 106 /** * RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS * * Requests to send a SAT/USAT envelope command to SIM. * The SAT/USAT envelope command refers to 3GPP TS 11.14 and 3GPP TS 31.111. * * This request has one difference from RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: * the SW1 and SW2 status bytes from the UICC response are returned along with * the response data, using the same structure as RIL_REQUEST_SIM_IO. * * The RIL implementation shall perform the normal processing of a '91XX' * response in SW1/SW2 to retrieve the pending proactive command and send it * as an unsolicited response, as RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND does. * * "data" is a const char * containing the SAT/USAT command * in hexadecimal format starting with command tag * * "response" is a const RIL_SIM_IO_Response * * * Valid errors: * RIL_E_SUCCESS * RIL_E_RADIO_NOT_AVAILABLE (radio resetting) * SIM_BUSY * OPERATION_NOT_ALLOWED * RIL_E_GENERIC_FAILURE */ #define RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS 107 /** * RIL_REQUEST_VOICE_RADIO_TECH * * Query the radio technology type (3GPP/3GPP2) used for voice. Query is valid only * when radio state is not RADIO_STATE_UNAVAILABLE * * "data" is NULL * "response" is int * * ((int *) response)[0] is of type const RIL_RadioTechnology * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE */ #define RIL_REQUEST_VOICE_RADIO_TECH 108 /** * RIL_REQUEST_GET_CELL_INFO_LIST * * Request all of the current cell information known to the radio. The radio * must a list of all current cells, including the neighboring cells. If for a particular * cell information isn't known then the appropriate unknown value will be returned. * This does not cause or change the rate of RIL_UNSOL_CELL_INFO_LIST. * * "data" is NULL * * "response" is an array of RIL_CellInfo_v12. */ #define RIL_REQUEST_GET_CELL_INFO_LIST 109 /** * RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE * * Sets the minimum time between when RIL_UNSOL_CELL_INFO_LIST should be invoked. * A value of 0, means invoke RIL_UNSOL_CELL_INFO_LIST when any of the reported * information changes. Setting the value to INT_MAX(0x7fffffff) means never issue * a RIL_UNSOL_CELL_INFO_LIST. * * "data" is int * * ((int *)data)[0] is minimum time in milliseconds * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE */ #define RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE 110 /** * RIL_REQUEST_SET_INITIAL_ATTACH_APN * * Set an apn to initial attach network * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * GENERIC_FAILURE * SUBSCRIPTION_NOT_AVAILABLE */ #define RIL_REQUEST_SET_INITIAL_ATTACH_APN 111 /** * RIL_REQUEST_IMS_REGISTRATION_STATE * * Request current IMS registration state * * "data" is NULL * * "response" is int * * ((int *)response)[0] is registration state: * 0 - Not registered * 1 - Registered * * If ((int*)response)[0] is = 1, then ((int *) response)[1] * must follow with IMS SMS format: * * ((int *) response)[1] is of type RIL_RadioTechnologyFamily * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE */ #define RIL_REQUEST_IMS_REGISTRATION_STATE 112 /** * RIL_REQUEST_IMS_SEND_SMS * * Send a SMS message over IMS * * "data" is const RIL_IMS_SMS_Message * * * "response" is a const RIL_SMS_Response * * * Based on the return error, caller decides to resend if sending sms * fails. SMS_SEND_FAIL_RETRY means retry, and other errors means no retry. * In case of retry, data is encoded based on Voice Technology available. * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * SMS_SEND_FAIL_RETRY * FDN_CHECK_FAILURE * NETWORK_REJECT * INVALID_ARGUMENTS * INVALID_STATE * NO_MEMORY * INVALID_SMS_FORMAT * SYSTEM_ERR * REQUEST_RATE_LIMITED * MODEM_ERR * NETWORK_ERR * ENCODING_ERR * INVALID_SMSC_ADDRESS * MODE_NOT_SUPPORTED * GENERIC_FAILURE * */ #define RIL_REQUEST_IMS_SEND_SMS 113 /** * RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC * * Request APDU exchange on the basic channel. This command reflects TS 27.007 * "generic SIM access" operation (+CSIM). The modem must ensure proper function * of GSM/CDMA, and filter commands appropriately. It should filter * channel management and SELECT by DF name commands. * * "data" is a const RIL_SIM_APDU * * "sessionid" field should be ignored. * * "response" is a const RIL_SIM_IO_Response * * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE */ #define RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC 114 /** * RIL_REQUEST_SIM_OPEN_CHANNEL * * Open a new logical channel and select the given application. This command * reflects TS 27.007 "open logical channel" operation (+CCHO). * * "data" is const char * and set to AID value, See ETSI 102.221 and 101.220. * * "response" is int * * ((int *)data)[0] contains the session id of the logical channel. * ((int *)data)[1] onwards may optionally contain the select response for the * open channel command with one byte per integer. * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE * MISSING_RESOURCE * NO_SUCH_ELEMENT */ #define RIL_REQUEST_SIM_OPEN_CHANNEL 115 /** * RIL_REQUEST_SIM_CLOSE_CHANNEL * * Close a previously opened logical channel. This command reflects TS 27.007 * "close logical channel" operation (+CCHC). * * "data" is int * * ((int *)data)[0] is the session id of logical the channel to close. * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE */ #define RIL_REQUEST_SIM_CLOSE_CHANNEL 116 /** * RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL * * Exchange APDUs with a UICC over a previously opened logical channel. This * command reflects TS 27.007 "generic logical channel access" operation * (+CGLA). The modem should filter channel management and SELECT by DF name * commands. * * "data" is a const RIL_SIM_APDU* * * "response" is a const RIL_SIM_IO_Response * * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE */ #define RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL 117 /** * RIL_REQUEST_NV_READ_ITEM * * Read one of the radio NV items defined in RadioNVItems.java / ril_nv_items.h. * This is used for device configuration by some CDMA operators. * * "data" is a const RIL_NV_ReadItem * * * "response" is const char * containing the contents of the NV item * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE */ #define RIL_REQUEST_NV_READ_ITEM 118 /** * RIL_REQUEST_NV_WRITE_ITEM * * Write one of the radio NV items defined in RadioNVItems.java / ril_nv_items.h. * This is used for device configuration by some CDMA operators. * * "data" is a const RIL_NV_WriteItem * * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE */ #define RIL_REQUEST_NV_WRITE_ITEM 119 /** * RIL_REQUEST_NV_WRITE_CDMA_PRL * * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage. * This is used for device configuration by some CDMA operators. * * "data" is a const char * containing the PRL as a byte array * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE */ #define RIL_REQUEST_NV_WRITE_CDMA_PRL 120 /** * RIL_REQUEST_NV_RESET_CONFIG * * Reset the radio NV configuration to the factory state. * This is used for device configuration by some CDMA operators. * * "data" is int * * ((int *)data)[0] is 1 to reload all NV items * ((int *)data)[0] is 2 for erase NV reset (SCRTN) * ((int *)data)[0] is 3 for factory reset (RTN) * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE */ #define RIL_REQUEST_NV_RESET_CONFIG 121 /** RIL_REQUEST_SET_UICC_SUBSCRIPTION * FIXME This API needs to have more documentation. * * Selection/de-selection of a subscription from a SIM card * "data" is const RIL_SelectUiccSub* * * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * GENERIC_FAILURE * SUBSCRIPTION_NOT_SUPPORTED * */ #define RIL_REQUEST_SET_UICC_SUBSCRIPTION 122 /** * RIL_REQUEST_ALLOW_DATA * * Tells the modem whether data calls are allowed or not * * "data" is int * * FIXME slotId and aid will be added. * ((int *)data)[0] is == 0 to allow data calls * ((int *)data)[0] is == 1 to disallow data calls * * "response" is NULL * * Valid errors: * * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * GENERIC_FAILURE * */ #define RIL_REQUEST_ALLOW_DATA 123 /** * RIL_REQUEST_GET_HARDWARE_CONFIG * * Request all of the current hardware (modem and sim) associated * with the RIL. * * "data" is NULL * * "response" is an array of RIL_HardwareConfig. */ #define RIL_REQUEST_GET_HARDWARE_CONFIG 124 /** * RIL_REQUEST_SIM_AUTHENTICATION * * Returns the response of SIM Authentication through RIL to a * challenge request. * * "data" Base64 encoded string containing challenge: * int authContext; P2 value of authentication command, see P2 parameter in * 3GPP TS 31.102 7.1.2 * char *authData; the challenge string in Base64 format, see 3GPP * TS 31.102 7.1.2 * char *aid; AID value, See ETSI 102.221 8.1 and 101.220 4, * NULL if no value * * "response" Base64 encoded strings containing response: * int sw1; Status bytes per 3GPP TS 31.102 section 7.3 * int sw2; * char *simResponse; Response in Base64 format, see 3GPP TS 31.102 7.1.2 */ #define RIL_REQUEST_SIM_AUTHENTICATION 125 /** * RIL_REQUEST_GET_DC_RT_INFO * * The request is DEPRECATED, use RIL_REQUEST_GET_ACTIVITY_INFO * Requests the Data Connection Real Time Info * * "data" is NULL * * "response" is the most recent RIL_DcRtInfo * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE * * See also: RIL_UNSOL_DC_RT_INFO_CHANGED */ #define RIL_REQUEST_GET_DC_RT_INFO 126 /** * RIL_REQUEST_SET_DC_RT_INFO_RATE * * The request is DEPRECATED * This is the minimum number of milliseconds between successive * RIL_UNSOL_DC_RT_INFO_CHANGED messages and defines the highest rate * at which RIL_UNSOL_DC_RT_INFO_CHANGED's will be sent. A value of * 0 means send as fast as possible. * * "data" The number of milliseconds as an int * * "response" is null * * Valid errors: * SUCCESS must not fail */ #define RIL_REQUEST_SET_DC_RT_INFO_RATE 127 /** * RIL_REQUEST_SET_DATA_PROFILE * * Set data profile in modem * Modem should erase existed profiles from framework, and apply new profiles * "data" is an const RIL_DataProfileInfo ** * "datalen" is count * sizeof(const RIL_DataProfileInfo *) * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * GENERIC_FAILURE * SUBSCRIPTION_NOT_AVAILABLE */ #define RIL_REQUEST_SET_DATA_PROFILE 128 /** * RIL_REQUEST_SHUTDOWN * * Device is shutting down. All further commands are ignored * and RADIO_NOT_AVAILABLE must be returned. * * "data" is null * "response" is NULL * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * OPERATION_NOT_ALLOWED * GENERIC_FAILURE */ #define RIL_REQUEST_SHUTDOWN 129 /** * RIL_REQUEST_GET_RADIO_CAPABILITY * * Used to get phone radio capablility. * * "data" is the RIL_RadioCapability structure * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * OPERATION_NOT_ALLOWED * GENERIC_FAILURE */ #define RIL_REQUEST_GET_RADIO_CAPABILITY 130 /** * RIL_REQUEST_SET_RADIO_CAPABILITY * * Used to set the phones radio capability. Be VERY careful * using this request as it may cause some vendor modems to reset. Because * of the possible modem reset any RIL commands after this one may not be * processed. * * "data" is the RIL_RadioCapability structure * * "response" is the RIL_RadioCapability structure, used to feedback return status * * Valid errors: * SUCCESS means a RIL_UNSOL_RADIO_CAPABILITY will be sent within 30 seconds. * RADIO_NOT_AVAILABLE * OPERATION_NOT_ALLOWED * GENERIC_FAILURE */ #define RIL_REQUEST_SET_RADIO_CAPABILITY 131 /** * RIL_REQUEST_START_LCE * * Start Link Capacity Estimate (LCE) service if supported by the radio. * * "data" is const int * * ((const int*)data)[0] specifies the desired reporting interval (ms). * ((const int*)data)[1] specifies the LCE service mode. 1: PULL; 0: PUSH. * * "response" is the RIL_LceStatusInfo. * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * LCE_NOT_SUPPORTED */ #define RIL_REQUEST_START_LCE 132 /** * RIL_REQUEST_STOP_LCE * * Stop Link Capacity Estimate (LCE) service, the STOP operation should be * idempotent for the radio modem. * * "response" is the RIL_LceStatusInfo. * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * LCE_NOT_SUPPORTED */ #define RIL_REQUEST_STOP_LCE 133 /** * RIL_REQUEST_PULL_LCEDATA * * Pull LCE service for capacity information. * * "response" is the RIL_LceDataInfo. * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * LCE_NOT_SUPPORTED */ #define RIL_REQUEST_PULL_LCEDATA 134 /** * RIL_REQUEST_GET_ACTIVITY_INFO * * Get modem activity statisitics info. * * There can be multiple RIL_REQUEST_GET_ACTIVITY_INFO calls to modem. * Once the response for the request is sent modem will clear * current statistics information. * * "data" is null * "response" is const RIL_ActivityStatsInfo * * * Valid errors: * * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * GENERIC_FAILURE */ #define RIL_REQUEST_GET_ACTIVITY_INFO 135 /** * RIL_REQUEST_SIM_GET_ATR * * Get the ATR from SIM Card * * Only valid when radio state is "RADIO_STATE_ON" * * "data" is const int * * ((const int *)data)[0] contains the slot index on the SIM from which ATR is requested. * * "response" is a const char * containing the ATR, See ETSI 102.221 8.1 and ISO/IEC 7816 3 * * Valid errors: * * SUCCESS * RADIO_NOT_AVAILABLE (radio resetting) * GENERIC_FAILURE */ #define RIL_REQUEST_SIM_GET_ATR 136 /** * RIL_REQUEST_CAF_SIM_OPEN_CHANNEL_WITH_P2 * * Open a new logical channel and select the given application. This command * reflects TS 27.007 "open logical channel" operation (+CCHO). This request * also specifies the P2 parameter. * * "data" is a const RIL_CafOpenChannelParam * * * "response" is int * * ((int *)data)[0] contains the session id of the logical channel. * ((int *)data)[1] onwards may optionally contain the select response for the * open channel command with one byte per integer. * * Valid errors: * SUCCESS * RADIO_NOT_AVAILABLE * GENERIC_FAILURE * MISSING_RESOURCE * NO_SUCH_ELEMENT */ #define RIL_REQUEST_CAF_SIM_OPEN_CHANNEL_WITH_P2 137 /** * RIL_REQUEST_GET_ADN_RECORD * * Requests ADN count record of the SIM card * * "data" is NULL * * "response" is const int * * ((int *)data)[0] is the max adn count. * ((int *)data)[1] is the valid adn count. * ((int *)data)[2] is the max email count. * ((int *)data)[3] is the max anr count. * * Valid errors: * SUCCESS * GENERIC_FAILURE */ #define RIL_REQUEST_GET_ADN_RECORD 138 /** * RIL_REQUEST_UPDATE_ADN_RECORD * * Requests ADN count of the the SIM card * * "data" is RIL_AdnRecordInfo * * * "response" is const int * * * Valid errors: * Must never fail */ #define RIL_REQUEST_UPDATE_ADN_RECORD 139 /** * RIL_REQUEST_SET_CARRIER_RESTRICTIONS * * Set carrier restrictions for this sim slot. Expected modem behavior: * If never receives this command * - Must allow all carriers * Receives this command with data being NULL * - Must allow all carriers. If a previously allowed SIM is present, modem must not reload * the SIM. If a previously disallowed SIM is present, reload the SIM and notify Android. * Receives this command with a list of carriers * - Only allow specified carriers, persist across power cycles and FDR. If a present SIM * is in the allowed list, modem must not reload the SIM. If a present SIM is *not* in * the allowed list, modem must detach from the registered network and only keep emergency * service, and notify Android SIM refresh reset with new SIM state being * RIL_CARDSTATE_RESTRICTED. Emergency service must be enabled. * * "data" is const RIL_CarrierRestrictions * * A list of allowed carriers and possibly a list of excluded carriers. * If data is NULL, means to clear previous carrier restrictions and allow all carriers * * "response" is int * * ((int *)data)[0] contains the number of allowed carriers which have been set correctly. * On success, it should match the length of list data->allowed_carriers. * If data is NULL, the value must be 0. * * Valid errors: * RIL_E_SUCCESS * RIL_E_INVALID_ARGUMENTS * RIL_E_RADIO_NOT_AVAILABLE * RIL_E_REQUEST_NOT_SUPPORTED */ #define RIL_REQUEST_SET_CARRIER_RESTRICTIONS 140 /** * RIL_REQUEST_GET_CARRIER_RESTRICTIONS * * Get carrier restrictions for this sim slot. Expected modem behavior: * Return list of allowed carriers, or null if all carriers are allowed. * * "data" is NULL * * "response" is const RIL_CarrierRestrictions *. * If response is NULL, it means all carriers are allowed. * * Valid errors: * RIL_E_SUCCESS * RIL_E_RADIO_NOT_AVAILABLE * RIL_E_REQUEST_NOT_SUPPORTED */ #define RIL_REQUEST_GET_CARRIER_RESTRICTIONS 141 /***********************************************************************/ /** * RIL_RESPONSE_ACKNOWLEDGEMENT * * This is used by Asynchronous solicited messages and Unsolicited messages * to acknowledge the receipt of those messages in RIL.java so that the ack * can be used to let ril.cpp to release wakelock. * * Valid errors * SUCCESS * RADIO_NOT_AVAILABLE */ #define RIL_RESPONSE_ACKNOWLEDGEMENT 800 /***********************************************************************/ #define RIL_UNSOL_RESPONSE_BASE 1000 /** * RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED * * Indicate when value of RIL_RadioState has changed. * * Callee will invoke RIL_RadioStateRequest method on main thread * * "data" is NULL */ #define RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED 1000 /** * RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED * * Indicate when call state has changed * * Callee will invoke RIL_REQUEST_GET_CURRENT_CALLS on main thread * * "data" is NULL * * Response should be invoked on, for example, * "RING", "BUSY", "NO CARRIER", and also call state * transitions (DIALING->ALERTING ALERTING->ACTIVE) * * Redundent or extraneous invocations are tolerated */ #define RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED 1001 /** * RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED * * Called when the voice network state changed * * Callee will invoke the following requests on main thread: * * RIL_REQUEST_VOICE_REGISTRATION_STATE * RIL_REQUEST_OPERATOR * * "data" is NULL * * FIXME should this happen when SIM records are loaded? (eg, for * EONS) */ #define RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED 1002 /** * RIL_UNSOL_RESPONSE_NEW_SMS * * Called when new SMS is received. * * "data" is const char * * This is a pointer to a string containing the PDU of an SMS-DELIVER * as an ascii string of hex digits. The PDU starts with the SMSC address * per TS 27.005 (+CMT:) * * Callee will subsequently confirm the receipt of thei SMS with a * RIL_REQUEST_SMS_ACKNOWLEDGE * * No new RIL_UNSOL_RESPONSE_NEW_SMS * or RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT messages should be sent until a * RIL_REQUEST_SMS_ACKNOWLEDGE has been received */ #define RIL_UNSOL_RESPONSE_NEW_SMS 1003 /** * RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT * * Called when new SMS Status Report is received. * * "data" is const char * * This is a pointer to a string containing the PDU of an SMS-STATUS-REPORT * as an ascii string of hex digits. The PDU starts with the SMSC address * per TS 27.005 (+CDS:). * * Callee will subsequently confirm the receipt of the SMS with a * RIL_REQUEST_SMS_ACKNOWLEDGE * * No new RIL_UNSOL_RESPONSE_NEW_SMS * or RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT messages should be sent until a * RIL_REQUEST_SMS_ACKNOWLEDGE has been received */ #define RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT 1004 /** * RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM * * Called when new SMS has been stored on SIM card * * "data" is const int * * ((const int *)data)[0] contains the slot index on the SIM that contains * the new message */ #define RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM 1005 /** * RIL_UNSOL_ON_USSD * * Called when a new USSD message is received. * * "data" is const char ** * ((const char **)data)[0] points to a type code, which is * one of these string values: * "0" USSD-Notify -- text in ((const char **)data)[1] * "1" USSD-Request -- text in ((const char **)data)[1] * "2" Session terminated by network * "3" other local client (eg, SIM Toolkit) has responded * "4" Operation not supported * "5" Network timeout * * The USSD session is assumed to persist if the type code is "1", otherwise * the current session (if any) is assumed to have terminated. * * ((const char **)data)[1] points to a message string if applicable, which * should always be in UTF-8. */ #define RIL_UNSOL_ON_USSD 1006 /* Previously #define RIL_UNSOL_ON_USSD_NOTIFY 1006 */ /** * RIL_UNSOL_ON_USSD_REQUEST * * Obsolete. Send via RIL_UNSOL_ON_USSD */ #define RIL_UNSOL_ON_USSD_REQUEST 1007 /** * RIL_UNSOL_NITZ_TIME_RECEIVED * * Called when radio has received a NITZ time message * * "data" is const char * pointing to NITZ time string * in the form "yy/mm/dd,hh:mm:ss(+/-)tz,dt" */ #define RIL_UNSOL_NITZ_TIME_RECEIVED 1008 /** * RIL_UNSOL_SIGNAL_STRENGTH * * Radio may report signal strength rather han have it polled. * * "data" is a const RIL_SignalStrength * */ #define RIL_UNSOL_SIGNAL_STRENGTH 1009 /** * RIL_UNSOL_DATA_CALL_LIST_CHANGED * * "data" is an array of RIL_Data_Call_Response_v6 identical to that * returned by RIL_REQUEST_DATA_CALL_LIST. It is the complete list * of current data contexts including new contexts that have been * activated. A data call is only removed from this list when the * framework sends a RIL_REQUEST_DEACTIVATE_DATA_CALL or the radio * is powered off/on. * * See also: RIL_REQUEST_DATA_CALL_LIST */ #define RIL_UNSOL_DATA_CALL_LIST_CHANGED 1010 /** * RIL_UNSOL_SUPP_SVC_NOTIFICATION * * Reports supplementary service related notification from the network. * * "data" is a const RIL_SuppSvcNotification * * */ #define RIL_UNSOL_SUPP_SVC_NOTIFICATION 1011 /** * RIL_UNSOL_STK_SESSION_END * * Indicate when STK session is terminated by SIM. * * "data" is NULL */ #define RIL_UNSOL_STK_SESSION_END 1012 /** * RIL_UNSOL_STK_PROACTIVE_COMMAND * * Indicate when SIM issue a STK proactive command to applications * * "data" is a const char * containing SAT/USAT proactive command * in hexadecimal format string starting with command tag * */ #define RIL_UNSOL_STK_PROACTIVE_COMMAND 1013 /** * RIL_UNSOL_STK_EVENT_NOTIFY * * Indicate when SIM notifies applcations some event happens. * Generally, application does not need to have any feedback to * SIM but shall be able to indicate appropriate messages to users. * * "data" is a const char * containing SAT/USAT commands or responses * sent by ME to SIM or commands handled by ME, in hexadecimal format string * starting with first byte of response data or command tag * */ #define RIL_UNSOL_STK_EVENT_NOTIFY 1014 /** * RIL_UNSOL_STK_CALL_SETUP * * Indicate when SIM wants application to setup a voice call. * * "data" is const int * * ((const int *)data)[0] contains timeout value (in milliseconds) */ #define RIL_UNSOL_STK_CALL_SETUP 1015 /** * RIL_UNSOL_SIM_SMS_STORAGE_FULL * * Indicates that SMS storage on the SIM is full. Sent when the network * attempts to deliver a new SMS message. Messages cannot be saved on the * SIM until space is freed. In particular, incoming Class 2 messages * cannot be stored. * * "data" is null * */ #define RIL_UNSOL_SIM_SMS_STORAGE_FULL 1016 /** * RIL_UNSOL_SIM_REFRESH * * Indicates that file(s) on the SIM have been updated, or the SIM * has been reinitialized. * * In the case where RIL is version 6 or older: * "data" is an int * * ((int *)data)[0] is a RIL_SimRefreshResult. * ((int *)data)[1] is the EFID of the updated file if the result is * SIM_FILE_UPDATE or NULL for any other result. * * In the case where RIL is version 7: * "data" is a RIL_SimRefreshResponse_v7 * * * Note: If the SIM state changes as a result of the SIM refresh (eg, * SIM_READY -> SIM_LOCKED_OR_ABSENT), RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED * should be sent. */ #define RIL_UNSOL_SIM_REFRESH 1017 /** * RIL_UNSOL_CALL_RING * * Ring indication for an incoming call (eg, RING or CRING event). * There must be at least one RIL_UNSOL_CALL_RING at the beginning * of a call and sending multiple is optional. If the system property * ro.telephony.call_ring.multiple is false then the upper layers * will generate the multiple events internally. Otherwise the vendor * ril must generate multiple RIL_UNSOL_CALL_RING if * ro.telephony.call_ring.multiple is true or if it is absent. * * The rate of these events is controlled by ro.telephony.call_ring.delay * and has a default value of 3000 (3 seconds) if absent. * * "data" is null for GSM * "data" is const RIL_CDMA_SignalInfoRecord * if CDMA */ #define RIL_UNSOL_CALL_RING 1018 /** * RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED * * Indicates that SIM state changes. * * Callee will invoke RIL_REQUEST_GET_SIM_STATUS on main thread * "data" is null */ #define RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED 1019 /** * RIL_UNSOL_RESPONSE_CDMA_NEW_SMS * * Called when new CDMA SMS is received * * "data" is const RIL_CDMA_SMS_Message * * * Callee will subsequently confirm the receipt of the SMS with * a RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE * * No new RIL_UNSOL_RESPONSE_CDMA_NEW_SMS should be sent until * RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE has been received * */ #define RIL_UNSOL_RESPONSE_CDMA_NEW_SMS 1020 /** * RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS * * Called when new Broadcast SMS is received * * "data" can be one of the following: * If received from GSM network, "data" is const char of 88 bytes * which indicates each page of a CBS Message sent to the MS by the * BTS as coded in 3GPP 23.041 Section 9.4.1.2. * If received from UMTS network, "data" is const char of 90 up to 1252 * bytes which contain between 1 and 15 CBS Message pages sent as one * packet to the MS by the BTS as coded in 3GPP 23.041 Section 9.4.2.2. * */ #define RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS 1021 /** * RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL * * Indicates that SMS storage on the RUIM is full. Messages * cannot be saved on the RUIM until space is freed. * * "data" is null * */ #define RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL 1022 /** * RIL_UNSOL_RESTRICTED_STATE_CHANGED * * Indicates a restricted state change (eg, for Domain Specific Access Control). * * Radio need send this msg after radio off/on cycle no matter it is changed or not. * * "data" is an int * * ((int *)data)[0] contains a bitmask of RIL_RESTRICTED_STATE_* values. */ #define RIL_UNSOL_RESTRICTED_STATE_CHANGED 1023 /** * RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE * * Indicates that the radio system selection module has * autonomously entered emergency callback mode. * * "data" is null * */ #define RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE 1024 /** * RIL_UNSOL_CDMA_CALL_WAITING * * Called when CDMA radio receives a call waiting indication. * * "data" is const RIL_CDMA_CallWaiting * * */ #define RIL_UNSOL_CDMA_CALL_WAITING 1025 /** * RIL_UNSOL_CDMA_OTA_PROVISION_STATUS * * Called when CDMA radio receives an update of the progress of an * OTASP/OTAPA call. * * "data" is const int * * For CDMA this is an integer OTASP/OTAPA status listed in * RIL_CDMA_OTA_ProvisionStatus. * */ #define RIL_UNSOL_CDMA_OTA_PROVISION_STATUS 1026 /** * RIL_UNSOL_CDMA_INFO_REC * * Called when CDMA radio receives one or more info recs. * * "data" is const RIL_CDMA_InformationRecords * * */ #define RIL_UNSOL_CDMA_INFO_REC 1027 /** * RIL_UNSOL_OEM_HOOK_RAW * * This is for OEM specific use. * * "data" is a byte[] */ #define RIL_UNSOL_OEM_HOOK_RAW 1028 /** * RIL_UNSOL_RINGBACK_TONE * * Indicates that nework doesn't have in-band information, need to * play out-band tone. * * "data" is an int * * ((int *)data)[0] == 0 for stop play ringback tone. * ((int *)data)[0] == 1 for start play ringback tone. */ #define RIL_UNSOL_RINGBACK_TONE 1029 /** * RIL_UNSOL_RESEND_INCALL_MUTE * * Indicates that framework/application need reset the uplink mute state. * * There may be situations where the mute state becomes out of sync * between the application and device in some GSM infrastructures. * * "data" is null */ #define RIL_UNSOL_RESEND_INCALL_MUTE 1030 /** * RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED * * Called when CDMA subscription source changed. * * "data" is int * * ((int *)data)[0] is == RIL_CdmaSubscriptionSource */ #define RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED 1031 /** * RIL_UNSOL_CDMA_PRL_CHANGED * * Called when PRL (preferred roaming list) changes. * * "data" is int * * ((int *)data)[0] is PRL_VERSION as would be returned by RIL_REQUEST_CDMA_SUBSCRIPTION */ #define RIL_UNSOL_CDMA_PRL_CHANGED 1032 /** * RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE * * Called when Emergency Callback Mode Ends * * Indicates that the radio system selection module has * proactively exited emergency callback mode. * * "data" is NULL * */ #define RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE 1033 /** * RIL_UNSOL_RIL_CONNECTED * * Called the ril connects and returns the version * * "data" is int * * ((int *)data)[0] is RIL_VERSION */ #define RIL_UNSOL_RIL_CONNECTED 1034 /** * RIL_UNSOL_VOICE_RADIO_TECH_CHANGED * * Indicates that voice technology has changed. Contains new radio technology * as a data in the message. * * "data" is int * * ((int *)data)[0] is of type const RIL_RadioTechnology * */ #define RIL_UNSOL_VOICE_RADIO_TECH_CHANGED 1035 /** * RIL_UNSOL_CELL_INFO_LIST * * Same information as returned by RIL_REQUEST_GET_CELL_INFO_LIST, but returned * at the rate no greater than specified by RIL_REQUEST_SET_UNSOL_CELL_INFO_RATE. * * "data" is NULL * * "response" is an array of RIL_CellInfo_v12. */ #define RIL_UNSOL_CELL_INFO_LIST 1036 /** * RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED * * Called when IMS registration state has changed * * To get IMS registration state and IMS SMS format, callee needs to invoke the * following request on main thread: * * RIL_REQUEST_IMS_REGISTRATION_STATE * * "data" is NULL * */ #define RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED 1037 /** * RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED * * Indicated when there is a change in subscription status. * This event will be sent in the following scenarios * - subscription readiness at modem, which was selected by telephony layer * - when subscription is deactivated by modem due to UICC card removal * - When network invalidates the subscription i.e. attach reject due to authentication reject * * "data" is const int * * ((const int *)data)[0] == 0 for Subscription Deactivated * ((const int *)data)[0] == 1 for Subscription Activated * */ #define RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED 1038 /** * RIL_UNSOL_SRVCC_STATE_NOTIFY * * Called when Single Radio Voice Call Continuity(SRVCC) * progress state has changed * * "data" is int * * ((int *)data)[0] is of type const RIL_SrvccState * */ #define RIL_UNSOL_SRVCC_STATE_NOTIFY 1039 /** * RIL_UNSOL_HARDWARE_CONFIG_CHANGED * * Called when the hardware configuration associated with the RILd changes * * "data" is an array of RIL_HardwareConfig * */ #define RIL_UNSOL_HARDWARE_CONFIG_CHANGED 1040 /** * RIL_UNSOL_DC_RT_INFO_CHANGED * * The message is DEPRECATED, use RIL_REQUEST_GET_ACTIVITY_INFO * Sent when the DC_RT_STATE changes but the time * between these messages must not be less than the * value set by RIL_REQUEST_SET_DC_RT_RATE. * * "data" is the most recent RIL_DcRtInfo * */ #define RIL_UNSOL_DC_RT_INFO_CHANGED 1041 /** * RIL_UNSOL_RADIO_CAPABILITY * * Sent when RIL_REQUEST_SET_RADIO_CAPABILITY completes. * Returns the phone radio capability exactly as * RIL_REQUEST_GET_RADIO_CAPABILITY and should be the * same set as sent by RIL_REQUEST_SET_RADIO_CAPABILITY. * * "data" is the RIL_RadioCapability structure */ #define RIL_UNSOL_RADIO_CAPABILITY 1042 /* * RIL_UNSOL_ON_SS * * Called when SS response is received when DIAL/USSD/SS is changed to SS by * call control. * * "data" is const RIL_StkCcUnsolSsResponse * * */ #define RIL_UNSOL_ON_SS 1043 /** * RIL_UNSOL_STK_CC_ALPHA_NOTIFY * * Called when there is an ALPHA from UICC during Call Control. * * "data" is const char * containing ALPHA string from UICC in UTF-8 format. * */ #define RIL_UNSOL_STK_CC_ALPHA_NOTIFY 1044 /** * RIL_UNSOL_LCEDATA_RECV * * Called when there is an incoming Link Capacity Estimate (LCE) info report. * * "data" is the RIL_LceDataInfo structure. * */ #define RIL_UNSOL_LCEDATA_RECV 1045 /** * RIL_UNSOL_RESPONSE_ADN_INIT_DONE * * Called when the ADN has already init done, * * "data" is NULL. * */ #define RIL_UNSOL_RESPONSE_ADN_INIT_DONE 1046 /** * RIL_UNSOL_RESPONSE_ADN_RECORDS * * Called when there is a group of ADN record report, * * "data" is the RIL_ADN structure. * */ #define RIL_UNSOL_RESPONSE_ADN_RECORDS 1047 /** * RIL_UNSOL_PCO_DATA * * Called when there is new Carrier PCO data received for a data call. Ideally * only new data will be forwarded, though this is not required. Multiple * boxes of carrier PCO data for a given call should result in a series of * RIL_UNSOL_PCO_DATA calls. * * "data" is the RIL_PCO_Data structure. * */ #define RIL_UNSOL_PCO_DATA 1049 /***********************************************************************/ #if defined(ANDROID_MULTI_SIM) /** * RIL_Request Function pointer * * @param request is one of RIL_REQUEST_* * @param data is pointer to data defined for that RIL_REQUEST_* * data is owned by caller, and should not be modified or freed by callee * structures passed as data may contain pointers to non-contiguous memory * @param t should be used in subsequent call to RIL_onResponse * @param datalen is the length of "data" which is defined as other argument. It may or may * not be equal to sizeof(data). Refer to the documentation of individual structures * to find if pointers listed in the structure are contiguous and counted in the datalen * length or not. * (Eg: RIL_IMS_SMS_Message where we don't have datalen equal to sizeof(data)) * */ typedef void (*RIL_RequestFunc) (int request, void *data, size_t datalen, RIL_Token t, RIL_SOCKET_ID socket_id); /** * This function should return the current radio state synchronously */ typedef RIL_RadioState (*RIL_RadioStateRequest)(RIL_SOCKET_ID socket_id); #else /* Backward compatible */ /** * RIL_Request Function pointer * * @param request is one of RIL_REQUEST_* * @param data is pointer to data defined for that RIL_REQUEST_* * data is owned by caller, and should not be modified or freed by callee * structures passed as data may contain pointers to non-contiguous memory * @param t should be used in subsequent call to RIL_onResponse * @param datalen is the length of "data" which is defined as other argument. It may or may * not be equal to sizeof(data). Refer to the documentation of individual structures * to find if pointers listed in the structure are contiguous and counted in the datalen * length or not. * (Eg: RIL_IMS_SMS_Message where we don't have datalen equal to sizeof(data)) * */ typedef void (*RIL_RequestFunc) (int request, void *data, size_t datalen, RIL_Token t); /** * This function should return the current radio state synchronously */ typedef RIL_RadioState (*RIL_RadioStateRequest)(); #endif /** * This function returns "1" if the specified RIL_REQUEST code is * supported and 0 if it is not * * @param requestCode is one of RIL_REQUEST codes */ typedef int (*RIL_Supports)(int requestCode); /** * This function is called from a separate thread--not the * thread that calls RIL_RequestFunc--and indicates that a pending * request should be cancelled. * * On cancel, the callee should do its best to abandon the request and * call RIL_onRequestComplete with RIL_Errno CANCELLED at some later point. * * Subsequent calls to RIL_onRequestComplete for this request with * other results will be tolerated but ignored. (That is, it is valid * to ignore the cancellation request) * * RIL_Cancel calls should return immediately, and not wait for cancellation * * Please see ITU v.250 5.6.1 for how one might implement this on a TS 27.007 * interface * * @param t token wants to be canceled */ typedef void (*RIL_Cancel)(RIL_Token t); typedef void (*RIL_TimedCallback) (void *param); /** * Return a version string for your RIL implementation */ typedef const char * (*RIL_GetVersion) (void); typedef struct { int version; /* set to RIL_VERSION */ RIL_RequestFunc onRequest; RIL_RadioStateRequest onStateRequest; RIL_Supports supports; RIL_Cancel onCancel; RIL_GetVersion getVersion; } RIL_RadioFunctions; typedef struct { char *apn; char *protocol; int authtype; char *username; char *password; } RIL_InitialAttachApn; typedef struct { int authContext; /* P2 value of authentication command, see P2 parameter in 3GPP TS 31.102 7.1.2 */ char *authData; /* the challenge string in Base64 format, see 3GPP TS 31.102 7.1.2 */ char *aid; /* AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. */ } RIL_SimAuthentication; typedef struct { int cid; /* Context ID, uniquely identifies this call */ char *bearer_proto; /* One of the PDP_type values in TS 27.007 section 10.1.1. For example, "IP", "IPV6", "IPV4V6" */ int pco_id; /* The protocol ID for this box. Note that only IDs from FF00H - FFFFH are accepted. If more than one is included from the network, multiple calls should be made to send all of them. */ int contents_length; /* The number of octets in the contents. */ char *contents; /* Carrier-defined content. It is binary, opaque and loosely defined in LTE Layer 3 spec 24.008 */ } RIL_PCO_Data; #ifdef RIL_SHLIB struct RIL_Env { /** * "t" is parameter passed in on previous call to RIL_Notification * routine. * * If "e" != SUCCESS, then response can be null/is ignored * * "response" is owned by caller, and should not be modified or * freed by callee * * RIL_onRequestComplete will return as soon as possible */ void (*OnRequestComplete)(RIL_Token t, RIL_Errno e, void *response, size_t responselen); #if defined(ANDROID_MULTI_SIM) /** * "unsolResponse" is one of RIL_UNSOL_RESPONSE_* * "data" is pointer to data defined for that RIL_UNSOL_RESPONSE_* * * "data" is owned by caller, and should not be modified or freed by callee */ void (*OnUnsolicitedResponse)(int unsolResponse, const void *data, size_t datalen, RIL_SOCKET_ID socket_id); #else /** * "unsolResponse" is one of RIL_UNSOL_RESPONSE_* * "data" is pointer to data defined for that RIL_UNSOL_RESPONSE_* * * "data" is owned by caller, and should not be modified or freed by callee */ void (*OnUnsolicitedResponse)(int unsolResponse, const void *data, size_t datalen); #endif /** * Call user-specifed "callback" function on on the same thread that * RIL_RequestFunc is called. If "relativeTime" is specified, then it specifies * a relative time value at which the callback is invoked. If relativeTime is * NULL or points to a 0-filled structure, the callback will be invoked as * soon as possible */ void (*RequestTimedCallback) (RIL_TimedCallback callback, void *param, const struct timeval *relativeTime); /** * "t" is parameter passed in on previous call RIL_Notification routine * * RIL_onRequestAck will be called by vendor when an Async RIL request was received * by them and an ack needs to be sent back to java ril. */ void (*OnRequestAck) (RIL_Token t); }; /** * RIL implementations must defined RIL_Init * argc and argv will be command line arguments intended for the RIL implementation * Return NULL on error * * @param env is environment point defined as RIL_Env * @param argc number of arguments * @param argv list fo arguments * */ const RIL_RadioFunctions *RIL_Init(const struct RIL_Env *env, int argc, char **argv); /** * If BT SAP(SIM Access Profile) is supported, then RIL implementations must define RIL_SAP_Init * for initializing RIL_RadioFunctions used for BT SAP communcations. It is called whenever RILD * starts or modem restarts. Returns handlers for SAP related request that are made on SAP * sepecific socket, analogous to the RIL_RadioFunctions returned by the call to RIL_Init * and used on the general RIL socket. * argc and argv will be command line arguments intended for the RIL implementation * Return NULL on error. * * @param env is environment point defined as RIL_Env * @param argc number of arguments * @param argv list fo arguments * */ const RIL_RadioFunctions *RIL_SAP_Init(const struct RIL_Env *env, int argc, char **argv); #else /* RIL_SHLIB */ /** * Call this once at startup to register notification routine * * @param callbacks user-specifed callback function */ void RIL_register (const RIL_RadioFunctions *callbacks); /** * * RIL_onRequestComplete will return as soon as possible * * @param t is parameter passed in on previous call to RIL_Notification * routine. * @param e error code * if "e" != SUCCESS, then response can be null/is ignored * @param response is owned by caller, and should not be modified or * freed by callee * @param responselen the length of response in byte */ void RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen); /** * RIL_onRequestAck will be called by vendor when an Async RIL request was received by them and * an ack needs to be sent back to java ril. This doesn't mark the end of the command or it's * results, just that the command was received and will take a while. After sending this Ack * its vendor's responsibility to make sure that AP is up whenever needed while command is * being processed. * * @param t is parameter passed in on previous call to RIL_Notification * routine. */ void RIL_onRequestAck(RIL_Token t); #if defined(ANDROID_MULTI_SIM) /** * @param unsolResponse is one of RIL_UNSOL_RESPONSE_* * @param data is pointer to data defined for that RIL_UNSOL_RESPONSE_* * "data" is owned by caller, and should not be modified or freed by callee * @param datalen the length of data in byte */ void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, size_t datalen, RIL_SOCKET_ID socket_id); #else /** * @param unsolResponse is one of RIL_UNSOL_RESPONSE_* * @param data is pointer to data defined for that RIL_UNSOL_RESPONSE_* * "data" is owned by caller, and should not be modified or freed by callee * @param datalen the length of data in byte */ void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, size_t datalen); #endif /** * Call user-specifed "callback" function on on the same thread that * RIL_RequestFunc is called. If "relativeTime" is specified, then it specifies * a relative time value at which the callback is invoked. If relativeTime is * NULL or points to a 0-filled structure, the callback will be invoked as * soon as possible * * @param callback user-specifed callback function * @param param parameter list * @param relativeTime a relative time value at which the callback is invoked */ void RIL_requestTimedCallback (RIL_TimedCallback callback, void *param, const struct timeval *relativeTime); #endif /* RIL_SHLIB */ #ifdef __cplusplus } #endif #endif /*ANDROID_RIL_H*/ ================================================ FILE: init/Android.mk ================================================ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_C_INCLUDES := system/core/init LOCAL_CFLAGS := -Wall LOCAL_SRC_FILES := init_oneplus2.cpp LOCAL_MODULE := libinit_oneplus2 include $(BUILD_STATIC_LIBRARY) ================================================ FILE: init/init_oneplus2.cpp ================================================ /* Copyright (c) 2016, The CyanogenMod Project Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "vendor_init.h" #include "property_service.h" #include "log.h" #include "util.h" void init_variant_properties() { std::string device = property_get("ro.cm.device"); std::string rf_version; if (device != "oneplus2") return; rf_version = property_get("ro.boot.rf_v1"); if (rf_version == "14") { /* Chinese */ property_set("ro.product.model", "ONE A2001"); property_set("ro.rf_version", "TDD_FDD_Ch_All"); property_set("telephony.lteOnCdmaDevice", "1"); property_set("ro.telephony.default_network", "20,20"); } else if (rf_version == "24") { /* Asia/Europe */ property_set("ro.product.model", "ONE A2003"); property_set("ro.rf_version", "TDD_FDD_Eu"); property_set("ro.telephony.default_network", "9,9"); } else if (rf_version == "34") { /* America */ property_set("ro.product.model", "ONE A2005"); property_set("ro.rf_version", "TDD_FDD_Am"); property_set("telephony.lteOnCdmaDevice", "1"); property_set("ro.telephony.default_network", "9,9"); } } void vendor_load_properties() { init_variant_properties(); } ================================================ FILE: keylayout/fpc1020.kl ================================================ # Copyright (c) 2012, 2014 The Linux Foundation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of The Linux Foundation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN # IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. key 102 HOME VIRTUAL key 116 POWER key 60 F2 ================================================ FILE: keylayout/synaptics.kl ================================================ # Copyright (c) 2012, 2014 The Linux Foundation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of The Linux Foundation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN # IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. key 158 APP_SWITCH VIRTUAL key 580 BACK VIRTUAL key 143 WAKEUP VIRTUAL ================================================ FILE: liblight/Android.mk ================================================ # Copyright (C) 2014 The CyanogenMod Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. LOCAL_PATH:= $(call my-dir) # HAL module implemenation stored in # hw/..so include $(CLEAR_VARS) LOCAL_SRC_FILES := lights.c LOCAL_MODULE_RELATIVE_PATH := hw LOCAL_SHARED_LIBRARIES := liblog libcutils LOCAL_MODULE := lights.msm8994 LOCAL_MODULE_TAGS := optional include $(BUILD_SHARED_LIBRARY) ================================================ FILE: liblight/NOTICE ================================================ Copyright (c) 2008, The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS ================================================ FILE: liblight/lights.c ================================================ /* * Copyright (C) 2008 The Android Open Source Project * Copyright (C) 2014 The Linux Foundation. All rights reserved. * Copyright (C) 2015 The CyanogenMod Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "lights" #include #include #include #include #include #include #include #include #include #include #include /******************************************************************************/ static pthread_once_t g_init = PTHREAD_ONCE_INIT; static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER; static struct light_state_t g_attention; static struct light_state_t g_notification; static struct light_state_t g_battery; char const*const RED_LED_FILE = "/sys/class/leds/red/brightness"; char const*const GREEN_LED_FILE = "/sys/class/leds/green/brightness"; char const*const BLUE_LED_FILE = "/sys/class/leds/blue/brightness"; char const*const LCD_FILE = "/sys/class/leds/lcd-backlight/brightness"; const char*const BUTTONS_FILE = "/sys/class/leds/button-backlight/brightness"; char const*const RED_DUTY_PCTS_FILE = "/sys/class/leds/red/duty_pcts"; char const*const GREEN_DUTY_PCTS_FILE = "/sys/class/leds/green/duty_pcts"; char const*const BLUE_DUTY_PCTS_FILE = "/sys/class/leds/blue/duty_pcts"; char const*const RED_START_IDX_FILE = "/sys/class/leds/red/start_idx"; char const*const GREEN_START_IDX_FILE = "/sys/class/leds/green/start_idx"; char const*const BLUE_START_IDX_FILE = "/sys/class/leds/blue/start_idx"; char const*const RED_PAUSE_LO_FILE = "/sys/class/leds/red/pause_lo"; char const*const GREEN_PAUSE_LO_FILE = "/sys/class/leds/green/pause_lo"; char const*const BLUE_PAUSE_LO_FILE = "/sys/class/leds/blue/pause_lo"; char const*const RED_PAUSE_HI_FILE = "/sys/class/leds/red/pause_hi"; char const*const GREEN_PAUSE_HI_FILE = "/sys/class/leds/green/pause_hi"; char const*const BLUE_PAUSE_HI_FILE = "/sys/class/leds/blue/pause_hi"; char const*const RED_RAMP_STEP_MS_FILE = "/sys/class/leds/red/ramp_step_ms"; char const*const GREEN_RAMP_STEP_MS_FILE = "/sys/class/leds/green/ramp_step_ms"; char const*const BLUE_RAMP_STEP_MS_FILE = "/sys/class/leds/blue/ramp_step_ms"; char const*const RED_BLINK_FILE = "/sys/class/leds/red/blink"; char const*const GREEN_BLINK_FILE = "/sys/class/leds/green/blink"; char const*const BLUE_BLINK_FILE = "/sys/class/leds/blue/blink"; #define RAMP_SIZE 8 static int BRIGHTNESS_RAMP[RAMP_SIZE] = { 0, 12, 25, 37, 50, 72, 85, 100 }; #define RAMP_STEP_DURATION 50 /** * device methods */ void init_globals(void) { // init the mutex pthread_mutex_init(&g_lock, NULL); } static int write_int(char const* path, int value) { int fd; static int already_warned = 0; fd = open(path, O_RDWR); if (fd >= 0) { char buffer[20]; int bytes = snprintf(buffer, sizeof(buffer), "%d\n", value); ssize_t amt = write(fd, buffer, (size_t)bytes); close(fd); return amt == -1 ? -errno : 0; } else { if (already_warned == 0) { ALOGE("write_int failed to open %s\n", path); already_warned = 1; } return -errno; } } static int write_str(char const* path, char* value) { int fd; static int already_warned = 0; fd = open(path, O_RDWR); if (fd >= 0) { char buffer[1024]; int bytes = snprintf(buffer, sizeof(buffer), "%s\n", value); ssize_t amt = write(fd, buffer, (size_t)bytes); close(fd); return amt == -1 ? -errno : 0; } else { if (already_warned == 0) { ALOGE("write_int failed to open %s\n", path); already_warned = 1; } return -errno; } } static int is_lit(struct light_state_t const* state) { return state->color & 0x00ffffff; } static int rgb_to_brightness(struct light_state_t const* state) { int color = state->color & 0x00ffffff; return ((77*((color>>16)&0x00ff)) + (150*((color>>8)&0x00ff)) + (29*(color&0x00ff))) >> 8; } static int set_light_backlight(struct light_device_t* dev, struct light_state_t const* state) { int err = 0; int brightness = rgb_to_brightness(state); if(!dev) { return -1; } pthread_mutex_lock(&g_lock); err = write_int(LCD_FILE, brightness); pthread_mutex_unlock(&g_lock); return err; } static int set_light_buttons(struct light_device_t *dev, const struct light_state_t *state) { int err = 0; int brightness = rgb_to_brightness(state); if(!dev) { return -1; } pthread_mutex_lock(&g_lock); err = write_int(BUTTONS_FILE, brightness); pthread_mutex_unlock(&g_lock); return err; } static char* get_scaled_duty_pcts(int brightness) { char *buf = malloc(5 * RAMP_SIZE * sizeof(char)); char *pad = ""; int i = 0; memset(buf, 0, 5 * RAMP_SIZE * sizeof(char)); for (i = 0; i < RAMP_SIZE; i++) { char temp[5] = ""; snprintf(temp, sizeof(temp), "%s%d", pad, (BRIGHTNESS_RAMP[i] * brightness / 255)); strcat(buf, temp); pad = ","; } ALOGV("%s: brightness=%d duty=%s", __func__, brightness, buf); return buf; } static int set_speaker_light_locked(struct light_device_t* dev, struct light_state_t const* state) { int red, green, blue, blink; int onMS, offMS, stepDuration, pauseHi; unsigned int colorRGB; char *duty; if(!dev) { return -1; } switch (state->flashMode) { case LIGHT_FLASH_TIMED: onMS = state->flashOnMS; offMS = state->flashOffMS; break; case LIGHT_FLASH_NONE: default: onMS = 0; offMS = 0; break; } colorRGB = state->color; ALOGV("set_speaker_light_locked mode %d, colorRGB=%08X, onMS=%d, offMS=%d\n", state->flashMode, colorRGB, onMS, offMS); red = (colorRGB >> 16) & 0xFF; green = (colorRGB >> 8) & 0xFF; blue = colorRGB & 0xFF; // bias for true white if (colorRGB != 0 && red == green && green == blue) { blue = (blue * 171) / 256; } blink = onMS > 0 && offMS > 0; // disable all blinking to start write_int(RED_BLINK_FILE, 0); write_int(GREEN_BLINK_FILE, 0); write_int(BLUE_BLINK_FILE, 0); if (blink) { stepDuration = RAMP_STEP_DURATION; pauseHi = onMS - (stepDuration * RAMP_SIZE * 2); if (stepDuration * RAMP_SIZE * 2 > onMS) { stepDuration = onMS / (RAMP_SIZE * 2); pauseHi = 0; } // red write_int(RED_START_IDX_FILE, 0); duty = get_scaled_duty_pcts(red); write_str(RED_DUTY_PCTS_FILE, duty); write_int(RED_PAUSE_LO_FILE, offMS); // The led driver is configured to ramp up then ramp // down the lut. This effectively doubles the ramp duration. write_int(RED_PAUSE_HI_FILE, pauseHi); write_int(RED_RAMP_STEP_MS_FILE, stepDuration); free(duty); // green write_int(GREEN_START_IDX_FILE, RAMP_SIZE); duty = get_scaled_duty_pcts(green); write_str(GREEN_DUTY_PCTS_FILE, duty); write_int(GREEN_PAUSE_LO_FILE, offMS); // The led driver is configured to ramp up then ramp // down the lut. This effectively doubles the ramp duration. write_int(GREEN_PAUSE_HI_FILE, pauseHi); write_int(GREEN_RAMP_STEP_MS_FILE, stepDuration); free(duty); // blue write_int(BLUE_START_IDX_FILE, RAMP_SIZE * 2); duty = get_scaled_duty_pcts(blue); write_str(BLUE_DUTY_PCTS_FILE, duty); write_int(BLUE_PAUSE_LO_FILE, offMS); // The led driver is configured to ramp up then ramp // down the lut. This effectively doubles the ramp duration. write_int(BLUE_PAUSE_HI_FILE, pauseHi); write_int(BLUE_RAMP_STEP_MS_FILE, stepDuration); free(duty); // start the party write_int(RED_BLINK_FILE, red); write_int(GREEN_BLINK_FILE, green); write_int(BLUE_BLINK_FILE, blue); } else { write_int(RED_LED_FILE, red); write_int(GREEN_LED_FILE, green); write_int(BLUE_LED_FILE, blue); } return 0; } static void handle_speaker_light_locked(struct light_device_t* dev) { if (is_lit(&g_attention)) { set_speaker_light_locked(dev, &g_attention); } else if (is_lit(&g_notification)) { set_speaker_light_locked(dev, &g_notification); } else { set_speaker_light_locked(dev, &g_battery); } } static int set_light_battery(struct light_device_t* dev, struct light_state_t const* state) { pthread_mutex_lock(&g_lock); g_battery = *state; handle_speaker_light_locked(dev); pthread_mutex_unlock(&g_lock); return 0; } static int set_light_notifications(struct light_device_t* dev, struct light_state_t const* state) { pthread_mutex_lock(&g_lock); unsigned int brightness; unsigned int color; unsigned int rgb[3]; g_notification = *state; // If a brightness has been applied by the user brightness = (g_notification.color & 0xFF000000) >> 24; if (brightness > 0 && brightness < 0xFF) { // Retrieve each of the RGB colors color = g_notification.color & 0x00FFFFFF; rgb[0] = (color >> 16) & 0xFF; rgb[1] = (color >> 8) & 0xFF; rgb[2] = color & 0xFF; // Apply the brightness level if (rgb[0] > 0) rgb[0] = (rgb[0] * brightness) / 0xFF; if (rgb[1] > 0) rgb[1] = (rgb[1] * brightness) / 0xFF; if (rgb[2] > 0) rgb[2] = (rgb[2] * brightness) / 0xFF; // Update with the new color g_notification.color = (rgb[0] << 16) + (rgb[1] << 8) + rgb[2]; } handle_speaker_light_locked(dev); pthread_mutex_unlock(&g_lock); return 0; } static int set_light_attention(struct light_device_t* dev, struct light_state_t const* state) { pthread_mutex_lock(&g_lock); g_attention = *state; handle_speaker_light_locked(dev); pthread_mutex_unlock(&g_lock); return 0; } /** Close the lights device */ static int close_lights(struct light_device_t *dev) { if (dev) { free(dev); } return 0; } /******************************************************************************/ /** * module methods */ /** Open a new instance of a lights device using name */ static int open_lights(const struct hw_module_t* module, char const* name, struct hw_device_t** device) { int (*set_light)(struct light_device_t* dev, struct light_state_t const* state); if (0 == strcmp(LIGHT_ID_BACKLIGHT, name)) set_light = set_light_backlight; else if (0 == strcmp(LIGHT_ID_BUTTONS, name)) set_light = set_light_buttons; else if (0 == strcmp(LIGHT_ID_BATTERY, name)) set_light = set_light_battery; else if (0 == strcmp(LIGHT_ID_NOTIFICATIONS, name)) set_light = set_light_notifications; else if (0 == strcmp(LIGHT_ID_ATTENTION, name)) set_light = set_light_attention; else return -EINVAL; pthread_once(&g_init, init_globals); struct light_device_t *dev = malloc(sizeof(struct light_device_t)); if(!dev) return -ENOMEM; memset(dev, 0, sizeof(*dev)); dev->common.tag = HARDWARE_DEVICE_TAG; dev->common.version = 0; dev->common.module = (struct hw_module_t*)module; dev->common.close = (int (*)(struct hw_device_t*))close_lights; dev->set_light = set_light; *device = (struct hw_device_t*)dev; return 0; } static struct hw_module_methods_t lights_module_methods = { .open = open_lights, }; /* * The lights Module */ struct hw_module_t HAL_MODULE_INFO_SYM = { .tag = HARDWARE_MODULE_TAG, .version_major = 1, .version_minor = 0, .id = LIGHTS_HARDWARE_MODULE_ID, .name = "Lights Module", .author = "The CyanogenMod Project", .methods = &lights_module_methods, }; ================================================ FILE: libshims/Android.mk ================================================ # Copyright 2010 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. CAMERA_CLIENT_LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_PATH := $(CAMERA_CLIENT_LOCAL_PATH) LOCAL_SRC_FILES:= \ Camera.cpp \ CameraMetadata.cpp \ CaptureResult.cpp \ CameraParameters2.cpp \ ICamera.cpp \ ICameraClient.cpp \ ICameraService.cpp \ ICameraServiceListener.cpp \ ICameraServiceProxy.cpp \ ICameraRecordingProxy.cpp \ ICameraRecordingProxyListener.cpp \ camera2/ICameraDeviceUser.cpp \ camera2/ICameraDeviceCallbacks.cpp \ camera2/CaptureRequest.cpp \ camera2/OutputConfiguration.cpp \ CameraBase.cpp \ CameraUtils.cpp \ VendorTagDescriptor.cpp \ CameraParameters.cpp LOCAL_SHARED_LIBRARIES := \ libcutils \ libutils \ liblog \ libbinder \ libhardware \ libui \ libgui \ libcamera_metadata LOCAL_C_INCLUDES += \ $(LOCAL_PATH)/include \ system/media/camera/include \ system/media/private/camera/include LOCAL_MODULE:= libshim_ims-camera include $(BUILD_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_SRC_FILES := camera.cpp LOCAL_MODULE := libshim_camera LOCAL_MODULE_TAGS := optional LOCAL_MODULE_CLASS := SHARED_LIBRARIES LOCAL_32_BIT_ONLY := true LOCAL_SHARED_LIBRARIES := libgui libui include $(BUILD_SHARED_LIBRARY) ================================================ FILE: libshims/Camera.cpp ================================================ /* ** ** Copyright (C) 2008, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ //#define LOG_NDEBUG 0 #define LOG_TAG "Camera" #include #include #include #include #include #include #include #include #include #include #include #include namespace android { Camera::Camera(int cameraId) : CameraBase(cameraId) { } CameraTraits::TCamConnectService CameraTraits::fnConnectService = &ICameraService::connect; // construct a camera client from an existing camera remote sp Camera::create(const sp& camera) { ALOGV("create"); if (camera == 0) { ALOGE("camera remote is a NULL pointer"); return 0; } sp c = new Camera(-1); if (camera->connect(c) == NO_ERROR) { c->mStatus = NO_ERROR; c->mCamera = camera; IInterface::asBinder(camera)->linkToDeath(c); return c; } return 0; } Camera::~Camera() { // We don't need to call disconnect() here because if the CameraService // thinks we are the owner of the hardware, it will hold a (strong) // reference to us, and we can't possibly be here. We also don't want to // call disconnect() here if we are in the same process as mediaserver, // because we may be invoked by CameraService::Client::connect() and will // deadlock if we call any method of ICamera here. } sp Camera::connect(int cameraId, const String16& clientPackageName, int clientUid) { return CameraBaseT::connect(cameraId, clientPackageName, clientUid); } status_t Camera::connectLegacy(int cameraId, int halVersion, const String16& clientPackageName, int clientUid, sp& camera) { ALOGV("%s: connect legacy camera device", __FUNCTION__); sp c = new Camera(cameraId); sp cl = c; status_t status = NO_ERROR; const sp& cs = CameraBaseT::getCameraService(); if (cs != 0) { status = cs.get()->connectLegacy(cl, cameraId, halVersion, clientPackageName, clientUid, /*out*/c->mCamera); } if (status == OK && c->mCamera != 0) { IInterface::asBinder(c->mCamera)->linkToDeath(c); c->mStatus = NO_ERROR; camera = c; } else { ALOGW("An error occurred while connecting to camera %d: %d (%s)", cameraId, status, strerror(-status)); c.clear(); } return status; } status_t Camera::reconnect() { ALOGV("reconnect"); sp c = mCamera; if (c == 0) return NO_INIT; return c->connect(this); } status_t Camera::lock() { sp c = mCamera; if (c == 0) return NO_INIT; return c->lock(); } status_t Camera::unlock() { sp c = mCamera; if (c == 0) return NO_INIT; return c->unlock(); } // pass the buffered IGraphicBufferProducer to the camera service status_t Camera::setPreviewTarget(const sp& bufferProducer) { ALOGV("setPreviewTarget(%p)", bufferProducer.get()); sp c = mCamera; if (c == 0) return NO_INIT; ALOGD_IF(bufferProducer == 0, "app passed NULL surface"); return c->setPreviewTarget(bufferProducer); } // start preview mode status_t Camera::startPreview() { ALOGV("startPreview"); sp c = mCamera; if (c == 0) return NO_INIT; return c->startPreview(); } status_t Camera::storeMetaDataInBuffers(bool enabled) { ALOGV("storeMetaDataInBuffers: %s", enabled? "true": "false"); sp c = mCamera; if (c == 0) return NO_INIT; return c->storeMetaDataInBuffers(enabled); } // start recording mode, must call setPreviewTarget first status_t Camera::startRecording() { ALOGV("startRecording"); sp c = mCamera; if (c == 0) return NO_INIT; return c->startRecording(); } // stop preview mode void Camera::stopPreview() { ALOGV("stopPreview"); sp c = mCamera; if (c == 0) return; c->stopPreview(); } // stop recording mode void Camera::stopRecording() { ALOGV("stopRecording"); { Mutex::Autolock _l(mLock); mRecordingProxyListener.clear(); } sp c = mCamera; if (c == 0) return; c->stopRecording(); } // release a recording frame void Camera::releaseRecordingFrame(const sp& mem) { ALOGV("releaseRecordingFrame"); sp c = mCamera; if (c == 0) return; c->releaseRecordingFrame(mem); } // get preview state bool Camera::previewEnabled() { ALOGV("previewEnabled"); sp c = mCamera; if (c == 0) return false; return c->previewEnabled(); } // get recording state bool Camera::recordingEnabled() { ALOGV("recordingEnabled"); sp c = mCamera; if (c == 0) return false; return c->recordingEnabled(); } status_t Camera::autoFocus() { ALOGV("autoFocus"); sp c = mCamera; if (c == 0) return NO_INIT; return c->autoFocus(); } status_t Camera::cancelAutoFocus() { ALOGV("cancelAutoFocus"); sp c = mCamera; if (c == 0) return NO_INIT; return c->cancelAutoFocus(); } // take a picture status_t Camera::takePicture(int msgType) { ALOGV("takePicture: 0x%x", msgType); sp c = mCamera; if (c == 0) return NO_INIT; return c->takePicture(msgType); } // set preview/capture parameters - key/value pairs status_t Camera::setParameters(const String8& params) { ALOGV("setParameters"); sp c = mCamera; if (c == 0) return NO_INIT; return c->setParameters(params); } // get preview/capture parameters - key/value pairs String8 Camera::getParameters() const { ALOGV("getParameters"); String8 params; sp c = mCamera; if (c != 0) params = mCamera->getParameters(); return params; } // send command to camera driver status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) { ALOGV("sendCommand"); sp c = mCamera; if (c == 0) return NO_INIT; return c->sendCommand(cmd, arg1, arg2); } void Camera::setListener(const sp& listener) { Mutex::Autolock _l(mLock); mListener = listener; } void Camera::setRecordingProxyListener(const sp& listener) { Mutex::Autolock _l(mLock); mRecordingProxyListener = listener; } void Camera::setPreviewCallbackFlags(int flag) { ALOGV("setPreviewCallbackFlags"); sp c = mCamera; if (c == 0) return; mCamera->setPreviewCallbackFlag(flag); } status_t Camera::setPreviewCallbackTarget( const sp& callbackProducer) { sp c = mCamera; if (c == 0) return NO_INIT; return c->setPreviewCallbackTarget(callbackProducer); } // callback from camera service void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) { return CameraBaseT::notifyCallback(msgType, ext1, ext2); } // callback from camera service when frame or image is ready void Camera::dataCallback(int32_t msgType, const sp& dataPtr, camera_frame_metadata_t *metadata) { sp listener; { Mutex::Autolock _l(mLock); listener = mListener; } if (listener != NULL) { listener->postData(msgType, dataPtr, metadata); } } // callback from camera service when timestamped frame is ready void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp& dataPtr) { // If recording proxy listener is registered, forward the frame and return. // The other listener (mListener) is ignored because the receiver needs to // call releaseRecordingFrame. sp proxylistener; { Mutex::Autolock _l(mLock); proxylistener = mRecordingProxyListener; } if (proxylistener != NULL) { proxylistener->dataCallbackTimestamp(timestamp, msgType, dataPtr); return; } sp listener; { Mutex::Autolock _l(mLock); listener = mListener; } if (listener != NULL) { listener->postDataTimestamp(timestamp, msgType, dataPtr); } else { ALOGW("No listener was set. Drop a recording frame."); releaseRecordingFrame(dataPtr); } } sp Camera::getRecordingProxy() { ALOGV("getProxy"); return new RecordingProxy(this); } status_t Camera::RecordingProxy::startRecording(const sp& listener) { ALOGV("RecordingProxy::startRecording"); mCamera->setRecordingProxyListener(listener); mCamera->reconnect(); return mCamera->startRecording(); } void Camera::RecordingProxy::stopRecording() { ALOGV("RecordingProxy::stopRecording"); mCamera->stopRecording(); } void Camera::RecordingProxy::releaseRecordingFrame(const sp& mem) { ALOGV("RecordingProxy::releaseRecordingFrame"); mCamera->releaseRecordingFrame(mem); } Camera::RecordingProxy::RecordingProxy(const sp& camera) { mCamera = camera; } }; // namespace android ================================================ FILE: libshims/CameraBase.cpp ================================================ /* ** ** Copyright (C) 2013, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ //#define LOG_NDEBUG 0 #define LOG_TAG "CameraBase" #include #include #include #include #include #include #include #include // needed to instantiate #include #include namespace android { namespace { sp gCameraService; const int kCameraServicePollDelay = 500000; // 0.5s const char* kCameraServiceName = "media.camera"; Mutex gLock; class DeathNotifier : public IBinder::DeathRecipient { public: DeathNotifier() { } virtual void binderDied(const wp& /*who*/) { ALOGV("binderDied"); Mutex::Autolock _l(gLock); gCameraService.clear(); ALOGW("Camera service died!"); } }; sp gDeathNotifier; }; // namespace anonymous /////////////////////////////////////////////////////////// // CameraBase definition /////////////////////////////////////////////////////////// // establish binder interface to camera service template const sp& CameraBase::getCameraService() { Mutex::Autolock _l(gLock); if (gCameraService.get() == 0) { sp sm = defaultServiceManager(); sp binder; do { binder = sm->getService(String16(kCameraServiceName)); if (binder != 0) { break; } ALOGW("CameraService not published, waiting..."); usleep(kCameraServicePollDelay); } while(true); if (gDeathNotifier == NULL) { gDeathNotifier = new DeathNotifier(); } binder->linkToDeath(gDeathNotifier); gCameraService = interface_cast(binder); } ALOGE_IF(gCameraService == 0, "no CameraService!?"); return gCameraService; } template sp CameraBase::connect(int cameraId, const String16& clientPackageName, int clientUid) { ALOGV("%s: connect", __FUNCTION__); sp c = new TCam(cameraId); sp cl = c; status_t status = NO_ERROR; const sp& cs = getCameraService(); if (cs != 0) { TCamConnectService fnConnectService = TCamTraits::fnConnectService; status = (cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid, /*out*/ c->mCamera); } if (status == OK && c->mCamera != 0) { IInterface::asBinder(c->mCamera)->linkToDeath(c); c->mStatus = NO_ERROR; } else { ALOGW("An error occurred while connecting to camera: %d", cameraId); c.clear(); } return c; } template void CameraBase::disconnect() { ALOGV("%s: disconnect", __FUNCTION__); if (mCamera != 0) { mCamera->disconnect(); IInterface::asBinder(mCamera)->unlinkToDeath(this); mCamera = 0; } ALOGV("%s: disconnect (done)", __FUNCTION__); } template CameraBase::CameraBase(int cameraId) : mStatus(UNKNOWN_ERROR), mCameraId(cameraId) { } template CameraBase::~CameraBase() { } template sp CameraBase::remote() { return mCamera; } template status_t CameraBase::getStatus() { return mStatus; } template void CameraBase::binderDied(const wp& /*who*/) { ALOGW("mediaserver's remote binder Camera object died"); notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, /*ext2*/0); } template void CameraBase::setListener(const sp& listener) { Mutex::Autolock _l(mLock); mListener = listener; } // callback from camera service template void CameraBase::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) { sp listener; { Mutex::Autolock _l(mLock); listener = mListener; } if (listener != NULL) { listener->notify(msgType, ext1, ext2); } } template int CameraBase::getNumberOfCameras() { const sp cs = getCameraService(); if (!cs.get()) { // as required by the public Java APIs return 0; } return cs->getNumberOfCameras(); } // this can be in BaseCamera but it should be an instance method template status_t CameraBase::getCameraInfo(int cameraId, struct CameraInfo* cameraInfo) { const sp& cs = getCameraService(); if (cs == 0) return UNKNOWN_ERROR; return cs->getCameraInfo(cameraId, cameraInfo); } template status_t CameraBase::addServiceListener( const sp& listener) { const sp& cs = getCameraService(); if (cs == 0) return UNKNOWN_ERROR; return cs->addListener(listener); } template status_t CameraBase::removeServiceListener( const sp& listener) { const sp& cs = getCameraService(); if (cs == 0) return UNKNOWN_ERROR; return cs->removeListener(listener); } template class CameraBase; } // namespace android ================================================ FILE: libshims/CameraMetadata.cpp ================================================ /* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // #define LOG_NDEBUG 0 #define LOG_TAG "Camera2-Metadata" #include #include #include #include namespace android { #define ALIGN_TO(val, alignment) \ (((uintptr_t)(val) + ((alignment) - 1)) & ~((alignment) - 1)) typedef Parcel::WritableBlob WritableBlob; typedef Parcel::ReadableBlob ReadableBlob; CameraMetadata::CameraMetadata() : mBuffer(NULL), mLocked(false) { } CameraMetadata::CameraMetadata(size_t entryCapacity, size_t dataCapacity) : mLocked(false) { mBuffer = allocate_camera_metadata(entryCapacity, dataCapacity); } CameraMetadata::CameraMetadata(const CameraMetadata &other) : mLocked(false) { mBuffer = clone_camera_metadata(other.mBuffer); } CameraMetadata::CameraMetadata(camera_metadata_t *buffer) : mBuffer(NULL), mLocked(false) { acquire(buffer); } CameraMetadata &CameraMetadata::operator=(const CameraMetadata &other) { return operator=(other.mBuffer); } CameraMetadata &CameraMetadata::operator=(const camera_metadata_t *buffer) { if (mLocked) { ALOGE("%s: Assignment to a locked CameraMetadata!", __FUNCTION__); return *this; } if (CC_LIKELY(buffer != mBuffer)) { camera_metadata_t *newBuffer = clone_camera_metadata(buffer); clear(); mBuffer = newBuffer; } return *this; } CameraMetadata::~CameraMetadata() { mLocked = false; clear(); } const camera_metadata_t* CameraMetadata::getAndLock() const { mLocked = true; return mBuffer; } status_t CameraMetadata::unlock(const camera_metadata_t *buffer) { if (!mLocked) { ALOGE("%s: Can't unlock a non-locked CameraMetadata!", __FUNCTION__); return INVALID_OPERATION; } if (buffer != mBuffer) { ALOGE("%s: Can't unlock CameraMetadata with wrong pointer!", __FUNCTION__); return BAD_VALUE; } mLocked = false; return OK; } camera_metadata_t* CameraMetadata::release() { if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return NULL; } camera_metadata_t *released = mBuffer; mBuffer = NULL; return released; } void CameraMetadata::clear() { if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return; } if (mBuffer) { free_camera_metadata(mBuffer); mBuffer = NULL; } } void CameraMetadata::acquire(camera_metadata_t *buffer) { if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return; } clear(); mBuffer = buffer; ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/NULL) != OK, "%s: Failed to validate metadata structure %p", __FUNCTION__, buffer); } void CameraMetadata::acquire(CameraMetadata &other) { if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return; } acquire(other.release()); } status_t CameraMetadata::append(const CameraMetadata &other) { return append(other.mBuffer); } status_t CameraMetadata::append(const camera_metadata_t* other) { if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } size_t extraEntries = get_camera_metadata_entry_count(other); size_t extraData = get_camera_metadata_data_count(other); resizeIfNeeded(extraEntries, extraData); return append_camera_metadata(mBuffer, other); } size_t CameraMetadata::entryCount() const { return (mBuffer == NULL) ? 0 : get_camera_metadata_entry_count(mBuffer); } bool CameraMetadata::isEmpty() const { return entryCount() == 0; } status_t CameraMetadata::sort() { if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } return sort_camera_metadata(mBuffer); } status_t CameraMetadata::checkType(uint32_t tag, uint8_t expectedType) { int tagType = get_camera_metadata_tag_type(tag); if ( CC_UNLIKELY(tagType == -1)) { ALOGE("Update metadata entry: Unknown tag %d", tag); return INVALID_OPERATION; } if ( CC_UNLIKELY(tagType != expectedType) ) { ALOGE("Mismatched tag type when updating entry %s (%d) of type %s; " "got type %s data instead ", get_camera_metadata_tag_name(tag), tag, camera_metadata_type_names[tagType], camera_metadata_type_names[expectedType]); return INVALID_OPERATION; } return OK; } status_t CameraMetadata::update(uint32_t tag, const int32_t *data, size_t data_count) { status_t res; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } if ( (res = checkType(tag, TYPE_INT32)) != OK) { return res; } return updateImpl(tag, (const void*)data, data_count); } status_t CameraMetadata::update(uint32_t tag, const uint8_t *data, size_t data_count) { status_t res; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } if ( (res = checkType(tag, TYPE_BYTE)) != OK) { return res; } return updateImpl(tag, (const void*)data, data_count); } status_t CameraMetadata::update(uint32_t tag, const float *data, size_t data_count) { status_t res; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } if ( (res = checkType(tag, TYPE_FLOAT)) != OK) { return res; } return updateImpl(tag, (const void*)data, data_count); } status_t CameraMetadata::update(uint32_t tag, const int64_t *data, size_t data_count) { status_t res; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } if ( (res = checkType(tag, TYPE_INT64)) != OK) { return res; } return updateImpl(tag, (const void*)data, data_count); } status_t CameraMetadata::update(uint32_t tag, const double *data, size_t data_count) { status_t res; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } if ( (res = checkType(tag, TYPE_DOUBLE)) != OK) { return res; } return updateImpl(tag, (const void*)data, data_count); } status_t CameraMetadata::update(uint32_t tag, const camera_metadata_rational_t *data, size_t data_count) { status_t res; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } if ( (res = checkType(tag, TYPE_RATIONAL)) != OK) { return res; } return updateImpl(tag, (const void*)data, data_count); } status_t CameraMetadata::update(uint32_t tag, const String8 &string) { status_t res; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } if ( (res = checkType(tag, TYPE_BYTE)) != OK) { return res; } // string.size() doesn't count the null termination character. return updateImpl(tag, (const void*)string.string(), string.size() + 1); } status_t CameraMetadata::updateImpl(uint32_t tag, const void *data, size_t data_count) { status_t res; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } int type = get_camera_metadata_tag_type(tag); if (type == -1) { ALOGE("%s: Tag %d not found", __FUNCTION__, tag); return BAD_VALUE; } // Safety check - ensure that data isn't pointing to this metadata, since // that would get invalidated if a resize is needed size_t bufferSize = get_camera_metadata_size(mBuffer); uintptr_t bufAddr = reinterpret_cast(mBuffer); uintptr_t dataAddr = reinterpret_cast(data); if (dataAddr > bufAddr && dataAddr < (bufAddr + bufferSize)) { ALOGE("%s: Update attempted with data from the same metadata buffer!", __FUNCTION__); return INVALID_OPERATION; } size_t data_size = calculate_camera_metadata_entry_data_size(type, data_count); res = resizeIfNeeded(1, data_size); if (res == OK) { camera_metadata_entry_t entry; res = find_camera_metadata_entry(mBuffer, tag, &entry); if (res == NAME_NOT_FOUND) { res = add_camera_metadata_entry(mBuffer, tag, data, data_count); } else if (res == OK) { res = update_camera_metadata_entry(mBuffer, entry.index, data, data_count, NULL); } } if (res != OK) { ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)", __FUNCTION__, get_camera_metadata_section_name(tag), get_camera_metadata_tag_name(tag), tag, strerror(-res), res); } IF_ALOGV() { ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/NULL) != OK, "%s: Failed to validate metadata structure after update %p", __FUNCTION__, mBuffer); } return res; } bool CameraMetadata::exists(uint32_t tag) const { camera_metadata_ro_entry entry; return find_camera_metadata_ro_entry(mBuffer, tag, &entry) == 0; } camera_metadata_entry_t CameraMetadata::find(uint32_t tag) { status_t res; camera_metadata_entry entry; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); entry.count = 0; return entry; } res = find_camera_metadata_entry(mBuffer, tag, &entry); if (CC_UNLIKELY( res != OK )) { entry.count = 0; entry.data.u8 = NULL; } return entry; } camera_metadata_ro_entry_t CameraMetadata::find(uint32_t tag) const { status_t res; camera_metadata_ro_entry entry; res = find_camera_metadata_ro_entry(mBuffer, tag, &entry); if (CC_UNLIKELY( res != OK )) { entry.count = 0; entry.data.u8 = NULL; } return entry; } status_t CameraMetadata::erase(uint32_t tag) { camera_metadata_entry_t entry; status_t res; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } res = find_camera_metadata_entry(mBuffer, tag, &entry); if (res == NAME_NOT_FOUND) { return OK; } else if (res != OK) { ALOGE("%s: Error looking for entry %s.%s (%x): %s %d", __FUNCTION__, get_camera_metadata_section_name(tag), get_camera_metadata_tag_name(tag), tag, strerror(-res), res); return res; } res = delete_camera_metadata_entry(mBuffer, entry.index); if (res != OK) { ALOGE("%s: Error deleting entry %s.%s (%x): %s %d", __FUNCTION__, get_camera_metadata_section_name(tag), get_camera_metadata_tag_name(tag), tag, strerror(-res), res); } return res; } void CameraMetadata::dump(int fd, int verbosity, int indentation) const { dump_indented_camera_metadata(mBuffer, fd, verbosity, indentation); } status_t CameraMetadata::resizeIfNeeded(size_t extraEntries, size_t extraData) { if (mBuffer == NULL) { mBuffer = allocate_camera_metadata(extraEntries * 2, extraData * 2); if (mBuffer == NULL) { ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__); return NO_MEMORY; } } else { size_t currentEntryCount = get_camera_metadata_entry_count(mBuffer); size_t currentEntryCap = get_camera_metadata_entry_capacity(mBuffer); size_t newEntryCount = currentEntryCount + extraEntries; newEntryCount = (newEntryCount > currentEntryCap) ? newEntryCount * 2 : currentEntryCap; size_t currentDataCount = get_camera_metadata_data_count(mBuffer); size_t currentDataCap = get_camera_metadata_data_capacity(mBuffer); size_t newDataCount = currentDataCount + extraData; newDataCount = (newDataCount > currentDataCap) ? newDataCount * 2 : currentDataCap; if (newEntryCount > currentEntryCap || newDataCount > currentDataCap) { camera_metadata_t *oldBuffer = mBuffer; mBuffer = allocate_camera_metadata(newEntryCount, newDataCount); if (mBuffer == NULL) { ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__); return NO_MEMORY; } append_camera_metadata(mBuffer, oldBuffer); free_camera_metadata(oldBuffer); } } return OK; } status_t CameraMetadata::readFromParcel(const Parcel& data, camera_metadata_t** out) { status_t err = OK; camera_metadata_t* metadata = NULL; if (out) { *out = NULL; } // See CameraMetadata::writeToParcel for parcel data layout diagram and explanation. // arg0 = blobSize (int32) int32_t blobSizeTmp = -1; if ((err = data.readInt32(&blobSizeTmp)) != OK) { ALOGE("%s: Failed to read metadata size (error %d %s)", __FUNCTION__, err, strerror(-err)); return err; } const size_t blobSize = static_cast(blobSizeTmp); const size_t alignment = get_camera_metadata_alignment(); // Special case: zero blob size means zero sized (NULL) metadata. if (blobSize == 0) { ALOGV("%s: Read 0-sized metadata", __FUNCTION__); return OK; } if (blobSize <= alignment) { ALOGE("%s: metadata blob is malformed, blobSize(%zu) should be larger than alignment(%zu)", __FUNCTION__, blobSize, alignment); return BAD_VALUE; } const size_t metadataSize = blobSize - alignment; // NOTE: this doesn't make sense to me. shouldn't the blob // know how big it is? why do we have to specify the size // to Parcel::readBlob ? ReadableBlob blob; // arg1 = metadata (blob) do { if ((err = data.readBlob(blobSize, &blob)) != OK) { ALOGE("%s: Failed to read metadata blob (sized %zu). Possible " " serialization bug. Error %d %s", __FUNCTION__, blobSize, err, strerror(-err)); break; } // arg2 = offset (blob) // Must be after blob since we don't know offset until after writeBlob. int32_t offsetTmp; if ((err = data.readInt32(&offsetTmp)) != OK) { ALOGE("%s: Failed to read metadata offsetTmp (error %d %s)", __FUNCTION__, err, strerror(-err)); break; } const size_t offset = static_cast(offsetTmp); if (offset >= alignment) { ALOGE("%s: metadata offset(%zu) should be less than alignment(%zu)", __FUNCTION__, blobSize, alignment); err = BAD_VALUE; break; } const uintptr_t metadataStart = reinterpret_cast(blob.data()) + offset; const camera_metadata_t* tmp = reinterpret_cast(metadataStart); ALOGV("%s: alignment is: %zu, metadata start: %p, offset: %zu", __FUNCTION__, alignment, tmp, offset); metadata = allocate_copy_camera_metadata_checked(tmp, metadataSize); if (metadata == NULL) { // We consider that allocation only fails if the validation // also failed, therefore the readFromParcel was a failure. ALOGE("%s: metadata allocation and copy failed", __FUNCTION__); err = BAD_VALUE; } } while(0); blob.release(); if (out) { ALOGV("%s: Set out metadata to %p", __FUNCTION__, metadata); *out = metadata; } else if (metadata != NULL) { ALOGV("%s: Freed camera metadata at %p", __FUNCTION__, metadata); free_camera_metadata(metadata); } return err; } status_t CameraMetadata::writeToParcel(Parcel& data, const camera_metadata_t* metadata) { status_t res = OK; /** * Below is the camera metadata parcel layout: * * |--------------------------------------------| * | arg0: blobSize | * | (length = 4) | * |--------------------------------------------|<--Skip the rest if blobSize == 0. * | | * | | * | arg1: blob | * | (length = variable, see arg1 layout below) | * | | * | | * |--------------------------------------------| * | arg2: offset | * | (length = 4) | * |--------------------------------------------| */ // arg0 = blobSize (int32) if (metadata == NULL) { // Write zero blobSize for null metadata. return data.writeInt32(0); } /** * Always make the blob size sufficiently larger, as we need put alignment * padding and metadata into the blob. Since we don't know the alignment * offset before writeBlob. Then write the metadata to aligned offset. */ const size_t metadataSize = get_camera_metadata_compact_size(metadata); const size_t alignment = get_camera_metadata_alignment(); const size_t blobSize = metadataSize + alignment; res = data.writeInt32(static_cast(blobSize)); if (res != OK) { return res; } size_t offset = 0; /** * arg1 = metadata (blob). * * The blob size is the sum of front padding size, metadata size and back padding * size, which is equal to metadataSize + alignment. * * The blob layout is: * |------------------------------------|<----Start address of the blob (unaligned). * | front padding | * | (size = offset) | * |------------------------------------|<----Aligned start address of metadata. * | | * | | * | metadata | * | (size = metadataSize) | * | | * | | * |------------------------------------| * | back padding | * | (size = alignment - offset) | * |------------------------------------|<----End address of blob. * (Blob start address + blob size). */ WritableBlob blob; do { res = data.writeBlob(blobSize, false, &blob); if (res != OK) { break; } const uintptr_t metadataStart = ALIGN_TO(blob.data(), alignment); offset = metadataStart - reinterpret_cast(blob.data()); ALOGV("%s: alignment is: %zu, metadata start: %p, offset: %zu", __FUNCTION__, alignment, reinterpret_cast(metadataStart), offset); copy_camera_metadata(reinterpret_cast(metadataStart), metadataSize, metadata); // Not too big of a problem since receiving side does hard validation // Don't check the size since the compact size could be larger if (validate_camera_metadata_structure(metadata, /*size*/NULL) != OK) { ALOGW("%s: Failed to validate metadata %p before writing blob", __FUNCTION__, metadata); } } while(false); blob.release(); // arg2 = offset (int32) res = data.writeInt32(static_cast(offset)); return res; } status_t CameraMetadata::readFromParcel(Parcel *parcel) { ALOGV("%s: parcel = %p", __FUNCTION__, parcel); status_t res = OK; if (parcel == NULL) { ALOGE("%s: parcel is null", __FUNCTION__); return BAD_VALUE; } if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } camera_metadata *buffer = NULL; // TODO: reading should return a status code, in case validation fails res = CameraMetadata::readFromParcel(*parcel, &buffer); if (res != NO_ERROR) { ALOGE("%s: Failed to read from parcel. Metadata is unchanged.", __FUNCTION__); return res; } clear(); mBuffer = buffer; return OK; } status_t CameraMetadata::writeToParcel(Parcel *parcel) const { ALOGV("%s: parcel = %p", __FUNCTION__, parcel); if (parcel == NULL) { ALOGE("%s: parcel is null", __FUNCTION__); return BAD_VALUE; } return CameraMetadata::writeToParcel(*parcel, mBuffer); } void CameraMetadata::swap(CameraMetadata& other) { if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return; } else if (other.mLocked) { ALOGE("%s: Other CameraMetadata is locked", __FUNCTION__); return; } camera_metadata* thisBuf = mBuffer; camera_metadata* otherBuf = other.mBuffer; other.mBuffer = thisBuf; mBuffer = otherBuf; } }; // namespace android ================================================ FILE: libshims/CameraParameters.cpp ================================================ /* ** ** Copyright 2008, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ #define LOG_TAG "CameraParams" #include #include #include #include #include #include namespace android { // Parameter keys to communicate between camera application and driver. const char CameraParameters::KEY_PREVIEW_SIZE[] = "preview-size"; const char CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES[] = "preview-size-values"; const char CameraParameters::KEY_PREVIEW_FORMAT[] = "preview-format"; const char CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS[] = "preview-format-values"; const char CameraParameters::KEY_PREVIEW_FRAME_RATE[] = "preview-frame-rate"; const char CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES[] = "preview-frame-rate-values"; const char CameraParameters::KEY_PREVIEW_FPS_RANGE[] = "preview-fps-range"; const char CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE[] = "preview-fps-range-values"; const char CameraParameters::KEY_PICTURE_SIZE[] = "picture-size"; const char CameraParameters::KEY_SUPPORTED_PICTURE_SIZES[] = "picture-size-values"; const char CameraParameters::KEY_PICTURE_FORMAT[] = "picture-format"; const char CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS[] = "picture-format-values"; const char CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH[] = "jpeg-thumbnail-width"; const char CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT[] = "jpeg-thumbnail-height"; const char CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES[] = "jpeg-thumbnail-size-values"; const char CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY[] = "jpeg-thumbnail-quality"; const char CameraParameters::KEY_JPEG_QUALITY[] = "jpeg-quality"; const char CameraParameters::KEY_ROTATION[] = "rotation"; const char CameraParameters::KEY_GPS_LATITUDE[] = "gps-latitude"; const char CameraParameters::KEY_GPS_LONGITUDE[] = "gps-longitude"; const char CameraParameters::KEY_GPS_ALTITUDE[] = "gps-altitude"; const char CameraParameters::KEY_GPS_TIMESTAMP[] = "gps-timestamp"; const char CameraParameters::KEY_GPS_PROCESSING_METHOD[] = "gps-processing-method"; const char CameraParameters::KEY_WHITE_BALANCE[] = "whitebalance"; const char CameraParameters::KEY_SUPPORTED_WHITE_BALANCE[] = "whitebalance-values"; const char CameraParameters::KEY_EFFECT[] = "effect"; const char CameraParameters::KEY_SUPPORTED_EFFECTS[] = "effect-values"; const char CameraParameters::KEY_ANTIBANDING[] = "antibanding"; const char CameraParameters::KEY_SUPPORTED_ANTIBANDING[] = "antibanding-values"; const char CameraParameters::KEY_SCENE_MODE[] = "scene-mode"; const char CameraParameters::KEY_SUPPORTED_SCENE_MODES[] = "scene-mode-values"; const char CameraParameters::KEY_FLASH_MODE[] = "flash-mode"; const char CameraParameters::KEY_SUPPORTED_FLASH_MODES[] = "flash-mode-values"; const char CameraParameters::KEY_FOCUS_MODE[] = "focus-mode"; const char CameraParameters::KEY_SUPPORTED_FOCUS_MODES[] = "focus-mode-values"; const char CameraParameters::KEY_MAX_NUM_FOCUS_AREAS[] = "max-num-focus-areas"; const char CameraParameters::KEY_FOCUS_AREAS[] = "focus-areas"; const char CameraParameters::KEY_FOCAL_LENGTH[] = "focal-length"; const char CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE[] = "horizontal-view-angle"; const char CameraParameters::KEY_VERTICAL_VIEW_ANGLE[] = "vertical-view-angle"; const char CameraParameters::KEY_EXPOSURE_COMPENSATION[] = "exposure-compensation"; const char CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION[] = "max-exposure-compensation"; const char CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION[] = "min-exposure-compensation"; const char CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP[] = "exposure-compensation-step"; const char CameraParameters::KEY_AUTO_EXPOSURE_LOCK[] = "auto-exposure-lock"; const char CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED[] = "auto-exposure-lock-supported"; const char CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK[] = "auto-whitebalance-lock"; const char CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED[] = "auto-whitebalance-lock-supported"; const char CameraParameters::KEY_MAX_NUM_METERING_AREAS[] = "max-num-metering-areas"; const char CameraParameters::KEY_METERING_AREAS[] = "metering-areas"; const char CameraParameters::KEY_ZOOM[] = "zoom"; const char CameraParameters::KEY_MAX_ZOOM[] = "max-zoom"; const char CameraParameters::KEY_ZOOM_RATIOS[] = "zoom-ratios"; const char CameraParameters::KEY_ZOOM_SUPPORTED[] = "zoom-supported"; const char CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED[] = "smooth-zoom-supported"; const char CameraParameters::KEY_FOCUS_DISTANCES[] = "focus-distances"; const char CameraParameters::KEY_VIDEO_FRAME_FORMAT[] = "video-frame-format"; const char CameraParameters::KEY_VIDEO_SIZE[] = "video-size"; const char CameraParameters::KEY_SUPPORTED_VIDEO_SIZES[] = "video-size-values"; const char CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO[] = "preferred-preview-size-for-video"; const char CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW[] = "max-num-detected-faces-hw"; const char CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW[] = "max-num-detected-faces-sw"; const char CameraParameters::KEY_RECORDING_HINT[] = "recording-hint"; const char CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED[] = "video-snapshot-supported"; const char CameraParameters::KEY_VIDEO_STABILIZATION[] = "video-stabilization"; const char CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED[] = "video-stabilization-supported"; const char CameraParameters::KEY_LIGHTFX[] = "light-fx"; const char CameraParameters::TRUE[] = "true"; const char CameraParameters::FALSE[] = "false"; const char CameraParameters::FOCUS_DISTANCE_INFINITY[] = "Infinity"; // Values for white balance settings. const char CameraParameters::WHITE_BALANCE_AUTO[] = "auto"; const char CameraParameters::WHITE_BALANCE_INCANDESCENT[] = "incandescent"; const char CameraParameters::WHITE_BALANCE_FLUORESCENT[] = "fluorescent"; const char CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT[] = "warm-fluorescent"; const char CameraParameters::WHITE_BALANCE_DAYLIGHT[] = "daylight"; const char CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT[] = "cloudy-daylight"; const char CameraParameters::WHITE_BALANCE_TWILIGHT[] = "twilight"; const char CameraParameters::WHITE_BALANCE_SHADE[] = "shade"; const char CameraParameters::WHITE_BALANCE_MANUAL_CCT[] = "manual-cct"; // Values for effect settings. const char CameraParameters::EFFECT_NONE[] = "none"; const char CameraParameters::EFFECT_MONO[] = "mono"; const char CameraParameters::EFFECT_NEGATIVE[] = "negative"; const char CameraParameters::EFFECT_SOLARIZE[] = "solarize"; const char CameraParameters::EFFECT_SEPIA[] = "sepia"; const char CameraParameters::EFFECT_POSTERIZE[] = "posterize"; const char CameraParameters::EFFECT_WHITEBOARD[] = "whiteboard"; const char CameraParameters::EFFECT_BLACKBOARD[] = "blackboard"; const char CameraParameters::EFFECT_AQUA[] = "aqua"; // Values for antibanding settings. const char CameraParameters::ANTIBANDING_AUTO[] = "auto"; const char CameraParameters::ANTIBANDING_50HZ[] = "50hz"; const char CameraParameters::ANTIBANDING_60HZ[] = "60hz"; const char CameraParameters::ANTIBANDING_OFF[] = "off"; // Values for flash mode settings. const char CameraParameters::FLASH_MODE_OFF[] = "off"; const char CameraParameters::FLASH_MODE_AUTO[] = "auto"; const char CameraParameters::FLASH_MODE_ON[] = "on"; const char CameraParameters::FLASH_MODE_RED_EYE[] = "red-eye"; const char CameraParameters::FLASH_MODE_TORCH[] = "torch"; // Values for scene mode settings. const char CameraParameters::SCENE_MODE_AUTO[] = "auto"; const char CameraParameters::SCENE_MODE_ACTION[] = "action"; const char CameraParameters::SCENE_MODE_PORTRAIT[] = "portrait"; const char CameraParameters::SCENE_MODE_LANDSCAPE[] = "landscape"; const char CameraParameters::SCENE_MODE_NIGHT[] = "night"; const char CameraParameters::SCENE_MODE_NIGHT_PORTRAIT[] = "night-portrait"; const char CameraParameters::SCENE_MODE_THEATRE[] = "theatre"; const char CameraParameters::SCENE_MODE_BEACH[] = "beach"; const char CameraParameters::SCENE_MODE_SNOW[] = "snow"; const char CameraParameters::SCENE_MODE_SUNSET[] = "sunset"; const char CameraParameters::SCENE_MODE_STEADYPHOTO[] = "steadyphoto"; const char CameraParameters::SCENE_MODE_FIREWORKS[] = "fireworks"; const char CameraParameters::SCENE_MODE_SPORTS[] = "sports"; const char CameraParameters::SCENE_MODE_PARTY[] = "party"; const char CameraParameters::SCENE_MODE_CANDLELIGHT[] = "candlelight"; const char CameraParameters::SCENE_MODE_BARCODE[] = "barcode"; const char CameraParameters::SCENE_MODE_HDR[] = "hdr"; const char CameraParameters::PIXEL_FORMAT_YUV422SP[] = "yuv422sp"; const char CameraParameters::PIXEL_FORMAT_YUV420SP[] = "yuv420sp"; const char CameraParameters::PIXEL_FORMAT_YUV422I[] = "yuv422i-yuyv"; const char CameraParameters::PIXEL_FORMAT_YUV420P[] = "yuv420p"; const char CameraParameters::PIXEL_FORMAT_RGB565[] = "rgb565"; const char CameraParameters::PIXEL_FORMAT_RGBA8888[] = "rgba8888"; const char CameraParameters::PIXEL_FORMAT_JPEG[] = "jpeg"; const char CameraParameters::PIXEL_FORMAT_BAYER_RGGB[] = "bayer-rggb"; const char CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE[] = "android-opaque"; // Values for focus mode settings. const char CameraParameters::FOCUS_MODE_AUTO[] = "auto"; const char CameraParameters::FOCUS_MODE_INFINITY[] = "infinity"; const char CameraParameters::FOCUS_MODE_MACRO[] = "macro"; const char CameraParameters::FOCUS_MODE_FIXED[] = "fixed"; const char CameraParameters::FOCUS_MODE_EDOF[] = "edof"; const char CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO[] = "continuous-video"; const char CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE[] = "continuous-picture"; const char CameraParameters::FOCUS_MODE_MANUAL_POSITION[] = "manual"; // Values for light fx settings const char CameraParameters::LIGHTFX_LOWLIGHT[] = "low-light"; const char CameraParameters::LIGHTFX_HDR[] = "high-dynamic-range"; #ifdef CAMERA_PARAMETERS_EXTRA_C CAMERA_PARAMETERS_EXTRA_C #endif CameraParameters::CameraParameters() : mMap() { } CameraParameters::~CameraParameters() { } String8 CameraParameters::flatten() const { String8 flattened(""); size_t size = mMap.size(); for (size_t i = 0; i < size; i++) { String8 k, v; k = mMap.keyAt(i); v = mMap.valueAt(i); flattened += k; flattened += "="; flattened += v; if (i != size-1) flattened += ";"; } return flattened; } void CameraParameters::unflatten(const String8 ¶ms) { const char *a = params.string(); const char *b; mMap.clear(); for (;;) { // Find the bounds of the key name. b = strchr(a, '='); if (b == 0) break; // Create the key string. String8 k(a, (size_t)(b-a)); // Find the value. a = b+1; b = strchr(a, ';'); if (b == 0) { // If there's no semicolon, this is the last item. String8 v(a); mMap.add(k, v); break; } String8 v(a, (size_t)(b-a)); mMap.add(k, v); a = b+1; } } void CameraParameters::set(const char *key, const char *value) { if (key == NULL || value == NULL) return; // XXX i think i can do this with strspn() if (strchr(key, '=') || strchr(key, ';')) { //XXX ALOGE("Key \"%s\"contains invalid character (= or ;)", key); return; } if (strchr(value, '=') || strchr(value, ';')) { //XXX ALOGE("Value \"%s\"contains invalid character (= or ;)", value); return; } #ifdef QCOM_HARDWARE // qcom cameras default to delivering an extra zero-exposure frame on HDR. // The android SDK only wants one frame, so disable this unless the app // explicitly asks for it if (!get("hdr-need-1x")) { mMap.replaceValueFor(String8("hdr-need-1x"), String8("false")); } #endif mMap.replaceValueFor(String8(key), String8(value)); } void CameraParameters::set(const char *key, int value) { char str[16]; sprintf(str, "%d", value); set(key, str); } void CameraParameters::setFloat(const char *key, float value) { char str[16]; // 14 should be enough. We overestimate to be safe. snprintf(str, sizeof(str), "%g", value); set(key, str); } const char *CameraParameters::get(const char *key) const { String8 v = mMap.valueFor(String8(key)); if (v.length() == 0) return 0; return v.string(); } int CameraParameters::getInt(const char *key) const { const char *v = get(key); if (v == 0) return -1; return strtol(v, 0, 0); } float CameraParameters::getFloat(const char *key) const { const char *v = get(key); if (v == 0) return -1; return strtof(v, 0); } void CameraParameters::remove(const char *key) { mMap.removeItem(String8(key)); } // Parse string like "640x480" or "10000,20000" static int parse_pair(const char *str, int *first, int *second, char delim, char **endptr = NULL) { // Find the first integer. char *end; int w = (int)strtol(str, &end, 10); // If a delimeter does not immediately follow, give up. if (*end != delim) { ALOGE("Cannot find delimeter (%c) in str=%s", delim, str); return -1; } // Find the second integer, immediately after the delimeter. int h = (int)strtol(end+1, &end, 10); *first = w; *second = h; if (endptr) { *endptr = end; } return 0; } static void parseSizesList(const char *sizesStr, Vector &sizes) { if (sizesStr == 0) { return; } char *sizeStartPtr = (char *)sizesStr; while (true) { int width, height; int success = parse_pair(sizeStartPtr, &width, &height, 'x', &sizeStartPtr); if (success == -1 || (*sizeStartPtr != ',' && *sizeStartPtr != '\0')) { ALOGE("Picture sizes string \"%s\" contains invalid character.", sizesStr); return; } sizes.push(Size(width, height)); if (*sizeStartPtr == '\0') { return; } sizeStartPtr++; } } void CameraParameters::setPreviewSize(int width, int height) { char str[32]; sprintf(str, "%dx%d", width, height); set(KEY_PREVIEW_SIZE, str); } void CameraParameters::getPreviewSize(int *width, int *height) const { *width = *height = -1; // Get the current string, if it doesn't exist, leave the -1x-1 const char *p = get(KEY_PREVIEW_SIZE); if (p == 0) return; parse_pair(p, width, height, 'x'); } void CameraParameters::getPreferredPreviewSizeForVideo(int *width, int *height) const { *width = *height = -1; const char *p = get(KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO); if (p == 0) return; parse_pair(p, width, height, 'x'); } void CameraParameters::getSupportedPreviewSizes(Vector &sizes) const { const char *previewSizesStr = get(KEY_SUPPORTED_PREVIEW_SIZES); parseSizesList(previewSizesStr, sizes); } void CameraParameters::setVideoSize(int width, int height) { char str[32]; sprintf(str, "%dx%d", width, height); set(KEY_VIDEO_SIZE, str); } void CameraParameters::getVideoSize(int *width, int *height) const { *width = *height = -1; const char *p = get(KEY_VIDEO_SIZE); if (p == 0) return; parse_pair(p, width, height, 'x'); } void CameraParameters::getSupportedVideoSizes(Vector &sizes) const { const char *videoSizesStr = get(KEY_SUPPORTED_VIDEO_SIZES); parseSizesList(videoSizesStr, sizes); } void CameraParameters::setPreviewFrameRate(int fps) { set(KEY_PREVIEW_FRAME_RATE, fps); } int CameraParameters::getPreviewFrameRate() const { return getInt(KEY_PREVIEW_FRAME_RATE); } void CameraParameters::getPreviewFpsRange(int *min_fps, int *max_fps) const { *min_fps = *max_fps = -1; const char *p = get(KEY_PREVIEW_FPS_RANGE); if (p == 0) return; parse_pair(p, min_fps, max_fps, ','); } void CameraParameters::setPreviewFormat(const char *format) { set(KEY_PREVIEW_FORMAT, format); } const char *CameraParameters::getPreviewFormat() const { return get(KEY_PREVIEW_FORMAT); } void CameraParameters::setPictureSize(int width, int height) { char str[32]; sprintf(str, "%dx%d", width, height); set(KEY_PICTURE_SIZE, str); } void CameraParameters::getPictureSize(int *width, int *height) const { *width = *height = -1; // Get the current string, if it doesn't exist, leave the -1x-1 const char *p = get(KEY_PICTURE_SIZE); if (p == 0) return; parse_pair(p, width, height, 'x'); } void CameraParameters::getSupportedPictureSizes(Vector &sizes) const { const char *pictureSizesStr = get(KEY_SUPPORTED_PICTURE_SIZES); parseSizesList(pictureSizesStr, sizes); } void CameraParameters::setPictureFormat(const char *format) { set(KEY_PICTURE_FORMAT, format); } const char *CameraParameters::getPictureFormat() const { return get(KEY_PICTURE_FORMAT); } void CameraParameters::dump() const { ALOGD("dump: mMap.size = %zu", mMap.size()); for (size_t i = 0; i < mMap.size(); i++) { String8 k, v; k = mMap.keyAt(i); v = mMap.valueAt(i); ALOGD("%s: %s\n", k.string(), v.string()); } } status_t CameraParameters::dump(int fd, const Vector& /*args*/) const { const size_t SIZE = 256; char buffer[SIZE]; String8 result; snprintf(buffer, 255, "CameraParameters::dump: mMap.size = %zu\n", mMap.size()); result.append(buffer); for (size_t i = 0; i < mMap.size(); i++) { String8 k, v; k = mMap.keyAt(i); v = mMap.valueAt(i); snprintf(buffer, 255, "\t%s: %s\n", k.string(), v.string()); result.append(buffer); } write(fd, result.string(), result.size()); return NO_ERROR; } void CameraParameters::getSupportedPreviewFormats(Vector& formats) const { const char* supportedPreviewFormats = get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS); if (supportedPreviewFormats == NULL) { ALOGW("%s: No supported preview formats.", __FUNCTION__); return; } String8 fmtStr(supportedPreviewFormats); char* prevFmts = fmtStr.lockBuffer(fmtStr.size()); char* savePtr; char* fmt = strtok_r(prevFmts, ",", &savePtr); while (fmt) { int actual = previewFormatToEnum(fmt); if (actual != -1) { formats.add(actual); } fmt = strtok_r(NULL, ",", &savePtr); } fmtStr.unlockBuffer(fmtStr.size()); } int CameraParameters::previewFormatToEnum(const char* format) { return !format ? HAL_PIXEL_FORMAT_YCrCb_420_SP : !strcmp(format, PIXEL_FORMAT_YUV422SP) ? HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16 !strcmp(format, PIXEL_FORMAT_YUV420SP) ? HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21 !strcmp(format, PIXEL_FORMAT_YUV422I) ? HAL_PIXEL_FORMAT_YCbCr_422_I : // YUY2 !strcmp(format, PIXEL_FORMAT_YUV420P) ? HAL_PIXEL_FORMAT_YV12 : // YV12 !strcmp(format, PIXEL_FORMAT_RGB565) ? HAL_PIXEL_FORMAT_RGB_565 : // RGB565 !strcmp(format, PIXEL_FORMAT_RGBA8888) ? HAL_PIXEL_FORMAT_RGBA_8888 : // RGB8888 !strcmp(format, PIXEL_FORMAT_BAYER_RGGB) ? HAL_PIXEL_FORMAT_RAW16 : // Raw sensor data -1; } bool CameraParameters::isEmpty() const { return mMap.isEmpty(); } }; // namespace android ================================================ FILE: libshims/CameraParameters2.cpp ================================================ /* ** ** Copyright 2008, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ #define LOG_TAG "CameraParams2" // #define LOG_NDEBUG 0 #include #include #include #include namespace android { CameraParameters2::CameraParameters2() : mMap() { } CameraParameters2::~CameraParameters2() { } String8 CameraParameters2::flatten() const { String8 flattened(""); size_t size = mMap.size(); for (size_t i = 0; i < size; i++) { String8 k, v; k = mMap.keyAt(i); v = mMap.valueAt(i); flattened += k; flattened += "="; flattened += v; if (i != size-1) flattened += ";"; } ALOGV("%s: Flattened params = %s", __FUNCTION__, flattened.string()); return flattened; } void CameraParameters2::unflatten(const String8 ¶ms) { const char *a = params.string(); const char *b; mMap.clear(); for (;;) { // Find the bounds of the key name. b = strchr(a, '='); if (b == 0) break; // Create the key string. String8 k(a, (size_t)(b-a)); // Find the value. a = b+1; b = strchr(a, ';'); if (b == 0) { // If there's no semicolon, this is the last item. String8 v(a); mMap.add(k, v); break; } String8 v(a, (size_t)(b-a)); mMap.add(k, v); a = b+1; } } void CameraParameters2::set(const char *key, const char *value) { // XXX i think i can do this with strspn() if (strchr(key, '=') || strchr(key, ';')) { //XXX ALOGE("Key \"%s\"contains invalid character (= or ;)", key); return; } if (strchr(value, '=') || strchr(value, ';')) { //XXX ALOGE("Value \"%s\"contains invalid character (= or ;)", value); return; } // Replacing a value updates the key's order to be the new largest order ssize_t res = mMap.replaceValueFor(String8(key), String8(value)); LOG_ALWAYS_FATAL_IF(res < 0, "replaceValueFor(%s,%s) failed", key, value); } void CameraParameters2::set(const char *key, int value) { char str[16]; sprintf(str, "%d", value); set(key, str); } void CameraParameters2::setFloat(const char *key, float value) { char str[16]; // 14 should be enough. We overestimate to be safe. snprintf(str, sizeof(str), "%g", value); set(key, str); } const char *CameraParameters2::get(const char *key) const { ssize_t idx = mMap.indexOfKey(String8(key)); if (idx < 0) { return NULL; } else { return mMap.valueAt(idx).string(); } } int CameraParameters2::getInt(const char *key) const { const char *v = get(key); if (v == 0) return -1; return strtol(v, 0, 0); } float CameraParameters2::getFloat(const char *key) const { const char *v = get(key); if (v == 0) return -1; return strtof(v, 0); } status_t CameraParameters2::compareSetOrder(const char *key1, const char *key2, int *order) const { if (key1 == NULL) { ALOGE("%s: key1 must not be NULL", __FUNCTION__); return BAD_VALUE; } else if (key2 == NULL) { ALOGE("%s: key2 must not be NULL", __FUNCTION__); return BAD_VALUE; } else if (order == NULL) { ALOGE("%s: order must not be NULL", __FUNCTION__); return BAD_VALUE; } ssize_t index1 = mMap.indexOfKey(String8(key1)); ssize_t index2 = mMap.indexOfKey(String8(key2)); if (index1 < 0) { ALOGW("%s: Key1 (%s) was not set", __FUNCTION__, key1); return NAME_NOT_FOUND; } else if (index2 < 0) { ALOGW("%s: Key2 (%s) was not set", __FUNCTION__, key2); return NAME_NOT_FOUND; } *order = (index1 == index2) ? 0 : (index1 < index2) ? -1 : 1; return OK; } void CameraParameters2::remove(const char *key) { mMap.removeItem(String8(key)); } // Parse string like "640x480" or "10000,20000" static int parse_pair(const char *str, int *first, int *second, char delim, char **endptr = NULL) { // Find the first integer. char *end; int w = (int)strtol(str, &end, 10); // If a delimeter does not immediately follow, give up. if (*end != delim) { ALOGE("Cannot find delimeter (%c) in str=%s", delim, str); return -1; } // Find the second integer, immediately after the delimeter. int h = (int)strtol(end+1, &end, 10); *first = w; *second = h; if (endptr) { *endptr = end; } return 0; } static void parseSizesList(const char *sizesStr, Vector &sizes) { if (sizesStr == 0) { return; } char *sizeStartPtr = (char *)sizesStr; while (true) { int width, height; int success = parse_pair(sizeStartPtr, &width, &height, 'x', &sizeStartPtr); if (success == -1 || (*sizeStartPtr != ',' && *sizeStartPtr != '\0')) { ALOGE("Picture sizes string \"%s\" contains invalid character.", sizesStr); return; } sizes.push(Size(width, height)); if (*sizeStartPtr == '\0') { return; } sizeStartPtr++; } } void CameraParameters2::setPreviewSize(int width, int height) { char str[32]; sprintf(str, "%dx%d", width, height); set(CameraParameters::KEY_PREVIEW_SIZE, str); } void CameraParameters2::getPreviewSize(int *width, int *height) const { *width = *height = -1; // Get the current string, if it doesn't exist, leave the -1x-1 const char *p = get(CameraParameters::KEY_PREVIEW_SIZE); if (p == 0) return; parse_pair(p, width, height, 'x'); } void CameraParameters2::getPreferredPreviewSizeForVideo(int *width, int *height) const { *width = *height = -1; const char *p = get(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO); if (p == 0) return; parse_pair(p, width, height, 'x'); } void CameraParameters2::getSupportedPreviewSizes(Vector &sizes) const { const char *previewSizesStr = get(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES); parseSizesList(previewSizesStr, sizes); } void CameraParameters2::setVideoSize(int width, int height) { char str[32]; sprintf(str, "%dx%d", width, height); set(CameraParameters::KEY_VIDEO_SIZE, str); } void CameraParameters2::getVideoSize(int *width, int *height) const { *width = *height = -1; const char *p = get(CameraParameters::KEY_VIDEO_SIZE); if (p == 0) return; parse_pair(p, width, height, 'x'); } void CameraParameters2::getSupportedVideoSizes(Vector &sizes) const { const char *videoSizesStr = get(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES); parseSizesList(videoSizesStr, sizes); } void CameraParameters2::setPreviewFrameRate(int fps) { set(CameraParameters::KEY_PREVIEW_FRAME_RATE, fps); } int CameraParameters2::getPreviewFrameRate() const { return getInt(CameraParameters::KEY_PREVIEW_FRAME_RATE); } void CameraParameters2::getPreviewFpsRange(int *min_fps, int *max_fps) const { *min_fps = *max_fps = -1; const char *p = get(CameraParameters::KEY_PREVIEW_FPS_RANGE); if (p == 0) return; parse_pair(p, min_fps, max_fps, ','); } void CameraParameters2::setPreviewFpsRange(int min_fps, int max_fps) { String8 str = String8::format("%d,%d", min_fps, max_fps); set(CameraParameters::KEY_PREVIEW_FPS_RANGE, str.string()); } void CameraParameters2::setPreviewFormat(const char *format) { set(CameraParameters::KEY_PREVIEW_FORMAT, format); } const char *CameraParameters2::getPreviewFormat() const { return get(CameraParameters::KEY_PREVIEW_FORMAT); } void CameraParameters2::setPictureSize(int width, int height) { char str[32]; sprintf(str, "%dx%d", width, height); set(CameraParameters::KEY_PICTURE_SIZE, str); } void CameraParameters2::getPictureSize(int *width, int *height) const { *width = *height = -1; // Get the current string, if it doesn't exist, leave the -1x-1 const char *p = get(CameraParameters::KEY_PICTURE_SIZE); if (p == 0) return; parse_pair(p, width, height, 'x'); } void CameraParameters2::getSupportedPictureSizes(Vector &sizes) const { const char *pictureSizesStr = get(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES); parseSizesList(pictureSizesStr, sizes); } void CameraParameters2::setPictureFormat(const char *format) { set(CameraParameters::KEY_PICTURE_FORMAT, format); } const char *CameraParameters2::getPictureFormat() const { return get(CameraParameters::KEY_PICTURE_FORMAT); } void CameraParameters2::dump() const { ALOGD("dump: mMap.size = %d", mMap.size()); for (size_t i = 0; i < mMap.size(); i++) { String8 k, v; k = mMap.keyAt(i); v = mMap.valueAt(i); ALOGD("%s: %s\n", k.string(), v.string()); } } status_t CameraParameters2::dump(int fd, const Vector& args) const { (void)args; const size_t SIZE = 256; char buffer[SIZE]; String8 result; snprintf(buffer, 255, "CameraParameters2::dump: mMap.size = %zu\n", mMap.size()); result.append(buffer); for (size_t i = 0; i < mMap.size(); i++) { String8 k, v; k = mMap.keyAt(i); v = mMap.valueAt(i); snprintf(buffer, 255, "\t%s: %s\n", k.string(), v.string()); result.append(buffer); } write(fd, result.string(), result.size()); return NO_ERROR; } }; // namespace android ================================================ FILE: libshims/CameraUtils.cpp ================================================ /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "CameraUtils" //#define LOG_NDEBUG 0 #include #include #include #include namespace android { status_t CameraUtils::getRotationTransform(const CameraMetadata& staticInfo, /*out*/int32_t* transform) { ALOGV("%s", __FUNCTION__); if (transform == NULL) { ALOGW("%s: null transform", __FUNCTION__); return BAD_VALUE; } *transform = 0; camera_metadata_ro_entry_t entry = staticInfo.find(ANDROID_SENSOR_ORIENTATION); if (entry.count == 0) { ALOGE("%s: Can't find android.sensor.orientation in static metadata!", __FUNCTION__); return INVALID_OPERATION; } camera_metadata_ro_entry_t entryFacing = staticInfo.find(ANDROID_LENS_FACING); if (entry.count == 0) { ALOGE("%s: Can't find android.lens.facing in static metadata!", __FUNCTION__); return INVALID_OPERATION; } int32_t& flags = *transform; bool mirror = (entryFacing.data.u8[0] == ANDROID_LENS_FACING_FRONT); int orientation = entry.data.i32[0]; if (!mirror) { switch (orientation) { case 0: flags = 0; break; case 90: flags = NATIVE_WINDOW_TRANSFORM_ROT_90; break; case 180: flags = NATIVE_WINDOW_TRANSFORM_ROT_180; break; case 270: flags = NATIVE_WINDOW_TRANSFORM_ROT_270; break; default: ALOGE("%s: Invalid HAL android.sensor.orientation value: %d", __FUNCTION__, orientation); return INVALID_OPERATION; } } else { // Front camera needs to be horizontally flipped for mirror-like behavior. // Note: Flips are applied before rotates; using XOR here as some of these flags are // composed in terms of other flip/rotation flags, and are not bitwise-ORable. switch (orientation) { case 0: flags = NATIVE_WINDOW_TRANSFORM_FLIP_H; break; case 90: flags = NATIVE_WINDOW_TRANSFORM_FLIP_H ^ NATIVE_WINDOW_TRANSFORM_ROT_270; break; case 180: flags = NATIVE_WINDOW_TRANSFORM_FLIP_H ^ NATIVE_WINDOW_TRANSFORM_ROT_180; break; case 270: flags = NATIVE_WINDOW_TRANSFORM_FLIP_H ^ NATIVE_WINDOW_TRANSFORM_ROT_90; break; default: ALOGE("%s: Invalid HAL android.sensor.orientation value: %d", __FUNCTION__, orientation); return INVALID_OPERATION; } } /** * This magic flag makes surfaceflinger un-rotate the buffers * to counter the extra global device UI rotation whenever the user * physically rotates the device. * * By doing this, the camera buffer always ends up aligned * with the physical camera for a "see through" effect. * * In essence, the buffer only gets rotated during preview use-cases. * The user is still responsible to re-create streams of the proper * aspect ratio, or the preview will end up looking non-uniformly * stretched. */ flags |= NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY; ALOGV("%s: final transform = 0x%x", __FUNCTION__, flags); return OK; } } /* namespace android */ ================================================ FILE: libshims/CaptureResult.cpp ================================================ /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "Camera-CaptureResult" #include #include #include namespace android { bool CaptureResultExtras::isValid() { return requestId >= 0; } status_t CaptureResultExtras::readFromParcel(Parcel *parcel) { if (parcel == NULL) { ALOGE("%s: Null parcel", __FUNCTION__); return BAD_VALUE; } parcel->readInt32(&requestId); parcel->readInt32(&burstId); parcel->readInt32(&afTriggerId); parcel->readInt32(&precaptureTriggerId); parcel->readInt64(&frameNumber); parcel->readInt32(&partialResultCount); return OK; } status_t CaptureResultExtras::writeToParcel(Parcel *parcel) const { if (parcel == NULL) { ALOGE("%s: Null parcel", __FUNCTION__); return BAD_VALUE; } parcel->writeInt32(requestId); parcel->writeInt32(burstId); parcel->writeInt32(afTriggerId); parcel->writeInt32(precaptureTriggerId); parcel->writeInt64(frameNumber); parcel->writeInt32(partialResultCount); return OK; } CaptureResult::CaptureResult() : mMetadata(), mResultExtras() { } CaptureResult::CaptureResult(const CaptureResult &otherResult) { mResultExtras = otherResult.mResultExtras; mMetadata = otherResult.mMetadata; } status_t CaptureResult::readFromParcel(Parcel *parcel) { ALOGV("%s: parcel = %p", __FUNCTION__, parcel); if (parcel == NULL) { ALOGE("%s: parcel is null", __FUNCTION__); return BAD_VALUE; } mMetadata.clear(); status_t res = OK; res = mMetadata.readFromParcel(parcel); if (res != OK) { ALOGE("%s: Failed to read metadata from parcel.", __FUNCTION__); return res; } ALOGV("%s: Read metadata from parcel", __FUNCTION__); res = mResultExtras.readFromParcel(parcel); if (res != OK) { ALOGE("%s: Failed to read result extras from parcel.", __FUNCTION__); return res; } ALOGV("%s: Read result extras from parcel", __FUNCTION__); return OK; } status_t CaptureResult::writeToParcel(Parcel *parcel) const { ALOGV("%s: parcel = %p", __FUNCTION__, parcel); if (parcel == NULL) { ALOGE("%s: parcel is null", __FUNCTION__); return BAD_VALUE; } status_t res; res = mMetadata.writeToParcel(parcel); if (res != OK) { ALOGE("%s: Failed to write metadata to parcel", __FUNCTION__); return res; } ALOGV("%s: Wrote metadata to parcel", __FUNCTION__); res = mResultExtras.writeToParcel(parcel); if (res != OK) { ALOGE("%s: Failed to write result extras to parcel", __FUNCTION__); return res; } ALOGV("%s: Wrote result extras to parcel", __FUNCTION__); return OK; } } ================================================ FILE: libshims/ICamera.cpp ================================================ /* ** ** Copyright 2008, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ //#define LOG_NDEBUG 0 #define LOG_TAG "ICamera" #include #include #include #include #include #include #include namespace android { enum { DISCONNECT = IBinder::FIRST_CALL_TRANSACTION, SET_PREVIEW_TARGET, SET_PREVIEW_CALLBACK_FLAG, SET_PREVIEW_CALLBACK_TARGET, START_PREVIEW, STOP_PREVIEW, AUTO_FOCUS, CANCEL_AUTO_FOCUS, TAKE_PICTURE, SET_PARAMETERS, GET_PARAMETERS, SEND_COMMAND, CONNECT, LOCK, UNLOCK, PREVIEW_ENABLED, START_RECORDING, STOP_RECORDING, RECORDING_ENABLED, RELEASE_RECORDING_FRAME, STORE_META_DATA_IN_BUFFERS, }; class BpCamera: public BpInterface { public: BpCamera(const sp& impl) : BpInterface(impl) { } // disconnect from camera service void disconnect() { ALOGV("disconnect"); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); remote()->transact(DISCONNECT, data, &reply); reply.readExceptionCode(); } // pass the buffered IGraphicBufferProducer to the camera service status_t setPreviewTarget(const sp& bufferProducer) { ALOGV("setPreviewTarget"); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); sp b(IInterface::asBinder(bufferProducer)); data.writeStrongBinder(b); remote()->transact(SET_PREVIEW_TARGET, data, &reply); return reply.readInt32(); } // set the preview callback flag to affect how the received frames from // preview are handled. See Camera.h for details. void setPreviewCallbackFlag(int flag) { ALOGV("setPreviewCallbackFlag(%d)", flag); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); data.writeInt32(flag); remote()->transact(SET_PREVIEW_CALLBACK_FLAG, data, &reply); } status_t setPreviewCallbackTarget( const sp& callbackProducer) { ALOGV("setPreviewCallbackTarget"); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); sp b(IInterface::asBinder(callbackProducer)); data.writeStrongBinder(b); remote()->transact(SET_PREVIEW_CALLBACK_TARGET, data, &reply); return reply.readInt32(); } // start preview mode, must call setPreviewTarget first status_t startPreview() { ALOGV("startPreview"); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); remote()->transact(START_PREVIEW, data, &reply); return reply.readInt32(); } // start recording mode, must call setPreviewTarget first status_t startRecording() { ALOGV("startRecording"); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); remote()->transact(START_RECORDING, data, &reply); return reply.readInt32(); } // stop preview mode void stopPreview() { ALOGV("stopPreview"); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); remote()->transact(STOP_PREVIEW, data, &reply); } // stop recording mode void stopRecording() { ALOGV("stopRecording"); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); remote()->transact(STOP_RECORDING, data, &reply); } void releaseRecordingFrame(const sp& mem) { ALOGV("releaseRecordingFrame"); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); data.writeStrongBinder(IInterface::asBinder(mem)); remote()->transact(RELEASE_RECORDING_FRAME, data, &reply); } status_t storeMetaDataInBuffers(bool enabled) { ALOGV("storeMetaDataInBuffers: %s", enabled? "true": "false"); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); data.writeInt32(enabled); remote()->transact(STORE_META_DATA_IN_BUFFERS, data, &reply); return reply.readInt32(); } // check preview state bool previewEnabled() { ALOGV("previewEnabled"); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); remote()->transact(PREVIEW_ENABLED, data, &reply); return reply.readInt32(); } // check recording state bool recordingEnabled() { ALOGV("recordingEnabled"); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); remote()->transact(RECORDING_ENABLED, data, &reply); return reply.readInt32(); } // auto focus status_t autoFocus() { ALOGV("autoFocus"); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); remote()->transact(AUTO_FOCUS, data, &reply); status_t ret = reply.readInt32(); return ret; } // cancel focus status_t cancelAutoFocus() { ALOGV("cancelAutoFocus"); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); remote()->transact(CANCEL_AUTO_FOCUS, data, &reply); status_t ret = reply.readInt32(); return ret; } // take a picture - returns an IMemory (ref-counted mmap) status_t takePicture(int msgType) { ALOGV("takePicture: 0x%x", msgType); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); data.writeInt32(msgType); remote()->transact(TAKE_PICTURE, data, &reply); status_t ret = reply.readInt32(); return ret; } // set preview/capture parameters - key/value pairs status_t setParameters(const String8& params) { ALOGV("setParameters"); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); data.writeString8(params); remote()->transact(SET_PARAMETERS, data, &reply); return reply.readInt32(); } // get preview/capture parameters - key/value pairs String8 getParameters() const { ALOGV("getParameters"); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); remote()->transact(GET_PARAMETERS, data, &reply); return reply.readString8(); } virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) { ALOGV("sendCommand"); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); data.writeInt32(cmd); data.writeInt32(arg1); data.writeInt32(arg2); remote()->transact(SEND_COMMAND, data, &reply); return reply.readInt32(); } virtual status_t connect(const sp& cameraClient) { Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); data.writeStrongBinder(IInterface::asBinder(cameraClient)); remote()->transact(CONNECT, data, &reply); return reply.readInt32(); } virtual status_t lock() { Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); remote()->transact(LOCK, data, &reply); return reply.readInt32(); } virtual status_t unlock() { Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); remote()->transact(UNLOCK, data, &reply); return reply.readInt32(); } }; IMPLEMENT_META_INTERFACE(Camera, "android.hardware.ICamera"); // ---------------------------------------------------------------------- status_t BnCamera::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch(code) { case DISCONNECT: { ALOGV("DISCONNECT"); CHECK_INTERFACE(ICamera, data, reply); disconnect(); reply->writeNoException(); return NO_ERROR; } break; case SET_PREVIEW_TARGET: { ALOGV("SET_PREVIEW_TARGET"); CHECK_INTERFACE(ICamera, data, reply); sp st = interface_cast(data.readStrongBinder()); reply->writeInt32(setPreviewTarget(st)); return NO_ERROR; } break; case SET_PREVIEW_CALLBACK_FLAG: { ALOGV("SET_PREVIEW_CALLBACK_TYPE"); CHECK_INTERFACE(ICamera, data, reply); int callback_flag = data.readInt32(); setPreviewCallbackFlag(callback_flag); return NO_ERROR; } break; case SET_PREVIEW_CALLBACK_TARGET: { ALOGV("SET_PREVIEW_CALLBACK_TARGET"); CHECK_INTERFACE(ICamera, data, reply); sp cp = interface_cast(data.readStrongBinder()); reply->writeInt32(setPreviewCallbackTarget(cp)); return NO_ERROR; } case START_PREVIEW: { ALOGV("START_PREVIEW"); CHECK_INTERFACE(ICamera, data, reply); reply->writeInt32(startPreview()); return NO_ERROR; } break; case START_RECORDING: { ALOGV("START_RECORDING"); CHECK_INTERFACE(ICamera, data, reply); reply->writeInt32(startRecording()); return NO_ERROR; } break; case STOP_PREVIEW: { ALOGV("STOP_PREVIEW"); CHECK_INTERFACE(ICamera, data, reply); stopPreview(); return NO_ERROR; } break; case STOP_RECORDING: { ALOGV("STOP_RECORDING"); CHECK_INTERFACE(ICamera, data, reply); stopRecording(); return NO_ERROR; } break; case RELEASE_RECORDING_FRAME: { ALOGV("RELEASE_RECORDING_FRAME"); CHECK_INTERFACE(ICamera, data, reply); sp mem = interface_cast(data.readStrongBinder()); releaseRecordingFrame(mem); return NO_ERROR; } break; case STORE_META_DATA_IN_BUFFERS: { ALOGV("STORE_META_DATA_IN_BUFFERS"); CHECK_INTERFACE(ICamera, data, reply); bool enabled = data.readInt32(); reply->writeInt32(storeMetaDataInBuffers(enabled)); return NO_ERROR; } break; case PREVIEW_ENABLED: { ALOGV("PREVIEW_ENABLED"); CHECK_INTERFACE(ICamera, data, reply); reply->writeInt32(previewEnabled()); return NO_ERROR; } break; case RECORDING_ENABLED: { ALOGV("RECORDING_ENABLED"); CHECK_INTERFACE(ICamera, data, reply); reply->writeInt32(recordingEnabled()); return NO_ERROR; } break; case AUTO_FOCUS: { ALOGV("AUTO_FOCUS"); CHECK_INTERFACE(ICamera, data, reply); reply->writeInt32(autoFocus()); return NO_ERROR; } break; case CANCEL_AUTO_FOCUS: { ALOGV("CANCEL_AUTO_FOCUS"); CHECK_INTERFACE(ICamera, data, reply); reply->writeInt32(cancelAutoFocus()); return NO_ERROR; } break; case TAKE_PICTURE: { ALOGV("TAKE_PICTURE"); CHECK_INTERFACE(ICamera, data, reply); int msgType = data.readInt32(); reply->writeInt32(takePicture(msgType)); return NO_ERROR; } break; case SET_PARAMETERS: { ALOGV("SET_PARAMETERS"); CHECK_INTERFACE(ICamera, data, reply); String8 params(data.readString8()); reply->writeInt32(setParameters(params)); return NO_ERROR; } break; case GET_PARAMETERS: { ALOGV("GET_PARAMETERS"); CHECK_INTERFACE(ICamera, data, reply); reply->writeString8(getParameters()); return NO_ERROR; } break; case SEND_COMMAND: { ALOGV("SEND_COMMAND"); CHECK_INTERFACE(ICamera, data, reply); int command = data.readInt32(); int arg1 = data.readInt32(); int arg2 = data.readInt32(); reply->writeInt32(sendCommand(command, arg1, arg2)); return NO_ERROR; } break; case CONNECT: { CHECK_INTERFACE(ICamera, data, reply); sp cameraClient = interface_cast(data.readStrongBinder()); reply->writeInt32(connect(cameraClient)); return NO_ERROR; } break; case LOCK: { CHECK_INTERFACE(ICamera, data, reply); reply->writeInt32(lock()); return NO_ERROR; } break; case UNLOCK: { CHECK_INTERFACE(ICamera, data, reply); reply->writeInt32(unlock()); return NO_ERROR; } break; default: return BBinder::onTransact(code, data, reply, flags); } } // ---------------------------------------------------------------------------- }; // namespace android ================================================ FILE: libshims/ICameraClient.cpp ================================================ /* ** ** Copyright 2008, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ //#define LOG_NDEBUG 0 #define LOG_TAG "ICameraClient" #include #include #include #include namespace android { enum { NOTIFY_CALLBACK = IBinder::FIRST_CALL_TRANSACTION, DATA_CALLBACK, DATA_CALLBACK_TIMESTAMP, }; class BpCameraClient: public BpInterface { public: BpCameraClient(const sp& impl) : BpInterface(impl) { } // generic callback from camera service to app void notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) { ALOGV("notifyCallback"); Parcel data, reply; data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor()); data.writeInt32(msgType); data.writeInt32(ext1); if ((msgType == CAMERA_MSG_PREVIEW_FRAME) && (ext1 == CAMERA_FRAME_DATA_FD)) { ALOGD("notifyCallback: CAMERA_MSG_PREVIEW_FRAME fd = %d", ext2); data.writeFileDescriptor(ext2); } else { data.writeInt32(ext2); } remote()->transact(NOTIFY_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY); } // generic data callback from camera service to app with image data void dataCallback(int32_t msgType, const sp& imageData, camera_frame_metadata_t *metadata) { ALOGV("dataCallback"); Parcel data, reply; data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor()); data.writeInt32(msgType); data.writeStrongBinder(IInterface::asBinder(imageData)); if (metadata) { data.writeInt32(metadata->number_of_faces); data.write(metadata->faces, sizeof(camera_face_t) * metadata->number_of_faces); } remote()->transact(DATA_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY); } // generic data callback from camera service to app with image data void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp& imageData) { ALOGV("dataCallback"); Parcel data, reply; data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor()); data.writeInt64(timestamp); data.writeInt32(msgType); data.writeStrongBinder(IInterface::asBinder(imageData)); remote()->transact(DATA_CALLBACK_TIMESTAMP, data, &reply, IBinder::FLAG_ONEWAY); } }; IMPLEMENT_META_INTERFACE(CameraClient, "android.hardware.ICameraClient"); // ---------------------------------------------------------------------- status_t BnCameraClient::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch(code) { case NOTIFY_CALLBACK: { ALOGV("NOTIFY_CALLBACK"); CHECK_INTERFACE(ICameraClient, data, reply); int32_t msgType = data.readInt32(); int32_t ext1 = data.readInt32(); int32_t ext2 = 0; if ((msgType == CAMERA_MSG_PREVIEW_FRAME) && (ext1 == CAMERA_FRAME_DATA_FD)) { ext2 = data.readFileDescriptor(); ALOGD("onTransact: CAMERA_MSG_PREVIEW_FRAME fd = %d", ext2); } else { ext2 = data.readInt32(); } notifyCallback(msgType, ext1, ext2); return NO_ERROR; } break; case DATA_CALLBACK: { ALOGV("DATA_CALLBACK"); CHECK_INTERFACE(ICameraClient, data, reply); int32_t msgType = data.readInt32(); sp imageData = interface_cast(data.readStrongBinder()); camera_frame_metadata_t *metadata = NULL; if (data.dataAvail() > 0) { metadata = new camera_frame_metadata_t; metadata->number_of_faces = data.readInt32(); metadata->faces = (camera_face_t *) data.readInplace( sizeof(camera_face_t) * metadata->number_of_faces); } dataCallback(msgType, imageData, metadata); if (metadata) delete metadata; return NO_ERROR; } break; case DATA_CALLBACK_TIMESTAMP: { ALOGV("DATA_CALLBACK_TIMESTAMP"); CHECK_INTERFACE(ICameraClient, data, reply); nsecs_t timestamp = data.readInt64(); int32_t msgType = data.readInt32(); sp imageData = interface_cast(data.readStrongBinder()); dataCallbackTimestamp(timestamp, msgType, imageData); return NO_ERROR; } break; default: return BBinder::onTransact(code, data, reply, flags); } } // ---------------------------------------------------------------------------- }; // namespace android ================================================ FILE: libshims/ICameraRecordingProxy.cpp ================================================ /* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ //#define LOG_NDEBUG 0 #define LOG_TAG "ICameraRecordingProxy" #include #include #include #include #include #include namespace android { enum { START_RECORDING = IBinder::FIRST_CALL_TRANSACTION, STOP_RECORDING, RELEASE_RECORDING_FRAME, }; uint8_t ICameraRecordingProxy::baseObject = 0; size_t ICameraRecordingProxy::getCommonBaseAddress() { return (size_t)&baseObject; } class BpCameraRecordingProxy: public BpInterface { public: BpCameraRecordingProxy(const sp& impl) : BpInterface(impl) { } status_t startRecording(const sp& listener) { ALOGV("startRecording"); Parcel data, reply; data.writeInterfaceToken(ICameraRecordingProxy::getInterfaceDescriptor()); data.writeStrongBinder(IInterface::asBinder(listener)); remote()->transact(START_RECORDING, data, &reply); return reply.readInt32(); } void stopRecording() { ALOGV("stopRecording"); Parcel data, reply; data.writeInterfaceToken(ICameraRecordingProxy::getInterfaceDescriptor()); remote()->transact(STOP_RECORDING, data, &reply); } void releaseRecordingFrame(const sp& mem) { ALOGV("releaseRecordingFrame"); Parcel data, reply; data.writeInterfaceToken(ICameraRecordingProxy::getInterfaceDescriptor()); data.writeStrongBinder(IInterface::asBinder(mem)); remote()->transact(RELEASE_RECORDING_FRAME, data, &reply); } }; IMPLEMENT_META_INTERFACE(CameraRecordingProxy, "android.hardware.ICameraRecordingProxy"); // ---------------------------------------------------------------------- status_t BnCameraRecordingProxy::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch(code) { case START_RECORDING: { ALOGV("START_RECORDING"); CHECK_INTERFACE(ICameraRecordingProxy, data, reply); sp listener = interface_cast(data.readStrongBinder()); reply->writeInt32(startRecording(listener)); return NO_ERROR; } break; case STOP_RECORDING: { ALOGV("STOP_RECORDING"); CHECK_INTERFACE(ICameraRecordingProxy, data, reply); stopRecording(); return NO_ERROR; } break; case RELEASE_RECORDING_FRAME: { ALOGV("RELEASE_RECORDING_FRAME"); CHECK_INTERFACE(ICameraRecordingProxy, data, reply); sp mem = interface_cast(data.readStrongBinder()); releaseRecordingFrame(mem); return NO_ERROR; } break; default: return BBinder::onTransact(code, data, reply, flags); } } // ---------------------------------------------------------------------------- }; // namespace android ================================================ FILE: libshims/ICameraRecordingProxyListener.cpp ================================================ /* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ //#define LOG_NDEBUG 0 #define LOG_TAG "ICameraRecordingProxyListener" #include #include #include #include namespace android { enum { DATA_CALLBACK_TIMESTAMP = IBinder::FIRST_CALL_TRANSACTION, }; class BpCameraRecordingProxyListener: public BpInterface { public: BpCameraRecordingProxyListener(const sp& impl) : BpInterface(impl) { } void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp& imageData) { ALOGV("dataCallback"); Parcel data, reply; data.writeInterfaceToken(ICameraRecordingProxyListener::getInterfaceDescriptor()); data.writeInt64(timestamp); data.writeInt32(msgType); data.writeStrongBinder(IInterface::asBinder(imageData)); remote()->transact(DATA_CALLBACK_TIMESTAMP, data, &reply, IBinder::FLAG_ONEWAY); } }; IMPLEMENT_META_INTERFACE(CameraRecordingProxyListener, "android.hardware.ICameraRecordingProxyListener"); // ---------------------------------------------------------------------- status_t BnCameraRecordingProxyListener::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch(code) { case DATA_CALLBACK_TIMESTAMP: { ALOGV("DATA_CALLBACK_TIMESTAMP"); CHECK_INTERFACE(ICameraRecordingProxyListener, data, reply); nsecs_t timestamp = data.readInt64(); int32_t msgType = data.readInt32(); sp imageData = interface_cast(data.readStrongBinder()); dataCallbackTimestamp(timestamp, msgType, imageData); return NO_ERROR; } break; default: return BBinder::onTransact(code, data, reply, flags); } } // ---------------------------------------------------------------------------- }; // namespace android ================================================ FILE: libshims/ICameraService.cpp ================================================ /* ** ** Copyright 2008, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ #define LOG_TAG "BpCameraService" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace android { namespace { enum { EX_SECURITY = -1, EX_BAD_PARCELABLE = -2, EX_ILLEGAL_ARGUMENT = -3, EX_NULL_POINTER = -4, EX_ILLEGAL_STATE = -5, EX_HAS_REPLY_HEADER = -128, // special; see below }; static bool readExceptionCode(Parcel& reply) { int32_t exceptionCode = reply.readExceptionCode(); if (exceptionCode != 0) { const char* errorMsg; switch(exceptionCode) { case EX_SECURITY: errorMsg = "Security"; break; case EX_BAD_PARCELABLE: errorMsg = "BadParcelable"; break; case EX_NULL_POINTER: errorMsg = "NullPointer"; break; case EX_ILLEGAL_STATE: errorMsg = "IllegalState"; break; // Binder should be handling this code inside Parcel::readException // but lets have a to-string here anyway just in case. case EX_HAS_REPLY_HEADER: errorMsg = "HasReplyHeader"; break; default: errorMsg = "Unknown"; } ALOGE("Binder transmission error %s (%d)", errorMsg, exceptionCode); return true; } return false; } }; class BpCameraService: public BpInterface { public: BpCameraService(const sp& impl) : BpInterface(impl) { } // get number of cameras available that support standard camera operations virtual int32_t getNumberOfCameras() { return getNumberOfCameras(CAMERA_TYPE_BACKWARD_COMPATIBLE); } // get number of cameras available of a given type virtual int32_t getNumberOfCameras(int type) { Parcel data, reply; data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); data.writeInt32(type); remote()->transact(BnCameraService::GET_NUMBER_OF_CAMERAS, data, &reply); if (readExceptionCode(reply)) return 0; return reply.readInt32(); } // get information about a camera virtual status_t getCameraInfo(int cameraId, struct CameraInfo* cameraInfo) { Parcel data, reply; data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); data.writeInt32(cameraId); remote()->transact(BnCameraService::GET_CAMERA_INFO, data, &reply); if (readExceptionCode(reply)) return -EPROTO; status_t result = reply.readInt32(); if (reply.readInt32() != 0) { cameraInfo->facing = reply.readInt32(); cameraInfo->orientation = reply.readInt32(); } return result; } // get camera characteristics (static metadata) virtual status_t getCameraCharacteristics(int cameraId, CameraMetadata* cameraInfo) { Parcel data, reply; data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); data.writeInt32(cameraId); remote()->transact(BnCameraService::GET_CAMERA_CHARACTERISTICS, data, &reply); if (readExceptionCode(reply)) return -EPROTO; status_t result = reply.readInt32(); CameraMetadata out; if (reply.readInt32() != 0) { out.readFromParcel(&reply); } if (cameraInfo != NULL) { cameraInfo->swap(out); } return result; } // Get enumeration and description of vendor tags for camera virtual status_t getCameraVendorTagDescriptor(/*out*/sp& desc) { Parcel data, reply; data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); remote()->transact(BnCameraService::GET_CAMERA_VENDOR_TAG_DESCRIPTOR, data, &reply); if (readExceptionCode(reply)) return -EPROTO; status_t result = reply.readInt32(); if (reply.readInt32() != 0) { sp d; if (VendorTagDescriptor::createFromParcel(&reply, /*out*/d) == OK) { desc = d; } } return result; } // connect to camera service (android.hardware.Camera) virtual status_t connect(const sp& cameraClient, int cameraId, const String16 &clientPackageName, int clientUid, /*out*/ sp& device) { Parcel data, reply; data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); data.writeStrongBinder(IInterface::asBinder(cameraClient)); data.writeInt32(cameraId); data.writeString16(clientPackageName); data.writeInt32(clientUid); status_t status; status = remote()->transact(BnCameraService::CONNECT, data, &reply); if (status != OK) return status; if (readExceptionCode(reply)) return -EPROTO; status = reply.readInt32(); if (reply.readInt32() != 0) { device = interface_cast(reply.readStrongBinder()); } return status; } // connect to camera service (android.hardware.Camera) virtual status_t connectLegacy(const sp& cameraClient, int cameraId, int halVersion, const String16 &clientPackageName, int clientUid, /*out*/sp& device) { Parcel data, reply; data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); data.writeStrongBinder(IInterface::asBinder(cameraClient)); data.writeInt32(cameraId); data.writeInt32(halVersion); data.writeString16(clientPackageName); data.writeInt32(clientUid); status_t status; status = remote()->transact(BnCameraService::CONNECT_LEGACY, data, &reply); if (status != OK) return status; if (readExceptionCode(reply)) return -EPROTO; status = reply.readInt32(); if (reply.readInt32() != 0) { device = interface_cast(reply.readStrongBinder()); } return status; } virtual status_t setTorchMode(const String16& cameraId, bool enabled, const sp& clientBinder) { Parcel data, reply; data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); data.writeString16(cameraId); data.writeInt32(enabled ? 1 : 0); data.writeStrongBinder(clientBinder); remote()->transact(BnCameraService::SET_TORCH_MODE, data, &reply); if (readExceptionCode(reply)) return -EPROTO; return reply.readInt32(); } // connect to camera service (android.hardware.camera2.CameraDevice) virtual status_t connectDevice( const sp& cameraCb, int cameraId, const String16& clientPackageName, int clientUid, /*out*/ sp& device) { Parcel data, reply; data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); data.writeStrongBinder(IInterface::asBinder(cameraCb)); data.writeInt32(cameraId); data.writeString16(clientPackageName); data.writeInt32(clientUid); status_t status; status = remote()->transact(BnCameraService::CONNECT_DEVICE, data, &reply); if (status != OK) return status; if (readExceptionCode(reply)) return -EPROTO; status = reply.readInt32(); if (reply.readInt32() != 0) { device = interface_cast(reply.readStrongBinder()); } return status; } virtual status_t addListener(const sp& listener) { Parcel data, reply; data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); data.writeStrongBinder(IInterface::asBinder(listener)); remote()->transact(BnCameraService::ADD_LISTENER, data, &reply); if (readExceptionCode(reply)) return -EPROTO; return reply.readInt32(); } virtual status_t removeListener(const sp& listener) { Parcel data, reply; data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); data.writeStrongBinder(IInterface::asBinder(listener)); remote()->transact(BnCameraService::REMOVE_LISTENER, data, &reply); if (readExceptionCode(reply)) return -EPROTO; return reply.readInt32(); } virtual status_t getLegacyParameters(int cameraId, String16* parameters) { if (parameters == NULL) { ALOGE("%s: parameters must not be null", __FUNCTION__); return BAD_VALUE; } Parcel data, reply; data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); data.writeInt32(cameraId); remote()->transact(BnCameraService::GET_LEGACY_PARAMETERS, data, &reply); if (readExceptionCode(reply)) return -EPROTO; status_t res = data.readInt32(); int32_t length = data.readInt32(); // -1 means null if (length > 0) { *parameters = data.readString16(); } else { *parameters = String16(); } return res; } virtual status_t supportsCameraApi(int cameraId, int apiVersion) { Parcel data, reply; data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); data.writeInt32(cameraId); data.writeInt32(apiVersion); remote()->transact(BnCameraService::SUPPORTS_CAMERA_API, data, &reply); if (readExceptionCode(reply)) return -EPROTO; status_t res = data.readInt32(); return res; } virtual void notifySystemEvent(int32_t eventId, const int32_t* args, size_t len) { Parcel data, reply; data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); data.writeInt32(eventId); data.writeInt32Array(len, args); remote()->transact(BnCameraService::NOTIFY_SYSTEM_EVENT, data, &reply, IBinder::FLAG_ONEWAY); } }; IMPLEMENT_META_INTERFACE(CameraService, "android.hardware.ICameraService"); // ---------------------------------------------------------------------- status_t BnCameraService::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch(code) { case GET_NUMBER_OF_CAMERAS: { CHECK_INTERFACE(ICameraService, data, reply); reply->writeNoException(); reply->writeInt32(getNumberOfCameras(data.readInt32())); return NO_ERROR; } break; case GET_CAMERA_INFO: { CHECK_INTERFACE(ICameraService, data, reply); CameraInfo cameraInfo = CameraInfo(); memset(&cameraInfo, 0, sizeof(cameraInfo)); status_t result = getCameraInfo(data.readInt32(), &cameraInfo); reply->writeNoException(); reply->writeInt32(result); // Fake a parcelable object here reply->writeInt32(1); // means the parcelable is included reply->writeInt32(cameraInfo.facing); reply->writeInt32(cameraInfo.orientation); return NO_ERROR; } break; case GET_CAMERA_CHARACTERISTICS: { CHECK_INTERFACE(ICameraService, data, reply); CameraMetadata info; status_t result = getCameraCharacteristics(data.readInt32(), &info); reply->writeNoException(); reply->writeInt32(result); // out-variables are after exception and return value reply->writeInt32(1); // means the parcelable is included info.writeToParcel(reply); return NO_ERROR; } break; case GET_CAMERA_VENDOR_TAG_DESCRIPTOR: { CHECK_INTERFACE(ICameraService, data, reply); sp d; status_t result = getCameraVendorTagDescriptor(d); reply->writeNoException(); reply->writeInt32(result); // out-variables are after exception and return value if (d == NULL) { reply->writeInt32(0); } else { reply->writeInt32(1); // means the parcelable is included d->writeToParcel(reply); } return NO_ERROR; } break; case CONNECT: { CHECK_INTERFACE(ICameraService, data, reply); sp cameraClient = interface_cast(data.readStrongBinder()); int32_t cameraId = data.readInt32(); const String16 clientName = data.readString16(); int32_t clientUid = data.readInt32(); sp camera; status_t status = connect(cameraClient, cameraId, clientName, clientUid, /*out*/camera); reply->writeNoException(); reply->writeInt32(status); if (camera != NULL) { reply->writeInt32(1); reply->writeStrongBinder(IInterface::asBinder(camera)); } else { reply->writeInt32(0); } return NO_ERROR; } break; case CONNECT_DEVICE: { CHECK_INTERFACE(ICameraService, data, reply); sp cameraClient = interface_cast(data.readStrongBinder()); int32_t cameraId = data.readInt32(); const String16 clientName = data.readString16(); int32_t clientUid = data.readInt32(); sp camera; status_t status = connectDevice(cameraClient, cameraId, clientName, clientUid, /*out*/camera); reply->writeNoException(); reply->writeInt32(status); if (camera != NULL) { reply->writeInt32(1); reply->writeStrongBinder(IInterface::asBinder(camera)); } else { reply->writeInt32(0); } return NO_ERROR; } break; case ADD_LISTENER: { CHECK_INTERFACE(ICameraService, data, reply); sp listener = interface_cast(data.readStrongBinder()); reply->writeNoException(); reply->writeInt32(addListener(listener)); return NO_ERROR; } break; case REMOVE_LISTENER: { CHECK_INTERFACE(ICameraService, data, reply); sp listener = interface_cast(data.readStrongBinder()); reply->writeNoException(); reply->writeInt32(removeListener(listener)); return NO_ERROR; } break; case GET_LEGACY_PARAMETERS: { CHECK_INTERFACE(ICameraService, data, reply); int cameraId = data.readInt32(); String16 parameters; reply->writeNoException(); // return value reply->writeInt32(getLegacyParameters(cameraId, ¶meters)); // out parameters reply->writeInt32(1); // parameters is always available reply->writeString16(parameters); return NO_ERROR; } break; case SUPPORTS_CAMERA_API: { CHECK_INTERFACE(ICameraService, data, reply); int cameraId = data.readInt32(); int apiVersion = data.readInt32(); reply->writeNoException(); // return value reply->writeInt32(supportsCameraApi(cameraId, apiVersion)); return NO_ERROR; } break; case CONNECT_LEGACY: { CHECK_INTERFACE(ICameraService, data, reply); sp cameraClient = interface_cast(data.readStrongBinder()); int32_t cameraId = data.readInt32(); int32_t halVersion = data.readInt32(); const String16 clientName = data.readString16(); int32_t clientUid = data.readInt32(); sp camera; status_t status = connectLegacy(cameraClient, cameraId, halVersion, clientName, clientUid, /*out*/camera); reply->writeNoException(); reply->writeInt32(status); if (camera != NULL) { reply->writeInt32(1); reply->writeStrongBinder(IInterface::asBinder(camera)); } else { reply->writeInt32(0); } return NO_ERROR; } break; case SET_TORCH_MODE: { CHECK_INTERFACE(ICameraService, data, reply); String16 cameraId = data.readString16(); bool enabled = data.readInt32() != 0 ? true : false; const sp clientBinder = data.readStrongBinder(); status_t status = setTorchMode(cameraId, enabled, clientBinder); reply->writeNoException(); reply->writeInt32(status); return NO_ERROR; } break; case NOTIFY_SYSTEM_EVENT: { CHECK_INTERFACE(ICameraService, data, reply); int32_t eventId = data.readInt32(); int32_t len = data.readInt32(); if (len < 0) { ALOGE("%s: Received poorly formatted length in binder request: notifySystemEvent.", __FUNCTION__); return FAILED_TRANSACTION; } if (len > 512) { ALOGE("%s: Length %" PRIi32 " too long in binder request: notifySystemEvent.", __FUNCTION__, len); return FAILED_TRANSACTION; } int32_t events[len]; memset(events, 0, sizeof(int32_t) * len); status_t status = data.read(events, sizeof(int32_t) * len); if (status != NO_ERROR) { ALOGE("%s: Received poorly formatted binder request: notifySystemEvent.", __FUNCTION__); return FAILED_TRANSACTION; } notifySystemEvent(eventId, events, len); return NO_ERROR; } break; default: return BBinder::onTransact(code, data, reply, flags); } } // ---------------------------------------------------------------------------- }; // namespace android ================================================ FILE: libshims/ICameraServiceListener.cpp ================================================ /* ** ** Copyright 2013, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ #include #include #include #include #include #include namespace android { namespace { enum { STATUS_CHANGED = IBinder::FIRST_CALL_TRANSACTION, TORCH_STATUS_CHANGED, }; }; // namespace anonymous class BpCameraServiceListener: public BpInterface { public: BpCameraServiceListener(const sp& impl) : BpInterface(impl) { } virtual void onStatusChanged(Status status, int32_t cameraId) { Parcel data, reply; data.writeInterfaceToken(ICameraServiceListener::getInterfaceDescriptor()); data.writeInt32(static_cast(status)); data.writeInt32(cameraId); remote()->transact(STATUS_CHANGED, data, &reply, IBinder::FLAG_ONEWAY); } virtual void onTorchStatusChanged(TorchStatus status, const String16 &cameraId) { Parcel data, reply; data.writeInterfaceToken(ICameraServiceListener::getInterfaceDescriptor()); data.writeInt32(static_cast(status)); data.writeString16(cameraId); remote()->transact(TORCH_STATUS_CHANGED, data, &reply, IBinder::FLAG_ONEWAY); } }; IMPLEMENT_META_INTERFACE(CameraServiceListener, "android.hardware.ICameraServiceListener"); // ---------------------------------------------------------------------- status_t BnCameraServiceListener::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch(code) { case STATUS_CHANGED: { CHECK_INTERFACE(ICameraServiceListener, data, reply); Status status = static_cast(data.readInt32()); int32_t cameraId = data.readInt32(); onStatusChanged(status, cameraId); return NO_ERROR; } break; case TORCH_STATUS_CHANGED: { CHECK_INTERFACE(ICameraServiceListener, data, reply); TorchStatus status = static_cast(data.readInt32()); String16 cameraId = data.readString16(); onTorchStatusChanged(status, cameraId); return NO_ERROR; } break; default: return BBinder::onTransact(code, data, reply, flags); } } // ---------------------------------------------------------------------------- }; // namespace android ================================================ FILE: libshims/ICameraServiceProxy.cpp ================================================ /* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "BpCameraServiceProxy" #include #include #include namespace android { class BpCameraServiceProxy: public BpInterface { public: BpCameraServiceProxy(const sp& impl) : BpInterface(impl) {} virtual void pingForUserUpdate() { Parcel data; data.writeInterfaceToken(ICameraServiceProxy::getInterfaceDescriptor()); remote()->transact(BnCameraServiceProxy::PING_FOR_USER_UPDATE, data, nullptr, IBinder::FLAG_ONEWAY); } virtual void notifyCameraState(String16 cameraId, CameraState newCameraState) { Parcel data; data.writeInterfaceToken(ICameraServiceProxy::getInterfaceDescriptor()); data.writeString16(cameraId); data.writeInt32(newCameraState); remote()->transact(BnCameraServiceProxy::NOTIFY_CAMERA_STATE, data, nullptr, IBinder::FLAG_ONEWAY); } }; IMPLEMENT_META_INTERFACE(CameraServiceProxy, "android.hardware.ICameraServiceProxy"); status_t BnCameraServiceProxy::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch(code) { case PING_FOR_USER_UPDATE: { CHECK_INTERFACE(ICameraServiceProxy, data, reply); pingForUserUpdate(); return NO_ERROR; } break; case NOTIFY_CAMERA_STATE: { CHECK_INTERFACE(ICameraServiceProxy, data, reply); String16 cameraId = data.readString16(); CameraState newCameraState = static_cast(data.readInt32()); notifyCameraState(cameraId, newCameraState); return NO_ERROR; } break; default: return BBinder::onTransact(code, data, reply, flags); } } }; // namespace android ================================================ FILE: libshims/VendorTagDescriptor.cpp ================================================ /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "VendorTagDescriptor" #include #include #include #include #include #include #include #include #include "camera/VendorTagDescriptor.h" #include #include namespace android { extern "C" { static int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* v); static void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* v, uint32_t* tagArray); static const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* v, uint32_t tag); static const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* v, uint32_t tag); static int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* v, uint32_t tag); } /* extern "C" */ static Mutex sLock; static sp sGlobalVendorTagDescriptor; VendorTagDescriptor::VendorTagDescriptor() {} VendorTagDescriptor::~VendorTagDescriptor() { size_t len = mReverseMapping.size(); for (size_t i = 0; i < len; ++i) { delete mReverseMapping[i]; } } status_t VendorTagDescriptor::createDescriptorFromOps(const vendor_tag_ops_t* vOps, /*out*/ sp& descriptor) { if (vOps == NULL) { ALOGE("%s: vendor_tag_ops argument was NULL.", __FUNCTION__); return BAD_VALUE; } int tagCount = vOps->get_tag_count(vOps); if (tagCount < 0 || tagCount > INT32_MAX) { ALOGE("%s: tag count %d from vendor ops is invalid.", __FUNCTION__, tagCount); return BAD_VALUE; } Vector tagArray; LOG_ALWAYS_FATAL_IF(tagArray.resize(tagCount) != tagCount, "%s: too many (%u) vendor tags defined.", __FUNCTION__, tagCount); vOps->get_all_tags(vOps, /*out*/tagArray.editArray()); sp desc = new VendorTagDescriptor(); desc->mTagCount = tagCount; SortedVector sections; KeyedVector tagToSectionMap; for (size_t i = 0; i < static_cast(tagCount); ++i) { uint32_t tag = tagArray[i]; if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) { ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag); return BAD_VALUE; } const char *tagName = vOps->get_tag_name(vOps, tag); if (tagName == NULL) { ALOGE("%s: no tag name defined for vendor tag %d.", __FUNCTION__, tag); return BAD_VALUE; } desc->mTagToNameMap.add(tag, String8(tagName)); const char *sectionName = vOps->get_section_name(vOps, tag); if (sectionName == NULL) { ALOGE("%s: no section name defined for vendor tag %d.", __FUNCTION__, tag); return BAD_VALUE; } String8 sectionString(sectionName); sections.add(sectionString); tagToSectionMap.add(tag, sectionString); int tagType = vOps->get_tag_type(vOps, tag); if (tagType < 0 || tagType >= NUM_TYPES) { ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType); return BAD_VALUE; } desc->mTagToTypeMap.add(tag, tagType); } desc->mSections = sections; for (size_t i = 0; i < static_cast(tagCount); ++i) { uint32_t tag = tagArray[i]; String8 sectionString = tagToSectionMap.valueFor(tag); // Set up tag to section index map ssize_t index = sections.indexOf(sectionString); LOG_ALWAYS_FATAL_IF(index < 0, "index %zd must be non-negative", index); desc->mTagToSectionMap.add(tag, static_cast(index)); // Set up reverse mapping ssize_t reverseIndex = -1; if ((reverseIndex = desc->mReverseMapping.indexOfKey(sectionString)) < 0) { KeyedVector* nameMapper = new KeyedVector(); reverseIndex = desc->mReverseMapping.add(sectionString, nameMapper); } desc->mReverseMapping[reverseIndex]->add(desc->mTagToNameMap.valueFor(tag), tag); } descriptor = desc; return OK; } status_t VendorTagDescriptor::createFromParcel(const Parcel* parcel, /*out*/ sp& descriptor) { status_t res = OK; if (parcel == NULL) { ALOGE("%s: parcel argument was NULL.", __FUNCTION__); return BAD_VALUE; } int32_t tagCount = 0; if ((res = parcel->readInt32(&tagCount)) != OK) { ALOGE("%s: could not read tag count from parcel", __FUNCTION__); return res; } if (tagCount < 0 || tagCount > INT32_MAX) { ALOGE("%s: tag count %d from vendor ops is invalid.", __FUNCTION__, tagCount); return BAD_VALUE; } sp desc = new VendorTagDescriptor(); desc->mTagCount = tagCount; uint32_t tag, sectionIndex; uint32_t maxSectionIndex = 0; int32_t tagType; Vector allTags; for (int32_t i = 0; i < tagCount; ++i) { if ((res = parcel->readInt32(reinterpret_cast(&tag))) != OK) { ALOGE("%s: could not read tag id from parcel for index %d", __FUNCTION__, i); break; } if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) { ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag); res = BAD_VALUE; break; } if ((res = parcel->readInt32(&tagType)) != OK) { ALOGE("%s: could not read tag type from parcel for tag %d", __FUNCTION__, tag); break; } if (tagType < 0 || tagType >= NUM_TYPES) { ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType); res = BAD_VALUE; break; } String8 tagName = parcel->readString8(); if (tagName.isEmpty()) { ALOGE("%s: parcel tag name was NULL for tag %d.", __FUNCTION__, tag); res = NOT_ENOUGH_DATA; break; } if ((res = parcel->readInt32(reinterpret_cast(§ionIndex))) != OK) { ALOGE("%s: could not read section index for tag %d.", __FUNCTION__, tag); break; } maxSectionIndex = (maxSectionIndex >= sectionIndex) ? maxSectionIndex : sectionIndex; allTags.add(tag); desc->mTagToNameMap.add(tag, tagName); desc->mTagToSectionMap.add(tag, sectionIndex); desc->mTagToTypeMap.add(tag, tagType); } if (res != OK) { return res; } size_t sectionCount = 0; if (tagCount > 0) { if ((res = parcel->readInt32(reinterpret_cast(§ionCount))) != OK) { ALOGE("%s: could not read section count for.", __FUNCTION__); return res; } if (sectionCount < (maxSectionIndex + 1)) { ALOGE("%s: Incorrect number of sections defined, received %zu, needs %d.", __FUNCTION__, sectionCount, (maxSectionIndex + 1)); return BAD_VALUE; } LOG_ALWAYS_FATAL_IF(desc->mSections.setCapacity(sectionCount) <= 0, "Vector capacity must be positive"); for (size_t i = 0; i < sectionCount; ++i) { String8 sectionName = parcel->readString8(); if (sectionName.isEmpty()) { ALOGE("%s: parcel section name was NULL for section %zu.", __FUNCTION__, i); return NOT_ENOUGH_DATA; } desc->mSections.add(sectionName); } } LOG_ALWAYS_FATAL_IF(static_cast(tagCount) != allTags.size(), "tagCount must be the same as allTags size"); // Set up reverse mapping for (size_t i = 0; i < static_cast(tagCount); ++i) { uint32_t tag = allTags[i]; String8 sectionString = desc->mSections[desc->mTagToSectionMap.valueFor(tag)]; ssize_t reverseIndex = -1; if ((reverseIndex = desc->mReverseMapping.indexOfKey(sectionString)) < 0) { KeyedVector* nameMapper = new KeyedVector(); reverseIndex = desc->mReverseMapping.add(sectionString, nameMapper); } desc->mReverseMapping[reverseIndex]->add(desc->mTagToNameMap.valueFor(tag), tag); } descriptor = desc; return res; } int VendorTagDescriptor::getTagCount() const { size_t size = mTagToNameMap.size(); if (size == 0) { return VENDOR_TAG_COUNT_ERR; } return size; } void VendorTagDescriptor::getTagArray(uint32_t* tagArray) const { size_t size = mTagToNameMap.size(); for (size_t i = 0; i < size; ++i) { tagArray[i] = mTagToNameMap.keyAt(i); } } const char* VendorTagDescriptor::getSectionName(uint32_t tag) const { ssize_t index = mTagToSectionMap.indexOfKey(tag); if (index < 0) { return VENDOR_SECTION_NAME_ERR; } return mSections[mTagToSectionMap.valueAt(index)].string(); } const char* VendorTagDescriptor::getTagName(uint32_t tag) const { ssize_t index = mTagToNameMap.indexOfKey(tag); if (index < 0) { return VENDOR_TAG_NAME_ERR; } return mTagToNameMap.valueAt(index).string(); } int VendorTagDescriptor::getTagType(uint32_t tag) const { ssize_t index = mTagToNameMap.indexOfKey(tag); if (index < 0) { return VENDOR_TAG_TYPE_ERR; } return mTagToTypeMap.valueFor(tag); } status_t VendorTagDescriptor::writeToParcel(Parcel* parcel) const { status_t res = OK; if (parcel == NULL) { ALOGE("%s: parcel argument was NULL.", __FUNCTION__); return BAD_VALUE; } if ((res = parcel->writeInt32(mTagCount)) != OK) { return res; } size_t size = mTagToNameMap.size(); uint32_t tag, sectionIndex; int32_t tagType; for (size_t i = 0; i < size; ++i) { tag = mTagToNameMap.keyAt(i); String8 tagName = mTagToNameMap[i]; sectionIndex = mTagToSectionMap.valueFor(tag); tagType = mTagToTypeMap.valueFor(tag); if ((res = parcel->writeInt32(tag)) != OK) break; if ((res = parcel->writeInt32(tagType)) != OK) break; if ((res = parcel->writeString8(tagName)) != OK) break; if ((res = parcel->writeInt32(sectionIndex)) != OK) break; } size_t numSections = mSections.size(); if (numSections > 0) { if ((res = parcel->writeInt32(numSections)) != OK) return res; for (size_t i = 0; i < numSections; ++i) { if ((res = parcel->writeString8(mSections[i])) != OK) return res; } } return res; } SortedVector VendorTagDescriptor::getAllSectionNames() const { return mSections; } status_t VendorTagDescriptor::lookupTag(String8 name, String8 section, /*out*/uint32_t* tag) const { ssize_t index = mReverseMapping.indexOfKey(section); if (index < 0) { ALOGE("%s: Section '%s' does not exist.", __FUNCTION__, section.string()); return BAD_VALUE; } ssize_t nameIndex = mReverseMapping[index]->indexOfKey(name); if (nameIndex < 0) { ALOGE("%s: Tag name '%s' does not exist.", __FUNCTION__, name.string()); return BAD_VALUE; } if (tag != NULL) { *tag = mReverseMapping[index]->valueAt(nameIndex); } return OK; } void VendorTagDescriptor::dump(int fd, int verbosity, int indentation) const { size_t size = mTagToNameMap.size(); if (size == 0) { dprintf(fd, "%*sDumping configured vendor tag descriptors: None set\n", indentation, ""); return; } dprintf(fd, "%*sDumping configured vendor tag descriptors: %zu entries\n", indentation, "", size); for (size_t i = 0; i < size; ++i) { uint32_t tag = mTagToNameMap.keyAt(i); if (verbosity < 1) { dprintf(fd, "%*s0x%x\n", indentation + 2, "", tag); continue; } String8 name = mTagToNameMap.valueAt(i); uint32_t sectionId = mTagToSectionMap.valueFor(tag); String8 sectionName = mSections[sectionId]; int type = mTagToTypeMap.valueFor(tag); const char* typeName = (type >= 0 && type < NUM_TYPES) ? camera_metadata_type_names[type] : "UNKNOWN"; dprintf(fd, "%*s0x%x (%s) with type %d (%s) defined in section %s\n", indentation + 2, "", tag, name.string(), type, typeName, sectionName.string()); } } status_t VendorTagDescriptor::setAsGlobalVendorTagDescriptor(const sp& desc) { status_t res = OK; Mutex::Autolock al(sLock); sGlobalVendorTagDescriptor = desc; vendor_tag_ops_t* opsPtr = NULL; if (desc != NULL) { opsPtr = &(desc->mVendorOps); opsPtr->get_tag_count = vendor_tag_descriptor_get_tag_count; opsPtr->get_all_tags = vendor_tag_descriptor_get_all_tags; opsPtr->get_section_name = vendor_tag_descriptor_get_section_name; opsPtr->get_tag_name = vendor_tag_descriptor_get_tag_name; opsPtr->get_tag_type = vendor_tag_descriptor_get_tag_type; } if((res = set_camera_metadata_vendor_ops(opsPtr)) != OK) { ALOGE("%s: Could not set vendor tag descriptor, received error %s (%d)." , __FUNCTION__, strerror(-res), res); } return res; } void VendorTagDescriptor::clearGlobalVendorTagDescriptor() { Mutex::Autolock al(sLock); set_camera_metadata_vendor_ops(NULL); sGlobalVendorTagDescriptor.clear(); } sp VendorTagDescriptor::getGlobalVendorTagDescriptor() { Mutex::Autolock al(sLock); return sGlobalVendorTagDescriptor; } extern "C" { int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* /*v*/) { Mutex::Autolock al(sLock); if (sGlobalVendorTagDescriptor == NULL) { ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__); return VENDOR_TAG_COUNT_ERR; } return sGlobalVendorTagDescriptor->getTagCount(); } void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* /*v*/, uint32_t* tagArray) { Mutex::Autolock al(sLock); if (sGlobalVendorTagDescriptor == NULL) { ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__); return; } sGlobalVendorTagDescriptor->getTagArray(tagArray); } const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* /*v*/, uint32_t tag) { Mutex::Autolock al(sLock); if (sGlobalVendorTagDescriptor == NULL) { ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__); return VENDOR_SECTION_NAME_ERR; } return sGlobalVendorTagDescriptor->getSectionName(tag); } const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* /*v*/, uint32_t tag) { Mutex::Autolock al(sLock); if (sGlobalVendorTagDescriptor == NULL) { ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__); return VENDOR_TAG_NAME_ERR; } return sGlobalVendorTagDescriptor->getTagName(tag); } int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* /*v*/, uint32_t tag) { Mutex::Autolock al(sLock); if (sGlobalVendorTagDescriptor == NULL) { ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__); return VENDOR_TAG_TYPE_ERR; } return sGlobalVendorTagDescriptor->getTagType(tag); } } /* extern "C" */ } /* namespace android */ ================================================ FILE: libshims/camera.cpp ================================================ /* * Copyright (C) 2016 The CyanogenMod Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include extern "C" { extern ssize_t _ZN7android13SensorManager13getSensorListEPPKPKNS_6SensorE(void*, void*); ssize_t _ZNK7android13SensorManager13getSensorListEPPKPKNS_6SensorE(void* thiz, void* list) { return _ZN7android13SensorManager13getSensorListEPPKPKNS_6SensorE(thiz, list); } } // GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, // uint32_t inUsage, std::string requestorName = ""); extern "C" void _ZN7android13GraphicBufferC1EjjijNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE( uint32_t inWidth, uint32_t inHeight, int inFormat, uint32_t inUsage, std::string requestorName); extern "C" void _ZN7android13GraphicBufferC1Ejjij( uint32_t inWidth, uint32_t inHeight, int inFormat, uint32_t inUsage) { std::string requestorName = ""; _ZN7android13GraphicBufferC1EjjijNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE( inWidth, inHeight, inFormat, inUsage, requestorName); } ================================================ FILE: libshims/camera2/CaptureRequest.cpp ================================================ /* ** ** Copyright 2013, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ // #define LOG_NDEBUG 0 #define LOG_TAG "CameraRequest" #include #include #include #include namespace android { status_t CaptureRequest::readFromParcel(Parcel* parcel) { if (parcel == NULL) { ALOGE("%s: Null parcel", __FUNCTION__); return BAD_VALUE; } mMetadata.clear(); mSurfaceList.clear(); status_t err; if ((err = mMetadata.readFromParcel(parcel)) != OK) { ALOGE("%s: Failed to read metadata from parcel", __FUNCTION__); return err; } ALOGV("%s: Read metadata from parcel", __FUNCTION__); int32_t size; if ((err = parcel->readInt32(&size)) != OK) { ALOGE("%s: Failed to read surface list size from parcel", __FUNCTION__); return err; } ALOGV("%s: Read surface list size = %d", __FUNCTION__, size); // Do not distinguish null arrays from 0-sized arrays. for (int i = 0; i < size; ++i) { // Parcel.writeParcelableArray size_t len; const char16_t* className = parcel->readString16Inplace(&len); ALOGV("%s: Read surface class = %s", __FUNCTION__, className != NULL ? String8(className).string() : ""); if (className == NULL) { continue; } // Surface.writeToParcel const char16_t* name = parcel->readString16Inplace(&len); ALOGV("%s: Read surface name = %s", __FUNCTION__, name != NULL ? String8(name).string() : ""); sp binder(parcel->readStrongBinder()); ALOGV("%s: Read surface binder = %p", __FUNCTION__, binder.get()); sp surface; if (binder != NULL) { sp gbp = interface_cast(binder); surface = new Surface(gbp); } mSurfaceList.push_back(surface); } int isReprocess = 0; if ((err = parcel->readInt32(&isReprocess)) != OK) { ALOGE("%s: Failed to read reprocessing from parcel", __FUNCTION__); return err; } mIsReprocess = (isReprocess != 0); return OK; } status_t CaptureRequest::writeToParcel(Parcel* parcel) const { if (parcel == NULL) { ALOGE("%s: Null parcel", __FUNCTION__); return BAD_VALUE; } status_t err; if ((err = mMetadata.writeToParcel(parcel)) != OK) { return err; } int32_t size = static_cast(mSurfaceList.size()); // Send 0-sized arrays when it's empty. Do not send null arrays. parcel->writeInt32(size); for (int32_t i = 0; i < size; ++i) { sp surface = mSurfaceList[i]; sp binder; if (surface != 0) { binder = IInterface::asBinder(surface->getIGraphicBufferProducer()); } // not sure if readParcelableArray does this, hard to tell from source parcel->writeString16(String16("android.view.Surface")); // Surface.writeToParcel parcel->writeString16(String16("unknown_name")); // Surface.nativeWriteToParcel parcel->writeStrongBinder(binder); } parcel->writeInt32(mIsReprocess ? 1 : 0); return OK; } }; // namespace android ================================================ FILE: libshims/camera2/ICameraDeviceCallbacks.cpp ================================================ /* ** ** Copyright 2013, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ //#define LOG_NDEBUG 0 #define LOG_TAG "ICameraDeviceCallbacks" #include #include #include #include #include #include #include #include #include "camera/CameraMetadata.h" #include "camera/CaptureResult.h" namespace android { enum { CAMERA_ERROR = IBinder::FIRST_CALL_TRANSACTION, CAMERA_IDLE, CAPTURE_STARTED, RESULT_RECEIVED, PREPARED }; class BpCameraDeviceCallbacks: public BpInterface { public: BpCameraDeviceCallbacks(const sp& impl) : BpInterface(impl) { } void onDeviceError(CameraErrorCode errorCode, const CaptureResultExtras& resultExtras) { ALOGV("onDeviceError"); Parcel data, reply; data.writeInterfaceToken(ICameraDeviceCallbacks::getInterfaceDescriptor()); data.writeInt32(static_cast(errorCode)); data.writeInt32(1); // to mark presence of CaptureResultExtras object resultExtras.writeToParcel(&data); remote()->transact(CAMERA_ERROR, data, &reply, IBinder::FLAG_ONEWAY); data.writeNoException(); } void onDeviceIdle() { ALOGV("onDeviceIdle"); Parcel data, reply; data.writeInterfaceToken(ICameraDeviceCallbacks::getInterfaceDescriptor()); remote()->transact(CAMERA_IDLE, data, &reply, IBinder::FLAG_ONEWAY); data.writeNoException(); } void onCaptureStarted(const CaptureResultExtras& result, int64_t timestamp) { ALOGV("onCaptureStarted"); Parcel data, reply; data.writeInterfaceToken(ICameraDeviceCallbacks::getInterfaceDescriptor()); data.writeInt32(1); // to mark presence of CaptureResultExtras object result.writeToParcel(&data); data.writeInt64(timestamp); remote()->transact(CAPTURE_STARTED, data, &reply, IBinder::FLAG_ONEWAY); data.writeNoException(); } void onResultReceived(const CameraMetadata& metadata, const CaptureResultExtras& resultExtras) { ALOGV("onResultReceived"); Parcel data, reply; data.writeInterfaceToken(ICameraDeviceCallbacks::getInterfaceDescriptor()); data.writeInt32(1); // to mark presence of metadata object metadata.writeToParcel(&data); data.writeInt32(1); // to mark presence of CaptureResult object resultExtras.writeToParcel(&data); remote()->transact(RESULT_RECEIVED, data, &reply, IBinder::FLAG_ONEWAY); data.writeNoException(); } void onPrepared(int streamId) { ALOGV("onPrepared"); Parcel data, reply; data.writeInterfaceToken(ICameraDeviceCallbacks::getInterfaceDescriptor()); data.writeInt32(streamId); remote()->transact(PREPARED, data, &reply, IBinder::FLAG_ONEWAY); data.writeNoException(); } }; IMPLEMENT_META_INTERFACE(CameraDeviceCallbacks, "android.hardware.camera2.ICameraDeviceCallbacks"); // ---------------------------------------------------------------------- status_t BnCameraDeviceCallbacks::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { ALOGV("onTransact - code = %d", code); switch(code) { case CAMERA_ERROR: { ALOGV("onDeviceError"); CHECK_INTERFACE(ICameraDeviceCallbacks, data, reply); CameraErrorCode errorCode = static_cast(data.readInt32()); CaptureResultExtras resultExtras; if (data.readInt32() != 0) { resultExtras.readFromParcel(const_cast(&data)); } else { ALOGE("No CaptureResultExtras object is present!"); } onDeviceError(errorCode, resultExtras); data.readExceptionCode(); return NO_ERROR; } break; case CAMERA_IDLE: { ALOGV("onDeviceIdle"); CHECK_INTERFACE(ICameraDeviceCallbacks, data, reply); onDeviceIdle(); data.readExceptionCode(); return NO_ERROR; } break; case CAPTURE_STARTED: { ALOGV("onCaptureStarted"); CHECK_INTERFACE(ICameraDeviceCallbacks, data, reply); CaptureResultExtras result; if (data.readInt32() != 0) { result.readFromParcel(const_cast(&data)); } else { ALOGE("No CaptureResultExtras object is present in result!"); } int64_t timestamp = data.readInt64(); onCaptureStarted(result, timestamp); data.readExceptionCode(); return NO_ERROR; } break; case RESULT_RECEIVED: { ALOGV("onResultReceived"); CHECK_INTERFACE(ICameraDeviceCallbacks, data, reply); CameraMetadata metadata; if (data.readInt32() != 0) { metadata.readFromParcel(const_cast(&data)); } else { ALOGW("No metadata object is present in result"); } CaptureResultExtras resultExtras; if (data.readInt32() != 0) { resultExtras.readFromParcel(const_cast(&data)); } else { ALOGW("No capture result extras object is present in result"); } onResultReceived(metadata, resultExtras); data.readExceptionCode(); return NO_ERROR; } break; case PREPARED: { ALOGV("onPrepared"); CHECK_INTERFACE(ICameraDeviceCallbacks, data, reply); CaptureResultExtras result; int streamId = data.readInt32(); onPrepared(streamId); data.readExceptionCode(); return NO_ERROR; } break; default: return BBinder::onTransact(code, data, reply, flags); } } // ---------------------------------------------------------------------------- }; // namespace android ================================================ FILE: libshims/camera2/ICameraDeviceUser.cpp ================================================ /* ** ** Copyright 2013, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ // #define LOG_NDEBUG 0 #define LOG_TAG "ICameraDeviceUser" #include #include #include #include #include #include #include #include #include #include namespace android { typedef Parcel::WritableBlob WritableBlob; typedef Parcel::ReadableBlob ReadableBlob; enum { DISCONNECT = IBinder::FIRST_CALL_TRANSACTION, SUBMIT_REQUEST, SUBMIT_REQUEST_LIST, CANCEL_REQUEST, BEGIN_CONFIGURE, END_CONFIGURE, DELETE_STREAM, CREATE_STREAM, CREATE_INPUT_STREAM, GET_INPUT_SURFACE, CREATE_DEFAULT_REQUEST, GET_CAMERA_INFO, WAIT_UNTIL_IDLE, FLUSH, PREPARE, TEAR_DOWN, PREPARE2 }; namespace { // Read empty strings without printing a false error message. String16 readMaybeEmptyString16(const Parcel& parcel) { size_t len; const char16_t* str = parcel.readString16Inplace(&len); if (str != NULL) { return String16(str, len); } else { return String16(); } } }; class BpCameraDeviceUser : public BpInterface { public: BpCameraDeviceUser(const sp& impl) : BpInterface(impl) { } // disconnect from camera service void disconnect() { ALOGV("disconnect"); Parcel data, reply; data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor()); remote()->transact(DISCONNECT, data, &reply); reply.readExceptionCode(); } virtual int submitRequest(sp request, bool repeating, int64_t *lastFrameNumber) { Parcel data, reply; data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor()); // arg0 = CaptureRequest if (request != 0) { data.writeInt32(1); request->writeToParcel(&data); } else { data.writeInt32(0); } // arg1 = streaming (bool) data.writeInt32(repeating); remote()->transact(SUBMIT_REQUEST, data, &reply); reply.readExceptionCode(); status_t res = reply.readInt32(); status_t resFrameNumber = BAD_VALUE; if (reply.readInt32() != 0) { if (lastFrameNumber != NULL) { resFrameNumber = reply.readInt64(lastFrameNumber); } } if (res < 0 || (resFrameNumber != NO_ERROR)) { res = FAILED_TRANSACTION; } return res; } virtual int submitRequestList(List > requestList, bool repeating, int64_t *lastFrameNumber) { Parcel data, reply; data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor()); data.writeInt32(requestList.size()); for (List >::iterator it = requestList.begin(); it != requestList.end(); ++it) { sp request = *it; if (request != 0) { data.writeInt32(1); if (request->writeToParcel(&data) != OK) { return BAD_VALUE; } } else { data.writeInt32(0); } } data.writeInt32(repeating); remote()->transact(SUBMIT_REQUEST_LIST, data, &reply); reply.readExceptionCode(); status_t res = reply.readInt32(); status_t resFrameNumber = BAD_VALUE; if (reply.readInt32() != 0) { if (lastFrameNumber != NULL) { resFrameNumber = reply.readInt64(lastFrameNumber); } } if (res < 0 || (resFrameNumber != NO_ERROR)) { res = FAILED_TRANSACTION; } return res; } virtual status_t cancelRequest(int requestId, int64_t *lastFrameNumber) { Parcel data, reply; data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor()); data.writeInt32(requestId); remote()->transact(CANCEL_REQUEST, data, &reply); reply.readExceptionCode(); status_t res = reply.readInt32(); status_t resFrameNumber = BAD_VALUE; if (reply.readInt32() != 0) { if (lastFrameNumber != NULL) { resFrameNumber = reply.readInt64(lastFrameNumber); } } if ((res != NO_ERROR) || (resFrameNumber != NO_ERROR)) { res = FAILED_TRANSACTION; } return res; } virtual status_t beginConfigure() { ALOGV("beginConfigure"); Parcel data, reply; data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor()); remote()->transact(BEGIN_CONFIGURE, data, &reply); reply.readExceptionCode(); return reply.readInt32(); } virtual status_t endConfigure(bool isConstrainedHighSpeed) { ALOGV("endConfigure"); Parcel data, reply; data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor()); data.writeInt32(isConstrainedHighSpeed); remote()->transact(END_CONFIGURE, data, &reply); reply.readExceptionCode(); return reply.readInt32(); } virtual status_t deleteStream(int streamId) { Parcel data, reply; data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor()); data.writeInt32(streamId); remote()->transact(DELETE_STREAM, data, &reply); reply.readExceptionCode(); return reply.readInt32(); } virtual status_t createStream(const OutputConfiguration& outputConfiguration) { Parcel data, reply; data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor()); if (outputConfiguration.getGraphicBufferProducer() != NULL) { data.writeInt32(1); // marker that OutputConfiguration is not null. Mimic aidl behavior outputConfiguration.writeToParcel(data); } else { data.writeInt32(0); } remote()->transact(CREATE_STREAM, data, &reply); reply.readExceptionCode(); return reply.readInt32(); } virtual status_t createInputStream(int width, int height, int format) { Parcel data, reply; data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor()); data.writeInt32(width); data.writeInt32(height); data.writeInt32(format); remote()->transact(CREATE_INPUT_STREAM, data, &reply); reply.readExceptionCode(); return reply.readInt32(); } // get the buffer producer of the input stream virtual status_t getInputBufferProducer( sp *producer) { if (producer == NULL) { return BAD_VALUE; } Parcel data, reply; data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor()); remote()->transact(GET_INPUT_SURFACE, data, &reply); reply.readExceptionCode(); status_t result = reply.readInt32() ; if (result != OK) { return result; } sp bp = NULL; if (reply.readInt32() != 0) { String16 name = readMaybeEmptyString16(reply); bp = interface_cast( reply.readStrongBinder()); } *producer = bp; return *producer == NULL ? INVALID_OPERATION : OK; } // Create a request object from a template. virtual status_t createDefaultRequest(int templateId, /*out*/ CameraMetadata* request) { Parcel data, reply; data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor()); data.writeInt32(templateId); remote()->transact(CREATE_DEFAULT_REQUEST, data, &reply); reply.readExceptionCode(); status_t result = reply.readInt32(); CameraMetadata out; if (reply.readInt32() != 0) { out.readFromParcel(&reply); } if (request != NULL) { request->swap(out); } return result; } virtual status_t getCameraInfo(CameraMetadata* info) { Parcel data, reply; data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor()); remote()->transact(GET_CAMERA_INFO, data, &reply); reply.readExceptionCode(); status_t result = reply.readInt32(); CameraMetadata out; if (reply.readInt32() != 0) { out.readFromParcel(&reply); } if (info != NULL) { info->swap(out); } return result; } virtual status_t waitUntilIdle() { ALOGV("waitUntilIdle"); Parcel data, reply; data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor()); remote()->transact(WAIT_UNTIL_IDLE, data, &reply); reply.readExceptionCode(); return reply.readInt32(); } virtual status_t flush(int64_t *lastFrameNumber) { ALOGV("flush"); Parcel data, reply; data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor()); remote()->transact(FLUSH, data, &reply); reply.readExceptionCode(); status_t res = reply.readInt32(); status_t resFrameNumber = BAD_VALUE; if (reply.readInt32() != 0) { if (lastFrameNumber != NULL) { resFrameNumber = reply.readInt64(lastFrameNumber); } } if ((res != NO_ERROR) || (resFrameNumber != NO_ERROR)) { res = FAILED_TRANSACTION; } return res; } virtual status_t prepare(int streamId) { ALOGV("prepare"); Parcel data, reply; data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor()); data.writeInt32(streamId); remote()->transact(PREPARE, data, &reply); reply.readExceptionCode(); return reply.readInt32(); } virtual status_t prepare2(int maxCount, int streamId) { ALOGV("prepare2"); Parcel data, reply; data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor()); data.writeInt32(maxCount); data.writeInt32(streamId); remote()->transact(PREPARE2, data, &reply); reply.readExceptionCode(); return reply.readInt32(); } virtual status_t tearDown(int streamId) { ALOGV("tearDown"); Parcel data, reply; data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor()); data.writeInt32(streamId); remote()->transact(TEAR_DOWN, data, &reply); reply.readExceptionCode(); return reply.readInt32(); } private: }; IMPLEMENT_META_INTERFACE(CameraDeviceUser, "android.hardware.camera2.ICameraDeviceUser"); // ---------------------------------------------------------------------- status_t BnCameraDeviceUser::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch(code) { case DISCONNECT: { ALOGV("DISCONNECT"); CHECK_INTERFACE(ICameraDeviceUser, data, reply); disconnect(); reply->writeNoException(); return NO_ERROR; } break; case SUBMIT_REQUEST: { CHECK_INTERFACE(ICameraDeviceUser, data, reply); // arg0 = request sp request; if (data.readInt32() != 0) { request = new CaptureRequest(); request->readFromParcel(const_cast(&data)); } // arg1 = streaming (bool) bool repeating = data.readInt32(); // return code: requestId (int32) reply->writeNoException(); int64_t lastFrameNumber = -1; reply->writeInt32(submitRequest(request, repeating, &lastFrameNumber)); reply->writeInt32(1); reply->writeInt64(lastFrameNumber); return NO_ERROR; } break; case SUBMIT_REQUEST_LIST: { CHECK_INTERFACE(ICameraDeviceUser, data, reply); List > requestList; int requestListSize = data.readInt32(); for (int i = 0; i < requestListSize; i++) { if (data.readInt32() != 0) { sp request = new CaptureRequest(); if (request->readFromParcel(const_cast(&data)) != OK) { return BAD_VALUE; } requestList.push_back(request); } else { sp request = 0; requestList.push_back(request); ALOGE("A request is missing. Sending in null request."); } } bool repeating = data.readInt32(); reply->writeNoException(); int64_t lastFrameNumber = -1; reply->writeInt32(submitRequestList(requestList, repeating, &lastFrameNumber)); reply->writeInt32(1); reply->writeInt64(lastFrameNumber); return NO_ERROR; } break; case CANCEL_REQUEST: { CHECK_INTERFACE(ICameraDeviceUser, data, reply); int requestId = data.readInt32(); reply->writeNoException(); int64_t lastFrameNumber = -1; reply->writeInt32(cancelRequest(requestId, &lastFrameNumber)); reply->writeInt32(1); reply->writeInt64(lastFrameNumber); return NO_ERROR; } break; case DELETE_STREAM: { CHECK_INTERFACE(ICameraDeviceUser, data, reply); int streamId = data.readInt32(); reply->writeNoException(); reply->writeInt32(deleteStream(streamId)); return NO_ERROR; } break; case CREATE_STREAM: { CHECK_INTERFACE(ICameraDeviceUser, data, reply); status_t ret = BAD_VALUE; if (data.readInt32() != 0) { OutputConfiguration outputConfiguration(data); ret = createStream(outputConfiguration); } else { ALOGE("%s: cannot take an empty OutputConfiguration", __FUNCTION__); } reply->writeNoException(); ALOGV("%s: CREATE_STREAM: write noException", __FUNCTION__); reply->writeInt32(ret); ALOGV("%s: CREATE_STREAM: write ret = %d", __FUNCTION__, ret); return NO_ERROR; } break; case CREATE_INPUT_STREAM: { CHECK_INTERFACE(ICameraDeviceUser, data, reply); int width, height, format; width = data.readInt32(); height = data.readInt32(); format = data.readInt32(); status_t ret = createInputStream(width, height, format); reply->writeNoException(); reply->writeInt32(ret); return NO_ERROR; } break; case GET_INPUT_SURFACE: { CHECK_INTERFACE(ICameraDeviceUser, data, reply); sp bp; status_t ret = getInputBufferProducer(&bp); sp b(IInterface::asBinder(ret == OK ? bp : NULL)); reply->writeNoException(); reply->writeInt32(ret); reply->writeInt32(1); reply->writeString16(String16("camera input")); // name of surface reply->writeStrongBinder(b); return NO_ERROR; } break; case CREATE_DEFAULT_REQUEST: { CHECK_INTERFACE(ICameraDeviceUser, data, reply); int templateId = data.readInt32(); CameraMetadata request; status_t ret; ret = createDefaultRequest(templateId, &request); reply->writeNoException(); reply->writeInt32(ret); // out-variables are after exception and return value reply->writeInt32(1); // to mark presence of metadata object request.writeToParcel(const_cast(reply)); return NO_ERROR; } break; case GET_CAMERA_INFO: { CHECK_INTERFACE(ICameraDeviceUser, data, reply); CameraMetadata info; status_t ret; ret = getCameraInfo(&info); reply->writeNoException(); reply->writeInt32(ret); // out-variables are after exception and return value reply->writeInt32(1); // to mark presence of metadata object info.writeToParcel(reply); return NO_ERROR; } break; case WAIT_UNTIL_IDLE: { CHECK_INTERFACE(ICameraDeviceUser, data, reply); reply->writeNoException(); reply->writeInt32(waitUntilIdle()); return NO_ERROR; } break; case FLUSH: { CHECK_INTERFACE(ICameraDeviceUser, data, reply); reply->writeNoException(); int64_t lastFrameNumber = -1; reply->writeInt32(flush(&lastFrameNumber)); reply->writeInt32(1); reply->writeInt64(lastFrameNumber); return NO_ERROR; } case BEGIN_CONFIGURE: { CHECK_INTERFACE(ICameraDeviceUser, data, reply); reply->writeNoException(); reply->writeInt32(beginConfigure()); return NO_ERROR; } break; case END_CONFIGURE: { CHECK_INTERFACE(ICameraDeviceUser, data, reply); bool isConstrainedHighSpeed = data.readInt32(); reply->writeNoException(); reply->writeInt32(endConfigure(isConstrainedHighSpeed)); return NO_ERROR; } break; case PREPARE: { CHECK_INTERFACE(ICameraDeviceUser, data, reply); int streamId = data.readInt32(); reply->writeNoException(); reply->writeInt32(prepare(streamId)); return NO_ERROR; } break; case TEAR_DOWN: { CHECK_INTERFACE(ICameraDeviceUser, data, reply); int streamId = data.readInt32(); reply->writeNoException(); reply->writeInt32(tearDown(streamId)); return NO_ERROR; } break; case PREPARE2: { CHECK_INTERFACE(ICameraDeviceUser, data, reply); int maxCount = data.readInt32(); int streamId = data.readInt32(); reply->writeNoException(); reply->writeInt32(prepare2(maxCount, streamId)); return NO_ERROR; } break; default: return BBinder::onTransact(code, data, reply, flags); } } // ---------------------------------------------------------------------------- }; // namespace android ================================================ FILE: libshims/camera2/OutputConfiguration.cpp ================================================ /* ** ** Copyright 2015, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ #define LOG_TAG "OutputConfiguration" #include #include #include namespace android { const int OutputConfiguration::INVALID_ROTATION = -1; // Read empty strings without printing a false error message. String16 OutputConfiguration::readMaybeEmptyString16(const Parcel& parcel) { size_t len; const char16_t* str = parcel.readString16Inplace(&len); if (str != NULL) { return String16(str, len); } else { return String16(); } } sp OutputConfiguration::getGraphicBufferProducer() const { return mGbp; } int OutputConfiguration::getRotation() const { return mRotation; } OutputConfiguration::OutputConfiguration(const Parcel& parcel) { status_t err; int rotation = 0; if ((err = parcel.readInt32(&rotation)) != OK) { ALOGE("%s: Failed to read rotation from parcel", __FUNCTION__); mGbp = NULL; mRotation = INVALID_ROTATION; return; } String16 name = readMaybeEmptyString16(parcel); const sp& gbp = interface_cast(parcel.readStrongBinder()); mGbp = gbp; mRotation = rotation; ALOGV("%s: OutputConfiguration: bp = %p, name = %s", __FUNCTION__, gbp.get(), String8(name).string()); } OutputConfiguration::OutputConfiguration(sp& gbp, int rotation) { mGbp = gbp; mRotation = rotation; } status_t OutputConfiguration::writeToParcel(Parcel& parcel) const { parcel.writeInt32(mRotation); parcel.writeString16(String16("unknown_name")); // name of surface sp b(IInterface::asBinder(mGbp)); parcel.writeStrongBinder(b); return OK; } }; // namespace android ================================================ FILE: libshims/include/camera/Camera.h ================================================ /* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_HARDWARE_CAMERA_H #define ANDROID_HARDWARE_CAMERA_H #include #include #include #include #include #include #include #include #include namespace android { class Surface; class String8; class String16; // ref-counted object for callbacks class CameraListener: virtual public RefBase { public: virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2) = 0; virtual void postData(int32_t msgType, const sp& dataPtr, camera_frame_metadata_t *metadata) = 0; virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp& dataPtr) = 0; }; class Camera; template <> struct CameraTraits { typedef CameraListener TCamListener; typedef ICamera TCamUser; typedef ICameraClient TCamCallbacks; typedef status_t (ICameraService::*TCamConnectService)(const sp&, int, const String16&, int, /*out*/ sp&); static TCamConnectService fnConnectService; }; class Camera : public CameraBase, public BnCameraClient { public: enum { USE_CALLING_UID = ICameraService::USE_CALLING_UID }; // construct a camera client from an existing remote static sp create(const sp& camera); static sp connect(int cameraId, const String16& clientPackageName, int clientUid); static status_t connectLegacy(int cameraId, int halVersion, const String16& clientPackageName, int clientUid, sp& camera); virtual ~Camera(); status_t reconnect(); status_t lock(); status_t unlock(); // pass the buffered IGraphicBufferProducer to the camera service status_t setPreviewTarget(const sp& bufferProducer); // start preview mode, must call setPreviewTarget first status_t startPreview(); // stop preview mode void stopPreview(); // get preview state bool previewEnabled(); // start recording mode, must call setPreviewTarget first status_t startRecording(); // stop recording mode void stopRecording(); // get recording state bool recordingEnabled(); // release a recording frame void releaseRecordingFrame(const sp& mem); // autoFocus - status returned from callback status_t autoFocus(); // cancel auto focus status_t cancelAutoFocus(); // take a picture - picture returned from callback status_t takePicture(int msgType); // set preview/capture parameters - key/value pairs status_t setParameters(const String8& params); // get preview/capture parameters - key/value pairs String8 getParameters() const; // send command to camera driver status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2); // tell camera hal to store meta data or real YUV in video buffers. status_t storeMetaDataInBuffers(bool enabled); void setListener(const sp& listener); void setRecordingProxyListener(const sp& listener); // Configure preview callbacks to app. Only one of the older // callbacks or the callback surface can be active at the same time; // enabling one will disable the other if active. Flags can be // disabled by calling it with CAMERA_FRAME_CALLBACK_FLAG_NOOP, and // Target by calling it with a NULL interface. void setPreviewCallbackFlags(int preview_callback_flag); status_t setPreviewCallbackTarget( const sp& callbackProducer); sp getRecordingProxy(); // ICameraClient interface virtual void notifyCallback(int32_t msgType, int32_t ext, int32_t ext2); virtual void dataCallback(int32_t msgType, const sp& dataPtr, camera_frame_metadata_t *metadata); virtual void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp& dataPtr); class RecordingProxy : public BnCameraRecordingProxy { public: RecordingProxy(const sp& camera); // ICameraRecordingProxy interface virtual status_t startRecording(const sp& listener); virtual void stopRecording(); virtual void releaseRecordingFrame(const sp& mem); private: sp mCamera; }; protected: Camera(int cameraId); Camera(const Camera&); Camera& operator=(const Camera); sp mRecordingProxyListener; friend class CameraBase; }; }; // namespace android #endif ================================================ FILE: libshims/include/camera/CameraBase.h ================================================ /* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_HARDWARE_CAMERA_BASE_H #define ANDROID_HARDWARE_CAMERA_BASE_H #include #include struct camera_frame_metadata; namespace android { struct CameraInfo { /** * The direction that the camera faces to. It should be CAMERA_FACING_BACK * or CAMERA_FACING_FRONT. */ int facing; /** * The orientation of the camera image. The value is the angle that the * camera image needs to be rotated clockwise so it shows correctly on the * display in its natural orientation. It should be 0, 90, 180, or 270. * * For example, suppose a device has a naturally tall screen. The * back-facing camera sensor is mounted in landscape. You are looking at * the screen. If the top side of the camera sensor is aligned with the * right edge of the screen in natural orientation, the value should be * 90. If the top side of a front-facing camera sensor is aligned with the * right of the screen, the value should be 270. */ int orientation; }; template struct CameraTraits { }; template > class CameraBase : public IBinder::DeathRecipient { public: typedef typename TCamTraits::TCamListener TCamListener; typedef typename TCamTraits::TCamUser TCamUser; typedef typename TCamTraits::TCamCallbacks TCamCallbacks; typedef typename TCamTraits::TCamConnectService TCamConnectService; static sp connect(int cameraId, const String16& clientPackageName, int clientUid); virtual void disconnect(); void setListener(const sp& listener); static int getNumberOfCameras(); static status_t getCameraInfo(int cameraId, /*out*/ struct CameraInfo* cameraInfo); static status_t addServiceListener( const sp& listener); static status_t removeServiceListener( const sp& listener); sp remote(); // Status is set to 'UNKNOWN_ERROR' after successful (re)connection status_t getStatus(); protected: CameraBase(int cameraId); virtual ~CameraBase(); //////////////////////////////////////////////////////// // TCamCallbacks implementation //////////////////////////////////////////////////////// virtual void notifyCallback(int32_t msgType, int32_t ext, int32_t ext2); //////////////////////////////////////////////////////// // Common instance variables //////////////////////////////////////////////////////// Mutex mLock; virtual void binderDied(const wp& who); // helper function to obtain camera service handle static const sp& getCameraService(); sp mCamera; status_t mStatus; sp mListener; const int mCameraId; typedef CameraBase CameraBaseT; }; }; // namespace android #endif ================================================ FILE: libshims/include/camera/CameraMetadata.h ================================================ /* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_CLIENT_CAMERA2_CAMERAMETADATA_CPP #define ANDROID_CLIENT_CAMERA2_CAMERAMETADATA_CPP #include "system/camera_metadata.h" #include #include namespace android { class Parcel; /** * A convenience wrapper around the C-based camera_metadata_t library. */ class CameraMetadata { public: /** Creates an empty object; best used when expecting to acquire contents * from elsewhere */ CameraMetadata(); /** Creates an object with space for entryCapacity entries, with * dataCapacity extra storage */ CameraMetadata(size_t entryCapacity, size_t dataCapacity = 10); ~CameraMetadata(); /** Takes ownership of passed-in buffer */ CameraMetadata(camera_metadata_t *buffer); /** Clones the metadata */ CameraMetadata(const CameraMetadata &other); /** * Assignment clones metadata buffer. */ CameraMetadata &operator=(const CameraMetadata &other); CameraMetadata &operator=(const camera_metadata_t *buffer); /** * Get reference to the underlying metadata buffer. Ownership remains with * the CameraMetadata object, but non-const CameraMetadata methods will not * work until unlock() is called. Note that the lock has nothing to do with * thread-safety, it simply prevents the camera_metadata_t pointer returned * here from being accidentally invalidated by CameraMetadata operations. */ const camera_metadata_t* getAndLock() const; /** * Unlock the CameraMetadata for use again. After this unlock, the pointer * given from getAndLock() may no longer be used. The pointer passed out * from getAndLock must be provided to guarantee that the right object is * being unlocked. */ status_t unlock(const camera_metadata_t *buffer); /** * Release a raw metadata buffer to the caller. After this call, * CameraMetadata no longer references the buffer, and the caller takes * responsibility for freeing the raw metadata buffer (using * free_camera_metadata()), or for handing it to another CameraMetadata * instance. */ camera_metadata_t* release(); /** * Clear the metadata buffer and free all storage used by it */ void clear(); /** * Acquire a raw metadata buffer from the caller. After this call, * the caller no longer owns the raw buffer, and must not free or manipulate it. * If CameraMetadata already contains metadata, it is freed. */ void acquire(camera_metadata_t* buffer); /** * Acquires raw buffer from other CameraMetadata object. After the call, the argument * object no longer has any metadata. */ void acquire(CameraMetadata &other); /** * Append metadata from another CameraMetadata object. */ status_t append(const CameraMetadata &other); /** * Append metadata from a raw camera_metadata buffer */ status_t append(const camera_metadata* other); /** * Number of metadata entries. */ size_t entryCount() const; /** * Is the buffer empty (no entires) */ bool isEmpty() const; /** * Sort metadata buffer for faster find */ status_t sort(); /** * Update metadata entry. Will create entry if it doesn't exist already, and * will reallocate the buffer if insufficient space exists. Overloaded for * the various types of valid data. */ status_t update(uint32_t tag, const uint8_t *data, size_t data_count); status_t update(uint32_t tag, const int32_t *data, size_t data_count); status_t update(uint32_t tag, const float *data, size_t data_count); status_t update(uint32_t tag, const int64_t *data, size_t data_count); status_t update(uint32_t tag, const double *data, size_t data_count); status_t update(uint32_t tag, const camera_metadata_rational_t *data, size_t data_count); status_t update(uint32_t tag, const String8 &string); template status_t update(uint32_t tag, Vector data) { return update(tag, data.array(), data.size()); } /** * Check if a metadata entry exists for a given tag id * */ bool exists(uint32_t tag) const; /** * Get metadata entry by tag id */ camera_metadata_entry find(uint32_t tag); /** * Get metadata entry by tag id, with no editing */ camera_metadata_ro_entry find(uint32_t tag) const; /** * Delete metadata entry by tag */ status_t erase(uint32_t tag); /** * Swap the underlying camera metadata between this and the other * metadata object. */ void swap(CameraMetadata &other); /** * Dump contents into FD for debugging. The verbosity levels are * 0: Tag entry information only, no data values * 1: Level 0 plus at most 16 data values per entry * 2: All information * * The indentation parameter sets the number of spaces to add to the start * each line of output. */ void dump(int fd, int verbosity = 1, int indentation = 0) const; /** * Serialization over Binder */ // Metadata object is unchanged when reading from parcel fails. status_t readFromParcel(Parcel *parcel); status_t writeToParcel(Parcel *parcel) const; /** * Caller becomes the owner of the new metadata * 'const Parcel' doesnt prevent us from calling the read functions. * which is interesting since it changes the internal state * * NULL can be returned when no metadata was sent, OR if there was an issue * unpacking the serialized data (i.e. bad parcel or invalid structure). */ static status_t readFromParcel(const Parcel &parcel, camera_metadata_t** out); /** * Caller retains ownership of metadata * - Write 2 (int32 + blob) args in the current position */ static status_t writeToParcel(Parcel &parcel, const camera_metadata_t* metadata); private: camera_metadata_t *mBuffer; mutable bool mLocked; /** * Check if tag has a given type */ status_t checkType(uint32_t tag, uint8_t expectedType); /** * Base update entry method */ status_t updateImpl(uint32_t tag, const void *data, size_t data_count); /** * Resize metadata buffer if needed by reallocating it and copying it over. */ status_t resizeIfNeeded(size_t extraEntries, size_t extraData); }; }; // namespace android #endif ================================================ FILE: libshims/include/camera/CameraParameters.h ================================================ /* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_HARDWARE_CAMERA_PARAMETERS_H #define ANDROID_HARDWARE_CAMERA_PARAMETERS_H #include #include #include namespace android { struct Size { int width; int height; Size() { width = 0; height = 0; } Size(int w, int h) { width = w; height = h; } }; class CameraParameters { public: CameraParameters(); CameraParameters(const String8 ¶ms) { unflatten(params); } ~CameraParameters(); String8 flatten() const; void unflatten(const String8 ¶ms); void set(const char *key, const char *value); void set(const char *key, int value); void setFloat(const char *key, float value); const char *get(const char *key) const; int getInt(const char *key) const; float getFloat(const char *key) const; void remove(const char *key); void setPreviewSize(int width, int height); void getPreviewSize(int *width, int *height) const; void getSupportedPreviewSizes(Vector &sizes) const; // Set the dimensions in pixels to the given width and height // for video frames. The given width and height must be one // of the supported dimensions returned from // getSupportedVideoSizes(). Must not be called if // getSupportedVideoSizes() returns an empty Vector of Size. void setVideoSize(int width, int height); // Retrieve the current dimensions (width and height) // in pixels for video frames, which must be one of the // supported dimensions returned from getSupportedVideoSizes(). // Must not be called if getSupportedVideoSizes() returns an // empty Vector of Size. void getVideoSize(int *width, int *height) const; // Retrieve a Vector of supported dimensions (width and height) // in pixels for video frames. If sizes returned from the method // is empty, the camera does not support calls to setVideoSize() // or getVideoSize(). In adddition, it also indicates that // the camera only has a single output, and does not have // separate output for video frames and preview frame. void getSupportedVideoSizes(Vector &sizes) const; // Retrieve the preferred preview size (width and height) in pixels // for video recording. The given width and height must be one of // supported preview sizes returned from getSupportedPreviewSizes(). // Must not be called if getSupportedVideoSizes() returns an empty // Vector of Size. If getSupportedVideoSizes() returns an empty // Vector of Size, the width and height returned from this method // is invalid, and is "-1x-1". void getPreferredPreviewSizeForVideo(int *width, int *height) const; void setPreviewFrameRate(int fps); int getPreviewFrameRate() const; void getPreviewFpsRange(int *min_fps, int *max_fps) const; void setPreviewFormat(const char *format); const char *getPreviewFormat() const; void setPictureSize(int width, int height); void getPictureSize(int *width, int *height) const; void getSupportedPictureSizes(Vector &sizes) const; void setPictureFormat(const char *format); const char *getPictureFormat() const; void dump() const; status_t dump(int fd, const Vector& args) const; /** * Returns a Vector containing the supported preview formats * as enums given in graphics.h. */ void getSupportedPreviewFormats(Vector& formats) const; // Returns true if no keys are present bool isEmpty() const; // Parameter keys to communicate between camera application and driver. // The access (read/write, read only, or write only) is viewed from the // perspective of applications, not driver. // Preview frame size in pixels (width x height). // Example value: "480x320". Read/Write. static const char KEY_PREVIEW_SIZE[]; // Supported preview frame sizes in pixels. // Example value: "800x600,480x320". Read only. static const char KEY_SUPPORTED_PREVIEW_SIZES[]; // The current minimum and maximum preview fps. This controls the rate of // preview frames received (CAMERA_MSG_PREVIEW_FRAME). The minimum and // maximum fps must be one of the elements from // KEY_SUPPORTED_PREVIEW_FPS_RANGE parameter. // Example value: "10500,26623" static const char KEY_PREVIEW_FPS_RANGE[]; // The supported preview fps (frame-per-second) ranges. Each range contains // a minimum fps and maximum fps. If minimum fps equals to maximum fps, the // camera outputs frames in fixed frame rate. If not, the camera outputs // frames in auto frame rate. The actual frame rate fluctuates between the // minimum and the maximum. The list has at least one element. The list is // sorted from small to large (first by maximum fps and then minimum fps). // Example value: "(10500,26623),(15000,26623),(30000,30000)" static const char KEY_SUPPORTED_PREVIEW_FPS_RANGE[]; // The image format for preview frames. See CAMERA_MSG_PREVIEW_FRAME in // frameworks/av/include/camera/Camera.h. The default is // PIXEL_FORMAT_YUV420SP. Example value: "yuv420sp" or PIXEL_FORMAT_XXX // constants. Read/write. static const char KEY_PREVIEW_FORMAT[]; // Supported image formats for preview frames. // Example value: "yuv420sp,yuv422i-yuyv". Read only. static const char KEY_SUPPORTED_PREVIEW_FORMATS[]; // Number of preview frames per second. This is the target frame rate. The // actual frame rate depends on the driver. // Example value: "15". Read/write. static const char KEY_PREVIEW_FRAME_RATE[]; // Supported number of preview frames per second. // Example value: "24,15,10". Read. static const char KEY_SUPPORTED_PREVIEW_FRAME_RATES[]; // The dimensions for captured pictures in pixels (width x height). // Example value: "1024x768". Read/write. static const char KEY_PICTURE_SIZE[]; // Supported dimensions for captured pictures in pixels. // Example value: "2048x1536,1024x768". Read only. static const char KEY_SUPPORTED_PICTURE_SIZES[]; // The image format for captured pictures. See CAMERA_MSG_COMPRESSED_IMAGE // in frameworks/base/include/camera/Camera.h. // Example value: "jpeg" or PIXEL_FORMAT_XXX constants. Read/write. static const char KEY_PICTURE_FORMAT[]; // Supported image formats for captured pictures. // Example value: "jpeg,rgb565". Read only. static const char KEY_SUPPORTED_PICTURE_FORMATS[]; // The width (in pixels) of EXIF thumbnail in Jpeg picture. // Example value: "512". Read/write. static const char KEY_JPEG_THUMBNAIL_WIDTH[]; // The height (in pixels) of EXIF thumbnail in Jpeg picture. // Example value: "384". Read/write. static const char KEY_JPEG_THUMBNAIL_HEIGHT[]; // Supported EXIF thumbnail sizes (width x height). 0x0 means not thumbnail // in EXIF. // Example value: "512x384,320x240,0x0". Read only. static const char KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES[]; // The quality of the EXIF thumbnail in Jpeg picture. The range is 1 to 100, // with 100 being the best. // Example value: "90". Read/write. static const char KEY_JPEG_THUMBNAIL_QUALITY[]; // Jpeg quality of captured picture. The range is 1 to 100, with 100 being // the best. // Example value: "90". Read/write. static const char KEY_JPEG_QUALITY[]; // The rotation angle in degrees relative to the orientation of the camera. // This affects the pictures returned from CAMERA_MSG_COMPRESSED_IMAGE. The // camera driver may set orientation in the EXIF header without rotating the // picture. Or the driver may rotate the picture and the EXIF thumbnail. If // the Jpeg picture is rotated, the orientation in the EXIF header will be // missing or 1 (row #0 is top and column #0 is left side). // // Note that the JPEG pictures of front-facing cameras are not mirrored // as in preview display. // // For example, suppose the natural orientation of the device is portrait. // The device is rotated 270 degrees clockwise, so the device orientation is // 270. Suppose a back-facing camera sensor is mounted in landscape and the // top side of the camera sensor is aligned with the right edge of the // display in natural orientation. So the camera orientation is 90. The // rotation should be set to 0 (270 + 90). // // Example value: "0" or "90" or "180" or "270". Write only. static const char KEY_ROTATION[]; // GPS latitude coordinate. GPSLatitude and GPSLatitudeRef will be stored in // JPEG EXIF header. // Example value: "25.032146" or "-33.462809". Write only. static const char KEY_GPS_LATITUDE[]; // GPS longitude coordinate. GPSLongitude and GPSLongitudeRef will be stored // in JPEG EXIF header. // Example value: "121.564448" or "-70.660286". Write only. static const char KEY_GPS_LONGITUDE[]; // GPS altitude. GPSAltitude and GPSAltitudeRef will be stored in JPEG EXIF // header. // Example value: "21.0" or "-5". Write only. static const char KEY_GPS_ALTITUDE[]; // GPS timestamp (UTC in seconds since January 1, 1970). This should be // stored in JPEG EXIF header. // Example value: "1251192757". Write only. static const char KEY_GPS_TIMESTAMP[]; // GPS Processing Method // Example value: "GPS" or "NETWORK". Write only. static const char KEY_GPS_PROCESSING_METHOD[]; // Current white balance setting. // Example value: "auto" or WHITE_BALANCE_XXX constants. Read/write. static const char KEY_WHITE_BALANCE[]; // Supported white balance settings. // Example value: "auto,incandescent,daylight". Read only. static const char KEY_SUPPORTED_WHITE_BALANCE[]; // Current color effect setting. // Example value: "none" or EFFECT_XXX constants. Read/write. static const char KEY_EFFECT[]; // Supported color effect settings. // Example value: "none,mono,sepia". Read only. static const char KEY_SUPPORTED_EFFECTS[]; // Current antibanding setting. // Example value: "auto" or ANTIBANDING_XXX constants. Read/write. static const char KEY_ANTIBANDING[]; // Supported antibanding settings. // Example value: "auto,50hz,60hz,off". Read only. static const char KEY_SUPPORTED_ANTIBANDING[]; // Current scene mode. // Example value: "auto" or SCENE_MODE_XXX constants. Read/write. static const char KEY_SCENE_MODE[]; // Supported scene mode settings. // Example value: "auto,night,fireworks". Read only. static const char KEY_SUPPORTED_SCENE_MODES[]; // Current flash mode. // Example value: "auto" or FLASH_MODE_XXX constants. Read/write. static const char KEY_FLASH_MODE[]; // Supported flash modes. // Example value: "auto,on,off". Read only. static const char KEY_SUPPORTED_FLASH_MODES[]; // Current focus mode. This will not be empty. Applications should call // CameraHardwareInterface.autoFocus to start the focus if focus mode is // FOCUS_MODE_AUTO or FOCUS_MODE_MACRO. // Example value: "auto" or FOCUS_MODE_XXX constants. Read/write. static const char KEY_FOCUS_MODE[]; // Supported focus modes. // Example value: "auto,macro,fixed". Read only. static const char KEY_SUPPORTED_FOCUS_MODES[]; // The maximum number of focus areas supported. This is the maximum length // of KEY_FOCUS_AREAS. // Example value: "0" or "2". Read only. static const char KEY_MAX_NUM_FOCUS_AREAS[]; // Current focus areas. // // Before accessing this parameter, apps should check // KEY_MAX_NUM_FOCUS_AREAS first to know the maximum number of focus areas // first. If the value is 0, focus area is not supported. // // Each focus area is a five-element int array. The first four elements are // the rectangle of the area (left, top, right, bottom). The direction is // relative to the sensor orientation, that is, what the sensor sees. The // direction is not affected by the rotation or mirroring of // CAMERA_CMD_SET_DISPLAY_ORIENTATION. Coordinates range from -1000 to 1000. // (-1000,-1000) is the upper left point. (1000, 1000) is the lower right // point. The width and height of focus areas cannot be 0 or negative. // // The fifth element is the weight. Values for weight must range from 1 to // 1000. The weight should be interpreted as a per-pixel weight - all // pixels in the area have the specified weight. This means a small area // with the same weight as a larger area will have less influence on the // focusing than the larger area. Focus areas can partially overlap and the // driver will add the weights in the overlap region. // // A special case of single focus area (0,0,0,0,0) means driver to decide // the focus area. For example, the driver may use more signals to decide // focus areas and change them dynamically. Apps can set (0,0,0,0,0) if they // want the driver to decide focus areas. // // Focus areas are relative to the current field of view (KEY_ZOOM). No // matter what the zoom level is, (-1000,-1000) represents the top of the // currently visible camera frame. The focus area cannot be set to be // outside the current field of view, even when using zoom. // // Focus area only has effect if the current focus mode is FOCUS_MODE_AUTO, // FOCUS_MODE_MACRO, FOCUS_MODE_CONTINUOUS_VIDEO, or // FOCUS_MODE_CONTINUOUS_PICTURE. // Example value: "(-10,-10,0,0,300),(0,0,10,10,700)". Read/write. static const char KEY_FOCUS_AREAS[]; // Focal length in millimeter. // Example value: "4.31". Read only. static const char KEY_FOCAL_LENGTH[]; // Horizontal angle of view in degrees. // Example value: "54.8". Read only. static const char KEY_HORIZONTAL_VIEW_ANGLE[]; // Vertical angle of view in degrees. // Example value: "42.5". Read only. static const char KEY_VERTICAL_VIEW_ANGLE[]; // Exposure compensation index. 0 means exposure is not adjusted. // Example value: "-5" or "5". Read/write. static const char KEY_EXPOSURE_COMPENSATION[]; // The maximum exposure compensation index (>=0). // Example value: "6". Read only. static const char KEY_MAX_EXPOSURE_COMPENSATION[]; // The minimum exposure compensation index (<=0). // Example value: "-6". Read only. static const char KEY_MIN_EXPOSURE_COMPENSATION[]; // The exposure compensation step. Exposure compensation index multiply by // step eqals to EV. Ex: if exposure compensation index is -6 and step is // 0.3333, EV is -2. // Example value: "0.333333333" or "0.5". Read only. static const char KEY_EXPOSURE_COMPENSATION_STEP[]; // The state of the auto-exposure lock. "true" means that // auto-exposure is locked to its current value and will not // change. "false" means the auto-exposure routine is free to // change exposure values. If auto-exposure is already locked, // setting this to true again has no effect (the driver will not // recalculate exposure values). Changing exposure compensation // settings will still affect the exposure settings while // auto-exposure is locked. Stopping preview or taking a still // image will not change the lock. In conjunction with // exposure compensation, this allows for capturing multi-exposure // brackets with known relative exposure values. Locking // auto-exposure after open but before the first call to // startPreview may result in severely over- or under-exposed // images. The driver will not change the AE lock after // auto-focus completes. static const char KEY_AUTO_EXPOSURE_LOCK[]; // Whether locking the auto-exposure is supported. "true" means it is, and // "false" or this key not existing means it is not supported. static const char KEY_AUTO_EXPOSURE_LOCK_SUPPORTED[]; // The state of the auto-white balance lock. "true" means that // auto-white balance is locked to its current value and will not // change. "false" means the auto-white balance routine is free to // change white balance values. If auto-white balance is already // locked, setting this to true again has no effect (the driver // will not recalculate white balance values). Stopping preview or // taking a still image will not change the lock. In conjunction // with exposure compensation, this allows for capturing // multi-exposure brackets with fixed white balance. Locking // auto-white balance after open but before the first call to // startPreview may result in severely incorrect color. The // driver will not change the AWB lock after auto-focus // completes. static const char KEY_AUTO_WHITEBALANCE_LOCK[]; // Whether locking the auto-white balance is supported. "true" // means it is, and "false" or this key not existing means it is // not supported. static const char KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED[]; // The maximum number of metering areas supported. This is the maximum // length of KEY_METERING_AREAS. // Example value: "0" or "2". Read only. static const char KEY_MAX_NUM_METERING_AREAS[]; // Current metering areas. Camera driver uses these areas to decide // exposure. // // Before accessing this parameter, apps should check // KEY_MAX_NUM_METERING_AREAS first to know the maximum number of metering // areas first. If the value is 0, metering area is not supported. // // Each metering area is a rectangle with specified weight. The direction is // relative to the sensor orientation, that is, what the sensor sees. The // direction is not affected by the rotation or mirroring of // CAMERA_CMD_SET_DISPLAY_ORIENTATION. Coordinates of the rectangle range // from -1000 to 1000. (-1000, -1000) is the upper left point. (1000, 1000) // is the lower right point. The width and height of metering areas cannot // be 0 or negative. // // The fifth element is the weight. Values for weight must range from 1 to // 1000. The weight should be interpreted as a per-pixel weight - all // pixels in the area have the specified weight. This means a small area // with the same weight as a larger area will have less influence on the // metering than the larger area. Metering areas can partially overlap and // the driver will add the weights in the overlap region. // // A special case of all-zero single metering area means driver to decide // the metering area. For example, the driver may use more signals to decide // metering areas and change them dynamically. Apps can set all-zero if they // want the driver to decide metering areas. // // Metering areas are relative to the current field of view (KEY_ZOOM). // No matter what the zoom level is, (-1000,-1000) represents the top of the // currently visible camera frame. The metering area cannot be set to be // outside the current field of view, even when using zoom. // // No matter what metering areas are, the final exposure are compensated // by KEY_EXPOSURE_COMPENSATION. // Example value: "(-10,-10,0,0,300),(0,0,10,10,700)". Read/write. static const char KEY_METERING_AREAS[]; // Current zoom value. // Example value: "0" or "6". Read/write. static const char KEY_ZOOM[]; // Maximum zoom value. // Example value: "6". Read only. static const char KEY_MAX_ZOOM[]; // The zoom ratios of all zoom values. The zoom ratio is in 1/100 // increments. Ex: a zoom of 3.2x is returned as 320. The number of list // elements is KEY_MAX_ZOOM + 1. The first element is always 100. The last // element is the zoom ratio of zoom value KEY_MAX_ZOOM. // Example value: "100,150,200,250,300,350,400". Read only. static const char KEY_ZOOM_RATIOS[]; // Whether zoom is supported. Zoom is supported if the value is "true". Zoom // is not supported if the value is not "true" or the key does not exist. // Example value: "true". Read only. static const char KEY_ZOOM_SUPPORTED[]; // Whether if smooth zoom is supported. Smooth zoom is supported if the // value is "true". It is not supported if the value is not "true" or the // key does not exist. // See CAMERA_CMD_START_SMOOTH_ZOOM, CAMERA_CMD_STOP_SMOOTH_ZOOM, and // CAMERA_MSG_ZOOM in frameworks/base/include/camera/Camera.h. // Example value: "true". Read only. static const char KEY_SMOOTH_ZOOM_SUPPORTED[]; // The distances (in meters) from the camera to where an object appears to // be in focus. The object is sharpest at the optimal focus distance. The // depth of field is the far focus distance minus near focus distance. // // Focus distances may change after starting auto focus, canceling auto // focus, or starting the preview. Applications can read this anytime to get // the latest focus distances. If the focus mode is FOCUS_MODE_CONTINUOUS, // focus distances may change from time to time. // // This is intended to estimate the distance between the camera and the // subject. After autofocus, the subject distance may be within near and far // focus distance. However, the precision depends on the camera hardware, // autofocus algorithm, the focus area, and the scene. The error can be // large and it should be only used as a reference. // // Far focus distance > optimal focus distance > near focus distance. If // the far focus distance is infinity, the value should be "Infinity" (case // sensitive). The format is three float values separated by commas. The // first is near focus distance. The second is optimal focus distance. The // third is far focus distance. // Example value: "0.95,1.9,Infinity" or "0.049,0.05,0.051". Read only. static const char KEY_FOCUS_DISTANCES[]; // The current dimensions in pixels (width x height) for video frames. // The width and height must be one of the supported sizes retrieved // via KEY_SUPPORTED_VIDEO_SIZES. // Example value: "1280x720". Read/write. static const char KEY_VIDEO_SIZE[]; // A list of the supported dimensions in pixels (width x height) // for video frames. See CAMERA_MSG_VIDEO_FRAME for details in // frameworks/base/include/camera/Camera.h. // Example: "176x144,1280x720". Read only. static const char KEY_SUPPORTED_VIDEO_SIZES[]; // The maximum number of detected faces supported by hardware face // detection. If the value is 0, hardware face detection is not supported. // Example: "5". Read only static const char KEY_MAX_NUM_DETECTED_FACES_HW[]; // The maximum number of detected faces supported by software face // detection. If the value is 0, software face detection is not supported. // Example: "5". Read only static const char KEY_MAX_NUM_DETECTED_FACES_SW[]; // Preferred preview frame size in pixels for video recording. // The width and height must be one of the supported sizes retrieved // via KEY_SUPPORTED_PREVIEW_SIZES. This key can be used only when // getSupportedVideoSizes() does not return an empty Vector of Size. // Camcorder applications are recommended to set the preview size // to a value that is not larger than the preferred preview size. // In other words, the product of the width and height of the // preview size should not be larger than that of the preferred // preview size. In addition, we recommend to choos a preview size // that has the same aspect ratio as the resolution of video to be // recorded. // Example value: "800x600". Read only. static const char KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO[]; // The image format for video frames. See CAMERA_MSG_VIDEO_FRAME in // frameworks/base/include/camera/Camera.h. // Example value: "yuv420sp" or PIXEL_FORMAT_XXX constants. Read only. static const char KEY_VIDEO_FRAME_FORMAT[]; // Sets the hint of the recording mode. If this is true, MediaRecorder.start // may be faster or has less glitches. This should be called before starting // the preview for the best result. But it is allowed to change the hint // while the preview is active. The default value is false. // // The apps can still call Camera.takePicture when the hint is true. The // apps can call MediaRecorder.start when the hint is false. But the // performance may be worse. // Example value: "true" or "false". Read/write. static const char KEY_RECORDING_HINT[]; // Returns true if video snapshot is supported. That is, applications // can call Camera.takePicture during recording. Applications do not need to // call Camera.startPreview after taking a picture. The preview will be // still active. Other than that, taking a picture during recording is // identical to taking a picture normally. All settings and methods related // to takePicture work identically. Ex: KEY_PICTURE_SIZE, // KEY_SUPPORTED_PICTURE_SIZES, KEY_JPEG_QUALITY, KEY_ROTATION, and etc. // The picture will have an EXIF header. FLASH_MODE_AUTO and FLASH_MODE_ON // also still work, but the video will record the flash. // // Applications can set shutter callback as null to avoid the shutter // sound. It is also recommended to set raw picture and post view callbacks // to null to avoid the interrupt of preview display. // // Field-of-view of the recorded video may be different from that of the // captured pictures. // Example value: "true" or "false". Read only. static const char KEY_VIDEO_SNAPSHOT_SUPPORTED[]; // The state of the video stabilization. If set to true, both the // preview stream and the recorded video stream are stabilized by // the camera. Only valid to set if KEY_VIDEO_STABILIZATION_SUPPORTED is // set to true. // // The value of this key can be changed any time the camera is // open. If preview or recording is active, it is acceptable for // there to be a slight video glitch when video stabilization is // toggled on and off. // // This only stabilizes video streams (between-frames stabilization), and // has no effect on still image capture. static const char KEY_VIDEO_STABILIZATION[]; // Returns true if video stabilization is supported. That is, applications // can set KEY_VIDEO_STABILIZATION to true and have a stabilized preview // stream and record stabilized videos. static const char KEY_VIDEO_STABILIZATION_SUPPORTED[]; // Supported modes for special effects with light. // Example values: "lowlight,hdr". static const char KEY_LIGHTFX[]; // Value for KEY_ZOOM_SUPPORTED or KEY_SMOOTH_ZOOM_SUPPORTED. static const char TRUE[]; static const char FALSE[]; // Value for KEY_FOCUS_DISTANCES. static const char FOCUS_DISTANCE_INFINITY[]; // Values for white balance settings. static const char WHITE_BALANCE_AUTO[]; static const char WHITE_BALANCE_INCANDESCENT[]; static const char WHITE_BALANCE_FLUORESCENT[]; static const char WHITE_BALANCE_WARM_FLUORESCENT[]; static const char WHITE_BALANCE_DAYLIGHT[]; static const char WHITE_BALANCE_CLOUDY_DAYLIGHT[]; static const char WHITE_BALANCE_TWILIGHT[]; static const char WHITE_BALANCE_SHADE[]; static const char WHITE_BALANCE_MANUAL_CCT[]; // Values for effect settings. static const char EFFECT_NONE[]; static const char EFFECT_MONO[]; static const char EFFECT_NEGATIVE[]; static const char EFFECT_SOLARIZE[]; static const char EFFECT_SEPIA[]; static const char EFFECT_POSTERIZE[]; static const char EFFECT_WHITEBOARD[]; static const char EFFECT_BLACKBOARD[]; static const char EFFECT_AQUA[]; // Values for antibanding settings. static const char ANTIBANDING_AUTO[]; static const char ANTIBANDING_50HZ[]; static const char ANTIBANDING_60HZ[]; static const char ANTIBANDING_OFF[]; // Values for flash mode settings. // Flash will not be fired. static const char FLASH_MODE_OFF[]; // Flash will be fired automatically when required. The flash may be fired // during preview, auto-focus, or snapshot depending on the driver. static const char FLASH_MODE_AUTO[]; // Flash will always be fired during snapshot. The flash may also be // fired during preview or auto-focus depending on the driver. static const char FLASH_MODE_ON[]; // Flash will be fired in red-eye reduction mode. static const char FLASH_MODE_RED_EYE[]; // Constant emission of light during preview, auto-focus and snapshot. // This can also be used for video recording. static const char FLASH_MODE_TORCH[]; // Values for scene mode settings. static const char SCENE_MODE_AUTO[]; static const char SCENE_MODE_ACTION[]; static const char SCENE_MODE_PORTRAIT[]; static const char SCENE_MODE_LANDSCAPE[]; static const char SCENE_MODE_NIGHT[]; static const char SCENE_MODE_NIGHT_PORTRAIT[]; static const char SCENE_MODE_THEATRE[]; static const char SCENE_MODE_BEACH[]; static const char SCENE_MODE_SNOW[]; static const char SCENE_MODE_SUNSET[]; static const char SCENE_MODE_STEADYPHOTO[]; static const char SCENE_MODE_FIREWORKS[]; static const char SCENE_MODE_SPORTS[]; static const char SCENE_MODE_PARTY[]; static const char SCENE_MODE_CANDLELIGHT[]; // Applications are looking for a barcode. Camera driver will be optimized // for barcode reading. static const char SCENE_MODE_BARCODE[]; // A high-dynamic range mode. In this mode, the HAL module will use a // capture strategy that extends the dynamic range of the captured // image in some fashion. Only the final image is returned. static const char SCENE_MODE_HDR[]; // Pixel color formats for KEY_PREVIEW_FORMAT, KEY_PICTURE_FORMAT, // and KEY_VIDEO_FRAME_FORMAT static const char PIXEL_FORMAT_YUV422SP[]; static const char PIXEL_FORMAT_YUV420SP[]; // NV21 static const char PIXEL_FORMAT_YUV422I[]; // YUY2 static const char PIXEL_FORMAT_YUV420P[]; // YV12 static const char PIXEL_FORMAT_RGB565[]; static const char PIXEL_FORMAT_RGBA8888[]; static const char PIXEL_FORMAT_JPEG[]; // Raw bayer format used for images, which is 10 bit precision samples // stored in 16 bit words. The filter pattern is RGGB. static const char PIXEL_FORMAT_BAYER_RGGB[]; // Pixel format is not known to the framework static const char PIXEL_FORMAT_ANDROID_OPAQUE[]; // Values for focus mode settings. // Auto-focus mode. Applications should call // CameraHardwareInterface.autoFocus to start the focus in this mode. static const char FOCUS_MODE_AUTO[]; // Focus is set at infinity. Applications should not call // CameraHardwareInterface.autoFocus in this mode. static const char FOCUS_MODE_INFINITY[]; // Macro (close-up) focus mode. Applications should call // CameraHardwareInterface.autoFocus to start the focus in this mode. static const char FOCUS_MODE_MACRO[]; // Focus is fixed. The camera is always in this mode if the focus is not // adjustable. If the camera has auto-focus, this mode can fix the // focus, which is usually at hyperfocal distance. Applications should // not call CameraHardwareInterface.autoFocus in this mode. static const char FOCUS_MODE_FIXED[]; // Extended depth of field (EDOF). Focusing is done digitally and // continuously. Applications should not call // CameraHardwareInterface.autoFocus in this mode. static const char FOCUS_MODE_EDOF[]; // Continuous auto focus mode intended for video recording. The camera // continuously tries to focus. This is the best choice for video // recording because the focus changes smoothly . Applications still can // call CameraHardwareInterface.takePicture in this mode but the subject may // not be in focus. Auto focus starts when the parameter is set. // // Applications can call CameraHardwareInterface.autoFocus in this mode. The // focus callback will immediately return with a boolean that indicates // whether the focus is sharp or not. The focus position is locked after // autoFocus call. If applications want to resume the continuous focus, // cancelAutoFocus must be called. Restarting the preview will not resume // the continuous autofocus. To stop continuous focus, applications should // change the focus mode to other modes. static const char FOCUS_MODE_CONTINUOUS_VIDEO[]; // Continuous auto focus mode intended for taking pictures. The camera // continuously tries to focus. The speed of focus change is more aggressive // than FOCUS_MODE_CONTINUOUS_VIDEO. Auto focus starts when the parameter is // set. // // Applications can call CameraHardwareInterface.autoFocus in this mode. If // the autofocus is in the middle of scanning, the focus callback will // return when it completes. If the autofocus is not scanning, focus // callback will immediately return with a boolean that indicates whether // the focus is sharp or not. The apps can then decide if they want to take // a picture immediately or to change the focus mode to auto, and run a full // autofocus cycle. The focus position is locked after autoFocus call. If // applications want to resume the continuous focus, cancelAutoFocus must be // called. Restarting the preview will not resume the continuous autofocus. // To stop continuous focus, applications should change the focus mode to // other modes. static const char FOCUS_MODE_CONTINUOUS_PICTURE[]; static const char FOCUS_MODE_MANUAL_POSITION[]; // Values for light special effects // Low-light enhancement mode static const char LIGHTFX_LOWLIGHT[]; // High-dynamic range mode static const char LIGHTFX_HDR[]; #ifdef CAMERA_PARAMETERS_EXTRA_H CAMERA_PARAMETERS_EXTRA_H #endif /** * Returns the the supported preview formats as an enum given in graphics.h * corrsponding to the format given in the input string or -1 if no such * conversion exists. */ static int previewFormatToEnum(const char* format); private: DefaultKeyedVector mMap; }; }; // namespace android #endif ================================================ FILE: libshims/include/camera/CameraParameters2.h ================================================ /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_HARDWARE_CAMERA_PARAMETERS2_H #define ANDROID_HARDWARE_CAMERA_PARAMETERS2_H #include #include #include "CameraParameters.h" namespace android { /** * A copy of CameraParameters plus ABI-breaking changes. Needed * because some camera HALs directly link to CameraParameters and cannot * tolerate an ABI change. */ class CameraParameters2 { public: CameraParameters2(); CameraParameters2(const String8 ¶ms) { unflatten(params); } ~CameraParameters2(); String8 flatten() const; void unflatten(const String8 ¶ms); void set(const char *key, const char *value); void set(const char *key, int value); void setFloat(const char *key, float value); // Look up string value by key. // -- The string remains valid until the next set/remove of the same key, // or until the map gets cleared. const char *get(const char *key) const; int getInt(const char *key) const; float getFloat(const char *key) const; // Compare the order that key1 was set vs the order that key2 was set. // // Sets the order parameter to an integer less than, equal to, or greater // than zero if key1's set order was respectively, to be less than, to // match, or to be greater than key2's set order. // // Error codes: // * NAME_NOT_FOUND - if either key has not been set previously // * BAD_VALUE - if any of the parameters are NULL status_t compareSetOrder(const char *key1, const char *key2, /*out*/ int *order) const; void remove(const char *key); void setPreviewSize(int width, int height); void getPreviewSize(int *width, int *height) const; void getSupportedPreviewSizes(Vector &sizes) const; // Set the dimensions in pixels to the given width and height // for video frames. The given width and height must be one // of the supported dimensions returned from // getSupportedVideoSizes(). Must not be called if // getSupportedVideoSizes() returns an empty Vector of Size. void setVideoSize(int width, int height); // Retrieve the current dimensions (width and height) // in pixels for video frames, which must be one of the // supported dimensions returned from getSupportedVideoSizes(). // Must not be called if getSupportedVideoSizes() returns an // empty Vector of Size. void getVideoSize(int *width, int *height) const; // Retrieve a Vector of supported dimensions (width and height) // in pixels for video frames. If sizes returned from the method // is empty, the camera does not support calls to setVideoSize() // or getVideoSize(). In adddition, it also indicates that // the camera only has a single output, and does not have // separate output for video frames and preview frame. void getSupportedVideoSizes(Vector &sizes) const; // Retrieve the preferred preview size (width and height) in pixels // for video recording. The given width and height must be one of // supported preview sizes returned from getSupportedPreviewSizes(). // Must not be called if getSupportedVideoSizes() returns an empty // Vector of Size. If getSupportedVideoSizes() returns an empty // Vector of Size, the width and height returned from this method // is invalid, and is "-1x-1". void getPreferredPreviewSizeForVideo(int *width, int *height) const; void setPreviewFrameRate(int fps); int getPreviewFrameRate() const; void getPreviewFpsRange(int *min_fps, int *max_fps) const; void setPreviewFpsRange(int min_fps, int max_fps); void setPreviewFormat(const char *format); const char *getPreviewFormat() const; void setPictureSize(int width, int height); void getPictureSize(int *width, int *height) const; void getSupportedPictureSizes(Vector &sizes) const; void setPictureFormat(const char *format); const char *getPictureFormat() const; void dump() const; status_t dump(int fd, const Vector& args) const; private: // Quick and dirty map that maintains insertion order template struct OrderedKeyedVector { ssize_t add(const KeyT& key, const ValueT& value) { return mList.add(Pair(key, value)); } size_t size() const { return mList.size(); } const KeyT& keyAt(size_t idx) const { return mList[idx].mKey; } const ValueT& valueAt(size_t idx) const { return mList[idx].mValue; } const ValueT& valueFor(const KeyT& key) const { ssize_t i = indexOfKey(key); LOG_ALWAYS_FATAL_IF(i<0, "%s: key not found", __PRETTY_FUNCTION__); return valueAt(i); } ssize_t indexOfKey(const KeyT& key) const { size_t vectorIdx = 0; for (; vectorIdx < mList.size(); ++vectorIdx) { if (mList[vectorIdx].mKey == key) { return (ssize_t) vectorIdx; } } return NAME_NOT_FOUND; } ssize_t removeItem(const KeyT& key) { size_t vectorIdx = (size_t) indexOfKey(key); if (vectorIdx < 0) { return vectorIdx; } return mList.removeAt(vectorIdx); } void clear() { mList.clear(); } // Same as removing and re-adding. The key's index changes to max. ssize_t replaceValueFor(const KeyT& key, const ValueT& value) { removeItem(key); return add(key, value); } private: struct Pair { Pair() : mKey(), mValue() {} Pair(const KeyT& key, const ValueT& value) : mKey(key), mValue(value) {} KeyT mKey; ValueT mValue; }; Vector mList; }; /** * Order matters: Keys that are set() later are stored later in the map. * * If two keys have meaning that conflict, then the later-set key * wins. * * For example, preview FPS and preview FPS range conflict since only * we only want to use the FPS range if that's the last thing that was set. * So in that case, only use preview FPS range if it was set later than * the preview FPS. */ OrderedKeyedVector mMap; }; }; // namespace android #endif ================================================ FILE: libshims/include/camera/CameraParametersExtra.h ================================================ // Overload this file in your device specific config if you need // to add extra camera parameters. // A typical file would look like this: /* * Copyright (C) 2014 The CyanogenMod Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* #define CAMERA_PARAMETERS_EXTRA_C \ const char CameraParameters::KEY_SUPPORTED_BURST_NUM[] = "supported-burst-num"; \ const char CameraParameters::KEY_BURST_NUM[] = "burst-num"; \ const char CameraParameters::KEY_SUPPORTED_HDR_MODES[] = "supported-hdr-modes"; \ const char CameraParameters::KEY_HDR_MODE[] = "hdr-mode"; \ const char CameraParameters::HDR_MODE_OFF[] = "hdr-mode-off"; \ const char CameraParameters::HDR_MODE_HDR[] = "hdr-mode-hdr"; #define CAMERA_PARAMETERS_EXTRA_H \ static const char KEY_SUPPORTED_BURST_NUM[]; \ static const char KEY_BURST_NUM[]; \ static const char KEY_SUPPORTED_HDR_MODES[]; \ static const char KEY_HDR_MODE[]; \ static const char HDR_MODE_OFF[]; \ static const char HDR_MODE_HDR[]; */ ================================================ FILE: libshims/include/camera/CameraUtils.h ================================================ /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_CAMERA_CLIENT_CAMERAUTILS_H #define ANDROID_CAMERA_CLIENT_CAMERAUTILS_H #include #include #include namespace android { /** * CameraUtils contains utility methods that are shared between the native * camera client, and the camera service. */ class CameraUtils { public: /** * Calculate the ANativeWindow transform from the static camera * metadata. This is based on the sensor orientation and lens facing * attributes of the camera device. * * Returns OK on success, or a negative error code. */ static status_t getRotationTransform(const CameraMetadata& staticInfo, /*out*/int32_t* transform); private: CameraUtils(); }; } /* namespace android */ #endif /* ANDROID_CAMERA_CLIENT_CAMERAUTILS_H */ ================================================ FILE: libshims/include/camera/CaptureResult.h ================================================ /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_HARDWARE_CAPTURERESULT_H #define ANDROID_HARDWARE_CAPTURERESULT_H #include #include namespace android { /** * CaptureResultExtras is a structure to encapsulate various indices for a capture result. * These indices are framework-internal and not sent to the HAL. */ struct CaptureResultExtras { /** * An integer to index the request sequence that this result belongs to. */ int32_t requestId; /** * An integer to index this result inside a request sequence, starting from 0. */ int32_t burstId; /** * TODO: Add documentation for this field. */ int32_t afTriggerId; /** * TODO: Add documentation for this field. */ int32_t precaptureTriggerId; /** * A 64bit integer to index the frame number associated with this result. */ int64_t frameNumber; /** * The partial result count (index) for this capture result. */ int32_t partialResultCount; /** * Constructor initializes object as invalid by setting requestId to be -1. */ CaptureResultExtras() : requestId(-1), burstId(0), afTriggerId(0), precaptureTriggerId(0), frameNumber(0), partialResultCount(0) { } /** * This function returns true if it's a valid CaptureResultExtras object. * Otherwise, returns false. It is valid only when requestId is non-negative. */ bool isValid(); status_t readFromParcel(Parcel* parcel); status_t writeToParcel(Parcel* parcel) const; }; struct CaptureResult : public virtual LightRefBase { CameraMetadata mMetadata; CaptureResultExtras mResultExtras; CaptureResult(); CaptureResult(const CaptureResult& otherResult); status_t readFromParcel(Parcel* parcel); status_t writeToParcel(Parcel* parcel) const; }; } #endif /* ANDROID_HARDWARE_CAPTURERESULT_H */ ================================================ FILE: libshims/include/camera/ICamera.h ================================================ /* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_HARDWARE_ICAMERA_H #define ANDROID_HARDWARE_ICAMERA_H #include #include #include #include #include #include namespace android { class ICameraClient; class IGraphicBufferProducer; class Surface; class ICamera: public IInterface { /** * Keep up-to-date with ICamera.aidl in frameworks/base */ public: DECLARE_META_INTERFACE(Camera); virtual void disconnect() = 0; // connect new client with existing camera remote virtual status_t connect(const sp& client) = 0; // prevent other processes from using this ICamera interface virtual status_t lock() = 0; // allow other processes to use this ICamera interface virtual status_t unlock() = 0; // pass the buffered IGraphicBufferProducer to the camera service virtual status_t setPreviewTarget( const sp& bufferProducer) = 0; // set the preview callback flag to affect how the received frames from // preview are handled. Enabling preview callback flags disables any active // preview callback surface set by setPreviewCallbackTarget(). virtual void setPreviewCallbackFlag(int flag) = 0; // set a buffer interface to use for client-received preview frames instead // of preview callback buffers. Passing a valid interface here disables any // active preview callbacks set by setPreviewCallbackFlag(). Passing NULL // disables the use of the callback target. virtual status_t setPreviewCallbackTarget( const sp& callbackProducer) = 0; // start preview mode, must call setPreviewTarget first virtual status_t startPreview() = 0; // stop preview mode virtual void stopPreview() = 0; // get preview state virtual bool previewEnabled() = 0; // start recording mode virtual status_t startRecording() = 0; // stop recording mode virtual void stopRecording() = 0; // get recording state virtual bool recordingEnabled() = 0; // release a recording frame virtual void releaseRecordingFrame(const sp& mem) = 0; // auto focus virtual status_t autoFocus() = 0; // cancel auto focus virtual status_t cancelAutoFocus() = 0; /* * take a picture. * @param msgType the message type an application selectively turn on/off * on a photo-by-photo basis. The supported message types are: * CAMERA_MSG_SHUTTER, CAMERA_MSG_RAW_IMAGE, CAMERA_MSG_COMPRESSED_IMAGE, * and CAMERA_MSG_POSTVIEW_FRAME. Any other message types will be ignored. */ virtual status_t takePicture(int msgType) = 0; // set preview/capture parameters - key/value pairs virtual status_t setParameters(const String8& params) = 0; // get preview/capture parameters - key/value pairs virtual String8 getParameters() const = 0; // send command to camera driver virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) = 0; // tell the camera hal to store meta data or real YUV data in video buffers. virtual status_t storeMetaDataInBuffers(bool enabled) = 0; }; // ---------------------------------------------------------------------------- class BnCamera: public BnInterface { public: virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0); }; }; // namespace android #endif ================================================ FILE: libshims/include/camera/ICameraClient.h ================================================ /* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_HARDWARE_ICAMERA_APP_H #define ANDROID_HARDWARE_ICAMERA_APP_H #include #include #include #include #include #include namespace android { class ICameraClient: public IInterface { /** * Keep up-to-date with ICameraClient.aidl in frameworks/base */ public: DECLARE_META_INTERFACE(CameraClient); virtual void notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) = 0; virtual void dataCallback(int32_t msgType, const sp& data, camera_frame_metadata_t *metadata) = 0; virtual void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp& data) = 0; }; // ---------------------------------------------------------------------------- class BnCameraClient: public BnInterface { public: virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0); }; }; // namespace android #endif ================================================ FILE: libshims/include/camera/ICameraRecordingProxy.h ================================================ /* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_HARDWARE_ICAMERA_RECORDING_PROXY_H #define ANDROID_HARDWARE_ICAMERA_RECORDING_PROXY_H #include #include namespace android { class ICameraRecordingProxyListener; class IMemory; class Parcel; /* * The purpose of ICameraRecordingProxy and ICameraRecordingProxyListener is to * allow applications using the camera during recording. * * Camera service allows only one client at a time. Since camcorder application * needs to own the camera to do things like zoom, the media recorder cannot * access the camera directly during recording. So ICameraRecordingProxy is a * proxy of ICamera, which allows the media recorder to start/stop the recording * and release recording frames. ICameraRecordingProxyListener is an interface * that allows the recorder to receive video frames during recording. * * ICameraRecordingProxy * startRecording() * stopRecording() * releaseRecordingFrame() * * ICameraRecordingProxyListener * dataCallbackTimestamp() * The camcorder app opens the camera and starts the preview. The app passes * ICamera and ICameraRecordingProxy to the media recorder by * MediaRecorder::setCamera(). The recorder uses ICamera to setup the camera in * MediaRecorder::start(). After setup, the recorder disconnects from camera * service. The recorder calls ICameraRecordingProxy::startRecording() and * passes a ICameraRecordingProxyListener to the app. The app connects back to * camera service and starts the recording. The app owns the camera and can do * things like zoom. The media recorder receives the video frames from the * listener and releases them by ICameraRecordingProxy::releaseRecordingFrame. * The recorder calls ICameraRecordingProxy::stopRecording() to stop the * recording. * * The call sequences are as follows: * 1. The app: Camera.unlock(). * 2. The app: MediaRecorder.setCamera(). * 3. Start recording * (1) The app: MediaRecorder.start(). * (2) The recorder: ICamera.unlock() and ICamera.disconnect(). * (3) The recorder: ICameraRecordingProxy.startRecording(). * (4) The app: ICamera.reconnect(). * (5) The app: ICamera.startRecording(). * 4. During recording * (1) The recorder: receive frames from ICameraRecordingProxyListener.dataCallbackTimestamp() * (2) The recorder: release frames by ICameraRecordingProxy.releaseRecordingFrame(). * 5. Stop recording * (1) The app: MediaRecorder.stop() * (2) The recorder: ICameraRecordingProxy.stopRecording(). * (3) The app: ICamera.stopRecording(). */ class ICameraRecordingProxy: public IInterface { public: DECLARE_META_INTERFACE(CameraRecordingProxy); virtual status_t startRecording(const sp& listener) = 0; virtual void stopRecording() = 0; virtual void releaseRecordingFrame(const sp& mem) = 0; // b/28466701 static size_t getCommonBaseAddress(); private: static uint8_t baseObject; }; // ---------------------------------------------------------------------------- class BnCameraRecordingProxy: public BnInterface { public: virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0); }; }; // namespace android #endif ================================================ FILE: libshims/include/camera/ICameraRecordingProxyListener.h ================================================ /* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_HARDWARE_ICAMERA_RECORDING_PROXY_LISTENER_H #define ANDROID_HARDWARE_ICAMERA_RECORDING_PROXY_LISTENER_H #include #include #include #include namespace android { class Parcel; class IMemory; class ICameraRecordingProxyListener: public IInterface { public: DECLARE_META_INTERFACE(CameraRecordingProxyListener); virtual void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp& data) = 0; }; // ---------------------------------------------------------------------------- class BnCameraRecordingProxyListener: public BnInterface { public: virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0); }; }; // namespace android #endif ================================================ FILE: libshims/include/camera/ICameraService.h ================================================ /* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_HARDWARE_ICAMERASERVICE_H #define ANDROID_HARDWARE_ICAMERASERVICE_H #include #include #include namespace android { class ICamera; class ICameraClient; class ICameraServiceListener; class ICameraDeviceUser; class ICameraDeviceCallbacks; class CameraMetadata; class VendorTagDescriptor; class String16; class ICameraService : public IInterface { public: /** * Keep up-to-date with ICameraService.aidl in frameworks/base */ enum { GET_NUMBER_OF_CAMERAS = IBinder::FIRST_CALL_TRANSACTION, GET_CAMERA_INFO, CONNECT, CONNECT_DEVICE, ADD_LISTENER, REMOVE_LISTENER, GET_CAMERA_CHARACTERISTICS, GET_CAMERA_VENDOR_TAG_DESCRIPTOR, GET_LEGACY_PARAMETERS, SUPPORTS_CAMERA_API, CONNECT_LEGACY, SET_TORCH_MODE, NOTIFY_SYSTEM_EVENT, }; enum { USE_CALLING_UID = -1 }; enum { API_VERSION_1 = 1, API_VERSION_2 = 2, }; enum { CAMERA_TYPE_BACKWARD_COMPATIBLE = 0, CAMERA_TYPE_ALL = 1, }; enum { CAMERA_HAL_API_VERSION_UNSPECIFIED = -1 }; /** * Keep up-to-date with declarations in * frameworks/base/services/core/java/com/android/server/camera/CameraService.java * * These event codes are intended to be used with the notifySystemEvent call. */ enum { NO_EVENT = 0, USER_SWITCHED, }; public: DECLARE_META_INTERFACE(CameraService); // Get the number of cameras that support basic color camera operation // (type CAMERA_TYPE_BACKWARD_COMPATIBLE) virtual int32_t getNumberOfCameras() = 0; // Get the number of cameras of the specified type, one of CAMERA_TYPE_* // enums virtual int32_t getNumberOfCameras(int cameraType) = 0; virtual status_t getCameraInfo(int cameraId, /*out*/ struct CameraInfo* cameraInfo) = 0; virtual status_t getCameraCharacteristics(int cameraId, /*out*/ CameraMetadata* cameraInfo) = 0; virtual status_t getCameraVendorTagDescriptor( /*out*/ sp& desc) = 0; // Returns 'OK' if operation succeeded // - Errors: ALREADY_EXISTS if the listener was already added virtual status_t addListener(const sp& listener) = 0; // Returns 'OK' if operation succeeded // - Errors: BAD_VALUE if specified listener was not in the listener list virtual status_t removeListener(const sp& listener) = 0; /** * clientPackageName and clientUid are used for permissions checking. if * clientUid == USE_CALLING_UID, then the calling UID is used instead. Only * trusted callers can set a clientUid other than USE_CALLING_UID. */ virtual status_t connect(const sp& cameraClient, int cameraId, const String16& clientPackageName, int clientUid, /*out*/ sp& device) = 0; virtual status_t connectDevice( const sp& cameraCb, int cameraId, const String16& clientPackageName, int clientUid, /*out*/ sp& device) = 0; virtual status_t getLegacyParameters( int cameraId, /*out*/ String16* parameters) = 0; /** * Returns OK if device supports camera2 api, * returns -EOPNOTSUPP if it doesn't. */ virtual status_t supportsCameraApi( int cameraId, int apiVersion) = 0; /** * Connect the device as a legacy device for a given HAL version. * For halVersion, use CAMERA_API_DEVICE_VERSION_* for a particular * version, or CAMERA_HAL_API_VERSION_UNSPECIFIED for a service-selected version. */ virtual status_t connectLegacy(const sp& cameraClient, int cameraId, int halVersion, const String16& clientPackageName, int clientUid, /*out*/ sp& device) = 0; /** * Turn on or off a camera's torch mode. Torch mode will be turned off by * camera service if the lastest client binder that turns it on dies. * * return values: * 0: on a successful operation. * -ENOSYS: the camera device doesn't support this operation. It it returned * if and only if android.flash.into.available is false. * -EBUSY: the camera device is opened. * -EINVAL: camera_id is invalid or clientBinder is NULL when enabling a * torch mode. */ virtual status_t setTorchMode(const String16& cameraId, bool enabled, const sp& clientBinder) = 0; /** * Notify the camera service of a system event. Should only be called from system_server. */ virtual void notifySystemEvent(int32_t eventId, const int32_t* args, size_t length) = 0; }; // ---------------------------------------------------------------------------- class BnCameraService: public BnInterface { public: virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0); }; }; // namespace android #endif ================================================ FILE: libshims/include/camera/ICameraServiceListener.h ================================================ /* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_HARDWARE_ICAMERASERVICE_LISTENER_H #define ANDROID_HARDWARE_ICAMERASERVICE_LISTENER_H #include #include #include #include namespace android { class ICameraServiceListener : public IInterface { /** * Keep up-to-date with ICameraServiceListener.aidl in frameworks/base */ public: /** * Initial status will be transmitted with onStatusChange immediately * after this listener is added to the service listener list. * * Allowed transitions: * * (Any) -> NOT_PRESENT * NOT_PRESENT -> PRESENT * NOT_PRESENT -> ENUMERATING * ENUMERATING -> PRESENT * PRESENT -> NOT_AVAILABLE * NOT_AVAILABLE -> PRESENT * * A state will never immediately transition back to itself. */ enum Status { // Device physically unplugged STATUS_NOT_PRESENT = CAMERA_DEVICE_STATUS_NOT_PRESENT, // Device physically has been plugged in // and the camera can be used exlusively STATUS_PRESENT = CAMERA_DEVICE_STATUS_PRESENT, // Device physically has been plugged in // but it will not be connect-able until enumeration is complete STATUS_ENUMERATING = CAMERA_DEVICE_STATUS_ENUMERATING, // Camera can be used exclusively STATUS_AVAILABLE = STATUS_PRESENT, // deprecated, will be removed // Camera is in use by another app and cannot be used exclusively STATUS_NOT_AVAILABLE = 0x80000000, // Use to initialize variables only STATUS_UNKNOWN = 0xFFFFFFFF, }; /** * The torch mode status of a camera. * * Initial status will be transmitted with onTorchStatusChanged immediately * after this listener is added to the service listener list. * * The enums should be set to values matching * include/hardware/camera_common.h */ enum TorchStatus { // The camera's torch mode has become not available to use via // setTorchMode(). TORCH_STATUS_NOT_AVAILABLE = TORCH_MODE_STATUS_NOT_AVAILABLE, // The camera's torch mode is off and available to be turned on via // setTorchMode(). TORCH_STATUS_AVAILABLE_OFF = TORCH_MODE_STATUS_AVAILABLE_OFF, // The camera's torch mode is on and available to be turned off via // setTorchMode(). TORCH_STATUS_AVAILABLE_ON = TORCH_MODE_STATUS_AVAILABLE_ON, // Use to initialize variables only TORCH_STATUS_UNKNOWN = 0xFFFFFFFF, }; DECLARE_META_INTERFACE(CameraServiceListener); virtual void onStatusChanged(Status status, int32_t cameraId) = 0; virtual void onTorchStatusChanged(TorchStatus status, const String16& cameraId) = 0; }; // ---------------------------------------------------------------------------- class BnCameraServiceListener : public BnInterface { public: virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0); }; }; // namespace android #endif ================================================ FILE: libshims/include/camera/ICameraServiceProxy.h ================================================ /* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_HARDWARE_ICAMERASERVICEPROXY_H #define ANDROID_HARDWARE_ICAMERASERVICEPROXY_H #include #include #include namespace android { /** * Interface from native camera service to managed-side camera service proxy. * * Keep in sync with frameworks/base/core/java/android/hardware/ICameraServiceProxy.aidl * */ class ICameraServiceProxy : public IInterface { public: enum { PING_FOR_USER_UPDATE = IBinder::FIRST_CALL_TRANSACTION, NOTIFY_CAMERA_STATE }; enum CameraState { CAMERA_STATE_OPEN, CAMERA_STATE_ACTIVE, CAMERA_STATE_IDLE, CAMERA_STATE_CLOSED }; DECLARE_META_INTERFACE(CameraServiceProxy); virtual void pingForUserUpdate() = 0; virtual void notifyCameraState(String16 cameraId, CameraState newCameraState) = 0; }; class BnCameraServiceProxy: public BnInterface { public: virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0); }; }; // namespace android #endif // ANDROID_HARDWARE_ICAMERASERVICEPROXY_H ================================================ FILE: libshims/include/camera/VendorTagDescriptor.h ================================================ /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef VENDOR_TAG_DESCRIPTOR_H #include #include #include #include #include #include namespace android { class Parcel; /** * VendorTagDescriptor objects are parcelable containers for the vendor tag * definitions provided, and are typically used to pass the vendor tag * information enumerated by the HAL to clients of the camera service. */ class VendorTagDescriptor : public LightRefBase { public: virtual ~VendorTagDescriptor(); /** * The following 'get*' methods implement the corresponding * functions defined in * system/media/camera/include/system/camera_vendor_tags.h */ // Returns the number of vendor tags defined. int getTagCount() const; // Returns an array containing the id's of vendor tags defined. void getTagArray(uint32_t* tagArray) const; // Returns the section name string for a given vendor tag id. const char* getSectionName(uint32_t tag) const; // Returns the tag name string for a given vendor tag id. const char* getTagName(uint32_t tag) const; // Returns the tag type for a given vendor tag id. int getTagType(uint32_t tag) const; /** * Write the VendorTagDescriptor object into the given parcel. * * Returns OK on success, or a negative error code. */ status_t writeToParcel( /*out*/ Parcel* parcel) const; /** * Convenience method to get a vector containing all vendor tag * sections, or an empty vector if none are defined. */ SortedVector getAllSectionNames() const; /** * Lookup the tag id for a given tag name and section. * * Returns OK on success, or a negative error code. */ status_t lookupTag(String8 name, String8 section, /*out*/uint32_t* tag) const; /** * Dump the currently configured vendor tags to a file descriptor. */ void dump(int fd, int verbosity, int indentation) const; // Static methods: /** * Create a VendorTagDescriptor object from the given parcel. * * Returns OK on success, or a negative error code. */ static status_t createFromParcel(const Parcel* parcel, /*out*/ sp& descriptor); /** * Create a VendorTagDescriptor object from the given vendor_tag_ops_t * struct. * * Returns OK on success, or a negative error code. */ static status_t createDescriptorFromOps(const vendor_tag_ops_t* vOps, /*out*/ sp& descriptor); /** * Sets the global vendor tag descriptor to use for this process. * Camera metadata operations that access vendor tags will use the * vendor tag definitions set this way. * * Returns OK on success, or a negative error code. */ static status_t setAsGlobalVendorTagDescriptor(const sp& desc); /** * Clears the global vendor tag descriptor used by this process. */ static void clearGlobalVendorTagDescriptor(); /** * Returns the global vendor tag descriptor used by this process. * This will contain NULL if no vendor tags are defined. */ static sp getGlobalVendorTagDescriptor(); protected: VendorTagDescriptor(); KeyedVector*> mReverseMapping; KeyedVector mTagToNameMap; KeyedVector mTagToSectionMap; // Value is offset in mSections KeyedVector mTagToTypeMap; SortedVector mSections; // must be int32_t to be compatible with Parcel::writeInt32 int32_t mTagCount; private: vendor_tag_ops mVendorOps; }; } /* namespace android */ #define VENDOR_TAG_DESCRIPTOR_H #endif /* VENDOR_TAG_DESCRIPTOR_H */ ================================================ FILE: libshims/include/camera/camera2/CaptureRequest.h ================================================ /* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_HARDWARE_PHOTOGRAPHY_CAPTUREREQUEST_H #define ANDROID_HARDWARE_PHOTOGRAPHY_CAPTUREREQUEST_H #include #include #include namespace android { class Surface; struct CaptureRequest : public virtual RefBase { public: CameraMetadata mMetadata; Vector > mSurfaceList; bool mIsReprocess; /** * Keep impl up-to-date with CaptureRequest.java in frameworks/base */ status_t readFromParcel(Parcel* parcel); status_t writeToParcel(Parcel* parcel) const; }; }; // namespace android #endif ================================================ FILE: libshims/include/camera/camera2/ICameraDeviceCallbacks.h ================================================ /* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_HARDWARE_PHOTOGRAPHY_CALLBACKS_H #define ANDROID_HARDWARE_PHOTOGRAPHY_CALLBACKS_H #include #include #include #include #include #include #include namespace android { class CameraMetadata; class ICameraDeviceCallbacks : public IInterface { /** * Keep up-to-date with ICameraDeviceCallbacks.aidl in frameworks/base */ public: DECLARE_META_INTERFACE(CameraDeviceCallbacks); /** * Error codes for CAMERA_MSG_ERROR */ enum CameraErrorCode { ERROR_CAMERA_INVALID_ERROR = -1, // To indicate all invalid error codes ERROR_CAMERA_DISCONNECTED = 0, ERROR_CAMERA_DEVICE = 1, ERROR_CAMERA_SERVICE = 2, ERROR_CAMERA_REQUEST = 3, ERROR_CAMERA_RESULT = 4, ERROR_CAMERA_BUFFER = 5, }; // One way virtual void onDeviceError(CameraErrorCode errorCode, const CaptureResultExtras& resultExtras) = 0; // One way virtual void onDeviceIdle() = 0; // One way virtual void onCaptureStarted(const CaptureResultExtras& resultExtras, int64_t timestamp) = 0; // One way virtual void onResultReceived(const CameraMetadata& metadata, const CaptureResultExtras& resultExtras) = 0; // One way virtual void onPrepared(int streamId) = 0; }; // ---------------------------------------------------------------------------- class BnCameraDeviceCallbacks : public BnInterface { public: virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0); }; }; // namespace android #endif ================================================ FILE: libshims/include/camera/camera2/ICameraDeviceUser.h ================================================ /* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_HARDWARE_PHOTOGRAPHY_ICAMERADEVICEUSER_H #define ANDROID_HARDWARE_PHOTOGRAPHY_ICAMERADEVICEUSER_H #include #include #include struct camera_metadata; namespace android { class ICameraDeviceUserClient; class IGraphicBufferProducer; class CaptureRequest; class CameraMetadata; class OutputConfiguration; enum { NO_IN_FLIGHT_REPEATING_FRAMES = -1, }; class ICameraDeviceUser : public IInterface { /** * Keep up-to-date with ICameraDeviceUser.aidl in frameworks/base */ public: DECLARE_META_INTERFACE(CameraDeviceUser); virtual void disconnect() = 0; /** * Request Handling **/ /** * For streaming requests, output lastFrameNumber is the last frame number * of the previous repeating request. * For non-streaming requests, output lastFrameNumber is the expected last * frame number of the current request. */ virtual int submitRequest(sp request, bool streaming = false, /*out*/ int64_t* lastFrameNumber = NULL) = 0; /** * For streaming requests, output lastFrameNumber is the last frame number * of the previous repeating request. * For non-streaming requests, output lastFrameNumber is the expected last * frame number of the current request. */ virtual int submitRequestList(List > requestList, bool streaming = false, /*out*/ int64_t* lastFrameNumber = NULL) = 0; /** * Output lastFrameNumber is the last frame number of the previous repeating request. */ virtual status_t cancelRequest(int requestId, /*out*/ int64_t* lastFrameNumber = NULL) = 0; /** * Begin the device configuration. * *

* beginConfigure must be called before any call to deleteStream, createStream, * or endConfigure. It is not valid to call this when the device is not idle. *

*/ virtual status_t beginConfigure() = 0; /** * End the device configuration. * *

* endConfigure must be called after stream configuration is complete (i.e. after * a call to beginConfigure and subsequent createStream/deleteStream calls). This * must be called before any requests can be submitted. *

*/ virtual status_t endConfigure(bool isConstrainedHighSpeed = false) = 0; virtual status_t deleteStream(int streamId) = 0; virtual status_t createStream(const OutputConfiguration& outputConfiguration) = 0; /** * Create an input stream of width, height, and format (one of * HAL_PIXEL_FORMAT_*) * * Return stream ID if it's a non-negative value. status_t if it's a * negative value. */ virtual status_t createInputStream(int width, int height, int format) = 0; // get the buffer producer of the input stream virtual status_t getInputBufferProducer( sp *producer) = 0; // Create a request object from a template. virtual status_t createDefaultRequest(int templateId, /*out*/ CameraMetadata* request) = 0; // Get static camera metadata virtual status_t getCameraInfo(/*out*/ CameraMetadata* info) = 0; // Wait until all the submitted requests have finished processing virtual status_t waitUntilIdle() = 0; /** * Flush all pending and in-progress work as quickly as possible. * Output lastFrameNumber is the last frame number of the previous repeating request. */ virtual status_t flush(/*out*/ int64_t* lastFrameNumber = NULL) = 0; /** * Preallocate buffers for a given output stream asynchronously. */ virtual status_t prepare(int streamId) = 0; /** * Preallocate up to maxCount buffers for a given output stream asynchronously. */ virtual status_t prepare2(int maxCount, int streamId) = 0; /** * Free all unused buffers for a given output stream. */ virtual status_t tearDown(int streamId) = 0; }; // ---------------------------------------------------------------------------- class BnCameraDeviceUser: public BnInterface { public: virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0); }; }; // namespace android #endif ================================================ FILE: libshims/include/camera/camera2/OutputConfiguration.h ================================================ /* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_HARDWARE_CAMERA2_OUTPUTCONFIGURATION_H #define ANDROID_HARDWARE_CAMERA2_OUTPUTCONFIGURATION_H #include #include namespace android { class Surface; class OutputConfiguration : public virtual RefBase { public: static const int INVALID_ROTATION; sp getGraphicBufferProducer() const; int getRotation() const; /** * Keep impl up-to-date with OutputConfiguration.java in frameworks/base */ status_t writeToParcel(Parcel& parcel) const; // getGraphicBufferProducer will be NULL if error occurred // getRotation will be INVALID_ROTATION if error occurred OutputConfiguration(const Parcel& parcel); OutputConfiguration(sp& gbp, int rotation); private: sp mGbp; int mRotation; // helper function static String16 readMaybeEmptyString16(const Parcel& parcel); }; }; // namespace android #endif ================================================ FILE: overlay/frameworks/base/core/res/res/values/config.xml ================================================ 5 40 100 325 600 1250 2200 4000 10000 11 22 47 61 84 107 154 212 245 255 6 1 55 true true true 0 1 20 21 0 10 20 30 40 true true 83 64 3 1 true true true wifi,1,1,1,-1,true mobile,0,0,0,-1,true mobile_mms,2,0,4,60000,true mobile_supl,3,0,2,60000,true mobile_dun,4,0,2,60000,true mobile_hipri,5,0,3,60000,true mobile_fota,10,0,2,60000,true mobile_ims,11,0,2,60000,true mobile_cbs,12,0,2,60000,true bluetooth,7,7,2,-1,true ethernet,9,9,9,-1,true "1,1" "0,1" "7,1" "usb\\d" "rndis\\d" "wlan0" "bnep\\d" "bt-pan" 0 1 4 5 7 true Android-Mms/2.0 http://www.google.com/oha/rdf/ua-profile-kila.xml true true true true true true true true true true true true true 4 true 17 true true com.android.systemui/com.android.systemui.doze.DozeService true lte:2097152,4194304,8388608,262144,524288,1048576 lte_ca:2097152,4194304,8388608,262144,524288,1048576 umts:4094,87380,1220608,4096,16384,1220608 hspa:4094,87380,1220608,4096,16384,1220608 hsupa:4094,87380,1220608,4096,16384,1220608 hsdpa:4094,87380,1220608,4096,16384,1220608 hspap:4094,87380,1220608,4096,16384,1220608 edge:4093,26280,35040,4096,16384,35040 gprs:4092,8760,11680,4096,8760,11680 evdo:4094,87380,524288,4096,16384,262144 524288,2097152,4194304,262144,524288,1048576 true 3300 true com.qualcomm.location com.qualcomm.location "/system/framework/arm64/boot-framework.oat" "/system/framework/oat/arm64/services.odex" "/system/framework/arm64/boot.oat" "/system/framework/arm64/boot-core-libart.oat" ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc204-mnc04/config.xml ================================================ *86;BAE0000000000000 false [ApnSettingV3]HOT mobile PC,pc.hotm,,,,,,,,,204,04,,DUN,,,true,0,,,,,,,spn,HOT mobile com.google.android.carrierentitlement com.google.android.carrierentitlement.CarrierEntitlementActivity com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK_RESULT ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc208-mnc10/config.xml ================================================ SFR option modem,websfr,,,,,,,,,208,10,,DUN [ApnSettingV3]INTERNET NRJ,internetnrj,,,,,,,,,208,10,,DUN,,,true,0,,,,,,,gid,4E [ApnSettingV3]Auchan,wap65,,,,,,,,,208,10,,DUN,,,true,0,,,,,,,spn,A MOBILE [ApnSettingV3]LeclercMobile,wap66,,,,,,,,,208,10,,DUN,,,true,0,,,,,,,spn,LeclercMobile [ApnSettingV3]Coriolis,fnetcoriolis,,,,,,,,,208,10,,DUN,,,true,0,,,,,,,gid,12 [ApnSettingV3]La Poste Mobile modem,websfr,,,,,,,,,208,10,,DUN,,,true,0,,,,,,,gid,4C [ApnSettingV3]Darty Surf Mails,wap68,,,,,,,,,208,10,,DUN,,,true,0,,,,,,,gid,44 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc214-mnc01/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc234-mnc15/config.xml ================================================ 121 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc262-mnc01/config.xml ================================================ 3311 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc262-mnc07/config.xml ================================================ true +491793000333 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc262-mnc08/config.xml ================================================ true +491793000333 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc268-mnc01/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc302-mnc220/config.xml ================================================ SUPL_HOST=supl.telusmobility.com SUPL_PORT=7275 XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin NTP_SERVER=north-america.pool.ntp.org SUPL_MODE=1 SUPL_VER=0x20000 LPP_PROFILE=2 NMEA_PROVIDER=0 A_GLONASS_POS_PROTOCOL_SELECT=0 ERR_ESTIMATE=0 INTERMEDIATE_POS=0 GPS_LOCK=0 SUPL_ES=0 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc302-mnc370/config.xml ================================================ [ApnSettingV3]Fido Tethering,ltedata.apn,,,,,,,,,302,370,,DUN,IPV4V6,,true,,,,,,,,, ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc302-mnc610/config.xml ================================================ SUPL_HOST=supl.google.com SUPL_PORT=7275 XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin NTP_SERVER=north-america.pool.ntp.org SUPL_MODE=1 SUPL_VER=0x20000 LPP_PROFILE=2 NMEA_PROVIDER=0 A_GLONASS_POS_PROTOCOL_SELECT=0 ERR_ESTIMATE=0 INTERMEDIATE_POS=0 GPS_LOCK=0 SUPL_ES=0 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc302-mnc720/config.xml ================================================ [ApnSettingV3]Rogers Tethering,ltedata.apn,,,,,,,,,302,720,,DUN,IPV4V6,IPV4V6,true,,,,,,,,, SUPL_HOST=supl.google.com SUPL_PORT=7275 XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin NTP_SERVER=north-america.pool.ntp.org SUPL_MODE=1 SUPL_VER=0x20000 LPP_PROFILE=2 NMEA_PROVIDER=0 A_GLONASS_POS_PROTOCOL_SELECT=0 ERR_ESTIMATE=0 INTERMEDIATE_POS=0 GPS_LOCK=0 SUPL_ES=0 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc310-mnc004/config.xml ================================================ *86 1 4 7 9 false SUPL_HOST=supl.google.com SUPL_PORT=7275 XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin NTP_SERVER=north-america.pool.ntp.org SUPL_VER=0x20000 NMEA_PROVIDER=0 A_GLONASS_POS_PROTOCOL_SELECT=0 ERR_ESTIMATE=0 INTERMEDIATE_POS=0 LPP_PROFILE=3 GPS_LOCK=3 SUPL_MODE=0 SUPL_ES=1 com.google.android.carrierentitlement com.google.android.carrierentitlement.CarrierEntitlementActivity com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK_RESULT ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc310-mnc070/config.xml ================================================ com.google.android.carrierentitlement com.google.android.carrierentitlement.CarrierEntitlementActivity com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK_RESULT ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc310-mnc090/config.xml ================================================ com.google.android.carrierentitlement com.google.android.carrierentitlement.CarrierEntitlementActivity com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK_RESULT ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc310-mnc120/config.xml ================================================ true 1 4 7 9 51200 4 SUPL_HOST=supl.google.com SUPL_PORT=7275 XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin NTP_SERVER=north-america.pool.ntp.org SUPL_VER=0x20000 NMEA_PROVIDER=0 A_GLONASS_POS_PROTOCOL_SELECT=0 ERR_ESTIMATE=0 INTERMEDIATE_POS=0 GPS_LOCK=3 LPP_PROFILE=2 SUPL_MODE=1 SUPL_ES=0 true 300 com.google.android.carrierentitlement com.google.android.carrierentitlement.CarrierEntitlementActivity com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK_RESULT ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc310-mnc150/config.xml ================================================ com.google.android.carrierentitlement com.google.android.carrierentitlement.CarrierEntitlementActivity com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK_RESULT ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc310-mnc170/config.xml ================================================ com.google.android.carrierentitlement com.google.android.carrierentitlement.CarrierEntitlementActivity com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK_RESULT ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc310-mnc260/config.xml ================================================ 1 4 7 9 T-Mobile Tethering,pcweb.tmobile.com,,,,,,,,,310,260,,DUN [ApnSettingV3]MetroPCS Tethering,pcweb.metropcs.com,,,,,,,,,310,260,,DUN,,,true,0,,,,,,,gid,6D umts:21135,131070,1056768,6144,24576,165312 hspa:18300,131070,1056768,6144,24576,393216 hsdpa:18300,131070,1056768,6144,24576,393216 hsupa:6141,131070,1056768,6144,24576,393216 hspap:31455,131070,1830912,6144,24576,1830912 edge:8192,26280,704512,4096,16384,110208 gprs:8192,8760,704512,4096,8760,110208 lte:786432,1572864,3840000,786432,1572864,3840000 SUPL_HOST=supl.google.com SUPL_PORT=7275 XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin NTP_SERVER=north-america.pool.ntp.org SUPL_VER=0x20000 NMEA_PROVIDER=0 A_GLONASS_POS_PROTOCOL_SELECT=0 ERR_ESTIMATE=0 INTERMEDIATE_POS=0 GPS_LOCK=1 LPP_PROFILE=2 SUPL_MODE=1 SUPL_ES=0 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc310-mnc380/config.xml ================================================ com.google.android.carrierentitlement com.google.android.carrierentitlement.CarrierEntitlementActivity com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK_RESULT ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc310-mnc410/config.xml ================================================ umts:131072,262144,1452032,4096,16384,399360 hspa:131072,262144,1452032,4096,16384,399360 hsdpa:131072,262144,1452032,4096,16384,399360 hsupa:131072,262144,1452032,4096,16384,399360 hspap:131072,262144,1452032,4096,16384,399360 edge:4093,26280,35040,4096,16384,35040 gprs:4092,8760,11680,4096,8760,11680 evdo:4094,87380,262144,4096,16384,262144 lte:524288,1048576,8388608,262144,524288,4194304 SUPL_HOST=supl.google.com SUPL_PORT=7275 XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin NTP_SERVER=north-america.pool.ntp.org SUPL_VER=0x20000 NMEA_PROVIDER=0 A_GLONASS_POS_PROTOCOL_SELECT=0 ERR_ESTIMATE=0 INTERMEDIATE_POS=0 GPS_LOCK=1 LPP_PROFILE=3 SUPL_MODE=1 SUPL_ES=0 3 com.google.android.carrierentitlement com.google.android.carrierentitlement.CarrierEntitlementActivity com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK_RESULT ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc310-mnc560/config.xml ================================================ com.google.android.carrierentitlement com.google.android.carrierentitlement.CarrierEntitlementActivity com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK_RESULT ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc310-mnc680/config.xml ================================================ com.google.android.carrierentitlement com.google.android.carrierentitlement.CarrierEntitlementActivity com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK_RESULT ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc311-mnc180/config.xml ================================================ com.google.android.carrierentitlement com.google.android.carrierentitlement.CarrierEntitlementActivity com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK_RESULT ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc311-mnc220/config.xml ================================================ SUPL_HOST=supl.google.com SUPL_PORT=7275 XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin NTP_SERVER=north-america.pool.ntp.org SUPL_VER=0x20000 NMEA_PROVIDER=0 A_GLONASS_POS_PROTOCOL_SELECT=0 ERR_ESTIMATE=0 INTERMEDIATE_POS=0 GPS_LOCK=3 LPP_PROFILE=2 SUPL_MODE=1 SUPL_ES=0 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc311-mnc221/config.xml ================================================ SUPL_HOST=supl.google.com SUPL_PORT=7275 XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin NTP_SERVER=north-america.pool.ntp.org SUPL_VER=0x20000 NMEA_PROVIDER=0 A_GLONASS_POS_PROTOCOL_SELECT=0 ERR_ESTIMATE=0 INTERMEDIATE_POS=0 GPS_LOCK=3 LPP_PROFILE=2 SUPL_MODE=1 SUPL_ES=0 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc311-mnc222/config.xml ================================================ SUPL_HOST=supl.google.com SUPL_PORT=7275 XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin NTP_SERVER=north-america.pool.ntp.org SUPL_VER=0x20000 NMEA_PROVIDER=0 A_GLONASS_POS_PROTOCOL_SELECT=0 ERR_ESTIMATE=0 INTERMEDIATE_POS=0 GPS_LOCK=3 LPP_PROFILE=2 SUPL_MODE=1 SUPL_ES=0 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc311-mnc223/config.xml ================================================ SUPL_HOST=supl.google.com SUPL_PORT=7275 XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin NTP_SERVER=north-america.pool.ntp.org SUPL_VER=0x20000 NMEA_PROVIDER=0 A_GLONASS_POS_PROTOCOL_SELECT=0 ERR_ESTIMATE=0 INTERMEDIATE_POS=0 GPS_LOCK=3 LPP_PROFILE=2 SUPL_MODE=1 SUPL_ES=0 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc311-mnc224/config.xml ================================================ SUPL_HOST=supl.google.com SUPL_PORT=7275 XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin NTP_SERVER=north-america.pool.ntp.org SUPL_VER=0x20000 NMEA_PROVIDER=0 A_GLONASS_POS_PROTOCOL_SELECT=0 ERR_ESTIMATE=0 INTERMEDIATE_POS=0 GPS_LOCK=3 LPP_PROFILE=2 SUPL_MODE=1 SUPL_ES=0 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc311-mnc225/config.xml ================================================ SUPL_HOST=supl.google.com SUPL_PORT=7275 XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin NTP_SERVER=north-america.pool.ntp.org SUPL_VER=0x20000 NMEA_PROVIDER=0 A_GLONASS_POS_PROTOCOL_SELECT=0 ERR_ESTIMATE=0 INTERMEDIATE_POS=0 GPS_LOCK=3 LPP_PROFILE=2 SUPL_MODE=1 SUPL_ES=1 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc311-mnc226/config.xml ================================================ SUPL_HOST=supl.google.com SUPL_PORT=7275 XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin NTP_SERVER=north-america.pool.ntp.org SUPL_VER=0x20000 NMEA_PROVIDER=0 A_GLONASS_POS_PROTOCOL_SELECT=0 ERR_ESTIMATE=0 INTERMEDIATE_POS=0 GPS_LOCK=3 LPP_PROFILE=2 SUPL_MODE=1 SUPL_ES=0 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc311-mnc227/config.xml ================================================ SUPL_HOST=supl.google.com SUPL_PORT=7275 XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin NTP_SERVER=north-america.pool.ntp.org SUPL_VER=0x20000 NMEA_PROVIDER=0 A_GLONASS_POS_PROTOCOL_SELECT=0 ERR_ESTIMATE=0 INTERMEDIATE_POS=0 GPS_LOCK=3 LPP_PROFILE=2 SUPL_MODE=1 SUPL_ES=0 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc311-mnc228/config.xml ================================================ SUPL_HOST=supl.google.com SUPL_PORT=7275 XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin NTP_SERVER=north-america.pool.ntp.org SUPL_VER=0x20000 NMEA_PROVIDER=0 A_GLONASS_POS_PROTOCOL_SELECT=0 ERR_ESTIMATE=0 INTERMEDIATE_POS=0 GPS_LOCK=3 LPP_PROFILE=2 SUPL_MODE=1 SUPL_ES=0 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc311-mnc229/config.xml ================================================ SUPL_HOST=supl.google.com SUPL_PORT=7275 XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin NTP_SERVER=north-america.pool.ntp.org SUPL_VER=0x20000 NMEA_PROVIDER=0 A_GLONASS_POS_PROTOCOL_SELECT=0 ERR_ESTIMATE=0 INTERMEDIATE_POS=0 GPS_LOCK=3 LPP_PROFILE=2 SUPL_MODE=1 SUPL_ES=0 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc311-mnc480/config.xml ================================================ *86 1 4 7 9 false SUPL_HOST=supl.google.com SUPL_PORT=7275 XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin NTP_SERVER=north-america.pool.ntp.org SUPL_VER=0x20000 NMEA_PROVIDER=0 A_GLONASS_POS_PROTOCOL_SELECT=0 ERR_ESTIMATE=0 INTERMEDIATE_POS=0 GPS_LOCK=3 LPP_PROFILE=3 SUPL_MODE=0 SUPL_ES=1 com.google.android.carrierentitlement com.google.android.carrierentitlement.CarrierEntitlementActivity com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK_RESULT ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc311-mnc490/config.xml ================================================ true 1422 1 4 7 9 51200 SUPL_HOST=supl.google.com SUPL_PORT=7275 XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin NTP_SERVER=north-america.pool.ntp.org SUPL_VER=0x20000 NMEA_PROVIDER=0 A_GLONASS_POS_PROTOCOL_SELECT=0 ERR_ESTIMATE=0 INTERMEDIATE_POS=0 GPS_LOCK=3 LPP_PROFILE=2 SUPL_MODE=1 SUPL_ES=0 300 com.google.android.carrierentitlement com.google.android.carrierentitlement.CarrierEntitlementActivity com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK_RESULT ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc311-mnc580/config.xml ================================================ SUPL_HOST=supl.google.com SUPL_PORT=7275 XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin NTP_SERVER=north-america.pool.ntp.org SUPL_VER=0x20000 NMEA_PROVIDER=0 A_GLONASS_POS_PROTOCOL_SELECT=0 ERR_ESTIMATE=0 INTERMEDIATE_POS=0 GPS_LOCK=3 LPP_PROFILE=2 SUPL_MODE=1 SUPL_ES=0 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc311-mnc581/config.xml ================================================ SUPL_HOST=supl.google.com SUPL_PORT=7275 XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin NTP_SERVER=north-america.pool.ntp.org SUPL_VER=0x20000 NMEA_PROVIDER=0 A_GLONASS_POS_PROTOCOL_SELECT=0 ERR_ESTIMATE=0 INTERMEDIATE_POS=0 GPS_LOCK=3 LPP_PROFILE=2 SUPL_MODE=1 SUPL_ES=0 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc311-mnc582/config.xml ================================================ SUPL_HOST=supl.google.com SUPL_PORT=7275 XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin NTP_SERVER=north-america.pool.ntp.org SUPL_VER=0x20000 NMEA_PROVIDER=0 A_GLONASS_POS_PROTOCOL_SELECT=0 ERR_ESTIMATE=0 INTERMEDIATE_POS=0 GPS_LOCK=3 LPP_PROFILE=2 SUPL_MODE=1 SUPL_ES=0 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc311-mnc583/config.xml ================================================ SUPL_HOST=supl.google.com SUPL_PORT=7275 XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin NTP_SERVER=north-america.pool.ntp.org SUPL_VER=0x20000 NMEA_PROVIDER=0 A_GLONASS_POS_PROTOCOL_SELECT=0 ERR_ESTIMATE=0 INTERMEDIATE_POS=0 GPS_LOCK=3 LPP_PROFILE=2 SUPL_MODE=1 SUPL_ES=0 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc311-mnc584/config.xml ================================================ SUPL_HOST=supl.google.com SUPL_PORT=7275 XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin NTP_SERVER=north-america.pool.ntp.org SUPL_VER=0x20000 NMEA_PROVIDER=0 A_GLONASS_POS_PROTOCOL_SELECT=0 ERR_ESTIMATE=0 INTERMEDIATE_POS=0 GPS_LOCK=3 LPP_PROFILE=2 SUPL_MODE=1 SUPL_ES=0 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc311-mnc585/config.xml ================================================ SUPL_HOST=supl.google.com SUPL_PORT=7275 XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin NTP_SERVER=north-america.pool.ntp.org SUPL_VER=0x20000 NMEA_PROVIDER=0 A_GLONASS_POS_PROTOCOL_SELECT=0 ERR_ESTIMATE=0 INTERMEDIATE_POS=0 GPS_LOCK=3 LPP_PROFILE=2 SUPL_MODE=1 SUPL_ES=0 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc311-mnc586/config.xml ================================================ SUPL_HOST=supl.google.com SUPL_PORT=7275 XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin NTP_SERVER=north-america.pool.ntp.org SUPL_VER=0x20000 NMEA_PROVIDER=0 A_GLONASS_POS_PROTOCOL_SELECT=0 ERR_ESTIMATE=0 INTERMEDIATE_POS=0 GPS_LOCK=3 LPP_PROFILE=2 SUPL_MODE=1 SUPL_ES=0 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc311-mnc587/config.xml ================================================ SUPL_HOST=supl.google.com SUPL_PORT=7275 XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin NTP_SERVER=north-america.pool.ntp.org SUPL_VER=0x20000 NMEA_PROVIDER=0 A_GLONASS_POS_PROTOCOL_SELECT=0 ERR_ESTIMATE=0 INTERMEDIATE_POS=0 GPS_LOCK=3 LPP_PROFILE=2 SUPL_MODE=1 SUPL_ES=0 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc311-mnc588/config.xml ================================================ SUPL_HOST=supl.google.com SUPL_PORT=7275 XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin NTP_SERVER=north-america.pool.ntp.org SUPL_VER=0x20000 NMEA_PROVIDER=0 A_GLONASS_POS_PROTOCOL_SELECT=0 ERR_ESTIMATE=0 INTERMEDIATE_POS=0 GPS_LOCK=3 LPP_PROFILE=2 SUPL_MODE=1 SUPL_ES=0 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc311-mnc589/config.xml ================================================ SUPL_HOST=supl.google.com SUPL_PORT=7275 XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin NTP_SERVER=north-america.pool.ntp.org SUPL_VER=0x20000 NMEA_PROVIDER=0 A_GLONASS_POS_PROTOCOL_SELECT=0 ERR_ESTIMATE=0 INTERMEDIATE_POS=0 GPS_LOCK=3 LPP_PROFILE=2 SUPL_MODE=1 SUPL_ES=0 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc311-mnc870/config.xml ================================================ true 1422 1 4 7 9 51200 SUPL_HOST=supl.google.com SUPL_PORT=7275 XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin NTP_SERVER=north-america.pool.ntp.org SUPL_VER=0x20000 NMEA_PROVIDER=0 A_GLONASS_POS_PROTOCOL_SELECT=0 ERR_ESTIMATE=0 INTERMEDIATE_POS=0 GPS_LOCK=3 LPP_PROFILE=2 SUPL_MODE=1 SUPL_ES=0 300 com.google.android.carrierentitlement com.google.android.carrierentitlement.CarrierEntitlementActivity com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK_RESULT ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc312-mnc530/config.xml ================================================ com.google.android.carrierentitlement com.google.android.carrierentitlement.CarrierEntitlementActivity com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK com.google.android.carrierentitlement.SILENT_ENTITLEMENT_CHECK_RESULT ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc316-mnc010/config.xml ================================================ 1422 1 4 7 9 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc330-mnc110/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc334-mnc020/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc334-mnc050/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc334-mnc090/config.xml ================================================ true Modem,modem.nexteldata.com.mx,,,,,,,,,334,090,,DUN ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc334-mnc30/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc370-mnc02/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc404-mnc01/config.xml ================================================ false ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc840/config.xml ================================================ LPP_PROFILE=2 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc840/strings.xml ================================================ Wi-Fi Calling ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc854/config.xml ================================================ LPP_PROFILE=2 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc855/config.xml ================================================ LPP_PROFILE=2 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc855/strings.xml ================================================ Wi-Fi Calling ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc856/config.xml ================================================ LPP_PROFILE=2 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc856/strings.xml ================================================ Wi-Fi Calling ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc857/config.xml ================================================ LPP_PROFILE=2 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc857/strings.xml ================================================ Wi-Fi Calling ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc858/config.xml ================================================ LPP_PROFILE=2 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc858/strings.xml ================================================ Wi-Fi Calling ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc859/config.xml ================================================ LPP_PROFILE=2 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc859/strings.xml ================================================ Wi-Fi Calling ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc860/config.xml ================================================ LPP_PROFILE=2 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc860/strings.xml ================================================ Wi-Fi Calling ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc861/config.xml ================================================ LPP_PROFILE=2 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc861/strings.xml ================================================ Wi-Fi Calling ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc862/config.xml ================================================ LPP_PROFILE=2 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc862/strings.xml ================================================ Wi-Fi Calling ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc863/config.xml ================================================ LPP_PROFILE=2 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc863/strings.xml ================================================ Wi-Fi Calling ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc864/config.xml ================================================ LPP_PROFILE=2 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc864/strings.xml ================================================ Wi-Fi Calling ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc865/config.xml ================================================ LPP_PROFILE=2 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc865/strings.xml ================================================ Wi-Fi Calling ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc866/config.xml ================================================ LPP_PROFILE=2 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc866/strings.xml ================================================ Wi-Fi Calling ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc867/config.xml ================================================ LPP_PROFILE=2 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc867/strings.xml ================================================ Wi-Fi Calling ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc868/config.xml ================================================ LPP_PROFILE=2 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc868/strings.xml ================================================ Wi-Fi Calling ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc869/config.xml ================================================ LPP_PROFILE=2 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc869/strings.xml ================================================ Wi-Fi Calling ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc870/config.xml ================================================ LPP_PROFILE=2 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc870/strings.xml ================================================ Wi-Fi Calling ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc871/config.xml ================================================ LPP_PROFILE=2 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc871/strings.xml ================================================ Wi-Fi Calling ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc872/config.xml ================================================ LPP_PROFILE=2 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc872/strings.xml ================================================ Wi-Fi Calling ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc873/config.xml ================================================ LPP_PROFILE=2 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc873/strings.xml ================================================ Wi-Fi Calling ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc874/config.xml ================================================ LPP_PROFILE=2 ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc405-mnc874/strings.xml ================================================ Wi-Fi Calling ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc505-mnc01/config.xml ================================================ +61101 false ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc505-mnc11/config.xml ================================================ +61101 false ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc505-mnc71/config.xml ================================================ +61101 false ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc505-mnc72/config.xml ================================================ +61101 false ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc706-mnc01/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc712-mnc03/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc714-mnc03/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc716-mnc06/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc716-mnc10/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc716-mnc17/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc722-mnc02/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc722-mnc07/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc722-mnc310/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc722-mnc34/config.xml ================================================ true Personal Internet Movil,internet.personal.com,,,internet,internet,,,,,722,34,1,DUN ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc722-mnc340/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc722-mnc341/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc722-mnc36/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc724-mnc02/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc724-mnc03/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc724-mnc04/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc724-mnc05/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc724-mnc06/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc724-mnc10/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc724-mnc11/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc724-mnc16/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc724-mnc23/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc724-mnc24/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc724-mnc31/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc724-mnc39/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc730-mnc01/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc730-mnc02/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc730-mnc09/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc730-mnc10/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc732-mnc101/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc732-mnc103/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc732-mnc111/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc732-mnc12/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc732-mnc123/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc732-mnc130/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc734-mnc04/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc740-mnc01/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc744-mnc02/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/values-mcc748-mnc10/config.xml ================================================ true ================================================ FILE: overlay/frameworks/base/core/res/res/xml/power_profile.xml ================================================ 0 80 240 93.5 1 1 115 200 30 123 90 159 41 3.9 2.8 384000 460800 600000 672000 768000 864000 960000 1248000 1344000 1478400 1555200 384000 480000 633600 768000 864000 960000 1248000 1344000 1440000 1536000 1632000 1766000 5.58 4.92 24.14 27.2 32.3 36.94 41.57 49.87 57.84 79.8 88.81 102.4 110.9 86.83 103.24 129.38 155.42 177.99 195.55 265.09 292.77 322.13 348.19 370.18 405.51 4 4 3300 .0002 .002 .02 .2 2 ================================================ FILE: overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml ================================================ 60000 true 82 ================================================ FILE: overlay/frameworks/base/packages/SystemUI/res/values/config.xml ================================================ true 10s,30s,60s,180s true 0 true ================================================ FILE: overlay/frameworks/opt/telephony/resources/res/values-mcc310-mnc030/config.xml ================================================ ================================================ FILE: overlay/frameworks/opt/telephony/resources/res/values-mcc310-mnc070/config.xml ================================================ ================================================ FILE: overlay/frameworks/opt/telephony/resources/res/values-mcc310-mnc080/config.xml ================================================ ================================================ FILE: overlay/frameworks/opt/telephony/resources/res/values-mcc310-mnc150/config.xml ================================================ ================================================ FILE: overlay/frameworks/opt/telephony/resources/res/values-mcc310-mnc170/config.xml ================================================ ================================================ FILE: overlay/frameworks/opt/telephony/resources/res/values-mcc310-mnc280/config.xml ================================================ ================================================ FILE: overlay/frameworks/opt/telephony/resources/res/values-mcc310-mnc380/config.xml ================================================ ================================================ FILE: overlay/frameworks/opt/telephony/resources/res/values-mcc310-mnc410/config.xml ================================================ ================================================ FILE: overlay/frameworks/opt/telephony/resources/res/values-mcc310-mnc560/config.xml ================================================ ================================================ FILE: overlay/frameworks/opt/telephony/resources/res/values-mcc310-mnc680/config.xml ================================================ ================================================ FILE: overlay/packages/apps/Bluetooth/res/values/config.xml ================================================ true true true true ================================================ FILE: overlay/packages/apps/CarrierConfig/res/xml/vendor.xml ================================================ ================================================ FILE: overlay/packages/apps/CellBroadcastReceiver/res/values/config.xml ================================================ true true true ================================================ FILE: overlay/packages/apps/Dialer/res/values/config.xml ================================================ true 4 ================================================ FILE: overlay/packages/apps/Mms/res/values/config.xml ================================================ true ================================================ FILE: overlay/packages/apps/Settings/res/values/config.xml ================================================ true 1 ================================================ FILE: overlay/packages/apps/Settings/res/values/dimens.xml ================================================ 5dp 73.91% ================================================ FILE: overlay/packages/apps/Snap/res/values/arrays.xml ================================================ @string/pref_camera_scenemode_entry_auto @string/pref_camera_scenemode_entry_steadyphoto @string/pref_camera_scenemode_entry_hdr @string/pref_camera_scenemode_entry_asd @string/pref_camera_advanced_feature_entry_chromaflash @string/pref_camera_scenemode_entry_sports auto steadyphoto hdr asd chroma-flash-on sports @drawable/ic_scene_mode_auto @drawable/ic_scene_mode_entry_steadyphoto @drawable/ic_scene_mode_hdr @drawable/ic_scene_mode_smartauto @drawable/ic_scene_mode_entry_dark @drawable/ic_scene_mode_sports ================================================ FILE: overlay/packages/apps/Snap/res/values/cm_strings.xml ================================================ Burst ClearShot ================================================ FILE: overlay/packages/apps/Snap/res/values/config.xml ================================================ 100 sports ================================================ FILE: overlay/packages/apps/Snap/res/values/qcomstrings.xml ================================================ false enable on enable on 1920x1080 ================================================ FILE: overlay/packages/services/Telecomm/res/values/config.xml ================================================ true ================================================ FILE: overlay/packages/services/Telephony/res/values/config.xml ================================================ 1 true true true true true true true true false ================================================ FILE: overlay/vendor/cmsdk/cm/res/res/values/config.xml ================================================ true 100 true 12000 43 ================================================ FILE: proprietary-files.txt ================================================ # ACDB etc/acdbdata/MTP/MTP_Bluetooth_cal.acdb etc/acdbdata/MTP/MTP_General_cal.acdb etc/acdbdata/MTP/MTP_Global_cal.acdb etc/acdbdata/MTP/MTP_Handset_cal.acdb etc/acdbdata/MTP/MTP_Hdmi_cal.acdb etc/acdbdata/MTP/MTP_Headset_cal.acdb etc/acdbdata/MTP/MTP_Speaker_cal.acdb # ADSP bin/adsprpcd vendor/lib/libadsprpc.so vendor/lib/libfastcvopt.so vendor/lib64/libadsprpc.so # Audio etc/firmware/tfa98xx.cnt vendor/lib/libacdb-fts.so vendor/lib/libacdbloader.so vendor/lib/libacdbrtac.so vendor/lib/libadiertac.so vendor/lib/libaudcal.so vendor/lib/libhwdaphal.so vendor/lib/soundfx/libqcbassboost.so vendor/lib/soundfx/libqcreverb.so vendor/lib/soundfx/libqcvirt.so vendor/lib64/libacdb-fts.so vendor/lib64/libacdbloader.so vendor/lib64/libacdbrtac.so vendor/lib64/libadiertac.so vendor/lib64/libaudcal.so vendor/lib64/libhwdaphal.so # Bluetooth bin/btnvtool bin/hci_qcomm_init bin/wcnss_filter etc/firmware/nvm_tlv.bin etc/firmware/nvm_tlv_1.3.bin etc/firmware/nvm_tlv_2.1.bin etc/firmware/nvm_tlv_3.0.bin etc/firmware/nvm_tlv_3.2.bin etc/firmware/rampatch_tlv.img etc/firmware/rampatch_tlv_1.3.tlv etc/firmware/rampatch_tlv_2.1.tlv etc/firmware/rampatch_tlv_3.0.tlv etc/firmware/rampatch_tlv_3.2.tlv vendor/lib/libbtnv.so vendor/lib64/libbtnv.so # Camera bin/mm-qcamera-app bin/mm-qcamera-daemon lib/hw/camera.msm8994.so:lib/hw/camera.vendor.msm8994.so lib/libFNVfbEngineLib.so lib/libmm-qcamera.so lib/libmmcamera_interface.so lib/libmmjpeg_interface.so lib/libmorpho_video_refiner.so lib/libopcamerahw_interface.so lib/libqomx_core.so lib64/libopcamera.so lib64/libopcameralib.so vendor/lib/libfastcvadsp_stub.so vendor/lib/libflash_pmic.so vendor/lib/libjpegdhw.so vendor/lib/libjpegdmahw.so vendor/lib/libjpegehw.so vendor/lib/libmmcamera2_c2d_module.so vendor/lib/libmmcamera2_cpp_module.so vendor/lib/libmmcamera2_frame_algorithm.so vendor/lib/libmmcamera2_iface_modules.so vendor/lib/libmmcamera2_imglib_modules.so vendor/lib/libmmcamera2_is.so vendor/lib/libmmcamera2_isp_modules.so vendor/lib/libmmcamera2_pp_buf_mgr.so vendor/lib/libmmcamera2_pproc_modules.so vendor/lib/libmmcamera2_q3a_core.so vendor/lib/libmmcamera2_sensor_debug.so vendor/lib/libmmcamera2_sensor_modules.so vendor/lib/libmmcamera2_stats_algorithm.so vendor/lib/libmmcamera2_stats_modules.so vendor/lib/libmmcamera2_vpe_module.so vendor/lib/libmmcamera2_wnr_module.so vendor/lib/libmmcamera_cac2_lib.so vendor/lib/libmmcamera_eeprom_util.so vendor/lib/libmmcamera_eztune_module.so vendor/lib/libmmcamera_faceproc.so vendor/lib/libmmcamera_hdr_gb_lib.so vendor/lib/libmmcamera_imglib.so vendor/lib/libmmcamera_pdaf.so vendor/lib/libmmcamera_pdafcamif.so vendor/lib/libmmcamera_ppbase_module.so vendor/lib/libmmcamera_tintless_algo.so vendor/lib/libmmcamera_tintless_bg_pca_algo.so vendor/lib/libmmcamera_tuning.so vendor/lib/libmmcamera_vpu_module.so vendor/lib/libmmipl.so vendor/lib/libmmjpeg.so vendor/lib/libmmqjpeg_codec.so vendor/lib/libmmqjpegdma.so vendor/lib/liboemcamera.so vendor/lib/libois_rohm_bu63165gwl.so vendor/lib/libqomx_jpegdec.so vendor/lib/libqomx_jpegenc_pipe.so vendor/lib64/libmmcamera2_q3a_core.so vendor/lib64/libmmcamera2_sensor_debug.so vendor/lib64/libmmcamera2_stats_algorithm.so # Camera actuators vendor/lib/libactuator_rohm_bu63165gwl.so vendor/lib/libactuator_rohm_bu63165gwl_camcorder.so vendor/lib/libactuator_rohm_bu63165gwl_camera.so # Camera chromatix vendor/lib/libchromatix_ov13860_common.so vendor/lib/libchromatix_ov13860_cpp_hfr.so vendor/lib/libchromatix_ov13860_cpp_liveshot.so vendor/lib/libchromatix_ov13860_cpp_panorama.so vendor/lib/libchromatix_ov13860_cpp_preview.so vendor/lib/libchromatix_ov13860_cpp_snapshot.so vendor/lib/libchromatix_ov13860_cpp_video.so vendor/lib/libchromatix_ov13860_cpp_zsl.so vendor/lib/libchromatix_ov13860_default_video.so vendor/lib/libchromatix_ov13860_hfr.so vendor/lib/libchromatix_ov13860_liveshot.so vendor/lib/libchromatix_ov13860_panorama.so vendor/lib/libchromatix_ov13860_postproc.so vendor/lib/libchromatix_ov13860_preview.so vendor/lib/libchromatix_ov13860_quarter_size_video.so vendor/lib/libchromatix_ov13860_snapshot.so vendor/lib/libchromatix_ov13860_zsl.so vendor/lib/libchromatix_ov5648_15fps_cpp_liveshot.so vendor/lib/libchromatix_ov5648_15fps_cpp_preview.so vendor/lib/libchromatix_ov5648_15fps_cpp_snapshot.so vendor/lib/libchromatix_ov5648_15fps_cpp_video.so vendor/lib/libchromatix_ov5648_15fps_postproc.so vendor/lib/libchromatix_ov5648_15fps_preview.so vendor/lib/libchromatix_ov5648_15fps_snapshot.so vendor/lib/libchromatix_ov5648_15fps_video.so vendor/lib/libchromatix_ov5648_30fps_cpp_liveshot.so vendor/lib/libchromatix_ov5648_30fps_cpp_preview.so vendor/lib/libchromatix_ov5648_30fps_cpp_snapshot.so vendor/lib/libchromatix_ov5648_30fps_cpp_video.so vendor/lib/libchromatix_ov5648_30fps_postproc.so vendor/lib/libchromatix_ov5648_30fps_preview.so vendor/lib/libchromatix_ov5648_30fps_snapshot.so vendor/lib/libchromatix_ov5648_30fps_video.so vendor/lib/libchromatix_ov5648_common.so # Camera firmware etc/firmware/cpp_firmware_v1_1_1.fw etc/firmware/cpp_firmware_v1_1_6.fw etc/firmware/cpp_firmware_v1_2_0.fw etc/firmware/cpp_firmware_v1_4_0.fw etc/firmware/cpp_firmware_v1_6_0.fw etc/firmware/cpp_firmware_v1_8_0.fw # Camera sensors vendor/lib/libmmcamera_isp_abf44.so vendor/lib/libmmcamera_isp_bcc44.so vendor/lib/libmmcamera_isp_be_stats44.so vendor/lib/libmmcamera_isp_bf_scale_stats46.so vendor/lib/libmmcamera_isp_bf_stats44.so vendor/lib/libmmcamera_isp_bg_stats46.so vendor/lib/libmmcamera_isp_bhist_stats44.so vendor/lib/libmmcamera_isp_bpc44.so vendor/lib/libmmcamera_isp_chroma_enhan40.so vendor/lib/libmmcamera_isp_chroma_suppress40.so vendor/lib/libmmcamera_isp_clamp_encoder40.so vendor/lib/libmmcamera_isp_clamp_video40.so vendor/lib/libmmcamera_isp_clamp_viewfinder40.so vendor/lib/libmmcamera_isp_clf46.so vendor/lib/libmmcamera_isp_color_correct46.so vendor/lib/libmmcamera_isp_color_xform_encoder46.so vendor/lib/libmmcamera_isp_color_xform_video46.so vendor/lib/libmmcamera_isp_color_xform_viewfinder46.so vendor/lib/libmmcamera_isp_cs_stats46.so vendor/lib/libmmcamera_isp_demosaic44.so vendor/lib/libmmcamera_isp_demux40.so vendor/lib/libmmcamera_isp_fovcrop_encoder46.so vendor/lib/libmmcamera_isp_fovcrop_video46.so vendor/lib/libmmcamera_isp_fovcrop_viewfinder46.so vendor/lib/libmmcamera_isp_gamma44.so vendor/lib/libmmcamera_isp_gic46.so vendor/lib/libmmcamera_isp_gtm46.so vendor/lib/libmmcamera_isp_hdr46.so vendor/lib/libmmcamera_isp_hdr_be_stats46.so vendor/lib/libmmcamera_isp_ihist_stats46.so vendor/lib/libmmcamera_isp_linearization40.so vendor/lib/libmmcamera_isp_ltm44.so vendor/lib/libmmcamera_isp_mce40.so vendor/lib/libmmcamera_isp_mesh_rolloff44.so vendor/lib/libmmcamera_isp_pedestal_correct46.so vendor/lib/libmmcamera_isp_rs_stats46.so vendor/lib/libmmcamera_isp_scaler_encoder46.so vendor/lib/libmmcamera_isp_scaler_video46.so vendor/lib/libmmcamera_isp_scaler_viewfinder46.so vendor/lib/libmmcamera_isp_sce40.so vendor/lib/libmmcamera_isp_sub_module.so vendor/lib/libmmcamera_isp_wb46.so vendor/lib/libmmcamera_ov13860.so vendor/lib/libmmcamera_ov13860_eeprom.so vendor/lib/libmmcamera_ov5648.so vendor/lib/libmmcamera_ov5648_eeprom.so # CNE bin/cnd etc/cne/SwimConfig.xml etc/cne/andsfCne.xml etc/permissions/ConnectivityExt.xml etc/permissions/cneapiclient.xml etc/permissions/com.quicinc.cne.xml framework/ConnectivityExt.jar framework/cneapiclient.jar framework/com.quicinc.cne.jar -priv-app/CNEService/CNEService.apk|df1c3a80a4a1a36915f423a7969cff1cdedddcb2 vendor/lib/libNimsWrap.so vendor/lib/libcne.so vendor/lib/libcneapiclient.so vendor/lib/libcneconn.so vendor/lib/libcneqmiutils.so vendor/lib/libvendorconn.so vendor/lib/libwqe.so vendor/lib/libxml.so vendor/lib64/libNimsWrap.so vendor/lib64/libcne.so vendor/lib64/libcneapiclient.so vendor/lib64/libcneconn.so vendor/lib64/libcneqmiutils.so vendor/lib64/libvendorconn.so vendor/lib64/libwqe.so vendor/lib64/libxml.so # Display calibration -etc/pp_calib_data_jd35695_1080p_cmd_mode_dsi_panel.xml # DPM bin/dpmd etc/dpm/dpm.conf etc/dpm/nsrm/NsrmConfiguration.xml etc/permissions/com.qti.dpmframework.xml etc/permissions/dpmapi.xml framework/com.qti.dpmframework.jar framework/dpmapi.jar framework/tcmclient.jar -priv-app/dpmserviceapp/dpmserviceapp.apk|27f91229cdbcec87edaf23c6b821c64a108dad83 vendor/lib/libdpmctmgr.so vendor/lib/libdpmfdmgr.so vendor/lib/libdpmframework.so vendor/lib/libdpmnsrm.so vendor/lib/libdpmtcm.so vendor/lib64/libdpmctmgr.so vendor/lib64/libdpmfdmgr.so vendor/lib64/libdpmframework.so vendor/lib64/libdpmnsrm.so vendor/lib64/libdpmtcm.so # DRM bin/qseecomd vendor/lib/libQSEEComAPI.so vendor/lib64/libQSEEComAPI.so vendor/lib64/libdrmfs.so vendor/lib64/libdrmtime.so vendor/lib64/librpmb.so vendor/lib64/libssd.so # Fingerprint sensor etc/firmware/fingerprints.b00 etc/firmware/fingerprints.b01 etc/firmware/fingerprints.b02 etc/firmware/fingerprints.b03 etc/firmware/fingerprints.mdt lib/hw/fingerprint.msm8994.so lib/lib_fpc_tac_shared.so lib64/hw/fingerprint.msm8994.so lib64/lib_fpc_tac_shared.so # Gatekeeper vendor/lib/hw/gatekeeper.msm8994.so vendor/lib64/hw/gatekeeper.msm8994.so # GPS bin/loc_launcher etc/permissions/com.qti.location.sdk.xml etc/permissions/com.qualcomm.location.xml framework/com.qti.location.sdk.jar|5f813d74715b42dc5175563cd5027269c5fe08fb -lib/libloc_api_v02.so -lib/libloc_ds_api.so -lib64/libloc_api_v02.so -lib64/libloc_ds_api.so -priv-app/com.qualcomm.location/com.qualcomm.location.apk|11c5e4aacb2e346645b9ab37f7f01d08a16e9297 vendor/bin/slim_daemon vendor/lib/hw/flp.default.so vendor/lib/libdataitems.so vendor/lib/libflp.so vendor/lib/libgeofence.so vendor/lib/libizat_core.so vendor/lib/liblbs_core.so vendor/lib/liblocationservice.so vendor/lib/liblocationservice_glue.so vendor/lib/liblowi_client.so vendor/lib/libquipc_os_api.so vendor/lib/libulp2.so vendor/lib/libxt_native.so vendor/lib/libxtadapter.so vendor/lib/libxtwifi_ulp_adaptor.so vendor/lib64/hw/flp.default.so vendor/lib64/libalarmservice_jni.so vendor/lib64/libdataitems.so vendor/lib64/libflp.so vendor/lib64/libgeofence.so vendor/lib64/libizat_core.so vendor/lib64/liblbs_core.so vendor/lib64/liblocationservice.so vendor/lib64/liblocationservice_glue.so vendor/lib64/liblowi_client.so vendor/lib64/liblowi_wifihal.so vendor/lib64/libquipc_os_api.so vendor/lib64/libulp2.so vendor/lib64/libxtadapter.so vendor/lib64/libxtwifi_ulp_adaptor.so # Graphics vendor/lib/egl/libQTapGLES.so vendor/lib/egl/libq3dtools_esx.so vendor/lib/libOpenCL.so vendor/lib64/egl/libQTapGLES.so vendor/lib64/egl/libq3dtools_esx.so vendor/lib64/libOpenCL.so # Graphics firmware etc/firmware/a420_pfp.fw etc/firmware/a420_pm4.fw # Keystore vendor/lib/hw/keystore.msm8994.so vendor/lib64/hw/keystore.msm8994.so # Listen vendor/lib/hw/sound_trigger.primary.msm8994.so # Media vendor/lib/libDivxDrm.so vendor/lib/libI420colorconvert.so vendor/lib/libOmxAacDec.so vendor/lib/libOmxAmrwbplusDec.so vendor/lib/libOmxEvrcDec.so vendor/lib/libOmxQcelp13Dec.so vendor/lib/libOmxWmaDec.so vendor/lib/libSHIMDivxDrm.so vendor/lib/libmm-color-convertor.so vendor/lib/libmmosal.so vendor/lib64/libDivxDrm.so vendor/lib64/libI420colorconvert.so vendor/lib64/libOmxAacDec.so vendor/lib64/libOmxAmrwbplusDec.so vendor/lib64/libOmxWmaDec.so vendor/lib64/libSHIMDivxDrm.so vendor/lib64/libmm-color-convertor.so vendor/lib64/libmmosal.so # Media firmware etc/firmware/venus.b00 etc/firmware/venus.b01 etc/firmware/venus.b02 etc/firmware/venus.b03 etc/firmware/venus.b04 etc/firmware/venus.mbn etc/firmware/venus.mdt # Network -priv-app/QtiTetherService/QtiTetherService.apk|1f88a499a74cff043a296637db1c1dcecaafdee7 vendor/lib/libconnctrl.so vendor/lib64/libconnctrl.so vendor/lib64/libQtiTether.so # Perf bin/energy-awareness bin/msm_irqbalance vendor/bin/perfd vendor/etc/perf-profile0.conf vendor/etc/perf-profile1.conf vendor/etc/perf-profile2.conf vendor/etc/perf-profile3.conf vendor/etc/perf-profile4.conf vendor/etc/perf-profile5.conf vendor/lib/libqti-perfd-client.so vendor/lib64/libqti-perfd-client.so # Peripheral manager bin/pm-proxy bin/pm-service vendor/lib/libperipheral_client.so vendor/lib64/libperipheral_client.so # Postprocessing bin/mm-pp-daemon vendor/lib/libdisp-aba.so vendor/lib/libmm-abl-oem.so -vendor/lib/libmm-abl.so vendor/lib/libmm-als.so vendor/lib64/libdisp-aba.so vendor/lib64/libmm-abl-oem.so -vendor/lib64/libmm-abl.so vendor/lib64/libmm-als.so # QMI bin/irsc_util etc/permissions/qti_permissions.xml -vendor/lib/libdiag.so vendor/lib/libdsi_netctrl.so -vendor/lib/libdsutils.so -vendor/lib/libidl.so -vendor/lib/libqcci_legacy.so vendor/lib/libqdi.so vendor/lib/libqdp.so -vendor/lib/libqmi.so -vendor/lib/libqmi_cci.so vendor/lib/libqmi_client_helper.so -vendor/lib/libqmi_client_qmux.so vendor/lib/libqmi_common_so.so vendor/lib/libqmi_csi.so vendor/lib/libqmi_encdec.so -vendor/lib/libqmiservices.so vendor/lib/libsmemlog.so -vendor/lib64/libdiag.so vendor/lib64/libdsi_netctrl.so -vendor/lib64/libdsutils.so -vendor/lib64/libidl.so -vendor/lib64/libqcci_legacy.so vendor/lib64/libqdi.so vendor/lib64/libqdp.so -vendor/lib64/libqmi.so -vendor/lib64/libqmi_cci.so vendor/lib64/libqmi_client_helper.so -vendor/lib64/libqmi_client_qmux.so vendor/lib64/libqmi_common_so.so vendor/lib64/libqmi_csi.so vendor/lib64/libqmi_encdec.so -vendor/lib64/libqmiservices.so vendor/lib64/libsmemlog.so # Radio -app/datastatusnotification/datastatusnotification.apk|d5b8dbdfb9010758dffec92851937ded0bcca43b -app/fastdormancy/fastdormancy.apk|3a7ba6ce1796fea35932b68a465071a1db72fef1 -app/QtiTelephonyService/QtiTelephonyService.apk|b3bd4921c583936d82d40582bde113fd58622efb -app/shutdownlistener/shutdownlistener.apk|5423f30ebab40e4a5b6609048681e060531e1eea bin/ipacm-diag bin/netmgrd bin/qmuxd bin/radish bin/rfs_access bin/rmt_storage etc/data/dsi_config.xml etc/data/netmgr_config.xml etc/data/qmi_config.xml etc/permissions/qcnvitems.xml etc/permissions/qcrilhook.xml etc/permissions/telephonyservice.xml -framework/qcnvitems.jar|8f1a22639392cef4e62bde005430a14bfa42d17e -framework/qcrilhook.jar|e94696ceea03cd31e159dc7fc10c5d694fe9fd94 framework/qti-telephony-common.jar|fbd9aa168759bca89327643a23a7d32aaa78f79a framework/QtiTelephonyServicelibrary.jar|1d4ff53f9229caaa91fe3994757bcd359a18b756 lib64/libparam.so -priv-app/qcrilmsgtunnel/qcrilmsgtunnel.apk|8d6a447cc4ee0ca78f6abb042b484c52775db9ed vendor/bin/qti -vendor/lib/libmdmdetect.so vendor/lib64/libconfigdb.so vendor/lib64/liblqe.so -vendor/lib64/libmdmdetect.so vendor/lib64/libnetmgr.so vendor/lib64/libqcmaputils.so vendor/lib64/libril-qc-qmi-1.so vendor/lib64/libril-qc-radioconfig.so vendor/lib64/libril-qcril-hook-oem.so vendor/lib64/libsystem_health_mon.so vendor/qcril.db # Radio - IMS bin/ims_rtp_daemon bin/imscmservice bin/imsdatadaemon bin/imsqmidaemon vendor/lib64/lib-dplmedia.so vendor/lib64/lib-ims-rcscmjni.so vendor/lib64/lib-imsSDP.so vendor/lib64/lib-imscamera.so vendor/lib64/lib-imsdpl.so vendor/lib64/lib-imsqimf.so vendor/lib64/lib-imsrcs.so vendor/lib64/lib-imsrcscm.so vendor/lib64/lib-imsrcscmclient.so vendor/lib64/lib-imsrcscmservice.so vendor/lib64/lib-imss.so vendor/lib64/lib-imsvt.so vendor/lib64/lib-imsxml.so vendor/lib64/lib-rcsimssjni.so vendor/lib64/lib-rtpcommon.so vendor/lib64/lib-rtpcore.so vendor/lib64/lib-rtpdaemoninterface.so vendor/lib64/lib-rtpsl.so vendor/lib64/libimscamera_jni.so vendor/lib64/libimsmedia_jni.so vendor/lib64/librcc.so vendor/lib64/libvoice-svc.so -vendor/app/ims/ims.apk|21f343af6b656ad1dc890b18fed940ad61e31fb0 -vendor/app/imssettings/imssettings.apk|87ada7621f77f9cf8efa27ebb46157c98df3a7cc # Sensors bin/sensors.qcom etc/sensors/sensor_def_qcomdev.conf vendor/lib/hw/activity_recognition.msm8994.so vendor/lib/libsensor1.so vendor/lib/libsensor_reg.so vendor/lib/libsensor_thresh.so vendor/lib/libsensor_user_cal.so vendor/lib/sensors.ssc.so vendor/lib64/hw/activity_recognition.msm8994.so vendor/lib64/libsensor1.so vendor/lib64/libsensor_reg.so vendor/lib64/libsensor_thresh.so vendor/lib64/libsensor_user_cal.so vendor/lib64/sensors.ssc.so # Thermal etc/thermal-engine.conf vendor/bin/thermal-engine vendor/lib/libthermalclient.so vendor/lib64/libthermalclient.so vendor/lib64/libthermalioctl.so # Time services -app/TimeService/TimeService.apk|5198efe6b554038a5c96962b381517a0274a26df bin/time_daemon vendor/lib/libTimeService.so -vendor/lib/libtime_genoff.so vendor/lib64/libTimeService.so -vendor/lib64/libtime_genoff.so # TP Firmware etc/firmware/tp/14049/14049_FW_S1302.img etc/firmware/tp/14049/14049_FW_S3320_jdi.img # Widevine vendor/lib/libWVStreamControlAPI_L3.so vendor/lib/libwvdrm_L3.so vendor/lib/mediadrm/libwvdrmengine.so # Wifi bin/cnss-daemon bin/cnss_diag -lib64/libwpa_qmi_eap_proxy.so ================================================ FILE: rootdir/Android.mk ================================================ LOCAL_PATH := $(call my-dir) # Device init scripts include $(CLEAR_VARS) LOCAL_MODULE := fstab.qcom LOCAL_MODULE_TAGS := optional eng LOCAL_MODULE_CLASS := ETC LOCAL_SRC_FILES := etc/fstab.qcom LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT) include $(BUILD_PREBUILT) include $(CLEAR_VARS) LOCAL_MODULE := init.qcom.power.rc LOCAL_MODULE_TAGS := optional eng LOCAL_MODULE_CLASS := ETC LOCAL_SRC_FILES := etc/init.qcom.power.rc LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT) include $(BUILD_PREBUILT) include $(CLEAR_VARS) LOCAL_MODULE := init.qcom.rc LOCAL_MODULE_TAGS := optional eng LOCAL_MODULE_CLASS := ETC LOCAL_SRC_FILES := etc/init.qcom.rc LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT) include $(BUILD_PREBUILT) include $(CLEAR_VARS) LOCAL_MODULE := init.qcom.sh LOCAL_MODULE_TAGS := optional eng LOCAL_MODULE_CLASS := ETC LOCAL_SRC_FILES := etc/init.qcom.sh LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT) include $(BUILD_PREBUILT) include $(CLEAR_VARS) LOCAL_MODULE := init.qcom.usb.rc LOCAL_MODULE_TAGS := optional eng LOCAL_MODULE_CLASS := ETC LOCAL_SRC_FILES := etc/init.qcom.usb.rc LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT) include $(BUILD_PREBUILT) include $(CLEAR_VARS) LOCAL_MODULE := init.qcom.usb.sh LOCAL_MODULE_TAGS := optional eng LOCAL_MODULE_CLASS := ETC LOCAL_SRC_FILES := etc/init.qcom.usb.sh LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT) include $(BUILD_PREBUILT) include $(CLEAR_VARS) LOCAL_MODULE := ueventd.qcom.rc LOCAL_MODULE_TAGS := optional eng LOCAL_MODULE_CLASS := ETC LOCAL_SRC_FILES := etc/ueventd.qcom.rc LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT) include $(BUILD_PREBUILT) # Configuration scripts include $(CLEAR_VARS) LOCAL_MODULE := init.qcom.bt.sh LOCAL_MODULE_TAGS := optional eng LOCAL_MODULE_CLASS := ETC LOCAL_SRC_FILES := etc/init.qcom.bt.sh include $(BUILD_PREBUILT) include $(CLEAR_VARS) LOCAL_MODULE := init.zram.sh LOCAL_MODULE_TAGS := optional eng LOCAL_MODULE_CLASS := ETC LOCAL_SRC_FILES := etc/init.zram.sh include $(BUILD_PREBUILT) ================================================ FILE: rootdir/etc/fstab.qcom ================================================ # Android fstab file. # The filesystem that contains the filesystem checker binary (typically /system) cannot # specify MF_CHECK, and must come before any filesystems that do specify MF_CHECK #TODO: Add 'check' as fs_mgr_flags with data partition. # Currently we dont have e2fsck compiled. So fs check would failed. # /dev/block/bootdevice/by-name/boot /boot emmc defaults defaults /dev/block/bootdevice/by-name/recovery /recovery emmc defaults defaults /dev/block/bootdevice/by-name/system /system ext4 ro,barrier=1 wait /dev/block/bootdevice/by-name/userdata /data ext4 nosuid,nodev,barrier=1 wait,check,encryptable=footer /dev/block/bootdevice/by-name/userdata /data f2fs rw,discard,nosuid,nodev,noatime,inline_xattr wait,check,encryptable=footer /dev/block/bootdevice/by-name/cache /cache ext4 nosuid,nodev,barrier=1 wait /dev/block/bootdevice/by-name/cache /cache f2fs rw,discard,nosuid,nodev,noatime,inline_xattr wait /dev/block/bootdevice/by-name/persist /persist ext4 nosuid,nodev,barrier=1 wait /dev/block/bootdevice/by-name/modem /firmware vfat ro,shortname=lower,uid=1000,gid=1000,dmask=227,fmask=337,context=u:object_r:firmware_file:s0 wait /dev/block/bootdevice/by-name/bluetooth /bt_firmware vfat ro,shortname=lower,uid=1002,gid=3002,dmask=222,fmask=333,context=u:object_r:bt_firmware_file:s0 wait /devices/soc.0/f9200000.ssusb/f9200000.dwc3/xhci-hcd* auto auto defaults voldmanaged=usbdisk:auto ================================================ FILE: rootdir/etc/init.qcom.bt.sh ================================================ #!/system/bin/sh # Copyright (c) 2009-2013, The Linux Foundation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of The Linux Foundation nor # the names of its contributors may be used to endorse or promote # products derived from this software without specific prior written # permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # #Read the arguments passed to the script config="$1" BLUETOOTH_SLEEP_PATH=/proc/bluetooth/sleep/proto LOG_TAG="qcom-bluetooth" LOG_NAME="${0}:" hciattach_pid="" loge () { /system/bin/log -t $LOG_TAG -p e "$LOG_NAME $@" } logi () { /system/bin/log -t $LOG_TAG -p i "$LOG_NAME $@" } failed () { loge "$1: exit code $2" exit $2 } program_bdaddr () { /system/bin/btnvtool -O logi "Bluetooth Address programmed successfully" } # # enable bluetooth profiles dynamically # config_bt () { baseband=`getprop ro.baseband` target=`getprop ro.board.platform` if [ -f /sys/devices/soc0/soc_id ]; then soc_hwid=`cat /sys/devices/soc0/soc_id` else soc_hwid=`cat /sys/devices/system/soc/soc0/id` fi btsoc=`getprop qcom.bluetooth.soc` case $baseband in "apq") setprop ro.qualcomm.bluetooth.opp true setprop ro.qualcomm.bluetooth.ftp true setprop ro.qualcomm.bluetooth.nap false setprop ro.bluetooth.sap false setprop ro.bluetooth.dun false # For MPQ as baseband is same for both case $soc_hwid in "130") setprop ro.qualcomm.bluetooth.hsp true setprop ro.qualcomm.bluetooth.hfp true setprop ro.qualcomm.bluetooth.pbap false setprop ro.qualcomm.bluetooth.map false ;; *) setprop ro.qualcomm.bluetooth.hsp false setprop ro.qualcomm.bluetooth.hfp false setprop ro.qualcomm.bluetooth.pbap true setprop ro.qualcomm.bluetooth.map true ;; esac ;; "mdm" | "svlte2a" | "svlte1" | "csfb") setprop ro.qualcomm.bluetooth.opp true setprop ro.qualcomm.bluetooth.hfp true setprop ro.qualcomm.bluetooth.hsp true setprop ro.qualcomm.bluetooth.pbap true setprop ro.qualcomm.bluetooth.ftp true setprop ro.qualcomm.bluetooth.map true setprop ro.qualcomm.bluetooth.nap true setprop ro.bluetooth.sap true case $target in "apq8084") setprop ro.bluetooth.dun true logi "Enabling BT-DUN for APQ8084" ;; *) setprop ro.bluetooth.dun false ;; esac ;; "msm") setprop ro.qualcomm.bluetooth.opp true setprop ro.qualcomm.bluetooth.hfp true setprop ro.qualcomm.bluetooth.hsp true setprop ro.qualcomm.bluetooth.pbap true setprop ro.qualcomm.bluetooth.ftp true setprop ro.qualcomm.bluetooth.nap true setprop ro.bluetooth.sap true setprop ro.bluetooth.dun true case $btsoc in "ath3k") setprop ro.qualcomm.bluetooth.map false ;; *) setprop ro.qualcomm.bluetooth.map true ;; esac ;; *) setprop ro.qualcomm.bluetooth.opp true setprop ro.qualcomm.bluetooth.hfp true setprop ro.qualcomm.bluetooth.hsp true setprop ro.qualcomm.bluetooth.pbap true setprop ro.qualcomm.bluetooth.ftp true setprop ro.qualcomm.bluetooth.map true setprop ro.qualcomm.bluetooth.nap true setprop ro.bluetooth.sap true setprop ro.bluetooth.dun true ;; esac #Enable Bluetooth Profiles specific to target Dynamically case $target in "msm8960") if [ "$btsoc" != "ath3k" ] && [ "$soc_hwid" != "130" ] then setprop ro.bluetooth.hfp.ver 1.6 setprop ro.qualcomm.bt.hci_transport smd fi ;; "msm8974" | "msm8226" | "msm8610" | "msm8916" | "msm8909" ) if [ "$btsoc" != "ath3k" ] then setprop ro.bluetooth.hfp.ver 1.6 setprop ro.qualcomm.bt.hci_transport smd fi ;; "apq8084" | "mpq8092" | "msm8994" | "msm8992" ) if [ "$btsoc" != "rome" ] then setprop ro.qualcomm.bt.hci_transport smd elif [ "$btsoc" = "rome" ] then setprop ro.bluetooth.hfp.ver 1.6 fi ;; *) ;; esac if [ -f /system/etc/bluetooth/stack.conf ]; then stack=`cat /system/etc/bluetooth/stack.conf` fi case "$stack" in "bluez") logi "Bluetooth stack is $stack" setprop ro.qc.bluetooth.stack $stack reason=`getprop vold.decrypt` case "$reason" in "trigger_restart_framework") start dbus ;; esac ;; *) logi "Bluetooth stack is Bluedroid" ;; esac } start_hciattach () { /system/bin/hciattach -n $BTS_DEVICE $BTS_TYPE $BTS_BAUD & hciattach_pid=$! logi "start_hciattach: pid = $hciattach_pid" echo 1 > $BLUETOOTH_SLEEP_PATH } kill_hciattach () { echo 0 > $BLUETOOTH_SLEEP_PATH logi "kill_hciattach: pid = $hciattach_pid" ## careful not to kill zero or null! kill -TERM $hciattach_pid # this shell doesn't exit now -- wait returns for normal exit } logi "init.qcom.bt.sh config = $config" case "$config" in "onboot") program_bdaddr config_bt exit 0 ;; *) ;; esac # mimic hciattach options parsing -- maybe a waste of effort USAGE="hciattach [-n] [-p] [-b] [-t timeout] [-s initial_speed] [speed] [flow|noflow] [bdaddr]" while getopts "blnpt:s:" f do case $f in b | l | n | p) opt_flags="$opt_flags -$f" ;; t) timeout=$OPTARG;; s) initial_speed=$OPTARG;; \?) echo $USAGE; exit 1;; esac done shift $(($OPTIND-1)) # Note that "hci_qcomm_init -e" prints expressions to set the shell variables # BTS_DEVICE, BTS_TYPE, BTS_BAUD, and BTS_ADDRESS. #Selectively Disable sleep BOARD=`getprop ro.board.platform` STACK=`getprop ro.qc.bluetooth.stack` # BR/EDR & LE power class configurations POWER_CLASS=`getprop qcom.bt.dev_power_class` LE_POWER_CLASS=`getprop qcom.bt.le_dev_pwr_class` #find the transport type TRANSPORT=`getprop ro.qualcomm.bt.hci_transport` logi "Transport : $TRANSPORT" case $STACK in "bluez") logi "** Bluez stack **" ;; *) logi "** Bluedroid stack **" setprop bluetooth.status off ;; esac case $POWER_CLASS in 1) PWR_CLASS="-p 0" ; logi "Power Class: 1";; 2) PWR_CLASS="-p 1" ; logi "Power Class: 2";; 3) PWR_CLASS="-p 2" ; logi "Power Class: CUSTOM";; *) PWR_CLASS=""; logi "Power Class: Ignored. Default(1) used (1-CLASS1/2-CLASS2/3-CUSTOM)"; logi "Power Class: To override, Before turning BT ON; setprop qcom.bt.dev_power_class <1 or 2 or 3>";; esac case $LE_POWER_CLASS in 1) LE_PWR_CLASS="-P 0" ; logi "LE Power Class: 1";; 2) LE_PWR_CLASS="-P 1" ; logi "LE Power Class: 2";; 3) LE_PWR_CLASS="-P 2" ; logi "LE Power Class: CUSTOM";; *) LE_PWR_CLASS="-P 1"; logi "LE Power Class: Ignored. Default(2) used (1-CLASS1/2-CLASS2/3-CUSTOM)"; logi "LE Power Class: To override, Before turning BT ON; setprop qcom.bt.le_dev_pwr_class <1 or 2 or 3>";; esac eval $(/system/bin/hci_qcomm_init -e $PWR_CLASS $LE_PWR_CLASS && echo "exit_code_hci_qcomm_init=0" || echo "exit_code_hci_qcomm_init=1") case $exit_code_hci_qcomm_init in 0) logi "Bluetooth QSoC firmware download succeeded, $BTS_DEVICE $BTS_TYPE $BTS_BAUD $BTS_ADDRESS";; *) failed "Bluetooth QSoC firmware download failed" $exit_code_hci_qcomm_init; case $STACK in "bluez") logi "** Bluez stack **" ;; *) logi "** Bluedroid stack **" setprop bluetooth.status off ;; esac exit $exit_code_hci_qcomm_init;; esac # init does SIGTERM on ctl.stop for service trap "kill_hciattach" TERM INT case $TRANSPORT in "smd") case $STACK in "bluez") logi "** Bluez stack **" echo 1 > /sys/module/hci_smd/parameters/hcismd_set ;; *) logi "** Bluedroid stack **" setprop bluetooth.status on ;; esac ;; *) logi "start hciattach" start_hciattach case $STACK in "bluez") logi "Bluetooth is turning On with Bluez stack " ;; *) logi "** Bluedroid stack **" setprop bluetooth.status on ;; esac wait $hciattach_pid logi "Bluetooth stopped" ;; esac exit 0 ================================================ FILE: rootdir/etc/init.qcom.power.rc ================================================ on boot # add a cpuset for the camera daemon # we want all the little cores for camera mkdir /dev/cpuset/camera-daemon write /dev/cpuset/camera-daemon/cpus 0 write /dev/cpuset/camera-daemon/mems 0 chown system system /dev/cpuset/camera-daemon chown system system /dev/cpuset/camera-daemon/tasks chmod 0664 /dev/cpuset/camera-daemon/tasks # update foreground cpuset now that processors are up # reserve CPU 3 for the top app and camera daemon write /dev/cpuset/foreground/cpus 0-2,4-7 write /dev/cpuset/foreground/boost/cpus 4-7 write /dev/cpuset/background/cpus 0 write /dev/cpuset/system-background/cpus 0-2 write /dev/cpuset/top-app/cpus 0-7 write /dev/cpuset/camera-daemon/cpus 0-3 on enable-low-power # Ensure at most one A57 is online when thermal hotplug is disabled write /sys/devices/system/cpu/cpu5/online 0 write /sys/devices/system/cpu/cpu6/online 0 write /sys/devices/system/cpu/cpu7/online 0 # Limit A57 max freq from msm_perf module in case CPU 4 is offline write /sys/module/msm_performance/parameters/cpu_max_freq "4:960000 5:960000 6:960000 7:960000" # Disable thermal bcl hotplug to switch governor write /sys/module/msm_thermal/core_control/enabled 0 write /sys/devices/soc.0/qcom,bcl.62/mode "disable" write /sys/devices/soc.0/qcom,bcl.62/hotplug_mask 0 write /sys/devices/soc.0/qcom,bcl.62/hotplug_soc_mask 0 write /sys/devices/soc.0/qcom,bcl.62/mode "enable" # Tune governor for little cores write /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor "interactive" write /sys/devices/system/cpu/cpu0/cpufreq/interactive/use_sched_load 1 write /sys/devices/system/cpu/cpu0/cpufreq/interactive/use_migration_notif 1 write /sys/devices/system/cpu/cpu0/cpufreq/interactive/above_hispeed_delay 19000 write /sys/devices/system/cpu/cpu0/cpufreq/interactive/go_hispeed_load 90 write /sys/devices/system/cpu/cpu0/cpufreq/interactive/timer_rate 20000 write /sys/devices/system/cpu/cpu0/cpufreq/interactive/hispeed_freq 960000 write /sys/devices/system/cpu/cpu0/cpufreq/interactive/io_is_busy 1 write /sys/devices/system/cpu/cpu0/cpufreq/interactive/target_loads 80 write /sys/devices/system/cpu/cpu0/cpufreq/interactive/min_sample_time 40000 write /sys/devices/system/cpu/cpu0/cpufreq/interactive/max_freq_hysteresis 80000 write /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq 384000 # Tune governors for big cores write /sys/devices/system/cpu/cpu4/online 1 write /sys/devices/system/cpu/cpu4/cpufreq/scaling_governor "interactive" write /sys/devices/system/cpu/cpu4/cpufreq/interactive/use_sched_load 1 write /sys/devices/system/cpu/cpu4/cpufreq/interactive/use_migration_notif 1 write /sys/devices/system/cpu/cpu4/cpufreq/interactive/above_hispeed_delay "19000 1400000:39000 1700000:19000" write /sys/devices/system/cpu/cpu4/cpufreq/interactive/go_hispeed_load 90 write /sys/devices/system/cpu/cpu4/cpufreq/interactive/timer_rate 20000 write /sys/devices/system/cpu/cpu4/cpufreq/interactive/hispeed_freq 1248000 write /sys/devices/system/cpu/cpu4/cpufreq/interactive/io_is_busy 1 write /sys/devices/system/cpu/cpu4/cpufreq/interactive/target_loads "85 1500000:90 1800000:70" write /sys/devices/system/cpu/cpu4/cpufreq/interactive/min_sample_time 40000 write /sys/devices/system/cpu/cpu4/cpufreq/interactive/max_freq_hysteresis 80000 write /sys/devices/system/cpu/cpu4/cpufreq/scaling_min_freq 384000 # Insert core_ctl module and use conservative paremeters insmod /system/lib/modules/hcube.ko write /sys/devices/system/cpu/cpu4/core_ctl/max_cpus 1 # Re-enable thermal and BCL hotplug write /sys/module/msm_thermal/core_control/enabled 1 write /sys/devices/soc.0/qcom,bcl.62/mode "disable" write /sys/devices/soc.0/qcom,bcl.62/hotplug_mask 192 write /sys/devices/soc.0/qcom,bcl.62/hotplug_soc_mask 240 write /sys/devices/soc.0/qcom,bcl.62/mode "enable" # Enable low power modes write /sys/module/lpm_levels/parameters/sleep_disabled 0 # Restore CPU 4 max freq from msm_performance write /sys/module/msm_performance/parameters/cpu_max_freq "4:4294967295 5:4294967295 6:4294967295 7:4294967295" # Input boost configuration write /sys/module/cpu_boost/parameters/input_boost_freq "0:1344000" write /sys/module/cpu_boost/parameters/input_boost_ms 40 # Configure core_ctl module parameters write /sys/devices/system/cpu/cpu4/core_ctl/max_cpus 4 write /sys/devices/system/cpu/cpu4/core_ctl/min_cpus 0 write /sys/devices/system/cpu/cpu4/core_ctl/busy_up_thres 70 write /sys/devices/system/cpu/cpu4/core_ctl/busy_down_thres 20 write /sys/devices/system/cpu/cpu4/core_ctl/offline_delay_ms 100 write /sys/devices/system/cpu/cpu4/core_ctl/is_big_cluster 1 write /sys/devices/system/cpu/cpu4/core_ctl/task_thres 4 # enable H-Cube tunings for big cores write /sys/devices/system/cpu/cpu4/core_ctl/hc_on 1 write /sys/devices/system/cpu/cpu4/core_ctl/hc_down_scale_on 1 write /sys/devices/system/cpu/cpu4/core_ctl/hc_thres_on 1 write /sys/devices/system/cpu/cpu4/core_ctl/hc_ro_use_gourd 1 write /sys/devices/system/cpu/cpu4/core_ctl/hc_correl_lvs "0 0 768000 1248000" write /sys/devices/system/cpu/cpu4/core_ctl/hc_correl_use_pcost 1 # Setting big.LITTLE scheduler parameters write /proc/sys/kernel/sched_migration_fixup 1 write /proc/sys/kernel/sched_small_task 30 write /proc/sys/kernel/sched_mostly_idle_load 20 write /proc/sys/kernel/sched_mostly_idle_nr_run 3 write /proc/sys/kernel/sched_upmigrate 99 write /proc/sys/kernel/sched_downmigrate 85 write /proc/sys/kernel/sched_freq_inc_notify 400000 write /proc/sys/kernel/sched_freq_dec_notify 400000 write /proc/sys/kernel/sched_boost 0 # Enable rps static configuration write /sys/class/net/rmnet_ipa0/queues/rx-0/rps_cpus 8 write /sys/class/devfreq/qcom,cpubw.33/governor "bw_hwmon" write /sys/class/devfreq/qcom,mincpubw.34/governor "cpufreq" # Set Memory parameters write /sys/module/lowmemorykiller/parameters/enable_adaptive_lmk 0 write /sys/module/lowmemorykiller/parameters/minfree "18432,23040,27648,32256,55296,80640" write /sys/module/lowmemorykiller/parameters/vmpressure_file_min 81250 # Set perfd properties rm /data/system/perfd/default_values setprop ro.min_freq_0 384000 setprop ro.min_freq_4 384000 start perfd service charger /charger class charger group log seclabel u:r:healthd:s0 on charger write /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor "powersave" write /sys/devices/system/cpu/cpu1/online 0 write /sys/devices/system/cpu/cpu2/online 0 write /sys/devices/system/cpu/cpu3/online 0 write /sys/module/lpm_levels/parameters/sleep_disabled 0 on class_start:late_start trigger enable-low-power on property:init.svc.recovery=running trigger enable-low-power on property:dev.bootcomplete=1 setprop sys.io.scheduler "bfq" ================================================ FILE: rootdir/etc/init.qcom.rc ================================================ # Copyright (c) 2009-2012, 2014-2015, The Linux Foundation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of The Linux Foundation nor # the names of its contributors may be used to endorse or promote # products derived from this software without specific prior written # permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # import init.qcom.power.rc import init.qcom.usb.rc on early-init symlink /data/tombstones /tombstones # Setup zram options write /sys/block/zram0/comp_algorithm lz4 write /proc/sys/vm/swappiness 100 on early-fs mkdir /firmware 0771 system system mkdir /bt_firmware 0771 system system mkdir /persist 0771 system system mount_all /fstab.qcom on init export LD_SHIM_LIBS "/system/vendor/lib64/lib-imscamera.so|libshim_ims-camera.so:/system/lib/libopcamerahw_interface.so|libshim_camera.so:/system/lib/libFNVfbEngineLib.so|libshim_camera.so" chmod 0644 /proc/cmdline symlink /sdcard /storage/sdcard0 # Slow Motion Scheduling Group mkdir /dev/cpuctl/smsg chown system system /dev/cpuctl/smsg/tasks chown system system /dev/cpuctl/smsg/cpu.cfs_period_us chown system system /dev/cpuctl/smsg/cpu.cfs_quota_us chown system system /dev/cpuctl/smsg/cpu.cfs_quota_us_per_task chmod 0666 /dev/cpuctl/smsg/tasks write /dev/cpuctl/smsg/cpu.shares 52 write /dev/cpuctl/smsg/cpu.upmigrate_discourage 1 # Add for fpc fingerprints permission chmod -h 777 /dev/qseecom chmod 0664 /sys/bus/spi/devices/spi12.0/irq chown system system /sys/bus/spi/devices/spi12.0/irq chmod 0660 /sys/bus/spi/devices/spi12.0/report_home chown system system /sys/bus/spi/devices/spi12.0/report_home chmod 0660 /sys/devices/soc/soc:fpc_fpc1020/update_info chown system system /sys/devices/soc/soc:fpc_fpc1020/update_info chmod 0660 /sys/bus/spi/devices/spi12.0/screen_state chown system system /sys/bus/spi/devices/spi12.0/screen_state chmod 0660 /sys/bus/spi/devices/spi12.0/clk_enable chown system system /sys/bus/spi/devices/spi12.0/clk_enable # Laser AF chown system system /dev/stmvl6180_ranging symlink /dev/input/event2 /dev/stm_sensor # Leds permission chown system system /sys/class/leds/led:flash_0/brightness chown system system /sys/class/leds/led:flash_1/brightness # Torch chown system system /sys/class/leds/led:torch_0/brightness chmod 0666 /sys/class/leds/led:torch_0/brightness chown system system /sys/class/leds/led:torch_1/brightness chmod 0666 /sys/class/leds/led:torch_1/brightness # Scheduler chown system system /sys/module/cpu_boost/parameters/sysctl_thermal_aware_scheduling # Display color calibration chown system system /sys/devices/platform/kcal_ctrl.0/kcal chown system system /sys/devices/platform/kcal_ctrl.0/kcal_enable chown system system /sys/devices/platform/kcal_ctrl.0/kcal_cont chown system system /sys/devices/platform/kcal_ctrl.0/kcal_hue chown system system /sys/devices/platform/kcal_ctrl.0/kcal_invert chown system system /sys/devices/platform/kcal_ctrl.0/kcal_min chown system system /sys/devices/platform/kcal_ctrl.0/kcal_sat chown system system /sys/devices/platform/kcal_ctrl.0/kcal_val # Touchscreen chown system radio /proc/touchpanel/double_tap_enable chmod 0660 /proc/touchpanel/double_tap_enable chown root system /proc/touchpanel/camera_enable chmod 0660 /proc/touchpanel/camera_enable chown root system /proc/touchpanel/music_enable chmod 0660 /proc/touchpanel/music_enable chown root system /proc/touchpanel/flashlight_enable chmod 0660 /proc/touchpanel/flashlight_enable # Buttons chown root system /proc/s1302/key_rep chmod 0660 /proc/s1302/key_rep chown root system /proc/s1302/virtual_key chmod 0660 /proc/s1302/virtual_key chown root system /proc/tri-state-key/keyCode_top chmod 0660 /proc/tri-state-key/keyCode_top chown root system /proc/tri-state-key/keyCode_middle chmod 0660 /proc/tri-state-key/keyCode_middle chown root system /proc/tri-state-key/keyCode_bottom chmod 0660 /proc/tri-state-key/keyCode_bottom # PCC Calibration chown system system /sys/devices/virtual/graphics/fb0/rgb chmod 0660 /sys/devices/virtual/graphics/fb0/rgb # for product mode flashlight chown system system /proc/qcom_flash # Modify for RGB light support chown system system /sys/class/leds/red/pause_lo chown system system /sys/class/leds/blue/pause_lo chown system system /sys/class/leds/green/pause_lo chown system system /sys/class/leds/red/pause_hi chown system system /sys/class/leds/blue/pause_hi chown system system /sys/class/leds/green/pause_hi chown system system /sys/class/leds/red/blink chown system system /sys/class/leds/blue/blink chown system system /sys/class/leds/green/blink # Modify for RGB breath effect control support chown system system /sys/class/leds/red/ramp_step_ms chown system system /sys/class/leds/blue/ramp_step_ms chown system system /sys/class/leds/green/ramp_step_ms chown system system /sys/class/leds/red/duty_pcts chown system system /sys/class/leds/blue/duty_pcts chown system system /sys/class/leds/green/duty_pcts chmod 660 /sys/class/leds/red/ramp_step_ms chmod 660 /sys/class/leds/green/ramp_step_ms chmod 660 /sys/class/leds/blue/ramp_step_ms chmod 660 /sys/class/leds/red/duty_pcts chmod 660 /sys/class/leds/green/duty_pcts chmod 660 /sys/class/leds/blue/duty_pcts # GPU Tuning chown root system /sys/class/kgsl/kgsl-3d0/dispatch/inflight chmod 0660 /sys/class/kgsl/kgsl-3d0/dispatch/inflight chown root system /sys/class/kgsl/kgsl-3d0/dispatch/inflight_low_latency chmod 0660 /sys/class/kgsl/kgsl-3d0/dispatch/inflight_low_latency # Enable cgroup_freezer mkdir /sys/fs/cgroup/freezer 0750 root system mount cgroup none /sys/fs/cgroup/freezer freezer chmod 777 /sys/fs/cgroup/freezer write /sys/module/printk/parameters/print_wall_time 1 # Access permission for secure touch chmod 0660 /sys/devices/soc.0/f9924000.i2c/i2c-2/2-0020/input/input0/secure_touch_enable chmod 0440 /sys/devices/soc.0/f9924000.i2c/i2c-2/2-0020/input/input0/secure_touch chmod 0660 /sys/devices/soc.0/f9924000.i2c/i2c-2/2-004a/secure_touch_enable chmod 0440 /sys/devices/soc.0/f9924000.i2c/i2c-2/2-004a/secure_touch chown system drmrpc /sys/devices/soc.0/f9924000.i2c/i2c-2/2-0020/input/input0/secure_touch_enable chown system drmrpc /sys/devices/soc.0/f9924000.i2c/i2c-2/2-0020/input/input0/secure_touch chown system drmrpc /sys/devices/soc.0/f9924000.i2c/i2c-2/2-004a/secure_touch_enable chown system drmrpc /sys/devices/soc.0/f9924000.i2c/i2c-2/2-004a/secure_touch write /proc/sys/kernel/sched_boost 1 write /proc/sys/vm/dirty_ratio 15 write /proc/sys/vm/dirty_background_ratio 1 # Modify for drv2605 support chmod 0666 /dev/drv2605 chown system system /dev/drv2605 on early-boot # set RLIMIT_MEMLOCK to 64MB setrlimit 8 67108864 67108864 write /sys/kernel/boot_adsp/boot 1 on boot start rmt_storage start rfs_access chown bluetooth bluetooth /sys/module/bluetooth_power/parameters/power chown bluetooth net_bt /sys/class/rfkill/rfkill0/type chown bluetooth net_bt /sys/class/rfkill/rfkill0/state chown bluetooth bluetooth /proc/bluetooth/sleep/proto chown bluetooth bluetooth /sys/module/hci_uart/parameters/ath_lpm chown bluetooth bluetooth /sys/module/hci_uart/parameters/ath_btwrite chown system system /sys/module/sco/parameters/disable_esco chown bluetooth bluetooth /sys/module/hci_smd/parameters/hcismd_set chmod 0660 /sys/module/bluetooth_power/parameters/power chmod 0660 /sys/module/hci_smd/parameters/hcismd_set chmod 0660 /sys/class/rfkill/rfkill0/state chmod 0660 /proc/bluetooth/sleep/proto chown bluetooth net_bt /dev/ttyHS0 chmod 0660 /sys/module/hci_uart/parameters/ath_lpm chmod 0660 /sys/module/hci_uart/parameters/ath_btwrite chmod 0660 /dev/ttyHS0 chown bluetooth bluetooth /sys/devices/platform/msm_serial_hs.0/clock chmod 0660 /sys/devices/platform/msm_serial_hs.0/clock chmod 0660 /dev/ttyHS2 chown bluetooth bluetooth /dev/ttyHS2 chown bluetooth net_bt /sys/class/rfkill/rfkill0/device/extldo chmod 0660 /sys/class/rfkill/rfkill0/device/extldo # Create QMUX deamon socket area mkdir /dev/socket/qmux_radio 0770 radio radio chmod 2770 /dev/socket/qmux_radio mkdir /dev/socket/qmux_audio 0770 media audio chmod 2770 /dev/socket/qmux_audio mkdir /dev/socket/qmux_bluetooth 0770 bluetooth bluetooth chmod 2770 /dev/socket/qmux_bluetooth mkdir /dev/socket/qmux_gps 0770 gps gps chmod 2770 /dev/socket/qmux_gps # Create NETMGR daemon socket area mkdir /dev/socket/netmgr 0750 radio radio setprop wifi.interface wlan0 setprop ro.telephony.call_ring.multiple false # Remove SUID bit for iproute2 ip tool chmod 0755 /system/bin/ip chmod 0444 /sys/devices/platform/msm_hsusb/gadget/usb_state setprop net.tcp.2g_init_rwnd 10 # Assign TCP buffer thresholds to be ceiling value of technology maximums # Increased technology maximums should be reflected here. write /proc/sys/net/core/rmem_max 8388608 write /proc/sys/net/core/wmem_max 8388608 #To allow interfaces to get v6 address when tethering is enabled write /proc/sys/net/ipv6/conf/rmnet0/accept_ra 2 write /proc/sys/net/ipv6/conf/rmnet1/accept_ra 2 write /proc/sys/net/ipv6/conf/rmnet2/accept_ra 2 write /proc/sys/net/ipv6/conf/rmnet3/accept_ra 2 write /proc/sys/net/ipv6/conf/rmnet4/accept_ra 2 write /proc/sys/net/ipv6/conf/rmnet5/accept_ra 2 write /proc/sys/net/ipv6/conf/rmnet6/accept_ra 2 write /proc/sys/net/ipv6/conf/rmnet7/accept_ra 2 write /proc/sys/net/ipv6/conf/rmnet_sdio0/accept_ra 2 write /proc/sys/net/ipv6/conf/rmnet_sdio1/accept_ra 2 write /proc/sys/net/ipv6/conf/rmnet_sdio2/accept_ra 2 write /proc/sys/net/ipv6/conf/rmnet_sdio3/accept_ra 2 write /proc/sys/net/ipv6/conf/rmnet_sdio4/accept_ra 2 write /proc/sys/net/ipv6/conf/rmnet_sdio5/accept_ra 2 write /proc/sys/net/ipv6/conf/rmnet_sdio6/accept_ra 2 write /proc/sys/net/ipv6/conf/rmnet_sdio7/accept_ra 2 write /proc/sys/net/ipv6/conf/rmnet_usb0/accept_ra 2 write /proc/sys/net/ipv6/conf/rmnet_usb1/accept_ra 2 write /proc/sys/net/ipv6/conf/rmnet_usb2/accept_ra 2 write /proc/sys/net/ipv6/conf/rmnet_usb3/accept_ra 2 # To prevent out of order acknowledgements from making # connection tracking to treat them as not belonging to # the connection they belong to. # Otherwise, a weird issue happens in which some long # connections on high-throughput links get dropped when # an ack packet comes out of order write /proc/sys/net/netfilter/nf_conntrack_tcp_be_liberal 1 # create symlink for fb1 as HDMI symlink /dev/graphics/fb1 /dev/graphics/hdmi # MDP idle notifier chown system graphics /sys/class/graphics/fb0/idle_time chmod 0664 /sys/class/graphics/fb0/idle_time # setup permissions for fb1 related nodes chown system graphics /sys/class/graphics/fb0/idle_time chown system graphics /sys/class/graphics/fb0/dynamic_fps chown system graphics /sys/class/graphics/fb0/dyn_pu chown system graphics /sys/class/graphics/fb0/modes chown system graphics /sys/class/graphics/fb0/mode chmod 0664 /sys/devices/virtual/graphics/fb0/idle_time chmod 0664 /sys/devices/virtual/graphics/fb0/dynamic_fps chmod 0664 /sys/devices/virtual/graphics/fb0/dyn_pu chmod 0664 /sys/devices/virtual/graphics/fb0/modes chmod 0664 /sys/devices/virtual/graphics/fb0/mode chown system graphics /sys/class/graphics/fb1/hpd chown system graphics /sys/class/graphics/fb1/res_info chown system graphics /sys/class/graphics/fb1/vendor_name chown system graphics /sys/class/graphics/fb1/product_description chown system graphics /sys/class/graphics/fb1/video_mode chown system graphics /sys/class/graphics/fb1/format_3d chown system graphics /sys/class/graphics/fb1/s3d_mode chown system graphics /sys/class/graphics/fb1/cec/enable chown system graphics /sys/class/graphics/fb1/cec/logical_addr chown system graphics /sys/class/graphics/fb1/cec/rd_msg chown system graphics /sys/class/graphics/fb1/pa chown system graphics /sys/class/graphics/fb1/cec/wr_msg chown system graphics /sys/class/graphics/fb1/hdcp/tp chmod 0664 /sys/devices/virtual/graphics/fb1/hpd chmod 0664 /sys/devices/virtual/graphics/fb1/res_info chmod 0664 /sys/devices/virtual/graphics/fb1/vendor_name chmod 0664 /sys/devices/virtual/graphics/fb1/product_description chmod 0664 /sys/devices/virtual/graphics/fb1/video_mode chmod 0664 /sys/devices/virtual/graphics/fb1/format_3d chmod 0664 /sys/devices/virtual/graphics/fb1/s3d_mode chmod 0664 /sys/devices/virtual/graphics/fb1/cec/enable chmod 0664 /sys/devices/virtual/graphics/fb1/cec/logical_addr chmod 0664 /sys/devices/virtual/graphics/fb1/cec/rd_msg chmod 0664 /sys/devices/virtual/graphics/fb1/pa chmod 0664 /sys/devices/virtual/graphics/fb1/cec/wr_msg chmod 0664 /sys/devices/virtual/graphics/fb1/hdcp/tp # Allow access for CCID command/response timeout configuration chown system system /sys/module/ccid_bridge/parameters/bulk_msg_timeout # Mark the copy complete flag to not completed write /data/misc/radio/copy_complete 0 chown radio radio /data/misc/radio/copy_complete chmod 0660 /data/misc/radio/copy_complete # msm specific files that need to be created on /data on post-fs-data mkdir /data/tombstones 0771 system system mkdir /tombstones/modem 0771 system system mkdir /tombstones/lpass 0771 system system mkdir /tombstones/wcnss 0771 system system mkdir /tombstones/dsps 0771 system system mkdir /persist/data/sfs 0700 system system mkdir /persist/data/tz 0700 system system mkdir /data/usf 0700 system system mkdir /data/misc/sfs/sfs 0700 system system mkdir /data/misc/sfs/tz 0700 system system mkdir /data/misc/dts 0770 media audio mkdir /data/oemnvitems 0771 radio radio # Fingerint mkdir /data/misc/fp 0700 system system mkdir /data/fpc_images 0770 system system mkdir /data/fpc_images/verify 0770 system system mkdir /data/fpc_images/enroll 0770 system system mkdir /data/fpc 0770 system system # Create directory for TZ Apps mkdir /data/misc/qsee 0770 system system # We will remap this as /mnt/sdcard with the sdcard fuse tool mkdir /data/misc/camera 0770 camera camera # Create folder for mm-qcamera-daemon mkdir /data/camera 0770 media camera # Create directory for IPA mkdir /data/misc/ipa 0700 net_admin net_admin mkdir /data/misc/bluetooth 0770 bluetooth bluetooth # Create the directories used by the Wireless subsystem mkdir /data/misc/wifi 0770 wifi wifi mkdir /data/misc/wifi/sockets 0770 wifi wifi mkdir /data/misc/wifi/wpa_supplicant 0770 wifi wifi mkdir /data/misc/dhcp 0770 dhcp dhcp chown dhcp dhcp /data/misc/dhcp # Create the directories used by CnE subsystem mkdir /data/connectivity 0771 system system chown system system /data/connectivity # Create the directories used by DPM subsystem mkdir /data/dpm 0771 system system chown system system /data/dpm mkdir /data/dpm/fdMgr 0771 system system chown system system /data/dpm/fdMgr mkdir /data/dpm/nsrm 0771 system system chown system system /data/dpm/nsrm # Create directory used by audio subsystem mkdir /data/misc/audio 0770 audio audio # Create directory for audio delta files mkdir /data/misc/audio/acdbdata 0770 media audio mkdir /data/misc/audio/acdbdata/delta 0770 media audio # Create directory used by the DASH client mkdir /data/misc/dash 0770 media audio # Create directory used by display clients mkdir /data/misc/display 0770 system graphics mkdir /persist/display 0770 system graphics # Mounting of persist is moved to 'on emmc-fs' and 'on fs' sections # We chown/chmod /persist again so because mount is run as root + defaults chown system system /persist chmod 0771 /persist chmod 0664 /sys/devices/platform/msm_sdcc.1/polling chmod 0664 /sys/devices/platform/msm_sdcc.2/polling chmod 0664 /sys/devices/platform/msm_sdcc.3/polling chmod 0664 /sys/devices/platform/msm_sdcc.4/polling # Chown polling nodes as needed from UI running on system server chown system system /sys/devices/platform/msm_sdcc.1/polling chown system system /sys/devices/platform/msm_sdcc.2/polling chown system system /sys/devices/platform/msm_sdcc.3/polling chown system system /sys/devices/platform/msm_sdcc.4/polling # Create the symlink to qcn wpa_supplicant folder for ar6000 wpa_supplicant mkdir /data/system 0775 system system #symlink /data/misc/wifi/wpa_supplicant /data/system/wpa_supplicant # Create directories for Location services mkdir /data/misc/location 0770 gps gps mkdir /data/misc/location/mq 0770 gps gps mkdir /data/misc/location/xtwifi 0770 gps gps mkdir /data/misc/location/gpsone_d 0770 system gps mkdir /data/misc/location/quipc 0770 gps system mkdir /data/misc/location/gsiff 0770 gps gps # Create directory from IMS services mkdir /data/shared 0755 chown system system /data/shared # Create directory for FOTA mkdir /data/fota 0771 chown system system /data/fota # Create directory for hostapd mkdir /data/hostapd 0770 system wifi # Create /data/time folder for time-services mkdir /data/time/ 0700 system system mkdir /data/audio/ 0770 media audio # Create a folder for audio delta files mkdir /data/audio/acdbdata 0770 media audio mkdir /data/audio/acdbdata/delta 0770 media audio setprop vold.post_fs_data_done 1 # Create a folder for SRS to be able to create a usercfg file mkdir /data/data/media 0770 media media # Create PERFD deamon related dirs mkdir /data/misc/perfd 0755 root system chmod 2755 /data/misc/perfd mkdir /data/system/perfd 0770 root system chmod 2770 /data/system/perfd # start camera server as daemon service qcamerasvr /system/bin/mm-qcamera-daemon class late_start user camera group camera system inet input graphics writepid /dev/cpuset/camera-daemon/tasks service qseecomd /system/bin/qseecomd class core user root group root writepid /dev/cpuset/system-background/tasks service perfd /system/vendor/bin/perfd class main user root disabled writepid /dev/cpuset/system-background/tasks service per_mgr /system/bin/pm-service class late_start user system group system net_raw writepid /dev/cpuset/system-background/tasks service per_proxy /system/bin/pm-proxy class late_start user system group system net_raw writepid /dev/cpuset/system-background/tasks disabled on property:init.svc.per_mgr=running start per_proxy on property:sys.shutdown.requested=* stop per_proxy service zram-init /system/bin/sh /system/etc/init.zram.sh class late_start user root disabled oneshot service fingerprintd /system/bin/fingerprintd class late_start user system group system writepid /dev/cpuset/system-background/tasks service thermal-engine /system/vendor/bin/thermal-engine class main user root socket thermal-send-client stream 0666 system system socket thermal-recv-client stream 0660 system system socket thermal-recv-passive-client stream 0666 system system group root writepid /dev/cpuset/system-background/tasks service time_daemon /system/bin/time_daemon class late_start user root group root writepid /dev/cpuset/system-background/tasks service adsprpcd /system/bin/adsprpcd class main user media group media service imsqmidaemon /system/bin/imsqmidaemon class main user system socket ims_qmid stream 0660 system radio group radio log diag service imsdatadaemon /system/bin/imsdatadaemon class main user system socket ims_datad stream 0660 system radio group system wifi radio inet log diag disabled on property:sys.ims.QMI_DAEMON_STATUS=1 start imsdatadaemon service ims_rtp_daemon /system/bin/ims_rtp_daemon class main user system socket ims_rtpd stream 0660 system radio group radio diag inet log disabled on property:sys.ims.DATA_DAEMON_STATUS=1 start ims_rtp_daemon service imscmservice /system/bin/imscmservice class main user system group radio diag log service usf_tester /system/bin/usf_tester user system group system inet disabled service usf_epos /system/bin/usf_epos class main user system group system inet disabled service usf_gesture /system/bin/usf_gesture user system group system inet disabled service usf_sync_gesture /system/bin/usf_sync_gesture user system group system inet audio disabled service usf_p2p /system/bin/usf_p2p user system group system inet disabled service usf_hovering /system/bin/usf_hovering user system group system inet disabled service usf_proximity /system/bin/usf_proximity user system group system inet disabled service usf_pairing /system/bin/usf_pairing user system group system inet disabled service usf_sw_calib /system/bin/usf_sw_calib user system group system inet disabled service usf-post-boot /system/bin/sh /system/etc/usf_post_boot.sh class late_start user root disabled oneshot on property:init.svc.bootanim=running write /sys/module/lpm_levels/system/a53/cpu0/retention/idle_enabled 0 write /sys/module/lpm_levels/system/a53/cpu1/retention/idle_enabled 0 write /sys/module/lpm_levels/system/a53/cpu2/retention/idle_enabled 0 write /sys/module/lpm_levels/system/a53/cpu3/retention/idle_enabled 0 write /sys/module/lpm_levels/system/a57/cpu4/retention/idle_enabled 0 write /sys/module/lpm_levels/system/a57/cpu5/retention/idle_enabled 0 write /sys/module/lpm_levels/system/a57/cpu6/retention/idle_enabled 0 write /sys/module/lpm_levels/system/a57/cpu7/retention/idle_enabled 0 write /sys/module/lpm_levels/system/a57/a57-l2-retention/idle_enabled 0 write /sys/module/lpm_levels/system/a53/a53-l2-retention/idle_enabled 0 write /sys/module/lpm_levels/parameters/sleep_disabled 0 on property:init.svc.bootanim=stopped start usf-post-boot service energy-awareness /system/bin/energy-awareness class main user root group system oneshot on property:sys.boot_completed=1 start zram-init write /dev/kmsg "Boot completed " # corefile limit and ETB enabling on property:persist.debug.trace=1 mkdir /data/core 0777 root root write /proc/sys/kernel/core_pattern "/data/core/%E.%p.%e" write /sys/devices/system/cpu/cpu1/online 1 write /sys/devices/system/cpu/cpu2/online 1 write /sys/devices/system/cpu/cpu3/online 1 write /sys/bus/coresight/devices/coresight-etm0/enable 0 write /sys/bus/coresight/devices/coresight-etm1/enable 0 write /sys/bus/coresight/devices/coresight-etm2/enable 0 write /sys/bus/coresight/devices/coresight-etm3/enable 0 write /sys/bus/coresight/devices/coresight-etm0/reset 1 write /sys/bus/coresight/devices/coresight-etm1/reset 1 write /sys/bus/coresight/devices/coresight-etm2/reset 1 write /sys/bus/coresight/devices/coresight-etm3/reset 1 write /sys/bus/coresight/devices/coresight-etm0/enable 1 write /sys/bus/coresight/devices/coresight-etm1/enable 1 write /sys/bus/coresight/devices/coresight-etm2/enable 1 write /sys/bus/coresight/devices/coresight-etm3/enable 1 write /sys/module/coresight_event/parameters/event_abort_enable 1 on property:bluetooth.isEnabled=true write /sys/class/bluetooth/hci0/idle_timeout 7000 on property:bluetooth.sap.status=running start bt-sap on property:bluetooth.sap.status=stopped stop bt-sap on property:bluetooth.dun.status=running start bt-dun on property:bluetooth.dun.status=stopped stop bt-dun on property:ro.bluetooth.ftm_enabled=true start ftmd on property:bluetooth.startbtsnoop=true start btsnoop on property:bluetooth.startbtsnoop=false stop btsnoop service ppd /system/bin/mm-pp-daemon class late_start disabled user system socket pps stream 0660 system system group system graphics on property:init.svc.surfaceflinger=stopped stop ppd on property:init.svc.surfaceflinger=running start ppd on property:vold.decrypt=trigger_restart_framework start config_bluetooth on property:persist.env.fastdorm.enabled=true setprop persist.radio.data_no_toggle 1 service cnd /system/bin/cnd class main socket cnd stream 660 root inet service dpmd /system/bin/dpmd class late_start socket dpmd stream 660 root system service irsc_util /system/bin/irsc_util "/etc/sec_config" class main user root oneshot service rmt_storage /system/bin/rmt_storage class core user root writepid /dev/cpuset/system-background/tasks service rfs_access /system/bin/rfs_access class core user root group system net_raw on property:wc_transport.start_hci=true start start_hci_filter on property:wc_transport.start_hci=false stop start_hci_filter # begin qrd patch for bluetoot cts test 2015 06 23 zuoyonghua@oneplus.cn service start_hci_filter /system/bin/wcnss_filter class late_start user bluetooth group bluetooth qcom_diag disabled on property:wc_transport.start_root=true start hci_filter_root on property:wc_transport.start_root=false stop hci_filter_root service hci_filter_root /system/bin/wcnss_filter class late_start user bluetooth group bluetooth qcom_diag net_bt_stack system disabled service config_bluetooth /system/bin/sh /system/etc/init.qcom.bt.sh "onboot" class core user root oneshot service hciattach /system/bin/sh /system/etc/init.qcom.bt.sh class late_start user bluetooth group bluetooth net_bt_admin disabled oneshot on property:bluetooth.hciattach=true start hciattach on property:bluetooth.hciattach=false setprop bluetooth.status off service bt-dun /system/bin/dun-server /dev/smd7 /dev/rfcomm0 class late_start user bluetooth group bluetooth net_bt_admin inet disabled oneshot service bt-sap /system/bin/sapd 15 user bluetooth group bluetooth net_bt_admin class late_start disabled oneshot service btsnoop /system/bin/btsnoop user bluetooth group bluetooth net_bt_admin sdcard_rw sdcard_r class late_start disabled oneshot service ftmd /system/bin/logwrapper /system/bin/ftmdaemon class late_start user root group bluetooth net_bt_admin misc net_bt_stack qcom_diag net_bt disabled oneshot # QMUX must be in multiple groups to support external process connections service qmuxd /system/bin/qmuxd class main user root group radio audio bluetooth gps qcom_diag writepid /dev/cpuset/system-background/tasks service netmgrd /system/bin/netmgrd class main writepid /dev/cpuset/system-background/tasks service ipacm-diag /system/bin/ipacm-diag class main user system socket ipacm_log_file dgram 660 system net_admin group net_admin qcom_diag service ipacm /system/bin/ipacm class main user net_admin group net_admin inet service qti /system/vendor/bin/qti class main user radio group radio net_raw qcom_diag usb net_admin writepid /dev/cpuset/system-background/tasks disabled service sensors /system/bin/sensors.qcom class late_start user root group root disabled on property:ro.use_data_netmgrd=false # netmgr not supported on specific target stop netmgrd # Adjust socket buffer to enlarge TCP receive window for high bandwidth # but only if ro.data.large_tcp_window_size property is set. on property:ro.data.large_tcp_window_size=true write /proc/sys/net/ipv4/tcp_adv_win_scale 2 on property:sys.sysctl.tcp_adv_win_scale=* write /proc/sys/net/ipv4/tcp_adv_win_scale ${sys.sysctl.tcp_adv_win_scale} service amp_init /system/bin/amploader -i class late_start user root disabled oneshot service amp_load /system/bin/amploader -l 7000 class late_start user root disabled oneshot service amp_unload /system/bin/amploader -u class late_start user root disabled oneshot service p2p_supplicant /system/bin/wpa_supplicant \ -ip2p0 -Dnl80211 -c/data/misc/wifi/p2p_supplicant.conf \ -I/system/etc/wifi/p2p_supplicant_overlay.conf -N \ -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \ -I/system/etc/wifi/wpa_supplicant_overlay.conf \ -O/data/misc/wifi/sockets -puse_p2p_group_interface=1 -dd \ -e/data/misc/wifi/entropy.bin -g@android:wpa_wlan0 # we will start as root and wpa_supplicant will switch to user wifi # after setting up the capabilities required for WEXT # user wifi # group wifi inet keystore class main socket wpa_wlan0 dgram 660 wifi wifi disabled oneshot service wpa_supplicant /system/bin/wpa_supplicant \ -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \ -I/system/etc/wifi/wpa_supplicant_overlay.conf \ -O/data/misc/wifi/sockets -dd \ -e/data/misc/wifi/entropy.bin -g@android:wpa_wlan0 # we will start as root and wpa_supplicant will switch to user wifi # after setting up the capabilities required for WEXT # user wifi # group wifi inet keystore class main socket wpa_wlan0 dgram 660 wifi wifi disabled oneshot service ptt_socket_app /system/bin/ptt_socket_app -d class main user root group root oneshot service ptt_ffbm /system/bin/ptt_socket_app -f -d user root group root disabled oneshot service ftm_ffbm /system/bin/ftmdaemon user root group root disabled oneshot service cnss_diag /system/bin/cnss_diag -q -f class main user root group root disabled on property:cnss_diag.load=true start cnss_diag on property:cnss_diag.load=false stop cnss_diag service cnss-daemon /system/bin/cnss-daemon -n -l class late_start service loc_launcher /system/bin/loc_launcher #loc_launcher will start as root and set its uid to gps class late_start group gps inet net_raw diag net_admin wifi service drmdiag /system/bin/drmdiagapp class late_start user root disabled oneshot on property:drmdiag.load=1 start drmdiag on property:drmdiag.load=0 stop drmdiag service qcom-sh /system/bin/sh /init.qcom.sh class late_start user root oneshot service hostapd /system/bin/hostapd /data/hostapd/hostapd.conf class late_start user root group root oneshot disabled service ims_regmanager /system/bin/exe-ims-regmanagerprocessnative class late_start group net_bt_admin inet radio wifi disabled on property:persist.ims.regmanager.mode=1 start ims_regmanager on property:ro.data.large_tcp_window_size=true # Adjust socket buffer to enlarge TCP receive window for high bandwidth (e.g. DO-RevB) write /proc/sys/net/ipv4/tcp_adv_win_scale 2 service battery_monitor /system/bin/battery_monitor user system group system disabled service ril-daemon2 /system/bin/rild -c 2 class main socket rild2 stream 660 root radio socket rild-debug2 stream 660 radio system user root group radio cache inet misc audio sdcard_r sdcard_rw diag qcom_diag log service profiler_daemon /system/bin/profiler_daemon class late_start user root group root disabled service ssr_diag /system/bin/ssr_diag class late_start user system group system disabled service hvdcp /system/bin/hvdcp class core user root disabled on property:persist.usb.hvdcp.detect=true start hvdcp on property:persist.usb.hvdcp.detect=false stop hvdcp service charger_monitor /system/bin/charger_monitor user root group root disabled service qbcharger /charger -m 1 disabled oneshot on property:sys.qbcharger.enable=true start qbcharger on property:sys.qbcharger.enable=false stop qbcharger service msm_irqbalance /system/bin/msm_irqbalance -f /system/vendor/etc/msm_irqbalance.conf socket msm_irqbalance seqpacket 660 root system class main user root group root disabled writepid /dev/cpuset/system-background/tasks ================================================ FILE: rootdir/etc/init.qcom.sh ================================================ #!/system/bin/sh # Copyright (c) 2009-2015, The Linux Foundation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of The Linux Foundation nor # the names of its contributors may be used to endorse or promote # products derived from this software without specific prior written # permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # target=`getprop ro.board.platform` if [ -f /sys/devices/soc0/soc_id ]; then platformid=`cat /sys/devices/soc0/soc_id` else platformid=`cat /sys/devices/system/soc/soc0/id` fi # # Function to start sensors for DSPS enabled platforms # # VENDOR_EDIT # qiuchangping@BSP 2015-04-16 add begin for gyro sensitity calibration start_sensors() { if [ -c /dev/msm_dsps -o -c /dev/sensors ]; then mkdir -p /persist/sensors chmod -h 775 /persist/sensors chmod -h 664 /persist/sensors/sensors_settings chown -h system.root /persist/sensors/sensors_settings chmod -h 664 /persist/sensors/gyro_sensitity_cal chown -h system.root /persist/sensors/gyro_sensitity_cal mkdir -p /data/misc/sensors chmod -h 775 /data/misc/sensors start sensors fi } # qiucahngping@BSP add end start_battery_monitor() { if ls /sys/bus/spmi/devices/qpnp-bms-*/fcc_data ; then chown -h root.system /sys/module/pm8921_bms/parameters/* chown -h root.system /sys/module/qpnp_bms/parameters/* chown -h root.system /sys/bus/spmi/devices/qpnp-bms-*/fcc_data chown -h root.system /sys/bus/spmi/devices/qpnp-bms-*/fcc_temp chown -h root.system /sys/bus/spmi/devices/qpnp-bms-*/fcc_chgcyl chmod 0660 /sys/module/qpnp_bms/parameters/* chmod 0660 /sys/module/pm8921_bms/parameters/* mkdir -p /data/bms chown -h root.system /data/bms chmod 0770 /data/bms start battery_monitor fi } start_charger_monitor() { if ls /sys/module/qpnp_charger/parameters/charger_monitor; then chown -h root.system /sys/module/qpnp_charger/parameters/* chown -h root.system /sys/class/power_supply/battery/input_current_max chown -h root.system /sys/class/power_supply/battery/input_current_trim chown -h root.system /sys/class/power_supply/battery/input_current_settled chown -h root.system /sys/class/power_supply/battery/voltage_min chmod 0664 /sys/class/power_supply/battery/input_current_max chmod 0664 /sys/class/power_supply/battery/input_current_trim chmod 0664 /sys/class/power_supply/battery/input_current_settled chmod 0664 /sys/class/power_supply/battery/voltage_min chmod 0664 /sys/module/qpnp_charger/parameters/charger_monitor start charger_monitor fi } start_vm_bms() { if [ -e /dev/vm_bms ]; then chown -h root.system /sys/class/power_supply/bms/current_now chown -h root.system /sys/class/power_supply/bms/voltage_ocv chmod 0664 /sys/class/power_supply/bms/current_now chmod 0664 /sys/class/power_supply/bms/voltage_ocv start vm_bms fi } start_msm_irqbalance_8939() { if [ -f /system/bin/msm_irqbalance ]; then case "$platformid" in "239") start msm_irqbalance;; esac fi } start_msm_irqbalance() { if [ -f /system/bin/msm_irqbalance ]; then start msm_irqbalance fi } baseband=`getprop ro.baseband` # # Suppress default route installation during RA for IPV6; user space will take # care of this # exception default ifc for file in /proc/sys/net/ipv6/conf/* do echo 0 > $file/accept_ra_defrtr done echo 1 > /proc/sys/net/ipv6/conf/default/accept_ra_defrtr case "$baseband" in "svlte2a") start bridgemgrd ;; esac start_sensors case "$target" in "msm7630_surf" | "msm7630_1x" | "msm7630_fusion") if [ -f /sys/devices/soc0/hw_platform ]; then value=`cat /sys/devices/soc0/hw_platform` else value=`cat /sys/devices/system/soc/soc0/hw_platform` fi case "$value" in "Fluid") start profiler_daemon;; esac ;; "msm8660" ) if [ -f /sys/devices/soc0/hw_platform ]; then platformvalue=`cat /sys/devices/soc0/hw_platform` else platformvalue=`cat /sys/devices/system/soc/soc0/hw_platform` fi case "$platformvalue" in "Fluid") start profiler_daemon;; esac ;; "msm8960") case "$baseband" in "msm") start_battery_monitor;; esac if [ -f /sys/devices/soc0/hw_platform ]; then platformvalue=`cat /sys/devices/soc0/hw_platform` else platformvalue=`cat /sys/devices/system/soc/soc0/hw_platform` fi case "$platformvalue" in "Fluid") start profiler_daemon;; "Liquid") start profiler_daemon;; esac ;; "msm8974") platformvalue=`cat /sys/devices/soc0/hw_platform` case "$platformvalue" in "Fluid") start profiler_daemon;; "Liquid") start profiler_daemon;; esac case "$baseband" in "msm") start_battery_monitor ;; esac start_charger_monitor ;; "apq8084") platformvalue=`cat /sys/devices/soc0/hw_platform` case "$platformvalue" in "Fluid") start profiler_daemon;; "Liquid") start profiler_daemon;; esac ;; "msm8226") start_charger_monitor ;; "msm8610") start_charger_monitor ;; "msm8916") start_vm_bms start_msm_irqbalance_8939 if [ -f /sys/devices/soc0/soc_id ]; then soc_id=`cat /sys/devices/soc0/soc_id` else soc_id=`cat /sys/devices/system/soc/soc0/id` fi if [ -f /sys/devices/soc0/platform_subtype_id ]; then platform_subtype_id=`cat /sys/devices/soc0/platform_subtype_id` fi if [ -f /sys/devices/soc0/hw_platform ]; then hw_platform=`cat /sys/devices/soc0/hw_platform` fi case "$soc_id" in "239") case "$hw_platform" in "Surf") case "$platform_subtype_id" in "1") setprop qemu.hw.mainkeys 0 ;; esac ;; "MTP") case "$platform_subtype_id" in "3") setprop qemu.hw.mainkeys 0 ;; esac ;; esac ;; esac ;; "msm8994" | "msm8992") start_msm_irqbalance ;; "msm8909") start_vm_bms ;; esac bootmode=`getprop ro.bootmode` emmc_boot=`getprop ro.boot.emmc` case "$emmc_boot" in "true") if [ "$bootmode" != "charger" ]; then # start rmt_storage and rfs_access start rmt_storage start rfs_access fi ;; esac # # Make modem config folder and copy firmware config to that folder # rm -rf /data/misc/radio/modem_config mkdir /data/misc/radio/modem_config #ifdef VENDOR_EDIT # Modify /data/misc/radio/modem_config authority to 770 from 660, and modify the target path to /system/etc/firmware/mbn_ota/, by hanqingpu@oneplus.cn, 20150530 chmod 770 /data/misc/radio/modem_config cp -r /system/etc/firmware/mbn_ota/* /data/misc/radio/modem_config #endif /*VENDOR_EDIT*/ chown -hR radio.radio /data/misc/radio/modem_config echo 1 > /data/misc/radio/copy_complete ================================================ FILE: rootdir/etc/init.qcom.usb.rc ================================================ # Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of The Linux Foundation nor # the names of its contributors may be used to endorse or promote # products derived from this software without specific prior written # permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # on init write /sys/class/android_usb/android0/f_rndis/wceis 1 write /sys/class/android_usb/android0/iSerial ${ro.serialno} on charger setprop persist.sys.usb.config mass_storage on fs mkdir /dev/usb-ffs 0770 shell shell mkdir /dev/usb-ffs/adb 0770 shell shell mount functionfs adb /dev/usb-ffs/adb uid=2000,gid=2000 write /sys/class/android_usb/android0/f_ffs/aliases adb setprop persist.sys.usb.config adb service qcom-usb-sh /system/bin/sh /init.qcom.usb.sh class core user root oneshot # Following are the parameters required for usb functionality. They provide configurable options like # product_id/vendor id and allows specifying required functions: # # Required parameters: # # /sys/class/android_usb/android0/enable: Enables/disables usb composition # Value: 0 (disable), 1 (enable) # # /sys/class/android_usb/android0/idVendor: Stores Vendor ID # Value: 05c6 (Vendor id for Qualcomm Inc) # # /sys/class/android_usb/android0/idProduct: Stores Product id corresponding to usb composition # Value: 0x9xxx for composite interface, 0xFxxx for single interface # # /sys/class/android_usb/android0/f_diag/clients: Stores name of clients representing a diag interface. # Value: Passed one per interface. e.g. diag[,diag_mdm, diag_qsc, diag_mdm2] # # /sys/class/android_usb/android0/functions: Stores name of the function drivers used in usb composition. # Value: Passed one per function driver. e.g. diag[,adb] # #Optional parameters: # # /sys/class/android_usb/android0/f_serial/transports: Stores type of underlying transports used to # communicate to serial interface. # Value: Passed one per interface. One value represents control and data transport together. # e.g. smd[,sdio,tty,hsic] # Only required if serial interface is present. # # /sys/class/android_usb/android0/f_serial/transport_names: Stores name of the underlying transports # used to communicate to serial interface. This is used to distinguish between more than one interface # using same transport type. # Value: Passed one per interface. One value represents control and data transport together. # e.g. serial_hsic[,serial_hsusb] # Only required for transport type hsic, optional for other transport types. # # /sys/class/android_usb/android0/f_rmnet/transports: Stores type of underlying transports used to # communicate to rmnet interface. # Value: Passed two per interface as control, data transport type pair. # e.g. smd,bam[,hsuart,hsuart] # Only required if rmnet interface is present. # # /sys/class/android_usb/android0/f_rmnet/transport_names: Stores name of the underlying transports # used to communicate to rmnet interface. This is used to distinguish between more than one interface # using same transport type. # Value: Passed one per interface. One value represents control and data transport together. # e.g. rmnet_hsic[,rmnet_hsusb] # Only required for transport type hsic, optional for other transport types. # USB compositions on property:sys.usb.config=diag,serial_tty,serial_smd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9002 write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_serial/transports tty,smd write /sys/class/android_usb/android0/functions diag,serial write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,serial_tty,serial_smd,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9020 write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_serial/transports smd,tty write /sys/class/android_usb/android0/functions diag,adb,serial write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 901D write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/functions diag,adb write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 900E write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/functions diag write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,serial_smd,rmnet_bam,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9091 write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_serial/transports smd write /sys/class/android_usb/android0/f_rmnet/transports smd,bam write /sys/class/android_usb/android0/functions diag,serial,rmnet,adb write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,serial_smd,rmnet_qti_bam,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9091 write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_serial/transports smd write /sys/class/android_usb/android0/f_rmnet/transports qti,bam write /sys/class/android_usb/android0/functions diag,serial,rmnet,adb write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,serial_smd,rmnet_bam write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9092 write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_serial/transports smd write /sys/class/android_usb/android0/f_rmnet/transports smd,bam write /sys/class/android_usb/android0/functions diag,serial,rmnet write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,serial_smd,rmnet_qti_bam write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9092 write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_serial/transports smd write /sys/class/android_usb/android0/f_rmnet/transports qti,bam write /sys/class/android_usb/android0/functions diag,serial,rmnet write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,serial_smd,serial_tty,rmnet_bam,mass_storage,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9025 write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_serial/transports smd,tty write /sys/class/android_usb/android0/f_rmnet/transports smd,bam write /sys/class/android_usb/android0/functions diag,adb,serial,rmnet,mass_storage write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,acm_smd,acm_tty,rmnet_bam,mass_storage,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 903D write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_acm/acm_transports smd,tty write /sys/class/android_usb/android0/f_rmnet/transports smd,bam write /sys/class/android_usb/android0/functions diag,adb,acm,rmnet,mass_storage write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,serial_smd,serial_tty,rmnet_bam,mass_storage write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9026 write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_serial/transports smd,tty write /sys/class/android_usb/android0/f_rmnet/transports smd,bam write /sys/class/android_usb/android0/functions diag,serial,rmnet,mass_storage write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,acm_smd,acm_tty,rmnet_bam,mass_storage write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 903E write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_acm/acm_transports smd,tty write /sys/class/android_usb/android0/f_rmnet/transports smd,bam write /sys/class/android_usb/android0/functions diag,serial,rmnet,mass_storage write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,diag_mdm,serial_sdio,serial_smd,rmnet_smd_sdio,mass_storage,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9037 write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm write /sys/class/android_usb/android0/f_serial/transports sdio,smd write /sys/class/android_usb/android0/functions diag,adb,serial,rmnet_smd_sdio,mass_storage write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,diag_mdm,acm_sdio,acm_smd,rmnet_smd_sdio,mass_storage,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 903B write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm write /sys/class/android_usb/android0/f_acm/acm_transports sdio,smd write /sys/class/android_usb/android0/functions diag,adb,acm,rmnet_smd_sdio,mass_storage write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,diag_mdm,serial_sdio,serial_smd,rmnet_smd_sdio,mass_storage write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9038 write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm write /sys/class/android_usb/android0/f_serial/transports sdio,smd write /sys/class/android_usb/android0/functions diag,serial,rmnet_smd_sdio,mass_storage write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,diag_mdm,acm_sdio,acm_smd,rmnet_smd_sdio,mass_storage write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 903C write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm write /sys/class/android_usb/android0/f_acm/acm_transports sdio,smd write /sys/class/android_usb/android0/functions diag,acm,rmnet_smd_sdio,mass_storage write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,diag_mdm,serial_sdio,serial_tty,rmnet_sdio,mass_storage,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9031 write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm write /sys/class/android_usb/android0/f_serial/transports sdio,tty write /sys/class/android_usb/android0/functions diag,adb,serial,rmnet_sdio,mass_storage write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,diag_mdm,acm_sdio,acm_tty,rmnet_sdio,mass_storage,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 903B write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm write /sys/class/android_usb/android0/f_acm/acm_transports sdio,tty write /sys/class/android_usb/android0/functions diag,adb,acm,rmnet_sdio,mass_storage write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,diag_mdm,serial_sdio,serial_tty,rmnet_sdio,mass_storage write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9032 write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm write /sys/class/android_usb/android0/f_serial/transports sdio,tty write /sys/class/android_usb/android0/functions diag,serial,rmnet_sdio,mass_storage write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,diag_mdm,acm_sdio,acm_tty,rmnet_sdio,mass_storage write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 903C write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm write /sys/class/android_usb/android0/f_acm/acm_transports sdio,tty write /sys/class/android_usb/android0/functions diag,acm,rmnet_sdio,mass_storage write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,serial_tty,serial_tty,rmnet_smd,mass_storage,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9025 write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_serial/transports tty,tty write /sys/class/android_usb/android0/functions diag,adb,serial,rmnet_smd,mass_storage write /sys/class/android_usb/android0/enable 1 start adbd start port-bridge setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,acm_tty,acm_tty,rmnet_smd,mass_storage,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 903D write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_acm/acm_transports tty,tty write /sys/class/android_usb/android0/functions diag,adb,acm,rmnet_smd,mass_storage write /sys/class/android_usb/android0/enable 1 start adbd start port-bridge setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,serial_tty,serial_tty,rmnet_smd,mass_storage write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9026 write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_serial/transports tty,tty write /sys/class/android_usb/android0/functions diag,serial,rmnet_smd,mass_storage write /sys/class/android_usb/android0/enable 1 start port-bridge setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,acm_tty,acm_tty,rmnet_smd,mass_storage write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 903E write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_acm/acm_transports tty,tty write /sys/class/android_usb/android0/functions diag,serial,rmnet_smd,mass_storage write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,serial_smd,serial_tty,rmnet_smd,mass_storage,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9025 write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_serial/transports smd,tty write /sys/class/android_usb/android0/functions diag,adb,serial,rmnet_smd,mass_storage write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,acm_smd,acm_tty,rmnet_smd,mass_storage,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 903D write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_acm/acm_transports smd,tty write /sys/class/android_usb/android0/functions diag,adb,acm,rmnet_smd,mass_storage write /sys/class/android_usb/android0/enable 1 start adbd start port-bridge setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,serial_smd,serial_tty,rmnet_smd,mass_storage write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9026 write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_serial/transports smd,tty write /sys/class/android_usb/android0/functions diag,serial,rmnet_smd,mass_storage write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,acm_smd,acm_tty,rmnet_smd,mass_storage write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 903E write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_acm/acm_transports smd,tty write /sys/class/android_usb/android0/functions diag,serial,rmnet_smd,mass_storage write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} # RmNet using USB BAM to IPA BAM on property:sys.usb.config=diag,serial_smd,serial_tty,rmnet_ipa,mass_storage,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9025 write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_serial/transports smd,tty write /sys/class/android_usb/android0/f_rmnet/transports qti,bam2bam_ipa write /sys/class/android_usb/android0/functions diag,adb,serial,rmnet,mass_storage write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,serial_smd,serial_tty,rmnet_ipa,mass_storage write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9026 write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_serial/transports smd,tty write /sys/class/android_usb/android0/f_rmnet/transports qti,bam2bam_ipa write /sys/class/android_usb/android0/functions diag,serial,rmnet,mass_storage write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,serial_smd,rmnet_ipa,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9091 write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_serial/transports smd write /sys/class/android_usb/android0/f_rmnet/transports qti,bam2bam_ipa write /sys/class/android_usb/android0/functions diag,serial,rmnet,adb write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,serial_smd,rmnet_ipa write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9092 write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_serial/transports smd write /sys/class/android_usb/android0/f_rmnet/transports qti,bam2bam_ipa write /sys/class/android_usb/android0/functions diag,serial,rmnet write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} # Fusion 3 composition on property:sys.usb.config=diag,serial_hsic,serial_tty,rmnet_hsic,mass_storage,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9025 write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_serial/transports hsic,tty write /sys/class/android_usb/android0/f_serial/transport_names serial_hsic write /sys/class/android_usb/android0/f_rmnet/transports hsic,hsic write /sys/class/android_usb/android0/f_rmnet/transport_names rmnet_hsic write /sys/class/android_usb/android0/functions diag,adb,serial,rmnet,mass_storage write /sys/module/mdm_bridge/parameters/rx_rmnet_buffer_size 16384 write /sys/module/mdm_bridge/parameters/max_rx_urbs 20 write /sys/module/g_android/parameters/ghsic_data_rx_req_size 16384 write /sys/module/g_android/parameters/ghsic_data_rmnet_rx_q_size 20 write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} # Fusion 3 composition with diag_mdm and adb on property:sys.usb.config=diag,diag_mdm,serial_hsic,serial_tty,rmnet_hsic,mass_storage,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9031 write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm write /sys/class/android_usb/android0/f_serial/transports hsic,tty write /sys/class/android_usb/android0/f_serial/transport_names serial_hsic write /sys/class/android_usb/android0/f_rmnet/transports hsic,hsic write /sys/class/android_usb/android0/f_rmnet/transport_names rmnet_hsic write /sys/class/android_usb/android0/functions diag,adb,serial,rmnet,mass_storage write /sys/module/mdm_bridge/parameters/rx_rmnet_buffer_size 16384 write /sys/module/mdm_bridge/parameters/max_rx_urbs 20 write /sys/module/g_android/parameters/ghsic_data_rx_req_size 16384 write /sys/module/g_android/parameters/ghsic_data_rmnet_rx_q_size 20 write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} # Fusion 3 composition with diag_mdm on property:sys.usb.config=diag,diag_mdm,serial_hsic,serial_tty,rmnet_hsic,mass_storage write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9032 write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm write /sys/class/android_usb/android0/f_serial/transports hsic,tty write /sys/class/android_usb/android0/f_serial/transport_names serial_hsic write /sys/class/android_usb/android0/f_rmnet/transports hsic,hsic write /sys/class/android_usb/android0/f_rmnet/transport_names rmnet_hsic write /sys/class/android_usb/android0/functions diag,serial,rmnet,mass_storage write /sys/module/mdm_bridge/parameters/rx_rmnet_buffer_size 16384 write /sys/module/mdm_bridge/parameters/max_rx_urbs 20 write /sys/module/g_android/parameters/ghsic_data_rx_req_size 16384 write /sys/module/g_android/parameters/ghsic_data_rmnet_rx_q_size 20 write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} # Fusion 3 DSDA composition with adb on property:sys.usb.config=diag,diag_mdm,diag_qsc,serial_hsic,serial_hsuart,rmnet_hsic,rmnet_hsuart,mass_storage,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9065 write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm,diag_qsc write /sys/class/android_usb/android0/f_serial/transports hsic,hsuart write /sys/class/android_usb/android0/f_serial/transport_names serial_hsic,serial_hsuart write /sys/class/android_usb/android0/f_rmnet/transports hsic,hsic,hsuart,hsuart write /sys/class/android_usb/android0/f_rmnet/transport_names rmnet_hsic,rmnet_hsuart write /sys/class/android_usb/android0/functions diag,adb,serial,rmnet,mass_storage write /sys/module/mdm_bridge/parameters/rx_rmnet_buffer_size 16384 write /sys/module/mdm_bridge/parameters/max_rx_urbs 20 write /sys/module/g_android/parameters/ghsic_data_rx_req_size 16384 write /sys/module/g_android/parameters/ghsic_data_rmnet_rx_q_size 20 write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} # Fusion 3 DSDA composition without adb on property:sys.usb.config=diag,diag_mdm,diag_qsc,serial_hsic,serial_hsuart,rmnet_hsic,rmnet_hsuart,mass_storage write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9066 write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm,diag_qsc write /sys/class/android_usb/android0/f_serial/transports hsic,hsuart write /sys/class/android_usb/android0/f_serial/transport_names serial_hsic,serial_hsuart write /sys/class/android_usb/android0/f_rmnet/transports hsic,hsic,hsuart,hsuart write /sys/class/android_usb/android0/f_rmnet/transport_names rmnet_hsic,rmnet_hsuart write /sys/class/android_usb/android0/functions diag,serial,rmnet,mass_storage write /sys/module/mdm_bridge/parameters/rx_rmnet_buffer_size 16384 write /sys/module/mdm_bridge/parameters/max_rx_urbs 20 write /sys/module/g_android/parameters/ghsic_data_rx_req_size 16384 write /sys/module/g_android/parameters/ghsic_data_rmnet_rx_q_size 20 write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} # Fusion 3 DSDA2 composition with adb on property:sys.usb.config=diag,diag_mdm,diag_mdm2,serial_hsic,serial_hsusb,rmnet_hsic,rmnet_hsusb,mass_storage,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9065 write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm,diag_mdm2 write /sys/class/android_usb/android0/f_serial/transports hsic,hsic write /sys/class/android_usb/android0/f_serial/transport_names serial_hsic,serial_hsusb write /sys/class/android_usb/android0/f_rmnet/transports hsic,hsic,hsic,hsic write /sys/class/android_usb/android0/f_rmnet/transport_names rmnet_hsic,rmnet_hsusb write /sys/class/android_usb/android0/functions diag,adb,serial,rmnet,mass_storage write /sys/module/mdm_bridge/parameters/rx_rmnet_buffer_size 16384 write /sys/module/mdm_bridge/parameters/max_rx_urbs 20 write /sys/module/g_android/parameters/ghsic_data_rx_req_size 16384 write /sys/module/g_android/parameters/ghsic_data_rmnet_rx_q_size 20 write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} # Fusion 3 DSDA2 composition without adb on property:sys.usb.config=diag,diag_mdm,diag_mdm2,serial_hsic,serial_hsusb,rmnet_hsic,rmnet_hsusb,mass_storage write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9066 write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm,diag_mdm2 write /sys/class/android_usb/android0/f_serial/transports hsic,hsic write /sys/class/android_usb/android0/f_serial/transport_names serial_hsic,serial_hsusb write /sys/class/android_usb/android0/f_rmnet/transports hsic,hsic,hsic,hsic write /sys/class/android_usb/android0/f_rmnet/transport_names rmnet_hsic,rmnet_hsusb write /sys/class/android_usb/android0/functions diag,serial,rmnet,mass_storage write /sys/module/mdm_bridge/parameters/rx_rmnet_buffer_size 16384 write /sys/module/mdm_bridge/parameters/max_rx_urbs 20 write /sys/module/g_android/parameters/ghsic_data_rx_req_size 16384 write /sys/module/g_android/parameters/ghsic_data_rmnet_rx_q_size 20 write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} # Fusion PCIe composition with diag_mdm and adb # Serial & RmNet bridged in userspace with tty and qti/ether on property:sys.usb.config=diag,diag_mdm,serial_tty,rmnet_qti_ether,mass_storage,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9035 write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm write /sys/class/android_usb/android0/f_serial/transports tty write /sys/class/android_usb/android0/f_rmnet/transports qti,ether write /sys/class/android_usb/android0/functions diag,adb,serial,rmnet,mass_storage write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} # Fusion PCIe composition with diag_mdm # Serial & RmNet bridged in userspace with tty and qti/ether on property:sys.usb.config=diag,diag_mdm,serial_hsic,rmnet_hsic,mass_storage write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9036 write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm write /sys/class/android_usb/android0/f_serial/transports tty write /sys/class/android_usb/android0/f_rmnet/transports qti,ether write /sys/class/android_usb/android0/functions diag,serial,rmnet,mass_storage write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} # Fusion HSIC/PCIe Hybrid composition with diag_mdm and adb # RmNet is bridged over PCIe using qti,ether ctrl/data transports on property:sys.usb.config=diag,diag_mdm,serial_hsic,rmnet_qti_ether,mass_storage,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9035 write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm write /sys/class/android_usb/android0/f_serial/transports hsic write /sys/class/android_usb/android0/f_serial/transport_names serial_hsic write /sys/class/android_usb/android0/f_rmnet/transports qti,ether write /sys/class/android_usb/android0/functions diag,adb,serial,rmnet,mass_storage write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} # Fusion HSIC/PCIe Hybrid composition with diag_mdm # RmNet is bridged over PCIe using qti,ether ctrl/data transports on property:sys.usb.config=diag,diag_mdm,serial_hsic,rmnet_hsic,mass_storage write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9036 write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm write /sys/class/android_usb/android0/f_serial/transports hsic write /sys/class/android_usb/android0/f_serial/transport_names serial_hsic write /sys/class/android_usb/android0/f_rmnet/transports qti,ether write /sys/class/android_usb/android0/functions diag,serial,rmnet,mass_storage write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} # Fusion 2.2 composition with diag_qsc and adb on property:sys.usb.config=diag,diag_qsc,serial_smd,serial_tty,serial_hsuart,rmnet_hsuart,mass_storage,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9053 write /sys/class/android_usb/android0/f_diag/clients diag,diag_qsc write /sys/class/android_usb/android0/f_serial/transports smd,tty,hsuart write /sys/class/android_usb/android0/f_rmnet/transports smd,bam,hsuart,hsuart write /sys/class/android_usb/android0/functions diag,adb,serial,rmnet,mass_storage write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} # Fusion 2.2 composition with diag_qsc on property:sys.usb.config=diag,diag_qsc,serial_smd,serial_tty,serial_hsuart,rmnet_hsuart,mass_storage write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9054 write /sys/class/android_usb/android0/f_diag/clients diag,diag_qsc write /sys/class/android_usb/android0/f_serial/transports smd,tty,hsuart write /sys/class/android_usb/android0/f_rmnet/transports smd,bam,hsuart,hsuart write /sys/class/android_usb/android0/functions diag,serial,rmnet,mass_storage write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=rndis setprop sys.usb.config rndis,${persist.sys.usb.config.extra} on property:sys.usb.config=rndis,none write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct F00E write /sys/class/android_usb/android0/functions rndis write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state rndis on property:sys.usb.config=rndis,adb setprop sys.usb.config rndis,${persist.sys.usb.config.extra},adb on property:sys.usb.config=rndis,none,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9024 write /sys/class/android_usb/android0/functions rndis,adb write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state rndis,adb on property:sys.usb.config=rndis,diag write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 902C write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/functions rndis,diag write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state rndis on property:sys.usb.config=rndis,diag,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 902D write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/functions rndis,diag,adb write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state rndis,adb on property:sys.usb.config=rndis,serial_smd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 90B3 write /sys/class/android_usb/android0/f_serial/transports smd write /sys/class/android_usb/android0/functions rndis,serial write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state rndis on property:sys.usb.config=rndis,serial_smd,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 90B4 write /sys/class/android_usb/android0/f_serial/transports smd write /sys/class/android_usb/android0/functions rndis,serial,adb write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state rndis,adb on property:sys.usb.config=rndis,serial_smd,diag write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 90B5 write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_serial/transports smd write /sys/class/android_usb/android0/functions rndis,serial,diag write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state rndis on property:sys.usb.config=rndis,serial_smd,diag,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 90B6 write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_serial/transports smd write /sys/class/android_usb/android0/functions rndis,serial,diag,adb write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state rndis,adb on property:sys.usb.config=rndis,diag,diag_mdm write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9041 write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm write /sys/class/android_usb/android0/functions rndis,diag write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state rndis on property:sys.usb.config=rndis,diag,diag_mdm,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9042 write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm write /sys/class/android_usb/android0/functions rndis,diag,adb write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state rndis,adb on property:sys.usb.config=rndis,diag,diag_mdm,diag_qsc write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9086 write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm,diag_qsc write /sys/class/android_usb/android0/functions rndis,diag write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state rndis on property:sys.usb.config=rndis,diag,diag_mdm,diag_qsc,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9087 write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm,diag_qsc write /sys/class/android_usb/android0/functions rndis,diag,adb write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state rndis,adb on property:sys.usb.config=ptp write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 904D write /sys/class/android_usb/android0/functions ptp write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=ptp,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 904E write /sys/class/android_usb/android0/functions ptp,adb write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=mtp write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct F003 write /sys/class/android_usb/android0/functions mtp write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=mtp,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9039 write /sys/class/android_usb/android0/functions mtp,adb write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=mtp,diag write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 901B write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/functions mtp,diag write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=mtp,diag,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 903A write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/functions mtp,diag,adb write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=mtp,diag,diag_mdm write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9040 write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm write /sys/class/android_usb/android0/functions mtp,diag write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=mtp,diag,diag_mdm,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 903F write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm write /sys/class/android_usb/android0/functions mtp,diag,adb write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=mtp,diag,diag_mdm,diag_qsc write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9088 write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm,diag_qsc write /sys/class/android_usb/android0/functions mtp,diag write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=mtp,diag,diag_mdm,diag_qsc,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9089 write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm,diag_qsc write /sys/class/android_usb/android0/functions mtp,diag,adb write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,diag_mdm,ccid write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9045 write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm write /sys/class/android_usb/android0/functions diag,ccid write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,diag_mdm,ccid,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9044 write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm write /sys/class/android_usb/android0/functions diag,adb,ccid write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=mass_storage,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9015 write /sys/class/android_usb/android0/functions adb,mass_storage write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} #Mass-storage only composition on property:sys.usb.config=mass_storage write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct F000 write /sys/class/android_usb/android0/functions mass_storage write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,qdss write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 904A write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_qdss/debug_intf 1 write /sys/class/android_usb/android0/f_qdss/transports bam write /sys/class/android_usb/android0/f_qdss/transport_names qdss_bam write /sys/class/android_usb/android0/functions diag,qdss write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,qdss,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9060 write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_qdss/debug_intf 1 write /sys/class/android_usb/android0/f_qdss/transports bam write /sys/class/android_usb/android0/f_qdss/transport_names qdss_bam write /sys/class/android_usb/android0/functions diag,qdss,adb write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,diag_mdm,qdss write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9099 write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm write /sys/class/android_usb/android0/f_qdss/debug_intf 1 write /sys/class/android_usb/android0/f_qdss/transports bam write /sys/class/android_usb/android0/f_qdss/transport_names qdss_bam write /sys/class/android_usb/android0/functions diag,qdss write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,diag_mdm,qdss,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9098 write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm write /sys/class/android_usb/android0/f_qdss/debug_intf 1 write /sys/class/android_usb/android0/f_qdss/transports bam write /sys/class/android_usb/android0/f_qdss/transport_names qdss_bam write /sys/class/android_usb/android0/functions diag,qdss,adb write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,qdss,rmnet_bam write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9083 write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_rmnet/transports smd,bam write /sys/class/android_usb/android0/f_qdss/debug_intf 1 write /sys/class/android_usb/android0/f_qdss/transports bam write /sys/class/android_usb/android0/f_qdss/transport_names qdss_bam write /sys/class/android_usb/android0/functions diag,qdss,rmnet write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,qdss,rmnet_qti_bam write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9083 write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_rmnet/transports qti,bam write /sys/class/android_usb/android0/f_qdss/debug_intf 1 write /sys/class/android_usb/android0/f_qdss/transports bam write /sys/class/android_usb/android0/f_qdss/transport_names qdss_bam write /sys/class/android_usb/android0/functions diag,qdss,rmnet write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,qdss,rmnet_bam,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9084 write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_rmnet/transports smd,bam write /sys/class/android_usb/android0/f_qdss/debug_intf 1 write /sys/class/android_usb/android0/f_qdss/transports bam write /sys/class/android_usb/android0/f_qdss/transport_names qdss_bam write /sys/class/android_usb/android0/functions diag,qdss,adb,rmnet write /sys/module/dwc3/parameters/tx_fifo_resize_enable 1 write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,qdss,rmnet_qti_bam,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9084 write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_rmnet/transports qti,bam write /sys/class/android_usb/android0/f_qdss/debug_intf 1 write /sys/class/android_usb/android0/f_qdss/transports bam write /sys/class/android_usb/android0/f_qdss/transport_names qdss_bam write /sys/class/android_usb/android0/functions diag,qdss,adb,rmnet write /sys/module/dwc3/parameters/tx_fifo_resize_enable 1 write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,qdss,rmnet_ipa write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9083 write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_rmnet/transports qti,bam2bam_ipa write /sys/class/android_usb/android0/f_qdss/debug_intf 1 write /sys/class/android_usb/android0/f_qdss/transports bam write /sys/class/android_usb/android0/f_qdss/transport_names qdss_bam write /sys/class/android_usb/android0/functions diag,qdss,rmnet write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,qdss,rmnet_ipa,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9084 write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_rmnet/transports qti,bam2bam_ipa write /sys/class/android_usb/android0/f_qdss/debug_intf 1 write /sys/class/android_usb/android0/f_qdss/transports bam write /sys/class/android_usb/android0/f_qdss/transport_names qdss_bam write /sys/class/android_usb/android0/functions diag,qdss,adb,rmnet write /sys/module/dwc3/parameters/tx_fifo_resize_enable 1 write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,diag_mdm,qdss,rmnet_hsic write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 909B write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm write /sys/class/android_usb/android0/f_rmnet/transports hsic,hsic write /sys/class/android_usb/android0/f_qdss/debug_intf 1 write /sys/class/android_usb/android0/f_qdss/transports bam write /sys/class/android_usb/android0/f_qdss/transport_names qdss_bam write /sys/class/android_usb/android0/functions diag,qdss,rmnet write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,diag_mdm,qdss,rmnet_hsic,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 909A write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm write /sys/class/android_usb/android0/f_rmnet/transports hsic,hsic write /sys/class/android_usb/android0/f_qdss/debug_intf 1 write /sys/class/android_usb/android0/f_qdss/transports bam write /sys/class/android_usb/android0/f_qdss/transport_names qdss_bam write /sys/class/android_usb/android0/functions diag,qdss,adb,rmnet write /sys/module/dwc3/parameters/tx_fifo_resize_enable 1 write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,diag_mdm,qdss_apq,qdss_mdm,rmnet_hsic write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 90A3 write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm write /sys/class/android_usb/android0/f_rmnet/transports hsic,hsic write /sys/class/android_usb/android0/f_qdss/debug_intf 0 write /sys/class/android_usb/android0/f_qdss/transports bam,hsic write /sys/class/android_usb/android0/f_qdss/transport_names qdss_bam,qdss_hsic write /sys/class/android_usb/android0/functions diag,qdss,rmnet write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=diag,diag_mdm,qdss_apq,qdss_mdm,rmnet_hsic,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 90A2 write /sys/class/android_usb/android0/f_diag/clients diag,diag_mdm write /sys/class/android_usb/android0/f_rmnet/transports hsic,hsic write /sys/class/android_usb/android0/f_qdss/debug_intf 0 write /sys/class/android_usb/android0/f_qdss/transports bam,hsic write /sys/class/android_usb/android0/f_qdss/transport_names qdss_bam,qdss_hsic write /sys/class/android_usb/android0/functions diag,qdss,adb,rmnet write /sys/module/dwc3/parameters/tx_fifo_resize_enable 1 write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=rndis,diag,qdss write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9081 write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_qdss/debug_intf 1 write /sys/class/android_usb/android0/f_qdss/transports bam write /sys/class/android_usb/android0/f_qdss/transport_names qdss_bam write /sys/class/android_usb/android0/functions rndis,diag,qdss write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=rndis,diag,qdss,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 9082 write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_qdss/debug_intf 1 write /sys/class/android_usb/android0/f_qdss/transports bam write /sys/class/android_usb/android0/f_qdss/transport_names qdss_bam write /sys/class/android_usb/android0/functions rndis,diag,qdss,adb write /sys/module/dwc3/parameters/tx_fifo_resize_enable 1 write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} # same as 9025, plus data packet logging (DPL) using QDSS on property:sys.usb.config=diag,serial_smd,serial_tty,rmnet_ipa,mass_storage,dpl,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 90AD write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_serial/transports smd,tty # DPL is implemented using QDSS write /sys/class/android_usb/android0/f_qdss/debug_intf 0 write /sys/class/android_usb/android0/f_qdss/transports qti,bam2bam_ipa write /sys/class/android_usb/android0/f_qdss/transport_names qdss_bam write /sys/class/android_usb/android0/f_rmnet/transports qti,bam2bam_ipa write /sys/class/android_usb/android0/functions diag,adb,serial,rmnet,mass_storage,qdss write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} # same as 9026, plus data packet logging (DPL) on property:sys.usb.config=diag,serial_smd,serial_tty,rmnet_ipa,mass_storage,dpl stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 90B0 write /sys/class/android_usb/android0/f_diag/clients diag write /sys/class/android_usb/android0/f_serial/transports smd,tty # DPL is implemented using QDSS write /sys/class/android_usb/android0/f_qdss/debug_intf 0 write /sys/class/android_usb/android0/f_qdss/transports qti,bam2bam_ipa write /sys/class/android_usb/android0/f_qdss/transport_names qdss_bam write /sys/class/android_usb/android0/f_rmnet/transports qti,bam2bam_ipa write /sys/class/android_usb/android0/functions diag,serial,rmnet,mass_storage,qdss write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=ncm write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 0525 write /sys/class/android_usb/android0/idProduct A4A1 write /sys/class/android_usb/android0/functions ncm write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=ncm,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 908C write /sys/class/android_usb/android0/functions ncm,adb write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=midi write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 90BA write /sys/class/android_usb/android0/functions midi write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=midi,adb stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 05C6 write /sys/class/android_usb/android0/idProduct 90BB write /sys/class/android_usb/android0/functions midi,adb write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state ${sys.usb.config} ================================================ FILE: rootdir/etc/init.qcom.usb.sh ================================================ #!/system/bin/sh # Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of The Linux Foundation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN # IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # chown -h root.system /sys/devices/platform/msm_hsusb/gadget/wakeup chmod -h 220 /sys/devices/platform/msm_hsusb/gadget/wakeup # Target as specified in build.prop at compile-time target=`getprop ro.board.platform` # Set platform variables if [ -d /sys/devices/soc0 ]; then soc_hwplatform=`cat /sys/devices/soc0/hw_platform` 2> /dev/null soc_id=`cat /sys/devices/soc0/soc_id` 2> /dev/null else soc_hwplatform=`cat /sys/devices/system/soc/soc0/hw_platform` 2> /dev/null fi # # soc_id may specify additional chip variants not captured in ro.board.platform # so allow for additional target differentiation based on that # case $soc_id in "252") target="apq8092" ;; "253") target="apq8094" ;; esac # # Allow persistent usb charging disabling # User needs to set usb charging disabled in persist.usb.chgdisabled # usbchgdisabled=`getprop persist.usb.chgdisabled` case "$usbchgdisabled" in "") ;; #Do nothing here * ) case $target in "msm8660") echo "$usbchgdisabled" > /sys/module/pmic8058_charger/parameters/disabled echo "$usbchgdisabled" > /sys/module/smb137b/parameters/disabled ;; "msm8960") echo "$usbchgdisabled" > /sys/module/pm8921_charger/parameters/disabled ;; esac esac usbcurrentlimit=`getprop persist.usb.currentlimit` case "$usbcurrentlimit" in "") ;; #Do nothing here * ) case $target in "msm8960") echo "$usbcurrentlimit" > /sys/module/pm8921_charger/parameters/usb_max_current ;; esac esac # # Check ESOC for external MDM # # Note: currently only a single MDM is supported # if [ -d /sys/bus/esoc/devices ]; then for f in /sys/bus/esoc/devices/*; do if [ -d $f ]; then esoc_name=`cat $f/esoc_name` if [ "$esoc_name" = "MDM9x25" -o "$esoc_name" = "MDM9x35" ]; then esoc_link=`cat $f/esoc_link` break fi fi done fi # # Allow USB enumeration with default PID/VID # baseband=`getprop ro.baseband` echo 1 > /sys/class/android_usb/f_mass_storage/lun/nofua usb_config=`getprop persist.sys.usb.config` case "$usb_config" in "" | "adb" | "none") #USB persist config not set, select default configuration case "$esoc_link" in "HSIC") setprop persist.sys.usb.config diag,diag_mdm,serial_hsic,serial_tty,rmnet_hsic,mass_storage,adb setprop persist.rmnet.mux enabled ;; "HSIC+PCIe") setprop persist.sys.usb.config diag,diag_mdm,serial_hsic,rmnet_qti_ether,mass_storage,adb ;; "PCIe") setprop persist.sys.usb.config diag,diag_mdm,serial_tty,rmnet_qti_ether,mass_storage,adb ;; *) case "$baseband" in "mdm") setprop persist.sys.usb.config diag,diag_mdm,serial_hsic,serial_tty,rmnet_hsic,mass_storage,adb ;; "mdm2") setprop persist.sys.usb.config diag,diag_mdm,serial_hsic,serial_tty,rmnet_hsic,mass_storage,adb ;; "sglte") setprop persist.sys.usb.config diag,diag_qsc,serial_smd,serial_tty,serial_hsuart,rmnet_hsuart,mass_storage,adb ;; "dsda" | "sglte2") setprop persist.sys.usb.config diag,diag_mdm,diag_qsc,serial_hsic,serial_hsuart,rmnet_hsic,rmnet_hsuart,mass_storage,adb ;; "dsda2") setprop persist.sys.usb.config diag,diag_mdm,diag_mdm2,serial_hsic,serial_hsusb,rmnet_hsic,rmnet_hsusb,mass_storage,adb ;; *) case "$target" in "msm8916") setprop persist.sys.usb.config diag,serial_smd,rmnet_bam,adb ;; "apq8094" | "apq8092") setprop persist.sys.usb.config diag,adb ;; "msm8994" | "msm8992") #[BSP-66]-Anderson-Disable_set_the_property. #This will ause BSP-66 issue and cause all the port enable in default. #setprop persist.sys.usb.config diag,serial_smd,serial_tty,rmnet_ipa,mass_storage,adb ;; "msm8909") setprop persist.sys.usb.config diag,serial_smd,rmnet_qti_bam,adb ;; *) setprop persist.sys.usb.config diag,serial_smd,serial_tty,rmnet_bam,mass_storage,adb ;; esac ;; esac ;; esac ;; * ) ;; #USB persist config exists, do nothing esac #VENDOR_EDIT #echo boot mode to kmsg boot_mode=`getprop ro.boot.ftm_mode` echo "boot_mode: $boot_mode" > /dev/kmsg case "$boot_mode" in "ftm_at" | "ftm_rf" | "ftm_wlan" | "ftm_mos") echo "FTM FORCE diag,adb" > /dev/kmsg setprop persist.sys.usb.config diag,adb ;; esac usb_config=`getprop persist.sys.usb.config` echo "AFTER: $usb_config" > /dev/kmsg #VENDOR_EDIT end # # Do target specific things # case "$target" in "msm8974") # Select USB BAM - 2.0 or 3.0 echo ssusb > /sys/bus/platform/devices/usb_bam/enable ;; "apq8084") if [ "$baseband" == "apq" ]; then echo "msm_hsic_host" > /sys/bus/platform/drivers/xhci_msm_hsic/unbind fi ;; "msm8226") if [ -e /sys/bus/platform/drivers/msm_hsic_host ]; then if [ ! -L /sys/bus/usb/devices/1-1 ]; then echo msm_hsic_host > /sys/bus/platform/drivers/msm_hsic_host/unbind fi fi ;; "msm8994" | "msm8992") echo BAM2BAM_IPA > /sys/class/android_usb/android0/f_rndis_qc/rndis_transports ;; esac # # set module params for embedded rmnet devices # rmnetmux=`getprop persist.rmnet.mux` case "$baseband" in "mdm" | "dsda" | "sglte2") case "$rmnetmux" in "enabled") echo 1 > /sys/module/rmnet_usb/parameters/mux_enabled echo 8 > /sys/module/rmnet_usb/parameters/no_fwd_rmnet_links echo 17 > /sys/module/rmnet_usb/parameters/no_rmnet_insts_per_dev ;; esac echo 1 > /sys/module/rmnet_usb/parameters/rmnet_data_init # Allow QMUX daemon to assign port open wait time chown -h radio.radio /sys/devices/virtual/hsicctl/hsicctl0/modem_wait ;; "dsda2") echo 2 > /sys/module/rmnet_usb/parameters/no_rmnet_devs echo hsicctl,hsusbctl > /sys/module/rmnet_usb/parameters/rmnet_dev_names case "$rmnetmux" in "enabled") #mux is neabled on both mdms echo 3 > /sys/module/rmnet_usb/parameters/mux_enabled echo 8 > /sys/module/rmnet_usb/parameters/no_fwd_rmnet_links echo 17 > write /sys/module/rmnet_usb/parameters/no_rmnet_insts_per_dev ;; "enabled_hsic") #mux is enabled on hsic mdm echo 1 > /sys/module/rmnet_usb/parameters/mux_enabled echo 8 > /sys/module/rmnet_usb/parameters/no_fwd_rmnet_links echo 17 > /sys/module/rmnet_usb/parameters/no_rmnet_insts_per_dev ;; "enabled_hsusb") #mux is enabled on hsusb mdm echo 2 > /sys/module/rmnet_usb/parameters/mux_enabled echo 8 > /sys/module/rmnet_usb/parameters/no_fwd_rmnet_links echo 17 > /sys/module/rmnet_usb/parameters/no_rmnet_insts_per_dev ;; esac echo 1 > /sys/module/rmnet_usb/parameters/rmnet_data_init # Allow QMUX daemon to assign port open wait time chown -h radio.radio /sys/devices/virtual/hsicctl/hsicctl0/modem_wait ;; esac # # Add support for exposing lun0 as cdrom in mass-storage # cdromname="/system/etc/cdrom_install.iso" case "$target" in "msm8226" | "msm8610" | "msm8916") case $soc_hwplatform in "QRD") echo "mounting usbcdrom lun" echo $cdromname > /sys/class/android_usb/android0/f_mass_storage/rom/file chmod 0444 /sys/class/android_usb/android0/f_mass_storage/rom/file ;; esac ;; esac # # Initialize RNDIS Diag option. If unset, set it to 'none'. # diag_extra=`getprop persist.sys.usb.config.extra` if [ "$diag_extra" == "" ]; then setprop persist.sys.usb.config.extra none fi ================================================ FILE: rootdir/etc/init.zram.sh ================================================ #!/system/bin/sh echo 536870912 > /sys/block/zram0/disksize mkswap /dev/block/zram0 swapon /dev/block/zram0 -p 32758 ================================================ FILE: rootdir/etc/ueventd.qcom.rc ================================================ # Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of The Linux Foundation nor # the names of its contributors may be used to endorse or promote # products derived from this software without specific prior written # permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # the DIAG device node is not world writable/readable. /dev/diag 0660 system qcom_diag /dev/genlock 0666 system system /dev/kgsl 0666 system system /dev/kgsl-3d0 0666 system system /dev/kgsl-2d0 0666 root root /dev/kgsl-2d1 0666 root root /dev/ion 0664 system system /dev/rtc0 0600 system system /dev/smd0 0660 system system /dev/smd4 0660 system system /dev/smd_cxm_qmi 0640 radio radio /dev/smd5 0660 system system /dev/smd6 0660 system system /dev/smd7 0660 bluetooth bluetooth /dev/ccid_bridge 0660 system system /dev/ipa 0660 net_admin net_admin /dev/wwan_ioctl 0660 net_admin net_admin /dev/ipaNatTable 0660 net_admin net_admin /dev/rmnet_ctrl 0660 usb usb /dev/dpl_ctrl 0660 usb usb #permissions for CSVT /dev/smd11 0660 radio radio /dev/radio0 0640 system system /dev/rfcomm0 0660 bluetooth bluetooth /dev/ttyUSB0 0660 bluetooth bluetooth /dev/smdcntl0 0640 radio radio /dev/smdcntl1 0640 radio radio /dev/smdcntl2 0640 radio radio /dev/smdcntl3 0640 radio radio /dev/smdcntl4 0640 radio radio /dev/smdcntl5 0640 radio radio /dev/smdcntl6 0640 radio radio /dev/smdcntl7 0640 radio radio /dev/smdcntl8 0640 radio radio /dev/smdcnt_rev0 0640 radio radio /dev/smdcnt_rev1 0640 radio radio /dev/smdcnt_rev2 0640 radio radio /dev/smdcnt_rev3 0640 radio radio /dev/smdcnt_rev4 0640 radio radio /dev/smdcnt_rev5 0640 radio radio /dev/smdcnt_rev6 0640 radio radio /dev/smdcnt_rev7 0640 radio radio /dev/smdcnt_rev8 0640 radio radio /dev/smuxctl32 0640 radio radio /dev/sdioctl0 0640 radio radio /dev/sdioctl1 0640 radio radio /dev/sdioctl2 0640 radio radio /dev/sdioctl3 0640 radio radio /dev/sdioctl4 0640 radio radio /dev/sdioctl5 0640 radio radio /dev/sdioctl6 0640 radio radio /dev/sdioctl7 0640 radio radio /dev/sdioctl8 0640 radio radio /dev/rmnet_mux_ctrl 0640 radio radio /dev/hsicctl0 0640 radio radio /dev/hsicctl1 0640 radio radio /dev/hsicctl2 0640 radio radio /dev/hsicctl3 0640 radio radio /dev/hsicctl4 0640 radio radio /dev/hsicctl5 0640 radio radio /dev/hsicctl6 0640 radio radio /dev/hsicctl7 0640 radio radio /dev/hsicctl8 0640 radio radio /dev/hsicctl9 0640 radio radio /dev/hsicctl10 0640 radio radio /dev/hsicctl11 0640 radio radio /dev/hsicctl12 0640 radio radio /dev/hsicctl13 0640 radio radio /dev/hsicctl14 0640 radio radio /dev/hsicctl15 0640 radio radio /dev/hsicctl16 0640 radio radio /dev/mhi_pipe_14 0640 radio radio /dev/mhi_pipe_16 0640 radio radio /dev/mhi_pipe_32 0640 radio radio /dev/video* 0660 system camera /dev/media* 0660 system camera /dev/v4l-subdev* 0660 system camera #changhua.li modify from 660 to 666 for alipay use tz /dev/qseecom 0666 system drmrpc /dev/seemplog 0660 system system /dev/pft 0660 system drmrpc /dev/gemini0 0660 system camera /dev/jpeg0 0660 system camera /dev/jpeg1 0660 system camera /dev/jpeg2 0660 system camera /dev/jpeg3 0660 system camera /dev/adsprpc-smd 0664 system system /dev/system_health_monitor 0640 radio system /dev/msm_camera/* 0660 system camera /dev/gemini/ 0660 system camera /dev/mercury0 0660 system camera /dev/msm_vidc_reg 0660 system audio /dev/msm_vidc_dec 0660 system audio /dev/msm_vidc_dec_sec 0660 system audio /dev/msm_vidc_enc 0660 system audio /dev/msm_rotator 0660 system system /dev/hw_random 0600 root root /dev/adsprpc-smd 0664 system system #permissions for audio /dev/audio_slimslave 0660 system audio /dev/msm_qcelp 0660 system audio /dev/msm_evrc 0660 system audio /dev/msm_wma 0660 system audio /dev/msm_wmapro 0660 system audio /dev/msm_amrnb 0660 system audio /dev/msm_amrwb 0660 system audio /dev/msm_amrwbplus 0660 system audio /dev/msm_aac 0660 system audio /dev/msm_multi_aac 0660 system audio /dev/msm_aac_in 0660 system audio /dev/msm_qcelp_in 0660 system audio /dev/msm_evrc_in 0660 system audio /dev/msm_amrnb_in 0640 system audio /dev/msm_a2dp_in 0660 system audio /dev/msm_ac3 0660 system audio /dev/msm_audio_cal 0660 system audio /dev/msm_hweffects 0660 system audio /dev/msm_cad 0660 system audio /dev/msm_fm 0660 system audio /dev/msm_mvs 0660 system audio /dev/msm_pcm_lp_dec 0660 system audio /dev/msm_preproc_ctl 0660 system audio /dev/msm_rtac 0660 system audio /dev/msm_voicememo 0660 system audio /dev/radio0 0640 fm_radio fm_radio /dev/smd3 0660 bluetooth net_bt_stack /dev/smd2 0660 bluetooth net_bt_stack /dev/ttyHSL1 0660 system system /dev/ttyHS1 0660 system system /dev/mdm 0660 system radio /sys/devices/virtual/smdpkt/smdcntl* open_timeout 0664 radio radio /dev/sdio_tty_ciq_00 0660 system system /dev/tty_sdio_00 0660 system system /dev/ttyGS0 0660 system system /dev/i2c-5 0660 media media /dev/voice_svc 0660 system audio /dev/avtimer 0660 system audio # DVB devices /dev/dvb/adapter0/demux* 0440 media media /dev/dvb/adapter0/dvr* 0660 media media /dev/dvb/adapter0/video* 0660 media media # Broadcast devices /dev/tsc_mux0 0660 media media /dev/tsc_ci0 0660 media media # sensors /sys/devices/i2c-12/12-* pollrate_ms 0664 system system /sys/devices/f9925000.i2c/i2c-0/0-* enable 0660 input system /sys/devices/f9925000.i2c/i2c-0/0-* poll_delay 0660 input system /sys/devices/soc.0/78b6000.i2c/i2c-0/0-* enable 0660 input system /sys/devices/soc.0/78b6000.i2c/i2c-0/0-* poll_delay 0660 input system /sys/devices/soc.0/78b6000.i2c/i2c-0/0-* enable_wakeup 0660 input system /sys/devices/soc.0/78b6000.i2c/i2c-0/0-* max_latency 0660 input system /sys/devices/soc.0/78b6000.i2c/i2c-0/0-* flush 0660 input system /sys/devices/soc.0/78b6000.i2c/i2c-0/0-* calibrate 0660 input system /sys/devices/soc.0/78b5000.i2c/i2c-1/1-* enable 0660 input system /sys/devices/soc.0/78b5000.i2c/i2c-1/1-* poll_delay 0660 input system /sys/devices/soc.0/78b5000.i2c/i2c-1/1-* enable_wakeup 0660 input system /sys/devices/soc.0/78b5000.i2c/i2c-1/1-* max_latency 0660 input system /sys/devices/soc.0/78b5000.i2c/i2c-1/1-* flush 0660 input system /sys/devices/soc.0/78b5000.i2c/i2c-1/1-* calibrate 0660 input system /sys/devices/virtual/optical_sensors/proximity ps_adc 0660 input system /sys/devices/virtual/optical_sensors/proximity ps_poll_delay 0660 input system /sys/devices/virtual/optical_sensors/lightsensor ls_auto 0660 input system /sys/devices/virtual/optical_sensors/lightsensor ls_poll_delay 0660 input system /sys/devices/virtual/input/input* poll 0660 input system /sys/devices/virtual/input/input* pollrate_ms 0660 input system # UIO devices /dev/uio0 0660 system system /dev/uio1 0660 system system /dev/uio2 0660 system system # SSR devices /dev/subsys_* 0640 system system # Ultrasound device /dev/usf1 0660 system system # Ramdump devices /dev/ramdump* 0640 system system # Add device block for FRP /dev/block/bootdevice/by-name/config 0660 system system # Fingerprint sensor /dev/fpc1020 0660 system system ================================================ FILE: sensors/Android.mk ================================================ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := sensors.ssc.wrapper LOCAL_PROPRIETARY_MODULE := true LOCAL_SRC_FILES := \ SensorsWrapper.c LOCAL_SHARED_LIBRARIES := libdl liblog include $(BUILD_SHARED_LIBRARY) ================================================ FILE: sensors/SensorsWrapper.c ================================================ /* Copyright (C) 2016, The CyanogenMod Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include #ifdef __aarch64__ #define HAL_VENDOR_PATH "/vendor/lib64" #else #define HAL_VENDOR_PATH "/vendor/lib" #endif int global_sensors_count = -1; struct sensor_t* global_sensors_list = 0; struct hw_module_t* global_sensor_module = 0; pthread_once_t init_sensors_once = PTHREAD_ONCE_INIT; static int open_sensors(__unused const struct hw_module_t* hw_module, __unused const char* name, struct hw_device_t** hw_device_out); static int module__get_sensors_list(__unused struct sensors_module_t* module, struct sensor_t const** list); static struct hw_module_methods_t sensors_module_methods = { .open = open_sensors }; struct sensors_module_t HAL_MODULE_INFO_SYM = { .common = { .tag = HARDWARE_MODULE_TAG, .version_major = 1, .version_minor = 0, .id = SENSORS_HARDWARE_MODULE_ID, .name = "Sensors wrapper", .author = "The CyanogenMod Project", .methods = &sensors_module_methods, .dso = NULL, .reserved = {0} }, .get_sensors_list = module__get_sensors_list, .set_operation_mode = 0 }; /* Initialize the sensor by loading the underlying sensor * Called only once in a thread safe manner */ void init_sensors(void) { void* handle; int idx; int sensors_count; const struct sensor_t* sensors_list = 0; handle = dlopen(HAL_VENDOR_PATH"/sensors.ssc.so", RTLD_NOW); if (!handle) { ALOGE("init_sensors: dlopen() failed to load \"sensors.ssc.so\""); goto fail; } global_sensor_module = (struct hw_module_t*) dlsym(handle, HAL_MODULE_INFO_SYM_AS_STR); if (!global_sensor_module) { ALOGE("init_sensors: dlsym() failed to load driver details"); goto fail; } /* Lazy initialize based on driver providing data */ HAL_MODULE_INFO_SYM.set_operation_mode = ((struct sensors_module_t*)global_sensor_module)->set_operation_mode; sensors_count = ((struct sensors_module_t*)global_sensor_module)->get_sensors_list( (struct sensors_module_t*)global_sensor_module, &sensors_list); /* Check if there are any underlying sensors provided */ if (sensors_count <= 0) { ALOGE("get_sensors_list() did not return any sensors"); return; } global_sensors_list = calloc(sensors_count, sizeof(struct sensor_t)); if (!global_sensors_list) { ALOGE("calloc() failed to allocate memory"); goto fail; } /* Let us make sure it is set to 0 to avoid overruns */ global_sensors_count = 0; for (idx = 0; idx < sensors_count; ++idx) { if (SENSOR_TYPE_ROTATION_VECTOR == sensors_list[idx].type) { ALOGV("Skipping sensor: SENSOR_TYPE_ROTATION_VECTOR"); continue; } memcpy(&global_sensors_list[global_sensors_count], &sensors_list[idx], sizeof(struct sensor_t)); ++global_sensors_count; } /* Looks good: Update the handle in the module */ global_sensor_module->dso = handle; return; fail: global_sensors_count = 0; global_sensor_module = 0; if (handle) { dlclose(handle); } if (global_sensors_list) { free(global_sensors_list); global_sensors_list = 0; } return; } int module__get_sensors_list(__unused struct sensors_module_t* module, struct sensor_t const** list) { int idx; ALOGV("module__get_sensors_list start"); pthread_once(&init_sensors_once, init_sensors); *list = global_sensors_list; ALOGV("global_sensors_count: %d", global_sensors_count); for (idx = 0; idx < global_sensors_count; ++idx) { ALOGV("sensor type: %d", global_sensors_list[idx].type); } return (global_sensors_count > 0) ? global_sensors_count : 0; } int open_sensors(__unused const struct hw_module_t* hw_module, __unused const char* name, struct hw_device_t** hw_device_out) { ALOGV("open_sensors begin..."); pthread_once(&init_sensors_once, init_sensors); if (global_sensor_module) { sensors_open(global_sensor_module, (struct sensors_poll_device_t**)hw_device_out); /* Hook the current driver to intercept function calls */ if (*hw_device_out) { (*hw_device_out)->module = global_sensor_module; } } ALOGV("...open_sensors end"); return (*hw_device_out) ? 0 : -EINVAL; } ================================================ FILE: sepolicy/audioserver.te ================================================ allow audioserver system_data_file:sock_file write; allow audioserver rootfs:lnk_file getattr; ================================================ FILE: sepolicy/cam_sysfs.te ================================================ allow cam_sysfs sysfs:filesystem associate; ================================================ FILE: sepolicy/cameraserver.te ================================================ allow cameraserver system_data_file:sock_file write; ================================================ FILE: sepolicy/dpmd.te ================================================ allow dpmd mm-qcamerad:dir search; allow dpmd mm-qcamerad:file read; dontaudit dpmd self:capability sys_ptrace; ================================================ FILE: sepolicy/file.te ================================================ type proc_touchpanel, fs_type; type cam_proc, file_type; type cam_sysfs, fs_type; type cam_blob, file_type; type nv_data_file, file_type; type stm_sensor, file_type; ================================================ FILE: sepolicy/file_contexts ================================================ # We have a couple of non-standard NV partitions /dev/block/bootdevice/by-name/oem_dycnvbk u:object_r:modem_efs_partition_device:s0 /dev/block/bootdevice/by-name/oem_stanvbk u:object_r:modem_efs_partition_device:s0 # FRP partition /dev/block/bootdevice/by-name/config u:object_r:frp_block_device:s0 /persist/.genmac u:object_r:wifi_data_file:s0 /sys/devices/soc.0/f9928000.i2c/i2c-6/6-0029/enable_ps_sensor u:object_r:cam_sysfs:s0 /sys/devices/soc.0/f9928000.i2c/i2c-6/6-0029/set_delay_ms u:object_r:cam_sysfs:s0 /dev/input/event2 u:object_r:stm_sensor:s0 /data/oemnvitems(/.*)? u:object_r:nv_data_file:s0 ================================================ FILE: sepolicy/fingerprintd.te ================================================ allow fingerprintd sysfs:file write; allow fingerprintd system_data_file:dir { write remove_name add_name }; allow fingerprintd system_data_file:sock_file { create unlink }; allow fingerprintd tee_device:chr_file { read write ioctl open }; allow fingerprintd firmware_file:dir search; ================================================ FILE: sepolicy/genfs_contexts ================================================ genfscon proc /qcom_flash u:object_r:cam_proc:s0 genfscon proc /laser_info u:object_r:cam_proc:s0 genfscon proc /touchpanel u:object_r:proc_touchpanel:s0 genfscon proc /s1302 u:object_r:proc_touchpanel:s0 genfscon proc /tri-state-key u:object_r:proc_touchpanel:s0 ================================================ FILE: sepolicy/ims.te ================================================ allow ims system_prop:property_service set; ================================================ FILE: sepolicy/init.te ================================================ allow init cam_sysfs:file relabelto; allow init proc_dirty_ratio:file write; ================================================ FILE: sepolicy/ipacm-diag.te ================================================ allow ipacm-diag property_socket:sock_file write; allow ipacm-diag init:unix_stream_socket connectto; allow ipacm-diag system_prop:property_service set; ================================================ FILE: sepolicy/kernel.te ================================================ allow kernel sysfs:file write; ================================================ FILE: sepolicy/mediacodec.te ================================================ allow mediacodec system_data_file:sock_file write; allow mediacodec mpctl_socket:dir search; allow mediacodec rootfs:lnk_file getattr; ================================================ FILE: sepolicy/mediadrmserver.te ================================================ allow mediadrmserver rootfs:lnk_file getattr; ================================================ FILE: sepolicy/mediaserver.te ================================================ allow mediaserver system_server:unix_stream_socket { read write }; allow mediaserver sensorservice_service:service_manager find; allow mediaserver audio_device:chr_file { ioctl open read write }; allow mediaserver system_data_file:sock_file write; ================================================ FILE: sepolicy/mm-pp-daemon.te ================================================ allow mm-pp-daemon diag_device:chr_file { ioctl open read write }; ================================================ FILE: sepolicy/mm-qcamerad.te ================================================ allow mm-qcamerad cam_sysfs:file { open read write }; allow mm-qcamerad stm_sensor:chr_file { ioctl open read }; allow mm-qcamerad system_file:file execmod; ================================================ FILE: sepolicy/netmgrd.te ================================================ allow netmgrd self:capability dac_override; ================================================ FILE: sepolicy/per_mgr.te ================================================ allow per_mgr self:capability net_raw; ================================================ FILE: sepolicy/perfd.te ================================================ allow perfd system_data_file:sock_file write; allow perfd system_data_file:dir { add_name remove_name write }; allow perfd system_data_file:sock_file { create setattr unlink }; ================================================ FILE: sepolicy/priv_app.te ================================================ allow priv_app device:dir { read open }; allow priv_app rfs_system_file:dir getattr; ================================================ FILE: sepolicy/qmuxd.te ================================================ allow qmuxd property_socket:sock_file write; allow qmuxd diag_device:chr_file { ioctl open read write }; allow qmuxd init:unix_stream_socket connectto; allow qmuxd system_prop:property_service set; ================================================ FILE: sepolicy/qti_init_shell.te ================================================ allow qti_init_shell bluetooth_loader_exec:file { read open }; allow qti_init_shell btnvtool_exec:file { read getattr open execute execute_no_trans }; allow qti_init_shell kmsg_device:chr_file { write open }; allow qti_init_shell persist_bluetooth_file:dir search; allow qti_init_shell persist_bluetooth_file:file { read getattr open }; allow qti_init_shell smem_log_device:chr_file { read write ioctl open }; ================================================ FILE: sepolicy/radio.te ================================================ allow radio system_app_data_file:dir getattr; ================================================ FILE: sepolicy/rild.te ================================================ allow rild nv_data_file:dir { getattr search write add_name }; allow rild nv_data_file:file { write open create }; ================================================ FILE: sepolicy/sensors.te ================================================ allow sensors cam_sysfs:file getattr; allow sensors device:dir { write add_name }; allow sensors input_device:chr_file { relabelfrom getattr link }; allow sensors stm_sensor:chr_file relabelto; allow sensors input_device:dir search; ================================================ FILE: sepolicy/sysinit.te ================================================ allow sysinit rootfs:lnk_file getattr; ================================================ FILE: sepolicy/system_app.te ================================================ allow system_app proc_touchpanel:dir search; allow system_app proc_touchpanel:file { write getattr open read }; allow system_app qmuxd_socket:dir search; allow system_app cne_service:service_manager add; allow system_app dpmservice:service_manager add; allow system_app qtitetherservice_service:service_manager add; allow system_app dpmd_data_file:dir { search write add_name }; allow system_app dpmd_data_file:file create; dontaudit system_app netd_service:service_manager find; ================================================ FILE: sepolicy/system_server.te ================================================ allow system_server persist_file:dir { read write }; allow system_server proc_touchpanel:dir search; allow system_server proc_touchpanel:file { write open getattr read }; allow system_server stm_sensor:chr_file { read write ioctl open }; allow system_app dpmd_data_file:dir { getattr open read }; allow system_app dpmd_data_file:file { getattr lock open read setattr write }; allow system_app dpmd_socket:sock_file write; allow system_app ipa_dev:chr_file { ioctl open read write }; allow system_app qmuxd:unix_stream_socket connectto; allow system_app qmuxd_socket:dir { add_name write }; allow system_app qmuxd_socket:sock_file { create setattr write }; allow system_server unlabeled:file unlink; allow system_server user_profile_data_file:dir { read open }; ================================================ FILE: sepolicy/tee.te ================================================ allow tee vfat:file { read getattr open }; ================================================ FILE: sepolicy/thermal-engine.te ================================================ allow thermal-engine property_socket:sock_file write; allow thermal-engine init:unix_stream_socket connectto; allow thermal-engine system_prop:property_service set; ================================================ FILE: sepolicy/time_daemon.te ================================================ allow time_daemon property_socket:sock_file write; allow time_daemon init:unix_stream_socket connectto; allow time_daemon system_prop:property_service set; ================================================ FILE: sepolicy/ueventd.te ================================================ allow ueventd vfat:dir search; allow ueventd vfat:file { read open }; allow ueventd stm_sensor:chr_file { create setattr }; allow ueventd cam_sysfs:file getattr; ================================================ FILE: sepolicy/vold.te ================================================ allow vold proc_touchpanel:dir { read open }; ================================================ FILE: sepolicy/wcnss_filter.te ================================================ allow wcnss_filter rootfs:lnk_file getattr; ================================================ FILE: sepolicy/wcnss_service.te ================================================ allow wcnss_service self:capability { setgid setuid }; ================================================ FILE: setup-makefiles.sh ================================================ #!/bin/bash # # Copyright (C) 2016 The CyanogenMod Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # set -e # Required! DEVICE=oneplus2 VENDOR=oneplus # Load extractutils and do some sanity checks MY_DIR="${BASH_SOURCE%/*}" if [[ ! -d "$MY_DIR" ]]; then MY_DIR="$PWD"; fi CM_ROOT="$MY_DIR"/../../.. HELPER="$CM_ROOT"/vendor/cm/build/tools/extract_utils.sh if [ ! -f "$HELPER" ]; then echo "Unable to find helper script at $HELPER" exit 1 fi . "$HELPER" # Initialize the helper setup_vendor "$DEVICE" "$VENDOR" "$CM_ROOT" # Copyright headers and guards write_headers # The standard blobs write_makefiles "$MY_DIR"/proprietary-files.txt cat << EOF >> "$ANDROIDMK" EOF printf '\n%s\n' "\$(call inherit-product, vendor/qcom/binaries/msm8994/graphics/graphics-vendor.mk)" >> "$PRODUCTMK" # We are done! write_footers ================================================ FILE: system.prop ================================================ # system.prop for OnePlus2 # Audio audio.offload.video=true persist.audio.fluence.voicecall=true persist.audio.fluence.voicerec=false persist.audio.fluence.speaker=true ro.qc.sdk.audio.fluencetype=fluence ro.qc.sdk.audio.ssr=false persist.audio.ssr.3mic=false media.aac_51_output_enabled=true audio.offload.pcm.16bit.enable=true audio.offload.pcm.24bit.enable=true use.voice.path.for.pcm.voip=true audio.offload.multiple.enabled=true audio.offload.gapless.enabled=true mm.enable.smoothstreaming=true audio.offload.buffer.size.kb=32 tunnel.audio.encode=false # Bluetooth bluetooth.hfp.client=1 qcom.bluetooth.soc=rome ro.bluetooth.a4wp=true ro.bluetooth.wipower=true # Camera persist.camera.HAL3.enabled=0 persist.camera.cpp.duplication=false vidc.debug.perf.mode=2 vidc.enc.dcvs.extra-buff-count=2 media.stagefright.legacyencoder=true media.stagefright.less-secure=true # CEC ro.hdmi.device_type=4 persist.sys.hdmi.addr.playback=4 ro.hdmi.enable=true persist.speaker.prot.enable=false persist.spkr.cal.duration=0 qcom.hw.aac.encoder=true # CNE persist.cne.feature=1 # Data Power Manager (DPM) persist.dpm.feature=7 persist.env.fastdorm.enabled=true persist.sys.dpmd.nsrm=3 # Debug logging for DPM & CNE can be enabled via: # Push libdpmlog.so to system/vendor/lib|64 #persist.dpm.nsrm.bkg.evt=3955 #persist.dpm.loglevel=7825 # Dex2oat limits dalvik.vm.boot-dex2oat-threads=4 dalvik.vm.dex2oat-threads=2 dalvik.vm.image-dex2oat-threads=4 # GPS persist.gps.qc_nlp_in_use=1 persist.loc.nlp_name=com.qualcomm.location ro.gps.agps_provider=1 ro.pip.gated=0 # Graphics persist.hwc.mdpcomp.enable=true dalvik.vm.heapsize=36m ro.qualcomm.cabl=0 ro.sf.lcd_density=480 ro.opengles.version=196610 # QC vendor extension ro.vendor.extension_library=libqti-perfd-client.so ro.frp.pst=/dev/block/bootdevice/by-name/config drm.service.enabled=true # RIL rild.libpath=/vendor/lib64/libril-qc-qmi-1.so rild.libargs=-d /dev/smd0 persist.rild.nitz_plmn= persist.rild.nitz_long_ons_0= persist.rild.nitz_long_ons_1= persist.rild.nitz_long_ons_2= persist.rild.nitz_long_ons_3= persist.rild.nitz_short_ons_0= persist.rild.nitz_short_ons_1= persist.rild.nitz_short_ons_2= persist.rild.nitz_short_ons_3= ril.subscription.types=NV,RUIM DEVICE_PROVISIONED=1 telephony.lteOnGsmDevice=1 persist.radio.multisim.config=dsds persist.radio.apm_sim_not_pwdn=1 persist.radio.sib16_support=1 persist.radio.sw_mbn_update=0 persist.radio.start_ota_daemon=1 persist.radio.rat_on=combine persist.data.qmi.adb_logmask=0 # Sensors ro.qc.sdk.sensors.gestures=true ro.qc.sdk.gestures.camera=false ro.qc.sdk.camera.facialproc=false # Storage ro.sys.sdcardfs=true # Time services persist.timed.enable=true # Wifi persist.data.iwlan.enable=true ================================================ FILE: tftp.mk ================================================ ######################################################################### # Create Folder Structure ######################################################################### $(shell rm -rf $(TARGET_OUT)/rfs/) #To be enabled when prepopulation support is needed for the read_write folder # $(shell rm -rf $(TARGET_OUT_DATA)/rfs/) # $(shell mkdir -p $(TARGET_OUT_DATA)/rfs/msm/mpss/) # $(shell mkdir -p $(TARGET_OUT_DATA)/rfs/msm/adsp/) # $(shell mkdir -p $(TARGET_OUT_DATA)/rfs/mdm/mpss/) # $(shell mkdir -p $(TARGET_OUT_DATA)/rfs/mdm/adsp/) ######################################################################### # MSM Folders ######################################################################### $(shell mkdir -p $(TARGET_OUT)/rfs/msm/mpss/readonly) $(shell mkdir -p $(TARGET_OUT)/rfs/msm/adsp/readonly) $(shell ln -s /data/tombstones/modem $(TARGET_OUT)/rfs/msm/mpss/ramdumps) $(shell ln -s /persist/rfs/msm/mpss $(TARGET_OUT)/rfs/msm/mpss/readwrite) $(shell ln -s /persist/rfs/shared $(TARGET_OUT)/rfs/msm/mpss/shared) $(shell ln -s /persist/hlos_rfs/shared $(TARGET_OUT)/rfs/msm/mpss/hlos) $(shell ln -s /firmware $(TARGET_OUT)/rfs/msm/mpss/readonly/firmware) $(shell ln -s /data/tombstones/lpass $(TARGET_OUT)/rfs/msm/adsp/ramdumps) $(shell ln -s /persist/rfs/msm/adsp $(TARGET_OUT)/rfs/msm/adsp/readwrite) $(shell ln -s /persist/rfs/shared $(TARGET_OUT)/rfs/msm/adsp/shared) $(shell ln -s /persist/hlos_rfs/shared $(TARGET_OUT)/rfs/msm/adsp/hlos) $(shell ln -s /firmware $(TARGET_OUT)/rfs/msm/adsp/readonly/firmware) ######################################################################### # MDM Folders ######################################################################### $(shell mkdir -p $(TARGET_OUT)/rfs/mdm/mpss/readonly) $(shell mkdir -p $(TARGET_OUT)/rfs/mdm/adsp/readonly) $(shell mkdir -p $(TARGET_OUT)/rfs/mdm/sparrow/readonly) $(shell ln -s /data/tombstones/modem $(TARGET_OUT)/rfs/mdm/mpss/ramdumps) $(shell ln -s /persist/rfs/mdm/mpss $(TARGET_OUT)/rfs/mdm/mpss/readwrite) $(shell ln -s /persist/rfs/shared $(TARGET_OUT)/rfs/mdm/mpss/shared) $(shell ln -s /persist/hlos_rfs/shared $(TARGET_OUT)/rfs/mdm/mpss/hlos) $(shell ln -s /firmware $(TARGET_OUT)/rfs/mdm/mpss/readonly/firmware) $(shell ln -s /data/tombstones/lpass $(TARGET_OUT)/rfs/mdm/adsp/ramdumps) $(shell ln -s /persist/rfs/mdm/adsp $(TARGET_OUT)/rfs/mdm/adsp/readwrite) $(shell ln -s /persist/rfs/shared $(TARGET_OUT)/rfs/mdm/adsp/shared) $(shell ln -s /persist/hlos_rfs/shared $(TARGET_OUT)/rfs/mdm/adsp/hlos) $(shell ln -s /firmware $(TARGET_OUT)/rfs/mdm/adsp/readonly/firmware) $(shell ln -s /data/tombstones/sparrow $(TARGET_OUT)/rfs/mdm/sparrow/ramdumps) $(shell ln -s /persist/rfs/mdm/sparrow $(TARGET_OUT)/rfs/mdm/sparrow/readwrite) $(shell ln -s /persist/rfs/shared $(TARGET_OUT)/rfs/mdm/sparrow/shared) $(shell ln -s /persist/hlos_rfs/shared $(TARGET_OUT)/rfs/mdm/sparrow/hlos) $(shell ln -s /firmware $(TARGET_OUT)/rfs/mdm/sparrow/readonly/firmware) ######################################################################### # APQ Folders ######################################################################### $(shell mkdir -p $(TARGET_OUT)/rfs/apq/gnss/readonly) $(shell ln -s /data/tombstones/modem $(TARGET_OUT)/rfs/apq/gnss/ramdumps) $(shell ln -s /persist/rfs/apq/gnss $(TARGET_OUT)/rfs/apq/gnss/readwrite) $(shell ln -s /persist/rfs/shared $(TARGET_OUT)/rfs/apq/gnss/shared) $(shell ln -s /persist/hlos_rfs/shared $(TARGET_OUT)/rfs/apq/gnss/hlos) $(shell ln -s /firmware $(TARGET_OUT)/rfs/apq/gnss/readonly/firmware) ================================================ FILE: vendorsetup.sh ================================================ add_lunch_combo cm_oneplus2-user add_lunch_combo cm_oneplus2-userdebug add_lunch_combo cm_oneplus2-eng ================================================ FILE: vr/Android.mk ================================================ # Copyright 2016 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := vr.c LOCAL_MODULE_RELATIVE_PATH := hw LOCAL_SHARED_LIBRARIES := liblog libcutils LOCAL_CFLAGS += -Wno-unused-parameter LOCAL_MODULE := vr.$(TARGET_BOARD_PLATFORM) LOCAL_MODULE_TAGS := optional include $(BUILD_SHARED_LIBRARY) ================================================ FILE: vr/vr.c ================================================ /* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "VrHALImpl" #include #include #include #include #include #include #include #include // OnePlus2 has two inflight numbers. By default, inflight=15 and inflight_low_latency=4. // Inflight is only used when there is a single GL context, when there is more than one // context, inflight_low_latency is used. Since we are only interested in affecting // performance when there is context preemption, we only have to modify the low latency // parameter. static const int DEFAULT_GPU_INFLIGHT = 4; static const int VR_MODE_GPU_INFLIGHT = 2; static const char* GPU_INFLIGHT_PATH = "/sys/class/kgsl/kgsl-3d0/dispatch/inflight_low_latency"; /** * Write 'len' characters from 'input' character array into file at path 'outFile.' * * Return 0 on success, or a negative error code. */ static int write_string(const char* input, size_t len, const char* outFile) { int fd = -1; ssize_t err = 0; // Check input strings. if (input == NULL || outFile == NULL) { ALOGE("%s: Invalid input to write", __FUNCTION__); return -1; } // Open file, check for errors. fd = open(outFile, O_WRONLY); if (fd < 0) { ALOGE("%s: Failed to open file %s, error %s (%d)", __FUNCTION__, outFile, strerror(errno), -errno); return -errno; } // Write file, check for errors. err = write(fd, input, len); if (err < 0) { ALOGE("%s: Failed to write file %s, error %s (%d)", __FUNCTION__, outFile, strerror(errno), -errno); close(fd); return -errno; } // Close and return success. close(fd); return 0; } /** * Write integer 'input' formatted as a character string into the file at path 'outFile.' * * Return 0 on success, or a negative error code. */ static int write_int(int input, const char* outFile) { char buffer[128] = {0,}; int bytes = snprintf(buffer, sizeof(buffer), "%d", input); if (bytes < 0 || (size_t) bytes >= sizeof(buffer)) { ALOGE("%s: Failed to format integer %d", __FUNCTION__, input); return -EINVAL; } return write_string(buffer, (size_t) bytes, outFile); } // Set global display/GPU/scheduler configuration to used for VR apps. static void set_vr_performance_configuration() { int err = 0; // Set in-flight buffers to 2. err = write_int(VR_MODE_GPU_INFLIGHT, GPU_INFLIGHT_PATH); if (err < 0) { ALOGW("%s: Error while setting configuration for VR mode.", __FUNCTION__); } } // Reset to default global display/GPU/scheduler configuration. static void unset_vr_performance_configuration() { int err = 0; // Set in-flight buffers back to default (15). err = write_int(DEFAULT_GPU_INFLIGHT, GPU_INFLIGHT_PATH); if (err < 0) { ALOGW("%s: Error while setting configuration for VR mode.", __FUNCTION__); } } static void vr_init(struct vr_module *module) { // NOOP } static void vr_set_vr_mode(struct vr_module *module, bool enabled) { if (enabled) { set_vr_performance_configuration(); } else { unset_vr_performance_configuration(); } } static struct hw_module_methods_t vr_module_methods = { .open = NULL, // There are no devices for this HAL interface. }; vr_module_t HAL_MODULE_INFO_SYM = { .common = { .tag = HARDWARE_MODULE_TAG, .module_api_version = VR_MODULE_API_VERSION_1_0, .hal_api_version = HARDWARE_HAL_API_VERSION, .id = VR_HARDWARE_MODULE_ID, .name = "OnePlus2 VR HAL", .author = "The Android Open Source Project", .methods = &vr_module_methods, }, .init = vr_init, .set_vr_mode = vr_set_vr_mode, }; ================================================ FILE: wifi/WCNSS_qcom_cfg.ini ================================================ # This file allows user to override the factory # defaults for the WLAN Driver # Enable IMPS or not gEnableImps=1 # Enable/Disable Idle Scan gEnableIdleScan=0 # Increase sleep duration (seconds) during IMPS # 0 implies no periodic wake up from IMPS. Periodic wakeup is # unnecessary if Idle Scan is disabled. gImpsModSleepTime=0 # Enable BMPS or not gEnableBmps=1 # Enable suspend or not # 1: Enable standby, 2: Enable Deep sleep, 3: Enable Mcast/Bcast Filter gEnableSuspend=3 # Phy Mode (auto, b, g, n, etc) # Valid values are 0-9, with 0 = Auto, 4 = 11n, 9 = 11ac # 1 = 11abg, 2 = 11b, 3 = 11g, 5 = 11g only, 6 = 11n only # 7 = 11b only 8 = 11ac only. gDot11Mode=0 # CSR Roaming Enable(1) Disable(0) gRoamingTime=0 # Assigned MAC Addresses - This will be used until NV items are in place # Each byte of MAC address is represented in Hex format as XX Intf0MacAddress=000AF58989FF Intf1MacAddress=000AF58989FE Intf2MacAddress=000AF58989FD Intf3MacAddress=000AF58989FC # UAPSD service interval for VO,VI, BE, BK traffic InfraUapsdVoSrvIntv=0 InfraUapsdViSrvIntv=0 InfraUapsdBeSrvIntv=0 InfraUapsdBkSrvIntv=0 # Flag to allow STA send AddTspec even when ACM is Off gAddTSWhenACMIsOff=1 # Make 1x1 the default antenna configuration gNumRxAnt=1 # Beacon filtering frequency (unit in beacon intervals) gNthBeaconFilter=50 # Enable WAPI or not # WAPIIsEnabled=0 # Flags to filter Mcast abd Bcast RX packets. # Value 0: No filtering, 1: Filter all Multicast. # 2: Filter all Broadcast. 3: Filter all Mcast abd Bcast McastBcastFilter=3 #Flag to enable HostARPOffload feature or not hostArpOffload=1 #Flag to enable TCPChkSumOffld feature or not gEnableTCPChkSumOffld=0 #Flag to enable HostNSOffload feature or not hostNSOffload=1 #Flag to enable IPChkSumOffld feature or not gEnableIPChecksumOffload=0 #SoftAP Related Parameters # AP MAc addr gAPMacAddr=000AF589dcab # 802.11n Protection flag gEnableApProt=1 #Enable OBSS protection gEnableApOBSSProt=1 #Enable/Disable UAPSD for SoftAP gEnableApUapsd=1 # Fixed Rate gFixedRate=0 # Maximum Tx power # gTxPowerCap=30 # Fragmentation Threshold # gFragmentationThreshold=2346 # RTS threshold #RTSThreshold=1048576 # Intra-BSS forward gDisableIntraBssFwd=0 # WMM Enable/Disable WmmIsEnabled=0 # 802.11d support g11dSupportEnabled=1 # 802.11h support g11hSupportEnabled=1 # DFS Master Capability gEnableDFSMasterCap=1 # ESE Support and fast transition EseEnabled=1 ImplicitQosIsEnabled=0 gNeighborScanTimerPeriod=200 gNeighborLookupThreshold=76 gNeighborReassocThreshold=81 gNeighborScanChannelMinTime=20 gNeighborScanChannelMaxTime=30 gMaxNeighborReqTries=3 # Legacy (non-ESE, non-802.11r) Fast Roaming Support # To enable, set FastRoamEnabled=1 # To disable, set FastRoamEnabled=0 FastRoamEnabled=1 #Check if the AP to which we are roaming is better than current AP in terms of RSSI. #Checking is disabled if set to Zero.Otherwise it will use this value as to how better #the RSSI of the new/roamable AP should be for roaming # ifdef VENDOR_EDIT RoamRssiDiff=5 # else #RoamRssiDiff=3 # endif /* VENDOR_EDIT */ # If the RSSI of any available candidate is better than currently associated # AP by at least gImmediateRoamRssiDiff, then being to roam immediately (without # registering for reassoc threshold). # NOTE: Value of 0 means that we would register for reassoc threshold. gImmediateRoamRssiDiff=10 # To enable, set gRoamIntraBand=1 (Roaming within band) # To disable, set gRoamIntraBand=0 (Roaming across band) gRoamIntraBand=0 # SAP Country code # Default Country Code is 2 bytes, 3rd byte is optional indoor or out door. # Example # US Indoor, USI # Korea Outdoor, KRO # Japan without optional byte, JP # France without optional byte, FR #gAPCntryCode=USI #Short Guard Interval Enable/disable gShortGI20Mhz=1 gShortGI40Mhz=1 #Auto Shutdown Value in seconds. A value of 0 means Auto shutoff is disabled gAPAutoShutOff=0 #Auto Shutdown wlan : Value in Seconds. 0 means disabled. Max 1 day = 86400 sec gWlanAutoShutdown = 0 # SAP auto channel selection configuration # 0 = disable auto channel selection # 1 = enable auto channel selection, channel provided by supplicant will be ignored gApAutoChannelSelection=0 # Listen Energy Detect Mode Configuration # Valid values 0-128 # 128 means disable Energy Detect feature # 0-9 are threshold code and 7 is recommended value from system if feature is to be enabled. # 10-128 are reserved. # The EDET threshold mapping is as follows in 3dB step: # 0 = -60 dBm # 1 = -63 dBm # 2 = -66 dBm # ... # 7 = -81 dBm # 8 = -84 dBm # 9 = -87 dBm # Note: Any of these settings are valid. Setting 0 would yield the highest power saving (in a noisy environment) at the cost of more range. The range impact is approximately #calculated as: # # Range Loss (dB) = EDET threshold level (dBm) + 97 dBm. # gEnablePhyAgcListenMode=128 #Preferred band (both or 2.4 only or 5 only) BandCapability=0 #Beacon Early Termination (1 = enable the BET feature, 0 = disable) enableBeaconEarlyTermination=0 beaconEarlyTerminationWakeInterval=3 #SOFTAP Channel Range selection gAPChannelSelectStartChannel=1 gAPChannelSelectEndChannel=11 #SOFTAP Channel Range selection Operating band # 0:2.4GHZ 1: LOW-5GHZ 2:MID-5GHZ 3:HIGH-5GHZ 4: 4.9HZ BAND gAPChannelSelectOperatingBand=0 #Channel Bonding gChannelBondingMode5GHz=1 gChannelBondingMode24GHz=0 #Enable Keep alive with non-zero period value gStaKeepAlivePeriod = 30 #Say gGoKeepAlivePeriod(5 seconds) and gGoLinkMonitorPeriod(10 seconds). #For every 10 seconds DUT send Qos Null frame(i.e., Keep Alive frame if link is idle for last 10 seconds.) #For both active and power save clients. #Power save clients: DUT set TIM bit from 10th second onwards and till client honors TIM bit. #If doesn't honor for 5 seconds then DUT remove client. #Active clients: DUT send Qos Null frame for 10th seconds onwards if it is not success still we try on #11th second if not tries on 12th and so on till 15th second. Hence before disconnection DUT will send 5 NULL frames. #Hence in any case DUT will detect client got removed in (10+5) seconds. i.e., (gGoKeepAlivePeriod + gGoLinkMonitorPeriod).. #gGoLinkMonitorPeriod/ gApLinkMonitorPeriod is period where link is idle and it is period #where we send NULL frame. #gApLinkMonitorPeriod = 10 #gGoLinkMonitorPeriod = 10 #gGoKeepAlivePeriod/gApKeepAlivePeriod is time to spend to check whether frame are succeed to send or not. #Hence total effective detection time is gGoLinkMonitorPeriod+ gGoKeepAlivePeriod/gApLinkMonitorPeriod+ gApKeepAlivePeriod. gGoKeepAlivePeriod = 20 gApKeepAlivePeriod = 20 #If set will start with active scan after driver load, otherwise will start with #passive scan to find out the domain gEnableBypass11d=1 #If set to 0, will not scan DFS channels gEnableDFSChnlScan=1 gVhtChannelWidth=2 gEnableLogp=1 # Enable Automatic Tx Power control gEnableAutomaticTxPowerControl=1 # 0 for OLPC 1 for CLPC and SCPC gEnableCloseLoop=1 #Data Inactivity Timeout when in powersave (in ms) gDataInactivityTimeout=200 # VHT Tx/Rx MCS values # Valid values are 0,1,2. If commented out, the default value is 0. # 0=MCS0-7, 1=MCS0-8, 2=MCS0-9 gVhtRxMCS=2 gVhtTxMCS=2 # VHT Tx/Rx MCS values for 2x2 # Valid values are 0,1,2. If commented out, the default value is 0. # 0=MCS0-7, 1=MCS0-8, 2=MCS0-9 gEnable2x2=1 gVhtRxMCS2x2=2 gVhtTxMCS2x2=2 # Enable Tx beamforming gTxBFEnable=1 # Enable Tx beamforming in VHT20MHz # Valid values are 0,1. If commented out, the default value is 0. # 0=disable, 1=enable gEnableTxBFin20MHz=1 # Set txchainmask and rxchainmask # These parameters are used only if gEnable2x2 is 0 # Valid values are 1,2 # Set gSetTxChainmask1x1=1 or gSetRxChainmask1x1=1 to select chain0. # Set gSetTxChainmask1x1=2 or gSetRxChainmask1x1=2 to select chain1. gSetTxChainmask1x1=1 gSetRxChainmask1x1=1 # Enable CRDA regulatory support by settings default country code #gCrdaDefaultCountryCode=TW # Scan Timing Parameters # gPassiveMaxChannelTime=110 # gPassiveMinChannelTime=60 gActiveMaxChannelTime=40 gActiveMinChannelTime=20 #If set to 0, MCC is not allowed. gEnableMCCMode=1 # MCC to SCC Switch mode: 0-Disable 1-Enable 2-Force SCC if same band gWlanMccToSccSwitchMode = 0 # 1=enable STBC; 0=disable STBC gEnableRXSTBC=1 # 1=enable tx STBC; 0=disable gEnableTXSTBC=1 # 1=enable rx LDPC; 0=disable gEnableRXLDPC=1 # Enable Active mode offload gEnableActiveModeOffload=1 #Enable Scan Results Aging based on timer #Timer value is in seconds #If Set to 0 it will not enable the feature gScanAgingTime=0 #Enable Scan Results Aging based on number of scans # ifdef VENDOR_EDIT # use default value 3 #gScanResultAgeCount=1 # endif /* VENDOR_EDIT */ #Enable Power saving mechanism Based on Android Framework #If set to 0 Driver internally control the Power saving mechanism #If set to 1 Android Framwrok control the Power saving mechanism isAndroidPsEn=0 #Enable thermal mitigation gThermalMitigationEnable=0 gEnableFastRoamInConcurrency=1 #List of Country codes for which 11ac needs to be disabled #Each country code must be delimited by comma(,) gListOfNon11acCountryCode=RU,UA,ZA #Maxium Channel time in msec gMaxMediumTime = 6000 # 802.11K support gRrmEnable=1 gRrmOperChanMax=8 gRrmNonOperChanMax=8 gRrmRandIntvl=100 #Scan offload gEnableDirectedScanOffload=1 #FlexConnect Power Factor #Default is set to 0 (disable) gFlexConnectPowerFactor=0 #Disable split scan, the FW will take care of it gNumChanCombinedConc=60 #Enable Power Save offload gEnablePowerSaveOffload=1 #Enable firmware uart print gEnablefwprint=0 #Enable firmware log gEnablefwlog=1 #IPA config gIPAEnable=0x00 gIPADescSize=800 gIPAPreFilterEnable=1 gIPARMEnable=1 gIPAIPv6Enable=1 #P2P Listen offload gEnableP2pListenOffload=1 # Maximum Receive AMPDU size (VHT only. Valid values: 0->8k 1->16k 2->32k 3->64k 4->128k) gVhtAmpduLenExponent=7 # Maximum MPDU length (VHT only. Valid values: 0->3895 octets, 1->7991 octets, 2->11454 octets) gVhtMpduLen=2 # Maximum number of wow filters required #gMaxWoWFilters=22 # WOW Enable/Disable. # 0 - Disable both magic pattern match and pattern byte match. # 1 - Enable magic pattern match on all interfaces. # 2 - Enable pattern byte match on all interfaces. # 3 - Enable both magic patter and pattern byte match on all interfaces. # Default value of gEnableWoW is 3. # gEnableWoW=0 # Enable or Disable MCC Adaptive Scheduler at the FW # 1=Enable (default), 0=Disable gEnableMCCAdaptiveScheduler=1 #Enable or Disable p2p device address administered isP2pDeviceAddrAdministrated=0 #Enable Rx thread gEnableRxThread=1 # Set Thermal Power limit TxPower2g=10 TxPower5g=10 # Remove Overlap channel restriction gEnableOverLapCh=0 #Enable VHT on 2.4Ghz gEnableVhtFor24GHzBand=1 #Enable or Disable 5G early beacon termination gEnable5gEBT=1 #Maximum number of offload peers supported # gMaxOffloadPeers=2 # controlling the following offload patterns # through ini parameter. Default value is 1 # to disable set it to zero. ssdp = 0 # Setup multicast pattern for mDNS 224.0.0.251, # SSDP 239.255.255.250 and LLMNR 224.0.0.252 ssdp = 0 #Enable Memory Deep Sleep gEnableMemDeepSleep=1 # Bus bandwidth threshold values in terms of number of packets gBusBandwidthHighThreshold=2000 gBusBandwidthMediumThreshold=500 gBusBandwidthLowThreshold=150 # Bus bandwidth compute timeout value in ms gBusBandwidthComputeInterval=100 # Regulatory Setting; 0=STRICT; 1=CUSTOM gRegulatoryChangeCountry=1 # Maximum number of concurrent connections gMaxConcurrentActiveSessions=2 # Radar PRI multiplier gDFSradarMappingPriMultiplier=4 gPNOScanSupport=1 # Enable/Disable RX full reorder offload gReorderOffloadSupported=1 # userspace country code setting shld take priority gCountryCodePriority=1 #Enable/Disable LPASS support # 0 to disable, 1 to enable gEnableLpassSupport=0 # Enable(1)/Disable(0) SIFS burst gEnableSifsBurst=1 # Enable or Disable Multi-user MIMO # 1=Enable (default), 0=Disable gEnableMuBformee=1 # Enable/Disable channel avoidance for SAP in SCC scenario # 0 - disable # 1 - enable gSapSccChanAvoidance=0 # RA filtering rate limit param, the current value would not # help if the lifetime in RA is less than 3*60=3min. Then # we need to change it, though it is uncommon. # gRAFilterEnable=0 gRArateLimitInterval=60 # Inactivity time (in ms) to end TX Service Period while in IBSS power save mode gIbssTxSpEndInactivityTime=10 # Enable support for TDLS # 0 - disable # 1 - enable gEnableTDLSSupport=1 # Enable support for Implicit Trigger of TDLS. That is, wlan driver shall # initiate TDLS Discovery towards a peer whenever setup criteria (throughput # and RSSI) is met and then will initiate teardown when teardown criteria # (idle packet count and RSSI) is met. # 0 - disable # 1 - enable gEnableTDLSImplicitTrigger=1 # Enable TDLS External Control. That is, user space application has to # first configure a peer MAC in wlan driver towards which TDLS is desired. # Device will establish TDLS only towards those configured peers whenever # TDLS criteria (throughput and RSSI threshold) is met and teardown TDLS # when teardown criteria (idle packet count and RSSI) is met. However, # device will accept TDLS connection if it is initiated from any other peer, # even if that peer is not configured. # 0 - disable # 1 - enable # For TDLS External Control, Implicit Trigger must also be enabled. gTDLSExternalControl=1 # Enable support for TDLS off-channel operation # 0 - disable # 1 - enable # TDLS off-channel operation will be invoked when there is only one # TDLS connection. gEnableTDLSOffChannel=1 # Enable/Disable Roaming Offload Support (a.k.a Key Management Offload) # 0 to disable, 1 to enable gRoamOffloadEnabled=0 gEnableSelfRecovery=1 # Enable Runtime PM Feature. # Enabling this feature will put target wow and shutdown pcie link # when inactivity is detected in WLAN Driver. # This feature is inactive when beaconing interfaces are active with # clients associated. # 0 - disable # 1 - enable gRuntimePM=0 # When gRuntimePM is disabled gRuntimeAutoTime won't take effect. # The Time is in msec. # 100 is min, 10000 is max, 500 is default. gRuntimePMDelay=500 # Enable to check FW hash if secure FW feature is enabled. It's for defconfig # builds only since it will be ignored in performance/release builds. gEnableFWHashCheck=1 #Enable TDLS Scan gEnableTDLSScan=1 #Disable scanning for DFS channels while roaming gAllowDFSChannelRoam=0 # jeff.lin, 2015.12.17, reduce the scan time while turning WiFi on # ifdef VENDOR_EDIT gInitialScanNoDFSChnl=1 gInitialDwellTime=20 # endif # ifdef VENDOR_EDIT gSoftApMaxPeers=15 gRoamBmissFirstBcnt=30 gRoamBmissFinalBcnt=30 RTSThreshold=2437 gTcpDelAckThresholdHigh=10000 # endif /* VENDOR_EDIT */ END # Note: Configuration parser would not read anything past the END marker ================================================ FILE: wifi/hostapd.accept ================================================ # List of MAC addresses that are allowed to authenticate (IEEE 802.11) # with the AP. Optional VLAN ID can be assigned for clients based on the # MAC address if dynamic VLANs (hostapd.conf dynamic_vlan option) are used. ================================================ FILE: wifi/hostapd.conf ================================================ ##### hostapd configuration file ############################################## # Empty lines and lines starting with # are ignored # AP netdevice name (without 'ap' postfix, i.e., wlan0 uses wlan0ap for # management frames); ath0 for madwifi interface=wlan0 # In case of madwifi and nl80211 driver interfaces, an additional configuration # parameter, bridge, must be used to notify hostapd if the interface is # included in a bridge. This parameter is not used with Host AP driver. #bridge=br0 # Driver interface type (hostap/wired/madwifi/prism54/test/none/nl80211/bsd); # default: hostap). nl80211 is used with all Linux mac80211 drivers. # Use driver=none if building hostapd as a standalone RADIUS server that does # not control any wireless/wired driver. driver=nl80211 # hostapd event logger configuration # # Two output method: syslog and stdout (only usable if not forking to # background). # # Module bitfield (ORed bitfield of modules that will be logged; -1 = all # modules): # bit 0 (1) = IEEE 802.11 # bit 1 (2) = IEEE 802.1X # bit 2 (4) = RADIUS # bit 3 (8) = WPA # bit 4 (16) = driver interface # bit 5 (32) = IAPP # bit 6 (64) = MLME # # Levels (minimum value for logged events): # 0 = verbose debugging # 1 = debugging # 2 = informational messages # 3 = notification # 4 = warning # logger_syslog=-1 logger_syslog_level=2 logger_stdout=-1 logger_stdout_level=2 # Dump file for state information (on SIGUSR1) dump_file=/tmp/hostapd.dump # Interface for separate control program. If this is specified, hostapd # will create this directory and a UNIX domain socket for listening to requests # from external programs (CLI/GUI, etc.) for status information and # configuration. The socket file will be named based on the interface name, so # multiple hostapd processes/interfaces can be run at the same time if more # than one interface is used. # /var/run/hostapd is the recommended directory for sockets and by default, # hostapd_cli will use it when trying to connect with hostapd. ctrl_interface=/data/misc/wifi/hostapd # Access control for the control interface can be configured by setting the # directory to allow only members of a group to use sockets. This way, it is # possible to run hostapd as root (since it needs to change network # configuration and open raw sockets) and still allow GUI/CLI components to be # run as non-root users. However, since the control interface can be used to # change the network configuration, this access needs to be protected in many # cases. By default, hostapd is configured to use gid 0 (root). If you # want to allow non-root users to use the contron interface, add a new group # and change this value to match with that group. Add users that should have # control interface access to this group. # # This variable can be a group name or gid. #ctrl_interface_group=wheel #ctrl_interface_group=0 ##### IEEE 802.11 related configuration ####################################### # SSID to be used in IEEE 802.11 management frames ssid=QualcommSoftAP # Country code (ISO/IEC 3166-1). Used to set regulatory domain. # Set as needed to indicate country in which device is operating. # This can limit available channels and transmit power. #country_code=US # Enable IEEE 802.11d. This advertises the country_code and the set of allowed # channels and transmit power levels based on the regulatory limits. The # country_code setting must be configured with the correct country for # IEEE 802.11d functions. # (default: 0 = disabled) #ieee80211d=1 # Operation mode (a = IEEE 802.11a, b = IEEE 802.11b, g = IEEE 802.11g, # n = IEEE 802.11n, g_only = IEEE 802.11g_only, n_only = IEEE 802.11n_only, # Default: IEEE 802.11n hw_mode=g # Channel number (IEEE 802.11) # (default: 0, i.e., not set) # Please note that some drivers (e.g., madwifi) do not use this value from # hostapd and the channel will need to be configuration separately with # iwconfig. channel=6 # Beacon interval in kus (1.024 ms) (default: 100; range 15..65535) beacon_int=100 # DTIM (delivery trafic information message) period (range 1..255): # number of beacons between DTIMs (1 = every beacon includes DTIM element) # (default: 2) dtim_period=2 # Maximum number of stations allowed in station table. New stations will be # rejected after the station table is full. IEEE 802.11 has a limit of 2007 # different association IDs, so this number should not be larger than that. # (default: 2007) max_num_sta=255 # RTS/CTS threshold; 2347 = disabled (default); range 0..2347 # If this field is not included in hostapd.conf, hostapd will not control # RTS threshold and 'iwconfig wlan# rts ' can be used to set it. #rts_threshold=2347 # Fragmentation threshold; 2346 = disabled (default); range 256..2346 # If this field is not included in hostapd.conf, hostapd will not control # fragmentation threshold and 'iwconfig wlan# frag ' can be used to set # it. #fragm_threshold=2346 # Rate configuration # Default is to enable all rates supported by the hardware. This configuration # item allows this list be filtered so that only the listed rates will be left # in the list. If the list is empty, all rates are used. This list can have # entries that are not in the list of rates the hardware supports (such entries # are ignored). The entries in this list are in 100 kbps, i.e., 11 Mbps = 110. # If this item is present, at least one rate have to be matching with the rates # hardware supports. # default: use the most common supported rate setting for the selected # hw_mode (i.e., this line can be removed from configuration file in most # cases) #supported_rates=10 20 55 110 60 90 120 180 240 360 480 540 # Basic rate set configuration # List of rates (in 100 kbps) that are included in the basic rate set. # If this item is not included, usually reasonable default set is used. # This basic rates set is currently used for g-only profile #basic_rates=60 # Short Preamble # This parameter can be used to enable optional use of short preamble for # frames sent at 2 Mbps, 5.5 Mbps, and 11 Mbps to improve network performance. # This applies only to IEEE 802.11b-compatible networks and this should only be # enabled if the local hardware supports use of short preamble. If any of the # associated STAs do not support short preamble, use of short preamble will be # disabled (and enabled when such STAs disassociate) dynamically. # 0 = do not allow use of short preamble (default) # 1 = allow use of short preamble #preamble=1 # Station MAC address -based authentication # Please note that this kind of access control requires a driver that uses # hostapd to take care of management frame processing and as such, this can be # used with driver=hostap or driver=nl80211, but not with driver=madwifi. # 0 = accept unless in deny list # 1 = deny unless in accept list # 2 = use external RADIUS server (accept/deny lists are searched first) macaddr_acl=0 # Accept/deny lists are read from separate files (containing list of # MAC addresses, one per line). Use absolute path name to make sure that the # files can be read on SIGHUP configuration reloads. accept_mac_file=/data/misc/wifi/hostapd.accept deny_mac_file=/data/misc/wifi/hostapd.deny # IEEE 802.11 specifies two authentication algorithms. hostapd can be # configured to allow both of these or only one. Open system authentication # should be used with IEEE 802.1X. # Bit fields of allowed authentication algorithms: # bit 0 = Open System Authentication # bit 1 = Shared Key Authentication (requires WEP) auth_algs=3 # Send empty SSID in beacons and ignore probe request frames that do not # specify full SSID, i.e., require stations to know SSID. # default: disabled (0) # 1 = send empty (length=0) SSID in beacon and ignore probe request for # broadcast SSID # 2 = clear SSID (ASCII 0), but keep the original length (this may be required # with some clients that do not support empty SSID) and ignore probe # requests for broadcast SSID ignore_broadcast_ssid=0 # TX queue parameters (EDCF / bursting) # default for all these fields: not set, use hardware defaults # tx_queue__ # queues: data0, data1, data2, data3, after_beacon, beacon # (data0 is the highest priority queue) # parameters: # aifs: AIFS (default 2) # cwmin: cwMin (1, 3, 7, 15, 31, 63, 127, 255, 511, 1023) # cwmax: cwMax (1, 3, 7, 15, 31, 63, 127, 255, 511, 1023); cwMax >= cwMin # burst: maximum length (in milliseconds with precision of up to 0.1 ms) for # bursting # # Default WMM parameters (IEEE 802.11 draft; 11-03-0504-03-000e): # These parameters are used by the access point when transmitting frames # to the clients. # # Low priority / AC_BK = background #tx_queue_data3_aifs=7 #tx_queue_data3_cwmin=15 #tx_queue_data3_cwmax=1023 #tx_queue_data3_burst=0 # Note: for IEEE 802.11b mode: cWmin=31 cWmax=1023 burst=0 # # Normal priority / AC_BE = best effort #tx_queue_data2_aifs=3 #tx_queue_data2_cwmin=15 #tx_queue_data2_cwmax=63 #tx_queue_data2_burst=0 # Note: for IEEE 802.11b mode: cWmin=31 cWmax=127 burst=0 # # High priority / AC_VI = video #tx_queue_data1_aifs=1 #tx_queue_data1_cwmin=7 #tx_queue_data1_cwmax=15 #tx_queue_data1_burst=3.0 # Note: for IEEE 802.11b mode: cWmin=15 cWmax=31 burst=6.0 # # Highest priority / AC_VO = voice #tx_queue_data0_aifs=1 #tx_queue_data0_cwmin=3 #tx_queue_data0_cwmax=7 #tx_queue_data0_burst=1.5 # Note: for IEEE 802.11b mode: cWmin=7 cWmax=15 burst=3.3 # # Special queues; normally not user configurable # #tx_queue_after_beacon_aifs=2 #tx_queue_after_beacon_cwmin=15 #tx_queue_after_beacon_cwmax=1023 #tx_queue_after_beacon_burst=0 # #tx_queue_beacon_aifs=2 #tx_queue_beacon_cwmin=3 #tx_queue_beacon_cwmax=7 #tx_queue_beacon_burst=1.5 # 802.1D Tag (= UP) to AC mappings # WMM specifies following mapping of data frames to different ACs. This mapping # can be configured using Linux QoS/tc and sch_pktpri.o module. # 802.1D Tag 802.1D Designation Access Category WMM Designation # 1 BK AC_BK Background # 2 - AC_BK Background # 0 BE AC_BE Best Effort # 3 EE AC_BE Best Effort # 4 CL AC_VI Video # 5 VI AC_VI Video # 6 VO AC_VO Voice # 7 NC AC_VO Voice # Data frames with no priority information: AC_BE # Management frames: AC_VO # PS-Poll frames: AC_BE # Default WMM parameters (IEEE 802.11 draft; 11-03-0504-03-000e): # for 802.11a or 802.11g networks # These parameters are sent to WMM clients when they associate. # The parameters will be used by WMM clients for frames transmitted to the # access point. # # note - txop_limit is in units of 32microseconds # note - acm is admission control mandatory flag. 0 = admission control not # required, 1 = mandatory # note - here cwMin and cmMax are in exponent form. the actual cw value used # will be (2^n)-1 where n is the value given here # wmm_enabled=1 # # Low priority / AC_BK = background wmm_ac_bk_cwmin=4 wmm_ac_bk_cwmax=10 wmm_ac_bk_aifs=7 wmm_ac_bk_txop_limit=0 wmm_ac_bk_acm=0 # Note: for IEEE 802.11b mode: cWmin=5 cWmax=10 # # Normal priority / AC_BE = best effort wmm_ac_be_aifs=3 wmm_ac_be_cwmin=4 wmm_ac_be_cwmax=10 wmm_ac_be_txop_limit=0 wmm_ac_be_acm=0 # Note: for IEEE 802.11b mode: cWmin=5 cWmax=7 # # High priority / AC_VI = video wmm_ac_vi_aifs=2 wmm_ac_vi_cwmin=3 wmm_ac_vi_cwmax=4 wmm_ac_vi_txop_limit=94 wmm_ac_vi_acm=0 # Note: for IEEE 802.11b mode: cWmin=4 cWmax=5 txop_limit=188 # # Highest priority / AC_VO = voice wmm_ac_vo_aifs=2 wmm_ac_vo_cwmin=2 wmm_ac_vo_cwmax=3 wmm_ac_vo_txop_limit=47 wmm_ac_vo_acm=0 # Note: for IEEE 802.11b mode: cWmin=3 cWmax=4 burst=102 # Static WEP key configuration # # The key number to use when transmitting. # It must be between 0 and 3, and the corresponding key must be set. # default: not set #wep_default_key=0 # The WEP keys to use. # A key may be a quoted string or unquoted hexadecimal digits. # The key length should be 5, 13, or 16 characters, or 10, 26, or 32 # digits, depending on whether 40-bit (64-bit), 104-bit (128-bit), or # 128-bit (152-bit) WEP is used. # Only the default key must be supplied; the others are optional. # default: not set #wep_key0=1234567890 #wep_key1=1234567890 #wep_key2=1234567890 #wep_key3=1234567890 # Station inactivity limit # # If a station does not send anything in ap_max_inactivity seconds, an # empty data frame is sent to it in order to verify whether it is # still in range. If this frame is not ACKed, the station will be # disassociated and then deauthenticated. This feature is used to # clear station table of old entries when the STAs move out of the # range. # # The station can associate again with the AP if it is still in range; # this inactivity poll is just used as a nicer way of verifying # inactivity; i.e., client will not report broken connection because # disassociation frame is not sent immediately without first polling # the STA with a data frame. # default: 300 (i.e., 5 minutes) #ap_max_inactivity=300 # Enable/disable internal bridge for packets between associated stations. # # When IEEE 802.11 is used in managed mode, packets are usually send through # the AP even if they are from a wireless station to another wireless station. # This functionality requires that the AP has a bridge functionality that sends # frames back to the same interface if their destination is another associated # station. In addition, broadcast/multicast frames from wireless stations will # be sent both to the host system net stack (e.g., to eventually wired network) # and back to the wireless interface. # # The internal bridge is implemented within the wireless kernel module and it # bypasses kernel filtering (netfilter/iptables/ebtables). If direct # communication between the stations needs to be prevented, the internal # bridge can be disabled by setting bridge_packets=0. # # Note: If this variable is not included in hostapd.conf, hostapd does not # change the configuration and iwpriv can be used to set the value with # 'iwpriv wlan# param 10 0' command. If the variable is in hostapd.conf, # hostapd will override possible iwpriv configuration whenever configuration # file is reloaded. # # default: do not control from hostapd (80211.o defaults to 1=enabled) #bridge_packets=1 # Maximum allowed Listen Interval (how many Beacon periods STAs are allowed to # remain asleep). Default: 65535 (no limit apart from field size) #max_listen_interval=100 # Client isolation can be used to prevent low-level bridging of frames between # associated stations in the BSS. By default, this bridging is allowed. #ap_isolate=1 ##### IEEE 802.11n related configuration ###################################### # ieee80211n: Whether IEEE 802.11n (HT) is enabled # 0 = disabled (default) # 1 = enabled # Note: You will also need to enable WMM for full HT functionality. ieee80211n=1 #require_ht=1 # ht_capab: HT capabilities (list of flags) # LDPC coding capability: [LDPC] = supported # Supported channel width set: [HT40-] = both 20 MHz and 40 MHz with secondary # channel below the primary channel; [HT40+] = both 20 MHz and 40 MHz # with secondary channel below the primary channel # (20 MHz only if neither is set) # Note: There are limits on which channels can be used with HT40- and # HT40+. Following table shows the channels that may be available for # HT40- and HT40+ use per IEEE 802.11n Annex J: # freq HT40- HT40+ # 2.4 GHz 5-13 1-7 (1-9 in Europe/Japan) # 5 GHz 40,48,56,64 36,44,52,60 # (depending on the location, not all of these channels may be available # for use) # Spatial Multiplexing (SM) Power Save: [SMPS-STATIC] or [SMPS-DYNAMIC] # (SMPS disabled if neither is set) # HT-greenfield: [GF] (disabled if not set) # Short GI for 20 MHz: [SHORT-GI-20] (disabled if not set) # Short GI for 40 MHz: [SHORT-GI-40] (disabled if not set) # Tx STBC: [TX-STBC] (disabled if not set) # Rx STBC: [RX-STBC1] (one spatial stream), [RX-STBC12] (one or two spatial # streams), or [RX-STBC123] (one, two, or three spatial streams); Rx STBC # disabled if none of these set # HT-delayed Block Ack: [DELAYED-BA] (disabled if not set) # Maximum A-MSDU length: [MAX-AMSDU-7935] for 7935 octets (3839 octets if not # set) # DSSS/CCK Mode in 40 MHz: [DSSS_CCK-40] = allowed (not allowed if not set) # PSMP support: [PSMP] (disabled if not set) # L-SIG TXOP protection support: [LSIG-TXOP-PROT] (disabled if not set) # QcHostapd: # LOWER byte for associated stations # UPPER byte for overlapping stations # each byte will have the following info # bit15 bit14 bit13 bit12 bit11 bit10 bit9 bit8 # OBSS RIFS LSIG_TXOP NON_GF HT20 FROM_11G FROM_11B FROM_11A # bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 # OBSS RIFS LSIG_TXOP NON_GF HT_20 FROM_11G FROM_11B FROM_11A #ht_capab=[HT40-] [SHORT-GI-20] [SHORT-GI-40] ht_capab=[SHORT-GI-20] [GF] [DSSS_CCK-40] [LSIG-TXOP-PROT] #ht_capab=[LDPC] [HT40-] [HT40+] [SMPS-STATIC] [SMPS-DYNAMIC] [GF] [SHORT-GI-20] [SHORT-GI-40] [TX-STBC] [RX-STBC1] [RX-STBC12] [RX-STBC123] [DELAYED-BA] [MAX-AMSDU-7935] [DSSS_CCK-40] [PSMP] [LSIG-TXOP-PROT] ##### IEEE 802.1X-2004 related configuration ################################## # Require IEEE 802.1X authorization #ieee8021x=1 # IEEE 802.1X/EAPOL version # hostapd is implemented based on IEEE Std 802.1X-2004 which defines EAPOL # version 2. However, there are many client implementations that do not handle # the new version number correctly (they seem to drop the frames completely). # In order to make hostapd interoperate with these clients, the version number # can be set to the older version (1) with this configuration value. #eapol_version=2 # Optional displayable message sent with EAP Request-Identity. The first \0 # in this string will be converted to ASCII-0 (nul). This can be used to # separate network info (comma separated list of attribute=value pairs); see, # e.g., RFC 4284. #eap_message=hello #eap_message=hello\0networkid=netw,nasid=foo,portid=0,NAIRealms=example.com # WEP rekeying (disabled if key lengths are not set or are set to 0) # Key lengths for default/broadcast and individual/unicast keys: # 5 = 40-bit WEP (also known as 64-bit WEP with 40 secret bits) # 13 = 104-bit WEP (also known as 128-bit WEP with 104 secret bits) #wep_key_len_broadcast=5 #wep_key_len_unicast=5 # Rekeying period in seconds. 0 = do not rekey (i.e., set keys only once) #wep_rekey_period=300 # EAPOL-Key index workaround (set bit7) for WinXP Supplicant (needed only if # only broadcast keys are used) eapol_key_index_workaround=0 # EAP reauthentication period in seconds (default: 3600 seconds; 0 = disable # reauthentication). #eap_reauth_period=3600 # Use PAE group address (01:80:c2:00:00:03) instead of individual target # address when sending EAPOL frames with driver=wired. This is the most common # mechanism used in wired authentication, but it also requires that the port # is only used by one station. #use_pae_group_addr=1 ##### Integrated EAP server ################################################### # Optionally, hostapd can be configured to use an integrated EAP server # to process EAP authentication locally without need for an external RADIUS # server. This functionality can be used both as a local authentication server # for IEEE 802.1X/EAPOL and as a RADIUS server for other devices. # Use integrated EAP server instead of external RADIUS authentication # server. This is also needed if hostapd is configured to act as a RADIUS # authentication server. eap_server=1 # Path for EAP server user database #eap_user_file=/etc/hostapd.eap_user # CA certificate (PEM or DER file) for EAP-TLS/PEAP/TTLS #ca_cert=/etc/hostapd.ca.pem # Server certificate (PEM or DER file) for EAP-TLS/PEAP/TTLS #server_cert=/etc/hostapd.server.pem # Private key matching with the server certificate for EAP-TLS/PEAP/TTLS # This may point to the same file as server_cert if both certificate and key # are included in a single file. PKCS#12 (PFX) file (.p12/.pfx) can also be # used by commenting out server_cert and specifying the PFX file as the # private_key. #private_key=/etc/hostapd.server.prv # Passphrase for private key #private_key_passwd=secret passphrase # Enable CRL verification. # Note: hostapd does not yet support CRL downloading based on CDP. Thus, a # valid CRL signed by the CA is required to be included in the ca_cert file. # This can be done by using PEM format for CA certificate and CRL and # concatenating these into one file. Whenever CRL changes, hostapd needs to be # restarted to take the new CRL into use. # 0 = do not verify CRLs (default) # 1 = check the CRL of the user certificate # 2 = check all CRLs in the certificate path #check_crl=1 # dh_file: File path to DH/DSA parameters file (in PEM format) # This is an optional configuration file for setting parameters for an # ephemeral DH key exchange. In most cases, the default RSA authentication does # not use this configuration. However, it is possible setup RSA to use # ephemeral DH key exchange. In addition, ciphers with DSA keys always use # ephemeral DH keys. This can be used to achieve forward secrecy. If the file # is in DSA parameters format, it will be automatically converted into DH # params. This parameter is required if anonymous EAP-FAST is used. # You can generate DH parameters file with OpenSSL, e.g., # "openssl dhparam -out /etc/hostapd.dh.pem 1024" #dh_file=/etc/hostapd.dh.pem # Configuration data for EAP-SIM database/authentication gateway interface. # This is a text string in implementation specific format. The example # implementation in eap_sim_db.c uses this as the UNIX domain socket name for # the HLR/AuC gateway (e.g., hlr_auc_gw). In this case, the path uses "unix:" # prefix. #eap_sim_db=unix:/tmp/hlr_auc_gw.sock # Encryption key for EAP-FAST PAC-Opaque values. This key must be a secret, # random value. It is configured as a 16-octet value in hex format. It can be # generated, e.g., with the following command: # od -tx1 -v -N16 /dev/random | colrm 1 8 | tr -d ' ' #pac_opaque_encr_key=000102030405060708090a0b0c0d0e0f # EAP-FAST authority identity (A-ID) # A-ID indicates the identity of the authority that issues PACs. The A-ID # should be unique across all issuing servers. In theory, this is a variable # length field, but due to some existing implementations required A-ID to be # 16 octets in length, it is strongly recommended to use that length for the # field to provided interoperability with deployed peer implementation. This # field is configured in hex format. #eap_fast_a_id=101112131415161718191a1b1c1d1e1f # EAP-FAST authority identifier information (A-ID-Info) # This is a user-friendly name for the A-ID. For example, the enterprise name # and server name in a human-readable format. This field is encoded as UTF-8. #eap_fast_a_id_info=test server # Enable/disable different EAP-FAST provisioning modes: #0 = provisioning disabled #1 = only anonymous provisioning allowed #2 = only authenticated provisioning allowed #3 = both provisioning modes allowed (default) #eap_fast_prov=3 # EAP-FAST PAC-Key lifetime in seconds (hard limit) #pac_key_lifetime=604800 # EAP-FAST PAC-Key refresh time in seconds (soft limit on remaining hard # limit). The server will generate a new PAC-Key when this number of seconds # (or fewer) of the lifetime remains. #pac_key_refresh_time=86400 # EAP-SIM and EAP-AKA protected success/failure indication using AT_RESULT_IND # (default: 0 = disabled). #eap_sim_aka_result_ind=1 # Trusted Network Connect (TNC) # If enabled, TNC validation will be required before the peer is allowed to # connect. Note: This is only used with EAP-TTLS and EAP-FAST. If any other # EAP method is enabled, the peer will be allowed to connect without TNC. #tnc=1 ##### IEEE 802.11f - Inter-Access Point Protocol (IAPP) ####################### # Interface to be used for IAPP broadcast packets #iapp_interface=eth0 ##### RADIUS client configuration ############################################# # for IEEE 802.1X with external Authentication Server, IEEE 802.11 # authentication with external ACL for MAC addresses, and accounting # The own IP address of the access point (used as NAS-IP-Address) own_ip_addr=127.0.0.1 # Optional NAS-Identifier string for RADIUS messages. When used, this should be # a unique to the NAS within the scope of the RADIUS server. For example, a # fully qualified domain name can be used here. # When using IEEE 802.11r, nas_identifier must be set and must be between 1 and # 48 octets long. #nas_identifier=ap.example.com # RADIUS authentication server #auth_server_addr=127.0.0.1 #auth_server_port=1812 #auth_server_shared_secret=secret # RADIUS accounting server #acct_server_addr=127.0.0.1 #acct_server_port=1813 #acct_server_shared_secret=secret # Secondary RADIUS servers; to be used if primary one does not reply to # RADIUS packets. These are optional and there can be more than one secondary # server listed. #auth_server_addr=127.0.0.2 #auth_server_port=1812 #auth_server_shared_secret=secret2 # #acct_server_addr=127.0.0.2 #acct_server_port=1813 #acct_server_shared_secret=secret2 # Retry interval for trying to return to the primary RADIUS server (in # seconds). RADIUS client code will automatically try to use the next server # when the current server is not replying to requests. If this interval is set, # primary server will be retried after configured amount of time even if the # currently used secondary server is still working. #radius_retry_primary_interval=600 # Interim accounting update interval # If this is set (larger than 0) and acct_server is configured, hostapd will # send interim accounting updates every N seconds. Note: if set, this overrides # possible Acct-Interim-Interval attribute in Access-Accept message. Thus, this # value should not be configured in hostapd.conf, if RADIUS server is used to # control the interim interval. # This value should not be less 600 (10 minutes) and must not be less than # 60 (1 minute). #radius_acct_interim_interval=600 # Dynamic VLAN mode; allow RADIUS authentication server to decide which VLAN # is used for the stations. This information is parsed from following RADIUS # attributes based on RFC 3580 and RFC 2868: Tunnel-Type (value 13 = VLAN), # Tunnel-Medium-Type (value 6 = IEEE 802), Tunnel-Private-Group-ID (value # VLANID as a string). vlan_file option below must be configured if dynamic # VLANs are used. Optionally, the local MAC ACL list (accept_mac_file) can be # used to set static client MAC address to VLAN ID mapping. # 0 = disabled (default) # 1 = option; use default interface if RADIUS server does not include VLAN ID # 2 = required; reject authentication if RADIUS server does not include VLAN ID #dynamic_vlan=0 # VLAN interface list for dynamic VLAN mode is read from a separate text file. # This list is used to map VLAN ID from the RADIUS server to a network # interface. Each station is bound to one interface in the same way as with # multiple BSSIDs or SSIDs. Each line in this text file is defining a new # interface and the line must include VLAN ID and interface name separated by # white space (space or tab). #vlan_file=/etc/hostapd.vlan # Interface where 802.1q tagged packets should appear when a RADIUS server is # used to determine which VLAN a station is on. hostapd creates a bridge for # each VLAN. Then hostapd adds a VLAN interface (associated with the interface # indicated by 'vlan_tagged_interface') and the appropriate wireless interface # to the bridge. #vlan_tagged_interface=eth0 ##### RADIUS authentication server configuration ############################## # hostapd can be used as a RADIUS authentication server for other hosts. This # requires that the integrated EAP server is also enabled and both # authentication services are sharing the same configuration. # File name of the RADIUS clients configuration for the RADIUS server. If this # commented out, RADIUS server is disabled. #radius_server_clients=/etc/hostapd.radius_clients # The UDP port number for the RADIUS authentication server #radius_server_auth_port=1812 # Use IPv6 with RADIUS server (IPv4 will also be supported using IPv6 API) #radius_server_ipv6=1 ##### WPA/IEEE 802.11i configuration ########################################## # Enable WPA. Setting this variable configures the AP to require WPA (either # WPA-PSK or WPA-RADIUS/EAP based on other configuration). For WPA-PSK, either # wpa_psk or wpa_passphrase must be set and wpa_key_mgmt must include WPA-PSK. # For WPA-RADIUS/EAP, ieee8021x must be set (but without dynamic WEP keys), # RADIUS authentication server must be configured, and WPA-EAP must be included # in wpa_key_mgmt. # This field is a bit field that can be used to enable WPA (IEEE 802.11i/D3.0) # and/or WPA2 (full IEEE 802.11i/RSN): # bit0 = WPA # bit1 = IEEE 802.11i/RSN (WPA2) (dot11RSNAEnabled) #wpa=1 # WPA pre-shared keys for WPA-PSK. This can be either entered as a 256-bit # secret in hex format (64 hex digits), wpa_psk, or as an ASCII passphrase # (8..63 characters) that will be converted to PSK. This conversion uses SSID # so the PSK changes when ASCII passphrase is used and the SSID is changed. # wpa_psk (dot11RSNAConfigPSKValue) # wpa_passphrase (dot11RSNAConfigPSKPassPhrase) #wpa_psk=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef #wpa_passphrase=qualcomm # Optionally, WPA PSKs can be read from a separate text file (containing list # of (PSK,MAC address) pairs. This allows more than one PSK to be configured. # Use absolute path name to make sure that the files can be read on SIGHUP # configuration reloads. #wpa_psk_file=/etc/hostapd.wpa_psk # Set of accepted key management algorithms (WPA-PSK, WPA-EAP, or both). The # entries are separated with a space. WPA-PSK-SHA256 and WPA-EAP-SHA256 can be # added to enable SHA256-based stronger algorithms. # (dot11RSNAConfigAuthenticationSuitesTable) #wpa_key_mgmt=WPA-PSK #wpa_key_mgmt=WPA-EAP # Set of accepted cipher suites (encryption algorithms) for pairwise keys # (unicast packets). This is a space separated list of algorithms: # CCMP = AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] # TKIP = Temporal Key Integrity Protocol [IEEE 802.11i/D7.0] # Group cipher suite (encryption algorithm for broadcast and multicast frames) # is automatically selected based on this configuration. If only CCMP is # allowed as the pairwise cipher, group cipher will also be CCMP. Otherwise, # TKIP will be used as the group cipher. # (dot11RSNAConfigPairwiseCiphersTable) # Pairwise cipher for WPA (v1) (default: TKIP) #wpa_pairwise=TKIP CCMP # Pairwise cipher for RSN/WPA2 (default: use wpa_pairwise value) #rsn_pairwise=CCMP # Time interval for rekeying GTK (broadcast/multicast encryption keys) in # seconds. (dot11RSNAConfigGroupRekeyTime) wpa_group_rekey=86400 # Rekey GTK when any STA that possesses the current GTK is leaving the BSS. # (dot11RSNAConfigGroupRekeyStrict) #wpa_strict_rekey=1 # Time interval for rekeying GMK (master key used internally to generate GTKs # (in seconds). #wpa_gmk_rekey=86400 # Maximum lifetime for PTK in seconds. This can be used to enforce rekeying of # PTK to mitigate some attacks against TKIP deficiencies. #wpa_ptk_rekey=600 # Enable IEEE 802.11i/RSN/WPA2 pre-authentication. This is used to speed up # roaming be pre-authenticating IEEE 802.1X/EAP part of the full RSN # authentication and key handshake before actually associating with a new AP. # (dot11RSNAPreauthenticationEnabled) #rsn_preauth=1 # # Space separated list of interfaces from which pre-authentication frames are # accepted (e.g., 'eth0' or 'eth0 wlan0wds0'. This list should include all # interface that are used for connections to other APs. This could include # wired interfaces and WDS links. The normal wireless data interface towards # associated stations (e.g., wlan0) should not be added, since # pre-authentication is only used with APs other than the currently associated # one. #rsn_preauth_interfaces=eth0 # peerkey: Whether PeerKey negotiation for direct links (IEEE 802.11e) is # allowed. This is only used with RSN/WPA2. # 0 = disabled (default) # 1 = enabled #peerkey=1 # ieee80211w: Whether management frame protection (MFP) is enabled # 0 = disabled (default) # 1 = optional # 2 = required #ieee80211w=0 # Association SA Query maximum timeout (in TU = 1.024 ms; for MFP) # (maximum time to wait for a SA Query response) # dot11AssociationSAQueryMaximumTimeout, 1...4294967295 #assoc_sa_query_max_timeout=1000 # Association SA Query retry timeout (in TU = 1.024 ms; for MFP) # (time between two subsequent SA Query requests) # dot11AssociationSAQueryRetryTimeout, 1...4294967295 #assoc_sa_query_retry_timeout=201 # okc: Opportunistic Key Caching (aka Proactive Key Caching) # Allow PMK cache to be shared opportunistically among configured interfaces # and BSSes (i.e., all configurations within a single hostapd process). # 0 = disabled (default) # 1 = enabled #okc=1 ##### IEEE 802.11r configuration ############################################## # Mobility Domain identifier (dot11FTMobilityDomainID, MDID) # MDID is used to indicate a group of APs (within an ESS, i.e., sharing the # same SSID) between which a STA can use Fast BSS Transition. # 2-octet identifier as a hex string. #mobility_domain=a1b2 # PMK-R0 Key Holder identifier (dot11FTR0KeyHolderID) # 1 to 48 octet identifier. # This is configured with nas_identifier (see RADIUS client section above). # Default lifetime of the PMK-RO in minutes; range 1..65535 # (dot11FTR0KeyLifetime) #r0_key_lifetime=10000 # PMK-R1 Key Holder identifier (dot11FTR1KeyHolderID) # 6-octet identifier as a hex string. #r1_key_holder=000102030405 # Reassociation deadline in time units (TUs / 1.024 ms; range 1000..65535) # (dot11FTReassociationDeadline) #reassociation_deadline=1000 # List of R0KHs in the same Mobility Domain # format: <128-bit key as hex string> # This list is used to map R0KH-ID (NAS Identifier) to a destination MAC # address when requesting PMK-R1 key from the R0KH that the STA used during the # Initial Mobility Domain Association. #r0kh=02:01:02:03:04:05 r0kh-1.example.com 000102030405060708090a0b0c0d0e0f #r0kh=02:01:02:03:04:06 r0kh-2.example.com 00112233445566778899aabbccddeeff # And so on.. One line per R0KH. # List of R1KHs in the same Mobility Domain # format: <128-bit key as hex string> # This list is used to map R1KH-ID to a destination MAC address when sending # PMK-R1 key from the R0KH. This is also the list of authorized R1KHs in the MD # that can request PMK-R1 keys. #r1kh=02:01:02:03:04:05 02:11:22:33:44:55 000102030405060708090a0b0c0d0e0f #r1kh=02:01:02:03:04:06 02:11:22:33:44:66 00112233445566778899aabbccddeeff # And so on.. One line per R1KH. # Whether PMK-R1 push is enabled at R0KH # 0 = do not push PMK-R1 to all configured R1KHs (default) # 1 = push PMK-R1 to all configured R1KHs whenever a new PMK-R0 is derived #pmk_r1_push=1 ##### Passive scanning ######################################################## # Scan different channels every N seconds. 0 = disable passive scanning. #passive_scan_interval=60 # Listen N usecs on each channel when doing passive scanning. # This value plus the time needed for changing channels should be less than # 32 milliseconds (i.e. 32000 usec) to avoid interruptions to normal # operations. Time needed for channel changing varies based on the used wlan # hardware. # default: disabled (0) #passive_scan_listen=10000 # Passive scanning mode: # 0 = scan all supported modes (802.11a/b/g/Turbo) (default) # 1 = scan only the mode that is currently used for normal operations #passive_scan_mode=1 # Maximum number of entries kept in AP table (either for passive scanning or # for detecting Overlapping Legacy BSS Condition). The oldest entry will be # removed when adding a new entry that would make the list grow over this # limit. Note! Wi-Fi certification for IEEE 802.11g requires that OLBC is # enabled, so this field should not be set to 0 when using IEEE 802.11g. # default: 255 #ap_table_max_size=255 # Number of seconds of no frames received after which entries may be deleted # from the AP table. Since passive scanning is not usually performed frequently # this should not be set to very small value. In addition, there is no # guarantee that every scan cycle will receive beacon frames from the # neighboring APs. # default: 60 #ap_table_expiration_time=3600 ##### Wi-Fi Protected Setup (WPS) ############################################# # WPS state # 0 = WPS disabled (default) # 1 = WPS enabled, not configured # 2 = WPS enabled, configured #wps_state=2 # AP can be configured into a locked state where new WPS Registrar are not # accepted, but previously authorized Registrars (including the internal one) # can continue to add new Enrollees. ap_setup_locked=1 # Universally Unique IDentifier (UUID; see RFC 4122) of the device # This value is used as the UUID for the internal WPS Registrar. If the AP # is also using UPnP, this value should be set to the device's UPnP UUID. # If not configured, UUID will be generated based on the local MAC address. #uuid=12345678-9abc-def0-1234-56789abcdef0 # Note: If wpa_psk_file is set, WPS is used to generate random, per-device PSKs # that will be appended to the wpa_psk_file. If wpa_psk_file is not set, the # default PSK (wpa_psk/wpa_passphrase) will be delivered to Enrollees. Use of # per-device PSKs is recommended as the more secure option (i.e., make sure to # set wpa_psk_file when using WPS with WPA-PSK). # When an Enrollee requests access to the network with PIN method, the Enrollee # PIN will need to be entered for the Registrar. PIN request notifications are # sent to hostapd ctrl_iface monitor. In addition, they can be written to a # text file that could be used, e.g., to populate the AP administration UI with # pending PIN requests. If the following variable is set, the PIN requests will # be written to the configured file. #wps_pin_requests=/var/run/hostapd_wps_pin_requests # Device Name # User-friendly description of device; up to 32 octets encoded in UTF-8 #device_name=Wireless AP # Manufacturer # The manufacturer of the device (up to 64 ASCII characters) #manufacturer=Qualcomm # Model Name # Model of the device (up to 32 ASCII characters) #model_name=QualcommSoftAP # Model Number # Additional device description (up to 32 ASCII characters) #model_number=123 # Serial Number # Serial number of the device (up to 32 characters) #serial_number=12345 # Primary Device Type # Used format: -- # categ = Category as an integer value # OUI = OUI and type octet as a 4-octet hex-encoded value; 0050F204 for # default WPS OUI # subcateg = OUI-specific Sub Category as an integer value # Examples: # 1-0050F204-1 (Computer / PC) # 1-0050F204-2 (Computer / Server) # 5-0050F204-1 (Storage / NAS) # 6-0050F204-1 (Network Infrastructure / AP) #device_type=6-0050F204-1 # OS Version # 4-octet operating system version number (hex string) #os_version=01020300 # Config Methods # List of the supported configuration methods config_methods=label display push_button keypad # Access point PIN for initial configuration and adding Registrars # If not set, hostapd will not allow external WPS Registrars to control the # access point. #ap_pin=12345670 # Skip building of automatic WPS credential # This can be used to allow the automatically generated Credential attribute to # be replaced with pre-configured Credential(s). #skip_cred_build=1 # Additional Credential attribute(s) # This option can be used to add pre-configured Credential attributes into M8 # message when acting as a Registrar. If skip_cred_build=1, this data will also # be able to override the Credential attribute that would have otherwise been # automatically generated based on network configuration. This configuration # option points to an external file that much contain the WPS Credential # attribute(s) as binary data. #extra_cred=hostapd.cred # Credential processing # 0 = process received credentials internally (default) # 1 = do not process received credentials; just pass them over ctrl_iface to # external program(s) # 2 = process received credentials internally and pass them over ctrl_iface # to external program(s) # Note: With wps_cred_processing=1, skip_cred_build should be set to 1 and # extra_cred be used to provide the Credential data for Enrollees. # # wps_cred_processing=1 will disabled automatic updates of hostapd.conf file # both for Credential processing and for marking AP Setup Locked based on # validation failures of AP PIN. An external program is responsible on updating # the configuration appropriately in this case. #wps_cred_processing=0 # AP Settings Attributes for M7 # By default, hostapd generates the AP Settings Attributes for M7 based on the # current configuration. It is possible to override this by providing a file # with pre-configured attributes. This is similar to extra_cred file format, # but the AP Settings attributes are not encapsulated in a Credential # attribute. #ap_settings=hostapd.ap_settings # WPS UPnP interface # If set, support for external Registrars is enabled. #upnp_iface=br0 # Friendly Name (required for UPnP) # Short description for end use. Should be less than 64 characters. #friendly_name=Qualcomm Access Point # Manufacturer URL (optional for UPnP) #manufacturer_url=http://www.qualcomm.com/ # Model Description (recommended for UPnP) # Long description for end user. Should be less than 128 characters. #model_description=Wireless Access Point # Model URL (optional for UPnP) #model_url=http://www.qualcomm.com/ # Universal Product Code (optional for UPnP) # 12-digit, all-numeric code that identifies the consumer package. #upc=123456789012 ##### Multiple BSSID support ################################################## # # Above configuration is using the default interface (wlan#, or multi-SSID VLAN # interfaces). Other BSSIDs can be added by using separator 'bss' with # default interface name to be allocated for the data packets of the new BSS. # # hostapd will generate BSSID mask based on the BSSIDs that are # configured. hostapd will verify that dev_addr & MASK == dev_addr. If this is # not the case, the MAC address of the radio must be changed before starting # hostapd (ifconfig wlan0 hw ether ). # # BSSIDs are assigned in order to each BSS, unless an explicit BSSID is # specified using the 'bssid' parameter. # If an explicit BSSID is specified, it must be chosen such that it: # - results in a valid MASK that covers it and the dev_addr # - is not the same as the MAC address of the radio # - is not the same as any other explicitly specified BSSID # # Please note that hostapd uses some of the values configured for the first BSS # as the defaults for the following BSSes. However, it is recommended that all # BSSes include explicit configuration of all relevant configuration items. # #bss=wlan0_0 #ssid=test2 # most of the above items can be used here (apart from radio interface specific # items, like channel) #bss=wlan0_1 #bssid=00:13:10:95:fe:0b # ... ================================================ FILE: wifi/hostapd.deny ================================================ # List of MAC addresses that are not allowed to authenticate (IEEE 802.11) # with the AP. ================================================ FILE: wifi/p2p_supplicant_overlay.conf ================================================ disable_scan_offload=1 p2p_search_delay=100 ================================================ FILE: wifi/wpa_supplicant_overlay.conf ================================================ disable_scan_offload=1 p2p_disabled=1