diff --git a/Android.mk b/Android.mk old mode 100644 new mode 100755 diff --git a/audio/octopus/ac100_paths.xml b/audio/octopus/ac100_paths.xml index 3a10538..2a43e43 100755 --- a/audio/octopus/ac100_paths.xml +++ b/audio/octopus/ac100_paths.xml @@ -95,6 +95,7 @@ + @@ -104,7 +105,8 @@ - + + diff --git a/audio/octopus/audio_hw.c b/audio/octopus/audio_hw.c index 51f1160..9da68d4 100755 --- a/audio/octopus/audio_hw.c +++ b/audio/octopus/audio_hw.c @@ -86,7 +86,7 @@ static bool NO_EARPIECE = 1; /* number of frames per long period (low power) */ #define LONG_PERIOD_SIZE (SHORT_PERIOD_SIZE * LONG_PERIOD_MULTIPLIER) /* number of pseudo periods for playback */ -#define PLAYBACK_PERIOD_COUNT 4 +#define PLAYBACK_PERIOD_COUNT 3 /* number of periods for capture */ #define CAPTURE_PERIOD_COUNT 2 /* minimum sleep time in out_write() when write threshold is not reached */ @@ -109,7 +109,6 @@ static bool last_call_path_is_bt = 0; static bool dmic_used = 0; static bool last_communication_is_bt = 0; - /*VOLUME CTL*/ #define MIXER_HP_VOLUME "headphone volume" #define MIXER_SPK_VOLUME "speaker volume" @@ -1736,6 +1735,7 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, WritePcmData((void *)buf, out_frames * frame_size, &adev->PcmManager); memset(buf, 0, out_frames * frame_size); //mute } + ret = pcm_write(out->pcm, (void *)buf, out_frames * frame_size); if(ret!=0) { @@ -2390,6 +2390,7 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer, struct sunxi_stream_in *in = (struct sunxi_stream_in *)stream; struct sunxi_audio_device *adev = in->dev; size_t frames_rq = bytes / audio_stream_frame_size(&stream->common); + int is_first_data = 0; if (adev->mode == AUDIO_MODE_IN_CALL) { //ALOGD("in call mode, in_read, return ;"); @@ -2432,6 +2433,7 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer, pthread_mutex_lock(&in->lock); if (in->standby) { ret = start_input_stream(in); + is_first_data = 1; if (ret == 0) in->standby = 0; } @@ -2450,6 +2452,15 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer, ret = pcm_read(in->pcm, buffer, bytes); } + + /* If connect headset, set the first data to zero. + * There may be a noise pulse. + */ + if (is_first_data && + (adev->in_device & AUDIO_DEVICE_IN_WIRED_HEADSET)) { + memset(buffer, 0, bytes); + } + if (ret > 0) ret = 0; @@ -2962,6 +2973,7 @@ static int adev_close(hw_device_t *device) audio_route_free(adev->ar); free(adev->vol_array); free(device); + return 0; } diff --git a/audio/octopus/audio_policy.conf b/audio/octopus/audio_policy.conf index c1ce9e7..e04323a 100755 --- a/audio/octopus/audio_policy.conf +++ b/audio/octopus/audio_policy.conf @@ -75,7 +75,7 @@ audio_hw_modules { usb_device { sampling_rates dynamic channel_masks AUDIO_CHANNEL_IN_STEREO - formats AUDIO_FORMAT_PCM_16_BIT + formats AUDIO_FORMAT_PCM_24_BIT_PACKED devices AUDIO_DEVICE_IN_USB_DEVICE } } diff --git a/audio/tulip/Android.mk b/audio/tulip/Android.mk index 2d5ef25..851d50b 100755 --- a/audio/tulip/Android.mk +++ b/audio/tulip/Android.mk @@ -17,7 +17,7 @@ LOCAL_PATH := $(call my-dir) # libAwHeadpSurround include $(CLEAR_VARS) LOCAL_MODULE := libAwHeadpSurround -LOCAL_SRC_FILES := libAwHeadpSurround.so +LOCAL_SRC_FILES := audio_3d_surround/libAwHeadpSurround.so LOCAL_MODULE_CLASS := SHARED_LIBRARIES LOCAL_MODULE_TAGS := optional LOCAL_MODULE_SUFFIX := .so @@ -31,7 +31,7 @@ LOCAL_MODULE := audio.primary.$(TARGET_BOARD_PLATFORM) #LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw LOCAL_MODULE_RELATIVE_PATH := hw -LOCAL_SRC_FILES := audio_hw.c audio_iface.c sunxi_volume.c +LOCAL_SRC_FILES := audio_hw.c audio_iface.c sunxi_volume.c audio_3d_surround/audio_3d_surround.c #ifneq ($(SW_BOARD_HAVE_3G), true) #LOCAL_SRC_FILES += audio_ril_stub.c diff --git a/audio/tulip/a64_paths.xml b/audio/tulip/a64_paths.xml index 24c84d5..a826935 100755 --- a/audio/tulip/a64_paths.xml +++ b/audio/tulip/a64_paths.xml @@ -22,8 +22,8 @@ - - + + @@ -56,8 +56,8 @@ - - + + diff --git a/audio/tulip/audio_3d_surround/audio_3d_surround.c b/audio/tulip/audio_3d_surround/audio_3d_surround.c new file mode 100755 index 0000000..b127012 --- /dev/null +++ b/audio/tulip/audio_3d_surround/audio_3d_surround.c @@ -0,0 +1,91 @@ +#define LOG_TAG "audio_3d_surround" + +#include +#include +#include +#include +#include +#include + +#include "audio_3d_surround.h" + +#define SUR_LIB_PATH "libAwHeadpSurround.so" + +#define SPACE_GAIN (0.50) +#define BASS_GAIN (0.33) +#define DEFINTION_GAIN (0.80) + +int surround_init(struct audio_3d_surround *sur, + int samp_rate, int chn, int num_frame) +{ + memset(sur, 0, sizeof(*sur)); + + /* open lib */ + sur->lib = dlopen(SUR_LIB_PATH, RTLD_LAZY); + if (NULL == sur->lib) { + ALOGW("%s,line:%d, can't open surround lib.", __func__, __LINE__); + return -1; + } + + /* get 3d srround function */ + sur->process_init = dlsym(sur->lib, "process_init"); + sur->process_exit = dlsym(sur->lib, "process_exit"); + sur->surround_pro_in_out = dlsym(sur->lib, "surround_pro_in_out"); + sur->set_bass = dlsym(sur->lib, "set_bass"); + sur->set_defintion = dlsym(sur->lib, "set_defintion"); + sur->set_space = dlsym(sur->lib, "set_space"); + + /* init 3d suround parameter */ + sur->sur_handle = sur->process_init(sur->sur_handle, samp_rate, chn, num_frame); + sur->set_bass(sur->sur_handle, BASS_GAIN); + sur->set_defintion(sur->sur_handle, DEFINTION_GAIN); + sur->set_space(sur->sur_handle, SPACE_GAIN); + + return 0; +} + +bool surround_ready(struct audio_3d_surround sur) +{ + if ( (NULL == sur.lib) || (NULL == sur.sur_handle) ) + return false; + return true; +} + +/* + * if out device is headset and android settings + * 3d surround switch opened, use surround. + */ +bool surround_use(int out_device) +{ + int hs_on; + int use; + char value[PROPERTY_VALUE_MAX]; + + /* get the current switch state. Default value is close. */ + property_get("persist.sys.audio_3d_surround", value, "0"); + use = atoi(value); + + hs_on = out_device & (AUDIO_DEVICE_OUT_WIRED_HEADSET | AUDIO_DEVICE_OUT_WIRED_HEADPHONE); + return (hs_on && use); +} + +int surround_process(struct audio_3d_surround sur, short *buf, int frames, int channels) +{ + sur.surround_pro_in_out(sur.sur_handle, buf, buf, frames * channels); + + return 0; +} + +void surround_exit(struct audio_3d_surround *sur) +{ + if (sur->sur_handle != NULL) { + sur->process_exit(sur->sur_handle); + sur->sur_handle = NULL; + } + + if (sur->lib != NULL) { + dlclose(sur->lib); + sur->lib = NULL; + } +} + diff --git a/audio/tulip/audio_3d_surround/audio_3d_surround.h b/audio/tulip/audio_3d_surround/audio_3d_surround.h new file mode 100755 index 0000000..7325043 --- /dev/null +++ b/audio/tulip/audio_3d_surround/audio_3d_surround.h @@ -0,0 +1,30 @@ +#ifndef __AUDIO_3D_SURROUND_H_ +#define __AUDIO_3D_SURROUND_H_ + +/* + * the 3d surround struct + * + */ +struct audio_3d_surround { + void *lib; + + void *sur_handle; + void *(*process_init)(void *handle, int samp_rate, int chn, int num_frame); + void (*surround_pro_in_out)(void *handle, short *buf, short *new_sp, int data_num); + void (*process_exit)(void *handle); + void (*set_space)(void *handle, double space_gain); + void (*set_bass)(void *handle, double sub_gain); + void (*set_defintion)(void *handle, double defintion_gain); +}; + +/* + * interface for user + * + */ +int surround_init(struct audio_3d_surround *sur, int samp_rate, int chn, int num_frame); +bool surround_ready(struct audio_3d_surround sur); +bool surround_use(int out_device); +int surround_process(struct audio_3d_surround sur, short *buf, int frames, int channels); +void surround_exit(struct audio_3d_surround *sur); + +#endif diff --git a/audio/tulip/libAwHeadpSurround.so b/audio/tulip/audio_3d_surround/libAwHeadpSurround.so similarity index 100% rename from audio/tulip/libAwHeadpSurround.so rename to audio/tulip/audio_3d_surround/libAwHeadpSurround.so diff --git a/audio/tulip/audio_hw.c b/audio/tulip/audio_hw.c index c16c44e..068bd11 100755 --- a/audio/tulip/audio_hw.c +++ b/audio/tulip/audio_hw.c @@ -41,11 +41,11 @@ #include "audio_iface.h" #include "volume.h" +#include +#include -#include // for property_get - -#include //add by wjc -#define VVS_USED 1 +#include "audio_3d_surround/audio_3d_surround.h" +#define USE_3D_SURROUND 1 #define F_LOG ALOGV("%s, line: %d", __FUNCTION__, __LINE__); @@ -67,14 +67,15 @@ static bool NO_EARPIECE = 1; #define PORT_HDMI 0 #define PORT_SPDIF 0 #define PORT_MODEM 1 -#define PORT_VIR_CODEC 2 -#define PORT_bt 3 +#define PORT_VIR_CODEC 2 +#define PORT_bt 3 #define SAMPLING_RATE_8K 8000 #define SAMPLING_RATE_11K 11025 #define SAMPLING_RATE_44K 44100 #define SAMPLING_RATE_48K 48000 #define SAMPLING_RATE_22050 22050 + /* constraint imposed by ABE: all period sizes must be multiples of 24 */ #define ABE_BASE_FRAME_COUNT 24 /* number of base blocks in a short period (low latency) */ @@ -84,14 +85,13 @@ static bool NO_EARPIECE = 1; //#define SHORT_PERIOD_SIZE (ABE_BASE_FRAME_COUNT * SHORT_PERIOD_MULTIPLIER) #define SHORT_PERIOD_SIZE 1024 - /* number of short periods in a long period (low power) */ //#define LONG_PERIOD_MULTIPLIER 14 /* 308 ms */ #define LONG_PERIOD_MULTIPLIER 6 /* 240 ms */ /* number of frames per long period (low power) */ #define LONG_PERIOD_SIZE (SHORT_PERIOD_SIZE * LONG_PERIOD_MULTIPLIER) /* number of pseudo periods for playback */ -#define PLAYBACK_PERIOD_COUNT 4 +#define PLAYBACK_PERIOD_COUNT 3 /* number of periods for capture */ #define CAPTURE_PERIOD_COUNT 2 /* minimum sleep time in out_write() when write threshold is not reached */ @@ -115,7 +115,6 @@ static bool dmic_used = 0; static bool spk_dul_used = 0; static bool last_communication_is_bt = 0; - /*VOLUME CTL*/ #define MIXER_HP_VOLUME "headphone volume" #define MIXER_SPK_VOLUME "speaker volume" @@ -137,168 +136,175 @@ static bool last_communication_is_bt = 0; static int spkvolume_init = 0x1b; static int earpiecevolume_init = 0x1e; static int hpvolume_init = 0x3b; + enum tty_modes { - TTY_MODE_OFF, - TTY_MODE_VCO, - TTY_MODE_HCO, - TTY_MODE_FULL + TTY_MODE_OFF, + TTY_MODE_VCO, + TTY_MODE_HCO, + TTY_MODE_FULL }; enum { - OUT_DEVICE_SPEAKER, - OUT_DEVICE_HEADSET, - OUT_DEVICE_HEADPHONES, - OUT_DEVICE_BT_SCO, - OUT_DEVICE_SPEAKER_AND_HEADSET, - OUT_DEVICE_EARPIECE, - OUT_DEVICE_SINGLE_SPEAKER, - OUT_DEVICE_TAB_SIZE, /* number of rows in route_configs[][] */ + OUT_DEVICE_SPEAKER, + OUT_DEVICE_HEADSET, + OUT_DEVICE_HEADPHONES, + OUT_DEVICE_BT_SCO, + OUT_DEVICE_SPEAKER_AND_HEADSET, + OUT_DEVICE_EARPIECE, + OUT_DEVICE_SINGLE_SPEAKER, + OUT_DEVICE_TAB_SIZE, /* number of rows in route_configs[][] */ }; enum { - IN_SOURCE_MAINMIC, - IN_SOURCE_HEADSETMIC, - IN_SOURCE_BTMIC, - IN_SOURCE_TAB_SIZE, /* number of lines in route_configs[][] */ - IN_SOURCE_NONE, + IN_SOURCE_MAINMIC, + IN_SOURCE_HEADSETMIC, + IN_SOURCE_BTMIC, + IN_SOURCE_TAB_SIZE, /* number of lines in route_configs[][] */ + IN_SOURCE_NONE, }; + const char * const normal_route_configs[OUT_DEVICE_TAB_SIZE] = { - media_speaker, /* OUT_DEVICE_SPEAKER */ - media_headset, /* OUT_DEVICE_HEADSET */ - media_headphones, /* OUT_DEVICE_HEADPHONES */ - media_bluetooth_sco, /* OUT_DEVICE_BT_SCO */ - media_speaker_and_headphones, /* OUT_DEVICE_SPEAKER_AND_HEADSET */ - media_earpiece, /* OUT_DEVICE_EARPIECE */ - media_single_speaker, /* OUT_DEVICE_SINGLE_SPEAKER */ + media_speaker, /* OUT_DEVICE_SPEAKER */ + media_headset, /* OUT_DEVICE_HEADSET */ + media_headphones, /* OUT_DEVICE_HEADPHONES */ + media_bluetooth_sco, /* OUT_DEVICE_BT_SCO */ + media_speaker_and_headphones, /* OUT_DEVICE_SPEAKER_AND_HEADSET */ + media_earpiece, /* OUT_DEVICE_EARPIECE */ + media_single_speaker, /* OUT_DEVICE_SINGLE_SPEAKER */ }; + const char * const ringtone_route_configs[OUT_DEVICE_TAB_SIZE] = { - media_speaker, /* OUT_DEVICE_SPEAKER */ - "null", /* OUT_DEVICE_HEADSET */ - "null", /* OUT_DEVICE_HEADPHONES */ - "null", /* OUT_DEVICE_BT_SCO */ - media_speaker_and_headphones, /* OUT_DEVICE_SPEAKER_AND_HEADSET */ - "null", /* OUT_DEVICE_EARPIECE */ - "null", + media_speaker, /* OUT_DEVICE_SPEAKER */ + "null", /* OUT_DEVICE_HEADSET */ + "null", /* OUT_DEVICE_HEADPHONES */ + "null", /* OUT_DEVICE_BT_SCO */ + media_speaker_and_headphones, /* OUT_DEVICE_SPEAKER_AND_HEADSET */ + "null", /* OUT_DEVICE_EARPIECE */ + "null", }; + const char * const phone_keytone_route_configs[2][OUT_DEVICE_TAB_SIZE] = { { - "abb-phone-keytone-speaker", /* OUT_DEVICE_SPEAKER */ - "abb-phone-keytone-headphones", /* OUT_DEVICE_HEADSET */ - "abb-phone-keytone-headphones", /* OUT_DEVICE_HEADPHONES */ - "abb-phone-keytone-bt", /* OUT_DEVICE_BT_SCO */ - "null", /* OUT_DEVICE_SPEAKER_AND_HEADSET */ - "abb-phone-keytone-earpiece", /* OUT_DEVICE_EARPIECE */ - "null" + "abb-phone-keytone-speaker", /* OUT_DEVICE_SPEAKER */ + "abb-phone-keytone-headphones", /* OUT_DEVICE_HEADSET */ + "abb-phone-keytone-headphones", /* OUT_DEVICE_HEADPHONES */ + "abb-phone-keytone-bt", /* OUT_DEVICE_BT_SCO */ + "null", /* OUT_DEVICE_SPEAKER_AND_HEADSET */ + "abb-phone-keytone-earpiece", /* OUT_DEVICE_EARPIECE */ + "null" }, - { - "null", /* OUT_DEVICE_SPEAKER */ - "null", /* OUT_DEVICE_HEADSET */ - "null", /* OUT_DEVICE_HEADPHONES */ - "null", /* OUT_DEVICE_BT_SCO */ - "null", /* OUT_DEVICE_SPEAKER_AND_HEADSET */ - "null", /* OUT_DEVICE_EARPIECE */ - "null" + { + "null", /* OUT_DEVICE_SPEAKER */ + "null", /* OUT_DEVICE_HEADSET */ + "null", /* OUT_DEVICE_HEADPHONES */ + "null", /* OUT_DEVICE_BT_SCO */ + "null", /* OUT_DEVICE_SPEAKER_AND_HEADSET */ + "null", /* OUT_DEVICE_EARPIECE */ + "null" } }; + const char * const phone_route_configs[2][OUT_DEVICE_TAB_SIZE] = { { - /*plan_one*/ - "analog-phone-speaker", /* OUT_DEVICE_SPEAKER */ - "analog-phone-headset", /* OUT_DEVICE_HEADSET */ - "analog-phone-headphone", /* OUT_DEVICE_HEADPHONES */ - "analog-phone-bt", /* OUT_DEVICE_BT_SCO */ - "null", /* OUT_DEVICE_SPEAKER_AND_HEADSET */ - "analog-phone-earpiece", /* OUT_DEVICE_EARPIECE */ - "null" - } - , + /* plan_one */ + "analog-phone-speaker", /* OUT_DEVICE_SPEAKER */ + "analog-phone-headset", /* OUT_DEVICE_HEADSET */ + "analog-phone-headphone", /* OUT_DEVICE_HEADPHONES */ + "analog-phone-bt", /* OUT_DEVICE_BT_SCO */ + "null", /* OUT_DEVICE_SPEAKER_AND_HEADSET */ + "analog-phone-earpiece", /* OUT_DEVICE_EARPIECE */ + "null" + }, { - /*plan_two*/ - "digital-phone-speaker", /* OUT_DEVICE_SPEAKER */ - "digital-phone-headset", /* OUT_DEVICE_HEADSET */ - "digital-phone-headphone", /* OUT_DEVICE_HEADPHONES */ - "digital-phone-bt", /* OUT_DEVICE_BT_SCO */ - "null", /* OUT_DEVICE_SPEAKER_AND_HEADSET */ - "digital-phone-earpiece", /* OUT_DEVICE_EARPIECE */ - "null" + /* plan_two */ + "digital-phone-speaker", /* OUT_DEVICE_SPEAKER */ + "digital-phone-headset", /* OUT_DEVICE_HEADSET */ + "digital-phone-headphone", /* OUT_DEVICE_HEADPHONES */ + "digital-phone-bt", /* OUT_DEVICE_BT_SCO */ + "null", /* OUT_DEVICE_SPEAKER_AND_HEADSET */ + "digital-phone-earpiece", /* OUT_DEVICE_EARPIECE */ + "null" } }; + const char * const cap_normal_route_configs[IN_SOURCE_TAB_SIZE] = { - media_mainmic, /* IN_DEVICE_MAINMIC */ - media_headsetmic, /* IN_DEVICE_HEADSET */ - media_btmic, /* IN_DEVICE_bt */ + media_mainmic, /* IN_DEVICE_MAINMIC */ + media_headsetmic, /* IN_DEVICE_HEADSET */ + media_btmic, /* IN_DEVICE_bt */ }; const char * const dmic_cap_normal_route_configs[IN_SOURCE_TAB_SIZE] = { - media_main_dmic, /* IN_DEVICE_MAINMIC */ - media_headsetmic, /* IN_DEVICE_HEADSET */ - media_btmic, /* IN_DEVICE_bt */ + media_main_dmic, /* IN_DEVICE_MAINMIC */ + media_headsetmic, /* IN_DEVICE_HEADSET */ + media_btmic, /* IN_DEVICE_bt */ }; const char * const cap_phone_normal_route_configs[2][IN_SOURCE_TAB_SIZE] = { { - "capture-abb-phone-mainmic", /* IN_DEVICE_MAINMIC */ - "capture-abb-phone-headsetmic", /* IN_DEVICE_HEADSET */ - "capture-abb-phone-btmic", /* IN_DEVICE_bt */ - } - , + "capture-abb-phone-mainmic", /* IN_DEVICE_MAINMIC */ + "capture-abb-phone-headsetmic", /* IN_DEVICE_HEADSET */ + "capture-abb-phone-btmic", /* IN_DEVICE_bt */ + }, { - "capture-dbb-phone-mainmic", /* IN_DEVICE_MAINMIC */ - "capture-dbb-phone-headsetmic", /* IN_DEVICE_HEADSET */ - "capture-dbb-phone-btmic", /* IN_DEVICE_bt */ + "capture-dbb-phone-mainmic", /* IN_DEVICE_MAINMIC */ + "capture-dbb-phone-headsetmic", /* IN_DEVICE_HEADSET */ + "capture-dbb-phone-btmic", /* IN_DEVICE_bt */ } }; + struct pcm_config pcm_config_mm_out = { - .channels = 2, - .rate = MM_SAMPLING_RATE, - .period_size = SHORT_PERIOD_SIZE, - .period_count = PLAYBACK_PERIOD_COUNT, - .format = PCM_FORMAT_S16_LE, + .channels = 2, + .rate = MM_SAMPLING_RATE, + .period_size = SHORT_PERIOD_SIZE, + .period_count = PLAYBACK_PERIOD_COUNT, + .format = PCM_FORMAT_S16_LE, }; struct pcm_config pcm_config_mm_in = { - .channels = 2, - .rate = MM_SAMPLING_RATE, - .period_size = 1024, - .period_count = CAPTURE_PERIOD_COUNT, - .format = PCM_FORMAT_S16_LE, + .channels = 2, + .rate = MM_SAMPLING_RATE, + .period_size = 1024, + .period_count = CAPTURE_PERIOD_COUNT, + .format = PCM_FORMAT_S16_LE, }; + struct pcm_config pcm_config_vx = { - .channels = 1, - .rate = SAMPLING_RATE_8K, - .period_size = 160, - .period_count = 2, - .format = PCM_FORMAT_S16_LE, + .channels = 1, + .rate = SAMPLING_RATE_8K, + .period_size = 160, + .period_count = 2, + .format = PCM_FORMAT_S16_LE, }; + struct route_setting { - char *ctl_name; - int intval; - char *strval; + char *ctl_name; + int intval; + char *strval; }; struct mixer_volumectls { - struct mixer_ctl *hpvolume; - struct mixer_ctl *spkvolume; - struct mixer_ctl *earpiecevolume; + struct mixer_ctl *hpvolume; + struct mixer_ctl *spkvolume; + struct mixer_ctl *earpiecevolume; }; struct pcm_buf_manager { - pthread_mutex_t lock; /* see note below on mutex acquisition order */ - bool BufExist; - unsigned char *BufStart; - int BufTotalLen; - unsigned char *BufReadPtr; - int DataLen; - unsigned char *BufWritPtr; - int BufValideLen; - int SampleRate; - int Channel; - struct sunxi_audio_device *dev; + pthread_mutex_t lock; /* see note below on mutex acquisition order */ + bool BufExist; + unsigned char *BufStart; + int BufTotalLen; + unsigned char *BufReadPtr; + int DataLen; + unsigned char *BufWritPtr; + int BufValideLen; + int SampleRate; + int Channel; + struct sunxi_audio_device *dev; }; struct sunxi_audio_device { @@ -334,83 +340,54 @@ struct sunxi_audio_device { }; -#if VVS_USED -/* vvs is the struct about 3D audio */ -struct vvs { - bool vvs_used; - void *lib_handle; - void *vvs_handle; - void *(*process_init)(void *handle, int samp_rate, int chn, int NumFrame); - void (*surround_pro_in_out)(void *handle, short* BUFFER, short* NewSp, int DataNum); - void (*process_exit)(void *handle); - - void (*set_space)(void *handle, double space_gain); - void (*set_bass)(void *handle, double sub_gain); - void (*set_defintion)(void *handle, double defintion_gain); -}; - -struct vvs vvs = { - .vvs_used = false, - .lib_handle = NULL, - .vvs_handle = NULL, - .process_init = NULL, - .surround_pro_in_out = NULL, - .process_exit = NULL, - .set_space = NULL, - .set_bass = NULL, - .set_defintion = NULL, - }; - +#if USE_3D_SURROUND +struct audio_3d_surround sur; #endif - struct sunxi_stream_out { - struct audio_stream_out stream; + struct audio_stream_out stream; - pthread_mutex_t lock; /* see note below on mutex acquisition order */ - struct pcm_config config; - struct pcm *pcm; - struct resampler_itfe *resampler; - char *buffer; - int standby; - struct echo_reference_itfe *echo_reference; - struct sunxi_audio_device *dev; - int write_threshold; - uint64_t written; + pthread_mutex_t lock; /* see note below on mutex acquisition order */ + struct pcm_config config; + struct pcm *pcm; + struct resampler_itfe *resampler; + char *buffer; + int standby; + struct echo_reference_itfe *echo_reference; + struct sunxi_audio_device *dev; + int write_threshold; + uint64_t written; }; - - - #define MAX_PREPROCESSORS 3 /* maximum one AGC + one NS + one AEC per input stream */ struct sunxi_stream_in { - struct audio_stream_in stream; + struct audio_stream_in stream; - pthread_mutex_t lock; /* see note below on mutex acquisition order */ - struct pcm_config config; - struct pcm *pcm; - int device; - struct resampler_itfe *resampler; - struct resampler_buffer_provider buf_provider; - int16_t *buffer; - size_t frames_in; - unsigned int requested_rate; - int standby; - int source; - struct echo_reference_itfe *echo_reference; - bool need_echo_reference; - effect_handle_t preprocessors[MAX_PREPROCESSORS]; - int num_preprocessors; - int16_t *proc_buf; - size_t proc_buf_size; - size_t proc_frames_in; - int16_t *ref_buf; - size_t ref_buf_size; - size_t ref_frames_in; - int read_status; + pthread_mutex_t lock; /* see note below on mutex acquisition order */ + struct pcm_config config; + struct pcm *pcm; + int device; + struct resampler_itfe *resampler; + struct resampler_buffer_provider buf_provider; + int16_t *buffer; + size_t frames_in; + unsigned int requested_rate; + int standby; + int source; + struct echo_reference_itfe *echo_reference; + bool need_echo_reference; + effect_handle_t preprocessors[MAX_PREPROCESSORS]; + int num_preprocessors; + int16_t *proc_buf; + size_t proc_buf_size; + size_t proc_frames_in; + int16_t *ref_buf; + size_t ref_buf_size; + size_t ref_frames_in; + int read_status; - struct sunxi_audio_device *dev; + struct sunxi_audio_device *dev; }; /*wifi display buffer manager*/ @@ -418,8 +395,7 @@ static int WritePcmData(void * pInbuf, int inSize, struct pcm_buf_manager *PcmMa { ALOGV("RequestWriteBuf ++: size: %d", inSize); - if (PcmManager->BufValideLen< inSize) - { + if (PcmManager->BufValideLen< inSize) { ALOGE("not enough buffer to write"); return -1; } @@ -427,8 +403,7 @@ static int WritePcmData(void * pInbuf, int inSize, struct pcm_buf_manager *PcmMa pthread_mutex_lock(&PcmManager->lock); if ((PcmManager->BufWritPtr + inSize) - > (PcmManager->BufStart + PcmManager->BufTotalLen)) - { + > (PcmManager->BufStart + PcmManager->BufTotalLen)) { int endSize = PcmManager->BufStart + PcmManager->BufTotalLen - PcmManager->BufWritPtr; memcpy(PcmManager->BufWritPtr, pInbuf, endSize); @@ -436,9 +411,7 @@ static int WritePcmData(void * pInbuf, int inSize, struct pcm_buf_manager *PcmMa PcmManager->BufWritPtr = PcmManager->BufWritPtr + inSize - PcmManager->BufTotalLen; - } - else - { + } else { memcpy(PcmManager->BufWritPtr, pInbuf, inSize); PcmManager->BufWritPtr += inSize; } @@ -447,8 +420,8 @@ static int WritePcmData(void * pInbuf, int inSize, struct pcm_buf_manager *PcmMa PcmManager->DataLen += inSize; ALOGV("after wr: BufTotalLen: %d, DataLen: %d, BufValideLen: %d, BufReadPtr: %p, BufWritPtr: %p", - PcmManager->BufTotalLen, PcmManager->DataLen, PcmManager->BufValideLen, - PcmManager->BufReadPtr, PcmManager->BufWritPtr); + PcmManager->BufTotalLen, PcmManager->DataLen, PcmManager->BufValideLen, + PcmManager->BufReadPtr, PcmManager->BufWritPtr); pthread_mutex_unlock(&PcmManager->lock); ALOGV("RequestWriteBuf --"); @@ -467,29 +440,25 @@ static int ReadPcmData(void *pBuf, int uGetLen, struct pcm_buf_manager *PcmManag max_wait_count *= 2;//twice ALOGV("ReadPcmDataForEnc ++, getLen: %d max_wait_count=%d", uGetLen,max_wait_count); - if (adev->active_output != NULL) - { - while(PcmManager->DataLen < uGetLen) - { - ALOGV("pcm is not enough for audio encoder! uGetLen: %d, uDataLen: %d\n", - uGetLen, PcmManager->DataLen); - usleep(10 * 1000); - timeout++; - if(timeout > max_wait_count) { + if (adev->active_output != NULL) { + while (PcmManager->DataLen < uGetLen) { + ALOGV("pcm is not enough for audio encoder! uGetLen: %d, uDataLen: %d\n", + uGetLen, PcmManager->DataLen); + usleep(10 * 1000); + timeout++; + if (timeout > max_wait_count) { if (PcmManager->DataLen < uGetLen) { underflow = 1; size_read = PcmManager->DataLen; fill_dc_size = uGetLen - PcmManager->DataLen; ALOGV("fill with dc size:%d",uGetLen - PcmManager->DataLen); } - break; - } - } - } - else - { - ALOGV("pcm is not enough for audio encoder! uGetLen: %d, uDataLen: %d\n", - uGetLen, PcmManager->DataLen); + break; + } + } + } else { + ALOGV("pcm is not enough for audio encoder! uGetLen: %d, uDataLen: %d\n", + uGetLen, PcmManager->DataLen); if (PcmManager->DataLen < uGetLen) { underflow = 1; size_read = PcmManager->DataLen; @@ -499,44 +468,40 @@ static int ReadPcmData(void *pBuf, int uGetLen, struct pcm_buf_manager *PcmManag } } - if((PcmManager->BufReadPtr + size_read) - > (PcmManager->BufStart + PcmManager->BufTotalLen)) - { - int len1 = PcmManager->BufStart + if ((PcmManager->BufReadPtr + size_read) + > (PcmManager->BufStart + PcmManager->BufTotalLen)) { + int len1 = PcmManager->BufStart + PcmManager->BufTotalLen - PcmManager->BufReadPtr; - memcpy((void *)pBuf, (void *)PcmManager->BufReadPtr, len1); - memcpy((void *)((char *)pBuf + len1), (void *)PcmManager->BufStart, size_read - len1); - } - else - { - memcpy(pBuf, PcmManager->BufReadPtr, size_read); - } + memcpy((void *)pBuf, (void *)PcmManager->BufReadPtr, len1); + memcpy((void *)((char *)pBuf + len1), (void *)PcmManager->BufStart, size_read - len1); + } else { + memcpy(pBuf, PcmManager->BufReadPtr, size_read); + } - pthread_mutex_lock(&PcmManager->lock); + pthread_mutex_lock(&PcmManager->lock); - PcmManager->BufReadPtr += size_read; + PcmManager->BufReadPtr += size_read; - if(PcmManager->BufReadPtr - >= PcmManager->BufStart + PcmManager->BufTotalLen) - { - PcmManager->BufReadPtr -= PcmManager->BufTotalLen; - } - PcmManager->DataLen -= size_read; - PcmManager->BufValideLen += size_read; + if (PcmManager->BufReadPtr + >= PcmManager->BufStart + PcmManager->BufTotalLen) { + PcmManager->BufReadPtr -= PcmManager->BufTotalLen; + } + PcmManager->DataLen -= size_read; + PcmManager->BufValideLen += size_read; - ALOGV("after rd: BufTotalLen: %d, DataLen: %d, BufValideLen: %d, pBufReadPtr: %p, pBufWritPtr: %p", - PcmManager->BufTotalLen, PcmManager->DataLen, PcmManager->BufValideLen, - PcmManager->BufReadPtr, PcmManager->BufWritPtr); + ALOGV("after rd: BufTotalLen: %d, DataLen: %d, BufValideLen: %d, pBufReadPtr: %p, pBufWritPtr: %p", + PcmManager->BufTotalLen, PcmManager->DataLen, PcmManager->BufValideLen, + PcmManager->BufReadPtr, PcmManager->BufWritPtr); - pthread_mutex_unlock(&PcmManager->lock); - ALOGV("ReadPcmDataForEnc --"); + pthread_mutex_unlock(&PcmManager->lock); + ALOGV("ReadPcmDataForEnc --"); - if (underflow) { - char *ptr = (char*)pBuf; - memset(ptr+size_read, ptr[size_read-1], fill_dc_size); - } + if (underflow) { + char *ptr = (char*)pBuf; + memset(ptr+size_read, ptr[size_read-1], fill_dc_size); + } - return uGetLen; + return uGetLen; } /** @@ -545,7 +510,6 @@ static int ReadPcmData(void *pBuf, int uGetLen, struct pcm_buf_manager *PcmManag */ static void select_device(struct sunxi_audio_device *adev); -//static void select_device(struct sunxi_audio_device *adev); static int adev_set_voice_volume(struct audio_hw_device *dev, float volume); static int do_input_standby(struct sunxi_stream_in *in); static int do_output_standby(struct sunxi_stream_out *out); @@ -553,41 +517,43 @@ static int do_output_standby(struct sunxi_stream_out *out); /* The enable flag when 0 makes the assumption that enums are disabled by * "Off" and integers/booleans by 0 */ static int set_route_by_array(struct mixer *mixer, struct route_setting *route, - int enable) + int enable) { - struct mixer_ctl *ctl; - unsigned int i, j; + struct mixer_ctl *ctl; + unsigned int i, j; - /* Go through the route array and set each value */ - i = 0; - while (route[i].ctl_name) { - ctl = mixer_get_ctl_by_name(mixer, route[i].ctl_name); - if (!ctl) - return -EINVAL; + /* Go through the route array and set each value */ + i = 0; + while (route[i].ctl_name) { + ctl = mixer_get_ctl_by_name(mixer, route[i].ctl_name); + if (!ctl) + return -EINVAL; - if (route[i].strval) { - if (enable) - mixer_ctl_set_enum_by_string(ctl, route[i].strval); - else - mixer_ctl_set_enum_by_string(ctl, "Off"); - } else { - /* This ensures multiple (i.e. stereo) values are set jointly */ - for (j = 0; j < mixer_ctl_get_num_values(ctl); j++) { - if (enable) - mixer_ctl_set_value(ctl, j, route[i].intval); - else - mixer_ctl_set_value(ctl, j, 0); - } - } - i++; - } + if (route[i].strval) { + if (enable) + mixer_ctl_set_enum_by_string(ctl, route[i].strval); + else + mixer_ctl_set_enum_by_string(ctl, "Off"); + } else { + /* This ensures multiple (i.e. stereo) values are set jointly */ + for (j = 0; j < mixer_ctl_get_num_values(ctl); j++) { + if (enable) + mixer_ctl_set_value(ctl, j, route[i].intval); + else + mixer_ctl_set_value(ctl, j, 0); + } + } + i++; + } - return 0; + return 0; } + static int bt_start_call(struct sunxi_audio_device *adev) { ALOGE("Opening modem PCMs"); ALOGV("%s, line: %d,CASE_NAME:%d", __FUNCTION__, __LINE__,CASE_NAME); + if (CASE_NAME == 1){ /* Open modem PCM channels */ if (adev->pcm_modem_dl == NULL) { @@ -628,8 +594,8 @@ static int bt_start_call(struct sunxi_audio_device *adev) pcm_start(adev->pcm_bt_dl); pcm_start(adev->pcm_bt_ul); - } else if(CASE_NAME == 2){ - /* Open bt PCM channels */ + } else if (CASE_NAME == 2) { + /* Open bt PCM channels */ if (adev->pcm_bt_dl == NULL) { adev->pcm_bt_dl = pcm_open(0, PORT_bt, PCM_OUT, &pcm_config_vx); if (!pcm_is_ready(adev->pcm_bt_dl)) { @@ -648,8 +614,8 @@ static int bt_start_call(struct sunxi_audio_device *adev) pcm_start(adev->pcm_bt_dl); pcm_start(adev->pcm_bt_ul); - }else { - ALOGV("%s,PHONE CASE ERR!!!!!!!! line: %d,CASE_NAME:%d", __FUNCTION__, __LINE__,CASE_NAME); + } else { + ALOGV("%s,PHONE CASE ERR!!!!!!!! line: %d,CASE_NAME:%d", __FUNCTION__, __LINE__,CASE_NAME); } return 0; @@ -666,12 +632,14 @@ err_open_bt_ul: err_open_bt_dl: pcm_close(adev->pcm_bt_dl); adev->pcm_bt_dl = NULL; + return -ENOMEM; } + static void end_bt_call(struct sunxi_audio_device *adev) { F_LOG; - if (CASE_NAME == 1){ + if (CASE_NAME == 1) { pcm_stop(adev->pcm_modem_dl); pcm_stop(adev->pcm_modem_ul); pcm_close(adev->pcm_modem_dl); @@ -685,8 +653,8 @@ static void end_bt_call(struct sunxi_audio_device *adev) pcm_close(adev->pcm_bt_ul); adev->pcm_bt_dl = NULL; adev->pcm_bt_ul = NULL; - //return 0; - } else if(CASE_NAME == 2){ + + } else if (CASE_NAME == 2) { pcm_stop(adev->pcm_bt_dl); pcm_stop(adev->pcm_bt_ul); pcm_close(adev->pcm_bt_dl); @@ -694,33 +662,36 @@ static void end_bt_call(struct sunxi_audio_device *adev) adev->pcm_bt_dl = NULL; adev->pcm_bt_ul = NULL; } - ALOGE("Closing modem PCMs"); + + ALOGE("Closing modem PCMs"); } + static int start_call(struct sunxi_audio_device *adev) { ALOGE("Opening modem PCMs"); ALOGV("%s, line: %d,CASE_NAME:%d", __FUNCTION__, __LINE__,CASE_NAME); - if (CASE_NAME == 1){ - return 0; - } else if(CASE_NAME == 2){ - }else { - ALOGV("%s,PHONE CASE ERR!!!!!!!! line: %d,CASE_NAME:%d", __FUNCTION__, __LINE__,CASE_NAME); + if (CASE_NAME == 1) { + return 0; + } else if (CASE_NAME == 2) { + + } else { + ALOGV("%s,PHONE CASE ERR!!!!!!!! line: %d,CASE_NAME:%d", __FUNCTION__, __LINE__,CASE_NAME); } /* Open modem PCM channels */ if (adev->pcm_modem_dl == NULL) { - adev->pcm_modem_dl = pcm_open(0, PORT_MODEM, PCM_OUT, &pcm_config_vx); - if (!pcm_is_ready(adev->pcm_modem_dl)) { - ALOGE("cannot open PCM modem DL stream: %s", pcm_get_error(adev->pcm_modem_dl)); + adev->pcm_modem_dl = pcm_open(0, PORT_MODEM, PCM_OUT, &pcm_config_vx); + if (!pcm_is_ready(adev->pcm_modem_dl)) { + ALOGE("cannot open PCM modem DL stream: %s", pcm_get_error(adev->pcm_modem_dl)); goto err_open_dl; } } if (adev->pcm_modem_ul == NULL) { - adev->pcm_modem_ul = pcm_open(0, PORT_MODEM, PCM_IN, &pcm_config_vx); - if (!pcm_is_ready(adev->pcm_modem_ul)) { - ALOGE("cannot open PCM modem UL stream: %s", pcm_get_error(adev->pcm_modem_ul)); + adev->pcm_modem_ul = pcm_open(0, PORT_MODEM, PCM_IN, &pcm_config_vx); + if (!pcm_is_ready(adev->pcm_modem_ul)) { + ALOGE("cannot open PCM modem UL stream: %s", pcm_get_error(adev->pcm_modem_ul)); goto err_open_ul; } } @@ -742,13 +713,12 @@ err_open_dl: static void end_call(struct sunxi_audio_device *adev) { F_LOG; - if (CASE_NAME == 1){ + if (CASE_NAME == 1) { if (last_call_path_is_bt) { end_bt_call(adev); last_call_path_is_bt = 0; } - //return 0; - } else if(CASE_NAME == 2){ + } else if (CASE_NAME == 2) { if (last_call_path_is_bt) { end_bt_call(adev); last_call_path_is_bt = 0; @@ -761,154 +731,156 @@ static void end_call(struct sunxi_audio_device *adev) adev->pcm_modem_dl = NULL; adev->pcm_modem_ul = NULL; } + mixer_ctl_set_value(adev->mixer_volumectls.spkvolume, 0, spkvolume_init); mixer_ctl_set_value(adev->mixer_volumectls.earpiecevolume, 0, earpiecevolume_init); mixer_ctl_set_value(adev->mixer_volumectls.hpvolume, 0, hpvolume_init); - //clear_phone_route(); + ALOGD("end_call, bluetooth_nrec=%d", adev->bluetooth_nrec); } static void set_incall_device(struct sunxi_audio_device *adev) { - int device_type; + int device_type; F_LOG; - switch(adev->out_device) { - case AUDIO_DEVICE_OUT_EARPIECE: - device_type = RIL_AUDIO_PATH_EARPIECE; - break; - case AUDIO_DEVICE_OUT_SPEAKER: - case AUDIO_DEVICE_OUT_AUX_DIGITAL: - device_type = RIL_AUDIO_PATH_SPK; - break; - case AUDIO_DEVICE_OUT_WIRED_HEADSET: - device_type = RIL_AUDIO_PATH_HEADSET; - break; - case AUDIO_DEVICE_OUT_WIRED_HEADPHONE: - device_type = RIL_AUDIO_PATH_HEADSET; - break; - case AUDIO_DEVICE_OUT_BLUETOOTH_SCO: - case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET: - case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT: - device_type = RIL_AUDIO_PATH_BT; - break; - default: - device_type = RIL_AUDIO_PATH_EARPIECE; - break; - } + switch(adev->out_device) { + case AUDIO_DEVICE_OUT_EARPIECE: + device_type = RIL_AUDIO_PATH_EARPIECE; + break; + case AUDIO_DEVICE_OUT_SPEAKER: + case AUDIO_DEVICE_OUT_AUX_DIGITAL: + device_type = RIL_AUDIO_PATH_SPK; + break; + case AUDIO_DEVICE_OUT_WIRED_HEADSET: + device_type = RIL_AUDIO_PATH_HEADSET; + break; + case AUDIO_DEVICE_OUT_WIRED_HEADPHONE: + device_type = RIL_AUDIO_PATH_HEADSET; + break; + case AUDIO_DEVICE_OUT_BLUETOOTH_SCO: + case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET: + case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT: + device_type = RIL_AUDIO_PATH_BT; + break; + default: + device_type = RIL_AUDIO_PATH_EARPIECE; + break; + } ril_set_call_audio_path(device_type); } static void set_bp_volume(struct sunxi_audio_device *adev, int volume) { - int device_type; + int device_type; F_LOG; - switch(adev->out_device) { - case AUDIO_DEVICE_OUT_EARPIECE: - device_type = RIL_AUDIO_PATH_EARPIECE; - break; - case AUDIO_DEVICE_OUT_SPEAKER: - case AUDIO_DEVICE_OUT_AUX_DIGITAL: - device_type = RIL_AUDIO_PATH_SPK; - break; - case AUDIO_DEVICE_OUT_WIRED_HEADSET: - device_type = RIL_AUDIO_PATH_HEADSET; - break; - case AUDIO_DEVICE_OUT_WIRED_HEADPHONE: - device_type = RIL_AUDIO_PATH_HEADSET; - break; - case AUDIO_DEVICE_OUT_BLUETOOTH_SCO: - case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET: - case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT: - device_type = RIL_AUDIO_PATH_BT; - break; - default: - device_type = RIL_AUDIO_PATH_EARPIECE; - break; - } + switch(adev->out_device) { + case AUDIO_DEVICE_OUT_EARPIECE: + device_type = RIL_AUDIO_PATH_EARPIECE; + break; + case AUDIO_DEVICE_OUT_SPEAKER: + case AUDIO_DEVICE_OUT_AUX_DIGITAL: + device_type = RIL_AUDIO_PATH_SPK; + break; + case AUDIO_DEVICE_OUT_WIRED_HEADSET: + device_type = RIL_AUDIO_PATH_HEADSET; + break; + case AUDIO_DEVICE_OUT_WIRED_HEADPHONE: + device_type = RIL_AUDIO_PATH_HEADSET; + break; + case AUDIO_DEVICE_OUT_BLUETOOTH_SCO: + case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET: + case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT: + device_type = RIL_AUDIO_PATH_BT; + break; + default: + device_type = RIL_AUDIO_PATH_EARPIECE; + break; + } - ril_set_call_volume(device_type, volume); + ril_set_call_volume(device_type, volume); } static void force_all_standby(struct sunxi_audio_device *adev) { - struct sunxi_stream_in *in; - struct sunxi_stream_out *out; + struct sunxi_stream_in *in; + struct sunxi_stream_out *out; - if (adev->active_output) { - out = adev->active_output; - pthread_mutex_lock(&out->lock); - do_output_standby(out); - pthread_mutex_unlock(&out->lock); - } - if (adev->active_input) { - in = adev->active_input; - pthread_mutex_lock(&in->lock); - do_input_standby(in); - pthread_mutex_unlock(&in->lock); - } + if (adev->active_output) { + out = adev->active_output; + pthread_mutex_lock(&out->lock); + do_output_standby(out); + pthread_mutex_unlock(&out->lock); + } + + if (adev->active_input) { + in = adev->active_input; + pthread_mutex_lock(&in->lock); + do_input_standby(in); + pthread_mutex_unlock(&in->lock); + } } static void select_mode(struct sunxi_audio_device *adev) { - if (adev->mode == AUDIO_MODE_IN_CALL || adev->mode == AUDIO_MODE_MODE_FACTORY_TEST) { - //ALOGV("Entering IN_CALL state, in_call=%d, adev->out_device is : %d", adev->in_call, adev->out_device); - if (!adev->in_call) { - force_all_standby(adev); - /* force earpiece route for in call state if speaker is the - only currently selected route. This prevents having to tear - down the modem PCMs to change route from speaker to earpiece - after the ringtone is played, but doesn't cause a route - change if a headset or bt device is already connected. If - speaker is not the only thing active, just remove it from - the route. We'll assume it'll never be used initially during - a call. This works because we're sure that the audio policy - manager will update the output device after the audio mode - change, even if the device selection did not change. */ - if (adev->out_device == AUDIO_DEVICE_OUT_SPEAKER) { - F_LOG; - adev->out_device = AUDIO_DEVICE_OUT_EARPIECE; - adev->in_device = AUDIO_DEVICE_IN_BUILTIN_MIC & ~AUDIO_DEVICE_BIT_IN; - } else{ - F_LOG - adev->out_device &= ~AUDIO_DEVICE_OUT_SPEAKER; - } + if (adev->mode == AUDIO_MODE_IN_CALL || adev->mode == AUDIO_MODE_MODE_FACTORY_TEST) { + //ALOGV("Entering IN_CALL state, in_call=%d, adev->out_device is : %d", adev->in_call, adev->out_device); + if (!adev->in_call) { + force_all_standby(adev); + /* force earpiece route for in call state if speaker is the + only currently selected route. This prevents having to tear + down the modem PCMs to change route from speaker to earpiece + after the ringtone is played, but doesn't cause a route + change if a headset or bt device is already connected. If + speaker is not the only thing active, just remove it from + the route. We'll assume it'll never be used initially during + a call. This works because we're sure that the audio policy + manager will update the output device after the audio mode + change, even if the device selection did not change. */ + if (adev->out_device == AUDIO_DEVICE_OUT_SPEAKER) { + F_LOG; + adev->out_device = AUDIO_DEVICE_OUT_EARPIECE; + adev->in_device = AUDIO_DEVICE_IN_BUILTIN_MIC & ~AUDIO_DEVICE_BIT_IN; + } else { + F_LOG + adev->out_device &= ~AUDIO_DEVICE_OUT_SPEAKER; + } - start_call(adev); - F_LOG; - select_device(adev); - adev_set_voice_volume(&adev->hw_device, adev->voice_volume); - adev->in_call = 1; + start_call(adev); + F_LOG; + select_device(adev); + adev_set_voice_volume(&adev->hw_device, adev->voice_volume); + adev->in_call = 1; + } + } else { + ALOGV("Leaving IN_CALL state, in_call=%d, mode=%d", + adev->in_call, adev->mode); + if (adev->in_call) { + adev->in_call = 0; + end_call(adev); + force_all_standby(adev); + //select_device(adev); + select_device(adev); + } } - } else { - ALOGV("Leaving IN_CALL state, in_call=%d, mode=%d", - adev->in_call, adev->mode); - if (adev->in_call) { - adev->in_call = 0; - end_call(adev); + + if (adev->mode == AUDIO_MODE_IN_COMMUNICATION) { + ALOGV("AUDIO_MODE_IN_COMMUNICATION"); + F_LOG; force_all_standby(adev); - //select_device(adev); select_device(adev); } - } - if (adev->mode == AUDIO_MODE_IN_COMMUNICATION) { - ALOGV("AUDIO_MODE_IN_COMMUNICATION"); - F_LOG; - force_all_standby(adev); - select_device(adev); - } - - if (adev->mode == AUDIO_MODE_FM) { - force_all_standby(adev); - F_LOG; - select_device(adev); - adev_set_voice_volume(&adev->hw_device, adev->voice_volume); - } + if (adev->mode == AUDIO_MODE_FM) { + force_all_standby(adev); + F_LOG; + select_device(adev); + adev_set_voice_volume(&adev->hw_device, adev->voice_volume); + } } @@ -917,9 +889,9 @@ static int i2s_suspend_get() int ret = -1, fd = 0; char i2s_suspend[2] = {0}; fd = open("/sys/module/sunxi_i2s/parameters/i2s_suspend", O_RDONLY); - if(fd > 0){ + if (fd > 0) { ret = read(fd, i2s_suspend, sizeof(i2s_suspend)); - if(ret < 0){ + if (ret < 0) { ALOGV("read state fail!"); } close(fd); @@ -936,9 +908,9 @@ static int i2s_suspend_set() int ret = -1, fd = 0; char state[2] = {0}; fd = open("/sys/module/sunxi_i2s/parameters/i2s_suspend", O_WRONLY); - if(fd > 0){ + if (fd > 0) { ret = write(fd, state, sizeof(state)); - if(ret < 0){ + if (ret < 0) { ALOGV("write state fail!"); } close(fd); @@ -952,16 +924,15 @@ static int sysopen_music() { int ret = -1, fd=0; int switch_to_headset = 0; - char h2w_state[2]={0}; + char h2w_state[2]={0}; fd = open("/sys/class/switch/h2w/state", O_RDONLY); - if (fd > 0){ + if (fd > 0) { ret = read(fd, h2w_state, sizeof(h2w_state)); close(fd); - if ( (atoi(h2w_state) == 2 || atoi(h2w_state) == 1) ) - { - ALOGV("h2w_state:erjicharu"); - switch_to_headset =1; + if ( (atoi(h2w_state) == 2 || atoi(h2w_state) == 1) ) { + ALOGV("h2w_state:erjicharu"); + switch_to_headset =1; } } @@ -970,26 +941,21 @@ static int sysopen_music() static int check_hdmi_status() { - int hdmi_fd; + int hdmi_fd; int switch_to_hdmi = 0; hdmi_fd = open("/sys/class/switch/hdmi/state", O_RDONLY); - if (hdmi_fd) - { + + if (hdmi_fd) { char val; - if (read(hdmi_fd, &val, 1) == 1 && val == '1') - { + if (read(hdmi_fd, &val, 1) == 1 && val == '1') { ALOGD( "init hdmi_plug: IN"); switch_to_hdmi = 1; - } - else - { + } else { ALOGD( "init hdmi_plug: OUT"); switch_to_hdmi = 0; } close(hdmi_fd); - } - else - { + } else { ALOGD("open /sys/class/switch/hdmi/state failed"); switch_to_hdmi = -1; } @@ -1008,73 +974,78 @@ static void select_device(struct sunxi_audio_device *adev) int main_mic_on = 0,sub_mic_on = 0; int bton_temp = 0; - if(!adev->ar) + if (!adev->ar) return; ALOGD(">>>>>> select_device"); audio_route_reset(adev->ar); - audio_route_update_mixer_old_value(adev->ar); - - if(spk_dul_used) + if (spk_dul_used) audio_route_apply_path(adev->ar, "media-speaker-off"); else audio_route_apply_path(adev->ar, "media-single-speaker-off"); - - if (adev->mode == AUDIO_MODE_IN_CALL){ - if(CASE_NAME <= 0){ + + audio_route_update_mixer(adev->ar); + + /* get phone route */ + if (adev->mode == AUDIO_MODE_IN_CALL) { + if(CASE_NAME <= 0) { ALOGV("%s,PHONE CASE ERR!!!!!!!!!!!!!!!!!!!! line: %d,CASE_NAME:%d", __FUNCTION__, __LINE__,CASE_NAME); //return CASE_NAME; } + headset_on = adev->out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET; // hp4p headphone_on = adev->out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE; // hp3p speaker_on = adev->out_device & AUDIO_DEVICE_OUT_SPEAKER; earpiece_on = adev->out_device & AUDIO_DEVICE_OUT_EARPIECE; bt_on = adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO; - //audio_route_reset(adev->ar); ALOGV("****LINE:%d,FUNC:%s, headset_on:%d, headphone_on:%d, speaker_on:%d, earpiece_on:%d, bt_on:%d",__LINE__,__FUNCTION__, headphone_on, headphone_on, speaker_on, earpiece_on, bt_on); + if (last_call_path_is_bt && !bt_on) { end_bt_call(adev); last_call_path_is_bt = 0; } - if ((headset_on || headphone_on) && speaker_on){ + + /* get output device id */ + if ((headset_on || headphone_on) && speaker_on) { output_device_id = OUT_DEVICE_SPEAKER_AND_HEADSET; } else if (earpiece_on) { F_LOG; - if (NO_EARPIECE) - { - F_LOG; - if(spk_dul_used){ - output_device_id = OUT_DEVICE_SPEAKER; - }else{ - output_device_id = OUT_DEVICE_SINGLE_SPEAKER; - } + if (NO_EARPIECE) { + F_LOG; + if (spk_dul_used) { + output_device_id = OUT_DEVICE_SPEAKER; + } else { + output_device_id = OUT_DEVICE_SINGLE_SPEAKER; } - else - {F_LOG; + } else { + F_LOG; output_device_id = OUT_DEVICE_EARPIECE; - } + } } else if (headset_on) { output_device_id = OUT_DEVICE_HEADSET; - } else if (headphone_on){ + } else if (headphone_on) { output_device_id = OUT_DEVICE_HEADPHONES; - }else if(bt_on){ + } else if (bt_on) { bton_temp = 1; //bt_start_call(adev); //last_call_path_is_bt = 1; output_device_id = OUT_DEVICE_BT_SCO; - }else if(speaker_on){ - if(spk_dul_used){ + } else if (speaker_on) { + if (spk_dul_used) { output_device_id = OUT_DEVICE_SPEAKER; - }else{ + } else { output_device_id = OUT_DEVICE_SINGLE_SPEAKER; } } ALOGV("****** output_id is : %d", output_device_id); + phone_route = phone_route_configs[CASE_NAME-1][output_device_id]; set_incall_device(adev); } + + /* get output route */ if (adev->active_output) { ALOGV("active_output, ****LINE:%d,FUNC:%s, adev->out_device:%d",__LINE__,__FUNCTION__, adev->out_device); headset_on = adev->out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET; // hp4p @@ -1082,45 +1053,38 @@ static void select_device(struct sunxi_audio_device *adev) speaker_on = adev->out_device & AUDIO_DEVICE_OUT_SPEAKER; earpiece_on = adev->out_device & AUDIO_DEVICE_OUT_EARPIECE; bt_on = adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO; - //audio_route_reset(adev->ar); ALOGV("****LINE:%d,FUNC:%s, headset_on:%d, headphone_on:%d, speaker_on:%d, earpiece_on:%d, bt_on:%d",__LINE__,__FUNCTION__, headset_on, headphone_on, speaker_on, earpiece_on, bt_on); - if ((headset_on || headphone_on) && speaker_on){ + + /* get output device id */ + if ((headset_on || headphone_on) && speaker_on) { output_device_id = OUT_DEVICE_SPEAKER_AND_HEADSET; } else if (earpiece_on) { - if (NO_EARPIECE){ - if(spk_dul_used){ + if (NO_EARPIECE) { + if (spk_dul_used) { output_device_id = OUT_DEVICE_SPEAKER; - }else{ + } else { output_device_id = OUT_DEVICE_SINGLE_SPEAKER; } - } - else + } else output_device_id = OUT_DEVICE_EARPIECE; - //output_device_id = OUT_DEVICE_EARPIECE; } else if (headset_on) { output_device_id = OUT_DEVICE_HEADSET; - } else if (headphone_on){ + } else if (headphone_on) { output_device_id = OUT_DEVICE_HEADSET; - }else if(bt_on){ + } else if (bt_on) { output_device_id = OUT_DEVICE_BT_SCO; - }else if(speaker_on){ - if(spk_dul_used){ + } else if (speaker_on) { + if (spk_dul_used) { output_device_id = OUT_DEVICE_SPEAKER; - }else{ + } else { output_device_id = OUT_DEVICE_SINGLE_SPEAKER; } } ALOGV("****LINE:%d,FUNC:%s, output_device_id:%d",__LINE__,__FUNCTION__, output_device_id); - switch (adev->mode){ + + switch (adev->mode) { case AUDIO_MODE_NORMAL: ALOGV("NORMAL mode, ****LINE:%d,FUNC:%s, adev->out_device:%d",__LINE__,__FUNCTION__, adev->out_device); - #if 0 - if(sysopen_music()) - output_device_id = OUT_DEVICE_HEADSET; - else - output_device_id = OUT_DEVICE_SPEAKER; - //output_device_id = OUT_DEVICE_HEADSET; - #endif output_route = normal_route_configs[output_device_id]; break; case AUDIO_MODE_RINGTONE: @@ -1146,30 +1110,30 @@ static void select_device(struct sunxi_audio_device *adev) if (!pcm_is_ready(adev->pcm_modem_dl)) { ALOGE("cannot open PCM modem DL stream: %s", pcm_get_error(adev->pcm_modem_dl)); //goto err_open_dl; - } } + } if (adev->pcm_modem_ul == NULL) { adev->pcm_modem_ul = pcm_open(0, 4, PCM_IN, &pcm_config_vx); if (!pcm_is_ready(adev->pcm_modem_ul)) { ALOGE("cannot open PCM modem UL stream: %s", pcm_get_error(adev->pcm_modem_ul)); //goto err_open_ul; - } } + } /* Open bt PCM channels */ if (adev->pcm_bt_dl == NULL) { adev->pcm_bt_dl = pcm_open(0, PORT_bt, PCM_OUT, &pcm_config_vx); if (!pcm_is_ready(adev->pcm_bt_dl)) { ALOGE("cannot open PCM bt DL stream: %s", pcm_get_error(adev->pcm_bt_dl)); //goto err_open_bt_dl; - } } + } if (adev->pcm_bt_ul == NULL) { adev->pcm_bt_ul = pcm_open(0, PORT_bt, PCM_IN, &pcm_config_vx); if (!pcm_is_ready(adev->pcm_bt_ul)) { ALOGE("cannot open PCM bt UL stream: %s", pcm_get_error(adev->pcm_bt_ul)); //goto err_open_bt_ul; - } } + } pcm_start(adev->pcm_modem_dl); pcm_start(adev->pcm_modem_ul); pcm_start(adev->pcm_bt_dl); @@ -1181,33 +1145,37 @@ static void select_device(struct sunxi_audio_device *adev) default: break; } - } + + /* get input route */ if (adev->active_input) { - if(adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO){ + if (adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO) { adev->in_device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; } int bt_on = adev->in_device & AUDIO_DEVICE_IN_ALL_SCO; ALOGV("record,****LINE:%d,FUNC:%s, adev->in_device:%x,AUDIO_DEVICE_IN_ALL_SCO:%x",__LINE__,__FUNCTION__, adev->in_device,AUDIO_DEVICE_IN_ALL_SCO); + if (!bt_on) { if ((adev->mode != AUDIO_MODE_IN_CALL) && (adev->active_input != 0)) { - /* sub mic is used for camcorder or VoIP on speaker phone */ - sub_mic_on = (adev->active_input->source == AUDIO_SOURCE_CAMCORDER) || - ((adev->out_device & AUDIO_DEVICE_OUT_SPEAKER) && - (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION)); - } - if (!sub_mic_on) { - headset_on = adev->in_device & AUDIO_DEVICE_IN_WIRED_HEADSET; - main_mic_on = adev->in_device & AUDIO_DEVICE_IN_BUILTIN_MIC; - } + /* sub mic is used for camcorder or VoIP on speaker phone */ + sub_mic_on = (adev->active_input->source == AUDIO_SOURCE_CAMCORDER) || + ((adev->out_device & AUDIO_DEVICE_OUT_SPEAKER) && + (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION)); + } + if (!sub_mic_on) { + headset_on = adev->in_device & AUDIO_DEVICE_IN_WIRED_HEADSET; + main_mic_on = adev->in_device & AUDIO_DEVICE_IN_BUILTIN_MIC; + } } - if (headset_on){ + + /* get input device id */ + if (headset_on) { input_device_id = IN_SOURCE_HEADSETMIC; } else if (main_mic_on) { input_device_id = IN_SOURCE_MAINMIC; - }else if (bt_on && (adev->mode == AUDIO_MODE_IN_COMMUNICATION || adev->mode == AUDIO_MODE_IN_CALL)) { + } else if (bt_on && (adev->mode == AUDIO_MODE_IN_COMMUNICATION || adev->mode == AUDIO_MODE_IN_CALL)) { input_device_id = IN_SOURCE_BTMIC; - }else{ + } else { input_device_id = IN_SOURCE_MAINMIC; } ALOGV("fm record,****LINE:%d,FUNC:%s,bt_on:%d,headset_on:%d,main_mic_on;%d,adev->in_device:%x,AUDIO_DEVICE_IN_ALL_SCO:%x",__LINE__,__FUNCTION__,bt_on,headset_on,main_mic_on,adev->in_device,AUDIO_DEVICE_IN_ALL_SCO); @@ -1220,13 +1188,13 @@ static void select_device(struct sunxi_audio_device *adev) //fm_record_route(adev->in_device); ALOGV("fm record,****LINE:%d,FUNC:%s",__LINE__,__FUNCTION__); } else if (adev->mode == AUDIO_MODE_NORMAL) { - if(dmic_used) + if (dmic_used) input_route = dmic_cap_normal_route_configs[input_device_id]; else input_route = cap_normal_route_configs[input_device_id]; ALOGV("normal record,****LINE:%d,FUNC:%s,adev->in_device:%d",__LINE__,__FUNCTION__,adev->in_device); } else if (adev->mode == AUDIO_MODE_IN_COMMUNICATION) { - if(dmic_used) + if (dmic_used) input_route = dmic_cap_normal_route_configs[input_device_id]; else input_route = cap_normal_route_configs[input_device_id]; @@ -1234,15 +1202,18 @@ static void select_device(struct sunxi_audio_device *adev) } } + if (phone_route) audio_route_apply_path(adev->ar, phone_route); if (output_route) - audio_route_apply_path(adev->ar, output_route); + audio_route_apply_path(adev->ar, output_route); if (input_route) - audio_route_apply_path(adev->ar, input_route); + audio_route_apply_path(adev->ar, input_route); + audio_route_update_mixer(adev->ar); - if (adev->mode == AUDIO_MODE_IN_CALL ){ - if(bton_temp && last_call_path_is_bt == 0){ + + if (adev->mode == AUDIO_MODE_IN_CALL ) { + if (bton_temp && last_call_path_is_bt == 0) { bt_start_call(adev); last_call_path_is_bt = 1; } @@ -1257,89 +1228,36 @@ static int start_output_stream(struct sunxi_stream_out *out) unsigned int port = PORT_CODEC; unsigned int ret; F_LOG; - if (adev->mode == AUDIO_MODE_IN_CALL || adev->mode == AUDIO_MODE_MODE_FACTORY_TEST || adev->mode == AUDIO_MODE_FM) // 10-16 modify - { + if (adev->mode == AUDIO_MODE_IN_CALL || adev->mode == AUDIO_MODE_MODE_FACTORY_TEST || adev->mode == AUDIO_MODE_FM) { return 0; } - if (adev->raw_flag) - { + if (adev->raw_flag) { return 0; } - #if 0 - int device = adev->out_device; - char prop_value[512]; - ret = property_get("audio.routing", prop_value, ""); - if (ret > 0) - { - F_LOG; - if(atoi(prop_value) == AUDIO_DEVICE_OUT_SPEAKER) - { - F_LOG; - ALOGD("start_output_stream, AUDIO_DEVICE_OUT_SPEAKER"); - device = AUDIO_DEVICE_OUT_SPEAKER; - } - else if(atoi(prop_value) == AUDIO_DEVICE_OUT_AUX_DIGITAL) - { - F_LOG; - ALOGD("start_output_stream AUDIO_DEVICE_OUT_AUX_DIGITAL"); - device = AUDIO_DEVICE_OUT_AUX_DIGITAL; - } - else if(atoi(prop_value) == AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) - { - F_LOG; - ALOGD("start_output_stream AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET"); - device = AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; - } - else - { - F_LOG; - ALOGW("unknown audio.routing : %s", prop_value); - } - } - else - { - F_LOG; - // ALOGW("get audio.routing failed"); - } - adev->out_device = device; - #endif - - #if 0 - if (1 == check_hdmi_status()) - { - int device = adev->out_device; - device = AUDIO_DEVICE_OUT_AUX_DIGITAL; - adev->out_device = device; - } - #endif - adev->active_output = out; - if (adev->mode != AUDIO_MODE_IN_CALL) { - /* FIXME: only works if only one output can be active at a time */ - select_device(adev); - } else { - select_device(adev); - } + select_device(adev); + /* S/PDIF takes priority over HDMI audio. In the case of multiple - * devices, this will cause use of S/PDIF or HDMI only */ + * devices, this will cause use of S/PDIF or HDMI only */ out->config.rate = MM_SAMPLING_RATE; if (adev->out_device & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) { card = CARD_A1X_SPDIF; port = PORT_SPDIF; - } else if(adev->out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL) { + } else if (adev->out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL) { card = CARD_A1X_HDMI; port = PORT_HDMI; out->config.rate = MM_SAMPLING_RATE; - } else if(adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO){ + } else if (adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO) { out->config.rate = SAMPLING_RATE_8K; //out->config.channels = 1; ALOGV("****LINE:%d,FUNC:%s",__LINE__,__FUNCTION__); } + /* default to low power: will be corrected in out_write if necessary before first write to - * tinyalsa. - */ + * tinyalsa. + */ out->write_threshold = PLAYBACK_PERIOD_COUNT * SHORT_PERIOD_SIZE; out->config.start_threshold = SHORT_PERIOD_SIZE * 2; out->config.avail_min = SHORT_PERIOD_SIZE; @@ -1350,351 +1268,344 @@ static int start_output_stream(struct sunxi_stream_out *out) out->config.stop_threshold = 0; ALOGV("start_output_stream: card:%d, port:%d, rate:%d, period_count:%d, period_size:%d", card, port, out->config.rate, out->config.period_count, out->config.period_size); out->pcm = pcm_open(card, port, PCM_OUT | PCM_MONOTONIC, &out->config); - //out->pcm = pcm_open_req(card, port, PCM_OUT | PCM_MMAP | PCM_NOIRQ, &out->config, DEFAULT_OUT_SAMPLING_RATE); - if (!pcm_is_ready(out->pcm)) { - ALOGE("cannot open pcm_out driver: %s", pcm_get_error(out->pcm)); - pcm_close(out->pcm); - adev->active_output = NULL; - return -ENOMEM; - } - if (adev->echo_reference != NULL) - out->echo_reference = adev->echo_reference; + if (!pcm_is_ready(out->pcm)) { + ALOGE("cannot open pcm_out driver: %s", pcm_get_error(out->pcm)); + pcm_close(out->pcm); + adev->active_output = NULL; + return -ENOMEM; + } - if (DEFAULT_OUT_SAMPLING_RATE != out->config.rate) - { + if (adev->echo_reference != NULL) + out->echo_reference = adev->echo_reference; + + if (DEFAULT_OUT_SAMPLING_RATE != out->config.rate) { ret = create_resampler(DEFAULT_OUT_SAMPLING_RATE, - out->config.rate, - 2, - RESAMPLER_QUALITY_DEFAULT, - NULL, - &out->resampler); - if (ret != 0) - { + out->config.rate, + 2, + RESAMPLER_QUALITY_DEFAULT, + NULL, + &out->resampler); + if (ret != 0) { ALOGE("create out resampler failed, %d -> %d", DEFAULT_OUT_SAMPLING_RATE, out->config.rate); return ret; } ALOGV("create out resampler OK, %d -> %d", DEFAULT_OUT_SAMPLING_RATE, out->config.rate); - } - else - { + } else { ALOGV("do not use out resampler"); } - if (out->resampler) - { - out->resampler->reset(out->resampler); + if (out->resampler) { + out->resampler->reset(out->resampler); } - return 0; + return 0; } static int check_input_parameters(uint32_t sample_rate, int format, int channel_count) { - if (format != AUDIO_FORMAT_PCM_16_BIT) - return -EINVAL; + if (format != AUDIO_FORMAT_PCM_16_BIT) + return -EINVAL; - if ((channel_count < 1) || (channel_count > 2)) - return -EINVAL; + if ((channel_count < 1) || (channel_count > 2)) + return -EINVAL; - switch(sample_rate) { - case 8000: - case 11025: - case 16000: - case 22050: - case 24000: - case 32000: - case 44100: - case 48000: - break; - default: - return -EINVAL; - } + switch (sample_rate) { + case 8000: + case 11025: + case 16000: + case 22050: + case 24000: + case 32000: + case 44100: + case 48000: + break; + default: + return -EINVAL; + } - return 0; + return 0; } static size_t get_input_buffer_size(uint32_t sample_rate, int format, int channel_count) { - size_t size; - size_t device_rate; + size_t size; + size_t device_rate; - if (check_input_parameters(sample_rate, format, channel_count) != 0) - return 0; + if (check_input_parameters(sample_rate, format, channel_count) != 0) + return 0; - /* take resampling into account and return the closest majoring - multiple of 16 frames, as audioflinger expects audio buffers to - be a multiple of 16 frames */ - size = (pcm_config_mm_in.period_size * sample_rate) / pcm_config_mm_in.rate; - size = ((size + 15) / 16) * 16; + /* take resampling into account and return the closest majoring + multiple of 16 frames, as audioflinger expects audio buffers to + be a multiple of 16 frames */ + size = (pcm_config_mm_in.period_size * sample_rate) / pcm_config_mm_in.rate; + size = ((size + 15) / 16) * 16; - return size * channel_count * sizeof(short); + return size * channel_count * sizeof(short); } static void add_echo_reference(struct sunxi_stream_out *out, - struct echo_reference_itfe *reference) + struct echo_reference_itfe *reference) { - pthread_mutex_lock(&out->lock); - out->echo_reference = reference; - pthread_mutex_unlock(&out->lock); + pthread_mutex_lock(&out->lock); + out->echo_reference = reference; + pthread_mutex_unlock(&out->lock); } static void remove_echo_reference(struct sunxi_stream_out *out, - struct echo_reference_itfe *reference) + struct echo_reference_itfe *reference) { - pthread_mutex_lock(&out->lock); - if (out->echo_reference == reference) { - /* stop writing to echo reference */ - reference->write(reference, NULL); - out->echo_reference = NULL; - } - pthread_mutex_unlock(&out->lock); + pthread_mutex_lock(&out->lock); + if (out->echo_reference == reference) { + /* stop writing to echo reference */ + reference->write(reference, NULL); + out->echo_reference = NULL; + } + pthread_mutex_unlock(&out->lock); } static void put_echo_reference(struct sunxi_audio_device *adev, - struct echo_reference_itfe *reference) + struct echo_reference_itfe *reference) { - if (adev->echo_reference != NULL && - reference == adev->echo_reference) { - if (adev->active_output != NULL) - remove_echo_reference(adev->active_output, reference); - release_echo_reference(reference); - adev->echo_reference = NULL; - } + if (adev->echo_reference != NULL && + reference == adev->echo_reference) { + if (adev->active_output != NULL) + remove_echo_reference(adev->active_output, reference); + release_echo_reference(reference); + adev->echo_reference = NULL; + } } static struct echo_reference_itfe *get_echo_reference(struct sunxi_audio_device *adev, - audio_format_t format, - uint32_t channel_count, - uint32_t sampling_rate) + audio_format_t format, + uint32_t channel_count, + uint32_t sampling_rate) { - put_echo_reference(adev, adev->echo_reference); - if (adev->active_output != NULL) { - struct audio_stream *stream = &adev->active_output->stream.common; - uint32_t wr_channel_count = popcount(stream->get_channels(stream)); - uint32_t wr_sampling_rate = stream->get_sample_rate(stream); + put_echo_reference(adev, adev->echo_reference); + if (adev->active_output != NULL) { + struct audio_stream *stream = &adev->active_output->stream.common; + uint32_t wr_channel_count = popcount(stream->get_channels(stream)); + uint32_t wr_sampling_rate = stream->get_sample_rate(stream); - int status = create_echo_reference(AUDIO_FORMAT_PCM_16_BIT, - channel_count, - sampling_rate, - AUDIO_FORMAT_PCM_16_BIT, - wr_channel_count, - wr_sampling_rate, - &adev->echo_reference); - if (status == 0) - add_echo_reference(adev->active_output, adev->echo_reference); - } - return adev->echo_reference; + int status = create_echo_reference(AUDIO_FORMAT_PCM_16_BIT, + channel_count, + sampling_rate, + AUDIO_FORMAT_PCM_16_BIT, + wr_channel_count, + wr_sampling_rate, + &adev->echo_reference); + if (status == 0) + add_echo_reference(adev->active_output, adev->echo_reference); + } + return adev->echo_reference; } static int get_playback_delay(struct sunxi_stream_out *out, - size_t frames, - struct echo_reference_buffer *buffer) + size_t frames, + struct echo_reference_buffer *buffer) { - size_t kernel_frames; - int status; + size_t kernel_frames; + int status; - status = pcm_get_htimestamp(out->pcm, &kernel_frames, &buffer->time_stamp); - if (status < 0) { - buffer->time_stamp.tv_sec = 0; - buffer->time_stamp.tv_nsec = 0; - buffer->delay_ns = 0; - ALOGV("get_playback_delay(): pcm_get_htimestamp error," - "setting playbackTimestamp to 0"); - return status; - } + status = pcm_get_htimestamp(out->pcm, &kernel_frames, &buffer->time_stamp); + if (status < 0) { + buffer->time_stamp.tv_sec = 0; + buffer->time_stamp.tv_nsec = 0; + buffer->delay_ns = 0; + ALOGV("get_playback_delay(): pcm_get_htimestamp error," + "setting playbackTimestamp to 0"); + return status; + } - kernel_frames = pcm_get_buffer_size(out->pcm) - kernel_frames; + kernel_frames = pcm_get_buffer_size(out->pcm) - kernel_frames; - /* adjust render time stamp with delay added by current driver buffer. - * Add the duration of current frame as we want the render time of the last - * sample being written. */ - buffer->delay_ns = (long)(((int64_t)(kernel_frames + frames)* 1000000000)/ - MM_SAMPLING_RATE); + /* adjust render time stamp with delay added by current driver buffer. + * Add the duration of current frame as we want the render time of the last + * sample being written. */ + buffer->delay_ns = (long)(((int64_t)(kernel_frames + frames)* 1000000000)/ + MM_SAMPLING_RATE); - return 0; + return 0; } - static int out_get_presentation_position(const struct audio_stream_out *stream, - uint64_t *frames, struct timespec *timestamp) + uint64_t *frames, struct timespec *timestamp) { - struct sunxi_stream_out *out = (struct sunxi_stream_out *)stream; - int ret = -1; + struct sunxi_stream_out *out = (struct sunxi_stream_out *)stream; + int ret = -1; - pthread_mutex_lock(&out->lock); + pthread_mutex_lock(&out->lock); - int i; - // There is a question how to implement this correctly when there is more than one PCM stream. - // We are just interested in the frames pending for playback in the kernel buffer here, - // not the total played since start. The current behavior should be safe because the - // cases where both cards are active are marginal. - //for (i = 0; i < PCM_TOTAL; i++) - if (out->pcm) { - size_t avail; - if (pcm_get_htimestamp(out->pcm, &avail, timestamp) == 0) { - size_t kernel_buffer_size = out->config.period_size * out->config.period_count; - // FIXME This calculation is incorrect if there is buffering after app processor - int64_t signed_frames = out->written - kernel_buffer_size + avail; - // It would be unusual for this value to be negative, but check just in case ... - if (signed_frames >= 0) { - *frames = signed_frames; - ret = 0; - } - //break; - } - } + int i; + // There is a question how to implement this correctly when there is more than one PCM stream. + // We are just interested in the frames pending for playback in the kernel buffer here, + // not the total played since start. The current behavior should be safe because the + // cases where both cards are active are marginal. + //for (i = 0; i < PCM_TOTAL; i++) + if (out->pcm) { + size_t avail; + if (pcm_get_htimestamp(out->pcm, &avail, timestamp) == 0) { + size_t kernel_buffer_size = out->config.period_size * out->config.period_count; + // FIXME This calculation is incorrect if there is buffering after app processor + int64_t signed_frames = out->written - kernel_buffer_size + avail; + // It would be unusual for this value to be negative, but check just in case ... + if (signed_frames >= 0) { + *frames = signed_frames; + ret = 0; + } + } + } - pthread_mutex_unlock(&out->lock); + pthread_mutex_unlock(&out->lock); - return ret; + return ret; } - static uint32_t out_get_sample_rate(const struct audio_stream *stream) { - return DEFAULT_OUT_SAMPLING_RATE; + return DEFAULT_OUT_SAMPLING_RATE; } static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate) { - return 0; + return 0; } static size_t out_get_buffer_size(const struct audio_stream *stream) { - struct sunxi_stream_out *out = (struct sunxi_stream_out *)stream; + struct sunxi_stream_out *out = (struct sunxi_stream_out *)stream; - /* take resampling into account and return the closest majoring - multiple of 16 frames, as audioflinger expects audio buffers to - be a multiple of 16 frames */ - size_t size = (SHORT_PERIOD_SIZE * DEFAULT_OUT_SAMPLING_RATE) / out->config.rate; - size = ((size + 15) / 16) * 16; - return size * audio_stream_frame_size((struct audio_stream *)stream); + /* take resampling into account and return the closest majoring + multiple of 16 frames, as audioflinger expects audio buffers to + be a multiple of 16 frames */ + size_t size = (SHORT_PERIOD_SIZE * DEFAULT_OUT_SAMPLING_RATE) / out->config.rate; + size = ((size + 15) / 16) * 16; + return size * audio_stream_frame_size((struct audio_stream *)stream); } static audio_channel_mask_t out_get_channels(const struct audio_stream *stream) { - return AUDIO_CHANNEL_OUT_STEREO; + return AUDIO_CHANNEL_OUT_STEREO; } static audio_format_t out_get_format(const struct audio_stream *stream) { - return AUDIO_FORMAT_PCM_16_BIT; + return AUDIO_FORMAT_PCM_16_BIT; } static int out_set_format(struct audio_stream *stream, audio_format_t format) { - return 0; + return 0; } /* must be called with hw device and output stream mutexes locked */ static int do_output_standby(struct sunxi_stream_out *out) { - struct sunxi_audio_device *adev = out->dev; + struct sunxi_audio_device *adev = out->dev; + + if (!out->standby) { + pcm_close(out->pcm); + out->pcm = NULL; + adev->active_output = 0; - if (!out->standby) { - pcm_close(out->pcm); - out->pcm = NULL; - adev->active_output = 0; if (out->resampler) { - release_resampler(out->resampler); - out->resampler = 0;//close resample - } - /* stop writing to echo reference */ - if (out->echo_reference != NULL) { - out->echo_reference->write(out->echo_reference, NULL); - out->echo_reference = NULL; - } - out->standby = 1; - } - return 0; + release_resampler(out->resampler); + out->resampler = 0;//close resample + } + + /* stop writing to echo reference */ + if (out->echo_reference != NULL) { + out->echo_reference->write(out->echo_reference, NULL); + out->echo_reference = NULL; + } + + out->standby = 1; + } + return 0; } static int out_standby(struct audio_stream *stream) { - struct sunxi_stream_out *out = (struct sunxi_stream_out *)stream; - int status; + struct sunxi_stream_out *out = (struct sunxi_stream_out *)stream; + int status; ALOGD("out_standby"); - //pthread_mutex_lock(&out->dev->lock); - pthread_mutex_lock(&out->lock); - status = do_output_standby(out); - pthread_mutex_unlock(&out->lock); - //pthread_mutex_unlock(&out->dev->lock); - return status; + pthread_mutex_lock(&out->lock); + status = do_output_standby(out); + pthread_mutex_unlock(&out->lock); + return status; } static int out_dump(const struct audio_stream *stream, int fd) { - return 0; + return 0; } static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) { - struct sunxi_stream_out *out = (struct sunxi_stream_out *)stream; - struct sunxi_audio_device *adev = out->dev; - struct sunxi_stream_in *in; - struct str_parms *parms; - char *str; - char value[32]; - int ret, val = 0; - bool force_input_standby = false; + struct sunxi_stream_out *out = (struct sunxi_stream_out *)stream; + struct sunxi_audio_device *adev = out->dev; + struct sunxi_stream_in *in; + struct str_parms *parms; + char *str; + char value[32]; + int ret, val = 0; + bool force_input_standby = false; - parms = str_parms_create_str(kvpairs); + parms = str_parms_create_str(kvpairs); ALOGV("out_set_parameters: %s", kvpairs); ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value)); if (ret >= 0) { F_LOG; - val = atoi(value); - pthread_mutex_lock(&adev->lock); - pthread_mutex_lock(&out->lock); + val = atoi(value); + pthread_mutex_lock(&adev->lock); + pthread_mutex_lock(&out->lock); ALOGV(">>>>>>>> adev->mode:%d,adev->out_device is: %d, val is : %d", adev->mode,adev->out_device, val); - if ((adev->out_device != val) && (val != 0)) { - if (out == adev->active_output) { - F_LOG; - /* a change in output device may change the microphone selection */ - if (adev->active_input && - adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) { - force_input_standby = true; - } - /* force standby if moving to/from HDMI */ - if (((val & AUDIO_DEVICE_OUT_AUX_DIGITAL) ^ - (adev->out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) || - ((val & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) ^ - (adev->out_device & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET)) || - ((val & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) ^ - (adev->out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET))) - do_output_standby(out); - } - adev->out_device = val; + + if ((adev->out_device != val) && (val != 0)) { + if (out == adev->active_output) { + F_LOG; + /* a change in output device may change the microphone selection */ + if (adev->active_input && + adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) { + force_input_standby = true; + } + /* force standby if moving to/from HDMI */ + if (((val & AUDIO_DEVICE_OUT_AUX_DIGITAL) ^ + (adev->out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) || + ((val & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) ^ + (adev->out_device & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET)) || + ((val & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) ^ + (adev->out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET))) + do_output_standby(out); + } + adev->out_device = val; F_LOG; - select_device(adev); + select_device(adev); if (adev->mode == AUDIO_MODE_IN_CALL || adev->mode == AUDIO_MODE_MODE_FACTORY_TEST || adev->mode == AUDIO_MODE_FM){ adev_set_voice_volume(&adev->hw_device, adev->voice_volume); } - } - pthread_mutex_unlock(&out->lock); - if (force_input_standby) { - in = adev->active_input; - pthread_mutex_lock(&in->lock); - do_input_standby(in); - pthread_mutex_unlock(&in->lock); - } + } + + pthread_mutex_unlock(&out->lock); + if (force_input_standby) { + in = adev->active_input; + pthread_mutex_lock(&in->lock); + do_input_standby(in); + pthread_mutex_unlock(&in->lock); + } pthread_mutex_unlock(&adev->lock); } ret = str_parms_get_str(parms, AUDIO_PARAMETER_RAW_DATA_OUT, value, sizeof(value)); - if (ret >= 0) - { + if (ret >= 0) { bool bval = (atoi(value) == 1) ? true : false; ALOGV("AUDIO_PARAMETER_RAW_DATA_OUT: %d", bval); pthread_mutex_lock(&adev->lock); pthread_mutex_lock(&out->lock); - if (adev->raw_flag != bval) - { + if (adev->raw_flag != bval) { adev->raw_flag = bval; do_output_standby(out); } @@ -1702,55 +1613,54 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) pthread_mutex_unlock(&adev->lock); } - str_parms_destroy(parms); - return ret; + str_parms_destroy(parms); + return ret; } static char * out_get_parameters(const struct audio_stream *stream, const char *keys) { - return strdup(""); + return strdup(""); } static uint32_t out_get_latency(const struct audio_stream_out *stream) { - struct sunxi_stream_out *out = (struct sunxi_stream_out *)stream; + struct sunxi_stream_out *out = (struct sunxi_stream_out *)stream; - return (SHORT_PERIOD_SIZE * PLAYBACK_PERIOD_COUNT * 1000) / out->config.rate; + return (SHORT_PERIOD_SIZE * PLAYBACK_PERIOD_COUNT * 1000) / out->config.rate; } static int out_set_volume(struct audio_stream_out *stream, float left, - float right) + float right) { - return -ENOSYS; + return -ENOSYS; } static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, - size_t bytes) + size_t bytes) { - int ret; - struct sunxi_stream_out *out = (struct sunxi_stream_out *)stream; - struct sunxi_audio_device *adev = out->dev; - size_t frame_size = audio_stream_frame_size(&out->stream.common); - size_t in_frames = bytes / frame_size; - size_t out_frames = RESAMPLER_BUFFER_SIZE / frame_size; - bool force_input_standby = false; - struct sunxi_stream_in *in; - int kernel_frames; - void *buf; - if (adev->mode == AUDIO_MODE_IN_CALL || adev->mode == AUDIO_MODE_MODE_FACTORY_TEST || adev->mode == AUDIO_MODE_FM) //10-16 modify - { + int ret; + struct sunxi_stream_out *out = (struct sunxi_stream_out *)stream; + struct sunxi_audio_device *adev = out->dev; + size_t frame_size = audio_stream_frame_size(&out->stream.common); + size_t in_frames = bytes / frame_size; + size_t out_frames = RESAMPLER_BUFFER_SIZE / frame_size; + bool force_input_standby = false; + struct sunxi_stream_in *in; + int kernel_frames; + void *buf; + + if (adev->mode == AUDIO_MODE_IN_CALL || adev->mode == AUDIO_MODE_MODE_FACTORY_TEST || adev->mode == AUDIO_MODE_FM) { return bytes; - if((CASE_NAME == 2) || adev->out_device==AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) { + if ((CASE_NAME == 2) || adev->out_device==AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) { ALOGD("mode in call, do not out_write"); return bytes; } - } - if (adev->raw_flag) - { + if (adev->raw_flag) { return 0; } + if (last_communication_is_bt && (adev->mode != AUDIO_MODE_IN_COMMUNICATION || adev->mode == AUDIO_MODE_IN_COMMUNICATION && adev->out_device!=AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET)) { pcm_stop(adev->pcm_modem_dl); pcm_stop(adev->pcm_modem_ul); @@ -1767,160 +1677,117 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, adev->pcm_bt_ul = NULL; last_communication_is_bt = false; } - /* acquiring hw device mutex systematically is useful if a low priority thread is waiting - * on the output stream mutex - e.g. executing select_mode() while holding the hw device - * mutex - */ - pthread_mutex_lock(&adev->lock); + + /* acquiring hw device mutex systematically is useful if a low priority thread is waiting + * on the output stream mutex - e.g. executing select_mode() while holding the hw device + * mutex + */ + pthread_mutex_lock(&adev->lock); pthread_mutex_lock(&out->lock); - if (out->standby) { - ret = start_output_stream(out); - if (ret != 0) { - pthread_mutex_unlock(&adev->lock); - goto exit; - } - out->standby = 0; - /* a change in output device may change the microphone selection */ - if (adev->active_input && - adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION){ - force_input_standby = true; - F_LOG; - } - } - pthread_mutex_unlock(&adev->lock); -#if 0 - out->write_threshold = SHORT_PERIOD_SIZE * PLAYBACK_PERIOD_COUNT; - out->config.avail_min = SHORT_PERIOD_SIZE; - pcm_set_avail_min(out->pcm, out->config.avail_min); -#endif + if (out->standby) { + ret = start_output_stream(out); + if (ret != 0) { + pthread_mutex_unlock(&adev->lock); + goto exit; + } + out->standby = 0; + /* a change in output device may change the microphone selection */ + if (adev->active_input && + adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION){ + force_input_standby = true; + F_LOG; + } + } + pthread_mutex_unlock(&adev->lock); + /* only use resampler if required */ + if (out->resampler) { + out->resampler->resample_from_input(out->resampler, + (int16_t *)buffer, + &in_frames, + (int16_t *)out->buffer, + &out_frames); + buf = out->buffer; + } else { + out_frames = in_frames; + buf = (void *)buffer; + } - /* only use resampler if required */ - if (out->resampler) { - out->resampler->resample_from_input(out->resampler, - (int16_t *)buffer, - &in_frames, - (int16_t *)out->buffer, - &out_frames); - buf = out->buffer; - } else { - out_frames = in_frames; - buf = (void *)buffer; - } - if (out->echo_reference != NULL) { - struct echo_reference_buffer b; - b.raw = (void *)buffer; - b.frame_count = in_frames; + if (out->echo_reference != NULL) { + struct echo_reference_buffer b; + b.raw = (void *)buffer; + b.frame_count = in_frames; - get_playback_delay(out, out_frames, &b); - out->echo_reference->write(out->echo_reference, &b); - } - -#if 0 - /* do not allow more than out->write_threshold frames in kernel pcm driver buffer */ - do { - struct timespec time_stamp; - - if (pcm_get_htimestamp(out->pcm, (unsigned int *)&kernel_frames, &time_stamp) < 0) - break; - kernel_frames = pcm_get_buffer_size(out->pcm) - kernel_frames; - - if (kernel_frames > out->write_threshold) { - unsigned long time = (unsigned long) - (((int64_t)(kernel_frames - out->write_threshold) * 1000000) / - MM_SAMPLING_RATE); - if (time < MIN_WRITE_SLEEP_US) - time = MIN_WRITE_SLEEP_US; - usleep(time); - } - } while (kernel_frames > out->write_threshold); -#endif + get_playback_delay(out, out_frames, &b); + out->echo_reference->write(out->echo_reference, &b); + } if (adev->af_capture_flag && adev->PcmManager.BufExist) { WritePcmData((void *)buf, out_frames * frame_size, &adev->PcmManager); memset(buf, 0, out_frames * frame_size); //mute } -#if VVS_USED -{ - char value[PROPERTY_VALUE_MAX]; - - /* If the library fails, nothing is done. */ - if (vvs.lib_handle == NULL) - goto vvs_exit; - - /* Gets the current switch state. Default value is open. */ - property_get("persist.sys.vvs_switch", value, "1"); - vvs.vvs_used = (atoi(value) != 0); - - if (vvs.vvs_used && (adev->out_device &(AUDIO_DEVICE_OUT_WIRED_HEADSET - | AUDIO_DEVICE_OUT_WIRED_HEADPHONE))){ - vvs.surround_pro_in_out(vvs.vvs_handle, (short*)buf, (short*)buf, - out_frames * out->config.channels); - } - //ALOGV("out_write: vvs_used=%d, out_device=%d", vvs.vvs_used, adev->out_device); -} -vvs_exit: +#if USE_3D_SURROUND + if (surround_ready(sur) && surround_use(adev->out_device)) + surround_process(sur, (short*)buf, out_frames, out->config.channels); #endif - ret = pcm_write(out->pcm, (void *)buf, out_frames * frame_size); - if(ret!=0) - { + ret = pcm_write(out->pcm, (void *)buf, out_frames * frame_size); + if (ret!=0) { do_output_standby(out); - }else if (ret == 0) - out->written += bytes / (out->config.channels * sizeof(short) - ); + } else if (ret == 0) + out->written += bytes / (out->config.channels * sizeof(short)); exit: - pthread_mutex_unlock(&out->lock); + pthread_mutex_unlock(&out->lock); - if (ret != 0) { - usleep(bytes * 1000000 / audio_stream_frame_size(&stream->common) / - out_get_sample_rate(&stream->common)); - } + if (ret != 0) { + usleep(bytes * 1000000 / audio_stream_frame_size(&stream->common) / + out_get_sample_rate(&stream->common)); + } - if (force_input_standby) { - pthread_mutex_lock(&adev->lock); - if (adev->active_input) { - in = adev->active_input; - pthread_mutex_lock(&in->lock); - do_input_standby(in); - pthread_mutex_unlock(&in->lock); - } - pthread_mutex_unlock(&adev->lock); - } + if (force_input_standby) { + pthread_mutex_lock(&adev->lock); + if (adev->active_input) { + in = adev->active_input; + pthread_mutex_lock(&in->lock); + do_input_standby(in); + pthread_mutex_unlock(&in->lock); + } + pthread_mutex_unlock(&adev->lock); + } - return bytes; + return bytes; } static int out_get_render_position(const struct audio_stream_out *stream, - uint32_t *dsp_frames) + uint32_t *dsp_frames) { - return -EINVAL; + return -EINVAL; } static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect) { - return 0; + return 0; } static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect) { - return 0; + return 0; } static int out_get_next_write_timestamp(const struct audio_stream_out *stream, - int64_t *timestamp) + int64_t *timestamp) { - return -EINVAL; + return -EINVAL; } /** audio_stream_in implementation **/ static int get_next_buffer(struct resampler_buffer_provider *buffer_provider, - struct resampler_buffer* buffer); + struct resampler_buffer* buffer); static void release_buffer(struct resampler_buffer_provider *buffer_provider, - struct resampler_buffer* buffer); + struct resampler_buffer* buffer); /* must be called with hw device and input stream mutexes locked */ static int start_input_stream(struct sunxi_stream_in *in) @@ -1933,96 +1800,71 @@ static int start_input_stream(struct sunxi_stream_in *in) if (adev->mode == AUDIO_MODE_IN_CALL) { // && adev->bluetooth_voice ALOGD("in call mode , start_input_stream, return"); - //return 0; } - //if (adev->mode != AUDIO_MODE_IN_CALL) { F_LOG; adev->in_device = in->device; select_device(adev); - //} if (in->need_echo_reference && in->echo_reference == NULL) - in->echo_reference = get_echo_reference(adev, - AUDIO_FORMAT_PCM_16_BIT, - in->config.channels, - in->requested_rate); + in->echo_reference = get_echo_reference(adev, + AUDIO_FORMAT_PCM_16_BIT, + in->config.channels, + in->requested_rate); in_ajust_rate = in->requested_rate; ALOGD(">>>>>> in_ajust_rate is : %d", in_ajust_rate); - // out/in stream should be both 44.1K serial - switch(CASE_NAME){ + // out/in stream should be both 44.1K serial + switch (CASE_NAME) { case 0 : case 1 : in_ajust_rate = SAMPLING_RATE_44K; ALOGV("%s, line: %d,adev->mode:%d,adev->out_device:%d", __FUNCTION__, __LINE__,adev->mode,adev->out_device); - //if((adev->mode == AUDIO_MODE_IN_CALL) && (adev->out_device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) ) - if((adev->mode == AUDIO_MODE_IN_CALL) && (adev->out_device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO) ){ + + if ((adev->mode == AUDIO_MODE_IN_CALL) && (adev->out_device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO)) { ALOGV("%s, line: %d,adev->mode:%d,adev->out_device:%d", __FUNCTION__, __LINE__,adev->mode,adev->out_device); in_ajust_rate = SAMPLING_RATE_8K; } - if((adev->mode == AUDIO_MODE_IN_COMMUNICATION) && (adev->out_device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) ){ + if ((adev->mode == AUDIO_MODE_IN_COMMUNICATION) && (adev->out_device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET)) { ALOGV("%s, line: %d,adev->mode:%d,adev->out_device:%d", __FUNCTION__, __LINE__,adev->mode,adev->out_device); in_ajust_rate = SAMPLING_RATE_8K; //in->config.rate = SAMPLING_RATE_8K; } break; case 2 : - if(adev->mode == AUDIO_MODE_IN_CALL) + if (adev->mode == AUDIO_MODE_IN_CALL) in_ajust_rate = in->requested_rate; else in_ajust_rate = SAMPLING_RATE_44K; default : break; - } -#if 0 - #ifdef USERECORD_44100_SAMPLERATE - in_ajust_rate = SAMPLING_RATE_44K; - #else - if (!(in->requested_rate % SAMPLING_RATE_11K)) - { - // OK - in_ajust_rate = in->requested_rate; - } - else - { - in_ajust_rate = SAMPLING_RATE_11K * in->requested_rate / SAMPLING_RATE_8K; - if (in_ajust_rate > SAMPLING_RATE_44K) - { - } - ALOGV("out/in stream should be both 44.1K serial, force capture rate: %d", in_ajust_rate); - } - #endif -#endif ALOGV("rate:%d, period_count:%d, period_size:%d,channels:%d", in->config.rate, in->config.period_count, in->config.period_size,in->config.channels); ALOGV("in_ajust_rate:%d", in_ajust_rate); if (adev->mode == AUDIO_MODE_IN_CALL) - //in->pcm = pcm_open_req(0, PORT_VIR_CODEC, PCM_IN, &in->config, in_ajust_rate); - in->pcm = pcm_open(0, PORT_VIR_CODEC, PCM_IN, &in->config); + in->pcm = pcm_open(0, PORT_VIR_CODEC, PCM_IN, &in->config); else - //in->pcm = pcm_open_req(0, PORT_CODEC, PCM_IN, &in->config, in_ajust_rate); in->pcm = pcm_open(0, PORT_CODEC, PCM_IN, &in->config); - if (!pcm_is_ready(in->pcm)) { - ALOGE("cannot open pcm_in driver: %s", pcm_get_error(in->pcm)); - pcm_close(in->pcm); - adev->active_input = NULL; - return -ENOMEM; - } + if (!pcm_is_ready(in->pcm)) { + ALOGE("cannot open pcm_in driver: %s", pcm_get_error(in->pcm)); + pcm_close(in->pcm); + adev->active_input = NULL; + return -ENOMEM; + } if (in->requested_rate != in->config.rate) { in->buf_provider.get_next_buffer = get_next_buffer; in->buf_provider.release_buffer = release_buffer; ret = create_resampler(in->config.rate, - in->requested_rate, - in->config.channels, - RESAMPLER_QUALITY_DEFAULT, - &in->buf_provider, - &in->resampler); + in->requested_rate, + in->config.channels, + RESAMPLER_QUALITY_DEFAULT, + &in->buf_provider, + &in->resampler); if (ret != 0) { ALOGE("create in resampler failed, %d -> %d", in->config.rate, in->requested_rate); ret = -EINVAL; @@ -2030,415 +1872,412 @@ static int start_input_stream(struct sunxi_stream_in *in) } ALOGV("create in resampler OK, %d -> %d", in->config.rate, in->requested_rate); - } - else - { + } else { ALOGV("do not use in resampler"); } - /* if no supported sample rate is available, use the resampler */ - if (in->resampler) { - in->resampler->reset(in->resampler); - in->frames_in = 0; - } - return 0; + /* if no supported sample rate is available, use the resampler */ + if (in->resampler) { + in->resampler->reset(in->resampler); + in->frames_in = 0; + } + return 0; err: - if (in->resampler) { - release_resampler(in->resampler); - } + if (in->resampler) { + release_resampler(in->resampler); + } - return -1; + return -1; } static uint32_t in_get_sample_rate(const struct audio_stream *stream) { - struct sunxi_stream_in *in = (struct sunxi_stream_in *)stream; + struct sunxi_stream_in *in = (struct sunxi_stream_in *)stream; - return in->requested_rate; + return in->requested_rate; } static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate) { - return 0; + return 0; } static size_t in_get_buffer_size(const struct audio_stream *stream) { - struct sunxi_stream_in *in = (struct sunxi_stream_in *)stream; + struct sunxi_stream_in *in = (struct sunxi_stream_in *)stream; - return get_input_buffer_size(in->requested_rate, - AUDIO_FORMAT_PCM_16_BIT, - in->config.channels); + return get_input_buffer_size(in->requested_rate, + AUDIO_FORMAT_PCM_16_BIT, + in->config.channels); } static audio_channel_mask_t in_get_channels(const struct audio_stream *stream) { - struct sunxi_stream_in *in = (struct sunxi_stream_in *)stream; + struct sunxi_stream_in *in = (struct sunxi_stream_in *)stream; - if (in->config.channels == 1) { - return AUDIO_CHANNEL_IN_MONO; - } else { - return AUDIO_CHANNEL_IN_STEREO; - } + if (in->config.channels == 1) { + return AUDIO_CHANNEL_IN_MONO; + } else { + return AUDIO_CHANNEL_IN_STEREO; + } } static audio_format_t in_get_format(const struct audio_stream *stream) { - return AUDIO_FORMAT_PCM_16_BIT; + return AUDIO_FORMAT_PCM_16_BIT; } static int in_set_format(struct audio_stream *stream, audio_format_t format) { - return 0; + return 0; } /* must be called with hw device and input stream mutexes locked */ static int do_input_standby(struct sunxi_stream_in *in) { - struct sunxi_audio_device *adev = in->dev; + struct sunxi_audio_device *adev = in->dev; - if (!in->standby) { - pcm_close(in->pcm); - in->pcm = NULL; + if (!in->standby) { + pcm_close(in->pcm); + in->pcm = NULL; - adev->active_input = 0; - if (in->resampler){ - release_resampler(in->resampler); - in->resampler = 0; - } - if (adev->mode != AUDIO_MODE_IN_CALL) { - adev->in_device = AUDIO_DEVICE_NONE; - select_device(adev); - } + adev->active_input = 0; + if (in->resampler) { + release_resampler(in->resampler); + in->resampler = 0; + } + if (adev->mode != AUDIO_MODE_IN_CALL) { + adev->in_device = AUDIO_DEVICE_NONE; + select_device(adev); + } - if (in->echo_reference != NULL) { - /* stop reading from echo reference */ - in->echo_reference->read(in->echo_reference, NULL); - put_echo_reference(adev, in->echo_reference); - in->echo_reference = NULL; - } + if (in->echo_reference != NULL) { + /* stop reading from echo reference */ + in->echo_reference->read(in->echo_reference, NULL); + put_echo_reference(adev, in->echo_reference); + in->echo_reference = NULL; + } - in->standby = 1; - } - return 0; + in->standby = 1; + } + return 0; } static int in_standby(struct audio_stream *stream) { - struct sunxi_stream_in *in = (struct sunxi_stream_in *)stream; - int status; + struct sunxi_stream_in *in = (struct sunxi_stream_in *)stream; + int status; - pthread_mutex_lock(&in->dev->lock); - pthread_mutex_lock(&in->lock); - status = do_input_standby(in); - pthread_mutex_unlock(&in->lock); - pthread_mutex_unlock(&in->dev->lock); - return status; + pthread_mutex_lock(&in->dev->lock); + pthread_mutex_lock(&in->lock); + status = do_input_standby(in); + pthread_mutex_unlock(&in->lock); + pthread_mutex_unlock(&in->dev->lock); + return status; } static int in_dump(const struct audio_stream *stream, int fd) { - return 0; + return 0; } static int in_set_parameters(struct audio_stream *stream, const char *kvpairs) { - struct sunxi_stream_in *in = (struct sunxi_stream_in *)stream; - struct sunxi_audio_device *adev = in->dev; - struct str_parms *parms; - char *str; - char value[128]; - int ret, val = 0; - bool do_standby = false; + struct sunxi_stream_in *in = (struct sunxi_stream_in *)stream; + struct sunxi_audio_device *adev = in->dev; + struct str_parms *parms; + char *str; + char value[128]; + int ret, val = 0; + bool do_standby = false; - ALOGV("in_set_parameters: %s", kvpairs); + ALOGV("in_set_parameters: %s", kvpairs); - parms = str_parms_create_str(kvpairs); + parms = str_parms_create_str(kvpairs); - ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value)); + ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value)); - pthread_mutex_lock(&adev->lock); - pthread_mutex_lock(&in->lock); - if (ret >= 0) { - val = atoi(value); - /* no audio source uses val == 0 */ - if ((in->source != val) && (val != 0)) { - in->source = val; - do_standby = true; - } - } - - ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value)); - if (ret >= 0) { - val = atoi(value) & ~AUDIO_DEVICE_BIT_IN; - if ((adev->mode != AUDIO_MODE_IN_CALL) && (in->device != val) && (val != 0)) { - in->device = val; - do_standby = true; - } else if((adev->mode == AUDIO_MODE_IN_CALL) && (in->source != val) && (val != 0)) { - in->device = val; - - select_device(adev); + pthread_mutex_lock(&adev->lock); + pthread_mutex_lock(&in->lock); + if (ret >= 0) { + val = atoi(value); + /* no audio source uses val == 0 */ + if ((in->source != val) && (val != 0)) { + in->source = val; + do_standby = true; } } - if (do_standby) - do_input_standby(in); - pthread_mutex_unlock(&in->lock); - pthread_mutex_unlock(&adev->lock); + ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value)); + if (ret >= 0) { + val = atoi(value) & ~AUDIO_DEVICE_BIT_IN; + if ((adev->mode != AUDIO_MODE_IN_CALL) && (in->device != val) && (val != 0)) { + in->device = val; + do_standby = true; + } else if ((adev->mode == AUDIO_MODE_IN_CALL) && (in->source != val) && (val != 0)) { + in->device = val; - str_parms_destroy(parms); - return ret; + select_device(adev); + } + } + + if (do_standby) + do_input_standby(in); + pthread_mutex_unlock(&in->lock); + pthread_mutex_unlock(&adev->lock); + + str_parms_destroy(parms); + return ret; } static char * in_get_parameters(const struct audio_stream *stream, - const char *keys) + const char *keys) { - return strdup(""); + return strdup(""); } static int in_set_gain(struct audio_stream_in *stream, float gain) { - return 0; + return 0; } static void get_capture_delay(struct sunxi_stream_in *in, - size_t frames, - struct echo_reference_buffer *buffer) + size_t frames, + struct echo_reference_buffer *buffer) { - /* read frames available in kernel driver buffer */ - size_t kernel_frames; - struct timespec tstamp; - long buf_delay; - long rsmp_delay; - long kernel_delay; - long delay_ns; + /* read frames available in kernel driver buffer */ + size_t kernel_frames; + struct timespec tstamp; + long buf_delay; + long rsmp_delay; + long kernel_delay; + long delay_ns; - if (pcm_get_htimestamp(in->pcm, &kernel_frames, &tstamp) < 0) { - buffer->time_stamp.tv_sec = 0; - buffer->time_stamp.tv_nsec = 0; - buffer->delay_ns = 0; - ALOGW("read get_capture_delay(): pcm_htimestamp error"); - return; - } + if (pcm_get_htimestamp(in->pcm, &kernel_frames, &tstamp) < 0) { + buffer->time_stamp.tv_sec = 0; + buffer->time_stamp.tv_nsec = 0; + buffer->delay_ns = 0; + ALOGW("read get_capture_delay(): pcm_htimestamp error"); + return; + } - /* read frames available in audio HAL input buffer - * add number of frames being read as we want the capture time of first sample - * in current buffer */ - buf_delay = (long)(((int64_t)(in->frames_in + in->proc_frames_in) * 1000000000) - / in->config.rate); - /* add delay introduced by resampler */ - rsmp_delay = 0; - if (in->resampler) { - rsmp_delay = in->resampler->delay_ns(in->resampler); - } + /* read frames available in audio HAL input buffer + * add number of frames being read as we want the capture time of first sample + * in current buffer */ + buf_delay = (long)(((int64_t)(in->frames_in + in->proc_frames_in) * 1000000000) + / in->config.rate); + /* add delay introduced by resampler */ + rsmp_delay = 0; + if (in->resampler) { + rsmp_delay = in->resampler->delay_ns(in->resampler); + } - kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / in->config.rate); + kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / in->config.rate); - delay_ns = kernel_delay + buf_delay + rsmp_delay; + delay_ns = kernel_delay + buf_delay + rsmp_delay; - buffer->time_stamp = tstamp; - buffer->delay_ns = delay_ns; - ALOGV("get_capture_delay time_stamp = [%ld].[%ld], delay_ns: [%d]," - " kernel_delay:[%ld], buf_delay:[%ld], rsmp_delay:[%ld], kernel_frames:[%d], " - "in->frames_in:[%d], in->proc_frames_in:[%d], frames:[%d]", - buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, buffer->delay_ns, - kernel_delay, buf_delay, rsmp_delay, kernel_frames, - in->frames_in, in->proc_frames_in, frames); + buffer->time_stamp = tstamp; + buffer->delay_ns = delay_ns; + ALOGV("get_capture_delay time_stamp = [%ld].[%ld], delay_ns: [%d]," + " kernel_delay:[%ld], buf_delay:[%ld], rsmp_delay:[%ld], kernel_frames:[%d], " + "in->frames_in:[%d], in->proc_frames_in:[%d], frames:[%d]", + buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, buffer->delay_ns, + kernel_delay, buf_delay, rsmp_delay, kernel_frames, + in->frames_in, in->proc_frames_in, frames); } static int32_t update_echo_reference(struct sunxi_stream_in *in, size_t frames) { - struct echo_reference_buffer b; - b.delay_ns = 0; + struct echo_reference_buffer b; + b.delay_ns = 0; - ALOGV("update_echo_reference, frames = [%d], in->ref_frames_in = [%d], " - "b.frame_count = [%d]", - frames, in->ref_frames_in, frames - in->ref_frames_in); - if (in->ref_frames_in < frames) { - if (in->ref_buf_size < frames) { - in->ref_buf_size = frames; - in->ref_buf = (int16_t *)realloc(in->ref_buf, - in->ref_buf_size * - in->config.channels * sizeof(int16_t)); - } + ALOGV("update_echo_reference, frames = [%d], in->ref_frames_in = [%d], " + "b.frame_count = [%d]", + frames, in->ref_frames_in, frames - in->ref_frames_in); + if (in->ref_frames_in < frames) { + if (in->ref_buf_size < frames) { + in->ref_buf_size = frames; + in->ref_buf = (int16_t *)realloc(in->ref_buf, + in->ref_buf_size * + in->config.channels * sizeof(int16_t)); + } - b.frame_count = frames - in->ref_frames_in; - b.raw = (void *)(in->ref_buf + in->ref_frames_in * in->config.channels); + b.frame_count = frames - in->ref_frames_in; + b.raw = (void *)(in->ref_buf + in->ref_frames_in * in->config.channels); - get_capture_delay(in, frames, &b); + get_capture_delay(in, frames, &b); - if (in->echo_reference->read(in->echo_reference, &b) == 0) - { - in->ref_frames_in += b.frame_count; - ALOGV("update_echo_reference: in->ref_frames_in:[%d], " - "in->ref_buf_size:[%d], frames:[%d], b.frame_count:[%d]", - in->ref_frames_in, in->ref_buf_size, frames, b.frame_count); - } - } else - ALOGW("update_echo_reference: NOT enough frames to read ref buffer"); - return b.delay_ns; + if (in->echo_reference->read(in->echo_reference, &b) == 0) { + in->ref_frames_in += b.frame_count; + ALOGV("update_echo_reference: in->ref_frames_in:[%d], " + "in->ref_buf_size:[%d], frames:[%d], b.frame_count:[%d]", + in->ref_frames_in, in->ref_buf_size, frames, b.frame_count); + } + } else + ALOGW("update_echo_reference: NOT enough frames to read ref buffer"); + + return b.delay_ns; } static int set_preprocessor_param(effect_handle_t handle, - effect_param_t *param) + effect_param_t *param) { - uint32_t size = sizeof(int); - uint32_t psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + - param->vsize; + uint32_t size = sizeof(int); + uint32_t psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + + param->vsize; - int status = (*handle)->command(handle, - EFFECT_CMD_SET_PARAM, - sizeof (effect_param_t) + psize, - param, - &size, - ¶m->status); - if (status == 0) - status = param->status; + int status = (*handle)->command(handle, + EFFECT_CMD_SET_PARAM, + sizeof (effect_param_t) + psize, + param, + &size, + ¶m->status); + if (status == 0) + status = param->status; - return status; + return status; } static int set_preprocessor_echo_delay(effect_handle_t handle, - int32_t delay_us) + int32_t delay_us) { - uint32_t buf[sizeof(effect_param_t) / sizeof(uint32_t) + 2]; - effect_param_t *param = (effect_param_t *)buf; + uint32_t buf[sizeof(effect_param_t) / sizeof(uint32_t) + 2]; + effect_param_t *param = (effect_param_t *)buf; - param->psize = sizeof(uint32_t); - param->vsize = sizeof(uint32_t); - *(uint32_t *)param->data = AEC_PARAM_ECHO_DELAY; - *((int32_t *)param->data + 1) = delay_us; + param->psize = sizeof(uint32_t); + param->vsize = sizeof(uint32_t); + *(uint32_t *)param->data = AEC_PARAM_ECHO_DELAY; + *((int32_t *)param->data + 1) = delay_us; - return set_preprocessor_param(handle, param); + return set_preprocessor_param(handle, param); } static void push_echo_reference(struct sunxi_stream_in *in, size_t frames) { - /* read frames from echo reference buffer and update echo delay - * in->ref_frames_in is updated with frames available in in->ref_buf */ - int32_t delay_us = update_echo_reference(in, frames)/1000; - int i; - audio_buffer_t buf; + /* read frames from echo reference buffer and update echo delay + * in->ref_frames_in is updated with frames available in in->ref_buf */ + int32_t delay_us = update_echo_reference(in, frames)/1000; + int i; + audio_buffer_t buf; - if (in->ref_frames_in < frames) - frames = in->ref_frames_in; + if (in->ref_frames_in < frames) + frames = in->ref_frames_in; - buf.frameCount = frames; - buf.raw = in->ref_buf; + buf.frameCount = frames; + buf.raw = in->ref_buf; - for (i = 0; i < in->num_preprocessors; i++) { - if ((*in->preprocessors[i])->process_reverse == NULL) - continue; + for (i = 0; i < in->num_preprocessors; i++) { + if ((*in->preprocessors[i])->process_reverse == NULL) + continue; - (*in->preprocessors[i])->process_reverse(in->preprocessors[i], - &buf, - NULL); - set_preprocessor_echo_delay(in->preprocessors[i], delay_us); - } + (*in->preprocessors[i])->process_reverse(in->preprocessors[i], + &buf, + NULL); + set_preprocessor_echo_delay(in->preprocessors[i], delay_us); + } - in->ref_frames_in -= buf.frameCount; - if (in->ref_frames_in) { - memcpy(in->ref_buf, - in->ref_buf + buf.frameCount * in->config.channels, - in->ref_frames_in * in->config.channels * sizeof(int16_t)); - } + in->ref_frames_in -= buf.frameCount; + if (in->ref_frames_in) { + memcpy(in->ref_buf, + in->ref_buf + buf.frameCount * in->config.channels, + in->ref_frames_in * in->config.channels * sizeof(int16_t)); + } } static int get_next_buffer(struct resampler_buffer_provider *buffer_provider, - struct resampler_buffer* buffer) + struct resampler_buffer* buffer) { - struct sunxi_stream_in *in; + struct sunxi_stream_in *in; - if (buffer_provider == NULL || buffer == NULL) - return -EINVAL; + if (buffer_provider == NULL || buffer == NULL) + return -EINVAL; - in = (struct sunxi_stream_in *)((char *)buffer_provider - - offsetof(struct sunxi_stream_in, buf_provider)); + in = (struct sunxi_stream_in *)((char *)buffer_provider - + offsetof(struct sunxi_stream_in, buf_provider)); - if (in->pcm == NULL) { - buffer->raw = NULL; - buffer->frame_count = 0; - in->read_status = -ENODEV; - return -ENODEV; - } + if (in->pcm == NULL) { + buffer->raw = NULL; + buffer->frame_count = 0; + in->read_status = -ENODEV; + return -ENODEV; + } -// ALOGV("get_next_buffer: in->config.period_size: %d, audio_stream_frame_size: %d", -// in->config.period_size, audio_stream_frame_size(&in->stream.common)); - if (in->frames_in == 0) { - in->read_status = pcm_read(in->pcm, - (void*)in->buffer, - in->config.period_size * - audio_stream_frame_size(&in->stream.common)); - if (in->read_status != 0) { - ALOGE("get_next_buffer() pcm_read error %d, %s", in->read_status, strerror(errno)); - buffer->raw = NULL; - buffer->frame_count = 0; - return in->read_status; - } - in->frames_in = in->config.period_size; - } + if (in->frames_in == 0) { + in->read_status = pcm_read(in->pcm, + (void*)in->buffer, + in->config.period_size * + audio_stream_frame_size(&in->stream.common)); + if (in->read_status != 0) { + ALOGE("get_next_buffer() pcm_read error %d, %s", in->read_status, strerror(errno)); + buffer->raw = NULL; + buffer->frame_count = 0; + return in->read_status; + } + in->frames_in = in->config.period_size; + } - buffer->frame_count = (buffer->frame_count > in->frames_in) ? - in->frames_in : buffer->frame_count; - buffer->i16 = in->buffer + (in->config.period_size - in->frames_in) * - in->config.channels; + buffer->frame_count = (buffer->frame_count > in->frames_in) ? + in->frames_in : buffer->frame_count; + buffer->i16 = in->buffer + (in->config.period_size - in->frames_in) * + in->config.channels; - return in->read_status; + return in->read_status; } static void release_buffer(struct resampler_buffer_provider *buffer_provider, - struct resampler_buffer* buffer) + struct resampler_buffer* buffer) { - struct sunxi_stream_in *in; + struct sunxi_stream_in *in; - if (buffer_provider == NULL || buffer == NULL) - return; + if (buffer_provider == NULL || buffer == NULL) + return; - in = (struct sunxi_stream_in *)((char *)buffer_provider - - offsetof(struct sunxi_stream_in, buf_provider)); + in = (struct sunxi_stream_in *)((char *)buffer_provider - + offsetof(struct sunxi_stream_in, buf_provider)); - in->frames_in -= buffer->frame_count; + in->frames_in -= buffer->frame_count; } /* read_frames() reads frames from kernel driver, down samples to capture rate * if necessary and output the number of frames requested to the buffer specified */ static ssize_t read_frames(struct sunxi_stream_in *in, void *buffer, ssize_t frames) { - ssize_t frames_wr = 0; + ssize_t frames_wr = 0; - while (frames_wr < frames) { - size_t frames_rd = frames - frames_wr; - if (in->resampler != NULL) { - in->resampler->resample_from_provider(in->resampler, - (int16_t *)((char *)buffer + - frames_wr * audio_stream_frame_size(&in->stream.common)), - &frames_rd); - } else { - struct resampler_buffer buf = { - { raw : NULL, }, - frame_count : frames_rd, - }; - get_next_buffer(&in->buf_provider, &buf); - if (buf.raw != NULL) { - memcpy((char *)buffer + - frames_wr * audio_stream_frame_size(&in->stream.common), - buf.raw, - buf.frame_count * audio_stream_frame_size(&in->stream.common)); - frames_rd = buf.frame_count; - } - release_buffer(&in->buf_provider, &buf); - } - /* in->read_status is updated by getNextBuffer() also called by - * in->resampler->resample_from_provider() */ - if (in->read_status != 0) - return in->read_status; + while (frames_wr < frames) { + size_t frames_rd = frames - frames_wr; + if (in->resampler != NULL) { + in->resampler->resample_from_provider(in->resampler, + (int16_t *)((char *)buffer + + frames_wr * audio_stream_frame_size(&in->stream.common)), + &frames_rd); + } else { + struct resampler_buffer buf = { + { raw : NULL, }, + frame_count : frames_rd, + }; + get_next_buffer(&in->buf_provider, &buf); + if (buf.raw != NULL) { + memcpy((char *)buffer + + frames_wr * audio_stream_frame_size(&in->stream.common), + buf.raw, + buf.frame_count * audio_stream_frame_size(&in->stream.common)); + frames_rd = buf.frame_count; + } + release_buffer(&in->buf_provider, &buf); + } - frames_wr += frames_rd; - } - return frames_wr; + /* in->read_status is updated by getNextBuffer() also called by + * in->resampler->resample_from_provider() */ + if (in->read_status != 0) + return in->read_status; + + frames_wr += frames_rd; + } + return frames_wr; } /* process_frames() reads frames from kernel driver (via read_frames()), @@ -2446,429 +2285,407 @@ static ssize_t read_frames(struct sunxi_stream_in *in, void *buffer, ssize_t fra * to the buffer specified */ static ssize_t process_frames(struct sunxi_stream_in *in, void* buffer, ssize_t frames) { - ssize_t frames_wr = 0; - audio_buffer_t in_buf; - audio_buffer_t out_buf; - int i; + ssize_t frames_wr = 0; + audio_buffer_t in_buf; + audio_buffer_t out_buf; + int i; - while (frames_wr < frames) { - /* first reload enough frames at the end of process input buffer */ - if (in->proc_frames_in < (size_t)frames) { - ssize_t frames_rd; + while (frames_wr < frames) { + /* first reload enough frames at the end of process input buffer */ + if (in->proc_frames_in < (size_t)frames) { + ssize_t frames_rd; - if (in->proc_buf_size < (size_t)frames) { - in->proc_buf_size = (size_t)frames; - in->proc_buf = (int16_t *)realloc(in->proc_buf, - in->proc_buf_size * - in->config.channels * sizeof(int16_t)); - ALOGV("process_frames(): in->proc_buf %p size extended to %d frames", - in->proc_buf, in->proc_buf_size); - } - frames_rd = read_frames(in, - in->proc_buf + - in->proc_frames_in * in->config.channels, - frames - in->proc_frames_in); - if (frames_rd < 0) { - frames_wr = frames_rd; - break; - } - in->proc_frames_in += frames_rd; - } + if (in->proc_buf_size < (size_t)frames) { + in->proc_buf_size = (size_t)frames; + in->proc_buf = (int16_t *)realloc(in->proc_buf, + in->proc_buf_size * + in->config.channels * sizeof(int16_t)); + ALOGV("process_frames(): in->proc_buf %p size extended to %d frames", + in->proc_buf, in->proc_buf_size); + } + frames_rd = read_frames(in, + in->proc_buf + + in->proc_frames_in * in->config.channels, + frames - in->proc_frames_in); + if (frames_rd < 0) { + frames_wr = frames_rd; + break; + } + in->proc_frames_in += frames_rd; + } - if (in->echo_reference != NULL) - push_echo_reference(in, in->proc_frames_in); + if (in->echo_reference != NULL) + push_echo_reference(in, in->proc_frames_in); - /* in_buf.frameCount and out_buf.frameCount indicate respectively - * the maximum number of frames to be consumed and produced by process() */ - in_buf.frameCount = in->proc_frames_in; - in_buf.s16 = in->proc_buf; - out_buf.frameCount = frames - frames_wr; - out_buf.s16 = (int16_t *)buffer + frames_wr * in->config.channels; + /* in_buf.frameCount and out_buf.frameCount indicate respectively + * the maximum number of frames to be consumed and produced by process() */ + in_buf.frameCount = in->proc_frames_in; + in_buf.s16 = in->proc_buf; + out_buf.frameCount = frames - frames_wr; + out_buf.s16 = (int16_t *)buffer + frames_wr * in->config.channels; - for (i = 0; i < in->num_preprocessors; i++) - (*in->preprocessors[i])->process(in->preprocessors[i], - &in_buf, - &out_buf); + for (i = 0; i < in->num_preprocessors; i++) + (*in->preprocessors[i])->process(in->preprocessors[i], + &in_buf, + &out_buf); - /* process() has updated the number of frames consumed and produced in - * in_buf.frameCount and out_buf.frameCount respectively - * move remaining frames to the beginning of in->proc_buf */ - in->proc_frames_in -= in_buf.frameCount; - if (in->proc_frames_in) { - memcpy(in->proc_buf, - in->proc_buf + in_buf.frameCount * in->config.channels, - in->proc_frames_in * in->config.channels * sizeof(int16_t)); - } + /* process() has updated the number of frames consumed and produced in + * in_buf.frameCount and out_buf.frameCount respectively + * move remaining frames to the beginning of in->proc_buf */ + in->proc_frames_in -= in_buf.frameCount; + if (in->proc_frames_in) { + memcpy(in->proc_buf, + in->proc_buf + in_buf.frameCount * in->config.channels, + in->proc_frames_in * in->config.channels * sizeof(int16_t)); + } - /* if not enough frames were passed to process(), read more and retry. */ - if (out_buf.frameCount == 0) - continue; + /* if not enough frames were passed to process(), read more and retry. */ + if (out_buf.frameCount == 0) + continue; - frames_wr += out_buf.frameCount; - } - return frames_wr; + frames_wr += out_buf.frameCount; + } + return frames_wr; } static ssize_t in_read(struct audio_stream_in *stream, void* buffer, - size_t bytes) + size_t bytes) { - int ret = 0; - struct sunxi_stream_in *in = (struct sunxi_stream_in *)stream; - struct sunxi_audio_device *adev = in->dev; - size_t frames_rq = bytes / audio_stream_frame_size(&stream->common); + int ret = 0; + struct sunxi_stream_in *in = (struct sunxi_stream_in *)stream; + struct sunxi_audio_device *adev = in->dev; + size_t frames_rq = bytes / audio_stream_frame_size(&stream->common); + int is_first_data = 0; - if (adev->mode == AUDIO_MODE_IN_CALL) { - //ALOGD("in call mode, in_read, return ;"); - memset(buffer, 0, bytes); - //usleep(10000); - //return 1; - } + if (adev->mode == AUDIO_MODE_IN_CALL) { + //ALOGD("in call mode, in_read, return ;"); + memset(buffer, 0, bytes); + //usleep(10000); + //return 1; + } - /* acquiring hw device mutex systematically is useful if a low priority thread is waiting - * on the input stream mutex - e.g. executing select_mode() while holding the hw device - * mutex - */ - if (adev->af_capture_flag && adev->PcmManager.BufExist) { - pthread_mutex_lock(&adev->lock); - pthread_mutex_lock(&in->lock); - if (in->standby) { - in->standby = 0; - } - pthread_mutex_unlock(&adev->lock); + /* acquiring hw device mutex systematically is useful if a low priority thread is waiting + * on the input stream mutex - e.g. executing select_mode() while holding the hw device + * mutex + */ + if (adev->af_capture_flag && adev->PcmManager.BufExist) { + pthread_mutex_lock(&adev->lock); + pthread_mutex_lock(&in->lock); + if (in->standby) { + in->standby = 0; + } + pthread_mutex_unlock(&adev->lock); - if (ret < 0) - goto exit; + if (ret < 0) + goto exit; //if (bytes > adev->PcmManager.DataLen) - //usleep(10000); + //usleep(10000); - ret = ReadPcmData(buffer, bytes, &adev->PcmManager); + ret = ReadPcmData(buffer, bytes, &adev->PcmManager); - if (ret > 0) - ret = 0; + if (ret > 0) + ret = 0; - if (ret == 0 && adev->mic_mute) - memset(buffer, 0, bytes); + if (ret == 0 && adev->mic_mute) + memset(buffer, 0, bytes); - pthread_mutex_unlock(&in->lock); - return bytes; + pthread_mutex_unlock(&in->lock); + return bytes; } pthread_mutex_lock(&adev->lock); pthread_mutex_lock(&in->lock); if (in->standby) { ret = start_input_stream(in); + is_first_data = 1; if (ret == 0) in->standby = 0; } pthread_mutex_unlock(&adev->lock); - if (ret < 0) - goto exit; + if (ret < 0) + goto exit; - if (in->num_preprocessors != 0) { - ret = read_frames(in, buffer, frames_rq);//ret = process_frames(in, buffer, frames_rq); + if (in->num_preprocessors != 0) { + ret = read_frames(in, buffer, frames_rq);//ret = process_frames(in, buffer, frames_rq); - } else if (in->resampler != NULL) { - ret = read_frames(in, buffer, frames_rq); + } else if (in->resampler != NULL) { + ret = read_frames(in, buffer, frames_rq); } else { - ret = pcm_read(in->pcm, buffer, bytes); + ret = pcm_read(in->pcm, buffer, bytes); } - if (ret > 0) - ret = 0; + /* If connect headset, set the first data to zero. + * There may be a noise pulse. + */ + if (is_first_data && + (adev->in_device & AUDIO_DEVICE_IN_WIRED_HEADSET)) { + memset(buffer, 0, bytes); + } - if (ret == 0 && adev->mic_mute) - memset(buffer, 0, bytes); + if (ret > 0) + ret = 0; + + if (ret == 0 && adev->mic_mute) + memset(buffer, 0, bytes); exit: - if (ret < 0) - usleep(bytes * 1000000 / audio_stream_frame_size(&stream->common) / - in_get_sample_rate(&stream->common)); + if (ret < 0) + usleep(bytes * 1000000 / audio_stream_frame_size(&stream->common) / + in_get_sample_rate(&stream->common)); - pthread_mutex_unlock(&in->lock); - return bytes; + pthread_mutex_unlock(&in->lock); + return bytes; } static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream) { - return 0; + return 0; } static int in_add_audio_effect(const struct audio_stream *stream, - effect_handle_t effect) + effect_handle_t effect) { - struct sunxi_stream_in *in = (struct sunxi_stream_in *)stream; - int status; - effect_descriptor_t desc; + struct sunxi_stream_in *in = (struct sunxi_stream_in *)stream; + int status; + effect_descriptor_t desc; - pthread_mutex_lock(&in->dev->lock); - pthread_mutex_lock(&in->lock); - if (in->num_preprocessors >= MAX_PREPROCESSORS) { - status = -ENOSYS; - goto exit; - } + pthread_mutex_lock(&in->dev->lock); + pthread_mutex_lock(&in->lock); + if (in->num_preprocessors >= MAX_PREPROCESSORS) { + status = -ENOSYS; + goto exit; + } - status = (*effect)->get_descriptor(effect, &desc); - if (status != 0) - goto exit; + status = (*effect)->get_descriptor(effect, &desc); + if (status != 0) + goto exit; - in->preprocessors[in->num_preprocessors++] = effect; + in->preprocessors[in->num_preprocessors++] = effect; - if (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) { - in->need_echo_reference = true; - do_input_standby(in); - } + if (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) { + in->need_echo_reference = true; + do_input_standby(in); + } exit: - pthread_mutex_unlock(&in->lock); - pthread_mutex_unlock(&in->dev->lock); - return status; + pthread_mutex_unlock(&in->lock); + pthread_mutex_unlock(&in->dev->lock); + return status; } static int in_remove_audio_effect(const struct audio_stream *stream, - effect_handle_t effect) + effect_handle_t effect) { - struct sunxi_stream_in *in = (struct sunxi_stream_in *)stream; - int i; - int status = -EINVAL; - bool found = false; - effect_descriptor_t desc; + struct sunxi_stream_in *in = (struct sunxi_stream_in *)stream; + int i; + int status = -EINVAL; + bool found = false; + effect_descriptor_t desc; - pthread_mutex_lock(&in->dev->lock); - pthread_mutex_lock(&in->lock); - if (in->num_preprocessors <= 0) { - status = -ENOSYS; - goto exit; - } + pthread_mutex_lock(&in->dev->lock); + pthread_mutex_lock(&in->lock); + if (in->num_preprocessors <= 0) { + status = -ENOSYS; + goto exit; + } - for (i = 0; i < in->num_preprocessors; i++) { - if (found) { - in->preprocessors[i - 1] = in->preprocessors[i]; - continue; - } - if (in->preprocessors[i] == effect) { - in->preprocessors[i] = NULL; - status = 0; - found = true; - } - } + for (i = 0; i < in->num_preprocessors; i++) { + if (found) { + in->preprocessors[i - 1] = in->preprocessors[i]; + continue; + } + if (in->preprocessors[i] == effect) { + in->preprocessors[i] = NULL; + status = 0; + found = true; + } + } - if (status != 0) - goto exit; + if (status != 0) + goto exit; - in->num_preprocessors--; + in->num_preprocessors--; - status = (*effect)->get_descriptor(effect, &desc); - if (status != 0) - goto exit; - if (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) { - in->need_echo_reference = false; - do_input_standby(in); - } + status = (*effect)->get_descriptor(effect, &desc); + if (status != 0) + goto exit; + if (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) { + in->need_echo_reference = false; + do_input_standby(in); + } exit: - pthread_mutex_unlock(&in->lock); - pthread_mutex_unlock(&in->dev->lock); - return status; + pthread_mutex_unlock(&in->lock); + pthread_mutex_unlock(&in->dev->lock); + return status; } static int adev_open_output_stream(struct audio_hw_device *dev, - audio_io_handle_t handle, - audio_devices_t devices, - audio_output_flags_t flags, - struct audio_config *config, - struct audio_stream_out **stream_out) + audio_io_handle_t handle, + audio_devices_t devices, + audio_output_flags_t flags, + struct audio_config *config, + struct audio_stream_out **stream_out) { struct sunxi_audio_device *ladev = (struct sunxi_audio_device *)dev; - struct sunxi_stream_out *out; - int ret; + struct sunxi_stream_out *out; + int ret; + - ALOGV("adev_open_output_stream, flags: %x", flags); - out = (struct sunxi_stream_out *)calloc(1, sizeof(struct sunxi_stream_out)); - if (!out) - return -ENOMEM; + out = (struct sunxi_stream_out *)calloc(1, sizeof(struct sunxi_stream_out)); + if (!out) + return -ENOMEM; - out->buffer = malloc(RESAMPLER_BUFFER_SIZE); /* todo: allow for reallocing */ + out->buffer = malloc(RESAMPLER_BUFFER_SIZE); /* todo: allow for reallocing */ - out->stream.common.get_sample_rate = out_get_sample_rate; - out->stream.common.set_sample_rate = out_set_sample_rate; - out->stream.common.get_buffer_size = out_get_buffer_size; - out->stream.common.get_channels = out_get_channels; - out->stream.common.get_format = out_get_format; - out->stream.common.set_format = out_set_format; - out->stream.common.standby = out_standby; - out->stream.common.dump = out_dump; - out->stream.common.set_parameters = out_set_parameters; - out->stream.common.get_parameters = out_get_parameters; - out->stream.common.add_audio_effect = out_add_audio_effect; - out->stream.common.remove_audio_effect = out_remove_audio_effect; - out->stream.get_latency = out_get_latency; - out->stream.set_volume = out_set_volume; - out->stream.write = out_write; - out->stream.get_render_position = out_get_render_position; + out->stream.common.get_sample_rate = out_get_sample_rate; + out->stream.common.set_sample_rate = out_set_sample_rate; + out->stream.common.get_buffer_size = out_get_buffer_size; + out->stream.common.get_channels = out_get_channels; + out->stream.common.get_format = out_get_format; + out->stream.common.set_format = out_set_format; + out->stream.common.standby = out_standby; + out->stream.common.dump = out_dump; + out->stream.common.set_parameters = out_set_parameters; + out->stream.common.get_parameters = out_get_parameters; + out->stream.common.add_audio_effect = out_add_audio_effect; + out->stream.common.remove_audio_effect = out_remove_audio_effect; + out->stream.get_latency = out_get_latency; + out->stream.set_volume = out_set_volume; + out->stream.write = out_write; + out->stream.get_render_position = out_get_render_position; out->stream.get_next_write_timestamp = out_get_next_write_timestamp; out->stream.get_presentation_position = out_get_presentation_position; - out->config = pcm_config_mm_out; + out->config = pcm_config_mm_out; - out->dev = ladev; - out->standby = 1; + out->dev = ladev; + out->standby = 1; - /* FIXME: when we support multiple output devices, we will want to - * do the following: + /* FIXME: when we support multiple output devices, we will want to + * do the following: * adev->out_device = out->device; - * select_output_device(adev); - * This is because out_set_parameters() with a route is not - * guaranteed to be called after an output stream is opened. */ + * select_output_device(adev); + * This is because out_set_parameters() with a route is not + * guaranteed to be called after an output stream is opened. */ config->format = out_get_format(&out->stream.common); - config->channel_mask = out_get_channels(&out->stream.common); - config->sample_rate = out_get_sample_rate(&out->stream.common); + config->channel_mask = out_get_channels(&out->stream.common); + config->sample_rate = out_get_sample_rate(&out->stream.common); ALOGV("+++++++++++++++ adev_open_output_stream: req_sample_rate: %d, fmt: %x, channel_count: %d", - config->sample_rate, config->format, config->channel_mask); + config->sample_rate, config->format, config->channel_mask); -#if VVS_USED - vvs.lib_handle = NULL; - vvs.lib_handle = dlopen("libAwHeadpSurround.so",RTLD_LAZY); - if (vvs.lib_handle == NULL){ - ALOGV("can't open libAwHeadpSurround.so!"); - goto vvs_init_exit; - } + *stream_out = &out->stream; - vvs.process_init = dlsym(vvs.lib_handle,"process_init"); - vvs.surround_pro_in_out = dlsym(vvs.lib_handle,"surround_pro_in_out"); - vvs.process_exit = dlsym(vvs.lib_handle,"process_exit"); - vvs.set_bass = dlsym(vvs.lib_handle,"set_bass"); - vvs.set_defintion = dlsym(vvs.lib_handle,"set_defintion"); - vvs.set_space = dlsym(vvs.lib_handle,"set_space"); - vvs.vvs_handle = vvs.process_init(vvs.vvs_handle, config->sample_rate, 2, SHORT_PERIOD_SIZE); - vvs.set_bass(vvs.vvs_handle, 0.33); - vvs.set_defintion(vvs.vvs_handle, 0.80); - vvs.set_space(vvs.vvs_handle, 0.50); - -vvs_init_exit: -#endif - - *stream_out = &out->stream; - - return 0; + return 0; err_open: - free(out); - *stream_out = NULL; - return ret; + free(out); + *stream_out = NULL; + return ret; } static void adev_close_output_stream(struct audio_hw_device *dev, - struct audio_stream_out *stream) + struct audio_stream_out *stream) { - struct sunxi_stream_out *out = (struct sunxi_stream_out *)stream; - struct sunxi_audio_device *adev = out->dev; + struct sunxi_stream_out *out = (struct sunxi_stream_out *)stream; + struct sunxi_audio_device *adev = out->dev; - if (adev->mode == AUDIO_MODE_IN_CALL || adev->mode == AUDIO_MODE_MODE_FACTORY_TEST || adev->mode == AUDIO_MODE_FM) - { + if (adev->mode == AUDIO_MODE_IN_CALL || adev->mode == AUDIO_MODE_MODE_FACTORY_TEST || adev->mode == AUDIO_MODE_FM) { ALOGW("mode in call, do not adev_close_output_stream"); return ; } - out_standby(&stream->common); + out_standby(&stream->common); - if (out->buffer){ - free(out->buffer); + if (out->buffer) { + free(out->buffer); out->buffer = 0; } - if (out->resampler){ - release_resampler(out->resampler); + if (out->resampler) { + release_resampler(out->resampler); out->resampler = 0; - } - free(stream); - -#if VVS_USED - if (vvs.vvs_handle != NULL) - vvs.process_exit(vvs.vvs_handle); - if (vvs.lib_handle != NULL) - dlclose(vvs.lib_handle); -#endif - + } + free(stream); } static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs) { - struct sunxi_audio_device *adev = (struct sunxi_audio_device *)dev; - struct str_parms *parms; - char *str; - char value[32]; - int ret; + struct sunxi_audio_device *adev = (struct sunxi_audio_device *)dev; + struct str_parms *parms; + char *str; + char value[32]; + int ret; ALOGV("adev_set_parameters, %s", kvpairs); - parms = str_parms_create_str(kvpairs); - ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_TTY_MODE, value, sizeof(value)); - if (ret >= 0) { - int tty_mode; + parms = str_parms_create_str(kvpairs); + ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_TTY_MODE, value, sizeof(value)); + if (ret >= 0) { + int tty_mode; - if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_OFF) == 0) - tty_mode = TTY_MODE_OFF; - else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_VCO) == 0) - tty_mode = TTY_MODE_VCO; - else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_HCO) == 0) - tty_mode = TTY_MODE_HCO; - else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_FULL) == 0) - tty_mode = TTY_MODE_FULL; - else - return -EINVAL; + if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_OFF) == 0) + tty_mode = TTY_MODE_OFF; + else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_VCO) == 0) + tty_mode = TTY_MODE_VCO; + else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_HCO) == 0) + tty_mode = TTY_MODE_HCO; + else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_FULL) == 0) + tty_mode = TTY_MODE_FULL; + else + return -EINVAL; - pthread_mutex_lock(&adev->lock); - if (tty_mode != adev->tty_mode) { - adev->tty_mode = tty_mode; - if (adev->mode == AUDIO_MODE_IN_CALL || adev->mode == AUDIO_MODE_MODE_FACTORY_TEST || adev->mode == AUDIO_MODE_FM) { - select_device(adev); - adev_set_voice_volume(&adev->hw_device, adev->voice_volume); + pthread_mutex_lock(&adev->lock); + if (tty_mode != adev->tty_mode) { + adev->tty_mode = tty_mode; + if (adev->mode == AUDIO_MODE_IN_CALL || adev->mode == AUDIO_MODE_MODE_FACTORY_TEST || adev->mode == AUDIO_MODE_FM) { + select_device(adev); + adev_set_voice_volume(&adev->hw_device, adev->voice_volume); } - } - pthread_mutex_unlock(&adev->lock); - } + } + pthread_mutex_unlock(&adev->lock); + } - ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value)); - if (ret >= 0) { - if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0) - adev->bluetooth_nrec = true; - else - adev->bluetooth_nrec = false; - } + ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value)); + if (ret >= 0) { + if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0) + adev->bluetooth_nrec = true; + else + adev->bluetooth_nrec = false; + } - str_parms_destroy(parms); - return ret; + str_parms_destroy(parms); + return ret; } static char * adev_get_parameters(const struct audio_hw_device *dev, - const char *keys) + const char *keys) { - if (!strcmp(keys, "routing")) - { - char prop_value[512]; - int ret = property_get("audio.routing", prop_value, ""); - if (ret > 0) + if (!strcmp(keys, "routing")) { - return strdup(prop_value); + char prop_value[512]; + int ret = property_get("audio.routing", prop_value, ""); + if (ret > 0) { + return strdup(prop_value); + } } - } - return strdup(""); + return strdup(""); } static int adev_init_check(const struct audio_hw_device *dev) { - return 0; + return 0; } static int adev_set_voice_volume(struct audio_hw_device *dev, float volume) { - struct sunxi_audio_device *adev = (struct sunxi_audio_device *)dev; + struct sunxi_audio_device *adev = (struct sunxi_audio_device *)dev; ALOGV("adev_set_voice_volume, volume: %f", volume); @@ -2888,13 +2705,13 @@ static int adev_set_voice_volume(struct audio_hw_device *dev, float volume) if (volume_codec >= 10) { level = 5; - } else if (volume_codec >= 8){ + } else if (volume_codec >= 8) { level = 4; - } else if (volume_codec >= 6){ + } else if (volume_codec >= 6) { level = 3; - } else if (volume_codec >= 4){ + } else if (volume_codec >= 4) { level = 2; - } else if (volume_codec >= 2){ + } else if (volume_codec >= 2) { level = 1; } else { level = 0; @@ -2902,34 +2719,28 @@ static int adev_set_voice_volume(struct audio_hw_device *dev, float volume) ALOGD("adev_set_voice_volume, speaker_on: %d, earpiece_on: %d, headset_on: %d", speaker_on ,earpiece_on, headset_on); ALOGD("adev_set_voice_volume, volume:%d, level: %d", volume_codec, level); - #if 0 - int i=0; - for(i=0;i<=5;i++){ - ALOGD("\nadev->vol_array->speaker_spk_gain[level]:%d\n",adev->vol_array->speaker_spk_gain[i]); - ALOGD("\nadev->vol_array->earpiece_hp_gain[level]:%d\n",adev->vol_array->earpiece_hp_gain[i]); - ALOGD("\nadev->vol_array->headset_hp_gain[level]:%d\n",adev->vol_array->headset_hp_gain[i]); - } - #endif - if (speaker_on || (earpiece_on && (NO_EARPIECE == 1))){ + + if (speaker_on || (earpiece_on && (NO_EARPIECE == 1))) { mixer_ctl_set_value(adev->mixer_volumectls.spkvolume, 0, adev->vol_array->speaker_spk_gain[level]); ALOGD("adev_set_voice_volume, speaker volume:%d ", adev->vol_array->speaker_spk_gain[level]); - } else if (earpiece_on && (NO_EARPIECE == 0) ){ + } else if (earpiece_on && (NO_EARPIECE == 0) ) { mixer_ctl_set_value(adev->mixer_volumectls.earpiecevolume, 0, adev->vol_array->earpiece_hp_gain[level]); ALOGD("adev_set_voice_volume, earpiece volume:%d ", adev->vol_array->earpiece_hp_gain[level]); - } else if (headset_on || headphone_on){ + } else if (headset_on || headphone_on) { mixer_ctl_set_value(adev->mixer_volumectls.hpvolume, 0, adev->vol_array->headset_hp_gain[level]); ALOGD("adev_set_voice_volume, headset volume:%d ", adev->vol_array->headset_hp_gain[level]); } + set_bp_volume(adev,(int)(volume*100/10)); ALOGV("set phone debug,adev_set_voice_volume, volume: %f, intege of volume: %d", volume, (int)(volume*100/10)); } - return 0; + return 0; } static int adev_set_master_volume(struct audio_hw_device *dev, float volume) { F_LOG; - return -ENOSYS; + return -ENOSYS; } static int adev_get_master_volume(struct audio_hw_device *dev, float *volume) @@ -2940,113 +2751,113 @@ static int adev_get_master_volume(struct audio_hw_device *dev, float *volume) static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode) { - struct sunxi_audio_device *adev = (struct sunxi_audio_device *)dev; + struct sunxi_audio_device *adev = (struct sunxi_audio_device *)dev; - pthread_mutex_lock(&adev->lock); - if (adev->mode != mode) { - adev->mode = mode; - select_mode(adev); - } - pthread_mutex_unlock(&adev->lock); + pthread_mutex_lock(&adev->lock); + if (adev->mode != mode) { + adev->mode = mode; + select_mode(adev); + } + pthread_mutex_unlock(&adev->lock); - return 0; + return 0; } static int adev_set_mic_mute(struct audio_hw_device *dev, bool state) { - struct sunxi_audio_device *adev = (struct sunxi_audio_device *)dev; + struct sunxi_audio_device *adev = (struct sunxi_audio_device *)dev; - adev->mic_mute = state; + adev->mic_mute = state; - return 0; + return 0; } static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state) { - struct sunxi_audio_device *adev = (struct sunxi_audio_device *)dev; + struct sunxi_audio_device *adev = (struct sunxi_audio_device *)dev; - *state = adev->mic_mute; + *state = adev->mic_mute; - return 0; + return 0; } static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev, - const struct audio_config *config) + const struct audio_config *config) { - size_t size; - int channel_count = popcount(config->channel_mask); - if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0) - return 0; + size_t size; + int channel_count = popcount(config->channel_mask); + if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0) + return 0; - return get_input_buffer_size(config->sample_rate, config->format, channel_count); + return get_input_buffer_size(config->sample_rate, config->format, channel_count); } static int adev_open_input_stream(struct audio_hw_device *dev, - audio_io_handle_t handle, - audio_devices_t devices, - struct audio_config *config, - struct audio_stream_in **stream_in) + audio_io_handle_t handle, + audio_devices_t devices, + struct audio_config *config, + struct audio_stream_in **stream_in) { - struct sunxi_audio_device *ladev = (struct sunxi_audio_device *)dev; - struct sunxi_stream_in *in; - int ret; - int channel_count = popcount(config->channel_mask); + struct sunxi_audio_device *ladev = (struct sunxi_audio_device *)dev; + struct sunxi_stream_in *in; + int ret; + int channel_count = popcount(config->channel_mask); - *stream_in = NULL; + *stream_in = NULL; - if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0) - return -EINVAL; + if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0) + return -EINVAL; - in = (struct sunxi_stream_in *)calloc(1, sizeof(struct sunxi_stream_in)); - if (!in) - return -ENOMEM; + in = (struct sunxi_stream_in *)calloc(1, sizeof(struct sunxi_stream_in)); + if (!in) + return -ENOMEM; - in->stream.common.get_sample_rate = in_get_sample_rate; - in->stream.common.set_sample_rate = in_set_sample_rate; - in->stream.common.get_buffer_size = in_get_buffer_size; - in->stream.common.get_channels = in_get_channels; - in->stream.common.get_format = in_get_format; - in->stream.common.set_format = in_set_format; - in->stream.common.standby = in_standby; - in->stream.common.dump = in_dump; - in->stream.common.set_parameters = in_set_parameters; - in->stream.common.get_parameters = in_get_parameters; - in->stream.common.add_audio_effect = in_add_audio_effect; - in->stream.common.remove_audio_effect = in_remove_audio_effect; - in->stream.set_gain = in_set_gain; - in->stream.read = in_read; - in->stream.get_input_frames_lost = in_get_input_frames_lost; + in->stream.common.get_sample_rate = in_get_sample_rate; + in->stream.common.set_sample_rate = in_set_sample_rate; + in->stream.common.get_buffer_size = in_get_buffer_size; + in->stream.common.get_channels = in_get_channels; + in->stream.common.get_format = in_get_format; + in->stream.common.set_format = in_set_format; + in->stream.common.standby = in_standby; + in->stream.common.dump = in_dump; + in->stream.common.set_parameters = in_set_parameters; + in->stream.common.get_parameters = in_get_parameters; + in->stream.common.add_audio_effect = in_add_audio_effect; + in->stream.common.remove_audio_effect = in_remove_audio_effect; + in->stream.set_gain = in_set_gain; + in->stream.read = in_read; + in->stream.get_input_frames_lost = in_get_input_frames_lost; - in->requested_rate = config->sample_rate; + in->requested_rate = config->sample_rate; - // default config - memcpy(&in->config, &pcm_config_mm_in, sizeof(pcm_config_mm_in)); - in->config.channels = channel_count; - //in->config.in_init_channels = channel_count; + // default config + memcpy(&in->config, &pcm_config_mm_in, sizeof(pcm_config_mm_in)); + in->config.channels = channel_count; + //in->config.in_init_channels = channel_count; - ALOGV("to malloc in-buffer: period_size: %d, frame_size: %d", - in->config.period_size, audio_stream_frame_size(&in->stream.common)); - in->buffer = malloc(in->config.period_size * - audio_stream_frame_size(&in->stream.common) * 8); + ALOGV("to malloc in-buffer: period_size: %d, frame_size: %d", + in->config.period_size, audio_stream_frame_size(&in->stream.common)); + in->buffer = malloc(in->config.period_size * + audio_stream_frame_size(&in->stream.common) * 8); - if (!in->buffer) { - ret = -ENOMEM; - goto err; - } - memset(in->buffer, 0, in->config.period_size * - audio_stream_frame_size(&in->stream.common) * 8); //mute + if (!in->buffer) { + ret = -ENOMEM; + goto err; + } + memset(in->buffer, 0, in->config.period_size * + audio_stream_frame_size(&in->stream.common) * 8); //mute - ladev->af_capture_flag = false; - //devices = AUDIO_DEVICE_IN_WIFI_DISPLAY;//for test + ladev->af_capture_flag = false; + //devices = AUDIO_DEVICE_IN_WIFI_DISPLAY;//for test - if (devices == AUDIO_DEVICE_IN_AF) { + if (devices == AUDIO_DEVICE_IN_AF) { ALOGV("to malloc PcmManagerBuffer: Buffer_size: %d", AF_BUFFER_SIZE); ladev->PcmManager.BufStart= (unsigned char *)malloc(AF_BUFFER_SIZE); if(!ladev->PcmManager.BufStart) { ret = -ENOMEM; goto err; - } + } ladev->PcmManager.BufExist = true; ladev->PcmManager.BufTotalLen = AF_BUFFER_SIZE; @@ -3059,54 +2870,54 @@ static int adev_open_input_stream(struct audio_hw_device *dev, ladev->af_capture_flag = true; ladev->PcmManager.dev = (struct sunxi_audio_device *)ladev; - } + } - in->dev = ladev; - in->standby = 1; - in->device = devices & ~AUDIO_DEVICE_BIT_IN; + in->dev = ladev; + in->standby = 1; + in->device = devices & ~AUDIO_DEVICE_BIT_IN; - *stream_in = &in->stream; - return 0; + *stream_in = &in->stream; + return 0; err: - if (in->resampler) - release_resampler(in->resampler); + if (in->resampler) + release_resampler(in->resampler); - free(in); - return ret; + free(in); + return ret; } static void adev_close_input_stream(struct audio_hw_device *dev, - struct audio_stream_in *stream) + struct audio_stream_in *stream) { - struct sunxi_stream_in *in = (struct sunxi_stream_in *)stream; - struct sunxi_audio_device *ladev = (struct sunxi_audio_device *)dev; + struct sunxi_stream_in *in = (struct sunxi_stream_in *)stream; + struct sunxi_audio_device *ladev = (struct sunxi_audio_device *)dev; - in_standby(&stream->common); + in_standby(&stream->common); - if (in->buffer) { - free(in->buffer); - in->buffer = 0; - } - if (in->resampler) { - release_resampler(in->resampler); - in->resampler = 0; - } - if (ladev->af_capture_flag) { - ladev->af_capture_flag = false; - } - if (ladev->PcmManager.BufStart) { - ladev->PcmManager.BufExist = false; - free(ladev->PcmManager.BufStart); - ladev->PcmManager.BufStart = 0; - } - free(stream); + if (in->buffer) { + free(in->buffer); + in->buffer = 0; + } + if (in->resampler) { + release_resampler(in->resampler); + in->resampler = 0; + } + if (ladev->af_capture_flag) { + ladev->af_capture_flag = false; + } + if (ladev->PcmManager.BufStart) { + ladev->PcmManager.BufExist = false; + free(ladev->PcmManager.BufStart); + ladev->PcmManager.BufStart = 0; + } + free(stream); - normal_record_enable(false); - fm_record_enable(false); - phone_record_enable(false); - ALOGD("adev_close_input_stream set voice record status"); - return; + normal_record_enable(false); + fm_record_enable(false); + phone_record_enable(false); + ALOGD("adev_close_input_stream set voice record status"); + return; } static int adev_dump(const audio_hw_device_t *device, int fd) @@ -3117,6 +2928,11 @@ static int adev_dump(const audio_hw_device_t *device, int fd) static int adev_close(hw_device_t *device) { struct sunxi_audio_device *adev = (struct sunxi_audio_device *)device; + +#if USE_3D_SURROUND + surround_exit(&sur); +#endif + audio_route_free(adev->ar); free(adev->vol_array); free(device); @@ -3131,10 +2947,8 @@ static int case_init(void) char usename[PROPERTY_VALUE_MAX]={0}; ret = property_get("audio.without.earpiece", prop_value, "1"); - if (ret > 0) - { - if (atoi(prop_value) == 0) - { + if (ret > 0) { + if (atoi(prop_value) == 0) { NO_EARPIECE = 0; ALOGD("get property audio.without.earpiece: %d", NO_EARPIECE); } @@ -3143,53 +2957,56 @@ static int case_init(void) ALOGV("****LINE:%d,FUNC:%s, ret:%d",__LINE__,__FUNCTION__, ret); ret = property_get("ro.dmic.used", usename, "0"); - if(ret <= 0){ + if (ret <= 0) { ALOGE("wrn: get ro.dmic.used failed"); } - if(!strcmp(usename, "true")) { + if (!strcmp(usename, "true")) { dmic_used = true; - }else{ + } else { dmic_used = false; } + ret = property_get("ro.spk_dul.used", usename, "0"); - if(ret <= 0){ + if (ret <= 0) { ALOGE("wrn: get ro.dmic.used failed"); } - if(!strcmp(usename, "true")) { + if (!strcmp(usename, "true")) { spk_dul_used = true; - }else{ + } else { spk_dul_used = false; } + ret = property_get("ro.sw.audio.codec_plan_name", device_name, "0"); - if(ret <= 0){ + if (ret <= 0) { ALOGE("wrn: get ro.sw.audio.codec_plan_name failed"); } ALOGD("PROPERTY_VALUE_MAX:%d,get ro.sw.audio.codec_plan_name =%s", PROPERTY_VALUE_MAX, device_name); - if (strstr(device_name, "PLAN_ONE") != NULL){ + if (strstr(device_name, "PLAN_ONE") != NULL) { /*case:plan_one*/ CASE_NAME = 1; - }else if (strstr(device_name, "PLAN_TWO") != NULL){ + } else if (strstr(device_name, "PLAN_TWO") != NULL) { /*case:plan_two*/ CASE_NAME = 2; - } else { - /*case:pad*/ + } else { + /*case:pad*/ CASE_NAME = 0; } return ret; } + static int adev_open(const hw_module_t* module, const char* name, - hw_device_t** device) + hw_device_t** device) { struct sunxi_audio_device *adev; int ret; if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) - return -EINVAL; + return -EINVAL; adev = calloc(1, sizeof(struct sunxi_audio_device)); if (!adev) - return -ENOMEM; + return -ENOMEM; adev->hw_device.common.tag = HARDWARE_DEVICE_TAG; adev->hw_device.common.version = AUDIO_DEVICE_API_VERSION_2_0; adev->hw_device.common.module = (struct hw_module_t *) module; @@ -3197,8 +3014,8 @@ static int adev_open(const hw_module_t* module, const char* name, adev->hw_device.init_check = adev_init_check; adev->hw_device.set_voice_volume = adev_set_voice_volume; -// adev->hw_device.set_master_volume = adev_set_master_volume; -// adev->hw_device.get_master_volume = adev_get_master_volume; + // adev->hw_device.set_master_volume = adev_set_master_volume; + // adev->hw_device.get_master_volume = adev_get_master_volume; adev->hw_device.set_mode = adev_set_mode; adev->hw_device.set_mic_mute = adev_set_mic_mute; adev->hw_device.get_mic_mute = adev_get_mic_mute; @@ -3233,11 +3050,11 @@ static int adev_open(const hw_module_t* module, const char* name, } /*volume ctl*/ adev->mixer_volumectls.hpvolume = mixer_get_ctl_by_name(adev->mixer, - MIXER_HP_VOLUME); + MIXER_HP_VOLUME); adev->mixer_volumectls.spkvolume = mixer_get_ctl_by_name(adev->mixer, - MIXER_SPK_VOLUME); + MIXER_SPK_VOLUME); adev->mixer_volumectls.earpiecevolume = mixer_get_ctl_by_name(adev->mixer, - MIXER_EARPIECE_VOLUME); + MIXER_EARPIECE_VOLUME); pthread_mutex_unlock(&adev->lock); *device = &adev->hw_device.common; adev->vol_array = calloc(1, sizeof(struct volume_array)); @@ -3248,6 +3065,10 @@ static int adev_open(const hw_module_t* module, const char* name, } case_init(); +#if USE_3D_SURROUND + surround_init(&sur, MM_SAMPLING_RATE, 2, SHORT_PERIOD_SIZE); +#endif + return 0; error_out: @@ -3256,17 +3077,17 @@ error_out: } static struct hw_module_methods_t hal_module_methods = { - .open = adev_open, + .open = adev_open, }; struct audio_module HAL_MODULE_INFO_SYM = { - .common = { - .tag = HARDWARE_MODULE_TAG, - .module_api_version = AUDIO_MODULE_API_VERSION_0_1, + .common = { + .tag = HARDWARE_MODULE_TAG, + .module_api_version = AUDIO_MODULE_API_VERSION_0_1, .hal_api_version = HARDWARE_HAL_API_VERSION, - .id = AUDIO_HARDWARE_MODULE_ID, - .name = "sunxi audio HW HAL", - .author = "author", - .methods = &hal_module_methods, - }, + .id = AUDIO_HARDWARE_MODULE_ID, + .name = "sunxi audio HW HAL", + .author = "author", + .methods = &hal_module_methods, + }, }; diff --git a/audio/tulip/audio_policy.conf b/audio/tulip/audio_policy.conf index c1ce9e7..f20d248 100755 --- a/audio/tulip/audio_policy.conf +++ b/audio/tulip/audio_policy.conf @@ -39,8 +39,8 @@ audio_hw_modules { } inputs { primary { - sampling_rates 8000|11025|16000|22050|24000|32000|44100|48000 - channel_masks AUDIO_CHANNEL_IN_MONO|AUDIO_CHANNEL_IN_STEREO|AUDIO_CHANNEL_IN_VOICE_UPLINK|AUDIO_CHANNEL_IN_VOICE_DNLINK|AUDIO_CHANNEL_IN_VOICE + sampling_rates 44100 + channel_masks AUDIO_CHANNEL_IN_STEREO formats AUDIO_FORMAT_PCM_16_BIT devices AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET|AUDIO_DEVICE_IN_WIRED_HEADSET|AUDIO_DEVICE_IN_BACK_MIC|AUDIO_DEVICE_IN_AF|AUDIO_DEVICE_IN_VOICE_CALL|AUDIO_DEVICE_IN_FM } @@ -75,7 +75,7 @@ audio_hw_modules { usb_device { sampling_rates dynamic channel_masks AUDIO_CHANNEL_IN_STEREO - formats AUDIO_FORMAT_PCM_16_BIT + formats AUDIO_FORMAT_PCM_24_BIT_PACKED devices AUDIO_DEVICE_IN_USB_DEVICE } } diff --git a/audio/tulip/libcodec_audio/volume_conf.c b/audio/tulip/libcodec_audio/volume_conf.c index f548747..94139a4 100755 --- a/audio/tulip/libcodec_audio/volume_conf.c +++ b/audio/tulip/libcodec_audio/volume_conf.c @@ -1,6 +1,7 @@ #include #include #include +#include #define LOG_TAG "codec_audio" #define LOG_NDEBUG 0 diff --git a/client-api/Android.mk b/client-api/Android.mk index 1f07ecf..44fd01b 100755 --- a/client-api/Android.mk +++ b/client-api/Android.mk @@ -1,6 +1,8 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) +ifeq ($(SECURE_OS_OPTEE), no) + LOCAL_SRC_FILES:= \ sunxi_tee_api.c @@ -29,3 +31,5 @@ LOCAL_MODULE_TAGS := optional LOCAL_MODULE:= test_api #include $(BUILD_EXECUTABLE) + +endif diff --git a/client-api/sunxi_tee_api.c b/client-api/sunxi_tee_api.c index d38dbf0..2520628 100755 --- a/client-api/sunxi_tee_api.c +++ b/client-api/sunxi_tee_api.c @@ -48,6 +48,7 @@ TEEC_Result TEEC_InitializeContext(const char* name, TEEC_Context* context) { context->fd = ret; context->session_count = 0; context->shared_mem_cnt = 0; + context->nSessionNum = 0; INIT_LIST_HEAD(&context->shared_mem_list); } return TEEC_SUCCESS; @@ -325,7 +326,7 @@ TEEC_Result TEEC_InvokeCommand( (param_types[param_count] == TEEC_MEMREF_PARTIAL_INPUT) || (param_types[param_count] == TEEC_MEMREF_PARTIAL_INOUT) || (param_types[param_count] == TEEC_MEMREF_PARTIAL_OUTPUT)) { - + //* check the info if(!operation->params[param_count].memref.parent) { if(returnOrigin){ *returnOrigin = TEEC_ORIGIN_API; @@ -393,41 +394,44 @@ TEEC_Result TEEC_InvokeCommand( break; } } + //* assign sunxi_tee_param from operation->param if (param_types[param_count] == TEEC_MEMREF_PARTIAL_INPUT) { sunxi_tee_param[param_count].type = TE_PARAM_TYPE_MEM_RO; - sunxi_tee_param[param_count].u.Mem.base = (void*) ((uint32_t)operation->params[param_count].memref.parent->buffer + + sunxi_tee_param[param_count].u.Mem.base = (void*) ((uintptr_t)operation->params[param_count].memref.parent->buffer + (uint32_t)operation->params[param_count].memref.offset); sunxi_tee_param[param_count].u.Mem.len = operation->params[param_count].memref.parent->size; - sunxi_tee_param[param_count].index = (uint32_t)operation->params[param_count].memref.parent->buffer; + sunxi_tee_param[param_count].index = (uintptr_t)operation->params[param_count].memref.parent->buffer; }else if((param_types[param_count] == TEEC_MEMREF_PARTIAL_OUTPUT) || (param_types[param_count] == TEEC_MEMREF_PARTIAL_INOUT)){ sunxi_tee_param[param_count].type = TE_PARAM_TYPE_MEM_RW; - sunxi_tee_param[param_count].u.Mem.base = (void*) ((uint32_t)operation->params[param_count].memref.parent->buffer + + sunxi_tee_param[param_count].u.Mem.base = (void*) ((uintptr_t)operation->params[param_count].memref.parent->buffer + (uint32_t)operation->params[param_count].memref.offset); sunxi_tee_param[param_count].u.Mem.len = operation->params[param_count].memref.parent->size; - sunxi_tee_param[param_count].index = (uint32_t)operation->params[param_count].memref.parent->buffer; + sunxi_tee_param[param_count].index = (uintptr_t)operation->params[param_count].memref.parent->buffer; }else if((param_types[param_count] == TEEC_MEMREF_WHOLE)){ if(operation->params[param_count].memref.parent->flags == TEEC_MEM_INPUT){ sunxi_tee_param[param_count].type = TE_PARAM_TYPE_MEM_RO; - sunxi_tee_param[param_count].u.Mem.base = (void*) ((uint32_t)operation->params[param_count].memref.parent->buffer); + sunxi_tee_param[param_count].u.Mem.base = (void*) ((uintptr_t)operation->params[param_count].memref.parent->buffer); sunxi_tee_param[param_count].u.Mem.len = operation->params[param_count].memref.parent->size; - sunxi_tee_param[param_count].index = (uint32_t)operation->params[param_count].memref.parent->buffer; + sunxi_tee_param[param_count].index = (uintptr_t)operation->params[param_count].memref.parent->buffer; } if((operation->params[param_count].memref.parent->flags == TEEC_MEM_OUTPUT) || (operation->params[param_count].memref.parent->flags == (TEEC_MEM_INPUT|TEEC_MEM_OUTPUT ))){ sunxi_tee_param[param_count].type = TE_PARAM_TYPE_MEM_RW; - sunxi_tee_param[param_count].u.Mem.base = (void*) ((uint32_t)operation->params[param_count].memref.parent->buffer); + sunxi_tee_param[param_count].u.Mem.base = (void*) ((uintptr_t)operation->params[param_count].memref.parent->buffer); sunxi_tee_param[param_count].u.Mem.len = operation->params[param_count].memref.parent->size; - sunxi_tee_param[param_count].index = (uint32_t)operation->params[param_count].memref.parent->buffer; + sunxi_tee_param[param_count].index = (uintptr_t)operation->params[param_count].memref.parent->buffer; } } }else if(param_types[param_count] == TEEC_NONE){ sunxi_tee_param[param_count].type = TE_PARAM_TYPE_NONE; } } + + //* set sunxi_tee_param to cmd for (param_count = 0; param_count < 4; param_count++) { if (cmd->launchop.operation.list_count == 0) { cmd->launchop.operation.list_head = sunxi_tee_param + param_count; diff --git a/client-api/sunxi_tee_api.h b/client-api/sunxi_tee_api.h index 6965a0b..d4f5c2a 100755 --- a/client-api/sunxi_tee_api.h +++ b/client-api/sunxi_tee_api.h @@ -237,6 +237,8 @@ struct TEEC_Context struct list shared_mem_list; /*! Error number from the client driver */ int s_errno; + + int nSessionNum; }; diff --git a/hwc/octopus/hwc.cpp b/hwc/octopus/hwc.cpp index d426f79..fb41dcf 100755 --- a/hwc/octopus/hwc.cpp +++ b/hwc/octopus/hwc.cpp @@ -54,6 +54,11 @@ static int hwc_blank(struct hwc_composer_device_1* dev, int disp, int blank) HWC_UNREFERENCED_PARAMETER(blank); SUNXI_hwcdev_context_t *Globctx = &gSunxiHwcDevice; + if(!blank) + { + Globctx->unblank_flag = 1; + return 0; + } unsigned long arg[4]={0}; DisplayInfo *PsDisplayInfo = &Globctx->SunxiDisplay[disp]; if(PsDisplayInfo->VirtualToHWDisplay != -EINVAL) diff --git a/hwc/octopus/hwc.h b/hwc/octopus/hwc.h index 14d921b..16b0a27 100755 --- a/hwc/octopus/hwc.h +++ b/hwc/octopus/hwc.h @@ -174,6 +174,7 @@ typedef struct { int share_fd;//ion_handle share_fd int size_buffer; bool valid; + bool is_secure; }hwc_cache_t; typedef struct { @@ -191,6 +192,7 @@ typedef struct { int share_fd; bool needsync;//for sw_write bool iscursor; + bool is_secure; disp_layer_config hwc_layer_info; }hwc_commit_layer_t; @@ -255,6 +257,7 @@ typedef struct layer_info { bool is3D; bool is_cursor; bool need_sync; + bool is_secure; int shared_fd; AssignDUETO_T info; hwc_layer_1_t *psLayer; @@ -407,7 +410,7 @@ typedef struct mutable android::Condition CommitCondition; hwc_commit_layer_t cursor_rotate_layer[VIDEO_ROTATE_COUNT];// 0 is 90, 1 is 180,2 is 270; - + int unblank_flag; }SUNXI_hwcdev_context_t; typedef struct diff --git a/hwc/octopus/hwc_commit.cpp b/hwc/octopus/hwc_commit.cpp index 2b3f1b2..f445364 100755 --- a/hwc/octopus/hwc_commit.cpp +++ b/hwc/octopus/hwc_commit.cpp @@ -333,6 +333,7 @@ void *commit_thread(void *priv) hwc_dispc_data_t *DisplayData = NULL; int i = 0, j = 0, ret = -1, lyr = 0, rotatecall = 0; int primary_disp = 0, video_fence_fd = -1, share_fd = -1; + int unblank_count = 0; unsigned long arg[4] = {0}; unsigned int current_sync_count = 0, cusor_sync = 0; hwc_ioctl_arg hwc_cmd; @@ -498,6 +499,28 @@ deal_fence: arg[0] = 0; arg[1] = (unsigned long)(&hwc_cmd); ret = ioctl(Globctx->DisplayFd, DISP_HWC_COMMIT, (unsigned long)arg); + + if(Globctx->unblank_flag) + { + if(unblank_count == 3) + { + unsigned long arg[4]={0}; + DisplayInfo *PsDisplayInfo = &Globctx->SunxiDisplay[DisplayData->first_disp]; + + if(PsDisplayInfo->VirtualToHWDisplay != -EINVAL) + { + arg[0] = PsDisplayInfo->VirtualToHWDisplay; + arg[1] = 0; + if(ioctl(Globctx->DisplayFd, DISP_BLANK, (unsigned long)arg) != 0) + ALOGE("##########unblank error!"); + } + + Globctx->unblank_flag = 0; + unblank_count = 0; + } + + unblank_count++; + } /* check wb and display to HDMI or miracast */ /* update cursor disp data */ diff --git a/hwc/octopus/hwc_rotate.cpp b/hwc/octopus/hwc_rotate.cpp index 694748c..03099bb 100755 --- a/hwc/octopus/hwc_rotate.cpp +++ b/hwc/octopus/hwc_rotate.cpp @@ -98,7 +98,7 @@ int culate_timeout(disp_rectsz disp_src) return 32; } -static hwc_cache_t *hwc_video_cache_get(int size, int fd, unsigned int sync_count) +static hwc_cache_t *hwc_video_cache_get(int size, int fd, unsigned int sync_count, bool is_secure) { SUNXI_hwcdev_context_t *Globctx = &gSunxiHwcDevice; hwc_cache_t *wb_cache = NULL; @@ -130,7 +130,7 @@ static hwc_cache_t *hwc_video_cache_get(int size, int fd, unsigned int sync_coun close(wb_cache->fd); wb_cache->fd = -1; } - if(wb_cache->share_fd >= 0 && size < wb_cache->size_buffer) + if(wb_cache->share_fd >= 0 && size < wb_cache->size_buffer && wb_cache->is_secure == is_secure) { if(wb_cache->size_buffer - size > 4096) { @@ -148,23 +148,38 @@ static hwc_cache_t *hwc_video_cache_get(int size, int fd, unsigned int sync_coun } if(wb_cache->share_fd == -1 || wb_cache->size_buffer == 0) { - ret = ion_alloc_fd(Globctx->IonFd, size, - 4096, ION_HEAP_TYPE_DMA_MASK, 0, &wb_cache->share_fd); - if(ret < 0) + if(is_secure) { - ALOGD("alloc err from ION_HEAP_CARVEOUT_MASK"); - ret = ion_alloc_fd(Globctx->IonFd, size, - 4096, ION_HEAP_SYSTEM_CONTIG_MASK, 0, &wb_cache->share_fd); + ret = ion_alloc_fd(Globctx->IonFd, size, + 4096, ION_HEAP_SECURE_MASK, 0, &wb_cache->share_fd); if(ret < 0) { - ALOGD("alloc err from ION_HEAP_SYSTEM_CONTIG_MASK"); - wb_cache->share_fd = -1; - wb_cache->size_buffer = 0; - return NULL; + ALOGD("alloc err from ION_HEAP_SECURE_MASK"); + return NULL; + } + wb_cache->is_secure = 1; + }else{ + ret = ion_alloc_fd(Globctx->IonFd, size, + 4096, ION_HEAP_TYPE_DMA_MASK, 0, &wb_cache->share_fd); + if(ret < 0) + { + ALOGD("alloc err from ION_HEAP_CARVEOUT_MASK"); + ret = ion_alloc_fd(Globctx->IonFd, size, + 4096, ION_HEAP_SYSTEM_CONTIG_MASK, 0, &wb_cache->share_fd); + if(ret < 0) + { + ALOGD("alloc err from ION_HEAP_SYSTEM_CONTIG_MASK"); + wb_cache->share_fd = -1; + wb_cache->size_buffer = 0; + return NULL; + } } } - ion_sync_fd(Globctx->IonFd, wb_cache->share_fd); - wb_cache->size_buffer = size; + if(!is_secure) + { + ion_sync_fd(Globctx->IonFd, wb_cache->share_fd); + } + wb_cache->size_buffer = size; } wb_cache->sync_cnt = sync_count; wb_cache->valid = 0; @@ -520,7 +535,7 @@ bool hwc_rotate_layer_video(hwc_dispc_data_t *hwc_layer, hwc_rotate_settimeout(ret); Globctx->tr_time_out = ret; } - wb_cache = hwc_video_cache_get(size, commit_data->releasefencefd[disp], hwc_layer->sync_count); + wb_cache = hwc_video_cache_get(size, commit_data->releasefencefd[disp], hwc_layer->sync_count, commit_layer->is_secure); if(wb_cache != NULL) { memset(&tr_info, 0, sizeof(tr_info)); diff --git a/hwc/octopus/hwc_sunxi.cpp b/hwc/octopus/hwc_sunxi.cpp index 9076d15..b1379cc 100755 --- a/hwc/octopus/hwc_sunxi.cpp +++ b/hwc/octopus/hwc_sunxi.cpp @@ -443,8 +443,8 @@ static inline int check_valid_format(int format) case HAL_PIXEL_FORMAT_RGB_888: case HAL_PIXEL_FORMAT_RGB_565: case HAL_PIXEL_FORMAT_BGRA_8888: - case HAL_PIXEL_FORMAT_sRGB_A_8888: - case HAL_PIXEL_FORMAT_sRGB_X_8888: + // case HAL_PIXEL_FORMAT_sRGB_A_8888: + // case HAL_PIXEL_FORMAT_sRGB_X_8888: case HAL_PIXEL_FORMAT_YV12: case HAL_PIXEL_FORMAT_YCrCb_420_SP: case HAL_PIXEL_FORMAT_BGRX_8888: @@ -520,8 +520,8 @@ static inline bool check_support_blending(int format) case HAL_PIXEL_FORMAT_RGB_888: case HAL_PIXEL_FORMAT_RGB_565: case HAL_PIXEL_FORMAT_BGRA_8888: - case HAL_PIXEL_FORMAT_sRGB_A_8888: - case HAL_PIXEL_FORMAT_sRGB_X_8888: + // case HAL_PIXEL_FORMAT_sRGB_A_8888: + // case HAL_PIXEL_FORMAT_sRGB_X_8888: case HAL_PIXEL_FORMAT_BGRX_8888: return 1; default: @@ -764,7 +764,7 @@ static int hwc_can_scale(HwcDisContext_t *Localctx, hwc_layer_1_t *psLayer, bool { vsyncPeroid /= 2; } - de_freq = 504000000; + de_freq = 254000000; lcd_line_peroid = vsyncPeroid / lcd_h; layer_line_peroid = (src_w > dst_w) ? (1000000*((long long)(lcd_w - dst_w + src_w))/(de_freq/1000)) @@ -1395,7 +1395,7 @@ ret_ok: HwcAssignStatus hwc_try_assign_layer(HwcDisContext_t *Localctx, size_t singcout, int zOrder) { - bool needchannel = 1, isvideo = 0, isalpha = 0, isFB = 0; + bool needchannel = 1, isvideo = 0, isalpha = 0, isFB = 0, issecure = 0; bool is3D = 0, need_sync = 0, is_cursor = 0; float WscalFac = 1.0, HscaleFac = 1.0; int CH= -1, tmCnt1 = 0, tmCnt2 = 0, addLayerCnt = 1; @@ -1444,13 +1444,18 @@ HwcAssignStatus hwc_try_assign_layer(HwcDisContext_t *Localctx, size_t singcout, goto assign_gpu; } - if(check_usage_protected(handle) && !PsDisplayInfo->issecure) + if(check_usage_protected(handle)) { - ALOGV("%s:Video Protected", __func__); - dueto = D_VIDEO_PD; - goto assign_gpu; + if(!PsDisplayInfo->issecure) + { + ALOGV("%s:Video Protected", __func__); + dueto = D_VIDEO_PD; + goto assign_gpu; + }else{ + issecure = 1; + } } - + dueto = check_valid_layer(psLayer, is_cursor); if(dueto != I_OVERLAY) { @@ -1643,8 +1648,9 @@ assign_overlay: Localctx->psAllLayer[singcout].is3D = is3D; Localctx->psAllLayer[singcout].info = dueto; Localctx->psAllLayer[singcout].isvideo= isvideo; - Localctx->psAllLayer[singcout].need_sync = need_sync; - Localctx->psAllLayer[singcout].is_cursor= is_cursor; + Localctx->psAllLayer[singcout].need_sync = issecure?0:need_sync; + Localctx->psAllLayer[singcout].is_cursor = is_cursor; + Localctx->psAllLayer[singcout].is_secure = issecure; if(is_cursor) { return ASSIGN_CURSOR; @@ -1734,6 +1740,7 @@ int hwc_setup_layer(hwc_dispc_data_t *DisplayData, HwcDisContext_t *Localctx) } hw_layer_config->needsync = psHwlayer_info->need_sync; hw_layer_config->share_fd = dup(psHwlayer_info->shared_fd); + hw_layer_config->is_secure = psHwlayer_info->is_secure; if(check_is_blending(psLayer)) { layer_info->alpha_mode = 2; @@ -2054,6 +2061,9 @@ deal_fence: && PsDisplayInfo->VirtualToHWDisplay >= 0) { releasefecefd = returnfenceFd[ture_disp]; + }else{ + ALOGW("has plugout the disp[%d]",disp); + continue; } for(i = 0; i < psDisplay->numHwLayers; i++) { @@ -2378,7 +2388,7 @@ SUNXI_hwcdev_context_t* hwc_create_device(void) ALOGD("###open /sys/class/disp/disp/attr/runtime_enable fail"); } - open_fd = open("/sys/devices/platform/sunxi-ddrfreq/devfreq/sunxi-ddrfreq/max_freq", O_RDONLY); + open_fd = open("/sys/class/devfreq/sunxi-ddrfreq/max_freq", O_RDONLY); if(open_fd >= 0) { char val_ddr[10] = {0x0,}; @@ -2427,6 +2437,7 @@ SUNXI_hwcdev_context_t* hwc_create_device(void) Globctx->uiBeginFrame = 0; Globctx->hwcdebug = 0; Globctx->stop_rotate_hw = 0; + Globctx->unblank_flag = 0; Globctx->ManageLock = PTHREAD_MUTEX_INITIALIZER; Globctx->AbandonLock = PTHREAD_MUTEX_INITIALIZER; Globctx->HeadLock = PTHREAD_MUTEX_INITIALIZER; diff --git a/hwc/tulip/hwc.h b/hwc/tulip/hwc.h index c6de427..d4cd127 100755 --- a/hwc/tulip/hwc.h +++ b/hwc/tulip/hwc.h @@ -185,6 +185,7 @@ typedef struct { int share_fd;//ion_handle share_fd int size_buffer; bool valid; + bool is_secure; }hwc_cache_t; typedef struct { @@ -207,6 +208,7 @@ typedef struct { int share_fd; bool needsync;//for sw_write bool iscursor; + bool is_secure; disp_layer_config hwc_layer_info; }hwc_commit_layer_t; @@ -286,6 +288,7 @@ typedef struct layer_info { bool is3D; bool is_cursor; bool need_sync; + bool is_secure; int shared_fd; format_info form_info; AssignDUETO_T info; @@ -312,7 +315,6 @@ typedef struct{ bool VsyncEnable; bool issecure; bool active; - bool setblank; int HwChannelNum; int LayerNumofCH; @@ -460,6 +462,7 @@ typedef struct int fb_pre_mem; /* end mem limit */ int unblank_flag; + unsigned char has_secure; }SUNXI_hwcdev_context_t; @@ -603,8 +606,8 @@ static inline int check_valid_format(int format) //case HAL_PIXEL_FORMAT_RGB_888: case HAL_PIXEL_FORMAT_RGB_565: case HAL_PIXEL_FORMAT_BGRA_8888: - case HAL_PIXEL_FORMAT_sRGB_A_8888: - case HAL_PIXEL_FORMAT_sRGB_X_8888: + //case HAL_PIXEL_FORMAT_sRGB_A_8888: + //case HAL_PIXEL_FORMAT_sRGB_X_8888: case HAL_PIXEL_FORMAT_YV12: case HAL_PIXEL_FORMAT_YCrCb_420_SP: case HAL_PIXEL_FORMAT_BGRX_8888: @@ -690,8 +693,8 @@ static inline bool check_support_blending(int format) case HAL_PIXEL_FORMAT_RGB_888: case HAL_PIXEL_FORMAT_RGB_565: case HAL_PIXEL_FORMAT_BGRA_8888: - case HAL_PIXEL_FORMAT_sRGB_A_8888: - case HAL_PIXEL_FORMAT_sRGB_X_8888: + //case HAL_PIXEL_FORMAT_sRGB_A_8888: + //case HAL_PIXEL_FORMAT_sRGB_X_8888: case HAL_PIXEL_FORMAT_BGRX_8888: return 1; default: diff --git a/hwc/tulip/hwc_ion.cpp b/hwc/tulip/hwc_ion.cpp index a8b0085..04bd0c5 100755 --- a/hwc/tulip/hwc_ion.cpp +++ b/hwc/tulip/hwc_ion.cpp @@ -17,6 +17,13 @@ #include "hwc.h" +typedef struct { + ion_user_handle_t handle; + unsigned int phys_addr; + unsigned int size; +}sunxi_phys_data; +#define ION_IOC_SUNXI_PHYS_ADDR 7 + ion_user_handle_t ion_alloc_buffer(int iAllocBytes, unsigned int heap_mask) { SUNXI_hwcdev_context_t *Globctx = &gSunxiHwcDevice; @@ -36,7 +43,7 @@ ion_user_handle_t ion_alloc_buffer(int iAllocBytes, unsigned int heap_mask) ALOGW("%s: ION_IOC_ALLOC failed (ret=%d)", __func__, ret); return (ion_user_handle_t) -1; } - + return sAllocInfo.handle; } @@ -64,7 +71,7 @@ unsigned int ion_get_addr_fromfd(int sharefd) sunxi_phys_data phys_data; ion_handle_data freedata; struct ion_fd_data data ; - + data.fd = sharefd; ret = ioctl(Globctx->IonFd, ION_IOC_IMPORT, &data); if (ret < 0) @@ -88,7 +95,7 @@ unsigned int ion_get_addr_fromfd(int sharefd) ALOGE("%s: ION_IOC_FREE failed(ret=%d)", __func__, ret); return 0; } - return phys_data.phys_addr; + return phys_data.phys_addr; } unsigned long ion_get_addr_from_handle(ion_user_handle_t handle) @@ -122,7 +129,7 @@ ion_user_handle_t ion_handle_add_ref(int sharefd) ALOGE("%s: ION_IOC_IMPORT failed(ret=%d)", __func__, ret); return -1; } - return data.handle; + return data.handle; } void ion_handle_dec_ref(ion_user_handle_t handle_id) @@ -180,7 +187,7 @@ void ion_free_cache(hwc_ion_hold_t *ion_cache) bool hwc_manage_ref_cache(bool cache, hwc_dispc_data_t *dispc_data) { hwc_ion_hold_t *ion_cache = NULL; - int i, little_sync, cnt = 0, size = 0; + int i, little_sync, cnt = 0, size = 0; hwc_commit_layer_t *commit_layer = NULL; int *_array = NULL; @@ -237,8 +244,7 @@ bool hwc_manage_ref_cache(bool cache, hwc_dispc_data_t *dispc_data) } ion_cache->num_used = size; ion_cache->sync_count = dispc_data->sync_count; - + manage_ok: return 1; } - diff --git a/hwc/tulip/hwc_mem_ctrl.cpp b/hwc/tulip/hwc_mem_ctrl.cpp index 16e20b9..67c79ff 100755 --- a/hwc/tulip/hwc_mem_ctrl.cpp +++ b/hwc/tulip/hwc_mem_ctrl.cpp @@ -144,6 +144,11 @@ void hwc_down_limit(SUNXI_hwcdev_context_t *Globctx, int local_mem[NUMBEROFDISPL { HWC_UNREFERENCED_PARAMETER(local_mem); int i = 0, tmp_mem_thruput0 = 0; + if(Globctx->has_secure != 0) + { + Globctx->memlimit = Globctx->max_mem_limit; + return; + } if(Globctx->ForceGPUComp[0] == 0 && Globctx->CanForceGPUCom && force_gpu) { if(Globctx->psHwcProcs != NULL diff --git a/hwc/tulip/hwc_others.cpp b/hwc/tulip/hwc_others.cpp index 6f0a792..7c7b178 100755 --- a/hwc/tulip/hwc_others.cpp +++ b/hwc/tulip/hwc_others.cpp @@ -129,8 +129,6 @@ int _hwc_device_set_enhancemode(int disp, bool on_off, bool half) int _hwc_device_set_output_mode(int disp, int out_type, int out_mode) { SUNXI_hwcdev_context_t *Globctx = &gSunxiHwcDevice; - if(Globctx->SunxiDisplay[0].DisplayType == DISP_OUTPUT_TYPE_HDMI) - disp = 0; DisplayInfo *PsDisplayInfo = &Globctx->SunxiDisplay[disp]; int disp_t; @@ -149,8 +147,6 @@ int _hwc_set_persent(int disp,int para0, int para1) { SUNXI_hwcdev_context_t *Globctx = &gSunxiHwcDevice; DisplayInfo *PsDisplayInfo = NULL; - if(Globctx->SunxiDisplay[0].DisplayType == DISP_OUTPUT_TYPE_HDMI) - disp = 0; PsDisplayInfo = &Globctx->SunxiDisplay[disp]; if(PsDisplayInfo->VirtualToHWDisplay != -1 && PsDisplayInfo->DisplayType == DISP_OUTPUT_TYPE_HDMI) diff --git a/hwc/tulip/hwc_rotate.cpp b/hwc/tulip/hwc_rotate.cpp index 5d341ae..169edc3 100755 --- a/hwc/tulip/hwc_rotate.cpp +++ b/hwc/tulip/hwc_rotate.cpp @@ -15,6 +15,9 @@ */ #include "hwc.h" +#define ION_HEAP_TYPE_SECURE (ION_HEAP_TYPE_CUSTOM+1) +#define ION_HEAP_SECURE_MASK (1 << ION_HEAP_TYPE_SECURE) + int hwc_rotate_query(unsigned long tr_handle) { SUNXI_hwcdev_context_t *Globctx = &gSunxiHwcDevice; @@ -129,7 +132,7 @@ static rotate_cache_t *hwc_ratate_cache_manage(SUNXI_hwcdev_context_t *Globctx, return ratate_cache; } -static hwc_cache_t *hwc_tr_cache_get(rotate_cache_t *rotate_cache, int size, int fd, unsigned int sync_count) +static hwc_cache_t *hwc_tr_cache_get(rotate_cache_t *rotate_cache, int size, int fd, unsigned int sync_count, bool is_secure) { SUNXI_hwcdev_context_t *Globctx = &gSunxiHwcDevice; hwc_cache_t *tr_cache = NULL; @@ -163,7 +166,7 @@ static hwc_cache_t *hwc_tr_cache_get(rotate_cache_t *rotate_cache, int size, int close(tr_cache->fd); tr_cache->fd = -1; } - if(tr_cache->share_fd >= 0 && size <= tr_cache->size_buffer) + if(tr_cache->share_fd >= 0 && size <= tr_cache->size_buffer && tr_cache->is_secure == is_secure) { if(tr_cache->size_buffer - size > 4096) { @@ -181,22 +184,35 @@ static hwc_cache_t *hwc_tr_cache_get(rotate_cache_t *rotate_cache, int size, int } if(tr_cache->share_fd == -1 || tr_cache->size_buffer == 0) { - ret = ion_alloc_fd(Globctx->IonFd, size, - 4096, ION_HEAP_TYPE_DMA_MASK, 0, &tr_cache->share_fd); - if(ret < 0) - { - ALOGD("alloc err from ION_HEAP_TYPE_DMA_MASK"); - ret = ion_alloc_fd(Globctx->IonFd, size, - 4096, ION_HEAP_SYSTEM_CONTIG_MASK, 0, &tr_cache->share_fd); + if(is_secure){ + ret = ion_alloc_fd(Globctx->IonFd, size, + 4096, ION_HEAP_SECURE_MASK, 0, &tr_cache->share_fd); if(ret < 0) { - ALOGD("alloc err from ION_HEAP_SYSTEM_CONTIG_MASK"); - tr_cache->share_fd = -1; - tr_cache->size_buffer = 0; - return NULL; + ALOGD("alloc err from ION_HEAP_SECURE_MASK"); + return NULL; } - } - ion_sync_fd(Globctx->IonFd, tr_cache->share_fd); + tr_cache->is_secure = 1; + }else{ + ret = ion_alloc_fd(Globctx->IonFd, size, + 4096, ION_HEAP_TYPE_DMA_MASK, 0, &tr_cache->share_fd); + if(ret < 0) + { + ALOGD("alloc err from ION_HEAP_TYPE_DMA_MASK"); + ret = ion_alloc_fd(Globctx->IonFd, size, + 4096, ION_HEAP_SYSTEM_CONTIG_MASK, 0, &tr_cache->share_fd); + if(ret < 0) + { + ALOGD("alloc err from ION_HEAP_SYSTEM_CONTIG_MASK"); + tr_cache->share_fd = -1; + tr_cache->size_buffer = 0; + return NULL; + } + } + } + if(!is_secure){ + ion_sync_fd(Globctx->IonFd, tr_cache->share_fd); + } tr_cache->size_buffer = size; } tr_cache->sync_cnt = sync_count; @@ -267,7 +283,7 @@ void hwc_rotate_cache_free(void) static int inline hwc_disp_pixel_bytes(disp_pixel_format format) { - switch(format) + switch(format) { case DISP_FORMAT_YUV420_P: case DISP_FORMAT_YUV420_SP_VUVU: @@ -285,13 +301,13 @@ static int inline hwc_disp_pixel_bytes(disp_pixel_format format) return 16; default: return 0; - } + } return 0; } static inline int hwc_disp_layer_plan(disp_pixel_format format) { - switch(format) + switch(format) { case DISP_FORMAT_YUV420_P: return 3; @@ -308,7 +324,7 @@ static inline int hwc_disp_layer_plan(disp_pixel_format format) return 1; default: return 1; - } + } } static inline disp_pixel_format tr_to_disp(tr_pixel_format tr_format) @@ -473,9 +489,9 @@ bool hwc_layer_to_tr(disp_fb_info* hw_layer, tr_info *tr_info, hwc_cache_t *tr_b /*tr_info->dst_frame.laddr[2] --> V*/ if(cnt != 1)// is YUV Format { - tr_info->dst_frame.laddr[2] = tr_info->dst_frame.laddr[0] + + tr_info->dst_frame.laddr[2] = tr_info->dst_frame.laddr[0] + tr_info->dst_frame.pitch[0] * tr_info->dst_frame.height[0]; - tr_info->dst_frame.laddr[1] = tr_info->dst_frame.laddr[2] + + tr_info->dst_frame.laddr[1] = tr_info->dst_frame.laddr[2] + tr_info->dst_frame.pitch[2] * tr_info->dst_frame.height[2]; } return 1; @@ -487,7 +503,7 @@ void hwc_resize_crop(disp_fb_info *hw_layer, int w_original, int h_original, tr_ switch(mode) { case TR_HFLIP: - w_diff = hw_layer->size[0].width - w_original; + w_diff = hw_layer->size[0].width - w_original; hw_layer->crop.x + (long long)(((long long)w_diff)<<32); break; case TR_VFLIP: @@ -495,7 +511,7 @@ void hwc_resize_crop(disp_fb_info *hw_layer, int w_original, int h_original, tr_ hw_layer->crop.y + (long long)(((long long)h_diff)<<32); break; case TR_ROT_90: - w_diff = hw_layer->size[0].width - h_original; + w_diff = hw_layer->size[0].width - h_original; hw_layer->crop.x + (long long)(((long long)w_diff)<<32); h_diff = hw_layer->size[0].height - w_original; hw_layer->crop.y + (long long)(((long long)h_diff)<<32); @@ -503,7 +519,7 @@ void hwc_resize_crop(disp_fb_info *hw_layer, int w_original, int h_original, tr_ case TR_ROT_180: h_diff = hw_layer->size[0].height - h_original; hw_layer->crop.y + (long long)(((long long)h_diff)<<32); - w_diff = hw_layer->size[0].width - w_original; + w_diff = hw_layer->size[0].width - w_original; hw_layer->crop.x + (long long)(((long long)w_diff)<<32); break; case TR_ROT_270: @@ -580,7 +596,7 @@ bool hwc_tr_to_layer(disp_fb_info *hw_layer, tr_info *tr_info, hwc_cache_t *tr_b hw_layer->addr[0] = addr; if(hw_layer->format == DISP_FORMAT_YUV420_P) { - hw_layer->addr[2] = hw_layer->addr[0] + hw_layer->addr[2] = hw_layer->addr[0] + w_stride * h_stride ; hw_layer->addr[1] = hw_layer->addr[2] + w_stride * h_stride / 4; @@ -645,7 +661,7 @@ bool hwc_rotate_layer_tr(hwc_dispc_data_t *hwc_layer, goto translat_err; } tr_cache = hwc_tr_cache_get(rotate_cache, size, - commit_data->releasefencefd[disp], hwc_layer->sync_count); + commit_data->releasefencefd[disp], hwc_layer->sync_count,commit_layer->is_secure); if(tr_cache != NULL) { memset(&tr_info, 0, sizeof(tr_info)); @@ -720,6 +736,5 @@ translat_err: disp_layer->enable =0; ALOGE("######hwc get a rotate err#####"); return 0; - + } - diff --git a/hwc/tulip/hwc_sunxi.cpp b/hwc/tulip/hwc_sunxi.cpp index 56740da..c66ec79 100755 --- a/hwc/tulip/hwc_sunxi.cpp +++ b/hwc/tulip/hwc_sunxi.cpp @@ -178,6 +178,7 @@ static bool reset_globle(SUNXI_hwcdev_context_t *Globctx, Globctx->currentmem = 0; Globctx->has_tr_mem = 0; Globctx->has_tr_cnt = 0; + Globctx->has_secure = 0; int tmp_mem_thruput0 = 0; int all_mem_diff = 0, all_mem = 0, all_mem_fb = 0, ture_disp; for(i = 0; i < (int)NumofDisp && i < Globctx->NumberofDisp; i++) @@ -924,24 +925,6 @@ static bool resize_layer(HwcDisContext_t *Localctx, layer_info->fb.crop.y = fb_crop->top + ((cut_top == 1) ? cut_mod:0); layer_info->fb.crop.height = srcdiff - cut_mod; } - -#if defined(HWC_DEBUG) - ALOGD("\nold:\n[%f,%f]#S[%lld,%lld,%lld,%lld] F[%lld,%lld,%lld,%lld]\n", - Localctx->WidthScaleFactor, Localctx->HighetScaleFactor, - layer_info->fb.crop.x, layer_info->fb.crop.y, layer_info->fb.crop.width, - layer_info->fb.crop.height, layer_info->screen_win.x, layer_info->screen_win.y, - layer_info->screen_win.width, layer_info->screen_win.height); -#endif - - if(gSunxiHwcDevice.SunxiDisplay[0].DisplayType == DISP_OUTPUT_TYPE_HDMI) { - layer_info->fb.crop.x = (long long)(((long long)(psLayer->sourceCrop.left)) << 32); - layer_info->fb.crop.width = (long long)(((long long)(psLayer->sourceCrop.right)) << 32); - layer_info->fb.crop.width -= layer_info->fb.crop.x; - layer_info->fb.crop.y = (long long)(((long long)(psLayer->sourceCrop.top)) << 32); - layer_info->fb.crop.height = (long long)(((long long)(psLayer->sourceCrop.bottom)) << 32); - layer_info->fb.crop.height -= layer_info->fb.crop.y; - } - if(layer_info->b_trd_out == 1) { switch(PsDisplayInfo->Current3DMode) @@ -1045,7 +1028,7 @@ ret_ok: HwcAssignStatus hwc_try_assign_layer(HwcDisContext_t *Localctx, size_t singcout, int zOrder) { - bool needchannel = 1, isvideo = 0, isalpha = 0, isFB = 0, has_tr = 0; + bool needchannel = 1, isvideo = 0, isalpha = 0, isFB = 0, has_tr = 0, issecure = 0; bool is3D = 0, need_sync = 0, is_cursor = 0; float WscalFac = 1.0, HscaleFac = 1.0; int CH= -1, tmCnt1 = 0, tmCnt2 = 0, addLayerCnt = 1; @@ -1095,11 +1078,16 @@ HwcAssignStatus hwc_try_assign_layer(HwcDisContext_t *Localctx, size_t singcout, goto assign_gpu; } - if(check_usage_protected(handle) && !PsDisplayInfo->issecure) + if(check_usage_protected(handle)) { - ALOGV("%s:Video Protected", __func__); - dueto = D_VIDEO_PD; - goto assign_gpu; + if(!PsDisplayInfo->issecure) + { + ALOGV("%s:Video Protected", __func__); + dueto = D_VIDEO_PD; + goto assign_gpu; + }else{ + issecure = 1; + } } dueto = check_valid_layer(psLayer); @@ -1239,7 +1227,7 @@ needchannel: } } /*check the mem thruput*/ - if(!is_cursor) + if(!is_cursor && (Globctx->has_secure == 0)) { dueto = calculate_memthruput(Localctx, &Localctx->psAllLayer[singcout], WscalFac, HscaleFac, Localctx->HwCHUsedCnt - CHdiff, isFB, isvideo); @@ -1274,7 +1262,7 @@ needchannel: if(!Localctx->force_gpu && (Localctx->UsedFB? isFB: ((int)singcout == Localctx->numberofLayer - 2))) { - if(mem_ctrl_power_policy(Globctx, Localctx)) + if(mem_ctrl_power_policy(Globctx, Localctx) && (Globctx->has_secure == 0)) { Localctx->force_gpu = 1; goto assigned_need_resigne; @@ -1293,6 +1281,7 @@ assign_overlay: Globctx->has_tr_cnt += has_tr; Localctx->tr_mem += has_tr ? (handle->width * handle->height) : 0; Globctx->has_tr_mem += has_tr ? (handle->width * handle->height) : 0; + Globctx->has_secure += issecure; psCH[Localctx->HwCHUsedCnt - CHdiff].hasVideo = isvideo; psCH[Localctx->HwCHUsedCnt - CHdiff].iCHFormat = @@ -1315,8 +1304,9 @@ assign_overlay: Localctx->psAllLayer[singcout].is3D = is3D; Localctx->psAllLayer[singcout].info = dueto; Localctx->psAllLayer[singcout].isvideo = isvideo; - Localctx->psAllLayer[singcout].need_sync = need_sync; + Localctx->psAllLayer[singcout].need_sync = issecure?0:need_sync; Localctx->psAllLayer[singcout].is_cursor = is_cursor; + Localctx->psAllLayer[singcout].is_secure = issecure; if(is_cursor) { return ASSIGN_CURSOR; @@ -1360,7 +1350,6 @@ int hwc_setup_layer(hwc_dispc_data_t *DisplayData, HwcDisContext_t *Localctx) const DisplayInfo *PsDisplayInfo = Localctx->psDisplayInfo; ChannelInfo_t *psChannelInfo = Localctx->ChannelInfo; struct private_handle_t *handle = NULL; - bool enableLayer = !(PsDisplayInfo->setblank); ture_disp = PsDisplayInfo->VirtualToHWDisplay; if(ture_disp < 0 || ture_disp >= NUMBEROFDISPLAY) @@ -1413,6 +1402,7 @@ int hwc_setup_layer(hwc_dispc_data_t *DisplayData, HwcDisContext_t *Localctx) } hw_layer_config->needsync = psHwlayer_info->need_sync; hw_layer_config->share_fd = dup(psHwlayer_info->shared_fd); + hw_layer_config->is_secure = psHwlayer_info->is_secure; if(check_is_blending(psLayer)) { layer_info->alpha_mode = 2; @@ -1430,7 +1420,7 @@ int hwc_setup_layer(hwc_dispc_data_t *DisplayData, HwcDisContext_t *Localctx) layer_info->zorder = zOrder; layer_info->alpha_value = psChannelInfo[CHCnt].planeAlpha; - psDisconfig->enable = enableLayer; + psDisconfig->enable = 1; psDisconfig->layer_id = LCnt; psDisconfig->channel = psChannelInfo[CHCnt].hasVideo ? VideoCnt : UiCnt; psHwlayer_info->hwchannel = psDisconfig->channel; @@ -2033,11 +2023,10 @@ SUNXI_hwcdev_context_t* hwc_create_device(void) && Globctx->SunxiDisplay[1].VirtualToHWDisplay == -EINVAL) { hwc_hotplug_switch(1, 1, DISP_TV_MODE_NUM); - ALOGD("### init hdmi_plug: IN ###"); } + ALOGD("### init hdmi_plug: IN ###"); }else{ - if(Globctx->SunxiDisplay[0].DisplayType != DISP_OUTPUT_TYPE_HDMI) - ALOGD("### init hdmi_plug: OUT ###"); + ALOGD("### init hdmi_plug: OUT ###"); } close(open_fd); }else{ @@ -2119,7 +2108,8 @@ SUNXI_hwcdev_context_t* hwc_create_device(void) Globctx->layer_st = -1; Globctx->fBeginTime = 0.0; Globctx->uiBeginFrame = 0; - Globctx->unblank_flag = 0; + Globctx->unblank_flag = 0; + Globctx->has_secure = 0; hwc_list_init(&Globctx->rotate_cache_list); Globctx->rotate_hold_cnt = 0; diff --git a/hwc/tulip/hwc_uevent.cpp b/hwc/tulip/hwc_uevent.cpp index ff6a8ba..9ff8956 100755 --- a/hwc/tulip/hwc_uevent.cpp +++ b/hwc/tulip/hwc_uevent.cpp @@ -146,12 +146,12 @@ int hwc_manage_display(DisplayInfo **retDisplayInfo, int DispInfo, ManageDisp mo disp_tv_mode get_suitable_hdmi_mode(int select, disp_tv_mode lastmode) { + ALOGI("get_suitable_hdmi_mode select=%d lastmode=%d", select, lastmode); SUNXI_hwcdev_context_t *Globctx = &gSunxiHwcDevice; unsigned long arg[4]={0}; arg[0] = select; int ret, i, j = -1; disp_tv_mode theMostMode = DISP_TV_MODE_NUM; - struct disp_output para; i = sizeof(g_tv_para) / sizeof(g_tv_para[0]); if(lastmode < DISP_TV_MODE_NUM) { @@ -164,41 +164,38 @@ disp_tv_mode get_suitable_hdmi_mode(int select, disp_tv_mode lastmode) } } - if(Globctx->SunxiDisplay[0].DisplayType == DISP_OUTPUT_TYPE_HDMI) - { - arg[1] = (unsigned long)¶ - ret = ioctl(Globctx->DisplayFd, DISP_GET_OUTPUT, arg); - if(ret >= 0) - { - theMostMode = (disp_tv_mode)para.mode; - } - }else{ - while(i > 0) - { - i--; - if(g_tv_para[i].mode == DISP_TV_MOD_1080P_60HZ) +theMostMode = DISP_TV_MOD_1080P_60HZ; + arg[1] = DISP_OUTPUT_TYPE_HDMI; + arg[2] = theMostMode; + ret = ioctl(Globctx->DisplayFd, DISP_DEVICE_SWITCH, arg); + + return theMostMode; + + while(i > 0) + { + i--; + if(g_tv_para[i].mode == DISP_TV_MOD_1080P_60HZ) + { + j = i; + } + if(j != -1) + { + arg[1] = DISP_OUTPUT_TYPE_HDMI; + arg[2] = g_tv_para[i].mode; + ret = ioctl(Globctx->DisplayFd, DISP_DEVICE_SWITCH, arg); + if(ret >= 0) { - j = i; + if(theMostMode == DISP_TV_MODE_NUM) + { + g_tv_para[sizeof(g_tv_para) / sizeof(g_tv_para[0])-1].support = 1<DisplayFd, DISP_DEVICE_SWITCH, arg); - if(ret >= 0) - { - if(theMostMode == DISP_TV_MODE_NUM) - { - g_tv_para[sizeof(g_tv_para) / sizeof(g_tv_para[0])-1].support = 1<setblank = 1; PsDisplayInfo->VarDisplayWidth = get_info_mode(set_mode,WIDTH); PsDisplayInfo->VarDisplayHeight = get_info_mode(set_mode,HEIGHT); PsDisplayInfo->DisplayType = DISP_OUTPUT_TYPE_HDMI; @@ -252,16 +250,11 @@ int hwc_hotplug_switch(int DisplayNum, bool plug, disp_tv_mode set_mode) PsDisplayInfo->InitDisplayWidth = PsDisplayInfo->VarDisplayWidth; } Globctx->memlimit += PsDisplayInfo->InitDisplayHeight * PsDisplayInfo->InitDisplayWidth * 4; - if(Globctx->SunxiDisplay[0].DisplayType != DISP_OUTPUT_TYPE_HDMI) - { - Globctx->hot_plug = 1; - } + Globctx->hot_plug = 1; arg[0] = DisplayNum; arg[1] = DISP_OUTPUT_TYPE_HDMI; arg[2] = set_mode; ioctl(Globctx->DisplayFd, DISP_DEVICE_SWITCH, (unsigned long)arg); - PsDisplayInfo->setblank = 0; - Globctx->psHwcProcs->invalidate(Globctx->psHwcProcs); arg[0] = DisplayNum; arg[1] = 1; ioctl(Globctx->DisplayFd, DISP_VSYNC_EVENT_EN,(unsigned long)arg); @@ -273,8 +266,7 @@ int hwc_hotplug_switch(int DisplayNum, bool plug, disp_tv_mode set_mode) ALOGD( "###hdmi plug in, Type:%d, Mode:0x%08x###", PsDisplayInfo->DisplayType, PsDisplayInfo->DisplayMode); - } - else if(Globctx->SunxiDisplay[0].DisplayType != DISP_OUTPUT_TYPE_HDMI){ + }else{ Globctx->hot_plug = 0; hwc_manage_display(NULL, DisplayNum ,FREE_DISP); } @@ -289,7 +281,7 @@ int hwc_hotplug_switch(int DisplayNum, bool plug, disp_tv_mode set_mode) }else{ ALOGD("###psHwcProcs No register.###"); } - if(!plug && Globctx->SunxiDisplay[0].DisplayType != DISP_OUTPUT_TYPE_HDMI) + if(!plug) { arg[0] = DisplayNum; arg[1] = DISP_OUTPUT_TYPE_NONE; @@ -424,7 +416,7 @@ static int hwc_uevent(void) } } - if(IsHdmi && Globctx->SunxiDisplay[0].DisplayType != DISP_OUTPUT_TYPE_HDMI) + if(IsHdmi) { while(s) { diff --git a/lights/tulip/lights.c b/lights/tulip/lights.c index 77fd993..6801ad5 100755 --- a/lights/tulip/lights.c +++ b/lights/tulip/lights.c @@ -19,6 +19,7 @@ #include +#include #include #include #include diff --git a/optee_client-master/.gitignore b/optee_client-master/.gitignore new file mode 100755 index 0000000..69d7ce3 --- /dev/null +++ b/optee_client-master/.gitignore @@ -0,0 +1,7 @@ +cscope.* +build +out +Debug +*.swp +.cproject +.project diff --git a/optee_client-master/.travis.yml b/optee_client-master/.travis.yml new file mode 100755 index 0000000..143e183 --- /dev/null +++ b/optee_client-master/.travis.yml @@ -0,0 +1,18 @@ +# One may have a look at http://docs.travis-ci.com/user/installing-dependencies/ + +language: c + +notifications: + - email: true + +# Install the cross-compiler +before_install: + - sudo apt-get update -qq + - sudo apt-get install -y gcc-arm-linux-gnueabihf + - arm-linux-gnueabihf-gcc --version + +# Several compilation options are checked +script: + - make clean all + - CFG_TEE_CLIENT_LOG_LEVEL=0 make clean all + - CFG_TEE_CLIENT_LOG_LEVEL=5 make clean all diff --git a/optee_client-master/Android.mk b/optee_client-master/Android.mk new file mode 100755 index 0000000..eb2de4b --- /dev/null +++ b/optee_client-master/Android.mk @@ -0,0 +1,72 @@ +# Android optee-client and optee-supplicant makefile # +################################################################################ +LOCAL_PATH := $(call my-dir) + +ifeq ($(SECURE_OS_OPTEE), yes) + +################################################################################ +# Include optee-client common config and flags # +################################################################################ +include $(LOCAL_PATH)/config.mk +include $(LOCAL_PATH)/flags.mk + +################################################################################ +# Build libteec.so - TEE (Trusted Execution Environment) shared library # +################################################################################ +include $(CLEAR_VARS) +LOCAL_CFLAGS += -DANDROID_BUILD +#LOCAL_CFLAGS += $(CFLAGS) + +ifeq ($(CFG_TEE_CLIENT_LOG_FILE), true) +LOCAL_CFLAGS += -DTEEC_LOG_FILE=$(CFG_TEE_CLIENT_LOG_FILE) +endif + +LOCAL_CFLAGS += -DDEBUGLEVEL_$(CFG_TEE_CLIENT_LOG_LEVEL) +LOCAL_CFLAGS += -DBINARY_PREFIX=\"TEEC\" + +LOCAL_SRC_FILES += libteec/src/tee_client_api.c +LOCAL_SRC_FILES += libteec/src/teec_trace.c + +LOCAL_SHARED_LIBRARIES:=\ + libcutils \ + libutils + +LOCAL_C_INCLUDES := $(LOCAL_PATH)/public \ + $(LOCAL_PATH)/libteec/include \ + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE := libteec +LOCAL_MODULE_TAGS := optional +include $(BUILD_SHARED_LIBRARY) + +################################################################################ +# Build tee supplicant # +################################################################################ +include $(CLEAR_VARS) +#LOCAL_CFLAGS += -DANDROID_BUILD +#LOCAL_CFLAGS += $(CFLAGS) + +LOCAL_CFLAGS += -DDEBUGLEVEL_$(CFG_TEE_SUPP_LOG_LEVEL) +LOCAL_CFLAGS += -DBINARY_PREFIX=\"TEES\" +LOCAL_CFLAGS += -DTEEC_LOAD_PATH=\"$(CFG_TEE_CLIENT_LOAD_PATH)\" + +LOCAL_SRC_FILES += tee-supplicant/src/handle.c +LOCAL_SRC_FILES += tee-supplicant/src/tee_supp_fs.c +LOCAL_SRC_FILES += tee-supplicant/src/tee_supplicant.c +LOCAL_SRC_FILES += tee-supplicant/src/teec_ta_load.c + +LOCAL_SHARED_LIBRARIES:=\ + libcutils \ + libutils + +LOCAL_C_INCLUDES := $(LOCAL_PATH)/public \ + $(LOCAL_PATH)/libteec/include \ + $(LOCAL_PATH)/tee-supplicant/src + +LOCAL_SHARED_LIBRARIES := libteec liblog +LOCAL_MODULE := tee_supplicant +LOCAL_MODULE_TAGS := optional +LOCAL_MULTILIB := 32 +include $(BUILD_EXECUTABLE) + +endif diff --git a/optee_client-master/LICENSE b/optee_client-master/LICENSE new file mode 100755 index 0000000..fe903ec --- /dev/null +++ b/optee_client-master/LICENSE @@ -0,0 +1,27 @@ +Unless it has its own copyright/license embedded in its body, each source file +is subject to the following license terms: + +Copyright (c) 2014, STMicroelectronics International N.V. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +2. 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. + +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 AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. diff --git a/optee_client-master/Makefile b/optee_client-master/Makefile new file mode 100755 index 0000000..279db59 --- /dev/null +++ b/optee_client-master/Makefile @@ -0,0 +1,129 @@ +# Public variables are stored in config.mk +include ./config.mk + +######################################################################### +# Set Internal Variables # +# May be modified to match your setup # +######################################################################### +BUILD_VERBOSE ?= 0 +VPREFIX ?= @ +COMPILER_DIR ?= $(CURDIR)/../toolchain/gcc-aarch64/bin +ifeq ($(BUILD_VERBOSE),1) +VPREFIX:= +endif +export VPREFIX COMPILER_DIR + +EXPORT_DIR ?= $(O)/export +ROOTFS_DIR ?= $(CURDIR)/../../../out/sun50iw1p1/linux/common/rootfs_def + +.PHONY: all build build-libteec install copy_export \ + clean cscope clean-cscope \ + checkpatch-pre-req checkpatch-modified-patch checkpatch-modified-file \ + checkpatch-last-commit-patch checkpatch-last-commit-file \ + checkpatch-base-commit-patch checkpatch-base-commit-file \ + checkpatch-all-files distclean + +all: build install + +build-libteec: + @echo "Building libteec.so" + @$(MAKE) --directory=libteec --no-print-directory + +build-tee-supplicant: build-libteec + @echo "Building tee-supplicant" + $(MAKE) --directory=tee-supplicant --no-print-directory + +build: build-libteec build-tee-supplicant + +install: copy_export + +clean: clean-libteec clean-tee-supplicant clean-cscope + +clean-libteec: + @$(MAKE) --directory=libteec --no-print-directory clean + +clean-tee-supplicant: + @$(MAKE) --directory=tee-supplicant --no-print-directory clean + +cscope: + @echo " CSCOPE" + ${VPREFIX}find ${CURDIR} -name "*.[chsS]" > cscope.files + ${VPREFIX}cscope -b -q -k + +clean-cscope: + ${VPREFIX}rm -f cscope.* + +# Various checkpatch targets. The ones ending with "patch" only considers the +# patch, whilst the ones ending with "file" checks the complete file. +# +-------------------------------+------------+----------------------------+ +# | Target commit | File/Patch | Comment | +# +-------------------------------+------------+----------------------------+ +# | checkpatch-modified-patch | Patch | Check local modifications | +# +-------------------------------+------------+----------------------------+ +# | checkpatch-modified-file | File | Check Local modifications | +# +-------------------------------+------------+----------------------------+ +# | checkpatch-last-commit-patch | Patch | Check against HEAD^ | +# +-------------------------------+------------+----------------------------+ +# | checkpatch-last-commit-file | File | Check against HEAD^ | +# +-------------------------------+------------+----------------------------+ +# | checkpatch-base-commit-patch | Patch | Against specic commit | +# +-------------------------------+------------+----------------------------+ +# | checkpatch-base-commit-file | File | Against specic commit | +# +-------------------------------+------------+----------------------------+ +# | checkpatch-all-files | File | Check all tracked files | +# +-------------------------------+------------+----------------------------+ +CHECKPATCH_IGNORE ?= --ignore NEW_TYPEDEFS --no-signoff +CHECKPATCH_STRICT ?= --strict +CHECKPATCH_ARGS ?= $(CHECKPATCH_IGNORE) $(CHECKPATCH_STRICT) --no-tree --terse +CHECKPATCH_PATCH_ARGS := $(CHECKPATCH_ARGS) --patch +CHECKPATCH_FILE_ARGS := $(CHECKPATCH_ARGS) --file --no-patch + +checkpatch-pre-req: + @echo " CHECKPATCH" +ifndef CHECKPATCH + $(error "Environment variable CHECKPATCH must point to Linux kernels checkpatch script") +else +ifeq (,$(wildcard ${CHECKPATCH})) + $(error "CHECKPATCH points to the incorrect file") +endif +endif + +checkpatch-modified-patch: checkpatch-pre-req + ${VPREFIX}git diff | ${CHECKPATCH} $(CHECKPATCH_PATCH_ARGS) - || true + +checkpatch-modified-file: checkpatch-pre-req + ${VPREFIX}${CHECKPATCH} $(CHECKPATCH_FILE_ARGS) $(shell git diff --name-only) + + +checkpatch-last-commit-patch: checkpatch-pre-req + ${VPREFIX}git diff HEAD^ | ${CHECKPATCH} $(CHECKPATCH_PATCH_ARGS) - || true + +checkpatch-last-commit-file: checkpatch-pre-req + ${VPREFIX}${CHECKPATCH} $(CHECKPATCH_FILE_ARGS) $(shell git diff --name-only HEAD^) + + +checkpatch-base-commit-patch: checkpatch-pre-req +ifndef BASE_COMMIT + $(error "Environment variable BASE_COMMIT must contain a valid commit") +endif + ${VPREFIX}git diff $(BASE_COMMIT) | ${CHECKPATCH} $(CHECKPATCH_PATCH_ARGS) - || true + +checkpatch-base-commit-file: checkpatch-pre-req +ifndef BASE_COMMIT + $(error "Environment variable BASE_COMMIT must contain a valid commit") +endif + ${VPREFIX}${CHECKPATCH} $(CHECKPATCH_FILE_ARGS) $(shell git diff --name-only ${BASE_COMMIT}) + +checkpatch-all-files: checkpatch-pre-req + ${VPREFIX}${CHECKPATCH} $(CHECKPATCH_FILE_ARGS) $(shell git ls-files) + +distclean: clean + +copy_export: build + mkdir -p ${EXPORT_DIR}/lib ${EXPORT_DIR}/include ${EXPORT_DIR}/bin + cp ${O}/libteec/libteec.so* ${EXPORT_DIR}/lib + cp ${O}/tee-supplicant/tee-supplicant ${EXPORT_DIR}/bin + + cp ${O}/libteec/libteec.so* ${ROOTFS_DIR}/usr/lib64 + cp ${O}/tee-supplicant/tee-supplicant ${ROOTFS_DIR}/usr/bin + cp public/*.h ${EXPORT_DIR}/include diff --git a/optee_client-master/Notice.md b/optee_client-master/Notice.md new file mode 100755 index 0000000..617e1e5 --- /dev/null +++ b/optee_client-master/Notice.md @@ -0,0 +1,35 @@ +OP-TEE +======= + +This is the repository of OP-TEE (Open Portable Trusted Execution Environment), the open-source TEE maintained by STMicroelectronics, with initial contributions from STMicroelectronics, Ericsson, the Linaro industry association. + +What OP-TEE is +------ + +OP-TEE is designed primarily to rely on the ARM TrustZone(R) technology as the underlying hardware isolation mechanism. However, it has been structured to be compatible with any isolation technology suitable for the TEE concept and goals, such as running as a virtual machine or on a dedicated CPU. + +The main design goals for OP-TEE are: +- Isolation - the TEE provides isolation from the Rich OS (typically, Linux/Android) and it protects the Trusted Applications (TAs) it executes from each other, using underlying HW support, +- Small footprint - the TEE should remain small enough so that the TEE core, including all the code and data required to provide isolation, can reside in a reasonable amount of on-chip memory, +- Portability - the TEE must be easily pluggable to different architectures and available HW, and it has to support various setups such as multiple TEEs or multiple client OSes. + +Repository structure +------ + +OP-TEE is composed of three gits: +- The optee-client git, containing the source code for the TEE client library in Linux. This component provides the TEE Client API as defined by the GlobalPlatform TEE standard. It is distributed under the BSD 2-clause open-source license. +- The optee_os git, containing the source code for the TEE OS itself. This component provides the TEE Internal APIs as defined by the GlobalPlatform TEE standard to the Trusted Applications that it executes. It is distributed mostly under the BSD 2-clause open-source license. It includes few external files under BSD 3-clause license or other free software licenses. +- The optee_linuxdriver git, containing the source code for the TEE driver in Linux. This component implements a generic TEE driver, designed primarily for TEE implementations that rely on the ARM TrustZone(R)technology. It is distributed under the GPLv2 open-source license. Please note that re-distribution under other versions of the GPL license is not allowed. The rationale behind this limitation is to ensure that this code may be used on products which have security devices which prevent reloading the code. Such security devices would be incompatible with some licenses such as GPLv3 and so distribution under those licenses would be inconsistent with this goal. Therefore it is recommended that care be taken before redistributing any of the components under other license terms than those provided here. + +Contributions +------ + +Contributions to OP-TEE are managed by the OP-TEE gatekeepers, whose contact email is op-tee-support[at]st[.]com. + +Contributions must be original work of the contributor. In order to preserve the rights of the contributor while allowing distribution to and protection of the recipients of OP-TEE, the contributor must complete, sign and send the Contribution Agreement or a scanned copy to ST for counter-signature, prior to any contribution. The address where to send the agreement and other details will be provided upon contact with the OP-TEE gatekeepers. +Once the Contribution Agreement is complete, the contributor may propose contributions to the OP-TEE gatekeepers. Proposed Contributions are reviewed for acceptance by the OP-TEE gatekeepers and the OP-TEE community. + +Submission of non-original work +------ + +You may submit work that is not your original creation separately from any Contribution, identifying the complete details of its source and of any license or other restriction of which you are personally aware. Such submissions are not subject to the Contribution Agreement. They are reviewed for acceptance by the OP-TEE gatekeepers and the OP-TEE community. diff --git a/optee_client-master/README.md b/optee_client-master/README.md new file mode 100755 index 0000000..1557a50 --- /dev/null +++ b/optee_client-master/README.md @@ -0,0 +1,84 @@ +# OP-TEE Client API +The optee-client git, containing the source code for the TEE client library in +Linux. This component provides the TEE Client API as defined by the +GlobalPlatform TEE standard. It is distributed under the BSD 2-clause +open-source license. For a general overview of OP-TEE, please see the +[Notice.md](Notice.md) file. + +In this git there are two main target/binaries to build. There is libteec.so, +which is the library that contains that API for communication with the Trusted +OS. Then the other target is the binary tee-supplicant which is a daemon serving +the Trusted OS in secure world with miscellaneous features, such as file system +access. + +## License +The software is provided under the +[BSD 2-Clause](http://opensource.org/licenses/BSD-2-Clause) license. + +## Platforms supported +This software in this git doesn't directly have any dependencies to any +particular hardware, since it's pure software library directly communicating +with the Linux kernel. Currently the software has been tested using: + +- STMicroelectronics b2020-h416 (orly-2) hardware (32-bits) +- Some initial testing has been done using +[Foundation FVP](http://www.arm.com/fvp), which can be downloaded free of +charge. + +## Get and build the software +### Get the compiler +We will strive to use the latest available compiler from Linaro. Start by +downloading and unpacking the compiler. Then export the PATH to the bin folder. + + $ cd $HOME + $ mkdir toolchains + $ cd toolchains + $ wget http://releases.linaro.org/14.05/components/toolchain/binaries/gcc-linaro-arm-linux-gnueabihf-4.9-2014.05_linux.tar.xz + $ tar xvf gcc-linaro-arm-linux-gnueabihf-4.9-2014.05_linux.tar.xz + $ export PATH=$HOME/toolchains/gcc-linaro-arm-linux-gnueabihf-4.9-2014.05_linux/bin:$PATH + +### Download the source code + $ cd $HOME + $ mkdir devel + $ cd devel + $ git clone https://github.com/OP-TEE/optee_client.git + +### Build + $ cd $HOME/devel/optee_client + $ make + +#### Compiler flags +To be able to see the full command when building you could build using following +flag: + +`$ make BUILD_VERBOSE=1` + +## Coding standards +In this project we are trying to adhere to the same coding convention as used in +the Linux kernel (see +[CodingStyle](https://www.kernel.org/doc/Documentation/CodingStyle)). We achieve this by running +[checkpatch](http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/scripts/checkpatch.pl) from Linux kernel. +However there are a few exceptions that we had to make since the code also +follows GlobalPlatform standards. The exceptions are as follows: + +- CamelCase for GlobalPlatform types are allowed. +- And we also exclude checking third party code that we might use in this + project, such as LibTomCrypt, MPA, newlib (not in this particular git, but + those are also part of the complete TEE solution). The reason for excluding + and not fixing third party code is because we would probably deviate too much + from upstream and therefore it would be hard to rebase against those projects + later on (and we don't expect that it is easy to convince other software + projects to change coding style). + +### checkpatch +Since checkpatch is licensed under the terms of GNU GPL License Version 2, we +cannot include this script directly into this project. Therefore we have +written the Makefile so you need to explicitly point to the script by exporting +an environment variable, namely CHECKPATCH. So, suppose that the source code for +the Linux kernel is at `$HOME/devel/linux`, then you have to export like follows: + + $ export CHECKPATCH=$HOME/devel/linux/scripts/checkpatch.pl +thereafter it should be possible to use one of the different checkpatch targets +in the [Makefile](Makefile). There are targets for checking all files, checking +against latest commit, against a certain base-commit etc. For the details, read +the [Makefile](Makefile). diff --git a/optee_client-master/config.mk b/optee_client-master/config.mk new file mode 100755 index 0000000..10d8aeb --- /dev/null +++ b/optee_client-master/config.mk @@ -0,0 +1,53 @@ +######################################################################### +# Public variables # +# Developers may override these values when calling the makefile, # +# as for example # +# CFG_TEE_CLIENT_LOG_LEVEL=1 make # +# or by declaring the variable in their environement, as for example # +# export CFG_TEE_CLIENT_LOG_LEVEL=1 # +# make # +######################################################################### + +# CFG_TEE_CLIENT_LOG_LEVEL +# Client (User Non Secure) log level +# Supported values: 0 (no traces) to 4 (all traces) +CFG_TEE_CLIENT_LOG_LEVEL?=1 +export CFG_TEE_CLIENT_LOG_LEVEL + +# CFG_TEE_SUPP_LOG_LEVEL +# Supplicant log level +# Supported values: 0 (no traces) to 4 (all traces) +CFG_TEE_SUPP_LOG_LEVEL?=1 +export CFG_TEE_SUPP_LOG_LEVEL + +# CFG_TEE_CLIENT_LOG_FILE +# The location of the client log file when logging to file is enabled. +CFG_TEE_CLIENT_LOG_FILE ?= \"/data/teec.log\" + +# CFG_TEE_SUPP_LOG_FILE +# The location of the supplicant log file when logging to file is enabled. +CFG_TEE_SUPP_LOG_FILE ?= \"/data/teesupp.log\" + +# CFG_TEE_CLIENT_LOAD_PATH +# The location of the client library file. +CFG_TEE_CLIENT_LOAD_PATH ?= /system/lib + +# Default out dir. +# Must be a relative path with respect to the op-tee-client root directory +O ?= out +export O + +######################################################################### +# Private Values # +######################################################################### + +# Check that settings are coherent. + +ifdef ARM_TOOLCHAIN_DIR +ifeq ($(wildcard ${ARM_TOOLCHAIN_DIR}/bin/${ARM_GCC_PREFIX}-gcc),) + $(error "ARM_TOOLCHAIN_DIR wrongly setup. Is ${ARM_TOOLCHAIN_DIR}") +endif +export ARM_TOOLCHAIN_DIR +export ARM_GCC_PREFIX +endif + diff --git a/optee_client-master/flags.mk b/optee_client-master/flags.mk new file mode 100755 index 0000000..18de6e4 --- /dev/null +++ b/optee_client-master/flags.mk @@ -0,0 +1,24 @@ +######################################################################### +# COMMON COMPILATION FLAGS # +######################################################################### + +CROSS_COMPILE ?= $(COMPILER_DIR)/aarch64-linux-gnu- +CC := $(CROSS_COMPILE)gcc + +CFLAGS := -Wall -Wbad-function-cast -Wcast-align \ + -Werror-implicit-function-declaration -Wextra \ + -Wfloat-equal -Wformat-nonliteral -Wformat-security \ + -Wformat=2 -Winit-self -Wmissing-declarations \ + -Wmissing-format-attribute -Wmissing-include-dirs \ + -Wmissing-noreturn -Wmissing-prototypes -Wnested-externs \ + -Wpointer-arith -Wshadow -Wstrict-prototypes \ + -Wswitch-default -Wunsafe-loop-optimizations \ + -Wwrite-strings -Werror +CFLAGS += -c -fPIC + +DEBUG ?= 0 +ifeq ($(DEBUG), 1) +CFLAGS += -DDEBUG -O0 -g +endif + +RM := rm -rf diff --git a/optee_client-master/libteec/Makefile b/optee_client-master/libteec/Makefile new file mode 100755 index 0000000..9a69216 --- /dev/null +++ b/optee_client-master/libteec/Makefile @@ -0,0 +1,52 @@ +include ../flags.mk + +OUT_DIR ?= ${CURDIR}/../$(O)/libteec + +.PHONY: all libteec clean + +all: libteec +################################################################################ +# Teec configuration +################################################################################ +MAJOR_VERSION := 1 +MINOR_VERSION := 0 +LIB_NAME := libteec.so +LIB_MAJOR := $(LIB_NAME).$(MAJOR_VERSION) +LIB_MAJ_MIN := $(LIB_NAME).$(MAJOR_VERSION).$(MINOR_VERSION) + +TEEC_SRCS := tee_client_api.c \ + teec_trace.c + +TEEC_SRC_DIR := src +TEEC_OBJ_DIR := $(OUT_DIR) +TEEC_OBJS := $(patsubst %.c,$(TEEC_OBJ_DIR)/%.o, $(TEEC_SRCS)) +TEEC_INCLUDES := \ + ${CURDIR}/include \ + ${CURDIR}/../public \ + +TEEC_CFLAGS := $(addprefix -I, $(TEEC_INCLUDES)) $(CFLAGS) -D_GNU_SOURCE \ + -DDEBUGLEVEL_$(CFG_TEE_CLIENT_LOG_LEVEL) \ + -DBINARY_PREFIX=\"TEEC\" + +TEEC_LFLAGS := -lpthread +TEEC_LIBRARY := $(OUT_DIR)/$(LIB_MAJ_MIN) + +libteec: $(TEEC_LIBRARY) + $(VPREFIX)ln -sf $(TEEC_LIBRARY) $(OUT_DIR)/$(LIB_MAJOR) + $(VPREFIX)ln -sf $(OUT_DIR)/$(LIB_MAJOR) $(OUT_DIR)/$(LIB_NAME) + +$(TEEC_LIBRARY): $(TEEC_OBJS) + @echo " LD $@" + $(VPREFIX)$(CC) -shared -Wl,-soname,$(LIB_MAJ_MIN) $(TEEC_LFLAGS) -o $@ $+ + @echo "" + +$(TEEC_OBJ_DIR)/%.o: ${TEEC_SRC_DIR}/%.c + $(VPREFIX)mkdir -p $(TEEC_OBJ_DIR) + @echo " CC $<" + $(VPREFIX)$(CC) $(TEEC_CFLAGS) -c $< -o $@ + +################################################################################ +# Cleaning up configuration +################################################################################ +clean: + $(RM) $(OUT_DIR) diff --git a/optee_client-master/libteec/include/linux/tee_ioc.h b/optee_client-master/libteec/include/linux/tee_ioc.h new file mode 100755 index 0000000..e919479 --- /dev/null +++ b/optee_client-master/libteec/include/linux/tee_ioc.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2014, STMicroelectronics International N.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. 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. + * + * 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 AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 _TEE_IOC_H +#define _TEE_IOC_H + +#include + +#ifndef __KERNEL__ +#define __user +#endif + +/** + * struct tee_cmd_io - The command sent to an open tee device. + * @err: Error code (as in Global Platform TEE Client API spec) + * @origin: Origin for the error code (also from spec). + * @cmd: The command to be executed in the trusted application. + * @uuid: The uuid for the trusted application. + * @data: The trusted application or memory block. + * @data_size: The size of the trusted application or memory block. + * @op: The cmd payload operation for the trusted application. + * + * This structure is mainly used in the Linux kernel for communication + * with the user space. + */ +struct tee_cmd_io { + TEEC_Result err; + uint32_t origin; + uint32_t cmd; + int fd_sess; + /* + * Here fd_sess is 32-bit variable. Since TEEC_Result also is defined as + * "uint32_t", this structure is aligned. + */ + union { + TEEC_UUID __user *uuid; + uint64_t padding_uuid; + }; + union { + void __user *data; + uint64_t padding_data; + }; + union { + TEEC_Operation __user *op; + uint64_t padding_op; + }; + uint32_t data_size; + int32_t reserved; +}; + +struct tee_shm_io { + union { + void __user *buffer; + uint64_t padding_buf; + }; + uint32_t size; + uint32_t flags; + /* + * Here fd_shm is 32-bit. To be compliant with the convention of file + * descriptor definition, fd_shm is defined as "int" type other + * than "int32_t". Even though using "int32_t" is more obvious to + * indicate that we intend to keep this structure aligned. + */ + int fd_shm; + uint32_t registered; +}; + +#define TEE_OPEN_SESSION_IOC _IOWR('t', 161, struct tee_cmd_io) +#define TEE_INVOKE_COMMAND_IOC _IOWR('t', 163, struct tee_cmd_io) +#define TEE_REQUEST_CANCELLATION_IOC _IOWR('t', 164, struct tee_cmd_io) +#define TEE_ALLOC_SHM_IOC _IOWR('t', 165, struct tee_shm_io) +#define TEE_GET_FD_FOR_RPC_SHM_IOC _IOWR('t', 167, struct tee_shm_io) + +#endif /* _TEE_IOC_H */ diff --git a/optee_client-master/libteec/include/teec.h b/optee_client-master/libteec/include/teec.h new file mode 100755 index 0000000..583b2cb --- /dev/null +++ b/optee_client-master/libteec/include/teec.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2014, STMicroelectronics International N.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. 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. + * + * 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 AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 TEEC_H +#define TEEC_H + +#include +#include "tee_client_api.h" +#include + +#ifndef strlcpy +#define strlcpy(dst, src, size) snprintf((dst), (size), "%s", (src)) +#endif + +#endif diff --git a/optee_client-master/libteec/src/tee_client_api.c b/optee_client-master/libteec/src/tee_client_api.c new file mode 100755 index 0000000..08e5b78 --- /dev/null +++ b/optee_client-master/libteec/src/tee_client_api.c @@ -0,0 +1,452 @@ +/* + * Copyright (c) 2014, STMicroelectronics International N.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. 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. + * + * 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 AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 +#include + +#include +#include +#include +#include +#include + +#define TEE_TZ_DEVICE_NAME "opteearmtz00" + +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) + +/* + * Maximum size of the device name + */ +#define TEEC_MAX_DEVNAME_SIZE 256 + +/* +#ifdef _GNU_SOURCE +static pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; +#else +static pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER; +#endif +*/ +static pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; + +static void teec_mutex_lock(pthread_mutex_t *mu) +{ + int e = pthread_mutex_lock(mu); + + if (e != 0) + EMSG("pthread_mutex_lock failed: %d\n", e); +} + +static void teec_mutex_unlock(pthread_mutex_t *mu) +{ + int e = pthread_mutex_unlock(mu); + + if (e != 0) + EMSG("pthread_mutex_unlock failed: %d\n", e); +} + +static void teec_resetTeeCmd(struct tee_cmd_io *cmd) +{ + memset((void *)cmd, 0, sizeof(struct tee_cmd_io)); + + cmd->fd_sess = -1; + cmd->cmd = 0; + cmd->uuid = NULL; + cmd->origin = TEEC_ORIGIN_API; + cmd->err = TEEC_SUCCESS; + cmd->data = NULL; + cmd->data_size = 0; + cmd->op = NULL; +} + + + +/* + * This function initializes a new TEE Context, connecting this Client + * application to the TEE identified by the name name. + * + * name == NULL will give the default TEE. + */ +TEEC_Result TEEC_InitializeContext(const char *name, TEEC_Context *context) +{ + int name_size = 0; + const char* _name = name; + + INMSG("%s", name); + ALOGV("%s", name); + if (context == NULL) + return TEEC_ERROR_BAD_PARAMETERS; + + /* + * Specification says that when no name is provided it should fall back + * on a predefined TEE. + */ + if (name == NULL) + _name = TEE_TZ_DEVICE_NAME; + + name_size = snprintf(context->devname, TEEC_MAX_DEVNAME_SIZE, + "/dev/%s", _name); + + if (name_size >= TEEC_MAX_DEVNAME_SIZE) + return TEEC_ERROR_BAD_PARAMETERS; /* Device name truncated */ + + ALOGV("context->devname=%s\n", context->devname); + context->fd = open(context->devname, O_RDWR); + ALOGV("context-fd=%d, err=%d\n", context->fd, errno); + if (context->fd == -1) + return TEEC_ERROR_ITEM_NOT_FOUND; + + ALOGV("context-fd=%d\n", context->fd); + + pthread_mutex_init(&mutex, NULL); + + OUTMSG(""); + return TEEC_SUCCESS; +} + +/* + * This function destroys an initialized TEE Context, closing the connection + * between the Client and the TEE. + * The function implementation MUST do nothing if context is NULL + */ +void TEEC_FinalizeContext(TEEC_Context *context) +{ + if (context) + close(context->fd); +} + +/* + * Allocates or registers shared memory. + */ +TEEC_Result TEEC_AllocateSharedMemory(TEEC_Context *context, + TEEC_SharedMemory *shared_memory) +{ + struct tee_shm_io shm; + size_t size; + uint32_t flags; + + if (context == NULL || shared_memory == NULL) + return TEEC_ERROR_BAD_PARAMETERS; + + size = shared_memory->size; + flags = shared_memory->flags; + memset(shared_memory, 0, sizeof(TEEC_SharedMemory)); + shared_memory->size = size; + shared_memory->flags = flags; + + memset((void *)&shm, 0, sizeof(shm)); + shm.buffer = NULL; + shm.size = size; + shm.registered = 0; + shm.fd_shm = 0; + shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT; + if (ioctl(context->fd, TEE_ALLOC_SHM_IOC, &shm) != 0) { + EMSG("Ioctl(TEE_ALLOC_SHM_IOC) failed! (%s)\n", + strerror(errno)); + return TEEC_ERROR_OUT_OF_MEMORY; + } + + DMSG("fd %d size %d flags %08x", shared_memory->d.fd, + (int)shared_memory->size, shared_memory->flags); + + shared_memory->size = size; + shared_memory->d.fd = shm.fd_shm; + + /* + * Map memory to current user space process. + * + * Adjust the size in case it is 0 as, from the spec: + * The size is allowed to be zero. In this case memory is + * allocated and the pointer written in to the buffer field + * on return MUST not be NULL but MUST never be de-referenced + * by the Client Application. In this case however, the + * Shared Memory block can be used in Registered Memory References + */ + shared_memory->buffer = mmap(NULL, + (shared_memory->size == + 0) ? 8 : shared_memory->size, + PROT_READ | PROT_WRITE, MAP_SHARED, + shared_memory->d.fd, 0); + if (shared_memory->buffer == (void *)MAP_FAILED) { + EMSG("Mmap failed (%s)\n", strerror(errno)); + shared_memory->buffer = NULL; + close(shared_memory->d.fd); + return TEEC_ERROR_OUT_OF_MEMORY; + } + + shared_memory->registered = 0; + return TEEC_SUCCESS; +} + +/* + * Releases shared memory. + */ +void TEEC_ReleaseSharedMemory(TEEC_SharedMemory *shared_memory) +{ + if (!shared_memory) + return; + + if (shared_memory->registered) + return; + + if (shared_memory->d.fd != 0) { + munmap(shared_memory->buffer, (shared_memory->size == + 0) ? 8 : shared_memory->size); + close(shared_memory->d.fd); + shared_memory->d.fd = 0; + } + + shared_memory->buffer = NULL; +} + +/* + * Register shared memory + */ +TEEC_Result TEEC_RegisterSharedMemory(TEEC_Context *context, + TEEC_SharedMemory *shared_memory) +{ + if (!context || !shared_memory) + return TEEC_ERROR_BAD_PARAMETERS; + + shared_memory->registered = 1; + + /* Use a default fd when not using the dma_buf framework */ + if (!(shared_memory->flags & TEEC_MEM_DMABUF)) + shared_memory->d.fd = 0; + + return TEEC_SUCCESS; +} + +/* + * This function opens a new Session between the Client application and the + * specified TEE application. + * + * Only connection_method == TEEC_LOGIN_PUBLIC is supported connection_data and + * operation shall be set to NULL. + */ +TEEC_Result TEEC_OpenSession(TEEC_Context *context, + TEEC_Session *session, + const TEEC_UUID *destination, + uint32_t connection_method, + const void *connection_data, + TEEC_Operation *operation, uint32_t *error_origin) +{ + TEEC_Operation dummy_op; + uint32_t origin = TEEC_ORIGIN_API; + TEEC_Result res = TEEC_SUCCESS; + (void)connection_data; + struct tee_cmd_io cmd; + + if (session != NULL) + session->fd = -1; + + if ((context == NULL) || (session == NULL)) { + res = TEEC_ERROR_BAD_PARAMETERS; + goto error; + } + + if (connection_method != TEEC_LOGIN_PUBLIC) { + res = TEEC_ERROR_NOT_SUPPORTED; + goto error; + } + + teec_resetTeeCmd(&cmd); + cmd.uuid = (TEEC_UUID *)destination; + + if (operation == NULL) { + /* + * The code here exist because Global Platform API states that + * it is allowed to give operation as a NULL pointer. In kernel + * and secure world we in most cases don't want this to be NULL, + * hence we use this dummy operation when a client doesn't + * provide any operation. + */ + memset(&dummy_op, 0, sizeof(TEEC_Operation)); + operation = &dummy_op; + } + + cmd.op = operation; + + ALOGV("context-fd=%d\n", context->fd); + ALOGV("TEEC_OpenSession\n"); + ALOGV("TEE_OPEN_SESSION_IOC=0x%x\n", TEE_OPEN_SESSION_IOC); + + errno = 0; + if (ioctl(context->fd, TEE_OPEN_SESSION_IOC, &cmd) != 0) { + EMSG("Ioctl(TEE_OPEN_SESSION_IOC) failed! (%s) err %08x ori %08x\n", + strerror(errno), cmd.err, cmd.origin); + if (cmd.origin) + origin = cmd.origin; + else + origin = TEEC_ORIGIN_COMMS; + if (cmd.err) + res = cmd.err; + else + res = TEEC_ERROR_COMMUNICATION; + goto error; + } + session->fd = cmd.fd_sess; + + if (cmd.err != 0) { + EMSG("open session to TA UUID %x %x %x failed\n", + destination->timeLow, + destination->timeMid, destination->timeHiAndVersion); + } + origin = cmd.origin; + res = cmd.err; + +error: + // printf("**** res=0x%08x, org=%d, seeid=%d ***\n", res, origin, cmd.fd_sess) + + /* + * We do this check at the end instead of checking on every place where + * we set the error origin. + */ + if (res != TEEC_SUCCESS) { + if (session != NULL && session->fd != -1) { + close(session->fd); + session->fd = -1; + } + if (context) + close(context->fd); + } + + if (error_origin != NULL) + *error_origin = origin; + + return res; +} + +/* + * This function closes a session which has been opened with a TEE + * application. + */ +void TEEC_CloseSession(TEEC_Session *session) +{ + if (session == NULL) + return; + + close(session->fd); +} + +/* + * Invokes a TEE command (secure service, sub-PA or whatever). + */ +TEEC_Result TEEC_InvokeCommand(TEEC_Session *session, + uint32_t cmd_id, + TEEC_Operation *operation, + uint32_t *error_origin) +{ + INMSG("session: [%p], cmd_id: [%d]", session, cmd_id); + struct tee_cmd_io cmd; + TEEC_Operation dummy_op; + TEEC_Result result = TEEC_SUCCESS; + uint32_t origin = TEEC_ORIGIN_API; + + if (session == NULL) { + origin = TEEC_ORIGIN_API; + result = TEEC_ERROR_BAD_PARAMETERS; + goto error; + } + + if (operation == NULL) { + /* + * The code here exist because Global Platform API states that + * it is allowed to give operation as a NULL pointer. In kernel + * and secure world we in most cases don't want this to be NULL, + * hence we use this dummy operation when a client doesn't + * provide any operation. + */ + memset(&dummy_op, 0, sizeof(TEEC_Operation)); + operation = &dummy_op; + } + + teec_mutex_lock(&mutex); + operation->session = session; + teec_mutex_unlock(&mutex); + + teec_resetTeeCmd(&cmd); + + cmd.cmd = cmd_id; + cmd.op = operation; + + if (ioctl(session->fd, TEE_INVOKE_COMMAND_IOC, &cmd) != 0) + EMSG("Ioctl(TEE_INVOKE_COMMAND_IOC) failed! (%s)\n", + strerror(errno)); + + if (operation != NULL) { + teec_mutex_lock(&mutex); + + operation->session = NULL; + + teec_mutex_unlock(&mutex); + } + + origin = cmd.origin; + result = cmd.err; + ALOGV("cmd = 0x%x, cmd.err = %d \n", cmd.cmd, cmd.err); + +error: + + if (error_origin != NULL) + *error_origin = origin; + + OUTRMSG(result); +} + +void TEEC_RequestCancellation(TEEC_Operation *operation) +{ + struct tee_cmd_io cmd; + TEEC_Session *session; + + if (operation == NULL) + return; + + teec_mutex_lock(&mutex); + session = operation->session; + teec_mutex_unlock(&mutex); + + if (session == NULL) + return; + + teec_resetTeeCmd(&cmd); + + cmd.op = operation; + + if (ioctl(session->fd, TEE_REQUEST_CANCELLATION_IOC, &cmd) != 0) + EMSG("Ioctl(TEE_REQUEST_CANCELLATION_IOC) failed! (%s)\n", + strerror(errno)); +} diff --git a/optee_client-master/libteec/src/teec_trace.c b/optee_client-master/libteec/src/teec_trace.c new file mode 100755 index 0000000..79beead --- /dev/null +++ b/optee_client-master/libteec/src/teec_trace.c @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2014, STMicroelectronics International N.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. 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. + * + * 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 AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 "teec_trace.h" + +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) + +/* + * The length of the prefix is 37, for example it looks like this: + * P = Prefix + * M = Message + * F = Function name + * L = Line number + * PPPP: MMMMM [FFFFFFFFFFFFFFF : LLLLL] + */ +#define MAX_PRINT_SIZE 256 +#define MAX_FUNC_PRINT_SIZE 32 + +#ifdef TEEC_LOG_FILE +static void log_to_file(const char *buffer) +{ + FILE *log_file; + log_file = fopen(TEEC_LOG_FILE, "a"); + + if (log_file != NULL) { + fprintf(log_file, "%s", buffer); + fclose(log_file); + log_file = NULL; + } +} +#else +#define log_to_file(buffer) +#endif + +static const char * const trace_level_strings[] = { + "", "ERR", "INF", "DBG", "FLW" +}; + +int _dprintf(const char *function, int flen, int line, int level, + const char *prefix, const char *fmt, ...) +{ + char raw[MAX_PRINT_SIZE]; + char prefixed[MAX_PRINT_SIZE]; + char *to_print = NULL; + const char *func; + int err; + va_list ap; + + va_start(ap, fmt); + err = vsnprintf(raw, sizeof(raw), fmt, ap); + va_end(ap); + + if (function) { +#ifdef TRACE_FUNC_LENGTH_CST + char func_buf[MAX_FUNC_PRINT_SIZE]; + /* Limit the function name to MAX_FUNC_PRINT_SIZE characters. */ + strncpy(func_buf, function, flen > MAX_FUNC_PRINT_SIZE ? + (MAX_FUNC_PRINT_SIZE - 1) : flen); + if (flen < (MAX_FUNC_PRINT_SIZE - 1)) { + memset(func_buf + flen, 0x20, + (MAX_FUNC_PRINT_SIZE - flen)); + } + func_buf[MAX_FUNC_PRINT_SIZE - 1] = '\0'; + func = func_buf; +#else + (void)flen; + func = function; +#endif + +#ifdef ANDROID_BUILD + /* TOD(emi): What is the syscall eq for Android ? */ + int thread_id = pthread_self(); +#else + /* + * pthread_self returns the POSIX tid which is different from + * the kernel id + */ + int thread_id = syscall(SYS_gettid); /* perf issue ? */ +#endif + + snprintf(prefixed, MAX_PRINT_SIZE, + "%s [%d] %s:%s:%d: %s", + trace_level_strings[level], thread_id, prefix, func, + line, raw); + to_print = prefixed; + } else { + to_print = raw; + } + + fprintf(stdout, "%s", to_print); + + log_to_file(to_print); + + return err; +} + +#if (defined(DEBUGLEVEL_3) || defined(DEBUGLEVEL_true) || defined(DEBUGLEVEL_4)) +void dump_buffer(const char *bname, const uint8_t *buffer, size_t blen) +{ + fprintf(stderr, "#### %s\n", bname); + + while (blen > 0) { + size_t n; + + for (n = 0; n < 16; n++) { + if (n < blen) + fprintf(stderr, "%02x ", (int)buffer[n]); + else + fprintf(stderr, " "); + + if (n == 7) + fprintf(stderr, " "); + } + + fprintf(stderr, " |"); + + for (n = 0; n < 16; n++) { + if (n < blen) { + if (isprint(buffer[n])) + fprintf(stderr, "%c", (int)buffer[n]); + else + fprintf(stderr, "."); + } + } + + fprintf(stderr, "|\n"); + + blen -= MIN(blen, 16); + buffer += 16; + } +} +#else +void dump_buffer(const char *bname, const uint8_t *buffer, size_t blen) +{ + (void)bname; + (void)buffer; + (void)blen; +} +#endif diff --git a/optee_client-master/public/tee_client_api.h b/optee_client-master/public/tee_client_api.h new file mode 100755 index 0000000..ba03e48 --- /dev/null +++ b/optee_client-master/public/tee_client_api.h @@ -0,0 +1,615 @@ +/* + * Copyright (c) 2014, STMicroelectronics International N.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. 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. + * + * 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 AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 TEE_CLIENT_API_H +#define TEE_CLIENT_API_H + +#ifndef __KERNEL__ +#include +#include +#endif /* __KERNEL__ */ + +/* + * Defines the number of available memory references in an open session or + * invoke command operation payload. + */ +#define TEEC_CONFIG_PAYLOAD_REF_COUNT 4 + +/** + * Defines the maximum size of a single shared memory block, in bytes, of both + * API allocated and API registered memory. The size is currently set to + * 512 * kB (512 * 1024). + */ +#define TEEC_CONFIG_SHAREDMEM_MAX_SIZE 0x8000 + +/** + * Flag constants indicating the type of parameters encoded inside the + * operation payload (TEEC_Operation), Type is uint32_t. + * + * TEEC_NONE The Parameter is not used + * + * TEEC_VALUE_INPUT The Parameter is a TEEC_Value tagged as input. + * + * TEEC_VALUE_OUTPUT The Parameter is a TEEC_Value tagged as output. + * + * TEEC_VALUE_INOUT The Parameter is a TEEC_Value tagged as both as + * input and output, i.e., for which both the + * behaviors of TEEC_VALUE_INPUT and + * TEEC_VALUE_OUTPUT apply. + * + * TEEC_MEMREF_TEMP_INPUT The Parameter is a TEEC_TempMemoryReference + * describing a region of memory which needs to be + * temporarily registered for the duration of the + * Operation and is tagged as input. + * + * TEEC_MEMREF_TEMP_OUTPUT Same as TEEC_MEMREF_TEMP_INPUT, but the Memory + * Reference is tagged as output. The + * Implementation may update the size field to + * reflect the required output size in some use + * cases. + * + * TEEC_MEMREF_TEMP_INOUT A Temporary Memory Reference tagged as both + * input and output, i.e., for which both the + * behaviors of TEEC_MEMREF_TEMP_INPUT and + * TEEC_MEMREF_TEMP_OUTPUT apply. + * + * TEEC_MEMREF_WHOLE The Parameter is a Registered Memory Reference + * that refers to the entirety of its parent Shared + * Memory block. The parameter structure is a + * TEEC_MemoryReference. In this structure, the + * Implementation MUST read only the parent field + * and MAY update the size field when the operation + * completes. + * + * TEEC_MEMREF_PARTIAL_INPUT A Registered Memory Reference structure that + * refers to a partial region of its parent Shared + * Memory block and is tagged as input. + * + * TEEC_MEMREF_PARTIAL_OUTPUT Registered Memory Reference structure that + * refers to a partial region of its parent Shared + * Memory block and is tagged as output. + * + * TEEC_MEMREF_PARTIAL_INOUT The Registered Memory Reference structure that + * refers to a partial region of its parent Shared + * Memory block and is tagged as both input and + * output, i.e., for which both the behaviors of + * TEEC_MEMREF_PARTIAL_INPUT and + * TEEC_MEMREF_PARTIAL_OUTPUT apply. + */ +#define TEEC_NONE 0x00000000 +#define TEEC_VALUE_INPUT 0x00000001 +#define TEEC_VALUE_OUTPUT 0x00000002 +#define TEEC_VALUE_INOUT 0x00000003 +#define TEEC_MEMREF_TEMP_INPUT 0x00000005 +#define TEEC_MEMREF_TEMP_OUTPUT 0x00000006 +#define TEEC_MEMREF_TEMP_INOUT 0x00000007 +#define TEEC_MEMREF_WHOLE 0x0000000C +#define TEEC_MEMREF_PARTIAL_INPUT 0x0000000D +#define TEEC_MEMREF_PARTIAL_OUTPUT 0x0000000E +#define TEEC_MEMREF_PARTIAL_INOUT 0x0000000F + +/** + * Flag constants indicating the data transfer direction of memory in + * TEEC_Parameter. TEEC_MEM_INPUT signifies data transfer direction from the + * client application to the TEE. TEEC_MEM_OUTPUT signifies data transfer + * direction from the TEE to the client application. Type is uint32_t. + * + * TEEC_MEM_INPUT The Shared Memory can carry data from the client + * application to the Trusted Application. + * TEEC_MEM_OUTPUT The Shared Memory can carry data from the Trusted + * Application to the client application. + * TEEC_MEM_DMABUF The Shared Memory is allocated with the dma buf api and + * not necessarily user mapped. The handle will be then the + * fd instead of the buffer + * TEEC_MEM_KAPI Shared memory is required from another Linux module. + * Dma buf file descriptor is not created. + */ +#define TEEC_MEM_INPUT 0x00000001 +#define TEEC_MEM_OUTPUT 0x00000002 +#define TEEC_MEM_DMABUF 0x00010000 +#define TEEC_MEM_KAPI 0x00020000 + +/** + * Return values. Type is TEEC_Result + * + * TEEC_SUCCESS The operation was successful. + * TEEC_ERROR_GENERIC Non-specific cause. + * TEEC_ERROR_ACCESS_DENIED Access privileges are not sufficient. + * TEEC_ERROR_CANCEL The operation was canceled. + * TEEC_ERROR_ACCESS_CONFLICT Concurrent accesses caused conflict. + * TEEC_ERROR_EXCESS_DATA Too much data for the requested operation was + * passed. + * TEEC_ERROR_BAD_FORMAT Input data was of invalid format. + * TEEC_ERROR_BAD_PARAMETERS Input parameters were invalid. + * TEEC_ERROR_BAD_STATE Operation is not valid in the current state. + * TEEC_ERROR_ITEM_NOT_FOUND The requested data item is not found. + * TEEC_ERROR_NOT_IMPLEMENTED The requested operation should exist but is not + * yet implemented. + * TEEC_ERROR_NOT_SUPPORTED The requested operation is valid but is not + * supported in this implementation. + * TEEC_ERROR_NO_DATA Expected data was missing. + * TEEC_ERROR_OUT_OF_MEMORY System ran out of resources. + * TEEC_ERROR_BUSY The system is busy working on something else. + * TEEC_ERROR_COMMUNICATION Communication with a remote party failed. + * TEEC_ERROR_SECURITY A security fault was detected. + * TEEC_ERROR_SHORT_BUFFER The supplied buffer is too short for the + * generated output. + * TEEC_ERROR_TARGET_DEAD Trusted Application has panicked + * during the operation. + */ + +/** + * Standard defined error codes. + */ +#define TEEC_SUCCESS 0x00000000 +#define TEEC_ERROR_GENERIC 0xFFFF0000 +#define TEEC_ERROR_ACCESS_DENIED 0xFFFF0001 +#define TEEC_ERROR_CANCEL 0xFFFF0002 +#define TEEC_ERROR_ACCESS_CONFLICT 0xFFFF0003 +#define TEEC_ERROR_EXCESS_DATA 0xFFFF0004 +#define TEEC_ERROR_BAD_FORMAT 0xFFFF0005 +#define TEEC_ERROR_BAD_PARAMETERS 0xFFFF0006 +#define TEEC_ERROR_BAD_STATE 0xFFFF0007 +#define TEEC_ERROR_ITEM_NOT_FOUND 0xFFFF0008 +#define TEEC_ERROR_NOT_IMPLEMENTED 0xFFFF0009 +#define TEEC_ERROR_NOT_SUPPORTED 0xFFFF000A +#define TEEC_ERROR_NO_DATA 0xFFFF000B +#define TEEC_ERROR_OUT_OF_MEMORY 0xFFFF000C +#define TEEC_ERROR_BUSY 0xFFFF000D +#define TEEC_ERROR_COMMUNICATION 0xFFFF000E +#define TEEC_ERROR_SECURITY 0xFFFF000F +#define TEEC_ERROR_SHORT_BUFFER 0xFFFF0010 +#define TEEC_ERROR_EXTERNAL_CANCEL 0xFFFF0011 +#define TEEC_ERROR_TARGET_DEAD 0xFFFF3024 + +/** + * Function error origins, of type TEEC_ErrorOrigin. These indicate where in + * the software stack a particular return value originates from. + * + * TEEC_ORIGIN_API The error originated within the TEE Client API + * implementation. + * TEEC_ORIGIN_COMMS The error originated within the underlying + * communications stack linking the rich OS with + * the TEE. + * TEEC_ORIGIN_TEE The error originated within the common TEE code. + * TEEC_ORIGIN_TRUSTED_APP The error originated within the Trusted Application + * code. + */ +#define TEEC_ORIGIN_API 0x00000001 +#define TEEC_ORIGIN_COMMS 0x00000002 +#define TEEC_ORIGIN_TEE 0x00000003 +#define TEEC_ORIGIN_TRUSTED_APP 0x00000004 + +/** + * Session login methods, for use in TEEC_OpenSession() as parameter + * connectionMethod. Type is uint32_t. + * + * TEEC_LOGIN_PUBLIC No login data is provided. + * TEEC_LOGIN_USER Login data about the user running the Client + * Application process is provided. + * TEEC_LOGIN_GROUP Login data about the group running the Client + * Application process is provided. + * TEEC_LOGIN_APPLICATION Login data about the running Client Application + * itself is provided. + */ +#define TEEC_LOGIN_PUBLIC 0x00000000 +#define TEEC_LOGIN_USER 0x00000001 +#define TEEC_LOGIN_GROUP 0x00000002 +#define TEEC_LOGIN_APPLICATION 0x00000004 + +/** + * Encode the paramTypes according to the supplied types. + * + * @param p0 The first param type. + * @param p1 The second param type. + * @param p2 The third param type. + * @param p3 The fourth param type. + */ +#define TEEC_PARAM_TYPES(p0, p1, p2, p3) \ + ((p0) | ((p1) << 4) | ((p2) << 8) | ((p3) << 12)) + +/** + * Get the i_th param type from the paramType. + * + * @param p The paramType. + * @param i The i-th parameter to get the type for. + */ +#define TEEC_PARAM_TYPE_GET(p, i) (((p) >> (i * 4)) & 0xF) + +typedef uint32_t TEEC_Result; + +/** + * struct TEEC_Context - Represents a connection between a client application + * and a TEE. + * + * Context identifier can be a handle (when opened from user land) + * or a structure pointer (when opened from kernel land). + * Identifier is defined as an union to match type sizes on all architectures. + */ +typedef struct { + char devname[256]; + union { + struct tee_context *ctx; + int fd; + }; +} TEEC_Context; + +/** + * This type contains a Universally Unique Resource Identifier (UUID) type as + * defined in RFC4122. These UUID values are used to identify Trusted + * Applications. + */ +typedef struct { + uint32_t timeLow; + uint16_t timeMid; + uint16_t timeHiAndVersion; + uint8_t clockSeqAndNode[8]; +} TEEC_UUID; + +/** + * In terms of compatible kernel, the data struct shared by client application + * and TEE driver should be restructrued in "compatible" rules. To keep GP's + * standard in compatibility mode, the anonymous padding members are filled + * in the struct definition below. + */ + + +/** + * struct TEEC_SharedMemory - Memory to transfer data between a client + * application and trusted code. + * + * @param buffer The memory buffer which is to be, or has been, shared + * with the TEE. + * @param size The size, in bytes, of the memory buffer. + * @param flags Bit-vector which holds properties of buffer. + * The bit-vector can contain either or both of the + * TEEC_MEM_INPUT and TEEC_MEM_OUTPUT flags. + * + * A shared memory block is a region of memory allocated in the context of the + * client application memory space that can be used to transfer data between + * that client application and a trusted application. The user of this struct + * is responsible to populate the buffer pointer. + */ +typedef struct { + union { + void *buffer; + uint64_t padding_ptr; + }; + union { + size_t size; + uint64_t padding_sz; + }; + uint32_t flags; + /* + * Implementation-Defined, must match what the kernel driver have + * + * Identifier can store a handle (int) or a structure pointer (void *). + * Define this union to match case where sizeof(int)!=sizeof(void *). + */ + uint32_t reserved; + union { + int fd; + void *ptr; + uint64_t padding_d; + } d; + uint64_t registered; +} TEEC_SharedMemory; + +/** + * struct TEEC_TempMemoryReference - Temporary memory to transfer data between + * a client application and trusted code, only used for the duration of the + * operation. + * + * @param buffer The memory buffer which is to be, or has been shared with + * the TEE. + * @param size The size, in bytes, of the memory buffer. + * + * A memory buffer that is registered temporarily for the duration of the + * operation to be called. + */ +typedef struct { + union { + void *buffer; + uint64_t padding_ptr; + }; + union { + size_t size; + uint64_t padding_sz; + }; +} TEEC_TempMemoryReference; + +/** + * struct TEEC_RegisteredMemoryReference - use a pre-registered or + * pre-allocated shared memory block of memory to transfer data between + * a client application and trusted code. + * + * @param parent Points to a shared memory structure. The memory reference + * may utilize the whole shared memory or only a part of it. + * Must not be NULL + * + * @param size The size, in bytes, of the memory buffer. + * + * @param offset The offset, in bytes, of the referenced memory region from + * the start of the shared memory block. + * + */ +typedef struct { + union { + TEEC_SharedMemory *parent; + uint64_t padding_ptr; + }; + union { + size_t size; + uint64_t padding_sz; + }; + union { + size_t offset; + uint64_t padding_off; + }; +} TEEC_RegisteredMemoryReference; + +/** + * struct TEEC_Value - Small raw data container + * + * Instead of allocating a shared memory buffer this structure can be used + * to pass small raw data between a client application and trusted code. + * + * @param a The first integer value. + * + * @param b The second second value. + */ +typedef struct { + uint32_t a; + uint32_t b; +} TEEC_Value; + +/** + * union TEEC_Parameter - Memory container to be used when passing data between + * client application and trusted code. + * + * Either the client uses a shared memory reference, parts of it or a small raw + * data container. + * + * @param tmpref A temporary memory reference only valid for the duration + * of the operation. + * + * @param memref The entire shared memory or parts of it. + * + * @param value The small raw data container to use + */ +typedef union { + TEEC_TempMemoryReference tmpref; + TEEC_RegisteredMemoryReference memref; + TEEC_Value value; +} TEEC_Parameter; + +/** + * struct TEEC_Session - Represents a connection between a client application + * and a trusted application. + * + * Session identifier can be a handle (when opened from user land) or a + * structure pointer (when opened from kernel land). + * Identifier is defined as an union to match type sizes on all architectures. + */ +typedef union { + int fd; + struct tee_session *session; +} TEEC_Session; + +/** + * struct TEEC_Operation - Holds information and memory references used in + * TEEC_InvokeCommand(). + * + * @param started Client must initialize to zero if it needs to cancel + * an operation about to be performed. + * @param paramTypes Type of data passed. Use TEEC_PARAMS_TYPE macro to + * create the correct flags. + * 0 means TEEC_NONE is passed for all params. + * @param params Array of parameters of type TEEC_Parameter. + * @param session Internal pointer to the last session used by + * TEEC_InvokeCommand with this operation. + * + */ +typedef struct { + uint32_t started; + uint32_t paramTypes; + TEEC_Parameter params[TEEC_CONFIG_PAYLOAD_REF_COUNT]; + /* Implementation-Defined */ + union { + TEEC_Session *session; + uint64_t padding_ptr; + }; + TEEC_SharedMemory memRefs[TEEC_CONFIG_PAYLOAD_REF_COUNT]; + uint64_t flags; +} TEEC_Operation; + + +#ifdef __cplusplus +extern "C" { +#endif +/** + * TEEC_InitializeContext() - Initializes a context holding connection + * information on the specific TEE, designated by the name string. + + * @param name A zero-terminated string identifying the TEE to connect to. + * If name is set to NULL, the default TEE is connected to. NULL + * is the only supported value in this version of the API + * implementation. + * + * @param context The context structure which is to be initialized. + * + * @return TEEC_SUCCESS The initialization was successful. + * @return TEEC_Result Something failed. + */ +TEEC_Result TEEC_InitializeContext(const char *name, TEEC_Context *context); + +/** + * TEEC_FinalizeContext() - Destroys a context holding connection information + * on the specific TEE. + * + * This function destroys an initialized TEE context, closing the connection + * between the client application and the TEE. This function must only be + * called when all sessions related to this TEE context have been closed and + * all shared memory blocks have been released. + * + * @param context The context to be destroyed. + */ +void TEEC_FinalizeContext(TEEC_Context *context); + +/** + * TEEC_OpenSession() - Opens a new session with the specified trusted + * application. + * + * @param context The initialized TEE context structure in which + * scope to open the session. + * @param session The session to initialize. + * @param destination A structure identifying the trusted application + * with which to open a session. + * + * @param connectionMethod The connection method to use. + * @param connectionData Any data necessary to connect with the chosen + * connection method. Not supported, should be set to + * NULL. + * @param operation An operation structure to use in the session. May + * be set to NULL to signify no operation structure + * needed. + * + * @param returnOrigin A parameter which will hold the error origin if + * this function returns any value other than + * TEEC_SUCCESS. + * + * @return TEEC_SUCCESS OpenSession successfully opened a new session. + * @return TEEC_Result Something failed. + * + */ +TEEC_Result TEEC_OpenSession(TEEC_Context *context, + TEEC_Session *session, + const TEEC_UUID *destination, + uint32_t connectionMethod, + const void *connectionData, + TEEC_Operation *operation, + uint32_t *returnOrigin); + +/** + * TEEC_CloseSession() - Closes the session which has been opened with the + * specific trusted application. + * + * @param session The opened session to close. + */ +void TEEC_CloseSession(TEEC_Session *session); + +/** + * TEEC_InvokeCommand() - Executes a command in the specified trusted + * application. + * + * @param session A handle to an open connection to the trusted + * application. + * @param commandID Identifier of the command in the trusted application + * to invoke. + * @param operation An operation structure to use in the invoke command. + * May be set to NULL to signify no operation structure + * needed. + * @param returnOrigin A parameter which will hold the error origin if this + * function returns any value other than TEEC_SUCCESS. + * + * @return TEEC_SUCCESS OpenSession successfully opened a new session. + * @return TEEC_Result Something failed. + */ +TEEC_Result TEEC_InvokeCommand(TEEC_Session *session, + uint32_t commandID, + TEEC_Operation *operation, + uint32_t *returnOrigin); + +/** + * TEEC_RegisterSharedMemory() - Register a block of existing memory as a + * shared block within the scope of the specified context. + * + * @param context The initialized TEE context structure in which scope to + * open the session. + * @param sharedMem pointer to the shared memory structure to register. + * + * @return TEEC_SUCCESS The registration was successful. + * @return TEEC_ERROR_OUT_OF_MEMORY Memory exhaustion. + * @return TEEC_Result Something failed. + */ +TEEC_Result TEEC_RegisterSharedMemory(TEEC_Context *context, + TEEC_SharedMemory *sharedMem); + +/** + * TEEC_AllocateSharedMemory() - Allocate shared memory for TEE. + * + * @param context The initialized TEE context structure in which scope to + * open the session. + * @param sharedMem Pointer to the allocated shared memory. + * + * @return TEEC_SUCCESS The registration was successful. + * @return TEEC_ERROR_OUT_OF_MEMORY Memory exhaustion. + * @return TEEC_Result Something failed. + */ +TEEC_Result TEEC_AllocateSharedMemory(TEEC_Context *context, + TEEC_SharedMemory *sharedMem); + +/** + * TEEC_ReleaseSharedMemory() - Free or deregister the shared memory. + * + * @param sharedMem Pointer to the shared memory to be freed. + */ +void TEEC_ReleaseSharedMemory(TEEC_SharedMemory *sharedMemory); + +/** + * TEEC_RequestCancellation() - Request the cancellation of a pending open + * session or command invocation. + * + * @param operation Pointer to an operation previously passed to open session + * or invoke. + */ +void TEEC_RequestCancellation(TEEC_Operation *operation); + +/** + * Register a pre-allocated Trusted Application This is mainly intended for + * OS-FREE contexts or when a filesystem is not available. + * + * @param ta Pointer to the trusted application binary + * @param size The size of the TA binary + * + * @return TEEC_SUCCESS if successful. + * @return TEEC_Result something failed. + */ +TEEC_Result TEEC_RegisterTA(const void *ta, const size_t size); + +/** + * Unregister a pre-allocated Trusted Application This is mainly intended for + * OS-FREE contexts or when a filesystem is not available. + * + * @param ta Pointer to the trusted application binary + */ +void TEEC_UnregisterTA(const void *ta); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/optee_client-master/public/teec_trace.h b/optee_client-master/public/teec_trace.h new file mode 100755 index 0000000..0a6ffd1 --- /dev/null +++ b/optee_client-master/public/teec_trace.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2014, STMicroelectronics International N.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. 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. + * + * 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 AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 TEEC_TRACE_H +#define TEEC_TRACE_H +#include +#include +#include + +#ifndef BINARY_PREFIX +#error "BINARY_PREFIX not defined" +#endif + +/* + * Trace levels. + * + * ERROR is used when some kind of error has happened, this is most likely the + * print you will use most of the time when you report some kind of error. + * + * INFO is used when you want to print some 'normal' text to the user. + * This is the default level. + * + * DEBUG is used to print extra information to enter deeply in the module. + * + * FLOW is used to print the execution flox, typically the in/out of functions. + * + * */ +#define DEBUGLEVEL_0 1 + +#define TRACE_ERROR 1 +#define TRACE_INFO 2 +#define TRACE_DEBUG 3 +#define TRACE_FLOW 4 + +#if defined(DEBUGLEVEL_0) && !defined(DEBUGLEVEL) +#define DEBUGLEVEL TRACE_ERROR +#endif + +#if defined(DEBUGLEVEL_1) && !defined(DEBUGLEVEL) +#define DEBUGLEVEL TRACE_ERROR +#endif + +#if defined(DEBUGLEVEL_2) && !defined(DEBUGLEVEL) +#define DEBUGLEVEL TRACE_INFO +#endif + +#if defined(DEBUGLEVEL_3) && !defined(DEBUGLEVEL) +#define DEBUGLEVEL TRACE_DEBUG +#endif + +#if defined(DEBUGLEVEL_4) && !defined(DEBUGLEVEL) +#define DEBUGLEVEL TRACE_FLOW +#endif + +#ifndef DEBUGLEVEL +/* Default debug level. */ +#define DEBUGLEVEL TRACE_INFO +#endif + +/* + * This define make sure that parameters are checked in the same manner as it + * is done in the normal printf function. + */ +#define __PRINTFLIKE(__fmt, __varargs) __attribute__\ + ((__format__(__printf__, __fmt, __varargs))) + +int _dprintf(const char *function, int flen, int line, int level, + const char *prefix, const char *fmt, ...) __PRINTFLIKE(6, 7); + +#define dprintf(level, x...) do { \ + if ((level) <= DEBUGLEVEL) { \ + _dprintf(__func__, strlen(__func__), __LINE__, level, \ + BINARY_PREFIX, x); \ + } \ + } while (0) + +#define EMSG(fmt, ...) dprintf(TRACE_ERROR, fmt "\n", ##__VA_ARGS__) +#define IMSG(fmt, ...) dprintf(TRACE_INFO, fmt "\n", ##__VA_ARGS__) +#define DMSG(fmt, ...) dprintf(TRACE_DEBUG, fmt "\n", ##__VA_ARGS__) +#define FMSG(fmt, ...) dprintf(TRACE_FLOW, fmt "\n", ##__VA_ARGS__) + +#define INMSG(fmt, ...) FMSG("> " fmt, ##__VA_ARGS__) +#define OUTMSG(fmt, ...) FMSG("< " fmt, ##__VA_ARGS__) +#define OUTRMSG(r) \ + do { \ + if (r) \ + EMSG("Function returns with [%d]", r); \ + OUTMSG("r=[%d]", r); \ + return r; \ + } while (0) + +#define dprintf_raw(level, x...) do { \ + if ((level) <= DEBUGLEVEL) \ + _dprintf(0, 0, 0, (level), BINARY_PREFIX, x); \ + } while (0) + +#define EMSG_RAW(fmt, ...) dprintf_raw(TRACE_ERROR, fmt, ##__VA_ARGS__) +#define IMSG_RAW(fmt, ...) dprintf_raw(TRACE_INFO, fmt, ##__VA_ARGS__) +#define DMSG_RAW(fmt, ...) dprintf_raw(TRACE_DEBUG, fmt, ##__VA_ARGS__) +#define FMSG_RAW(fmt, ...) dprintf_raw(TRACE_FLOW, fmt, ##__VA_ARGS__) + +/* + * This function will hex and ascii dump a buffer. + * + * Note that this function will only print if debug flag + * DEBUGLEVEL is INFO or FLOOD. + * + * @param bname Information string describing the buffer. + * @param buffer Pointer to the buffer. + * @param blen Length of the buffer. + * + * @return void + */ +void dump_buffer(const char *bname, const uint8_t *buffer, size_t blen); + +#endif diff --git a/optee_client-master/tee-supplicant/Makefile b/optee_client-master/tee-supplicant/Makefile new file mode 100755 index 0000000..f05306c --- /dev/null +++ b/optee_client-master/tee-supplicant/Makefile @@ -0,0 +1,47 @@ +include ../flags.mk + +OUT_DIR ?= ${CURDIR}/../$(O)/tee-supplicant + +.PHONY: all tee-supplicant clean + +all: tee-supplicant +################################################################################ +# Teec configuration +################################################################################ +PACKAGE_NAME := tee-supplicant + +TEES_SRCS := tee_supplicant.c \ + teec_ta_load.c \ + tee_supp_fs.c \ + handle.c + +TEES_SRC_DIR := src +TEES_OBJ_DIR := $(OUT_DIR) +TEES_OBJS := $(patsubst %.c,$(TEES_OBJ_DIR)/%.o, $(TEES_SRCS)) +TEES_INCLUDES := ${CURDIR}/../libteec/include \ + ${CURDIR}/src \ + ${CURDIR}/../public \ + +TEES_CFLAGS := $(addprefix -I, $(TEES_INCLUDES)) $(CFLAGS) \ + -DDEBUGLEVEL_$(CFG_TEE_SUPP_LOG_LEVEL) \ + -DBINARY_PREFIX=\"TEES\" +TEES_FILE := $(OUT_DIR)/$(PACKAGE_NAME) +TEES_LDFLAGS := -L$(OUT_DIR)/../libteec -lteec + +tee-supplicant: $(TEES_FILE) + +$(TEES_FILE): $(TEES_OBJS) + @echo " LD $@" + $(VPREFIX)$(CC) -o $@ $+ $(TEES_LDFLAGS) + @echo "" + +$(TEES_OBJ_DIR)/%.o: $(TEES_SRC_DIR)/%.c + $(VPREFIX)mkdir -p $(dir $@) + @echo " CC $<" + $(VPREFIX)$(CC) $(TEES_CFLAGS) -c $< -o $@ + +################################################################################ +# Cleaning up configuration +################################################################################ +clean: + $(RM) $(OUT_DIR) diff --git a/optee_client-master/tee-supplicant/src/handle.c b/optee_client-master/tee-supplicant/src/handle.c new file mode 100755 index 0000000..b58f56f --- /dev/null +++ b/optee_client-master/tee-supplicant/src/handle.c @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2014, Linaro Limited + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. 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. + * + * 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 AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 "handle.h" + +/* + * Define the initial capacity of the database. It should be a low number + * multiple of 2 since some databases a likely to only use a few handles. + * Since the algorithm is to doubles up when growing it shouldn't cause a + * noticable overhead on large databases. + */ +#define HANDLE_DB_INITIAL_MAX_PTRS 4 + +static void mutex_lock(struct handle_db *db) +{ + if (db->mu) + pthread_mutex_lock(db->mu); +} + +static void mutex_unlock(struct handle_db *db) +{ + if (db->mu) + pthread_mutex_unlock(db->mu); +} + + +void handle_db_set_mutex(struct handle_db *db, pthread_mutex_t *mu) +{ + db->mu = mu; +} + +void handle_db_destroy(struct handle_db *db) +{ + if (db) { + mutex_lock(db); + free(db->ptrs); + db->ptrs = NULL; + db->max_ptrs = 0; + mutex_unlock(db); + } +} + +int handle_get(struct handle_db *db, void *ptr) +{ + size_t n; + void *p; + size_t new_max_ptrs; + int ret; + + if (!db || !ptr) + return -1; + + mutex_lock(db); + + /* Try to find an empty location */ + for (n = 0; n < db->max_ptrs; n++) { + if (!db->ptrs[n]) { + db->ptrs[n] = ptr; + ret = n; + goto out; + } + } + + /* No location available, grow the ptrs array */ + if (db->max_ptrs) + new_max_ptrs = db->max_ptrs * 2; + else + new_max_ptrs = HANDLE_DB_INITIAL_MAX_PTRS; + p = realloc(db->ptrs, new_max_ptrs * sizeof(void *)); + if (!p) { + ret = -1; + goto out; + } + db->ptrs = p; + memset(db->ptrs + db->max_ptrs, 0, + (new_max_ptrs - db->max_ptrs) * sizeof(void *)); + db->max_ptrs = new_max_ptrs; + + /* Since n stopped at db->max_ptrs there is an empty location there */ + db->ptrs[n] = ptr; + ret = n; + +out: + mutex_unlock(db); + return ret; +} + +void *handle_put(struct handle_db *db, int handle) +{ + void *p; + + if (!db || handle < 0) + return NULL; + + mutex_lock(db); + + if ((size_t)handle >= db->max_ptrs) { + p = NULL; + goto out; + } + + p = db->ptrs[handle]; + db->ptrs[handle] = NULL; + +out: + mutex_unlock(db); + return p; +} + +void *handle_lookup(struct handle_db *db, int handle) +{ + void *p; + + if (!db || handle < 0) + return NULL; + + mutex_lock(db); + + if ((size_t)handle >= db->max_ptrs) { + p = NULL; + goto out; + } + + p = db->ptrs[handle]; + +out: + mutex_unlock(db); + return p; +} diff --git a/optee_client-master/tee-supplicant/src/handle.h b/optee_client-master/tee-supplicant/src/handle.h new file mode 100755 index 0000000..304ff52 --- /dev/null +++ b/optee_client-master/tee-supplicant/src/handle.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2014, Linaro Limited + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. 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. + * + * 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 AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 HANDLE_H +#define HANDLE_H + +#include +#include + +struct handle_db { + void **ptrs; + size_t max_ptrs; + pthread_mutex_t *mu; +}; + +#define HANDLE_DB_INITIALIZER { NULL, 0, NULL } +#define HANDLE_DB_INITIALIZER_WITH_MUTEX(mu) { NULL, 0, (mu) } + +/* + * Assigns a mutex for the database. If mu != NULL the mutex will be + * acquired before each access to the database and released when + * the operation is done. + */ +void handle_db_set_mutex(struct handle_db *db, pthread_mutex_t *mu); + +/* + * Frees all internal data structures of the database, but does not free + * the db pointer. The database is safe to reuse after it's destroyed, it + * just be empty again. The assigned mutex is also preserved. + */ +void handle_db_destroy(struct handle_db *db); + +/* + * Allocates a new handle and assigns the supplied pointer to it, + * ptr must not be NULL. + * The function returns + * >= 0 on success and + * -1 on failure + */ +int handle_get(struct handle_db *db, void *ptr); + +/* + * Deallocates a handle. Returns the assiciated pointer of the handle + * the the handle was valid or NULL if it's invalid. + */ +void *handle_put(struct handle_db *db, int handle); + +/* + * Returns the assiciated pointer of the handle if the handle is a valid + * handle. + * Returns NULL on failure. + */ +void *handle_lookup(struct handle_db *db, int handle); + +#endif /*HANDLE_H*/ diff --git a/optee_client-master/tee-supplicant/src/tee_supp_fs.c b/optee_client-master/tee-supplicant/src/tee_supp_fs.c new file mode 100755 index 0000000..f67352f --- /dev/null +++ b/optee_client-master/tee-supplicant/src/tee_supp_fs.c @@ -0,0 +1,504 @@ +/* + * Copyright (c) 2014, STMicroelectronics International N.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. 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. + * + * 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 AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + +/* + * Operations and defines shared with TEE. + */ +#define TEE_FS_OPEN 1 +#define TEE_FS_CLOSE 2 +#define TEE_FS_READ 3 +#define TEE_FS_WRITE 4 +#define TEE_FS_SEEK 5 +#define TEE_FS_UNLINK 6 +#define TEE_FS_RENAME 7 +#define TEE_FS_TRUNC 8 +#define TEE_FS_MKDIR 9 +#define TEE_FS_OPENDIR 10 +#define TEE_FS_CLOSEDIR 11 +#define TEE_FS_READDIR 12 +#define TEE_FS_RMDIR 13 +#define TEE_FS_ACCESS 14 +#define TEE_FS_LINK 15 + +/* + * Open flags, defines shared with TEE. + */ +#define TEE_FS_O_RDONLY 0x1 +#define TEE_FS_O_WRONLY 0x2 +#define TEE_FS_O_RDWR 0x4 +#define TEE_FS_O_CREAT 0x8 +#define TEE_FS_O_EXCL 0x10 +#define TEE_FS_O_APPEND 0x20 + +/* + * Seek flags, defines shared with TEE. + */ +#define TEE_FS_SEEK_SET 0x1 +#define TEE_FS_SEEK_END 0x2 +#define TEE_FS_SEEK_CUR 0x4 + +/* + * Mkdir flags, defines shared with TEE. + */ +#define TEE_FS_S_IWUSR 0x1 +#define TEE_FS_S_IRUSR 0x2 + +/* + * Access flags, X_OK not supported, defines shared with TEE. + */ +#define TEE_FS_R_OK 0x1 +#define TEE_FS_W_OK 0x2 +#define TEE_FS_F_OK 0x4 + +/* Path to all secure storage files. */ +#define TEE_FS_SUBPATH "/data" +#define TEE_FS_PATH "/data/tee/" + +#ifndef PATH_MAX +#define PATH_MAX 255 +#endif + +#define TEE_FS_FILENAME_MAX_LENGTH 150 + +/* + * Structure for file related RPC calls + * + * @op The operation like open, close, read, write etc + * @flags Flags to the operation shared with secure world + * @arg Argument to operation + * @fd NW file descriptor + * @len Length of buffer at the end of this struct + * @res Result of the operation + */ +struct tee_fs_rpc { + int op; + int flags; + int arg; + int fd; + uint32_t len; + int res; +}; + +static pthread_mutex_t dir_handle_db_mutex = PTHREAD_MUTEX_INITIALIZER; +static struct handle_db dir_handle_db = + HANDLE_DB_INITIALIZER_WITH_MUTEX(&dir_handle_db_mutex); + +/* Function to convert TEE open flags to UNIX IO */ +static int tee_fs_conv_oflags(int in) +{ + int flags = 0; + + if (in & TEE_FS_O_RDONLY) + flags |= O_RDONLY; + + if (in & TEE_FS_O_WRONLY) + flags |= O_WRONLY; + + if (in & TEE_FS_O_RDWR) + flags |= O_RDWR; + + if (in & TEE_FS_O_CREAT) + flags |= O_CREAT; + + if (in & TEE_FS_O_EXCL) + flags |= O_EXCL; + + if (in & TEE_FS_O_APPEND) + flags |= O_APPEND; + + return flags; +} + +/* Function to convert TEE seek flags to UNIX IO */ +static int tee_fs_conv_whence(int in) +{ + int flags = 0; + + if (in & TEE_FS_SEEK_SET) + flags |= SEEK_SET; + + if (in & TEE_FS_SEEK_END) + flags |= SEEK_END; + + if (in & TEE_FS_SEEK_CUR) + flags |= SEEK_CUR; + + return flags; +} + +/* Function to convert TEE open flags to UNIX IO */ +static mode_t tee_fs_conv_mkdflags(int in) +{ + int flags = 0; + + if (in & TEE_FS_S_IWUSR) + flags |= S_IWUSR; + + if (in & TEE_FS_S_IRUSR) + flags |= S_IRUSR; + + return flags; +} + +static int tee_fs_conv_accessflags(int in) +{ + int flags = 0; + + if (in & TEE_FS_R_OK) + flags |= R_OK; + + if (in & TEE_FS_W_OK) + flags |= W_OK; + + if (in & TEE_FS_F_OK) + flags |= F_OK; + + return flags; +} + +static size_t tee_fs_get_absolute_filename(char *file, char *out, + size_t out_size) +{ + int s; + + if (!file || !out || (out_size <= sizeof(TEE_FS_PATH))) + return 0; + + s = snprintf(out, out_size, "%s%s", TEE_FS_PATH, file); + if (s < 0 || (size_t)s >= out_size) + return 0; + + /* Safe to cast since we have checked that sizes are OK */ + return (size_t)s; +} + +static int tee_fs_open(struct tee_fs_rpc *fsrpc) +{ + char abs_filename[PATH_MAX]; + char *filename = (char *)(fsrpc + 1); + int flags; + size_t filesize = tee_fs_get_absolute_filename(filename, abs_filename, + sizeof(abs_filename)); + if (!filesize) + return -1; /* Corresponds to error using open */ + + flags = tee_fs_conv_oflags(fsrpc->flags); + fsrpc->fd = open(abs_filename, flags, S_IRUSR | S_IWUSR); + return fsrpc->fd; +} + +static int tee_fs_close(struct tee_fs_rpc *fsrpc) +{ + return close(fsrpc->fd); +} + +static int tee_fs_read(struct tee_fs_rpc *fsrpc) +{ + void *data = (void *)(fsrpc + 1); + + return read(fsrpc->fd, data, fsrpc->len); +} + +static int tee_fs_write(struct tee_fs_rpc *fsrpc) +{ + void *data = (void *)(fsrpc + 1); + + return write(fsrpc->fd, data, fsrpc->len); +} + +static int tee_fs_seek(struct tee_fs_rpc *fsrpc) +{ + int wh = tee_fs_conv_whence(fsrpc->flags); + + fsrpc->res = lseek(fsrpc->fd, fsrpc->arg, wh); + + return fsrpc->res; +} + +static int tee_fs_unlink(struct tee_fs_rpc *fsrpc) +{ + char abs_filename[PATH_MAX]; + char *filename = (char *)(fsrpc + 1); + int ret = -1; /* Corresponds to error using unlink */ + size_t filesize = tee_fs_get_absolute_filename(filename, abs_filename, + sizeof(abs_filename)); + if (filesize) + ret = unlink(abs_filename); + + return ret; +} + +static int tee_fs_link(struct tee_fs_rpc *fsrpc) +{ + char old_fn[PATH_MAX]; + char new_fn[PATH_MAX]; + char *filenames = (char *)(fsrpc + 1); + int ret = -1; /* Corresponds to error value for link */ + + /* + * During a link operation secure world sends the two NULL terminated + * filenames as a single concatenated string, as for example: + * "old.txt\0new.txt\0" + * Therefore we start by finding the offset to where the new filename + * begins. + */ + size_t offset_new_fn = strlen(filenames) + 1; + size_t filesize = tee_fs_get_absolute_filename(filenames, old_fn, + sizeof(old_fn)); + if (!filesize) + goto exit; + + filesize = tee_fs_get_absolute_filename(filenames + offset_new_fn, + new_fn, sizeof(new_fn)); + if (filesize) + ret = link(old_fn, new_fn); + +exit: + return ret; +} + +static int tee_fs_rename(struct tee_fs_rpc *fsrpc) +{ + char old_fn[PATH_MAX]; + char new_fn[PATH_MAX]; + char *filenames = (char *)(fsrpc + 1); + int ret = -1; /* Corresponds to error value for rename */ + + /* + * During a rename operation secure world sends the two NULL terminated + * filenames as a single concatenated string, as for example: + * "old.txt\0new.txt\0" + * Therefore we start by finding the offset to where the new filename + * begins. + */ + size_t offset_new_fn = strlen(filenames) + 1; + size_t filesize = tee_fs_get_absolute_filename(filenames, old_fn, + sizeof(old_fn)); + if (!filesize) + goto exit; + + filesize = tee_fs_get_absolute_filename(filenames + offset_new_fn, + new_fn, sizeof(new_fn)); + if (filesize) + ret = rename(old_fn, new_fn); + +exit: + return ret; +} + +static int tee_fs_truncate(struct tee_fs_rpc *fsrpc) +{ + return ftruncate(fsrpc->fd, fsrpc->arg); +} + +static int tee_fs_mkdir(struct tee_fs_rpc *fsrpc) +{ + char abs_dirname[PATH_MAX]; + char *dirname = (char *)(fsrpc + 1); + mode_t mode; + int ret = -1; /* Same as mkir on error */ + size_t filesize = tee_fs_get_absolute_filename(dirname, abs_dirname, + sizeof(abs_dirname)); + + if (filesize) { + mode = tee_fs_conv_mkdflags(fsrpc->flags); + ret = mkdir(abs_dirname, mode); + } + + return ret; +} + +static int tee_fs_opendir(struct tee_fs_rpc *fsrpc) +{ + char abs_dirname[PATH_MAX]; + char *dirname = (char *)(fsrpc + 1); + DIR *dir; + int handle = -1; + size_t filesize = tee_fs_get_absolute_filename(dirname, abs_dirname, + sizeof(abs_dirname)); + if (!filesize) + goto exit; + + dir = opendir(abs_dirname); + if (!dir) + goto exit; + + handle = handle_get(&dir_handle_db, dir); + if (handle < 0) + closedir(dir); +exit: + return handle; +} + +static int tee_fs_closedir(struct tee_fs_rpc *fsrpc) +{ + DIR *dir = handle_put(&dir_handle_db, fsrpc->arg); + + return closedir(dir); +} + +static int tee_fs_readdir(struct tee_fs_rpc *fsrpc) +{ + char *dirname = (char *)(fsrpc + 1); + DIR *dir = handle_lookup(&dir_handle_db, fsrpc->arg); + struct dirent *dirent; + size_t len; + + do + dirent = readdir(dir); + while (dirent != NULL && dirent->d_name[0] == '.'); + + if (dirent == NULL) { + fsrpc->len = 0; + return -1; + } + + len = strlen(dirent->d_name); + if (len > PATH_MAX) + return -1; + + len++; + memcpy(dirname, dirent->d_name, len); + fsrpc->len = len; + + return 0; +} + +static int tee_fs_rmdir(struct tee_fs_rpc *fsrpc) +{ + char abs_dirname[PATH_MAX]; + char *dirname = (char *)(fsrpc + 1); + int ret = -1; /* Corresponds to the error value for rmdir */ + size_t filesize = tee_fs_get_absolute_filename(dirname, abs_dirname, + sizeof(abs_dirname)); + + if (filesize) + ret = rmdir(abs_dirname); + + return ret; +} + +static int tee_fs_access(struct tee_fs_rpc *fsrpc) +{ + char abs_filename[PATH_MAX]; + char *filename = (char *)(fsrpc + 1); + int flags; + int ret = -1; /* Corresponds to the error value for access */ + size_t filesize = tee_fs_get_absolute_filename(filename, abs_filename, + sizeof(abs_filename)); + if (filesize) { + flags = tee_fs_conv_accessflags(fsrpc->flags); + ret = access(abs_filename, flags); + } + + return ret; +} + +int tee_supp_fs_init(void) +{ + struct stat st; + + mkdir(TEE_FS_SUBPATH, 0700); + mkdir(TEE_FS_PATH, 0700); + if (stat(TEE_FS_PATH, &st) != 0) + return -1; + return 0; +} + +int tee_supp_fs_process(void *cmd, size_t cmd_size) +{ + struct tee_fs_rpc *fsrpc = cmd; + int ret = -1; + + if (cmd_size < sizeof(struct tee_fs_rpc)) + return ret; + + if (cmd == NULL) + return ret; + + switch (fsrpc->op) { + case TEE_FS_OPEN: + ret = tee_fs_open(fsrpc); + break; + case TEE_FS_CLOSE: + ret = tee_fs_close(fsrpc); + break; + case TEE_FS_READ: + ret = tee_fs_read(fsrpc); + break; + case TEE_FS_WRITE: + ret = tee_fs_write(fsrpc); + break; + case TEE_FS_SEEK: + ret = tee_fs_seek(fsrpc); + break; + case TEE_FS_UNLINK: + ret = tee_fs_unlink(fsrpc); + break; + case TEE_FS_RENAME: + ret = tee_fs_rename(fsrpc); + break; + case TEE_FS_TRUNC: + ret = tee_fs_truncate(fsrpc); + break; + case TEE_FS_MKDIR: + ret = tee_fs_mkdir(fsrpc); + break; + case TEE_FS_OPENDIR: + ret = tee_fs_opendir(fsrpc); + break; + case TEE_FS_CLOSEDIR: + ret = tee_fs_closedir(fsrpc); + break; + case TEE_FS_READDIR: + ret = tee_fs_readdir(fsrpc); + break; + case TEE_FS_RMDIR: + ret = tee_fs_rmdir(fsrpc); + break; + case TEE_FS_ACCESS: + ret = tee_fs_access(fsrpc); + break; + case TEE_FS_LINK: + ret = tee_fs_link(fsrpc); + default: + break; + } + + fsrpc->res = ret; + + return ret; +} diff --git a/optee_client-master/tee-supplicant/src/tee_supp_fs.h b/optee_client-master/tee-supplicant/src/tee_supp_fs.h new file mode 100755 index 0000000..3d14a98 --- /dev/null +++ b/optee_client-master/tee-supplicant/src/tee_supp_fs.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2014, STMicroelectronics International N.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. 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. + * + * 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 AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 TEE_SUPP_FS_H +#define TEE_SUPP_FS_H + +#include + +int tee_supp_fs_init(void); + +int tee_supp_fs_process(void *cmd, size_t cmd_size); + +#endif diff --git a/optee_client-master/tee-supplicant/src/tee_supplicant.c b/optee_client-master/tee-supplicant/src/tee_supplicant.c new file mode 100755 index 0000000..fd6c9b2 --- /dev/null +++ b/optee_client-master/tee-supplicant/src/tee_supplicant.c @@ -0,0 +1,487 @@ +/* + * Copyright (c) 2014, STMicroelectronics International N.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. 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. + * + * 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 AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#define TEE_RPC_BUFFER_NUMBER 5 + +/* Flags of the shared memory. Also defined in tee_service.h in the kernel. */ +/* + * Maximum size of the device name + */ +#define TEEC_MAX_DEVNAME_SIZE 256 + +char devname1[TEEC_MAX_DEVNAME_SIZE]; +char devname2[TEEC_MAX_DEVNAME_SIZE]; + +struct tee_rpc_cmd { + union { + void *buffer; + uint64_t padding_buf; + }; + uint32_t size; + uint32_t type; + int fd; + int reserved; +}; + +struct tee_rpc_invoke { + uint32_t cmd; + uint32_t res; + uint32_t nbr_bf; + uint32_t reserved; + struct tee_rpc_cmd cmds[TEE_RPC_BUFFER_NUMBER]; +}; + +struct tee_rpc_ta { + TEEC_UUID uuid; + uint32_t supp_ta_handle; +}; + +static int read_request(int fd, struct tee_rpc_invoke *request); +static void write_response(int fd, struct tee_rpc_invoke *request); +static void free_param(TEEC_SharedMemory *shared_mem); + +struct share_mem_entry { + TEEC_SharedMemory shared_mem; + TAILQ_ENTRY(share_mem_entry) link; +}; +static TAILQ_HEAD(, share_mem_entry) shared_memory_list = + TAILQ_HEAD_INITIALIZER(shared_memory_list); + +static void free_all_shared_memory(void) +{ + struct share_mem_entry *entry; + + DMSG(">"); + while (!TAILQ_EMPTY(&shared_memory_list)) { + entry = TAILQ_FIRST(&shared_memory_list); + TAILQ_REMOVE(&shared_memory_list, entry, link); + free_param(&entry->shared_mem); + free(entry); + } + DMSG("<"); +} + +static void free_shared_memory(int fd) +{ + struct share_mem_entry *entry; + + TAILQ_FOREACH(entry, &shared_memory_list, link) + if (entry->shared_mem.d.fd == fd) + break; + + if (!entry) { + EMSG("Cannot find fd=%d\n", fd); + return; + } + + free_param(&entry->shared_mem); + + TAILQ_REMOVE(&shared_memory_list, entry, link); + free(entry); +} + +static TEEC_SharedMemory *add_shared_memory(int fd, size_t size) +{ + struct tee_shm_io shm; + TEEC_SharedMemory *shared_mem; + struct share_mem_entry *entry; + + entry = calloc(1, sizeof(struct share_mem_entry)); + if (!entry) + return NULL; + + shared_mem = &entry->shared_mem; + + memset((void *)&shm, 0, sizeof(shm)); + shm.buffer = NULL; + shm.size = size; + shm.registered = 0; + shm.fd_shm = 0; + shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT; + if (ioctl(fd, TEE_ALLOC_SHM_IOC, &shm) != 0) { + EMSG("Ioctl(TEE_ALLOC_SHM_IOC) failed! (%s)", strerror(errno)); + shared_mem = NULL; + goto out; + } + + shared_mem->size = size; + shared_mem->d.fd = shm.fd_shm; + + shared_mem->buffer = mmap(NULL, size, + PROT_READ | PROT_WRITE, MAP_SHARED, + shared_mem->d.fd, 0); + + if (shared_mem->buffer == (void *)MAP_FAILED) { + EMSG("mmap(%zu) failed - Error = %s", size, strerror(errno)); + close(shared_mem->d.fd); + shared_mem = NULL; + goto out; + } + + TAILQ_INSERT_TAIL(&shared_memory_list, entry, link); +out: + if (!shared_mem) + free(entry); + + return shared_mem; +} + +/* Get parameter allocated by secure world */ +static int get_param(int fd, struct tee_rpc_invoke *inv, const uint32_t idx, + TEEC_SharedMemory *shared_mem) +{ + struct tee_shm_io shm; + + if (idx >= inv->nbr_bf) + return -1; + + memset((void *)&shm, 0, sizeof(shm)); + + shm.buffer = inv->cmds[idx].buffer; + shm.size = inv->cmds[idx].size; + shm.registered = 0; + shm.fd_shm = 0; + shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT; + + if (ioctl(fd, TEE_GET_FD_FOR_RPC_SHM_IOC, &shm) != 0) { + EMSG("Ioctl(TEE_ALLOC_SHM_IOC) failed! (%s)", strerror(errno)); + return -1; + } + + memset(shared_mem, 0, sizeof(TEEC_SharedMemory)); + shared_mem->size = shm.size; + shared_mem->flags = shm.flags; + shared_mem->d.fd = shm.fd_shm; + + DMSG("size %u fd_shm %d", (int)shared_mem->size, shared_mem->d.fd); + + shared_mem->buffer = mmap(NULL, shared_mem->size, + PROT_READ | PROT_WRITE, MAP_SHARED, + shared_mem->d.fd, 0); + + if (shared_mem->buffer == (void *)MAP_FAILED) { + dprintf(TRACE_ERROR, "mmap(%d, %p) failed - Error = %s\n", + inv->cmds[idx].size, inv->cmds[idx].buffer, + strerror(errno)); + close(shared_mem->d.fd); + return -1; + } + /* Erase value, since we don't want to send back input memory to TEE. */ + inv->cmds[idx].buffer = 0; + + return 0; +} + +/* Allocate new parameter to be used in RPC communication */ +static TEEC_SharedMemory *alloc_param(int fd, struct tee_rpc_invoke *inv, + const uint32_t idx, size_t size) +{ + TEEC_SharedMemory *shared_mem; + + if (idx >= inv->nbr_bf) { + EMSG("idx %d >= inv->nbr_bf %d", idx, inv->nbr_bf); + return NULL; + } + + if (inv->cmds[idx].buffer != NULL) { + EMSG("cmd[idx].buffer != NULL"); + return NULL; + } + + shared_mem = add_shared_memory(fd, size); + if (shared_mem == 0) { + EMSG("add_shared_memory() returned NULL"); + return NULL; + } + + inv->cmds[idx].buffer = shared_mem->buffer; + inv->cmds[idx].size = size; + inv->cmds[idx].type = TEE_RPC_BUFFER; + inv->cmds[idx].fd = shared_mem->d.fd; + + return shared_mem; +} + +/* Release parameter recieved from get_param or alloc_param */ +static void free_param(TEEC_SharedMemory *shared_mem) +{ + INMSG("%p %u (%p)", shared_mem->buffer, + (int)shared_mem->size, shared_mem); + if (munmap(shared_mem->buffer, shared_mem->size) != 0) + EMSG("munmap(%p, %u) failed - Error = %s", + shared_mem->buffer, (int)shared_mem->size, + strerror(errno)); + close(shared_mem->d.fd); + OUTMSG(); +} + +static void process_fs(int fd, struct tee_rpc_invoke *inv) +{ + TEEC_SharedMemory shared_mem; + + INMSG(); + if (get_param(fd, inv, 0, &shared_mem)) { + inv->res = TEEC_ERROR_BAD_PARAMETERS; + return; + } + + tee_supp_fs_process(shared_mem.buffer, shared_mem.size); + inv->res = TEEC_SUCCESS;; + + free_param(&shared_mem); + OUTMSG(); +} + +static void load_ta(int fd, struct tee_rpc_invoke *inv) +{ + void *ta = NULL; + int ta_found = 0; + size_t size = 0; + struct tee_rpc_ta *cmd; + TEEC_SharedMemory shared_mem; + + INMSG(); + if (get_param(fd, inv, 0, &shared_mem)) { + inv->res = TEEC_ERROR_BAD_PARAMETERS; + return; + } + cmd = (struct tee_rpc_ta *)shared_mem.buffer; + + ta_found = TEECI_LoadSecureModule(NULL, &cmd->uuid, &ta, &size); + /* Tracked by 6408 */ + if (ta_found != TA_BINARY_FOUND) + ta_found = TEECI_LoadSecureModule(devname2, &cmd->uuid, &ta, &size); + + if (ta_found != TA_BINARY_FOUND) + ta_found = TEECI_LoadSecureModule_ext(&cmd->uuid, &ta, &size); + + if (ta_found == TA_BINARY_FOUND) { + TEEC_SharedMemory *ta_shm = alloc_param(fd, inv, 1, size); + + if (!ta_shm) { + inv->res = TEEC_ERROR_OUT_OF_MEMORY; + } else { + inv->res = TEEC_SUCCESS; + + memcpy(ta_shm->buffer, ta, size); + + /* Fd will come back from TEE for unload. */ + cmd->supp_ta_handle = ta_shm->d.fd; + } + + free(ta); + } else { + EMSG(" TA not found"); + inv->res = TEEC_ERROR_ITEM_NOT_FOUND; + } + + free_param(&shared_mem); + OUTMSG(); +} + +static void free_ta(struct tee_rpc_invoke *inv) +{ + INMSG(); + free_shared_memory(inv->cmds[0].fd); + inv->nbr_bf = 0; + inv->res = TEEC_SUCCESS; + OUTMSG(); +} + +static void get_ree_time(int fd, struct tee_rpc_invoke *inv) +{ + struct TEE_Time { + uint32_t seconds; + uint32_t millis; + }; + struct timeval tv; + + TEEC_SharedMemory shared_mem; + struct TEE_Time *tee_time; + + INMSG(); + if (get_param(fd, inv, 0, &shared_mem)) { + inv->res = TEEC_ERROR_BAD_PARAMETERS; + return; + } + + tee_time = (struct TEE_Time *)shared_mem.buffer; + gettimeofday(&tv, NULL); + + tee_time->seconds = tv.tv_sec; + tee_time->millis = tv.tv_usec / 1000; + + DMSG("%ds:%dms", tee_time->seconds, tee_time->millis); + + inv->res = TEEC_SUCCESS; + + /* Unmap the memory. */ + free_param(&shared_mem); + OUTMSG(); +} + +int main(int argc, char *argv[]) +{ + int fd; + int n = 0; + char devpath[TEEC_MAX_DEVNAME_SIZE]; + struct tee_rpc_invoke request; + int ret; + + sprintf(devpath, "/dev/opteearmtz00"); + sprintf(devname1, "optee_armtz"); + sprintf(devname2, "teetz"); + + while (--argc) { + n++; + if (strncmp(argv[n], "opteearmtz00", 12) == 0) { + snprintf(devpath, TEEC_MAX_DEVNAME_SIZE, "%s", "/dev/opteearmtz00"); + snprintf(devname1, TEEC_MAX_DEVNAME_SIZE, "%s", "optee_armtz"); + snprintf(devname2, TEEC_MAX_DEVNAME_SIZE, "%s", "teetz"); + } else { + EMSG("Invalid argument #%d", n); + exit(EXIT_FAILURE); + } + } + + fd = open(devpath, O_RDWR); + if (fd < 0) { + EMSG("error opening [%s]", devpath); + exit(EXIT_FAILURE); + } + + if (tee_supp_fs_init() != 0) { + EMSG("error tee_supp_fs_init"); + exit(EXIT_FAILURE); + } + + IMSG("tee-supplicant running on %s", devpath); + + /* major failure on read kills supplicant, malformed data will not */ + do { + DMSG("looping"); + ret = read_request(fd, &request); + if (ret == 0) { + switch (request.cmd) { + case TEE_RPC_LOAD_TA: + load_ta(fd, &request); + break; + + case TEE_RPC_FREE_TA: + free_ta(&request); + break; + + case TEE_RPC_GET_TIME: + get_ree_time(fd, &request); + break; + + case TEE_RPC_FS: + process_fs(fd, &request); + break; + default: + EMSG("Cmd [0x%" PRIx32 "] not supported", + request.cmd); + /* Not supported. */ + break; + } + write_response(fd, &request); + } + } while (ret >= 0); + free_all_shared_memory(); + close(fd); + + return EXIT_SUCCESS; +} + +static int read_request(int fd, struct tee_rpc_invoke *request) +{ + ssize_t res = 0; + + if (fd < 0) { + EMSG("invalid fd"); + return -1; + } + + res = read(fd, request, sizeof(*request)); + if (res < 0) + return -1; + + if ((size_t)res < sizeof(*request) - sizeof(request->cmds)) { + EMSG("error reading from driver"); + return 1; + } + + if (sizeof(*request) - sizeof(request->cmds) + + sizeof(request->cmds[0]) * request->nbr_bf != (size_t)res) { + DMSG("length read does not equal expected length"); + return 1; + } + + return 0; +} + +static void write_response(int fd, struct tee_rpc_invoke *request) +{ + size_t writesize; + size_t res; + + if (fd < 0) { + EMSG("invalid fd"); + return; + } + + writesize = sizeof(*request) - sizeof(request->cmds) + + sizeof(request->cmds[0]) * request->nbr_bf; + + res = write(fd, request, writesize); + if (res != writesize) + EMSG("error writing to device (%zu)", res); +} diff --git a/optee_client-master/tee-supplicant/src/teec_rpc.h b/optee_client-master/tee-supplicant/src/teec_rpc.h new file mode 100755 index 0000000..adc3354 --- /dev/null +++ b/optee_client-master/tee-supplicant/src/teec_rpc.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2014, STMicroelectronics International N.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. 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. + * + * 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 AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 TEEC_RPC_H +#define TEEC_RPC_H + +#define TEE_RPC_LOAD_TA 0x10000001 +#define TEE_RPC_FREE_TA 0x10000009 +#define TEE_RPC_RPMB_CMD 0x1000000A +#define TEE_RPC_FS 0x10000010 +#define TEE_RPC_GET_TIME 0x10000011 + +#define TEE_RPC_BUFFER 0x00000001 +#define TEE_RPC_VALUE 0x00000002 + +#endif diff --git a/optee_client-master/tee-supplicant/src/teec_ta_load.c b/optee_client-master/tee-supplicant/src/teec_ta_load.c new file mode 100755 index 0000000..72114c6 --- /dev/null +++ b/optee_client-master/tee-supplicant/src/teec_ta_load.c @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2014, STMicroelectronics International N.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. 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. + * + * 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 AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + +#ifndef TEEC_LOAD_PATH +#define TEEC_LOAD_PATH "/lib" +#endif + +#ifndef PATH_MAX +#define PATH_MAX 255 +#endif + +struct tee_rpc_cmd { + void *buffer; + uint32_t size; + uint32_t type; + int fd; +}; + +/* + * Based on the uuid this function will try to find a TA-binary on the + * filesystem and return it back to the caller in the parameter ta. + * + * @param: destination The uuid of the TA we are searching for. + * @param: ta A pointer which this function will allocate and copy + * the TA from the filesystem to the pointer itself. It is + * the callers responsibility to free the pointer. + * @param: ta_size The size of the TA found on file system. It will be 0 + * if no TA was not found. + * + * @return 0 if TA was found, otherwise -1. + */ +int TEECI_LoadSecureModule(const char* dev_path, + const TEEC_UUID *destination, void **ta, + size_t *ta_size) +{ + char fname[PATH_MAX]; + FILE *file = NULL; + int n; + + if (!ta_size || !ta || !destination) { + printf("wrong inparameter to TEECI_LoadSecureModule\n"); + return TA_BINARY_NOT_FOUND; + } + + if(dev_path != NULL){ + n = snprintf(fname, PATH_MAX, + "%s/%s/%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x.ta", + TEEC_LOAD_PATH, dev_path, + destination->timeLow, + destination->timeMid, + destination->timeHiAndVersion, + destination->clockSeqAndNode[0], + destination->clockSeqAndNode[1], + destination->clockSeqAndNode[2], + destination->clockSeqAndNode[3], + destination->clockSeqAndNode[4], + destination->clockSeqAndNode[5], + destination->clockSeqAndNode[6], + destination->clockSeqAndNode[7]); + } + else{ + n = snprintf(fname, PATH_MAX, + "%s/%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x.ta", + "/system/bin", + destination->timeLow, + destination->timeMid, + destination->timeHiAndVersion, + destination->clockSeqAndNode[0], + destination->clockSeqAndNode[1], + destination->clockSeqAndNode[2], + destination->clockSeqAndNode[3], + destination->clockSeqAndNode[4], + destination->clockSeqAndNode[5], + destination->clockSeqAndNode[6], + destination->clockSeqAndNode[7]); + } + + DMSG("Attempt to load %s\n", fname); + ALOGE("Attempt to load %s\n", fname); + + if ((n < 0) || (n >= PATH_MAX)) { + EMSG("wrong TA path [%s]", fname); + return TA_BINARY_NOT_FOUND; + } + + file = fopen(fname, "r"); + if (file == NULL) { + DMSG("failed to open the ta %s TA-file", fname); + return TA_BINARY_NOT_FOUND; + } + + if (fseek(file, 0, SEEK_END) != 0) { + fclose(file); + return TA_BINARY_NOT_FOUND; + } + + *ta_size = ftell(file); + + if (fseek(file, 0, SEEK_SET) != 0) { + fclose(file); + return TA_BINARY_NOT_FOUND; + } + + *ta = malloc(*ta_size); + if (*ta == NULL) { + printf("OOM: failed allocating ta\n"); + fclose(file); + return TA_BINARY_NOT_FOUND; + } + + if (*ta_size != fread(*ta, 1, *ta_size, file)) { + printf("error fread TA file\n"); + free(*ta); + fclose(file); + return TA_BINARY_NOT_FOUND; + } + + fclose(file); + return TA_BINARY_FOUND; +} + + +int TEECI_LoadSecureModule_ext( + const TEEC_UUID *destination, void **ta, + size_t *ta_size) +{ + char fname[PATH_MAX]; + FILE *file = NULL; + int n; + + if (!ta_size || !ta || !destination) { + ALOGE("wrong inparameter to TEECI_LoadSecureModule\n"); + return TA_BINARY_NOT_FOUND; + } + + n = snprintf(fname, PATH_MAX, + "%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x.ta", + destination->timeLow, + destination->timeMid, + destination->timeHiAndVersion, + destination->clockSeqAndNode[0], + destination->clockSeqAndNode[1], + destination->clockSeqAndNode[2], + destination->clockSeqAndNode[3], + destination->clockSeqAndNode[4], + destination->clockSeqAndNode[5], + destination->clockSeqAndNode[6], + destination->clockSeqAndNode[7]); + + DMSG("Attempt to load %s\n", fname); + ALOGW("Attempt to load %s\n", fname); + + if ((n < 0) || (n >= PATH_MAX)) { + ALOGE("wrong TA path [%s]", fname); + return TA_BINARY_NOT_FOUND; + } + + file = fopen(fname, "r"); + if (file == NULL) { + ALOGE("failed to open the ta %s TA-file, errno=%d", fname, errno); + return TA_BINARY_NOT_FOUND; + } +ALOGW("%s %d\n", __FILE__, __LINE__); + if (fseek(file, 0, SEEK_END) != 0) { + fclose(file); + return TA_BINARY_NOT_FOUND; + } +ALOGW("%s %d\n", __FILE__, __LINE__); + *ta_size = ftell(file); + //makesure the size not 8byte align +ALOGW("%s %d\n", __FILE__, __LINE__); + if (fseek(file, 0, SEEK_SET) != 0) { + fclose(file); + return TA_BINARY_NOT_FOUND; + } +ALOGW("%s %d\n", __FILE__, __LINE__); + *ta = malloc(*ta_size); + if (*ta == NULL) { + printf("OOM: failed allocating ta\n"); + fclose(file); + return TA_BINARY_NOT_FOUND; + } +ALOGW("%s %d\n", __FILE__, __LINE__); + if (*ta_size != fread(*ta, 1, *ta_size, file)) { + printf("error fread TA file\n"); + free(*ta); + fclose(file); + return TA_BINARY_NOT_FOUND; + } + + fclose(file); +ALOGW("%s %d\n", __FILE__, __LINE__); + return TA_BINARY_FOUND; +} + diff --git a/optee_client-master/tee-supplicant/src/teec_ta_load.h b/optee_client-master/tee-supplicant/src/teec_ta_load.h new file mode 100755 index 0000000..e40112c --- /dev/null +++ b/optee_client-master/tee-supplicant/src/teec_ta_load.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014, STMicroelectronics International N.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. 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. + * + * 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 AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 _TEEC_TA_LOAD_H +#define _TEEC_TA_LOAD_H +#include + +#define TA_BINARY_FOUND 0 +#define TA_BINARY_NOT_FOUND -1 + +/** + * Based on the uuid this function will try to find a TA-binary on the + * filesystem and return it back to the caller in the parameter ta. + * + * @param: destination The uuid of the TA we are searching for. + * @param: ta A pointer which this function will allocate and copy + * the TA from the filesystem to the pointer itself. It is + * the callers responsibility to free the pointer. + * @param: ta_size The size of the TA found on file system. It will be 0 + * if no TA was not found. + * + * @return 0 if TA was found, otherwise -1. + */ +int TEECI_LoadSecureModule(const char *name, + const TEEC_UUID *destination, void **ta, + size_t *ta_size); + +int TEECI_LoadSecureModule_ext( + const TEEC_UUID *destination, void **ta, + size_t *ta_size); + +#endif diff --git a/widevine/Android.mk b/widevine/Android.mk index 2903734..af1a891 100755 --- a/widevine/Android.mk +++ b/widevine/Android.mk @@ -1,2 +1,7 @@ LOCAL_PATH:= $(call my-dir) -include $(LOCAL_PATH)/widevine_L$(BOARD_WIDEVINE_OEMCRYPTO_LEVEL)/Android.mk + +ifeq ($(SECURE_OS_OPTEE), yes) + include $(LOCAL_PATH)/adapt_optee/widevine_L$(BOARD_WIDEVINE_OEMCRYPTO_LEVEL)/Android.mk +else + include $(LOCAL_PATH)/adapt_semelis/widevine_L$(BOARD_WIDEVINE_OEMCRYPTO_LEVEL)/Android.mk +endif diff --git a/widevine/widevine_L3/Android.mk b/widevine/adapt_optee/widevine_L1/Android.mk similarity index 99% rename from widevine/widevine_L3/Android.mk rename to widevine/adapt_optee/widevine_L1/Android.mk index 3c41e6a..a970eb7 100755 --- a/widevine/widevine_L3/Android.mk +++ b/widevine/adapt_optee/widevine_L1/Android.mk @@ -38,7 +38,6 @@ LOCAL_MODULE_SUFFIX := .so LOCAL_SRC_FILES := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX) LOCAL_PROPRIETARY_MODULE := true #LOCAL_STRIP_MODULE := true - LOCAL_MULTILIB := 32 LOCAL_MODULE_TAGS := optional include $(BUILD_PREBUILT) diff --git a/widevine/widevine_L1/CleanSpec.mk b/widevine/adapt_optee/widevine_L1/CleanSpec.mk old mode 100644 new mode 100755 similarity index 100% rename from widevine/widevine_L1/CleanSpec.mk rename to widevine/adapt_optee/widevine_L1/CleanSpec.mk diff --git a/widevine/adapt_optee/widevine_L1/com.google.widevine.software.drm.jar b/widevine/adapt_optee/widevine_L1/com.google.widevine.software.drm.jar new file mode 100755 index 0000000..9e53c11 Binary files /dev/null and b/widevine/adapt_optee/widevine_L1/com.google.widevine.software.drm.jar differ diff --git a/widevine/widevine_L1/com.google.widevine.software.drm.xml b/widevine/adapt_optee/widevine_L1/com.google.widevine.software.drm.xml old mode 100644 new mode 100755 similarity index 100% rename from widevine/widevine_L1/com.google.widevine.software.drm.xml rename to widevine/adapt_optee/widevine_L1/com.google.widevine.software.drm.xml diff --git a/widevine/adapt_optee/widevine_L1/libWVStreamControlAPI_L1.so b/widevine/adapt_optee/widevine_L1/libWVStreamControlAPI_L1.so new file mode 100755 index 0000000..df92b26 Binary files /dev/null and b/widevine/adapt_optee/widevine_L1/libWVStreamControlAPI_L1.so differ diff --git a/widevine/adapt_optee/widevine_L1/libdrmdecrypt.so b/widevine/adapt_optee/widevine_L1/libdrmdecrypt.so new file mode 100755 index 0000000..4cf1549 Binary files /dev/null and b/widevine/adapt_optee/widevine_L1/libdrmdecrypt.so differ diff --git a/widevine/adapt_optee/widevine_L1/libdrmwvmplugin.so b/widevine/adapt_optee/widevine_L1/libdrmwvmplugin.so new file mode 100755 index 0000000..a2a14b3 Binary files /dev/null and b/widevine/adapt_optee/widevine_L1/libdrmwvmplugin.so differ diff --git a/widevine/adapt_optee/widevine_L1/liboemcrypto.so b/widevine/adapt_optee/widevine_L1/liboemcrypto.so new file mode 100755 index 0000000..4a2bda0 Binary files /dev/null and b/widevine/adapt_optee/widevine_L1/liboemcrypto.so differ diff --git a/widevine/adapt_optee/widevine_L1/libwvdrm_L1.so b/widevine/adapt_optee/widevine_L1/libwvdrm_L1.so new file mode 100755 index 0000000..8658aba Binary files /dev/null and b/widevine/adapt_optee/widevine_L1/libwvdrm_L1.so differ diff --git a/widevine/adapt_optee/widevine_L1/libwvdrmengine.so b/widevine/adapt_optee/widevine_L1/libwvdrmengine.so new file mode 100755 index 0000000..34a470d Binary files /dev/null and b/widevine/adapt_optee/widevine_L1/libwvdrmengine.so differ diff --git a/widevine/adapt_optee/widevine_L1/libwvm.so b/widevine/adapt_optee/widevine_L1/libwvm.so new file mode 100755 index 0000000..1a15651 Binary files /dev/null and b/widevine/adapt_optee/widevine_L1/libwvm.so differ diff --git a/widevine/widevine_L1/Android.mk b/widevine/adapt_optee/widevine_L3/Android.mk old mode 100755 new mode 100644 similarity index 60% rename from widevine/widevine_L1/Android.mk rename to widevine/adapt_optee/widevine_L3/Android.mk index d2161b1..a970eb7 --- a/widevine/widevine_L1/Android.mk +++ b/widevine/adapt_optee/widevine_L3/Android.mk @@ -3,7 +3,6 @@ LOCAL_PATH:= $(call my-dir) ################################################## include $(CLEAR_VARS) -ifeq ($(TARGET_ARCH),arm) LOCAL_MODULE := com.google.widevine.software.drm.xml LOCAL_SRC_FILES := $(LOCAL_MODULE) @@ -39,7 +38,7 @@ LOCAL_MODULE_SUFFIX := .so LOCAL_SRC_FILES := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX) LOCAL_PROPRIETARY_MODULE := true #LOCAL_STRIP_MODULE := true - +LOCAL_MULTILIB := 32 LOCAL_MODULE_TAGS := optional include $(BUILD_PREBUILT) @@ -52,10 +51,36 @@ LOCAL_MODULE_SUFFIX := .so LOCAL_SRC_FILES := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX) LOCAL_PROPRIETARY_MODULE := true #LOCAL_STRIP_MODULE := true - +LOCAL_MULTILIB := 32 LOCAL_MODULE_TAGS := optional include $(BUILD_PREBUILT) +##################################################################### +#libdrmdecrypt.so +include $(CLEAR_VARS) +LOCAL_MODULE := libdrmdecrypt +LOCAL_MODULE_CLASS := SHARED_LIBRARIES +LOCAL_MODULE_SUFFIX := .so +LOCAL_SRC_FILES := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX) +LOCAL_PROPRIETARY_MODULE := true +#LOCAL_STRIP_MODULE := true +LOCAL_MODULE_TAGS := optional +LOCAL_MULTILIB := 32 +include $(BUILD_PREBUILT) + +##################################################################### +#libwvm.so +include $(CLEAR_VARS) +LOCAL_MODULE := libwvm +LOCAL_MODULE_CLASS := SHARED_LIBRARIES +LOCAL_MODULE_SUFFIX := .so +LOCAL_SRC_FILES := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX) +LOCAL_PROPRIETARY_MODULE := true +#LOCAL_STRIP_MODULE := true +LOCAL_MODULE_TAGS := optional +LOCAL_MULTILIB := 32 +include $(BUILD_PREBUILT) + ##################################################################### #libwvdrmengine.so include $(CLEAR_VARS) @@ -65,105 +90,30 @@ LOCAL_MODULE_SUFFIX := .so LOCAL_SRC_FILES := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX) LOCAL_PROPRIETARY_MODULE := true #LOCAL_STRIP_MODULE := true -LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_SHARED_LIBRARIES)/mediadrm +#LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_SHARED_LIBRARIES)/mediadrm +LOCAL_PROPRIETARY_MODULE := true +LOCAL_MODULE_RELATIVE_PATH := mediadrm LOCAL_MODULE_TAGS := optional +LOCAL_MULTILIB := 32 include $(BUILD_PREBUILT) ##################################################################### -# liboemcrypto.a, lib1 +#libdrmwvmplugin.so include $(CLEAR_VARS) -LOCAL_PREBUILT_LIBS := \ - liboemcrypto.a \ - libdrmwvmcommon.a \ - libwvmcommon.a \ - libwvocs_L$(BOARD_WIDEVINE_OEMCRYPTO_LEVEL).a \ - libwvdecryptcommon.a - -LOCAL_MODULE_TAGS := optional -include $(BUILD_MULTI_PREBUILT) - -##################################################################### -# libdrmwvmplugin.so -include $(CLEAR_VARS) -LOCAL_WHOLE_STATIC_LIBRARIES := \ - libdrmframeworkcommon \ - libdrmwvmcommon \ - libwvocs_L$(BOARD_WIDEVINE_OEMCRYPTO_LEVEL) - -LOCAL_SHARED_LIBRARIES := \ - libbinder \ - libutils \ - libcutils \ - libstlport \ - libz \ - libwvdrm_L$(BOARD_WIDEVINE_OEMCRYPTO_LEVEL) \ - libWVStreamControlAPI_L$(BOARD_WIDEVINE_OEMCRYPTO_LEVEL) \ - libdl - -ifeq ($(BOARD_WIDEVINE_OEMCRYPTO_LEVEL),1) -LOCAL_SHARED_LIBRARIES += \ - libtee_client -endif - LOCAL_MODULE := libdrmwvmplugin -LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_SHARED_LIBRARIES)/drm -LOCAL_MODULE_TAGS := optional -LOCAL_STATIC_LIBRARIES += liboemcrypto -LOCAL_PRELINK_MODULE := false -include $(BUILD_SHARED_LIBRARY) - -##################################################################### -# libwvm.so -include $(CLEAR_VARS) - -LOCAL_WHOLE_STATIC_LIBRARIES := \ - libwvmcommon - -LOCAL_SHARED_LIBRARIES := \ - libstlport \ - libstagefright \ - libWVStreamControlAPI_L$(BOARD_WIDEVINE_OEMCRYPTO_LEVEL) \ - libdrmframework \ - libcutils \ - liblog \ - libutils - -ifeq ($(BOARD_WIDEVINE_OEMCRYPTO_LEVEL),1) -LOCAL_SHARED_LIBRARIES += \ - libtee_client -endif - -LOCAL_MODULE := libwvm +LOCAL_MODULE_CLASS := SHARED_LIBRARIES +LOCAL_MODULE_SUFFIX := .so +LOCAL_SRC_FILES := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX) LOCAL_PROPRIETARY_MODULE := true -LOCAL_MODULE_TAGS := optional -LOCAL_STATIC_LIBRARIES += liboemcrypto -LOCAL_PRELINK_MODULE := false -include $(BUILD_SHARED_LIBRARY) - -##################################################################### -#libdrmdecrypt.so -include $(CLEAR_VARS) - -LOCAL_WHOLE_STATIC_LIBRARIES := \ - libwvdecryptcommon - -LOCAL_SHARED_LIBRARIES := \ - libstagefright_foundation \ - liblog \ - libcutils \ - libcrypto - -ifeq ($(BOARD_WIDEVINE_OEMCRYPTO_LEVEL),1) -LOCAL_SHARED_LIBRARIES += \ - libtee_client -endif -LOCAL_MODULE := libdrmdecrypt +#LOCAL_STRIP_MODULE := true +#LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_SHARED_LIBRARIES)/drm LOCAL_PROPRIETARY_MODULE := true +LOCAL_MODULE_RELATIVE_PATH := drm LOCAL_MODULE_TAGS := optional -LOCAL_STATIC_LIBRARIES += liboemcrypto -LOCAL_PRELINK_MODULE := false +LOCAL_MULTILIB := 32 +include $(BUILD_PREBUILT) + -include $(BUILD_SHARED_LIBRARY) ##################################################################### #liboemcrypto.so @@ -176,7 +126,7 @@ LOCAL_SRC_FILES := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX) #LOCAL_PROPRIETARY_MODULE copies library to vendor/lib LOCAL_PROPRIETARY_MODULE := true LOCAL_MODULE_TAGS := optional +LOCAL_MULTILIB := 32 include $(BUILD_PREBUILT) endif# liboemcrypto -endif diff --git a/widevine/widevine_L3/CleanSpec.mk b/widevine/adapt_optee/widevine_L3/CleanSpec.mk old mode 100755 new mode 100644 similarity index 100% rename from widevine/widevine_L3/CleanSpec.mk rename to widevine/adapt_optee/widevine_L3/CleanSpec.mk diff --git a/widevine/adapt_optee/widevine_L3/com.google.widevine.software.drm.jar b/widevine/adapt_optee/widevine_L3/com.google.widevine.software.drm.jar new file mode 100755 index 0000000..ba8e2ce Binary files /dev/null and b/widevine/adapt_optee/widevine_L3/com.google.widevine.software.drm.jar differ diff --git a/widevine/widevine_L3/com.google.widevine.software.drm.xml b/widevine/adapt_optee/widevine_L3/com.google.widevine.software.drm.xml old mode 100755 new mode 100644 similarity index 100% rename from widevine/widevine_L3/com.google.widevine.software.drm.xml rename to widevine/adapt_optee/widevine_L3/com.google.widevine.software.drm.xml diff --git a/widevine/adapt_optee/widevine_L3/libWVStreamControlAPI_L3.so b/widevine/adapt_optee/widevine_L3/libWVStreamControlAPI_L3.so new file mode 100755 index 0000000..1fd88f9 Binary files /dev/null and b/widevine/adapt_optee/widevine_L3/libWVStreamControlAPI_L3.so differ diff --git a/widevine/adapt_optee/widevine_L3/libdrmdecrypt.so b/widevine/adapt_optee/widevine_L3/libdrmdecrypt.so new file mode 100755 index 0000000..be07cb3 Binary files /dev/null and b/widevine/adapt_optee/widevine_L3/libdrmdecrypt.so differ diff --git a/widevine/adapt_optee/widevine_L3/libdrmwvmplugin.so b/widevine/adapt_optee/widevine_L3/libdrmwvmplugin.so new file mode 100755 index 0000000..409cf4d Binary files /dev/null and b/widevine/adapt_optee/widevine_L3/libdrmwvmplugin.so differ diff --git a/widevine/adapt_optee/widevine_L3/libwvdrm_L3.so b/widevine/adapt_optee/widevine_L3/libwvdrm_L3.so new file mode 100755 index 0000000..ea8a6d9 Binary files /dev/null and b/widevine/adapt_optee/widevine_L3/libwvdrm_L3.so differ diff --git a/widevine/adapt_optee/widevine_L3/libwvdrmengine.so b/widevine/adapt_optee/widevine_L3/libwvdrmengine.so new file mode 100755 index 0000000..068c280 Binary files /dev/null and b/widevine/adapt_optee/widevine_L3/libwvdrmengine.so differ diff --git a/widevine/adapt_optee/widevine_L3/libwvm.so b/widevine/adapt_optee/widevine_L3/libwvm.so new file mode 100755 index 0000000..5a52077 Binary files /dev/null and b/widevine/adapt_optee/widevine_L3/libwvm.so differ diff --git a/widevine/adapt_semelis/widevine_L1/Android.mk b/widevine/adapt_semelis/widevine_L1/Android.mk new file mode 100755 index 0000000..a970eb7 --- /dev/null +++ b/widevine/adapt_semelis/widevine_L1/Android.mk @@ -0,0 +1,132 @@ +WIDEVINE_SUPPORTED_ARCH := arm x86 +LOCAL_PATH:= $(call my-dir) + +################################################## +include $(CLEAR_VARS) + +LOCAL_MODULE := com.google.widevine.software.drm.xml +LOCAL_SRC_FILES := $(LOCAL_MODULE) +LOCAL_MODULE_TAGS := optional + +LOCAL_MODULE_CLASS := ETC + +# This will install the file in /system/etc/permissions +# +LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions + +include $(BUILD_PREBUILT) + +######################## +# Dummy library used to indicate availability of widevine drm + +include $(CLEAR_VARS) +LOCAL_MODULE := com.google.widevine.software.drm +LOCAL_MODULE_SUFFIX := .jar +LOCAL_SRC_FILES := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX) +LOCAL_MODULE_TAGS := optional + +LOCAL_MODULE_CLASS := JAVA_LIBRARIES + +include $(BUILD_PREBUILT) +##################################################################### +#libWVStreamControlAPI_LX.so +include $(CLEAR_VARS) + +LOCAL_MODULE := libWVStreamControlAPI_L$(BOARD_WIDEVINE_OEMCRYPTO_LEVEL) +LOCAL_MODULE_CLASS := SHARED_LIBRARIES +LOCAL_MODULE_SUFFIX := .so +LOCAL_SRC_FILES := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX) +LOCAL_PROPRIETARY_MODULE := true +#LOCAL_STRIP_MODULE := true +LOCAL_MULTILIB := 32 +LOCAL_MODULE_TAGS := optional +include $(BUILD_PREBUILT) + +##################################################################### +#libwvdrm_LX.so +include $(CLEAR_VARS) +LOCAL_MODULE := libwvdrm_L$(BOARD_WIDEVINE_OEMCRYPTO_LEVEL) +LOCAL_MODULE_CLASS := SHARED_LIBRARIES +LOCAL_MODULE_SUFFIX := .so +LOCAL_SRC_FILES := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX) +LOCAL_PROPRIETARY_MODULE := true +#LOCAL_STRIP_MODULE := true +LOCAL_MULTILIB := 32 +LOCAL_MODULE_TAGS := optional +include $(BUILD_PREBUILT) + +##################################################################### +#libdrmdecrypt.so +include $(CLEAR_VARS) +LOCAL_MODULE := libdrmdecrypt +LOCAL_MODULE_CLASS := SHARED_LIBRARIES +LOCAL_MODULE_SUFFIX := .so +LOCAL_SRC_FILES := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX) +LOCAL_PROPRIETARY_MODULE := true +#LOCAL_STRIP_MODULE := true +LOCAL_MODULE_TAGS := optional +LOCAL_MULTILIB := 32 +include $(BUILD_PREBUILT) + +##################################################################### +#libwvm.so +include $(CLEAR_VARS) +LOCAL_MODULE := libwvm +LOCAL_MODULE_CLASS := SHARED_LIBRARIES +LOCAL_MODULE_SUFFIX := .so +LOCAL_SRC_FILES := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX) +LOCAL_PROPRIETARY_MODULE := true +#LOCAL_STRIP_MODULE := true +LOCAL_MODULE_TAGS := optional +LOCAL_MULTILIB := 32 +include $(BUILD_PREBUILT) + +##################################################################### +#libwvdrmengine.so +include $(CLEAR_VARS) +LOCAL_MODULE := libwvdrmengine +LOCAL_MODULE_CLASS := SHARED_LIBRARIES +LOCAL_MODULE_SUFFIX := .so +LOCAL_SRC_FILES := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX) +LOCAL_PROPRIETARY_MODULE := true +#LOCAL_STRIP_MODULE := true +#LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_SHARED_LIBRARIES)/mediadrm +LOCAL_PROPRIETARY_MODULE := true +LOCAL_MODULE_RELATIVE_PATH := mediadrm +LOCAL_MODULE_TAGS := optional +LOCAL_MULTILIB := 32 +include $(BUILD_PREBUILT) + +##################################################################### +#libdrmwvmplugin.so +include $(CLEAR_VARS) +LOCAL_MODULE := libdrmwvmplugin +LOCAL_MODULE_CLASS := SHARED_LIBRARIES +LOCAL_MODULE_SUFFIX := .so +LOCAL_SRC_FILES := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX) +LOCAL_PROPRIETARY_MODULE := true +#LOCAL_STRIP_MODULE := true +#LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_SHARED_LIBRARIES)/drm +LOCAL_PROPRIETARY_MODULE := true +LOCAL_MODULE_RELATIVE_PATH := drm +LOCAL_MODULE_TAGS := optional +LOCAL_MULTILIB := 32 +include $(BUILD_PREBUILT) + + + +##################################################################### +#liboemcrypto.so +ifeq ($(BOARD_WIDEVINE_OEMCRYPTO_LEVEL),1) +include $(CLEAR_VARS) +LOCAL_MODULE := liboemcrypto +LOCAL_MODULE_CLASS := SHARED_LIBRARIES +LOCAL_MODULE_SUFFIX := .so +LOCAL_SRC_FILES := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX) +#LOCAL_PROPRIETARY_MODULE copies library to vendor/lib +LOCAL_PROPRIETARY_MODULE := true +LOCAL_MODULE_TAGS := optional +LOCAL_MULTILIB := 32 +include $(BUILD_PREBUILT) +endif# liboemcrypto + diff --git a/widevine/adapt_semelis/widevine_L1/CleanSpec.mk b/widevine/adapt_semelis/widevine_L1/CleanSpec.mk new file mode 100755 index 0000000..49b5b9c --- /dev/null +++ b/widevine/adapt_semelis/widevine_L1/CleanSpec.mk @@ -0,0 +1,53 @@ +# 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. +# + +# 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/*) + +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/drm $(PRODUCT_OUT)/system/lib/libwv* $(PRODUCT_OUT)/system/lib/libWV*) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/cdm_protos_intermediates) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libcdm_intermediates) + +# ************************************************ +# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST +# ************************************************ diff --git a/widevine/adapt_semelis/widevine_L1/com.google.widevine.software.drm.jar b/widevine/adapt_semelis/widevine_L1/com.google.widevine.software.drm.jar new file mode 100755 index 0000000..502f061 Binary files /dev/null and b/widevine/adapt_semelis/widevine_L1/com.google.widevine.software.drm.jar differ diff --git a/widevine/adapt_semelis/widevine_L1/com.google.widevine.software.drm.xml b/widevine/adapt_semelis/widevine_L1/com.google.widevine.software.drm.xml new file mode 100755 index 0000000..f75abf9 --- /dev/null +++ b/widevine/adapt_semelis/widevine_L1/com.google.widevine.software.drm.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/widevine/adapt_semelis/widevine_L1/libWVStreamControlAPI_L1.so b/widevine/adapt_semelis/widevine_L1/libWVStreamControlAPI_L1.so new file mode 100755 index 0000000..df92b26 Binary files /dev/null and b/widevine/adapt_semelis/widevine_L1/libWVStreamControlAPI_L1.so differ diff --git a/widevine/adapt_semelis/widevine_L1/libdrmdecrypt.so b/widevine/adapt_semelis/widevine_L1/libdrmdecrypt.so new file mode 100755 index 0000000..2206b42 Binary files /dev/null and b/widevine/adapt_semelis/widevine_L1/libdrmdecrypt.so differ diff --git a/widevine/adapt_semelis/widevine_L1/libdrmwvmplugin.so b/widevine/adapt_semelis/widevine_L1/libdrmwvmplugin.so new file mode 100755 index 0000000..c8566b5 Binary files /dev/null and b/widevine/adapt_semelis/widevine_L1/libdrmwvmplugin.so differ diff --git a/widevine/adapt_semelis/widevine_L1/liboemcrypto.so b/widevine/adapt_semelis/widevine_L1/liboemcrypto.so new file mode 100755 index 0000000..c13a53d Binary files /dev/null and b/widevine/adapt_semelis/widevine_L1/liboemcrypto.so differ diff --git a/widevine/adapt_semelis/widevine_L1/libwvdrm_L1.so b/widevine/adapt_semelis/widevine_L1/libwvdrm_L1.so new file mode 100755 index 0000000..8658aba Binary files /dev/null and b/widevine/adapt_semelis/widevine_L1/libwvdrm_L1.so differ diff --git a/widevine/adapt_semelis/widevine_L1/libwvdrmengine.so b/widevine/adapt_semelis/widevine_L1/libwvdrmengine.so new file mode 100755 index 0000000..ab688d0 Binary files /dev/null and b/widevine/adapt_semelis/widevine_L1/libwvdrmengine.so differ diff --git a/widevine/adapt_semelis/widevine_L1/libwvm.so b/widevine/adapt_semelis/widevine_L1/libwvm.so new file mode 100755 index 0000000..2c88f28 Binary files /dev/null and b/widevine/adapt_semelis/widevine_L1/libwvm.so differ diff --git a/widevine/adapt_semelis/widevine_L3/Android.mk b/widevine/adapt_semelis/widevine_L3/Android.mk new file mode 100755 index 0000000..a970eb7 --- /dev/null +++ b/widevine/adapt_semelis/widevine_L3/Android.mk @@ -0,0 +1,132 @@ +WIDEVINE_SUPPORTED_ARCH := arm x86 +LOCAL_PATH:= $(call my-dir) + +################################################## +include $(CLEAR_VARS) + +LOCAL_MODULE := com.google.widevine.software.drm.xml +LOCAL_SRC_FILES := $(LOCAL_MODULE) +LOCAL_MODULE_TAGS := optional + +LOCAL_MODULE_CLASS := ETC + +# This will install the file in /system/etc/permissions +# +LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions + +include $(BUILD_PREBUILT) + +######################## +# Dummy library used to indicate availability of widevine drm + +include $(CLEAR_VARS) +LOCAL_MODULE := com.google.widevine.software.drm +LOCAL_MODULE_SUFFIX := .jar +LOCAL_SRC_FILES := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX) +LOCAL_MODULE_TAGS := optional + +LOCAL_MODULE_CLASS := JAVA_LIBRARIES + +include $(BUILD_PREBUILT) +##################################################################### +#libWVStreamControlAPI_LX.so +include $(CLEAR_VARS) + +LOCAL_MODULE := libWVStreamControlAPI_L$(BOARD_WIDEVINE_OEMCRYPTO_LEVEL) +LOCAL_MODULE_CLASS := SHARED_LIBRARIES +LOCAL_MODULE_SUFFIX := .so +LOCAL_SRC_FILES := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX) +LOCAL_PROPRIETARY_MODULE := true +#LOCAL_STRIP_MODULE := true +LOCAL_MULTILIB := 32 +LOCAL_MODULE_TAGS := optional +include $(BUILD_PREBUILT) + +##################################################################### +#libwvdrm_LX.so +include $(CLEAR_VARS) +LOCAL_MODULE := libwvdrm_L$(BOARD_WIDEVINE_OEMCRYPTO_LEVEL) +LOCAL_MODULE_CLASS := SHARED_LIBRARIES +LOCAL_MODULE_SUFFIX := .so +LOCAL_SRC_FILES := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX) +LOCAL_PROPRIETARY_MODULE := true +#LOCAL_STRIP_MODULE := true +LOCAL_MULTILIB := 32 +LOCAL_MODULE_TAGS := optional +include $(BUILD_PREBUILT) + +##################################################################### +#libdrmdecrypt.so +include $(CLEAR_VARS) +LOCAL_MODULE := libdrmdecrypt +LOCAL_MODULE_CLASS := SHARED_LIBRARIES +LOCAL_MODULE_SUFFIX := .so +LOCAL_SRC_FILES := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX) +LOCAL_PROPRIETARY_MODULE := true +#LOCAL_STRIP_MODULE := true +LOCAL_MODULE_TAGS := optional +LOCAL_MULTILIB := 32 +include $(BUILD_PREBUILT) + +##################################################################### +#libwvm.so +include $(CLEAR_VARS) +LOCAL_MODULE := libwvm +LOCAL_MODULE_CLASS := SHARED_LIBRARIES +LOCAL_MODULE_SUFFIX := .so +LOCAL_SRC_FILES := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX) +LOCAL_PROPRIETARY_MODULE := true +#LOCAL_STRIP_MODULE := true +LOCAL_MODULE_TAGS := optional +LOCAL_MULTILIB := 32 +include $(BUILD_PREBUILT) + +##################################################################### +#libwvdrmengine.so +include $(CLEAR_VARS) +LOCAL_MODULE := libwvdrmengine +LOCAL_MODULE_CLASS := SHARED_LIBRARIES +LOCAL_MODULE_SUFFIX := .so +LOCAL_SRC_FILES := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX) +LOCAL_PROPRIETARY_MODULE := true +#LOCAL_STRIP_MODULE := true +#LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_SHARED_LIBRARIES)/mediadrm +LOCAL_PROPRIETARY_MODULE := true +LOCAL_MODULE_RELATIVE_PATH := mediadrm +LOCAL_MODULE_TAGS := optional +LOCAL_MULTILIB := 32 +include $(BUILD_PREBUILT) + +##################################################################### +#libdrmwvmplugin.so +include $(CLEAR_VARS) +LOCAL_MODULE := libdrmwvmplugin +LOCAL_MODULE_CLASS := SHARED_LIBRARIES +LOCAL_MODULE_SUFFIX := .so +LOCAL_SRC_FILES := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX) +LOCAL_PROPRIETARY_MODULE := true +#LOCAL_STRIP_MODULE := true +#LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_SHARED_LIBRARIES)/drm +LOCAL_PROPRIETARY_MODULE := true +LOCAL_MODULE_RELATIVE_PATH := drm +LOCAL_MODULE_TAGS := optional +LOCAL_MULTILIB := 32 +include $(BUILD_PREBUILT) + + + +##################################################################### +#liboemcrypto.so +ifeq ($(BOARD_WIDEVINE_OEMCRYPTO_LEVEL),1) +include $(CLEAR_VARS) +LOCAL_MODULE := liboemcrypto +LOCAL_MODULE_CLASS := SHARED_LIBRARIES +LOCAL_MODULE_SUFFIX := .so +LOCAL_SRC_FILES := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX) +#LOCAL_PROPRIETARY_MODULE copies library to vendor/lib +LOCAL_PROPRIETARY_MODULE := true +LOCAL_MODULE_TAGS := optional +LOCAL_MULTILIB := 32 +include $(BUILD_PREBUILT) +endif# liboemcrypto + diff --git a/widevine/adapt_semelis/widevine_L3/CleanSpec.mk b/widevine/adapt_semelis/widevine_L3/CleanSpec.mk new file mode 100755 index 0000000..49b5b9c --- /dev/null +++ b/widevine/adapt_semelis/widevine_L3/CleanSpec.mk @@ -0,0 +1,53 @@ +# 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. +# + +# 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/*) + +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/drm $(PRODUCT_OUT)/system/lib/libwv* $(PRODUCT_OUT)/system/lib/libWV*) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/cdm_protos_intermediates) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libcdm_intermediates) + +# ************************************************ +# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST +# ************************************************ diff --git a/widevine/adapt_semelis/widevine_L3/com.google.widevine.software.drm.jar b/widevine/adapt_semelis/widevine_L3/com.google.widevine.software.drm.jar new file mode 100755 index 0000000..9bc8310 Binary files /dev/null and b/widevine/adapt_semelis/widevine_L3/com.google.widevine.software.drm.jar differ diff --git a/widevine/adapt_semelis/widevine_L3/com.google.widevine.software.drm.xml b/widevine/adapt_semelis/widevine_L3/com.google.widevine.software.drm.xml new file mode 100755 index 0000000..f75abf9 --- /dev/null +++ b/widevine/adapt_semelis/widevine_L3/com.google.widevine.software.drm.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/widevine/adapt_semelis/widevine_L3/libWVStreamControlAPI_L3.so b/widevine/adapt_semelis/widevine_L3/libWVStreamControlAPI_L3.so new file mode 100755 index 0000000..1fd88f9 Binary files /dev/null and b/widevine/adapt_semelis/widevine_L3/libWVStreamControlAPI_L3.so differ diff --git a/widevine/adapt_semelis/widevine_L3/libdrmdecrypt.so b/widevine/adapt_semelis/widevine_L3/libdrmdecrypt.so new file mode 100755 index 0000000..9862efc Binary files /dev/null and b/widevine/adapt_semelis/widevine_L3/libdrmdecrypt.so differ diff --git a/widevine/adapt_semelis/widevine_L3/libdrmwvmplugin.so b/widevine/adapt_semelis/widevine_L3/libdrmwvmplugin.so new file mode 100755 index 0000000..a36c2f2 Binary files /dev/null and b/widevine/adapt_semelis/widevine_L3/libdrmwvmplugin.so differ diff --git a/widevine/adapt_semelis/widevine_L3/libwvdrm_L3.so b/widevine/adapt_semelis/widevine_L3/libwvdrm_L3.so new file mode 100755 index 0000000..ea8a6d9 Binary files /dev/null and b/widevine/adapt_semelis/widevine_L3/libwvdrm_L3.so differ diff --git a/widevine/adapt_semelis/widevine_L3/libwvdrmengine.so b/widevine/adapt_semelis/widevine_L3/libwvdrmengine.so new file mode 100755 index 0000000..ab688d0 Binary files /dev/null and b/widevine/adapt_semelis/widevine_L3/libwvdrmengine.so differ diff --git a/widevine/adapt_semelis/widevine_L3/libwvm.so b/widevine/adapt_semelis/widevine_L3/libwvm.so new file mode 100755 index 0000000..881bf3d Binary files /dev/null and b/widevine/adapt_semelis/widevine_L3/libwvm.so differ diff --git a/widevine/widevine_L1/com.google.widevine.software.drm.jar b/widevine/widevine_L1/com.google.widevine.software.drm.jar deleted file mode 100644 index 1d07e51..0000000 Binary files a/widevine/widevine_L1/com.google.widevine.software.drm.jar and /dev/null differ diff --git a/widevine/widevine_L1/libWVStreamControlAPI_L1.so b/widevine/widevine_L1/libWVStreamControlAPI_L1.so deleted file mode 100755 index 181da25..0000000 Binary files a/widevine/widevine_L1/libWVStreamControlAPI_L1.so and /dev/null differ diff --git a/widevine/widevine_L1/libdrmwvmcommon.a b/widevine/widevine_L1/libdrmwvmcommon.a deleted file mode 100644 index ea320ec..0000000 Binary files a/widevine/widevine_L1/libdrmwvmcommon.a and /dev/null differ diff --git a/widevine/widevine_L1/liboemcrypto.a b/widevine/widevine_L1/liboemcrypto.a deleted file mode 100644 index a492484..0000000 Binary files a/widevine/widevine_L1/liboemcrypto.a and /dev/null differ diff --git a/widevine/widevine_L1/liboemcrypto.so b/widevine/widevine_L1/liboemcrypto.so deleted file mode 100755 index 0f139be..0000000 Binary files a/widevine/widevine_L1/liboemcrypto.so and /dev/null differ diff --git a/widevine/widevine_L1/libwvdecryptcommon.a b/widevine/widevine_L1/libwvdecryptcommon.a deleted file mode 100644 index 5db675f..0000000 Binary files a/widevine/widevine_L1/libwvdecryptcommon.a and /dev/null differ diff --git a/widevine/widevine_L1/libwvdrm_L1.so b/widevine/widevine_L1/libwvdrm_L1.so deleted file mode 100755 index be0ae5c..0000000 Binary files a/widevine/widevine_L1/libwvdrm_L1.so and /dev/null differ diff --git a/widevine/widevine_L1/libwvdrmengine.so b/widevine/widevine_L1/libwvdrmengine.so deleted file mode 100755 index aee0807..0000000 Binary files a/widevine/widevine_L1/libwvdrmengine.so and /dev/null differ diff --git a/widevine/widevine_L1/libwvmcommon.a b/widevine/widevine_L1/libwvmcommon.a deleted file mode 100644 index 26cb444..0000000 Binary files a/widevine/widevine_L1/libwvmcommon.a and /dev/null differ diff --git a/widevine/widevine_L1/libwvocs_L1.a b/widevine/widevine_L1/libwvocs_L1.a deleted file mode 100644 index 5a171b3..0000000 Binary files a/widevine/widevine_L1/libwvocs_L1.a and /dev/null differ diff --git a/widevine/widevine_L3/com.google.widevine.software.drm.jar b/widevine/widevine_L3/com.google.widevine.software.drm.jar deleted file mode 100755 index d26f978..0000000 Binary files a/widevine/widevine_L3/com.google.widevine.software.drm.jar and /dev/null differ diff --git a/widevine/widevine_L3/libWVStreamControlAPI_L3.so b/widevine/widevine_L3/libWVStreamControlAPI_L3.so deleted file mode 100755 index 7ec9f4b..0000000 Binary files a/widevine/widevine_L3/libWVStreamControlAPI_L3.so and /dev/null differ diff --git a/widevine/widevine_L3/libdrmdecrypt.so b/widevine/widevine_L3/libdrmdecrypt.so deleted file mode 100755 index 248b555..0000000 Binary files a/widevine/widevine_L3/libdrmdecrypt.so and /dev/null differ diff --git a/widevine/widevine_L3/libdrmwvmplugin.so b/widevine/widevine_L3/libdrmwvmplugin.so deleted file mode 100755 index 1b589b3..0000000 Binary files a/widevine/widevine_L3/libdrmwvmplugin.so and /dev/null differ diff --git a/widevine/widevine_L3/libwvdrm_L3.so b/widevine/widevine_L3/libwvdrm_L3.so deleted file mode 100755 index 4a1100f..0000000 Binary files a/widevine/widevine_L3/libwvdrm_L3.so and /dev/null differ diff --git a/widevine/widevine_L3/libwvdrmengine.so b/widevine/widevine_L3/libwvdrmengine.so deleted file mode 100755 index 9b25f28..0000000 Binary files a/widevine/widevine_L3/libwvdrmengine.so and /dev/null differ diff --git a/widevine/widevine_L3/libwvm.so b/widevine/widevine_L3/libwvm.so deleted file mode 100755 index 2795781..0000000 Binary files a/widevine/widevine_L3/libwvm.so and /dev/null differ