summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Tomsich <philipp.tomsich@theobroma-systems.com>2017-08-23 19:43:54 +0200
committerPhilipp Tomsich <philipp.tomsich@theobroma-systems.com>2017-08-23 19:43:54 +0200
commit61794954d2d83176c933f1d196f1d9aef98e42b3 (patch)
tree47a97cba4d98a288c4e92b3d69f6f14c9085aca6
Import of Rockchip Android 7.1.1 SDKHEADmaster
-rwxr-xr-xAndroid.mk4
-rwxr-xr-xaddon/Android.mk4
-rwxr-xr-xaddon/AudioRecordWav/Android.mk4
-rwxr-xr-xaddon/AudioRecordWav/AudioRecordWav/Android.mk10
-rwxr-xr-xaddon/AudioRecordWav/AudioRecordWav/AndroidManifest.xml37
-rwxr-xr-xaddon/AudioRecordWav/AudioRecordWav/res/drawable-hdpi/ic_launcher.pngbin0 -> 7658 bytes
-rwxr-xr-xaddon/AudioRecordWav/AudioRecordWav/res/drawable-hdpi/ic_voice_search.pngbin0 -> 2070 bytes
-rwxr-xr-xaddon/AudioRecordWav/AudioRecordWav/res/drawable-hdpi/ic_voice_search_api_holo_light.pngbin0 -> 1154 bytes
-rwxr-xr-xaddon/AudioRecordWav/AudioRecordWav/res/drawable-mdpi/ic_launcher.pngbin0 -> 3777 bytes
-rwxr-xr-xaddon/AudioRecordWav/AudioRecordWav/res/drawable-xhdpi/ic_launcher.pngbin0 -> 12516 bytes
-rwxr-xr-xaddon/AudioRecordWav/AudioRecordWav/res/drawable-xxhdpi/ic_launcher.pngbin0 -> 24777 bytes
-rwxr-xr-xaddon/AudioRecordWav/AudioRecordWav/res/layout/activity_main.xml42
-rwxr-xr-xaddon/AudioRecordWav/AudioRecordWav/res/values/strings.xml9
-rwxr-xr-xaddon/AudioRecordWav/AudioRecordWav/res/values/styles.xml6
-rwxr-xr-xaddon/AudioRecordWav/AudioRecordWav/src/com/example/audiorecordwav/MainActivity.java576
-rwxr-xr-xaddon/AudioRecordWav/addon.mk3
-rwxr-xr-xaddon/BluetoothRTK3ddService/Android.mk4
-rwxr-xr-xaddon/BluetoothRTK3ddService/BluetoothRTK3ddService/Android.mk11
-rwxr-xr-xaddon/BluetoothRTK3ddService/BluetoothRTK3ddService/BluetoothRTK3ddService.apkbin0 -> 23203 bytes
-rwxr-xr-xaddon/BluetoothRTK3ddService/addon.mk3
-rwxr-xr-xaddon/basic/Android.mk4
-rwxr-xr-xaddon/basic/addon.mk2
-rwxr-xr-xaddon/basic/system/etc/bluetooth/rtkbt_plugins.conf1
-rwxr-xr-xaddon/bee/Android.mk4
-rwxr-xr-xaddon/bee/addon.mk6
-rwxr-xr-xaddon/bee/system/etc/bluetooth/rtkbt_autopair_config.xml30
-rwxr-xr-xaddon/bee/system/etc/bluetooth/rtkbt_plugin_autopair_stack.conf12
-rwxr-xr-xaddon/bee/system/etc/bluetooth/rtkbt_plugins.conf2
-rwxr-xr-xaddon/bee/system/usr/keylayout/rtkbt_vhid_Vid_005d_Pid_0001.kl34
-rwxr-xr-xaddon/bee1/Android.mk4
-rwxr-xr-xaddon/bee1/addon.mk7
-rwxr-xr-xaddon/bee1/system/etc/bluetooth/rtkbt_autopair_config.xml30
-rwxr-xr-xaddon/bee1/system/etc/bluetooth/rtkbt_plugin_autopair_stack.conf12
-rwxr-xr-xaddon/bee1/system/etc/bluetooth/rtkbt_plugin_vr_bee1_hidraw.conf5
-rwxr-xr-xaddon/bee1/system/etc/bluetooth/rtkbt_plugins.conf3
-rwxr-xr-xaddon/bee1/system/usr/keylayout/Vendor_005d_Product_0001.kl49
-rwxr-xr-xaddon/bee1/system/usr/keylayout/rtkbt_vhid_Vid_005d_Pid_0001.kl34
-rwxr-xr-xaddon/bee2/Android.mk4
-rwxr-xr-xaddon/bee2/addon.mk6
-rwxr-xr-xaddon/bee2/system/etc/bluetooth/rtkbt_autopair_config.xml30
-rwxr-xr-xaddon/bee2/system/etc/bluetooth/rtkbt_plugin_autopair_stack.conf12
-rwxr-xr-xaddon/bee2/system/etc/bluetooth/rtkbt_plugin_vr_bee2_hidraw.conf5
-rwxr-xr-xaddon/bee2/system/etc/bluetooth/rtkbt_plugins.conf3
-rwxr-xr-xaddon/bee2/system/usr/keylayout/Vendor_005d_Product_0002.kl34
-rwxr-xr-xaddon/rtkbtAutoPairService/Android.mk4
-rwxr-xr-xaddon/rtkbtAutoPairService/addon.mk2
-rwxr-xr-xaddon/rtkbtAutoPairService/rtkbtAutoPairService/Android.mk11
-rwxr-xr-xaddon/rtkbtAutoPairService/rtkbtAutoPairService/rtkbtAutoPairService.apkbin0 -> 37884 bytes
-rwxr-xr-xaddon/rtkbtAutoPairUIDemo/Android.mk2
-rwxr-xr-xaddon/rtkbtAutoPairUIDemo/AndroidManifest.xml24
-rwxr-xr-xaddon/rtkbtAutoPairUIDemo/addon.mk3
-rwxr-xr-xaddon/rtkbtAutoPairUIDemo/res/drawable-hdpi/ic_launcher.pngbin0 -> 3014 bytes
-rwxr-xr-xaddon/rtkbtAutoPairUIDemo/res/drawable-ldpi/ic_launcher.pngbin0 -> 1504 bytes
-rwxr-xr-xaddon/rtkbtAutoPairUIDemo/res/drawable-mdpi/ic_launcher.pngbin0 -> 1969 bytes
-rwxr-xr-xaddon/rtkbtAutoPairUIDemo/res/drawable-xhdpi/ic_launcher.pngbin0 -> 4006 bytes
-rwxr-xr-xaddon/rtkbtAutoPairUIDemo/res/values-v11/styles.xml5
-rwxr-xr-xaddon/rtkbtAutoPairUIDemo/res/values-v14/styles.xml5
-rwxr-xr-xaddon/rtkbtAutoPairUIDemo/res/values-zh-rCN/strings.xml22
-rwxr-xr-xaddon/rtkbtAutoPairUIDemo/res/values-zh-rCN/styles.xml5
-rwxr-xr-xaddon/rtkbtAutoPairUIDemo/res/values/strings.xml24
-rwxr-xr-xaddon/rtkbtAutoPairUIDemo/res/values/styles.xml5
-rwxr-xr-xaddon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/Android.mk10
-rwxr-xr-xaddon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/AndroidManifest.xml24
-rwxr-xr-xaddon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/drawable-hdpi/ic_launcher.pngbin0 -> 3014 bytes
-rwxr-xr-xaddon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/drawable-ldpi/ic_launcher.pngbin0 -> 1504 bytes
-rwxr-xr-xaddon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/drawable-mdpi/ic_launcher.pngbin0 -> 1969 bytes
-rwxr-xr-xaddon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/drawable-xhdpi/ic_launcher.pngbin0 -> 4006 bytes
-rwxr-xr-xaddon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/values-v11/styles.xml5
-rwxr-xr-xaddon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/values-v14/styles.xml5
-rwxr-xr-xaddon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/values-zh-rCN/strings.xml22
-rwxr-xr-xaddon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/values-zh-rCN/styles.xml5
-rwxr-xr-xaddon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/values/strings.xml24
-rwxr-xr-xaddon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/values/styles.xml5
-rwxr-xr-xaddon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/src/com/android/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemoReceiver.java107
-rwxr-xr-xaddon/rtkbtAutoPairUIDemo/src/com/android/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemoReceiver.java107
-rwxr-xr-xaddon/vr_bee1_hidraw_daemon/Android.mk4
-rwxr-xr-xaddon/vr_bee1_hidraw_daemon/addon.mk5
-rwxr-xr-xaddon/vr_bee1_hidraw_daemon/hidraw/Android.mk24
-rwxr-xr-xaddon/vr_bee1_hidraw_daemon/hidraw/bee_settings.h35
-rwxr-xr-xaddon/vr_bee1_hidraw_daemon/hidraw/config.c251
-rwxr-xr-xaddon/vr_bee1_hidraw_daemon/hidraw/config.h34
-rwxr-xr-xaddon/vr_bee1_hidraw_daemon/hidraw/get_voice_app.c234
-rwxr-xr-xaddon/vr_bee1_hidraw_daemon/hidraw/get_voice_app.h22
-rwxr-xr-xaddon/vr_bee1_hidraw_daemon/hidraw/msbc/msbc.c1766
-rwxr-xr-xaddon/vr_bee1_hidraw_daemon/hidraw/msbc/msbc.h79
-rwxr-xr-xaddon/vr_bee1_hidraw_daemon/hidraw/msbc/msbc_math.h70
-rwxr-xr-xaddon/vr_bee1_hidraw_daemon/hidraw/msbc/msbc_tables.h169
-rwxr-xr-xaddon/vr_bee1_hidraw_daemon/hidraw/sbc/sbc.h85
-rwxr-xr-xaddon/vr_bee1_hidraw_daemon/hidraw/sbc/sbcdec.c1279
-rwxr-xr-xaddon/vr_bee1_hidraw_daemon/hidraw/sbc/sbcenc.c1705
-rwxr-xr-xaddon/vr_bee1_hidraw_daemon/hidraw/voice_hidraw.c1138
-rwxr-xr-xaddon/vr_bee1_hidraw_daemon/hidraw/voice_hidraw.h55
-rwxr-xr-xaddon/vr_bee1_hidraw_daemon/hidraw/voice_uipc.c916
-rwxr-xr-xaddon/vr_bee1_hidraw_daemon/hidraw/voice_uipc.h108
-rwxr-xr-xaddon/vr_bee1_hidraw_daemon/system/etc/hidraw_setting20
-rwxr-xr-xaddon/vr_bee2_hidraw_daemon/Android.mk4
-rwxr-xr-xaddon/vr_bee2_hidraw_daemon/addon.mk5
-rwxr-xr-xaddon/vr_bee2_hidraw_daemon/hidraw/Android.mk24
-rwxr-xr-xaddon/vr_bee2_hidraw_daemon/hidraw/bee_settings.h35
-rwxr-xr-xaddon/vr_bee2_hidraw_daemon/hidraw/config.c251
-rwxr-xr-xaddon/vr_bee2_hidraw_daemon/hidraw/config.h34
-rwxr-xr-xaddon/vr_bee2_hidraw_daemon/hidraw/get_voice_app.c234
-rwxr-xr-xaddon/vr_bee2_hidraw_daemon/hidraw/get_voice_app.h22
-rwxr-xr-xaddon/vr_bee2_hidraw_daemon/hidraw/msbc/msbc.c1766
-rwxr-xr-xaddon/vr_bee2_hidraw_daemon/hidraw/msbc/msbc.h79
-rwxr-xr-xaddon/vr_bee2_hidraw_daemon/hidraw/msbc/msbc_math.h70
-rwxr-xr-xaddon/vr_bee2_hidraw_daemon/hidraw/msbc/msbc_tables.h169
-rwxr-xr-xaddon/vr_bee2_hidraw_daemon/hidraw/sbc/sbc.h85
-rwxr-xr-xaddon/vr_bee2_hidraw_daemon/hidraw/sbc/sbcdec.c1279
-rwxr-xr-xaddon/vr_bee2_hidraw_daemon/hidraw/sbc/sbcenc.c1705
-rwxr-xr-xaddon/vr_bee2_hidraw_daemon/hidraw/voice_hidraw.c1140
-rwxr-xr-xaddon/vr_bee2_hidraw_daemon/hidraw/voice_hidraw.h55
-rwxr-xr-xaddon/vr_bee2_hidraw_daemon/hidraw/voice_uipc.c916
-rwxr-xr-xaddon/vr_bee2_hidraw_daemon/hidraw/voice_uipc.h108
-rwxr-xr-xaddon/vr_bee2_hidraw_daemon/system/etc/hidraw_setting20
-rwxr-xr-xcode/Android.mk4
-rwxr-xr-xcode/bt/.gn22
-rwxr-xr-xcode/bt/Android.mk55
-rwxr-xr-xcode/bt/BUILD.gn42
-rwxr-xr-xcode/bt/CleanSpec.mk53
-rwxr-xr-xcode/bt/MODULE_LICENSE_APACHE20
-rwxr-xr-xcode/bt/NOTICE202
-rwxr-xr-xcode/bt/README.md128
-rwxr-xr-xcode/bt/audio_a2dp_hw/Android.mk.disabled27
-rwxr-xr-xcode/bt/audio_a2dp_hw/BUILD.gn27
-rwxr-xr-xcode/bt/audio_a2dp_hw/audio_a2dp_hw.c1462
-rwxr-xr-xcode/bt/audio_a2dp_hw/audio_a2dp_hw.h126
-rwxr-xr-xcode/bt/bta/Android.mk104
-rwxr-xr-xcode/bt/bta/BUILD.gn110
-rwxr-xr-xcode/bt/bta/ag/bta_ag_act.c944
-rwxr-xr-xcode/bt/bta/ag/bta_ag_api.c289
-rwxr-xr-xcode/bt/bta/ag/bta_ag_at.c239
-rwxr-xr-xcode/bt/bta/ag/bta_ag_at.h121
-rwxr-xr-xcode/bt/bta/ag/bta_ag_cfg.c64
-rwxr-xr-xcode/bt/bta/ag/bta_ag_ci.c90
-rwxr-xr-xcode/bt/bta/ag/bta_ag_cmd.c1824
-rwxr-xr-xcode/bt/bta/ag/bta_ag_int.h433
-rwxr-xr-xcode/bt/bta/ag/bta_ag_main.c1021
-rwxr-xr-xcode/bt/bta/ag/bta_ag_rfc.c421
-rwxr-xr-xcode/bt/bta/ag/bta_ag_sco.c1744
-rwxr-xr-xcode/bt/bta/ag/bta_ag_sdp.c493
-rwxr-xr-xcode/bt/bta/ar/bta_ar.c344
-rwxr-xr-xcode/bt/bta/ar/bta_ar_int.h64
-rwxr-xr-xcode/bt/bta/av/bta_av_aact.c3208
-rwxr-xr-xcode/bt/bta/av/bta_av_act.c2201
-rwxr-xr-xcode/bt/bta/av/bta_av_api.c640
-rwxr-xr-xcode/bt/bta/av/bta_av_cfg.c255
-rwxr-xr-xcode/bt/bta/av/bta_av_ci.c91
-rwxr-xr-xcode/bt/bta/av/bta_av_int.h751
-rwxr-xr-xcode/bt/bta/av/bta_av_main.c1405
-rwxr-xr-xcode/bt/bta/av/bta_av_sbc.c665
-rwxr-xr-xcode/bt/bta/av/bta_av_ssm.c613
-rwxr-xr-xcode/bt/bta/dm/bta_dm_act.c5771
-rwxr-xr-xcode/bt/bta/dm/bta_dm_api.c1941
-rwxr-xr-xcode/bt/bta/dm/bta_dm_cfg.c587
-rwxr-xr-xcode/bt/bta/dm/bta_dm_ci.c110
-rwxr-xr-xcode/bt/bta/dm/bta_dm_int.h1210
-rwxr-xr-xcode/bt/bta/dm/bta_dm_main.c375
-rwxr-xr-xcode/bt/bta/dm/bta_dm_pm.c1287
-rwxr-xr-xcode/bt/bta/dm/bta_dm_sco.c695
-rwxr-xr-xcode/bt/bta/gatt/bta_gattc_act.c2107
-rwxr-xr-xcode/bt/bta/gatt/bta_gattc_api.c773
-rwxr-xr-xcode/bt/bta/gatt/bta_gattc_cache.c1635
-rwxr-xr-xcode/bt/bta/gatt/bta_gattc_int.h501
-rwxr-xr-xcode/bt/bta/gatt/bta_gattc_main.c505
-rwxr-xr-xcode/bt/bta/gatt/bta_gattc_utils.c815
-rwxr-xr-xcode/bt/bta/gatt/bta_gatts_act.c966
-rwxr-xr-xcode/bt/bta/gatt/bta_gatts_api.c492
-rwxr-xr-xcode/bt/bta/gatt/bta_gatts_int.h260
-rwxr-xr-xcode/bt/bta/gatt/bta_gatts_main.c143
-rwxr-xr-xcode/bt/bta/gatt/bta_gatts_utils.c234
-rwxr-xr-xcode/bt/bta/hf_client/bta_hf_client_act.c763
-rwxr-xr-xcode/bt/bta/hf_client/bta_hf_client_api.c265
-rwxr-xr-xcode/bt/bta/hf_client/bta_hf_client_at.c1956
-rwxr-xr-xcode/bt/bta/hf_client/bta_hf_client_at.h113
-rwxr-xr-xcode/bt/bta/hf_client/bta_hf_client_cmd.c88
-rwxr-xr-xcode/bt/bta/hf_client/bta_hf_client_int.h293
-rwxr-xr-xcode/bt/bta/hf_client/bta_hf_client_main.c676
-rwxr-xr-xcode/bt/bta/hf_client/bta_hf_client_rfc.c258
-rwxr-xr-xcode/bt/bta/hf_client/bta_hf_client_sco.c725
-rwxr-xr-xcode/bt/bta/hf_client/bta_hf_client_sdp.c370
-rwxr-xr-xcode/bt/bta/hh/bta_hh_act.c1337
-rwxr-xr-xcode/bt/bta/hh/bta_hh_api.c452
-rwxr-xr-xcode/bt/bta/hh/bta_hh_cfg.c62
-rwxr-xr-xcode/bt/bta/hh/bta_hh_int.h418
-rwxr-xr-xcode/bt/bta/hh/bta_hh_le.c2951
-rwxr-xr-xcode/bt/bta/hh/bta_hh_main.c585
-rwxr-xr-xcode/bt/bta/hh/bta_hh_utils.c535
-rwxr-xr-xcode/bt/bta/hl/bta_hl_act.c2802
-rwxr-xr-xcode/bt/bta/hl/bta_hl_api.c503
-rwxr-xr-xcode/bt/bta/hl/bta_hl_ci.c168
-rwxr-xr-xcode/bt/bta/hl/bta_hl_int.h880
-rwxr-xr-xcode/bt/bta/hl/bta_hl_main.c2112
-rwxr-xr-xcode/bt/bta/hl/bta_hl_sdp.c635
-rwxr-xr-xcode/bt/bta/hl/bta_hl_utils.c3483
-rwxr-xr-xcode/bt/bta/include/bta_ag_api.h528
-rwxr-xr-xcode/bt/bta/include/bta_ag_ci.h79
-rwxr-xr-xcode/bt/bta/include/bta_ag_co.h112
-rwxr-xr-xcode/bt/bta/include/bta_api.h2332
-rwxr-xr-xcode/bt/bta/include/bta_ar_api.h141
-rwxr-xr-xcode/bt/bta/include/bta_av_api.h842
-rwxr-xr-xcode/bt/bta/include/bta_av_ci.h73
-rwxr-xr-xcode/bt/bta/include/bta_av_co.h391
-rwxr-xr-xcode/bt/bta/include/bta_av_sbc.h219
-rwxr-xr-xcode/bt/bta/include/bta_dm_ci.h80
-rwxr-xr-xcode/bt/bta/include/bta_dm_co.h272
-rwxr-xr-xcode/bt/bta/include/bta_gatt_api.h1291
-rwxr-xr-xcode/bt/bta/include/bta_gatts_co.h81
-rwxr-xr-xcode/bt/bta/include/bta_hf_client_api.h382
-rwxr-xr-xcode/bt/bta/include/bta_hh_api.h558
-rwxr-xr-xcode/bt/bta/include/bta_hh_co.h133
-rwxr-xr-xcode/bt/bta/include/bta_hl_api.h896
-rwxr-xr-xcode/bt/bta/include/bta_hl_ci.h123
-rwxr-xr-xcode/bt/bta/include/bta_hl_co.h234
-rwxr-xr-xcode/bt/bta/include/bta_jv_api.h825
-rwxr-xr-xcode/bt/bta/include/bta_jv_co.h53
-rwxr-xr-xcode/bt/bta/include/bta_mce_api.h131
-rwxr-xr-xcode/bt/bta/include/bta_op_api.h67
-rwxr-xr-xcode/bt/bta/include/bta_pan_api.h200
-rwxr-xr-xcode/bt/bta/include/bta_pan_ci.h146
-rwxr-xr-xcode/bt/bta/include/bta_pan_co.h200
-rwxr-xr-xcode/bt/bta/include/bta_sdp_api.h145
-rwxr-xr-xcode/bt/bta/include/utl.h156
-rwxr-xr-xcode/bt/bta/jv/bta_jv_act.c2646
-rwxr-xr-xcode/bt/bta/jv/bta_jv_api.c996
-rwxr-xr-xcode/bt/bta/jv/bta_jv_cfg.c58
-rwxr-xr-xcode/bt/bta/jv/bta_jv_int.h439
-rwxr-xr-xcode/bt/bta/jv/bta_jv_main.c97
-rwxr-xr-xcode/bt/bta/mce/bta_mce_act.c185
-rwxr-xr-xcode/bt/bta/mce/bta_mce_api.c111
-rwxr-xr-xcode/bt/bta/mce/bta_mce_cfg.c44
-rwxr-xr-xcode/bt/bta/mce/bta_mce_int.h97
-rwxr-xr-xcode/bt/bta/mce/bta_mce_main.c78
-rwxr-xr-xcode/bt/bta/pan/bta_pan_act.c769
-rwxr-xr-xcode/bt/bta/pan/bta_pan_api.c222
-rwxr-xr-xcode/bt/bta/pan/bta_pan_ci.c303
-rwxr-xr-xcode/bt/bta/pan/bta_pan_int.h221
-rwxr-xr-xcode/bt/bta/pan/bta_pan_main.c416
-rwxr-xr-xcode/bt/bta/pb/bta_pbs_int.h59
-rwxr-xr-xcode/bt/bta/sdp/bta_sdp.c77
-rwxr-xr-xcode/bt/bta/sdp/bta_sdp_act.c564
-rwxr-xr-xcode/bt/bta/sdp/bta_sdp_api.c164
-rwxr-xr-xcode/bt/bta/sdp/bta_sdp_cfg.c40
-rwxr-xr-xcode/bt/bta/sdp/bta_sdp_int.h115
-rwxr-xr-xcode/bt/bta/sys/bta_sys.h286
-rwxr-xr-xcode/bt/bta/sys/bta_sys_conn.c580
-rwxr-xr-xcode/bt/bta/sys/bta_sys_int.h104
-rwxr-xr-xcode/bt/bta/sys/bta_sys_main.c667
-rwxr-xr-xcode/bt/bta/sys/utl.c277
-rwxr-xr-xcode/bt/btcore/Android.mk115
-rwxr-xr-xcode/bt/btcore/BUILD.gn60
-rwxr-xr-xcode/bt/btcore/include/bdaddr.h62
-rwxr-xr-xcode/bt/btcore/include/device_class.h92
-rwxr-xr-xcode/bt/btcore/include/device_features.h27
-rwxr-xr-xcode/bt/btcore/include/event_mask.h28
-rwxr-xr-xcode/bt/btcore/include/hal_util.h24
-rwxr-xr-xcode/bt/btcore/include/iac.h27
-rwxr-xr-xcode/bt/btcore/include/module.h67
-rwxr-xr-xcode/bt/btcore/include/osi_module.h21
-rwxr-xr-xcode/bt/btcore/include/property.h77
-rwxr-xr-xcode/bt/btcore/include/uuid.h75
-rwxr-xr-xcode/bt/btcore/include/version.h29
-rwxr-xr-xcode/bt/btcore/src/bdaddr.c101
-rwxr-xr-xcode/bt/btcore/src/device_class.c158
-rwxr-xr-xcode/bt/btcore/src/hal_util.c92
-rwxr-xr-xcode/bt/btcore/src/module.c245
-rwxr-xr-xcode/bt/btcore/src/osi_module.c49
-rwxr-xr-xcode/bt/btcore/src/property.c218
-rwxr-xr-xcode/bt/btcore/src/uuid.c164
-rwxr-xr-xcode/bt/btcore/test/bdaddr_test.cpp48
-rwxr-xr-xcode/bt/btcore/test/device_class_test.cpp220
-rwxr-xr-xcode/bt/btcore/test/property_test.cpp247
-rwxr-xr-xcode/bt/btcore/test/uuid_test.cpp166
-rwxr-xr-xcode/bt/btif/Android.mk143
-rwxr-xr-xcode/bt/btif/BUILD.gn89
-rwxr-xr-xcode/bt/btif/co/bta_ag_co.c155
-rwxr-xr-xcode/bt/btif/co/bta_av_co.c1843
-rwxr-xr-xcode/bt/btif/co/bta_dm_co.c438
-rwxr-xr-xcode/bt/btif/co/bta_gatts_co.c168
-rwxr-xr-xcode/bt/btif/co/bta_hh_co.c646
-rwxr-xr-xcode/bt/btif/co/bta_hl_co.c458
-rwxr-xr-xcode/bt/btif/co/bta_pan_co.c357
-rwxr-xr-xcode/bt/btif/include/btif_api.h423
-rwxr-xr-xcode/bt/btif/include/btif_av.h218
-rwxr-xr-xcode/bt/btif/include/btif_av_api.h210
-rwxr-xr-xcode/bt/btif/include/btif_av_co.h174
-rwxr-xr-xcode/bt/btif/include/btif_avrcp_audio_track.h73
-rwxr-xr-xcode/bt/btif/include/btif_common.h219
-rwxr-xr-xcode/bt/btif/include/btif_config.h55
-rwxr-xr-xcode/bt/btif/include/btif_config_transcode.h23
-rwxr-xr-xcode/bt/btif/include/btif_debug.h30
-rwxr-xr-xcode/bt/btif/include/btif_debug_btsnoop.h44
-rwxr-xr-xcode/bt/btif/include/btif_debug_conn.h34
-rwxr-xr-xcode/bt/btif/include/btif_dm.h114
-rwxr-xr-xcode/bt/btif/include/btif_gatt.h34
-rwxr-xr-xcode/bt/btif/include/btif_gatt_multi_adv_util.h92
-rwxr-xr-xcode/bt/btif/include/btif_gatt_util.h41
-rwxr-xr-xcode/bt/btif/include/btif_hh.h115
-rwxr-xr-xcode/bt/btif/include/btif_hl.h330
-rwxr-xr-xcode/bt/btif/include/btif_mce.h35
-rwxr-xr-xcode/bt/btif/include/btif_media.h303
-rwxr-xr-xcode/bt/btif/include/btif_pan.h36
-rwxr-xr-xcode/bt/btif/include/btif_pan_internal.h123
-rwxr-xr-xcode/bt/btif/include/btif_profile_queue.h39
-rwxr-xr-xcode/bt/btif/include/btif_sdp.h34
-rwxr-xr-xcode/bt/btif/include/btif_sm.h120
-rwxr-xr-xcode/bt/btif/include/btif_sock.h28
-rwxr-xr-xcode/bt/btif/include/btif_sock_l2cap.h25
-rwxr-xr-xcode/bt/btif/include/btif_sock_rfc.h40
-rwxr-xr-xcode/bt/btif/include/btif_sock_sco.h28
-rwxr-xr-xcode/bt/btif/include/btif_sock_sdp.h48
-rwxr-xr-xcode/bt/btif/include/btif_sock_thread.h53
-rwxr-xr-xcode/bt/btif/include/btif_sock_util.h38
-rwxr-xr-xcode/bt/btif/include/btif_storage.h322
-rwxr-xr-xcode/bt/btif/include/btif_uid.h43
-rwxr-xr-xcode/bt/btif/include/btif_util.h78
-rwxr-xr-xcode/bt/btif/include/stack_manager.h37
-rwxr-xr-xcode/bt/btif/include/uinput.h591
-rwxr-xr-xcode/bt/btif/src/bluetooth.c606
-rwxr-xr-xcode/bt/btif/src/btif_av.c1801
-rwxr-xr-xcode/bt/btif/src/btif_avrcp_audio_track.cpp152
-rwxr-xr-xcode/bt/btif/src/btif_config.c585
-rwxr-xr-xcode/bt/btif/src/btif_config_transcode.cpp62
-rwxr-xr-xcode/bt/btif/src/btif_core.c1479
-rwxr-xr-xcode/bt/btif/src/btif_debug.c40
-rwxr-xr-xcode/bt/btif/src/btif_debug_btsnoop.c209
-rwxr-xr-xcode/bt/btif/src/btif_debug_conn.c110
-rwxr-xr-xcode/bt/btif/src/btif_dm.c3671
-rwxr-xr-xcode/bt/btif/src/btif_gatt.c120
-rwxr-xr-xcode/bt/btif/src/btif_gatt_client.c2229
-rwxr-xr-xcode/bt/btif/src/btif_gatt_multi_adv_util.c529
-rwxr-xr-xcode/bt/btif/src/btif_gatt_server.c706
-rwxr-xr-xcode/bt/btif/src/btif_gatt_test.c299
-rwxr-xr-xcode/bt/btif/src/btif_gatt_util.c308
-rwxr-xr-xcode/bt/btif/src/btif_hf.c1655
-rwxr-xr-xcode/bt/btif/src/btif_hf_client.c990
-rwxr-xr-xcode/bt/btif/src/btif_hh.c1718
-rwxr-xr-xcode/bt/btif/src/btif_hl.c4975
-rwxr-xr-xcode/bt/btif/src/btif_mce.c186
-rwxr-xr-xcode/bt/btif/src/btif_media_task.c3425
-rwxr-xr-xcode/bt/btif/src/btif_pan.c839
-rwxr-xr-xcode/bt/btif/src/btif_profile_queue.c174
-rwxr-xr-xcode/bt/btif/src/btif_rc.c4280
-rwxr-xr-xcode/bt/btif/src/btif_sdp.c206
-rwxr-xr-xcode/bt/btif/src/btif_sdp_server.c778
-rwxr-xr-xcode/bt/btif/src/btif_sm.c186
-rwxr-xr-xcode/bt/btif/src/btif_sock.c202
-rwxr-xr-xcode/bt/btif/src/btif_sock_l2cap.c1108
-rwxr-xr-xcode/bt/btif/src/btif_sock_rfc.c922
-rwxr-xr-xcode/bt/btif/src/btif_sock_sco.c332
-rwxr-xr-xcode/bt/btif/src/btif_sock_sdp.c459
-rwxr-xr-xcode/bt/btif/src/btif_sock_thread.c602
-rwxr-xr-xcode/bt/btif/src/btif_sock_util.c244
-rwxr-xr-xcode/bt/btif/src/btif_storage.c1497
-rwxr-xr-xcode/bt/btif/src/btif_uid.c133
-rwxr-xr-xcode/bt/btif/src/btif_util.c540
-rwxr-xr-xcode/bt/btif/src/stack_manager.c263
-rwxr-xr-xcode/bt/btif/test/btif_storage_test.cpp66
-rwxr-xr-xcode/bt/build/BUILD.gn85
-rwxr-xr-xcode/bt/build/config/BUILDCONFIG.gn49
-rwxr-xr-xcode/bt/build/secondary/third_party/googletest/BUILD.gn91
-rwxr-xr-xcode/bt/build/secondary/third_party/libchrome/BUILD.gn256
-rwxr-xr-xcode/bt/build/toolchain/gcc/BUILD.gn97
-rwxr-xr-xcode/bt/conf/Android.mk22
-rwxr-xr-xcode/bt/conf/bt_did.conf85
-rwxr-xr-xcode/bt/conf/bt_stack.conf85
-rwxr-xr-xcode/bt/device/Android.mk72
-rwxr-xr-xcode/bt/device/BUILD.gn54
-rwxr-xr-xcode/bt/device/include/classic/peer.h34
-rwxr-xr-xcode/bt/device/include/controller.h86
-rwxr-xr-xcode/bt/device/include/interop.h91
-rwxr-xr-xcode/bt/device/include/interop_database.h114
-rwxr-xr-xcode/bt/device/src/classic/peer.c121
-rwxr-xr-xcode/bt/device/src/controller.c540
-rwxr-xr-xcode/bt/device/src/interop.c163
-rwxr-xr-xcode/bt/device/test/classic/peer_test.cpp86
-rwxr-xr-xcode/bt/device/test/interop_test.cpp77
-rwxr-xr-xcode/bt/doc/btsnoop_net.md15
-rwxr-xr-xcode/bt/doc/directory_layout.md29
-rwxr-xr-xcode/bt/doc/log_tags.md59
-rwxr-xr-xcode/bt/doc/network_ports.md8
-rwxr-xr-xcode/bt/doc/power_management.md202
-rwxr-xr-xcode/bt/doc/properties.md20
-rwxr-xr-xcode/bt/doc/style_guide.md325
-rwxr-xr-xcode/bt/doc/supported_features.md20
-rwxr-xr-xcode/bt/embdrv/Android.mk3
-rwxr-xr-xcode/bt/embdrv/sbc/Android.mk3
-rwxr-xr-xcode/bt/embdrv/sbc/BUILD.gn62
-rwxr-xr-xcode/bt/embdrv/sbc/decoder/Android.mk35
-rwxr-xr-xcode/bt/embdrv/sbc/decoder/include/oi_assert.h86
-rwxr-xr-xcode/bt/embdrv/sbc/decoder/include/oi_bitstream.h123
-rwxr-xr-xcode/bt/embdrv/sbc/decoder/include/oi_bt_spec.h229
-rwxr-xr-xcode/bt/embdrv/sbc/decoder/include/oi_codec_sbc.h484
-rwxr-xr-xcode/bt/embdrv/sbc/decoder/include/oi_codec_sbc_private.h229
-rwxr-xr-xcode/bt/embdrv/sbc/decoder/include/oi_common.h43
-rwxr-xr-xcode/bt/embdrv/sbc/decoder/include/oi_cpu_dep.h505
-rwxr-xr-xcode/bt/embdrv/sbc/decoder/include/oi_modules.h171
-rwxr-xr-xcode/bt/embdrv/sbc/decoder/include/oi_osinterface.h197
-rwxr-xr-xcode/bt/embdrv/sbc/decoder/include/oi_status.h579
-rwxr-xr-xcode/bt/embdrv/sbc/decoder/include/oi_stddefs.h232
-rwxr-xr-xcode/bt/embdrv/sbc/decoder/include/oi_string.h208
-rwxr-xr-xcode/bt/embdrv/sbc/decoder/include/oi_time.h200
-rwxr-xr-xcode/bt/embdrv/sbc/decoder/include/oi_utils.h377
-rwxr-xr-xcode/bt/embdrv/sbc/decoder/srce/alloc.c78
-rwxr-xr-xcode/bt/embdrv/sbc/decoder/srce/bitalloc-sbc.c165
-rwxr-xr-xcode/bt/embdrv/sbc/decoder/srce/bitalloc.c392
-rwxr-xr-xcode/bt/embdrv/sbc/decoder/srce/bitstream-decode.c92
-rwxr-xr-xcode/bt/embdrv/sbc/decoder/srce/decoder-oina.c140
-rwxr-xr-xcode/bt/embdrv/sbc/decoder/srce/decoder-private.c227
-rwxr-xr-xcode/bt/embdrv/sbc/decoder/srce/decoder-sbc.c465
-rwxr-xr-xcode/bt/embdrv/sbc/decoder/srce/dequant.c210
-rwxr-xr-xcode/bt/embdrv/sbc/decoder/srce/framing-sbc.c54
-rwxr-xr-xcode/bt/embdrv/sbc/decoder/srce/framing.c249
-rwxr-xr-xcode/bt/embdrv/sbc/decoder/srce/oi_codec_version.c57
-rwxr-xr-xcode/bt/embdrv/sbc/decoder/srce/readsamplesjoint.inc111
-rwxr-xr-xcode/bt/embdrv/sbc/decoder/srce/synthesis-8-generated.c135
-rwxr-xr-xcode/bt/embdrv/sbc/decoder/srce/synthesis-dct8.c305
-rwxr-xr-xcode/bt/embdrv/sbc/decoder/srce/synthesis-sbc.c510
-rwxr-xr-xcode/bt/embdrv/sbc/encoder/include/sbc_dct.h91
-rwxr-xr-xcode/bt/embdrv/sbc/encoder/include/sbc_enc_func_declare.h57
-rwxr-xr-xcode/bt/embdrv/sbc/encoder/include/sbc_encoder.h202
-rwxr-xr-xcode/bt/embdrv/sbc/encoder/include/sbc_if.h47
-rwxr-xr-xcode/bt/embdrv/sbc/encoder/include/sbc_types.h59
-rwxr-xr-xcode/bt/embdrv/sbc/encoder/srce/sbc_analysis.c1107
-rwxr-xr-xcode/bt/embdrv/sbc/encoder/srce/sbc_dct.c245
-rwxr-xr-xcode/bt/embdrv/sbc/encoder/srce/sbc_dct_coeffs.c200
-rwxr-xr-xcode/bt/embdrv/sbc/encoder/srce/sbc_enc_bit_alloc_mono.c199
-rwxr-xr-xcode/bt/embdrv/sbc/encoder/srce/sbc_enc_bit_alloc_ste.c212
-rwxr-xr-xcode/bt/embdrv/sbc/encoder/srce/sbc_enc_coeffs.c319
-rwxr-xr-xcode/bt/embdrv/sbc/encoder/srce/sbc_encoder.c306
-rwxr-xr-xcode/bt/embdrv/sbc/encoder/srce/sbc_packing.c274
-rwxr-xr-xcode/bt/hci/Android.mk97
-rwxr-xr-xcode/bt/hci/BUILD.gn79
-rwxr-xr-xcode/bt/hci/include/bt_hci_bdroid.h131
-rwxr-xr-xcode/bt/hci/include/bt_list.h168
-rwxr-xr-xcode/bt/hci/include/bt_skbuff.h362
-rwxr-xr-xcode/bt/hci/include/bt_vendor_lib.h414
-rwxr-xr-xcode/bt/hci/include/btsnoop.h39
-rwxr-xr-xcode/bt/hci/include/btsnoop_mem.h36
-rwxr-xr-xcode/bt/hci/include/buffer_allocator.h23
-rwxr-xr-xcode/bt/hci/include/hci_audio.h40
-rwxr-xr-xcode/bt/hci/include/hci_hal.h91
-rwxr-xr-xcode/bt/hci/include/hci_inject.h34
-rwxr-xr-xcode/bt/hci/include/hci_internals.h28
-rwxr-xr-xcode/bt/hci/include/hci_layer.h123
-rwxr-xr-xcode/bt/hci/include/hci_packet_factory.h46
-rwxr-xr-xcode/bt/hci/include/hci_packet_parser.h105
-rwxr-xr-xcode/bt/hci/include/low_power_manager.h47
-rwxr-xr-xcode/bt/hci/include/packet_fragmenter.h60
-rwxr-xr-xcode/bt/hci/include/rtk_parse.h96
-rwxr-xr-xcode/bt/hci/include/userial.h71
-rwxr-xr-xcode/bt/hci/include/vendor.h73
-rwxr-xr-xcode/bt/hci/src/bt_list.c144
-rwxr-xr-xcode/bt/hci/src/bt_skbuff.c573
-rwxr-xr-xcode/bt/hci/src/btsnoop.c245
-rwxr-xr-xcode/bt/hci/src/btsnoop_mem.c66
-rwxr-xr-xcode/bt/hci/src/btsnoop_net.c153
-rwxr-xr-xcode/bt/hci/src/buffer_allocator.c36
-rwxr-xr-xcode/bt/hci/src/hci_audio.c38
-rwxr-xr-xcode/bt/hci/src/hci_h5.c2975
-rwxr-xr-xcode/bt/hci/src/hci_h5_int.h66
-rwxr-xr-xcode/bt/hci/src/hci_hal.c38
-rwxr-xr-xcode/bt/hci/src/hci_hal_h4.c264
-rwxr-xr-xcode/bt/hci/src/hci_hal_h5.c312
-rwxr-xr-xcode/bt/hci/src/hci_hal_mct.c211
-rwxr-xr-xcode/bt/hci/src/hci_inject.c209
-rwxr-xr-xcode/bt/hci/src/hci_layer.c902
-rwxr-xr-xcode/bt/hci/src/hci_packet_factory.c207
-rwxr-xr-xcode/bt/hci/src/hci_packet_parser.c271
-rwxr-xr-xcode/bt/hci/src/low_power_manager.c249
-rwxr-xr-xcode/bt/hci/src/packet_fragmenter.c249
-rwxr-xr-xcode/bt/hci/src/rtk_btsnoop_net.c244
-rwxr-xr-xcode/bt/hci/src/rtk_parse.c2648
-rwxr-xr-xcode/bt/hci/src/vendor.c255
-rwxr-xr-xcode/bt/hci/test/hci_hal_h4_test.cpp270
-rwxr-xr-xcode/bt/hci/test/hci_hal_mct_test.cpp244
-rwxr-xr-xcode/bt/hci/test/hci_layer_test.cpp756
-rwxr-xr-xcode/bt/hci/test/low_power_manager_test.cpp140
-rwxr-xr-xcode/bt/hci/test/packet_fragmenter_test.cpp378
-rwxr-xr-xcode/bt/include/bt_common.h23
-rwxr-xr-xcode/bt/include/bt_target.h1558
-rwxr-xr-xcode/bt/include/bt_trace.h416
-rwxr-xr-xcode/bt/include/bte.h114
-rwxr-xr-xcode/bt/include/bte_appl.h37
-rwxr-xr-xcode/bt/include/stack_config.h55
-rwxr-xr-xcode/bt/main/Android.mk113
-rwxr-xr-xcode/bt/main/BUILD.gn85
-rwxr-xr-xcode/bt/main/bte_conf.c124
-rwxr-xr-xcode/bt/main/bte_init.c215
-rwxr-xr-xcode/bt/main/bte_logmsg.c254
-rwxr-xr-xcode/bt/main/bte_main.c306
-rwxr-xr-xcode/bt/main/stack_config.c168
-rwxr-xr-xcode/bt/osi/Android.mk207
-rwxr-xr-xcode/bt/osi/BUILD.gn97
-rwxr-xr-xcode/bt/osi/include/alarm.h120
-rwxr-xr-xcode/bt/osi/include/allocation_tracker.h57
-rwxr-xr-xcode/bt/osi/include/allocator.h48
-rwxr-xr-xcode/bt/osi/include/array.h57
-rwxr-xr-xcode/bt/osi/include/buffer.h56
-rwxr-xr-xcode/bt/osi/include/compat.h35
-rwxr-xr-xcode/bt/osi/include/config.h136
-rwxr-xr-xcode/bt/osi/include/data_dispatcher.h56
-rwxr-xr-xcode/bt/osi/include/eager_reader.h67
-rwxr-xr-xcode/bt/osi/include/fixed_queue.h124
-rwxr-xr-xcode/bt/osi/include/future.h41
-rwxr-xr-xcode/bt/osi/include/hash_functions.h30
-rwxr-xr-xcode/bt/osi/include/hash_map.h108
-rwxr-xr-xcode/bt/osi/include/hash_map_utils.h37
-rwxr-xr-xcode/bt/osi/include/list.h114
-rwxr-xr-xcode/bt/osi/include/log.h52
-rwxr-xr-xcode/bt/osi/include/metrics.h97
-rwxr-xr-xcode/bt/osi/include/mutex.h33
-rwxr-xr-xcode/bt/osi/include/osi.h64
-rwxr-xr-xcode/bt/osi/include/properties.h37
-rwxr-xr-xcode/bt/osi/include/reactor.h82
-rwxr-xr-xcode/bt/osi/include/ringbuffer.h61
-rwxr-xr-xcode/bt/osi/include/semaphore.h57
-rwxr-xr-xcode/bt/osi/include/socket.h104
-rwxr-xr-xcode/bt/osi/include/socket_utils/socket_local.h36
-rwxr-xr-xcode/bt/osi/include/socket_utils/sockets.h78
-rwxr-xr-xcode/bt/osi/include/thread.h75
-rwxr-xr-xcode/bt/osi/include/time.h30
-rwxr-xr-xcode/bt/osi/include/wakelock.h54
-rwxr-xr-xcode/bt/osi/src/alarm.c787
-rwxr-xr-xcode/bt/osi/src/allocation_tracker.c196
-rwxr-xr-xcode/bt/osi/src/allocator.c98
-rwxr-xr-xcode/bt/osi/src/array.c110
-rwxr-xr-xcode/bt/osi/src/buffer.c92
-rwxr-xr-xcode/bt/osi/src/compat.c133
-rwxr-xr-xcode/bt/osi/src/config.c506
-rwxr-xr-xcode/bt/osi/src/data_dispatcher.c100
-rwxr-xr-xcode/bt/osi/src/eager_reader.c276
-rwxr-xr-xcode/bt/osi/src/fixed_queue.c268
-rwxr-xr-xcode/bt/osi/src/future.c89
-rwxr-xr-xcode/bt/osi/src/hash_functions.c42
-rwxr-xr-xcode/bt/osi/src/hash_map.c246
-rwxr-xr-xcode/bt/osi/src/hash_map_utils.c104
-rwxr-xr-xcode/bt/osi/src/list.c223
-rwxr-xr-xcode/bt/osi/src/metrics.cpp226
-rwxr-xr-xcode/bt/osi/src/metrics_linux.cpp60
-rwxr-xr-xcode/bt/osi/src/mutex.c44
-rwxr-xr-xcode/bt/osi/src/osi.c53
-rwxr-xr-xcode/bt/osi/src/properties.c48
-rwxr-xr-xcode/bt/osi/src/protos/bluetooth.proto201
-rwxr-xr-xcode/bt/osi/src/reactor.c286
-rwxr-xr-xcode/bt/osi/src/ringbuffer.c119
-rwxr-xr-xcode/bt/osi/src/semaphore.c108
-rwxr-xr-xcode/bt/osi/src/socket.c228
-rwxr-xr-xcode/bt/osi/src/socket_utils/README36
-rwxr-xr-xcode/bt/osi/src/socket_utils/socket_local_client.c151
-rwxr-xr-xcode/bt/osi/src/socket_utils/socket_local_server.c106
-rwxr-xr-xcode/bt/osi/src/thread.c235
-rwxr-xr-xcode/bt/osi/src/time.c29
-rwxr-xr-xcode/bt/osi/src/wakelock.c393
-rwxr-xr-xcode/bt/osi/test/AlarmTestHarness.cpp127
-rwxr-xr-xcode/bt/osi/test/AlarmTestHarness.h37
-rwxr-xr-xcode/bt/osi/test/AllocationTestHarness.cpp34
-rwxr-xr-xcode/bt/osi/test/AllocationTestHarness.h27
-rwxr-xr-xcode/bt/osi/test/alarm_test.cpp465
-rwxr-xr-xcode/bt/osi/test/allocation_tracker_test.cpp60
-rwxr-xr-xcode/bt/osi/test/allocator_test.cpp54
-rwxr-xr-xcode/bt/osi/test/array_test.cpp77
-rwxr-xr-xcode/bt/osi/test/config_test.cpp203
-rwxr-xr-xcode/bt/osi/test/data_dispatcher_test.cpp253
-rwxr-xr-xcode/bt/osi/test/eager_reader_test.cpp147
-rwxr-xr-xcode/bt/osi/test/fixed_queue_test.cpp307
-rwxr-xr-xcode/bt/osi/test/future_test.cpp54
-rwxr-xr-xcode/bt/osi/test/hash_map_test.cpp202
-rwxr-xr-xcode/bt/osi/test/hash_map_utils_test.cpp122
-rwxr-xr-xcode/bt/osi/test/list_test.cpp216
-rwxr-xr-xcode/bt/osi/test/properties_test.cpp43
-rwxr-xr-xcode/bt/osi/test/rand_test.cpp19
-rwxr-xr-xcode/bt/osi/test/reactor_test.cpp119
-rwxr-xr-xcode/bt/osi/test/ringbuffer_test.cpp139
-rwxr-xr-xcode/bt/osi/test/semaphore_test.cpp87
-rwxr-xr-xcode/bt/osi/test/test_stubs.h99
-rwxr-xr-xcode/bt/osi/test/thread_test.cpp59
-rwxr-xr-xcode/bt/osi/test/time_test.cpp76
-rwxr-xr-xcode/bt/profile/Android.mk44
-rwxr-xr-xcode/bt/profile/include/manager.h41
-rwxr-xr-xcode/bt/profile/src/manager.c87
-rwxr-xr-xcode/bt/realtek/Android.mk32
-rwxr-xr-xcode/bt/realtek/include/bdroid_buildcfg.h70
-rwxr-xr-xcode/bt/realtek/include/rtkbt_api.h295
-rwxr-xr-xcode/bt/realtek/include/rtkbt_api_int.h27
-rwxr-xr-xcode/bt/realtek/include/rtkbt_api_ver.h6
-rwxr-xr-xcode/bt/realtek/include/rtkbt_api_ver_toolchain.h6
-rwxr-xr-xcode/bt/realtek/include/rtkbt_config.h6
-rwxr-xr-xcode/bt/realtek/src/Android.mk17
-rwxr-xr-xcode/bt/realtek/src/rtkbt_api.c444
-rwxr-xr-xcode/bt/realtek/src/rtkbt_conf.c321
-rwxr-xr-xcode/bt/service/Android.mk258
-rwxr-xr-xcode/bt/service/BUILD.gn98
-rwxr-xr-xcode/bt/service/adapter.cpp403
-rwxr-xr-xcode/bt/service/adapter.h143
-rwxr-xr-xcode/bt/service/bluetooth_instance.h75
-rwxr-xr-xcode/bt/service/bluetoothtbd.rc4
-rwxr-xr-xcode/bt/service/client/main.cpp886
-rwxr-xr-xcode/bt/service/common/README18
-rwxr-xr-xcode/bt/service/common/bluetooth/adapter_state.cpp44
-rwxr-xr-xcode/bt/service/common/bluetooth/adapter_state.h43
-rwxr-xr-xcode/bt/service/common/bluetooth/advertise_data.cpp109
-rwxr-xr-xcode/bt/service/common/bluetooth/advertise_data.h79
-rwxr-xr-xcode/bt/service/common/bluetooth/advertise_settings.cpp55
-rwxr-xr-xcode/bt/service/common/bluetooth/advertise_settings.h98
-rwxr-xr-xcode/bt/service/common/bluetooth/binder/IBluetooth.cpp314
-rwxr-xr-xcode/bt/service/common/bluetooth/binder/IBluetooth.h212
-rwxr-xr-xcode/bt/service/common/bluetooth/binder/IBluetoothCallback.cpp86
-rwxr-xr-xcode/bt/service/common/bluetooth/binder/IBluetoothCallback.h87
-rwxr-xr-xcode/bt/service/common/bluetooth/binder/IBluetoothGattClient.cpp109
-rwxr-xr-xcode/bt/service/common/bluetooth/binder/IBluetoothGattClient.h108
-rwxr-xr-xcode/bt/service/common/bluetooth/binder/IBluetoothGattClientCallback.cpp85
-rwxr-xr-xcode/bt/service/common/bluetooth/binder/IBluetoothGattClientCallback.h97
-rwxr-xr-xcode/bt/service/common/bluetooth/binder/IBluetoothGattServer.cpp331
-rwxr-xr-xcode/bt/service/common/bluetooth/binder/IBluetoothGattServer.h158
-rwxr-xr-xcode/bt/service/common/bluetooth/binder/IBluetoothGattServerCallback.cpp301
-rwxr-xr-xcode/bt/service/common/bluetooth/binder/IBluetoothGattServerCallback.h154
-rwxr-xr-xcode/bt/service/common/bluetooth/binder/IBluetoothLowEnergy.cpp304
-rwxr-xr-xcode/bt/service/common/bluetooth/binder/IBluetoothLowEnergy.h151
-rwxr-xr-xcode/bt/service/common/bluetooth/binder/IBluetoothLowEnergyCallback.cpp186
-rwxr-xr-xcode/bt/service/common/bluetooth/binder/IBluetoothLowEnergyCallback.h113
-rwxr-xr-xcode/bt/service/common/bluetooth/binder/parcel_helpers.cpp305
-rwxr-xr-xcode/bt/service/common/bluetooth/binder/parcel_helpers.h99
-rwxr-xr-xcode/bt/service/common/bluetooth/gatt_identifier.cpp188
-rwxr-xr-xcode/bt/service/common/bluetooth/gatt_identifier.h144
-rwxr-xr-xcode/bt/service/common/bluetooth/low_energy_constants.h125
-rwxr-xr-xcode/bt/service/common/bluetooth/scan_filter.cpp98
-rwxr-xr-xcode/bt/service/common/bluetooth/scan_filter.h77
-rwxr-xr-xcode/bt/service/common/bluetooth/scan_result.cpp49
-rwxr-xr-xcode/bt/service/common/bluetooth/scan_result.h55
-rwxr-xr-xcode/bt/service/common/bluetooth/scan_settings.cpp65
-rwxr-xr-xcode/bt/service/common/bluetooth/scan_settings.h164
-rwxr-xr-xcode/bt/service/common/bluetooth/util/address_helper.cpp58
-rwxr-xr-xcode/bt/service/common/bluetooth/util/address_helper.h36
-rwxr-xr-xcode/bt/service/common/bluetooth/util/atomic_string.cpp36
-rwxr-xr-xcode/bt/service/common/bluetooth/util/atomic_string.h40
-rwxr-xr-xcode/bt/service/common/bluetooth/uuid.cpp177
-rwxr-xr-xcode/bt/service/common/bluetooth/uuid.h110
-rwxr-xr-xcode/bt/service/daemon.cpp182
-rwxr-xr-xcode/bt/service/daemon.h74
-rwxr-xr-xcode/bt/service/doc/IBluetooth.txt119
-rwxr-xr-xcode/bt/service/doc/IBluetoothCallback.txt26
-rwxr-xr-xcode/bt/service/doc/IBluetoothGattClient.txt180
-rwxr-xr-xcode/bt/service/doc/IBluetoothGattClientCallback.txt121
-rwxr-xr-xcode/bt/service/doc/IBluetoothGattServer.txt114
-rwxr-xr-xcode/bt/service/doc/IBluetoothGattServerCallback.txt134
-rwxr-xr-xcode/bt/service/doc/IBluetoothLowEnergy.txt97
-rwxr-xr-xcode/bt/service/doc/IBluetoothLowEnergyCallback.txt54
-rwxr-xr-xcode/bt/service/example/heart_rate/constants.h45
-rwxr-xr-xcode/bt/service/example/heart_rate/heart_rate_server.cpp498
-rwxr-xr-xcode/bt/service/example/heart_rate/heart_rate_server.h143
-rwxr-xr-xcode/bt/service/example/heart_rate/server_main.cpp154
-rwxr-xr-xcode/bt/service/gatt_client.cpp111
-rwxr-xr-xcode/bt/service/gatt_client.h84
-rwxr-xr-xcode/bt/service/gatt_server.cpp1022
-rwxr-xr-xcode/bt/service/gatt_server.h390
-rwxr-xr-xcode/bt/service/gatt_server_old.cpp780
-rwxr-xr-xcode/bt/service/gatt_server_old.h125
-rwxr-xr-xcode/bt/service/hal/bluetooth_gatt_interface.cpp960
-rwxr-xr-xcode/bt/service/hal/bluetooth_gatt_interface.h291
-rwxr-xr-xcode/bt/service/hal/bluetooth_interface.cpp434
-rwxr-xr-xcode/bt/service/hal/bluetooth_interface.h127
-rwxr-xr-xcode/bt/service/hal/fake_bluetooth_gatt_interface.cpp416
-rwxr-xr-xcode/bt/service/hal/fake_bluetooth_gatt_interface.h153
-rwxr-xr-xcode/bt/service/hal/fake_bluetooth_interface.cpp168
-rwxr-xr-xcode/bt/service/hal/fake_bluetooth_interface.h75
-rwxr-xr-xcode/bt/service/hal/gatt_helpers.cpp43
-rwxr-xr-xcode/bt/service/hal/gatt_helpers.h41
-rwxr-xr-xcode/bt/service/ipc/binder/bluetooth_binder_server.cpp187
-rwxr-xr-xcode/bt/service/ipc/binder/bluetooth_binder_server.h93
-rwxr-xr-xcode/bt/service/ipc/binder/bluetooth_gatt_client_binder_server.cpp84
-rwxr-xr-xcode/bt/service/ipc/binder/bluetooth_gatt_client_binder_server.h69
-rwxr-xr-xcode/bt/service/ipc/binder/bluetooth_gatt_server_binder_server.cpp358
-rwxr-xr-xcode/bt/service/ipc/binder/bluetooth_gatt_server_binder_server.h118
-rwxr-xr-xcode/bt/service/ipc/binder/bluetooth_low_energy_binder_server.cpp298
-rwxr-xr-xcode/bt/service/ipc/binder/bluetooth_low_energy_binder_server.h94
-rwxr-xr-xcode/bt/service/ipc/binder/interface_with_instances_base.cpp157
-rwxr-xr-xcode/bt/service/ipc/binder/interface_with_instances_base.h108
-rwxr-xr-xcode/bt/service/ipc/binder/ipc_handler_binder.cpp82
-rwxr-xr-xcode/bt/service/ipc/binder/ipc_handler_binder.h46
-rwxr-xr-xcode/bt/service/ipc/binder/remote_callback_list.h207
-rwxr-xr-xcode/bt/service/ipc/binder/remote_callback_map.h260
-rwxr-xr-xcode/bt/service/ipc/ipc_handler.cpp33
-rwxr-xr-xcode/bt/service/ipc/ipc_handler.h62
-rwxr-xr-xcode/bt/service/ipc/ipc_handler_linux.cpp215
-rwxr-xr-xcode/bt/service/ipc/ipc_handler_linux.h86
-rwxr-xr-xcode/bt/service/ipc/ipc_manager.cpp81
-rwxr-xr-xcode/bt/service/ipc/ipc_manager.h100
-rwxr-xr-xcode/bt/service/ipc/linux_ipc_host.cpp343
-rwxr-xr-xcode/bt/service/ipc/linux_ipc_host.h107
-rwxr-xr-xcode/bt/service/logging_helpers.cpp149
-rwxr-xr-xcode/bt/service/logging_helpers.h47
-rwxr-xr-xcode/bt/service/low_energy_client.cpp895
-rwxr-xr-xcode/bt/service/low_energy_client.h276
-rwxr-xr-xcode/bt/service/main.cpp90
-rwxr-xr-xcode/bt/service/settings.cpp86
-rwxr-xr-xcode/bt/service/settings.h71
-rwxr-xr-xcode/bt/service/switches.h42
-rwxr-xr-xcode/bt/service/test/adapter_unittest.cpp288
-rwxr-xr-xcode/bt/service/test/advertise_data_unittest.cpp153
-rwxr-xr-xcode/bt/service/test/fake_hal_util.cpp29
-rwxr-xr-xcode/bt/service/test/gatt_client_unittest.cpp195
-rwxr-xr-xcode/bt/service/test/gatt_identifier_unittest.cpp117
-rwxr-xr-xcode/bt/service/test/gatt_server_unittest.cpp1336
-rwxr-xr-xcode/bt/service/test/ipc_linux_unittest.cpp206
-rwxr-xr-xcode/bt/service/test/low_energy_client_unittest.cpp1018
-rwxr-xr-xcode/bt/service/test/main.cpp36
-rwxr-xr-xcode/bt/service/test/mock_adapter.h54
-rwxr-xr-xcode/bt/service/test/mock_daemon.h41
-rwxr-xr-xcode/bt/service/test/parcel_helpers_unittest.cpp212
-rwxr-xr-xcode/bt/service/test/settings_unittest.cpp112
-rwxr-xr-xcode/bt/service/test/stub_ipc_handler_binder.cpp49
-rwxr-xr-xcode/bt/service/test/stub_ipc_handler_linux.cpp72
-rwxr-xr-xcode/bt/service/test/util_unittest.cpp46
-rwxr-xr-xcode/bt/service/test/uuid_unittest.cpp162
-rwxr-xr-xcode/bt/stack/Android.mk160
-rwxr-xr-xcode/bt/stack/BUILD.gn167
-rwxr-xr-xcode/bt/stack/a2dp/a2d_api.c399
-rwxr-xr-xcode/bt/stack/a2dp/a2d_int.h82
-rwxr-xr-xcode/bt/stack/a2dp/a2d_sbc.c226
-rwxr-xr-xcode/bt/stack/avct/avct_api.c473
-rwxr-xr-xcode/bt/stack/avct/avct_ccb.c150
-rwxr-xr-xcode/bt/stack/avct/avct_defs.h62
-rwxr-xr-xcode/bt/stack/avct/avct_int.h238
-rwxr-xr-xcode/bt/stack/avct/avct_l2c.c436
-rwxr-xr-xcode/bt/stack/avct/avct_lcb.c464
-rwxr-xr-xcode/bt/stack/avct/avct_lcb_act.c720
-rwxr-xr-xcode/bt/stack/avdt/avdt_ad.c640
-rwxr-xr-xcode/bt/stack/avdt/avdt_api.c1323
-rwxr-xr-xcode/bt/stack/avdt/avdt_ccb.c471
-rwxr-xr-xcode/bt/stack/avdt/avdt_ccb_act.c1116
-rwxr-xr-xcode/bt/stack/avdt/avdt_defs.h203
-rwxr-xr-xcode/bt/stack/avdt/avdt_int.h752
-rwxr-xr-xcode/bt/stack/avdt/avdt_l2c.c547
-rwxr-xr-xcode/bt/stack/avdt/avdt_msg.c1897
-rwxr-xr-xcode/bt/stack/avdt/avdt_scb.c790
-rwxr-xr-xcode/bt/stack/avdt/avdt_scb_act.c2160
-rwxr-xr-xcode/bt/stack/avrc/avrc_api.c1132
-rwxr-xr-xcode/bt/stack/avrc/avrc_bld_ct.c507
-rwxr-xr-xcode/bt/stack/avrc/avrc_bld_tg.c994
-rwxr-xr-xcode/bt/stack/avrc/avrc_int.h158
-rwxr-xr-xcode/bt/stack/avrc/avrc_opt.c227
-rwxr-xr-xcode/bt/stack/avrc/avrc_pars_ct.c453
-rwxr-xr-xcode/bt/stack/avrc/avrc_pars_tg.c421
-rwxr-xr-xcode/bt/stack/avrc/avrc_sdp.c336
-rwxr-xr-xcode/bt/stack/avrc/avrc_utils.c242
-rwxr-xr-xcode/bt/stack/bnep/bnep_api.c744
-rwxr-xr-xcode/bt/stack/bnep/bnep_int.h249
-rwxr-xr-xcode/bt/stack/bnep/bnep_main.c806
-rwxr-xr-xcode/bt/stack/bnep/bnep_utils.c1372
-rwxr-xr-xcode/bt/stack/btm/btm_acl.c2644
-rwxr-xr-xcode/bt/stack/btm/btm_ble.c2803
-rwxr-xr-xcode/bt/stack/btm/btm_ble_addr.c585
-rwxr-xr-xcode/bt/stack/btm/btm_ble_adv_filter.c1341
-rwxr-xr-xcode/bt/stack/btm/btm_ble_batchscan.c969
-rwxr-xr-xcode/bt/stack/btm/btm_ble_bgconn.c735
-rwxr-xr-xcode/bt/stack/btm/btm_ble_cont_energy.c111
-rwxr-xr-xcode/bt/stack/btm/btm_ble_gap.c3511
-rwxr-xr-xcode/bt/stack/btm/btm_ble_int.h497
-rwxr-xr-xcode/bt/stack/btm/btm_ble_multi_adv.c890
-rwxr-xr-xcode/bt/stack/btm/btm_ble_privacy.c1032
-rwxr-xr-xcode/bt/stack/btm/btm_dev.c610
-rwxr-xr-xcode/bt/stack/btm/btm_devctl.c984
-rwxr-xr-xcode/bt/stack/btm/btm_inq.c2969
-rwxr-xr-xcode/bt/stack/btm/btm_int.h1138
-rwxr-xr-xcode/bt/stack/btm/btm_main.c81
-rwxr-xr-xcode/bt/stack/btm/btm_pm.c1039
-rwxr-xr-xcode/bt/stack/btm/btm_sco.c1816
-rwxr-xr-xcode/bt/stack/btm/btm_sec.c6355
-rwxr-xr-xcode/bt/stack/btu/btu_hcif.c1709
-rwxr-xr-xcode/bt/stack/btu/btu_init.c174
-rwxr-xr-xcode/bt/stack/btu/btu_task.c239
-rwxr-xr-xcode/bt/stack/gap/gap_api.c75
-rwxr-xr-xcode/bt/stack/gap/gap_ble.c809
-rwxr-xr-xcode/bt/stack/gap/gap_conn.c1260
-rwxr-xr-xcode/bt/stack/gap/gap_int.h166
-rwxr-xr-xcode/bt/stack/gap/gap_utils.c142
-rwxr-xr-xcode/bt/stack/gatt/att_protocol.c606
-rwxr-xr-xcode/bt/stack/gatt/gatt_api.c1645
-rwxr-xr-xcode/bt/stack/gatt/gatt_attr.c491
-rwxr-xr-xcode/bt/stack/gatt/gatt_auth.c533
-rwxr-xr-xcode/bt/stack/gatt/gatt_cl.c1262
-rwxr-xr-xcode/bt/stack/gatt/gatt_db.c1207
-rwxr-xr-xcode/bt/stack/gatt/gatt_int.h692
-rwxr-xr-xcode/bt/stack/gatt/gatt_main.c1253
-rwxr-xr-xcode/bt/stack/gatt/gatt_sr.c1472
-rwxr-xr-xcode/bt/stack/gatt/gatt_utils.c2860
-rwxr-xr-xcode/bt/stack/hcic/hciblecmds.c770
-rwxr-xr-xcode/bt/stack/hcic/hcicmds.c1447
-rwxr-xr-xcode/bt/stack/hid/hid_conn.h69
-rwxr-xr-xcode/bt/stack/hid/hidh_api.c599
-rwxr-xr-xcode/bt/stack/hid/hidh_conn.c1111
-rwxr-xr-xcode/bt/stack/hid/hidh_int.h94
-rwxr-xr-xcode/bt/stack/include/a2d_api.h256
-rwxr-xr-xcode/bt/stack/include/a2d_sbc.h212
-rwxr-xr-xcode/bt/stack/include/avct_api.h279
-rwxr-xr-xcode/bt/stack/include/avdt_api.h959
-rwxr-xr-xcode/bt/stack/include/avdtc_api.h230
-rwxr-xr-xcode/bt/stack/include/avrc_api.h672
-rwxr-xr-xcode/bt/stack/include/avrc_defs.h1414
-rwxr-xr-xcode/bt/stack/include/bnep_api.h464
-rwxr-xr-xcode/bt/stack/include/bt_types.h794
-rwxr-xr-xcode/bt/stack/include/btm_api.h3960
-rwxr-xr-xcode/bt/stack/include/btm_ble_api.h1890
-rwxr-xr-xcode/bt/stack/include/btu.h90
-rwxr-xr-xcode/bt/stack/include/dyn_mem.h150
-rwxr-xr-xcode/bt/stack/include/gap_api.h382
-rwxr-xr-xcode/bt/stack/include/gatt_api.h1192
-rwxr-xr-xcode/bt/stack/include/gattdefs.h124
-rwxr-xr-xcode/bt/stack/include/hcidefs.h2613
-rwxr-xr-xcode/bt/stack/include/hcimsgs.h811
-rwxr-xr-xcode/bt/stack/include/hiddefs.h159
-rwxr-xr-xcode/bt/stack/include/hidh_api.h236
-rwxr-xr-xcode/bt/stack/include/l2c_api.h1239
-rwxr-xr-xcode/bt/stack/include/l2cap_client.h74
-rwxr-xr-xcode/bt/stack/include/l2cdefs.h334
-rwxr-xr-xcode/bt/stack/include/mca_api.h495
-rwxr-xr-xcode/bt/stack/include/mca_defs.h87
-rwxr-xr-xcode/bt/stack/include/pan_api.h459
-rwxr-xr-xcode/bt/stack/include/port_api.h659
-rwxr-xr-xcode/bt/stack/include/port_ext.h32
-rwxr-xr-xcode/bt/stack/include/profiles_api.h71
-rwxr-xr-xcode/bt/stack/include/rfcdefs.h248
-rwxr-xr-xcode/bt/stack/include/sdp_api.h679
-rwxr-xr-xcode/bt/stack/include/sdpdefs.h327
-rwxr-xr-xcode/bt/stack/include/smp_api.h494
-rwxr-xr-xcode/bt/stack/include/srvc_api.h217
-rwxr-xr-xcode/bt/stack/l2cap/l2c_api.c2306
-rwxr-xr-xcode/bt/stack/l2cap/l2c_ble.c1518
-rwxr-xr-xcode/bt/stack/l2cap/l2c_csm.c1523
-rwxr-xr-xcode/bt/stack/l2cap/l2c_fcr.c2522
-rwxr-xr-xcode/bt/stack/l2cap/l2c_int.h796
-rwxr-xr-xcode/bt/stack/l2cap/l2c_link.c1554
-rwxr-xr-xcode/bt/stack/l2cap/l2c_main.c954
-rwxr-xr-xcode/bt/stack/l2cap/l2c_ucd.c1175
-rwxr-xr-xcode/bt/stack/l2cap/l2c_utils.c3830
-rwxr-xr-xcode/bt/stack/l2cap/l2cap_client.c433
-rwxr-xr-xcode/bt/stack/mcap/mca_api.c906
-rwxr-xr-xcode/bt/stack/mcap/mca_cact.c580
-rwxr-xr-xcode/bt/stack/mcap/mca_csm.c383
-rwxr-xr-xcode/bt/stack/mcap/mca_dact.c168
-rwxr-xr-xcode/bt/stack/mcap/mca_dsm.c346
-rwxr-xr-xcode/bt/stack/mcap/mca_int.h365
-rwxr-xr-xcode/bt/stack/mcap/mca_l2c.c587
-rwxr-xr-xcode/bt/stack/mcap/mca_main.c631
-rwxr-xr-xcode/bt/stack/pan/pan_api.c768
-rwxr-xr-xcode/bt/stack/pan/pan_int.h156
-rwxr-xr-xcode/bt/stack/pan/pan_main.c724
-rwxr-xr-xcode/bt/stack/pan/pan_utils.c348
-rwxr-xr-xcode/bt/stack/rfcomm/port_api.c1868
-rwxr-xr-xcode/bt/stack/rfcomm/port_int.h251
-rwxr-xr-xcode/bt/stack/rfcomm/port_rfc.c1121
-rwxr-xr-xcode/bt/stack/rfcomm/port_utils.c592
-rwxr-xr-xcode/bt/stack/rfcomm/rfc_int.h384
-rwxr-xr-xcode/bt/stack/rfcomm/rfc_l2cap_if.c452
-rwxr-xr-xcode/bt/stack/rfcomm/rfc_mx_fsm.c679
-rwxr-xr-xcode/bt/stack/rfcomm/rfc_port_fsm.c918
-rwxr-xr-xcode/bt/stack/rfcomm/rfc_port_if.c376
-rwxr-xr-xcode/bt/stack/rfcomm/rfc_ts_frames.c876
-rwxr-xr-xcode/bt/stack/rfcomm/rfc_utils.c474
-rwxr-xr-xcode/bt/stack/sdp/sdp_api.c1277
-rwxr-xr-xcode/bt/stack/sdp/sdp_db.c980
-rwxr-xr-xcode/bt/stack/sdp/sdp_discovery.c1064
-rwxr-xr-xcode/bt/stack/sdp/sdp_main.c729
-rwxr-xr-xcode/bt/stack/sdp/sdp_server.c830
-rwxr-xr-xcode/bt/stack/sdp/sdp_utils.c1043
-rwxr-xr-xcode/bt/stack/sdp/sdpint.h324
-rwxr-xr-xcode/bt/stack/smp/aes.c934
-rwxr-xr-xcode/bt/stack/smp/aes.h162
-rwxr-xr-xcode/bt/stack/smp/p_256_curvepara.c80
-rwxr-xr-xcode/bt/stack/smp/p_256_ecc_pp.c262
-rwxr-xr-xcode/bt/stack/smp/p_256_ecc_pp.h65
-rwxr-xr-xcode/bt/stack/smp/p_256_multprecision.c704
-rwxr-xr-xcode/bt/stack/smp/p_256_multprecision.h62
-rwxr-xr-xcode/bt/stack/smp/smp_act.c2194
-rwxr-xr-xcode/bt/stack/smp/smp_api.c621
-rwxr-xr-xcode/bt/stack/smp/smp_br_main.c399
-rwxr-xr-xcode/bt/stack/smp/smp_cmac.c374
-rwxr-xr-xcode/bt/stack/smp/smp_int.h544
-rwxr-xr-xcode/bt/stack/smp/smp_keys.c2272
-rwxr-xr-xcode/bt/stack/smp/smp_l2c.c362
-rwxr-xr-xcode/bt/stack/smp/smp_main.c862
-rwxr-xr-xcode/bt/stack/smp/smp_utils.c1547
-rwxr-xr-xcode/bt/stack/srvc/srvc_battery.c408
-rwxr-xr-xcode/bt/stack/srvc/srvc_battery_int.h81
-rwxr-xr-xcode/bt/stack/srvc/srvc_dis.c482
-rwxr-xr-xcode/bt/stack/srvc/srvc_dis_int.h78
-rwxr-xr-xcode/bt/stack/srvc/srvc_eng.c484
-rwxr-xr-xcode/bt/stack/srvc/srvc_eng_int.h88
-rwxr-xr-xcode/bt/test/Android.mk1
-rwxr-xr-xcode/bt/test/run_unit_tests.sh120
-rwxr-xr-xcode/bt/test/suite/Android.mk.disabled59
-rwxr-xr-xcode/bt/test/suite/BUILD.gn44
-rwxr-xr-xcode/bt/test/suite/adapter/adapter_unittest.cpp174
-rwxr-xr-xcode/bt/test/suite/adapter/bluetooth_test.cpp130
-rwxr-xr-xcode/bt/test/suite/adapter/bluetooth_test.h113
-rwxr-xr-xcode/bt/test/suite/gatt/gatt_test.cpp190
-rwxr-xr-xcode/bt/test/suite/gatt/gatt_test.h137
-rwxr-xr-xcode/bt/test/suite/gatt/gatt_unittest.cpp163
-rwxr-xr-xcode/bt/tools/Android.mk.disabled1
-rwxr-xr-xcode/bt/tools/bdtool/Android.mk.disabled49
-rwxr-xr-xcode/bt/tools/bdtool/adapter.c306
-rwxr-xr-xcode/bt/tools/bdtool/bdtool.c336
-rwxr-xr-xcode/bt/tools/hci/Android.mk.disabled34
-rwxr-xr-xcode/bt/tools/hci/main.c215
-rwxr-xr-xcode/bt/tools/scripts/btsnooz.py167
-rwxr-xr-xcode/bt/tools/scripts/change_types.sh77
-rwxr-xr-xcode/bt/udrv/BUILD.gn31
-rwxr-xr-xcode/bt/udrv/include/uipc.h140
-rwxr-xr-xcode/bt/udrv/ulinux/uipc.c993
-rwxr-xr-xcode/bt/udrv/ulinux/uipc_linux.h42
-rwxr-xr-xcode/bt/utils/Android.mk25
-rwxr-xr-xcode/bt/utils/BUILD.gn27
-rwxr-xr-xcode/bt/utils/include/bt_utils.h46
-rwxr-xr-xcode/bt/utils/src/bt_utils.c183
-rwxr-xr-xcode/bt/vendor_libs/BUILD.gn23
-rwxr-xr-xcode/bt/vendor_libs/linux/Android.mk43
-rwxr-xr-xcode/bt/vendor_libs/linux/BUILD.gn33
-rwxr-xr-xcode/bt/vendor_libs/linux/bt_vendor_linux.c423
-rwxr-xr-xcode/bt/vendor_libs/test_vendor_lib/Android.mk77
-rwxr-xr-xcode/bt/vendor_libs/test_vendor_lib/BUILD.gn55
-rwxr-xr-xcode/bt/vendor_libs/test_vendor_lib/data/controller_properties.json13
-rwxr-xr-xcode/bt/vendor_libs/test_vendor_lib/include/command_packet.h80
-rwxr-xr-xcode/bt/vendor_libs/test_vendor_lib/include/dual_mode_controller.h369
-rwxr-xr-xcode/bt/vendor_libs/test_vendor_lib/include/event_packet.h161
-rwxr-xr-xcode/bt/vendor_libs/test_vendor_lib/include/hci_transport.h134
-rwxr-xr-xcode/bt/vendor_libs/test_vendor_lib/include/packet.h78
-rwxr-xr-xcode/bt/vendor_libs/test_vendor_lib/include/packet_stream.h66
-rwxr-xr-xcode/bt/vendor_libs/test_vendor_lib/include/test_channel_transport.h77
-rwxr-xr-xcode/bt/vendor_libs/test_vendor_lib/include/vendor_manager.h118
-rwxr-xr-xcode/bt/vendor_libs/test_vendor_lib/scripts/build_and_run.sh127
-rwxr-xr-xcode/bt/vendor_libs/test_vendor_lib/scripts/test_channel.py247
-rwxr-xr-xcode/bt/vendor_libs/test_vendor_lib/src/bt_vendor.cc107
-rwxr-xr-xcode/bt/vendor_libs/test_vendor_lib/src/command_packet.cc43
-rwxr-xr-xcode/bt/vendor_libs/test_vendor_lib/src/dual_mode_controller.cc561
-rwxr-xr-xcode/bt/vendor_libs/test_vendor_lib/src/event_packet.cc131
-rwxr-xr-xcode/bt/vendor_libs/test_vendor_lib/src/hci_transport.cc174
-rwxr-xr-xcode/bt/vendor_libs/test_vendor_lib/src/packet.cc69
-rwxr-xr-xcode/bt/vendor_libs/test_vendor_lib/src/packet_stream.cc134
-rwxr-xr-xcode/bt/vendor_libs/test_vendor_lib/src/test_channel_transport.cc138
-rwxr-xr-xcode/bt/vendor_libs/test_vendor_lib/src/vendor_manager.cc149
-rwxr-xr-xcode/bt/vendor_libs/test_vendor_lib/test/hci_transport_unittest.cc140
-rwxr-xr-xcode/bt/vendor_libs/test_vendor_lib/test/packet_stream_unittest.cc151
-rwxr-xr-xcode/bt/vnd/ble/vendor_hcidefs.h54
-rwxr-xr-xcode/bt/vnd/include/vendor_api.h49
-rwxr-xr-xcode/libbt-vendor/Android.mk1
-rwxr-xr-xcode/libbt-vendor/uart/Android.mk25
-rwxr-xr-xcode/libbt-vendor/uart/include/bt_vendor_rtk.h210
-rwxr-xr-xcode/libbt-vendor/uart/include/upio.h118
-rwxr-xr-xcode/libbt-vendor/uart/include/userial_vendor.h181
-rwxr-xr-xcode/libbt-vendor/uart/include/vnd_buildcfg.h11
-rwxr-xr-xcode/libbt-vendor/uart/src/bt_vendor_rtk.c229
-rwxr-xr-xcode/libbt-vendor/uart/src/hardware.c1619
-rwxr-xr-xcode/libbt-vendor/uart/src/upio.c532
-rwxr-xr-xcode/libbt-vendor/uart/src/userial_vendor.c445
-rwxr-xr-xcode/libbt-vendor/usb/Android.mk21
-rwxr-xr-xcode/libbt-vendor/usb/include/bt_vendor_rtk.h64
-rwxr-xr-xcode/libbt-vendor/usb/include/vnd_buildcfg.h6
-rwxr-xr-xcode/libbt-vendor/usb/src/bt_vendor_rtk.c271
-rwxr-xr-xrtkbt.mk69
-rwxr-xr-xsystem/etc/bluetooth/rtkbt.conf11
-rwxr-xr-xsystem/etc/firmware/rtl8703bs_configbin0 -> 63 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8703bs_fwbin0 -> 28368 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8723b_configbin0 -> 48 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8723b_fwbin0 -> 46964 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8723bs_VQ0_configbin0 -> 121 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8723bs_VQ0_fwbin0 -> 46236 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8723bs_configbin0 -> 109 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8723bs_fwbin0 -> 45928 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8723bu_configbin0 -> 82 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8723cs_xx_configbin0 -> 63 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8723cs_xx_fwbin0 -> 28892 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8723d_configbin0 -> 56 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8723d_fwbin0 -> 49964 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8723ds_configbin0 -> 89 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8723ds_fwbin0 -> 50276 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8761a_configbin0 -> 105 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8761a_fwbin0 -> 66740 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8761at_configbin0 -> 109 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8761at_fwbin0 -> 66436 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8761au8192ee_fwbin0 -> 68620 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8761au8812ae_fwbin0 -> 72100 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8761au_fwbin0 -> 67956 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8761aw8192eu_configbin0 -> 81 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8761aw8192eu_fwbin0 -> 71164 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8821a_configbin0 -> 82 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8821a_fwbin0 -> 41536 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8821as_configbin0 -> 105 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8821as_fwbin0 -> 40804 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8821c_configbin0 -> 64 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8821c_fwbin0 -> 38892 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8821cs_configbin0 -> 117 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8821cs_fwbin0 -> 39540 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8822b_configbin0 -> 60 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8822b_fwbin0 -> 53320 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8822bs_configbin0 -> 117 bytes
-rwxr-xr-xsystem/etc/firmware/rtl8822bs_fwbin0 -> 44704 bytes
-rwxr-xr-xsystem/etc/permissions/android.hardware.bluetooth.xml19
-rwxr-xr-xsystem/etc/permissions/android.hardware.bluetooth_le.xml19
-rwxr-xr-xsystem/lib/hw/audio.vr_bee_hidraw.default.sobin0 -> 22260 bytes
-rwxr-xr-xsystem/lib/rtkbt/3dd_service.sobin0 -> 18104 bytes
-rwxr-xr-xsystem/lib/rtkbt/autopair.sobin0 -> 13920 bytes
-rwxr-xr-xsystem/lib/rtkbt/autopair_huawei.sobin0 -> 13928 bytes
-rwxr-xr-xsystem/lib/rtkbt/autopair_stack.sobin0 -> 18024 bytes
-rwxr-xr-xsystem/lib/rtkbt/heartbeat.sobin0 -> 18024 bytes
-rwxr-xr-xsystem/lib/rtkbt/vr_bee1_hidraw.sobin0 -> 13928 bytes
-rwxr-xr-xsystem/lib/rtkbt/vr_bee2_hidraw.sobin0 -> 13928 bytes
-rwxr-xr-xsystem/usr/keylayout/rtkbt_virtual_hid.kl1
1008 files changed, 372575 insertions, 0 deletions
diff --git a/Android.mk b/Android.mk
new file mode 100755
index 0000000..720e5e4
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,4 @@
+ifeq ($(BOARD_HAVE_BLUETOOTH_RTK),true)
+LOCAL_PATH := $(call my-dir)
+include $(call all-subdir-makefiles)
+endif
diff --git a/addon/Android.mk b/addon/Android.mk
new file mode 100755
index 0000000..295b94e
--- /dev/null
+++ b/addon/Android.mk
@@ -0,0 +1,4 @@
+ifneq ($(BOARD_HAVE_BLUETOOTH_RTK_ADDON),)
+LOCAL_PATH := $(call my-dir)
+include $(foreach item,$(BOARD_HAVE_BLUETOOTH_RTK_ADDON),$(LOCAL_PATH)/$(item)/Android.mk)
+endif
diff --git a/addon/AudioRecordWav/Android.mk b/addon/AudioRecordWav/Android.mk
new file mode 100755
index 0000000..bd30b5b
--- /dev/null
+++ b/addon/AudioRecordWav/Android.mk
@@ -0,0 +1,4 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-subdir-makefiles)
+
diff --git a/addon/AudioRecordWav/AudioRecordWav/Android.mk b/addon/AudioRecordWav/AudioRecordWav/Android.mk
new file mode 100755
index 0000000..c88b671
--- /dev/null
+++ b/addon/AudioRecordWav/AudioRecordWav/Android.mk
@@ -0,0 +1,10 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+# Build all java files in the java subdirectory
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+# Name of the APK to build
+LOCAL_PACKAGE_NAME := rtkbtAudioRecordWav
+#LOCAL_CERTIFICATE := platform
+# Tell it to build an APK
+include $(BUILD_PACKAGE)
diff --git a/addon/AudioRecordWav/AudioRecordWav/AndroidManifest.xml b/addon/AudioRecordWav/AudioRecordWav/AndroidManifest.xml
new file mode 100755
index 0000000..187bef6
--- /dev/null
+++ b/addon/AudioRecordWav/AudioRecordWav/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.audiorecordwav"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk
+ android:minSdkVersion="8"
+ android:targetSdkVersion="21" />
+
+ <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+ <uses-permission android:name="android.permission.RECORD_AUDIO" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.BROADCAST_STICKY" />
+ <uses-permission android:name="android.permission.BLUETOOTH" />
+ <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
+
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme"
+ android:configChanges="keyboard|orientation|keyboardHidden|screenSize">
+ <activity
+ android:name=".MainActivity"
+ android:label="@string/app_name" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/addon/AudioRecordWav/AudioRecordWav/res/drawable-hdpi/ic_launcher.png b/addon/AudioRecordWav/AudioRecordWav/res/drawable-hdpi/ic_launcher.png
new file mode 100755
index 0000000..288b665
--- /dev/null
+++ b/addon/AudioRecordWav/AudioRecordWav/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/addon/AudioRecordWav/AudioRecordWav/res/drawable-hdpi/ic_voice_search.png b/addon/AudioRecordWav/AudioRecordWav/res/drawable-hdpi/ic_voice_search.png
new file mode 100755
index 0000000..66d14ae
--- /dev/null
+++ b/addon/AudioRecordWav/AudioRecordWav/res/drawable-hdpi/ic_voice_search.png
Binary files differ
diff --git a/addon/AudioRecordWav/AudioRecordWav/res/drawable-hdpi/ic_voice_search_api_holo_light.png b/addon/AudioRecordWav/AudioRecordWav/res/drawable-hdpi/ic_voice_search_api_holo_light.png
new file mode 100755
index 0000000..d2b2d21
--- /dev/null
+++ b/addon/AudioRecordWav/AudioRecordWav/res/drawable-hdpi/ic_voice_search_api_holo_light.png
Binary files differ
diff --git a/addon/AudioRecordWav/AudioRecordWav/res/drawable-mdpi/ic_launcher.png b/addon/AudioRecordWav/AudioRecordWav/res/drawable-mdpi/ic_launcher.png
new file mode 100755
index 0000000..6ae570b
--- /dev/null
+++ b/addon/AudioRecordWav/AudioRecordWav/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/addon/AudioRecordWav/AudioRecordWav/res/drawable-xhdpi/ic_launcher.png b/addon/AudioRecordWav/AudioRecordWav/res/drawable-xhdpi/ic_launcher.png
new file mode 100755
index 0000000..d4fb7cd
--- /dev/null
+++ b/addon/AudioRecordWav/AudioRecordWav/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/addon/AudioRecordWav/AudioRecordWav/res/drawable-xxhdpi/ic_launcher.png b/addon/AudioRecordWav/AudioRecordWav/res/drawable-xxhdpi/ic_launcher.png
new file mode 100755
index 0000000..85a6081
--- /dev/null
+++ b/addon/AudioRecordWav/AudioRecordWav/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/addon/AudioRecordWav/AudioRecordWav/res/layout/activity_main.xml b/addon/AudioRecordWav/AudioRecordWav/res/layout/activity_main.xml
new file mode 100755
index 0000000..4245fe8
--- /dev/null
+++ b/addon/AudioRecordWav/AudioRecordWav/res/layout/activity_main.xml
@@ -0,0 +1,42 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context="${relativePackage}.${activityClass}" >
+
+ <ProgressBar
+ android:id="@+id/progressBar1"
+ style="?android:attr/progressBarStyleLarge"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/start"
+ android:layout_centerHorizontal="true"
+ android:layout_marginTop="19dp" />
+
+ <TextView
+ android:id="@+id/textView1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerHorizontal="true"
+ android:layout_centerVertical="true"
+ android:text="@string/text_default_text"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+
+ <Button
+ android:id="@+id/start"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/textView1"
+ android:layout_centerHorizontal="true"
+ android:layout_marginTop="17dp"
+ android:text="@string/button_default_text" />
+
+ <ImageView
+ android:id="@+id/imageView1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_above="@+id/textView1"
+ android:layout_centerHorizontal="true"
+ android:src="@drawable/ic_voice_search" />
+
+</RelativeLayout> \ No newline at end of file
diff --git a/addon/AudioRecordWav/AudioRecordWav/res/values/strings.xml b/addon/AudioRecordWav/AudioRecordWav/res/values/strings.xml
new file mode 100755
index 0000000..d10bce0
--- /dev/null
+++ b/addon/AudioRecordWav/AudioRecordWav/res/values/strings.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <string name="app_name">AudioRecordWav</string>
+ <string name="hello_world">Hello world!</string>
+ <string name="button_default_text">REPLAY</string>
+ <string name="text_default_text">Press And Hold</string>
+
+</resources>
diff --git a/addon/AudioRecordWav/AudioRecordWav/res/values/styles.xml b/addon/AudioRecordWav/AudioRecordWav/res/values/styles.xml
new file mode 100755
index 0000000..3fe313c
--- /dev/null
+++ b/addon/AudioRecordWav/AudioRecordWav/res/values/styles.xml
@@ -0,0 +1,6 @@
+<resources>
+ <!-- Application theme. -->
+ <style name="AppTheme" parent="android:Theme.Light">
+ <!-- All customizations that are NOT specific to a particular API-level can go here. -->
+ </style>
+</resources>
diff --git a/addon/AudioRecordWav/AudioRecordWav/src/com/example/audiorecordwav/MainActivity.java b/addon/AudioRecordWav/AudioRecordWav/src/com/example/audiorecordwav/MainActivity.java
new file mode 100755
index 0000000..d923420
--- /dev/null
+++ b/addon/AudioRecordWav/AudioRecordWav/src/com/example/audiorecordwav/MainActivity.java
@@ -0,0 +1,576 @@
+package com.example.audiorecordwav;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import android.app.Activity;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.graphics.PixelFormat;
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.AudioRecord;
+import android.media.AudioTrack;
+import android.media.MediaPlayer;
+import android.media.MediaPlayer.OnCompletionListener;
+import android.media.MediaRecorder;
+import android.net.LocalServerSocket;
+import android.net.LocalSocket;
+import android.net.LocalSocketAddress;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+
+public class MainActivity extends Activity {
+
+ private static String TAG = "AudioRecordWav";
+ private int audioSource = MediaRecorder.AudioSource.CAMCORDER;
+ private static int sampleRateInHz = 16000;
+ private static int channelConfig = AudioFormat.CHANNEL_IN_MONO;
+ private static int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
+ private int bufferSizeInBytesAudioRecord = 0;
+ private Button mReplayBtn;
+ private Button Stop;
+ private AudioRecord audioRecord;
+ private boolean isRecord = false;
+ private static final String AudioName = "/sdcard/orig.raw";
+ private static final String NewAudioName = "/sdcard/new.wav";
+
+ private boolean keyLongPressFlag = false;
+
+ private static final boolean GOOGLEVOICE = false;
+ private static boolean VoiceKeyDown = false;
+
+
+ InputStream fis;
+ OutputStream fos;
+
+ private MediaPlayer mPlayer = null;
+ private ProgressBar mProgressBar = null;
+ private ImageView mVoiceImg = null;
+ private TextView mHintText = null;
+ private ProgressDialog recordProgressDialog = null;
+ private PlayingThread workThread;
+
+ private static final String BUTTON_TEXT_RECORDING = "RECORDING NOW";
+ private static final String BUTTON_TEXT_REPLAY = "REPLAY";
+ private static final String BUTTON_TEXT_REPLAYING = "REPLAYING NOW";
+
+ private static final int MSG_RECORD_STARTED = 1;
+ private static final int MSG_RECORD_STOPPED = 2;
+ private static final int MSG_RECORD_TIMEOUT = 3;
+ private static final int MSG_PLAY_STARTED = 4;
+ private static final int MSG_PLAY_STOPPED = 5;
+
+ private Handler mHandler = new Handler() {
+
+ @Override
+ public void handleMessage(Message msg) {
+ // TODO Auto-generated method stub
+ switch (msg.what) {
+ case MSG_RECORD_STARTED:
+ Log.d(TAG, "thread " + Thread.currentThread().getId() + " : OK, just mReplayBtn your work");
+ if(mReplayBtn != null) {
+ mReplayBtn.setText(BUTTON_TEXT_RECORDING);
+ mReplayBtn.setEnabled(false);
+ }
+
+ if(mProgressBar != null)
+ mProgressBar.setVisibility(View.VISIBLE);
+ break;
+
+ case MSG_RECORD_STOPPED:
+ Log.d(TAG, "stop msg");
+
+ if(mProgressBar != null)
+ mProgressBar.setVisibility(View.INVISIBLE);
+
+ if(mReplayBtn != null) {
+ mReplayBtn.setEnabled(true);
+ mReplayBtn.setText(BUTTON_TEXT_REPLAY);
+ }
+
+ stopRecord();
+ break;
+ case MSG_RECORD_TIMEOUT:
+ Log.d(TAG, "time to stop recording");
+ isRecord = false;
+ break;
+ case MSG_PLAY_STARTED:
+ Log.d(TAG, "thread " + Thread.currentThread().getId() + " : OK, just mReplayBtn your work");
+ if(mReplayBtn != null) {
+ mReplayBtn.setEnabled(false);
+ mReplayBtn.setText(BUTTON_TEXT_REPLAYING);
+ }
+ break;
+
+ case MSG_PLAY_STOPPED:
+ if(mReplayBtn != null) {
+ mReplayBtn.setText(BUTTON_TEXT_REPLAY);
+ mReplayBtn.setEnabled(true);
+ }
+ break;
+
+ default:
+ Log.d(TAG, "Unknown Message !!!");
+ }
+ super.handleMessage(msg);
+ }
+
+ };
+
+ private class LocalMPOnCompletionListener implements OnCompletionListener {
+
+ @Override
+ public void onCompletion(MediaPlayer mp) {
+ // TODO Auto-generated method stub
+ Log.d(TAG, "release the MediaPlayer!!!");
+ mp.release();
+ //mReplayBtn.setEnabled(true);
+ if(mHandler != null) {
+ Message msg = mHandler.obtainMessage(MSG_PLAY_STOPPED);
+ mHandler.sendMessage(msg);
+ }
+ }
+
+ }
+
+ private class PlayingThread extends Thread {
+
+ @Override
+ public void run() {
+ // TODO Auto-generated method stub
+ super.run();
+
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ mPlayer = new MediaPlayer();
+ if(mPlayer != null) {
+
+ Message msg = mHandler.obtainMessage(MSG_PLAY_STARTED);
+ mHandler.sendMessage(msg);
+
+ try {
+ mPlayer.setOnCompletionListener( new LocalMPOnCompletionListener() );
+ mPlayer.setDataSource(NewAudioName);
+ Log.d(TAG, "filename: "+ NewAudioName);
+ mPlayer.prepare();
+ mPlayer.start();
+ } catch (IOException e) {
+ Log.e(TAG, "prepare() failed");
+ }
+ }else
+ Log.d(TAG, "MediaPlayer is null!");
+
+
+ }
+
+ }
+
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ // TODO Auto-generated method stub
+ switch(keyCode)
+ {
+ case KeyEvent.KEYCODE_F5:
+ //Log.d(TAG, "key press F5" + event.getRepeatCount());
+ if (event.getRepeatCount() == 0)
+ {
+ Log.d(TAG, "Thread num: " + Thread.currentThread().getId());
+ //Log.d(TAG, "mReplayBtn Tracking");
+
+ //recordProgressDialog.show();
+
+ startRecord();
+
+ } else {
+ VoiceKeyDown = true;
+ }
+ break;
+ default:
+ Log.d(TAG, "key short press" + event.getRepeatCount());
+ break;
+ }
+ return super.onKeyDown(keyCode, event);
+ }
+/*
+ @Override
+ public boolean onKeyLongPress(int keyCode, KeyEvent event) {
+ // TODO Auto-generated method stub
+ switch(keyCode)
+ {
+ case KeyEvent.KEYCODE_F5:
+ Log.d(TAG, "key long press F5, mReplayBtn recording");
+ mReplayBtnRecord();
+ keyLongPressFlag = true;
+ return true;
+ default:
+ Log.d(TAG, "key long press");
+ break;
+ }
+ return super.onKeyLongPress(keyCode, event);
+ }
+*/
+ @Override
+ public boolean onKeyUp(int keyCode, KeyEvent event) {
+ // TODO Auto-generated method stub
+ switch(keyCode)
+ {
+ case KeyEvent.KEYCODE_F5:
+ Log.d(TAG, "key release F5");
+ if (!keyLongPressFlag)
+ {
+// if(mProgressBar != null)
+// mProgressBar.setVisibility(View.INVISIBLE);
+//
+// Log.d(TAG, "Thread num: " + Thread.currentThread());
+// if(mReplayBtn != null) {
+// mReplayBtn.setEnabled(true);
+// mReplayBtn.setText(BUTTON_TEXT_REPLAY);
+// }
+
+// stopRecord();
+ isRecord = false;
+ keyLongPressFlag = false;
+ }
+
+ break;
+ default:
+ Log.d(TAG, "key release");
+ break;
+ }
+
+ return super.onKeyUp(keyCode, event);
+ }
+
+
+
+ public void onCreate(Bundle savedInstanceState) {
+
+ getWindow().setFormat(PixelFormat.TRANSLUCENT);
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
+ setContentView(R.layout.activity_main);
+ init();
+ Log.d(TAG, "Thread num: " + Thread.currentThread());
+ mVoiceImg = (ImageView)findViewById(R.id.imageView1);
+ if(mVoiceImg!=null) {
+ double mWidth = mVoiceImg.getScaleX();
+ double mHeight = mVoiceImg.getScaleY();
+ }
+
+ mHintText = (TextView)findViewById(R.id.textView1);
+ if(mHintText != null)
+ mHintText.setText("Press And Hold");
+ super.onCreate(savedInstanceState);
+ }
+
+ private void init() {
+ mReplayBtn = (Button) this.findViewById(R.id.start);
+ mReplayBtn.setOnClickListener(new TestAudioListener());
+ mProgressBar = (ProgressBar)this.findViewById(R.id.progressBar1);
+ mProgressBar.setVisibility(View.INVISIBLE);
+ /*
+ recordProgressDialog = new ProgressDialog(MainActivity.this);
+ recordProgressDialog.setTitle("AudioRecordWav");
+ recordProgressDialog.setMessage("Recording Now ...");
+ recordProgressDialog.setCancelable(true);
+ */
+
+ //creatAudioRecord();
+ }
+
+ private void creatAudioRecord() {
+ bufferSizeInBytesAudioRecord = AudioRecord.getMinBufferSize(sampleRateInHz,
+ channelConfig, audioFormat);
+ Log.e(TAG, "AudioRecord getMinBufferSize"+bufferSizeInBytesAudioRecord);
+ audioRecord = new AudioRecord(audioSource, sampleRateInHz,
+ channelConfig, audioFormat, bufferSizeInBytesAudioRecord * 10);
+
+ if (audioRecord == null)
+ Log.d(TAG, "can't open audioRecord");
+
+ }
+
+ class TestAudioListener implements OnClickListener {
+
+ @Override
+ public void onClick(View v) {
+ Log.d(TAG, "mReplayBtn playing!!!");
+ if (v == mReplayBtn) {
+ if(mHandler != null) {
+ Message msg = mHandler.obtainMessage(MSG_PLAY_STARTED);
+ mHandler.sendMessage(msg);
+ }
+ mPlayer = new MediaPlayer();
+ try {
+ mPlayer.setOnCompletionListener( new LocalMPOnCompletionListener() );
+ mPlayer.setDataSource(NewAudioName);
+ Log.d(TAG, "filename: "+ NewAudioName);
+ mPlayer.prepare();
+ mPlayer.start();
+ } catch (IOException e) {
+ Log.e(TAG, "prepare() failed");
+ }
+ }
+ if (v == Stop) {
+ mPlayer.release();
+ mPlayer = null;
+ }
+
+ }
+
+
+ }
+
+ private void startRecord() {
+ while(audioRecord == null)
+ creatAudioRecord();
+ //new Thread(new AudioRecordThread()).mReplayBtn();
+ if(mHandler != null) {
+ Message msg = mHandler.obtainMessage(MSG_RECORD_STARTED);
+ mHandler.sendMessage(msg);
+ }
+ audioRecord.startRecording();
+ isRecord = true;
+
+ new Thread(new AudioRecordThread()).start();
+
+ }
+
+ private void stopRecord() {
+ if (audioRecord != null) {
+ Log.d(TAG, "Stop record");
+ audioRecord.stop();
+ audioRecord.release();
+ audioRecord = null;
+ }
+
+ //mHandler.sendMessage(mHandler.obtainMessage(MSG_STOP_RECORD));
+
+ /*
+ try {
+ Thread.sleep(3000);
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ */
+ workThread = new PlayingThread();
+ workThread.start();
+
+ //if(mPlayer == null) {
+
+// mPlayer = new MediaPlayer();
+// try {
+// mPlayer.setOnCompletionListener(new OnCompletionListener() {
+//
+// @Override
+// public void onCompletion(MediaPlayer mp) {
+// // TODO Auto-generated method stub
+// Log.d(TAG, "release the MediaPlayer!!!");
+// mp.release();
+// mReplayBtn.setEnabled(true);
+// }
+// });
+// mPlayer.setDataSource(NewAudioName);
+// Log.d(TAG, "filename: "+ NewAudioName);
+// mPlayer.prepare();
+// mPlayer.mReplayBtn();
+// } catch (IOException e) {
+// Log.e(TAG, "prepare() failed");
+// }
+
+ //}
+ }
+
+ private void close() {
+ if (audioRecord != null) {
+ System.out.println("stopRecord");
+ isRecord = false;
+ audioRecord.stop();
+ audioRecord.release();
+ audioRecord = null;
+ }
+
+ }
+
+ private class TimerThread implements Runnable {
+
+ @Override
+ public void run() {
+ // TODO Auto-generated method stub
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ Log.d(TAG, "recording timeout, stop it!");
+ Message msg = mHandler.obtainMessage(MSG_RECORD_TIMEOUT);
+ mHandler.sendMessage(msg);
+ }
+
+ }
+
+ class AudioRecordThread implements Runnable {
+ @Override
+ public void run() {
+ Log.d(TAG, "Thread enter");
+ writeDateTOFile();
+ copyWaveFile(AudioName, NewAudioName);
+ Message msg = mHandler.obtainMessage(MSG_RECORD_STOPPED);
+ mHandler.sendMessage(msg);
+ Log.d(TAG, "recording stopped!!!");
+ }
+ }
+
+ private void writeDateTOFile() {
+ byte[] audiodata = new byte[bufferSizeInBytesAudioRecord * 2];
+ FileOutputStream fos = null;
+ int readsize = 0;
+ long totalSize = 0;
+ try {
+ File file = new File(AudioName);
+ if (file.exists()) {
+ file.delete();
+ }
+ fos = new FileOutputStream(file);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ while (isRecord == true) {
+
+ //readsize = audioRecord.read(audiodata, 0, bufferSizeInBytesAudioRecord * 2);
+ readsize = audioRecord.read(audiodata, 0, bufferSizeInBytesAudioRecord * 2);
+ totalSize += readsize;
+
+ //Log.d(TAG, "readsize: " + readsize);
+
+ if (AudioRecord.ERROR_INVALID_OPERATION != readsize) {
+ try {
+ fos.write(audiodata);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ }
+
+ Log.d(TAG, "total size: " + totalSize);
+ try {
+ fos.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void copyWaveFile(String inFilename, String outFilename) {
+ FileInputStream in = null;
+ FileOutputStream out = null;
+ long totalAudioLen = 0;
+ long totalDataLen = totalAudioLen + 36;
+ long longSampleRate = sampleRateInHz;
+ int channels = 1;
+ long byteRate = 16 * sampleRateInHz * channels / 8;
+ byte[] data = new byte[bufferSizeInBytesAudioRecord];
+ try {
+ in = new FileInputStream(inFilename);
+ out = new FileOutputStream(outFilename);
+ totalAudioLen = in.getChannel().size();
+ totalDataLen = totalAudioLen + 36;
+ WriteWaveFileHeader(out, totalAudioLen, totalDataLen,
+ longSampleRate, channels, byteRate);
+ while (in.read(data) != -1) {
+ out.write(data);
+ }
+ in.close();
+ out.close();
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ private void WriteWaveFileHeader(FileOutputStream out, long totalAudioLen,
+ long totalDataLen, long longSampleRate, int channels, long byteRate)
+ throws IOException {
+ byte[] header = new byte[44];
+ header[0] = 'R'; // RIFF/WAVE header
+ header[1] = 'I';
+ header[2] = 'F';
+ header[3] = 'F';
+ header[4] = (byte) (totalDataLen & 0xff);
+ header[5] = (byte) ((totalDataLen >> 8) & 0xff);
+ header[6] = (byte) ((totalDataLen >> 16) & 0xff);
+ header[7] = (byte) ((totalDataLen >> 24) & 0xff);
+ header[8] = 'W';
+ header[9] = 'A';
+ header[10] = 'V';
+ header[11] = 'E';
+ header[12] = 'f'; // 'fmt ' chunk
+ header[13] = 'm';
+ header[14] = 't';
+ header[15] = ' ';
+ header[16] = 16; // 4 bytes: size of 'fmt ' chunk
+ header[17] = 0;
+ header[18] = 0;
+ header[19] = 0;
+ header[20] = 1; // format = 1
+ header[21] = 0;
+ header[22] = (byte) channels;
+ header[23] = 0;
+ header[24] = (byte) (longSampleRate & 0xff);
+ header[25] = (byte) ((longSampleRate >> 8) & 0xff);
+ header[26] = (byte) ((longSampleRate >> 16) & 0xff);
+ header[27] = (byte) ((longSampleRate >> 24) & 0xff);
+ header[28] = (byte) (byteRate & 0xff);
+ header[29] = (byte) ((byteRate >> 8) & 0xff);
+ header[30] = (byte) ((byteRate >> 16) & 0xff);
+ header[31] = (byte) ((byteRate >> 24) & 0xff);
+ header[32] = (byte) (2 * 16 / 8); // block align
+ header[33] = 0;
+ header[34] = 16; // bits per sample
+ header[35] = 0;
+ header[36] = 'd';
+ header[37] = 'a';
+ header[38] = 't';
+ header[39] = 'a';
+ header[40] = (byte) (totalAudioLen & 0xff);
+ header[41] = (byte) ((totalAudioLen >> 8) & 0xff);
+ header[42] = (byte) ((totalAudioLen >> 16) & 0xff);
+ header[43] = (byte) ((totalAudioLen >> 24) & 0xff);
+ out.write(header, 0, 44);
+ }
+
+ @Override
+ protected void onDestroy() {
+ close();
+ super.onDestroy();
+ }
+}
diff --git a/addon/AudioRecordWav/addon.mk b/addon/AudioRecordWav/addon.mk
new file mode 100755
index 0000000..4b7672e
--- /dev/null
+++ b/addon/AudioRecordWav/addon.mk
@@ -0,0 +1,3 @@
+PRODUCT_PACKAGES += \
+ rtkbtAudioRecordWav
+
diff --git a/addon/BluetoothRTK3ddService/Android.mk b/addon/BluetoothRTK3ddService/Android.mk
new file mode 100755
index 0000000..bd30b5b
--- /dev/null
+++ b/addon/BluetoothRTK3ddService/Android.mk
@@ -0,0 +1,4 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-subdir-makefiles)
+
diff --git a/addon/BluetoothRTK3ddService/BluetoothRTK3ddService/Android.mk b/addon/BluetoothRTK3ddService/BluetoothRTK3ddService/Android.mk
new file mode 100755
index 0000000..4631834
--- /dev/null
+++ b/addon/BluetoothRTK3ddService/BluetoothRTK3ddService/Android.mk
@@ -0,0 +1,11 @@
+app := BluetoothRTK3ddService
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+LOCAL_MODULE := ${app}
+LOCAL_MODULE_SUFFIX := .apk
+LOCAL_MODULE_CLASS := APPS
+LOCAL_MODULE_TAGS := optional
+LOCAL_CERTIFICATE := platform
+LOCAL_SRC_FILES := ${app}.apk
+include $(BUILD_PREBUILT)
+
diff --git a/addon/BluetoothRTK3ddService/BluetoothRTK3ddService/BluetoothRTK3ddService.apk b/addon/BluetoothRTK3ddService/BluetoothRTK3ddService/BluetoothRTK3ddService.apk
new file mode 100755
index 0000000..f536a06
--- /dev/null
+++ b/addon/BluetoothRTK3ddService/BluetoothRTK3ddService/BluetoothRTK3ddService.apk
Binary files differ
diff --git a/addon/BluetoothRTK3ddService/addon.mk b/addon/BluetoothRTK3ddService/addon.mk
new file mode 100755
index 0000000..68fa302
--- /dev/null
+++ b/addon/BluetoothRTK3ddService/addon.mk
@@ -0,0 +1,3 @@
+PRODUCT_PACKAGES += \
+ BluetoothRTK3ddService
+
diff --git a/addon/basic/Android.mk b/addon/basic/Android.mk
new file mode 100755
index 0000000..bd30b5b
--- /dev/null
+++ b/addon/basic/Android.mk
@@ -0,0 +1,4 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-subdir-makefiles)
+
diff --git a/addon/basic/addon.mk b/addon/basic/addon.mk
new file mode 100755
index 0000000..75c5eb6
--- /dev/null
+++ b/addon/basic/addon.mk
@@ -0,0 +1,2 @@
+PRODUCT_COPY_FILES += \
+ $(LOCAL_PATH)/system/etc/bluetooth/rtkbt_plugins.conf:system/etc/bluetooth/rtkbt_plugins.conf
diff --git a/addon/basic/system/etc/bluetooth/rtkbt_plugins.conf b/addon/basic/system/etc/bluetooth/rtkbt_plugins.conf
new file mode 100755
index 0000000..d616f59
--- /dev/null
+++ b/addon/basic/system/etc/bluetooth/rtkbt_plugins.conf
@@ -0,0 +1 @@
+heartbeat
diff --git a/addon/bee/Android.mk b/addon/bee/Android.mk
new file mode 100755
index 0000000..bd30b5b
--- /dev/null
+++ b/addon/bee/Android.mk
@@ -0,0 +1,4 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-subdir-makefiles)
+
diff --git a/addon/bee/addon.mk b/addon/bee/addon.mk
new file mode 100755
index 0000000..a420ccb
--- /dev/null
+++ b/addon/bee/addon.mk
@@ -0,0 +1,6 @@
+PRODUCT_COPY_FILES += \
+ $(LOCAL_PATH)/system/etc/bluetooth/rtkbt_plugins.conf:system/etc/bluetooth/rtkbt_plugins.conf \
+ $(LOCAL_PATH)/system/etc/bluetooth/rtkbt_autopair_config.xml:system/etc/bluetooth/rtkbt_autopair_config.xml \
+ $(LOCAL_PATH)/system/etc/bluetooth/rtkbt_plugin_autopair_stack.conf:system/etc/bluetooth/rtkbt_plugin_autopair_stack.conf \
+ $(LOCAL_PATH)/system/usr/keylayout/rtkbt_vhid_Vid_005d_Pid_0001.kl:system/usr/keylayout/rtkbt_vhid_Vid_005d_Pid_0001.kl \
+
diff --git a/addon/bee/system/etc/bluetooth/rtkbt_autopair_config.xml b/addon/bee/system/etc/bluetooth/rtkbt_autopair_config.xml
new file mode 100755
index 0000000..4229602
--- /dev/null
+++ b/addon/bee/system/etc/bluetooth/rtkbt_autopair_config.xml
@@ -0,0 +1,30 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<root>
+ <Autopair_type total_num = "4">
+ <type>136</type>
+ </Autopair_type>
+ <Autopair_rssi>
+ <rssi>60</rssi>
+ </Autopair_rssi>
+ <Address_pair address_num = "1">
+ <address_1>5C:31:3E</address_1>
+ </Address_pair>
+ <Name_pair name_num = "1">
+ <name_1>LETV</name_1>
+ </Name_pair>
+ <Key_pair key_num = "2">
+ <key_1>1</key_1>
+ <key_2>2</key_2>
+ <key_3>3</key_3>
+ <key_4>4</key_4>
+ </Key_pair>
+ <ManufactSpeciData data_length = "4">
+ <specidata_value>5D:00:04:00</specidata_value>
+ <mask_value>FF:FF:FF:FF</mask_value>
+ </ManufactSpeciData>
+ <Autopair_vendor_event vendor_type = "8">
+ </Autopair_vendor_event>
+ <Autopair_service_timeout>
+ <timeout>600000</timeout>
+ </Autopair_service_timeout>
+</root>
diff --git a/addon/bee/system/etc/bluetooth/rtkbt_plugin_autopair_stack.conf b/addon/bee/system/etc/bluetooth/rtkbt_plugin_autopair_stack.conf
new file mode 100755
index 0000000..cf98e40
--- /dev/null
+++ b/addon/bee/system/etc/bluetooth/rtkbt_plugin_autopair_stack.conf
@@ -0,0 +1,12 @@
+{2}
+[Autopair_type]
+Type=08
+#[Address_pair]
+#Address=
+#Address_mask=
+#[Name_pair]
+#Name=
+#Name_mask=
+[Manufact_pair]
+Manufact_data=5D000400
+Manufact_mask=FFFFFFFF
diff --git a/addon/bee/system/etc/bluetooth/rtkbt_plugins.conf b/addon/bee/system/etc/bluetooth/rtkbt_plugins.conf
new file mode 100755
index 0000000..0c36003
--- /dev/null
+++ b/addon/bee/system/etc/bluetooth/rtkbt_plugins.conf
@@ -0,0 +1,2 @@
+autopair
+heartbeat
diff --git a/addon/bee/system/usr/keylayout/rtkbt_vhid_Vid_005d_Pid_0001.kl b/addon/bee/system/usr/keylayout/rtkbt_vhid_Vid_005d_Pid_0001.kl
new file mode 100755
index 0000000..c76e12f
--- /dev/null
+++ b/addon/bee/system/usr/keylayout/rtkbt_vhid_Vid_005d_Pid_0001.kl
@@ -0,0 +1,34 @@
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Generic key layout file for full alphabetic US English PC style external keyboards.
+#
+# This file is intentionally very generic and is intended to support a broad rang of keyboards.
+# Do not edit the generic key layout to support a specific keyboard; instead, create
+# a new key layout file with the required keyboard configuration.
+#
+
+key 1 ESCAPE
+key 28 ENTER
+key 63 F5
+key 102 HOME
+key 103 DPAD_UP
+key 105 DPAD_LEFT
+key 106 DPAD_RIGHT
+key 108 DPAD_DOWN
+key 114 VOLUME_DOWN
+key 115 VOLUME_UP
+key 116 POWER
+key 130 MENU
diff --git a/addon/bee1/Android.mk b/addon/bee1/Android.mk
new file mode 100755
index 0000000..bd30b5b
--- /dev/null
+++ b/addon/bee1/Android.mk
@@ -0,0 +1,4 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-subdir-makefiles)
+
diff --git a/addon/bee1/addon.mk b/addon/bee1/addon.mk
new file mode 100755
index 0000000..91e0b0a
--- /dev/null
+++ b/addon/bee1/addon.mk
@@ -0,0 +1,7 @@
+PRODUCT_COPY_FILES += \
+ $(LOCAL_PATH)/system/etc/bluetooth/rtkbt_plugins.conf:system/etc/bluetooth/rtkbt_plugins.conf \
+ $(LOCAL_PATH)/system/etc/bluetooth/rtkbt_autopair_config.xml:system/etc/bluetooth/rtkbt_autopair_config.xml \
+ $(LOCAL_PATH)/system/etc/bluetooth/rtkbt_plugin_autopair_stack.conf:system/etc/bluetooth/rtkbt_plugin_autopair_stack.conf \
+ $(LOCAL_PATH)/system/usr/keylayout/Vendor_005d_Product_0001.kl:system/usr/keylayout/Vendor_005d_Product_0001.kl \
+ $(LOCAL_PATH)/system/etc/bluetooth/rtkbt_plugin_vr_bee1_hidraw.conf:system/etc/bluetooth/rtkbt_plugin_vr_bee1_hidraw.conf \
+
diff --git a/addon/bee1/system/etc/bluetooth/rtkbt_autopair_config.xml b/addon/bee1/system/etc/bluetooth/rtkbt_autopair_config.xml
new file mode 100755
index 0000000..4229602
--- /dev/null
+++ b/addon/bee1/system/etc/bluetooth/rtkbt_autopair_config.xml
@@ -0,0 +1,30 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<root>
+ <Autopair_type total_num = "4">
+ <type>136</type>
+ </Autopair_type>
+ <Autopair_rssi>
+ <rssi>60</rssi>
+ </Autopair_rssi>
+ <Address_pair address_num = "1">
+ <address_1>5C:31:3E</address_1>
+ </Address_pair>
+ <Name_pair name_num = "1">
+ <name_1>LETV</name_1>
+ </Name_pair>
+ <Key_pair key_num = "2">
+ <key_1>1</key_1>
+ <key_2>2</key_2>
+ <key_3>3</key_3>
+ <key_4>4</key_4>
+ </Key_pair>
+ <ManufactSpeciData data_length = "4">
+ <specidata_value>5D:00:04:00</specidata_value>
+ <mask_value>FF:FF:FF:FF</mask_value>
+ </ManufactSpeciData>
+ <Autopair_vendor_event vendor_type = "8">
+ </Autopair_vendor_event>
+ <Autopair_service_timeout>
+ <timeout>600000</timeout>
+ </Autopair_service_timeout>
+</root>
diff --git a/addon/bee1/system/etc/bluetooth/rtkbt_plugin_autopair_stack.conf b/addon/bee1/system/etc/bluetooth/rtkbt_plugin_autopair_stack.conf
new file mode 100755
index 0000000..cf98e40
--- /dev/null
+++ b/addon/bee1/system/etc/bluetooth/rtkbt_plugin_autopair_stack.conf
@@ -0,0 +1,12 @@
+{2}
+[Autopair_type]
+Type=08
+#[Address_pair]
+#Address=
+#Address_mask=
+#[Name_pair]
+#Name=
+#Name_mask=
+[Manufact_pair]
+Manufact_data=5D000400
+Manufact_mask=FFFFFFFF
diff --git a/addon/bee1/system/etc/bluetooth/rtkbt_plugin_vr_bee1_hidraw.conf b/addon/bee1/system/etc/bluetooth/rtkbt_plugin_vr_bee1_hidraw.conf
new file mode 100755
index 0000000..d154efd
--- /dev/null
+++ b/addon/bee1/system/etc/bluetooth/rtkbt_plugin_vr_bee1_hidraw.conf
@@ -0,0 +1,5 @@
+{3}
+[Rcu]
+Vid=005d
+Pid=0001
+#Ver=0000
diff --git a/addon/bee1/system/etc/bluetooth/rtkbt_plugins.conf b/addon/bee1/system/etc/bluetooth/rtkbt_plugins.conf
new file mode 100755
index 0000000..3a7c720
--- /dev/null
+++ b/addon/bee1/system/etc/bluetooth/rtkbt_plugins.conf
@@ -0,0 +1,3 @@
+heartbeat
+autopair
+vr_bee1_hidraw
diff --git a/addon/bee1/system/usr/keylayout/Vendor_005d_Product_0001.kl b/addon/bee1/system/usr/keylayout/Vendor_005d_Product_0001.kl
new file mode 100755
index 0000000..0b86eb2
--- /dev/null
+++ b/addon/bee1/system/usr/keylayout/Vendor_005d_Product_0001.kl
@@ -0,0 +1,49 @@
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Generic key layout file for full alphabetic US English PC style external keyboards.
+#
+# This file is intentionally very generic and is intended to support a broad rang of keyboards.
+# Do not edit the generic key layout to support a specific keyboard; instead, create
+# a new key layout file with the required keyboard configuration.
+#
+key 1 ESCAPE
+key 2 1
+key 3 2
+key 4 3
+key 5 4
+key 6 5
+key 7 6
+key 8 7
+key 9 8
+key 10 9
+key 11 0
+key 28 DPAD_CENTER
+key 59 HOME
+key 61 MEDIA_REPEAT
+key 62 INFO
+key 63 SEARCH
+key 103 DPAD_UP
+key 104 MEDIA_PREVIOUS
+key 105 DPAD_LEFT
+key 106 DPAD_RIGHT
+key 108 DPAD_DOWN
+key 109 MEDIA_NEXT
+key 113 VOLUME_MUTE
+key 114 VOLUME_DOWN
+key 115 VOLUME_UP
+key 116 POWER
+key 130 MENU
+#key 240 ESCAPE
diff --git a/addon/bee1/system/usr/keylayout/rtkbt_vhid_Vid_005d_Pid_0001.kl b/addon/bee1/system/usr/keylayout/rtkbt_vhid_Vid_005d_Pid_0001.kl
new file mode 100755
index 0000000..c76e12f
--- /dev/null
+++ b/addon/bee1/system/usr/keylayout/rtkbt_vhid_Vid_005d_Pid_0001.kl
@@ -0,0 +1,34 @@
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Generic key layout file for full alphabetic US English PC style external keyboards.
+#
+# This file is intentionally very generic and is intended to support a broad rang of keyboards.
+# Do not edit the generic key layout to support a specific keyboard; instead, create
+# a new key layout file with the required keyboard configuration.
+#
+
+key 1 ESCAPE
+key 28 ENTER
+key 63 F5
+key 102 HOME
+key 103 DPAD_UP
+key 105 DPAD_LEFT
+key 106 DPAD_RIGHT
+key 108 DPAD_DOWN
+key 114 VOLUME_DOWN
+key 115 VOLUME_UP
+key 116 POWER
+key 130 MENU
diff --git a/addon/bee2/Android.mk b/addon/bee2/Android.mk
new file mode 100755
index 0000000..bd30b5b
--- /dev/null
+++ b/addon/bee2/Android.mk
@@ -0,0 +1,4 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-subdir-makefiles)
+
diff --git a/addon/bee2/addon.mk b/addon/bee2/addon.mk
new file mode 100755
index 0000000..dfac7d3
--- /dev/null
+++ b/addon/bee2/addon.mk
@@ -0,0 +1,6 @@
+PRODUCT_COPY_FILES += \
+ $(LOCAL_PATH)/system/etc/bluetooth/rtkbt_plugins.conf:system/etc/bluetooth/rtkbt_plugins.conf \
+ $(LOCAL_PATH)/system/etc/bluetooth/rtkbt_autopair_config.xml:system/etc/bluetooth/rtkbt_autopair_config.xml \
+ $(LOCAL_PATH)/system/etc/bluetooth/rtkbt_plugin_autopair_stack.conf:system/etc/bluetooth/rtkbt_plugin_autopair_stack.conf \
+ $(LOCAL_PATH)/system/etc/bluetooth/rtkbt_plugin_vr_bee2_hidraw.conf:system/etc/bluetooth/rtkbt_plugin_vr_bee2_hidraw.conf \
+
diff --git a/addon/bee2/system/etc/bluetooth/rtkbt_autopair_config.xml b/addon/bee2/system/etc/bluetooth/rtkbt_autopair_config.xml
new file mode 100755
index 0000000..4229602
--- /dev/null
+++ b/addon/bee2/system/etc/bluetooth/rtkbt_autopair_config.xml
@@ -0,0 +1,30 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<root>
+ <Autopair_type total_num = "4">
+ <type>136</type>
+ </Autopair_type>
+ <Autopair_rssi>
+ <rssi>60</rssi>
+ </Autopair_rssi>
+ <Address_pair address_num = "1">
+ <address_1>5C:31:3E</address_1>
+ </Address_pair>
+ <Name_pair name_num = "1">
+ <name_1>LETV</name_1>
+ </Name_pair>
+ <Key_pair key_num = "2">
+ <key_1>1</key_1>
+ <key_2>2</key_2>
+ <key_3>3</key_3>
+ <key_4>4</key_4>
+ </Key_pair>
+ <ManufactSpeciData data_length = "4">
+ <specidata_value>5D:00:04:00</specidata_value>
+ <mask_value>FF:FF:FF:FF</mask_value>
+ </ManufactSpeciData>
+ <Autopair_vendor_event vendor_type = "8">
+ </Autopair_vendor_event>
+ <Autopair_service_timeout>
+ <timeout>600000</timeout>
+ </Autopair_service_timeout>
+</root>
diff --git a/addon/bee2/system/etc/bluetooth/rtkbt_plugin_autopair_stack.conf b/addon/bee2/system/etc/bluetooth/rtkbt_plugin_autopair_stack.conf
new file mode 100755
index 0000000..cf98e40
--- /dev/null
+++ b/addon/bee2/system/etc/bluetooth/rtkbt_plugin_autopair_stack.conf
@@ -0,0 +1,12 @@
+{2}
+[Autopair_type]
+Type=08
+#[Address_pair]
+#Address=
+#Address_mask=
+#[Name_pair]
+#Name=
+#Name_mask=
+[Manufact_pair]
+Manufact_data=5D000400
+Manufact_mask=FFFFFFFF
diff --git a/addon/bee2/system/etc/bluetooth/rtkbt_plugin_vr_bee2_hidraw.conf b/addon/bee2/system/etc/bluetooth/rtkbt_plugin_vr_bee2_hidraw.conf
new file mode 100755
index 0000000..3b583b2
--- /dev/null
+++ b/addon/bee2/system/etc/bluetooth/rtkbt_plugin_vr_bee2_hidraw.conf
@@ -0,0 +1,5 @@
+{3}
+[Rcu]
+Vid=005d
+Pid=0002
+#Ver=0000
diff --git a/addon/bee2/system/etc/bluetooth/rtkbt_plugins.conf b/addon/bee2/system/etc/bluetooth/rtkbt_plugins.conf
new file mode 100755
index 0000000..f2c293f
--- /dev/null
+++ b/addon/bee2/system/etc/bluetooth/rtkbt_plugins.conf
@@ -0,0 +1,3 @@
+heartbeat
+autopair
+vr_bee2_hidraw
diff --git a/addon/bee2/system/usr/keylayout/Vendor_005d_Product_0002.kl b/addon/bee2/system/usr/keylayout/Vendor_005d_Product_0002.kl
new file mode 100755
index 0000000..fdf96e2
--- /dev/null
+++ b/addon/bee2/system/usr/keylayout/Vendor_005d_Product_0002.kl
@@ -0,0 +1,34 @@
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Generic key layout file for full alphabetic US English PC style external keyboards.
+#
+# This file is intentionally very generic and is intended to support a broad rang of keyboards.
+# Do not edit the generic key layout to support a specific keyboard; instead, create
+# a new key layout file with the required keyboard configuration.
+#
+
+key 1 ESCAPE
+key 28 ENTER
+key 63 VOICE_ASSIST
+key 102 HOME
+key 103 DPAD_UP
+key 105 DPAD_LEFT
+key 106 DPAD_RIGHT
+key 108 DPAD_DOWN
+key 114 VOLUME_DOWN
+key 115 VOLUME_UP
+key 116 POWER
+key 130 MENU
diff --git a/addon/rtkbtAutoPairService/Android.mk b/addon/rtkbtAutoPairService/Android.mk
new file mode 100755
index 0000000..bd30b5b
--- /dev/null
+++ b/addon/rtkbtAutoPairService/Android.mk
@@ -0,0 +1,4 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-subdir-makefiles)
+
diff --git a/addon/rtkbtAutoPairService/addon.mk b/addon/rtkbtAutoPairService/addon.mk
new file mode 100755
index 0000000..8c75cf9
--- /dev/null
+++ b/addon/rtkbtAutoPairService/addon.mk
@@ -0,0 +1,2 @@
+PRODUCT_PACKAGES += \
+ rtkbtAutoPairService
diff --git a/addon/rtkbtAutoPairService/rtkbtAutoPairService/Android.mk b/addon/rtkbtAutoPairService/rtkbtAutoPairService/Android.mk
new file mode 100755
index 0000000..edc2798
--- /dev/null
+++ b/addon/rtkbtAutoPairService/rtkbtAutoPairService/Android.mk
@@ -0,0 +1,11 @@
+app := rtkbtAutoPairService
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+LOCAL_MODULE := ${app}
+LOCAL_MODULE_SUFFIX := .apk
+LOCAL_MODULE_CLASS := APPS
+LOCAL_MODULE_TAGS := optional
+LOCAL_CERTIFICATE := platform
+LOCAL_SRC_FILES := ${app}.apk
+include $(BUILD_PREBUILT)
+
diff --git a/addon/rtkbtAutoPairService/rtkbtAutoPairService/rtkbtAutoPairService.apk b/addon/rtkbtAutoPairService/rtkbtAutoPairService/rtkbtAutoPairService.apk
new file mode 100755
index 0000000..9f146f3
--- /dev/null
+++ b/addon/rtkbtAutoPairService/rtkbtAutoPairService/rtkbtAutoPairService.apk
Binary files differ
diff --git a/addon/rtkbtAutoPairUIDemo/Android.mk b/addon/rtkbtAutoPairUIDemo/Android.mk
new file mode 100755
index 0000000..aa2f4b5
--- /dev/null
+++ b/addon/rtkbtAutoPairUIDemo/Android.mk
@@ -0,0 +1,2 @@
+LOCAL_PATH := $(call my-dir)
+include $(call all-subdir-makefiles)
diff --git a/addon/rtkbtAutoPairUIDemo/AndroidManifest.xml b/addon/rtkbtAutoPairUIDemo/AndroidManifest.xml
new file mode 100755
index 0000000..293b2ff
--- /dev/null
+++ b/addon/rtkbtAutoPairUIDemo/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.realtek.rtkbt.AutoPairUIDemo"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15" />
+ <uses-permission android:name="android.permission.BLUETOOTH"/>
+ <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
+ <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED"/>
+ <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
+
+ <application android:label="@string/app_name"
+ android:icon="@drawable/ic_launcher"
+ android:theme="@style/AppTheme">
+
+ <receiver android:name="rtkbtAutoPairUIDemoReceiver">
+ <intent-filter>
+ <action android:name="com.realtek.autopair.message" />
+ </intent-filter>
+ </receiver>
+
+ </application>
+
+</manifest>
diff --git a/addon/rtkbtAutoPairUIDemo/addon.mk b/addon/rtkbtAutoPairUIDemo/addon.mk
new file mode 100755
index 0000000..1b59f11
--- /dev/null
+++ b/addon/rtkbtAutoPairUIDemo/addon.mk
@@ -0,0 +1,3 @@
+PRODUCT_PACKAGES += \
+ rtkbtAutoPairUIDemo
+
diff --git a/addon/rtkbtAutoPairUIDemo/res/drawable-hdpi/ic_launcher.png b/addon/rtkbtAutoPairUIDemo/res/drawable-hdpi/ic_launcher.png
new file mode 100755
index 0000000..a301d57
--- /dev/null
+++ b/addon/rtkbtAutoPairUIDemo/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/addon/rtkbtAutoPairUIDemo/res/drawable-ldpi/ic_launcher.png b/addon/rtkbtAutoPairUIDemo/res/drawable-ldpi/ic_launcher.png
new file mode 100755
index 0000000..2c2a58b
--- /dev/null
+++ b/addon/rtkbtAutoPairUIDemo/res/drawable-ldpi/ic_launcher.png
Binary files differ
diff --git a/addon/rtkbtAutoPairUIDemo/res/drawable-mdpi/ic_launcher.png b/addon/rtkbtAutoPairUIDemo/res/drawable-mdpi/ic_launcher.png
new file mode 100755
index 0000000..f91f736
--- /dev/null
+++ b/addon/rtkbtAutoPairUIDemo/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/addon/rtkbtAutoPairUIDemo/res/drawable-xhdpi/ic_launcher.png b/addon/rtkbtAutoPairUIDemo/res/drawable-xhdpi/ic_launcher.png
new file mode 100755
index 0000000..96095ec
--- /dev/null
+++ b/addon/rtkbtAutoPairUIDemo/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/addon/rtkbtAutoPairUIDemo/res/values-v11/styles.xml b/addon/rtkbtAutoPairUIDemo/res/values-v11/styles.xml
new file mode 100755
index 0000000..d408cbc
--- /dev/null
+++ b/addon/rtkbtAutoPairUIDemo/res/values-v11/styles.xml
@@ -0,0 +1,5 @@
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Holo.Light" />
+
+</resources> \ No newline at end of file
diff --git a/addon/rtkbtAutoPairUIDemo/res/values-v14/styles.xml b/addon/rtkbtAutoPairUIDemo/res/values-v14/styles.xml
new file mode 100755
index 0000000..1c089a7
--- /dev/null
+++ b/addon/rtkbtAutoPairUIDemo/res/values-v14/styles.xml
@@ -0,0 +1,5 @@
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar" />
+
+</resources> \ No newline at end of file
diff --git a/addon/rtkbtAutoPairUIDemo/res/values-zh-rCN/strings.xml b/addon/rtkbtAutoPairUIDemo/res/values-zh-rCN/strings.xml
new file mode 100755
index 0000000..729693d
--- /dev/null
+++ b/addon/rtkbtAutoPairUIDemo/res/values-zh-rCN/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<resources>
+ <string name="app_name">"BluetoothRTKAutoPairService"</string>
+ <string name="found">"找到遥控器设备,开始自动配对,请勿操作遥控器"</string>
+ <string name="removebond_timeout">"删除之前配对信息操作超时,失败!"</string>
+ <string name="ble_pair_success">"LE模式遥控器配对成功"</string>
+ <string name="ble_pair_fail">"LE模式遥控器配对失败"</string>
+ <string name="ble_pair_timeout">"LE模式遥控器配对超时,失败!"</string>
+ <string name="ble_sdp_success">"LE模式遥控器搜索服务(SDP)成功"</string>
+ <string name="ble_sdp_fail">"LE模式遥控器搜索服务(SDP)失败"</string>
+ <string name="classic_pair_success">"BR/EDR模式遥控器配对成功"</string>
+ <string name="classic_pair_fail">"BR/EDR模式遥控器配对失败"</string>
+ <string name="classic_pair_timeout">"BR/EDR模式遥控器配对超时,失败!"</string>
+ <string name="classic_sdp_success">"BR/EDR模式遥控器搜索服务(SDP)成功"</string>
+ <string name="classic_sdp_fail">"BR/EDR模式遥控器搜索服务(SDP)失败"</string>
+ <string name="over">"遥控器可以开始使用了!"</string>
+ <string name="connect_to_device">"遥控器配对已完成,正在连接遥控器,请勿操作遥控器"</string>
+ <string name="error_weak_signal">"请将遥控器靠近电视,等待自动配对!"</string>
+ <string name="remove_bond">解除遥控器配对</string>
+ <string name="auto_pair_stop">自动配对超时结束!</string>
+</resources>
diff --git a/addon/rtkbtAutoPairUIDemo/res/values-zh-rCN/styles.xml b/addon/rtkbtAutoPairUIDemo/res/values-zh-rCN/styles.xml
new file mode 100755
index 0000000..4dba0d0
--- /dev/null
+++ b/addon/rtkbtAutoPairUIDemo/res/values-zh-rCN/styles.xml
@@ -0,0 +1,5 @@
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Light" />
+
+</resources> \ No newline at end of file
diff --git a/addon/rtkbtAutoPairUIDemo/res/values/strings.xml b/addon/rtkbtAutoPairUIDemo/res/values/strings.xml
new file mode 100755
index 0000000..8898ccc
--- /dev/null
+++ b/addon/rtkbtAutoPairUIDemo/res/values/strings.xml
@@ -0,0 +1,24 @@
+<resources>
+ <string name="app_name">BluetoothRTKAutoPairService</string>
+ <string name="found">Found Remote Controller,Start BLE Pair Process. Please Do not operate remoter!</string>
+
+ <string name="removebond_timeout">Remove Old Pair Data Timeout</string>
+
+ <string name="ble_pair_success">BLE Pair Success</string>
+ <string name="ble_pair_fail">BLE Pair Fail</string>
+ <string name="ble_pair_timeout">BLE Pair Timeout</string>
+ <string name="ble_sdp_success">BLE SDP Success</string>
+ <string name="ble_sdp_fail">BLE SDP Fail</string>
+
+ <string name="classic_pair_success">Classic Pair Success</string>
+ <string name="classic_pair_fail">Classic Pair Fail</string>
+ <string name="classic_pair_timeout">Classic Pair Timeout</string>
+ <string name="classic_sdp_success">Classic SDP Success</string>
+ <string name="classic_sdp_fail">Classic SDP Fail</string>
+
+ <string name="connect_to_device">Remote Controller is paired, please wait to connect!</string>
+ <string name="over">Remote Controller can be used</string>
+ <string name="error_weak_signal">Please keep Remote Controller close to the TV, wait for autopair!</string>
+ <string name="remove_bond">remove the bond of the remoter</string>
+ <string name="auto_pair_stop">Auto pair stop!</string>
+</resources>
diff --git a/addon/rtkbtAutoPairUIDemo/res/values/styles.xml b/addon/rtkbtAutoPairUIDemo/res/values/styles.xml
new file mode 100755
index 0000000..4dba0d0
--- /dev/null
+++ b/addon/rtkbtAutoPairUIDemo/res/values/styles.xml
@@ -0,0 +1,5 @@
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Light" />
+
+</resources> \ No newline at end of file
diff --git a/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/Android.mk b/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/Android.mk
new file mode 100755
index 0000000..374ed04
--- /dev/null
+++ b/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/Android.mk
@@ -0,0 +1,10 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := rtkbtAutoPairUIDemo
+LOCAL_CERTIFICATE := platform
+
+include $(BUILD_PACKAGE)
diff --git a/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/AndroidManifest.xml b/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/AndroidManifest.xml
new file mode 100755
index 0000000..293b2ff
--- /dev/null
+++ b/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.realtek.rtkbt.AutoPairUIDemo"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15" />
+ <uses-permission android:name="android.permission.BLUETOOTH"/>
+ <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
+ <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED"/>
+ <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
+
+ <application android:label="@string/app_name"
+ android:icon="@drawable/ic_launcher"
+ android:theme="@style/AppTheme">
+
+ <receiver android:name="rtkbtAutoPairUIDemoReceiver">
+ <intent-filter>
+ <action android:name="com.realtek.autopair.message" />
+ </intent-filter>
+ </receiver>
+
+ </application>
+
+</manifest>
diff --git a/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/drawable-hdpi/ic_launcher.png b/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/drawable-hdpi/ic_launcher.png
new file mode 100755
index 0000000..a301d57
--- /dev/null
+++ b/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/drawable-ldpi/ic_launcher.png b/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/drawable-ldpi/ic_launcher.png
new file mode 100755
index 0000000..2c2a58b
--- /dev/null
+++ b/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/drawable-ldpi/ic_launcher.png
Binary files differ
diff --git a/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/drawable-mdpi/ic_launcher.png b/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/drawable-mdpi/ic_launcher.png
new file mode 100755
index 0000000..f91f736
--- /dev/null
+++ b/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/drawable-xhdpi/ic_launcher.png b/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/drawable-xhdpi/ic_launcher.png
new file mode 100755
index 0000000..96095ec
--- /dev/null
+++ b/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/values-v11/styles.xml b/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/values-v11/styles.xml
new file mode 100755
index 0000000..d408cbc
--- /dev/null
+++ b/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/values-v11/styles.xml
@@ -0,0 +1,5 @@
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Holo.Light" />
+
+</resources> \ No newline at end of file
diff --git a/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/values-v14/styles.xml b/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/values-v14/styles.xml
new file mode 100755
index 0000000..1c089a7
--- /dev/null
+++ b/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/values-v14/styles.xml
@@ -0,0 +1,5 @@
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar" />
+
+</resources> \ No newline at end of file
diff --git a/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/values-zh-rCN/strings.xml b/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/values-zh-rCN/strings.xml
new file mode 100755
index 0000000..729693d
--- /dev/null
+++ b/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/values-zh-rCN/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<resources>
+ <string name="app_name">"BluetoothRTKAutoPairService"</string>
+ <string name="found">"找到遥控器设备,开始自动配对,请勿操作遥控器"</string>
+ <string name="removebond_timeout">"删除之前配对信息操作超时,失败!"</string>
+ <string name="ble_pair_success">"LE模式遥控器配对成功"</string>
+ <string name="ble_pair_fail">"LE模式遥控器配对失败"</string>
+ <string name="ble_pair_timeout">"LE模式遥控器配对超时,失败!"</string>
+ <string name="ble_sdp_success">"LE模式遥控器搜索服务(SDP)成功"</string>
+ <string name="ble_sdp_fail">"LE模式遥控器搜索服务(SDP)失败"</string>
+ <string name="classic_pair_success">"BR/EDR模式遥控器配对成功"</string>
+ <string name="classic_pair_fail">"BR/EDR模式遥控器配对失败"</string>
+ <string name="classic_pair_timeout">"BR/EDR模式遥控器配对超时,失败!"</string>
+ <string name="classic_sdp_success">"BR/EDR模式遥控器搜索服务(SDP)成功"</string>
+ <string name="classic_sdp_fail">"BR/EDR模式遥控器搜索服务(SDP)失败"</string>
+ <string name="over">"遥控器可以开始使用了!"</string>
+ <string name="connect_to_device">"遥控器配对已完成,正在连接遥控器,请勿操作遥控器"</string>
+ <string name="error_weak_signal">"请将遥控器靠近电视,等待自动配对!"</string>
+ <string name="remove_bond">解除遥控器配对</string>
+ <string name="auto_pair_stop">自动配对超时结束!</string>
+</resources>
diff --git a/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/values-zh-rCN/styles.xml b/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/values-zh-rCN/styles.xml
new file mode 100755
index 0000000..4dba0d0
--- /dev/null
+++ b/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/values-zh-rCN/styles.xml
@@ -0,0 +1,5 @@
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Light" />
+
+</resources> \ No newline at end of file
diff --git a/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/values/strings.xml b/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/values/strings.xml
new file mode 100755
index 0000000..8898ccc
--- /dev/null
+++ b/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/values/strings.xml
@@ -0,0 +1,24 @@
+<resources>
+ <string name="app_name">BluetoothRTKAutoPairService</string>
+ <string name="found">Found Remote Controller,Start BLE Pair Process. Please Do not operate remoter!</string>
+
+ <string name="removebond_timeout">Remove Old Pair Data Timeout</string>
+
+ <string name="ble_pair_success">BLE Pair Success</string>
+ <string name="ble_pair_fail">BLE Pair Fail</string>
+ <string name="ble_pair_timeout">BLE Pair Timeout</string>
+ <string name="ble_sdp_success">BLE SDP Success</string>
+ <string name="ble_sdp_fail">BLE SDP Fail</string>
+
+ <string name="classic_pair_success">Classic Pair Success</string>
+ <string name="classic_pair_fail">Classic Pair Fail</string>
+ <string name="classic_pair_timeout">Classic Pair Timeout</string>
+ <string name="classic_sdp_success">Classic SDP Success</string>
+ <string name="classic_sdp_fail">Classic SDP Fail</string>
+
+ <string name="connect_to_device">Remote Controller is paired, please wait to connect!</string>
+ <string name="over">Remote Controller can be used</string>
+ <string name="error_weak_signal">Please keep Remote Controller close to the TV, wait for autopair!</string>
+ <string name="remove_bond">remove the bond of the remoter</string>
+ <string name="auto_pair_stop">Auto pair stop!</string>
+</resources>
diff --git a/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/values/styles.xml b/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/values/styles.xml
new file mode 100755
index 0000000..4dba0d0
--- /dev/null
+++ b/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/res/values/styles.xml
@@ -0,0 +1,5 @@
+<resources>
+
+ <style name="AppTheme" parent="android:Theme.Light" />
+
+</resources> \ No newline at end of file
diff --git a/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/src/com/android/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemoReceiver.java b/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/src/com/android/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemoReceiver.java
new file mode 100755
index 0000000..f936030
--- /dev/null
+++ b/addon/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemo/src/com/android/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemoReceiver.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2015 The Realtek Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.realtek.rtkbt.AutoPairUIDemo;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothRtkbt;
+import android.bluetooth.BluetoothDevice;
+import android.util.Log;
+import android.widget.Toast;
+import android.util.Log;
+import java.util.HashMap;
+
+
+/*
+ *BluetoothRTKAutoPairBroadcastReceiver sync state with bluetooth,
+ *STATE_ON start BluetoothRTKAutoPairService
+ *STATE_TURNING_OFF stop BluetoothRTKAutoPairService
+ */
+
+
+public class rtkbtAutoPairUIDemoReceiver extends BroadcastReceiver {
+ private static final String TAG = "<===AutoPairUIDemoReceiver===>";
+ private static final boolean RTK_DBG = true;
+ private static final String RTKBT_AUTOPAIR_MESSAGE = "com.realtek.autopair.message";
+ private static final String RTKBT_AUTOPAIR_MESSAGE_FIELD_RCUADDR = "com.realtek.autopair.message.rcuaddr";
+ private static final String RTKBT_AUTOPAIR_MESSAGE_FIELD_MESSAGE_ID = "com.realtek.autopair.message.id";
+ private static final String RTKBT_AUTOPAIR_MESSAGE_FIELD_DATA = "com.realtek.autopair.message.data";
+
+ private static final int RTKBT_AUTOPAIR_State_Idle = 0;
+ private static final int RTKBT_AUTOPAIR_State_Found = 1;
+ private static final int RTKBT_AUTOPAIR_State_RemoveBond = 2;
+ private static final int RTKBT_AUTOPAIR_State_BLEBond = 3;
+ private static final int RTKBT_AUTOPAIR_State_ClassicBond = 4;
+ private static final int RTKBT_AUTOPAIR_State_SaveNewRCU = 5;
+ private static final int RTKBT_AUTOPAIR_State_PairSuccess_to_connect = 6;
+ private static final int RTKBT_AUTOPAIR_State_ConnectSuccess = 7;
+
+ private static final int RTKBT_AUTOPAIR_State_PairFail = 0x101;
+ private static final int RTKBT_AUTOPAIR_State_PairTimeout = 0x102;
+ private static final int RTKBT_AUTOPAIR_State_ConnectFail = 0x103;
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.i(TAG, "receive intent:" + intent.getAction());
+
+ if(intent.getAction().equals(RTKBT_AUTOPAIR_MESSAGE)) {
+ Log.d(TAG, "RTKBT_AUTOPAIR_MESSAGE: ID:"+intent.getIntExtra(RTKBT_AUTOPAIR_MESSAGE_FIELD_MESSAGE_ID, 0)+" ADDR:"+intent.getStringExtra(RTKBT_AUTOPAIR_MESSAGE_FIELD_RCUADDR)+" DATA:"+intent.getByteArrayExtra(RTKBT_AUTOPAIR_MESSAGE_FIELD_DATA));
+ ShowMessage(context, intent);
+ }
+ }
+ private void ShowMessage(Context context, Intent intent)
+ {
+ int message_id = intent.getIntExtra(RTKBT_AUTOPAIR_MESSAGE_FIELD_MESSAGE_ID, 0);
+ String rcuaddr = intent.getStringExtra(RTKBT_AUTOPAIR_MESSAGE_FIELD_RCUADDR);
+ byte[] data =intent.getByteArrayExtra(RTKBT_AUTOPAIR_MESSAGE_FIELD_DATA);
+ switch(message_id)
+ {
+ case RTKBT_AUTOPAIR_State_Found:
+ Toast.makeText(context,"Found RCU("+rcuaddr+")",Toast.LENGTH_LONG).show();
+ break;
+ case RTKBT_AUTOPAIR_State_RemoveBond:
+ Toast.makeText(context,"RCU("+rcuaddr+") Remove Old RCU Bonding Info",Toast.LENGTH_LONG).show();
+ break;
+ case RTKBT_AUTOPAIR_State_BLEBond:
+ Toast.makeText(context,"RCU("+rcuaddr+") Start BLE Bonding",Toast.LENGTH_LONG).show();
+ break;
+ case RTKBT_AUTOPAIR_State_ClassicBond:
+ Toast.makeText(context,"RCU("+rcuaddr+") Start BREDR Bonding",Toast.LENGTH_LONG).show();
+ break;
+ case RTKBT_AUTOPAIR_State_SaveNewRCU:
+ Toast.makeText(context,"RCU("+rcuaddr+") Save New RCU Bonding Info",Toast.LENGTH_LONG).show();
+ break;
+ case RTKBT_AUTOPAIR_State_PairSuccess_to_connect:
+ Toast.makeText(context,"RCU("+rcuaddr+") Connecting to RCU",Toast.LENGTH_LONG).show();
+ break;
+ case RTKBT_AUTOPAIR_State_ConnectSuccess:
+ Toast.makeText(context,"RCU("+rcuaddr+") Connected to RCU, Pair success",Toast.LENGTH_LONG).show();
+ break;
+ case RTKBT_AUTOPAIR_State_PairFail:
+ Toast.makeText(context,"RCU("+rcuaddr+") Pair Failed",Toast.LENGTH_LONG).show();
+ break;
+ case RTKBT_AUTOPAIR_State_PairTimeout:
+ Toast.makeText(context,"RCU("+rcuaddr+") Pair Timeout",Toast.LENGTH_LONG).show();
+ break;
+ case RTKBT_AUTOPAIR_State_ConnectFail:
+ Toast.makeText(context,"RCU("+rcuaddr+") Connect Fail",Toast.LENGTH_LONG).show();
+ break;
+ }
+ }
+}
diff --git a/addon/rtkbtAutoPairUIDemo/src/com/android/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemoReceiver.java b/addon/rtkbtAutoPairUIDemo/src/com/android/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemoReceiver.java
new file mode 100755
index 0000000..f936030
--- /dev/null
+++ b/addon/rtkbtAutoPairUIDemo/src/com/android/rtkbtAutoPairUIDemo/rtkbtAutoPairUIDemoReceiver.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2015 The Realtek Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.realtek.rtkbt.AutoPairUIDemo;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothRtkbt;
+import android.bluetooth.BluetoothDevice;
+import android.util.Log;
+import android.widget.Toast;
+import android.util.Log;
+import java.util.HashMap;
+
+
+/*
+ *BluetoothRTKAutoPairBroadcastReceiver sync state with bluetooth,
+ *STATE_ON start BluetoothRTKAutoPairService
+ *STATE_TURNING_OFF stop BluetoothRTKAutoPairService
+ */
+
+
+public class rtkbtAutoPairUIDemoReceiver extends BroadcastReceiver {
+ private static final String TAG = "<===AutoPairUIDemoReceiver===>";
+ private static final boolean RTK_DBG = true;
+ private static final String RTKBT_AUTOPAIR_MESSAGE = "com.realtek.autopair.message";
+ private static final String RTKBT_AUTOPAIR_MESSAGE_FIELD_RCUADDR = "com.realtek.autopair.message.rcuaddr";
+ private static final String RTKBT_AUTOPAIR_MESSAGE_FIELD_MESSAGE_ID = "com.realtek.autopair.message.id";
+ private static final String RTKBT_AUTOPAIR_MESSAGE_FIELD_DATA = "com.realtek.autopair.message.data";
+
+ private static final int RTKBT_AUTOPAIR_State_Idle = 0;
+ private static final int RTKBT_AUTOPAIR_State_Found = 1;
+ private static final int RTKBT_AUTOPAIR_State_RemoveBond = 2;
+ private static final int RTKBT_AUTOPAIR_State_BLEBond = 3;
+ private static final int RTKBT_AUTOPAIR_State_ClassicBond = 4;
+ private static final int RTKBT_AUTOPAIR_State_SaveNewRCU = 5;
+ private static final int RTKBT_AUTOPAIR_State_PairSuccess_to_connect = 6;
+ private static final int RTKBT_AUTOPAIR_State_ConnectSuccess = 7;
+
+ private static final int RTKBT_AUTOPAIR_State_PairFail = 0x101;
+ private static final int RTKBT_AUTOPAIR_State_PairTimeout = 0x102;
+ private static final int RTKBT_AUTOPAIR_State_ConnectFail = 0x103;
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.i(TAG, "receive intent:" + intent.getAction());
+
+ if(intent.getAction().equals(RTKBT_AUTOPAIR_MESSAGE)) {
+ Log.d(TAG, "RTKBT_AUTOPAIR_MESSAGE: ID:"+intent.getIntExtra(RTKBT_AUTOPAIR_MESSAGE_FIELD_MESSAGE_ID, 0)+" ADDR:"+intent.getStringExtra(RTKBT_AUTOPAIR_MESSAGE_FIELD_RCUADDR)+" DATA:"+intent.getByteArrayExtra(RTKBT_AUTOPAIR_MESSAGE_FIELD_DATA));
+ ShowMessage(context, intent);
+ }
+ }
+ private void ShowMessage(Context context, Intent intent)
+ {
+ int message_id = intent.getIntExtra(RTKBT_AUTOPAIR_MESSAGE_FIELD_MESSAGE_ID, 0);
+ String rcuaddr = intent.getStringExtra(RTKBT_AUTOPAIR_MESSAGE_FIELD_RCUADDR);
+ byte[] data =intent.getByteArrayExtra(RTKBT_AUTOPAIR_MESSAGE_FIELD_DATA);
+ switch(message_id)
+ {
+ case RTKBT_AUTOPAIR_State_Found:
+ Toast.makeText(context,"Found RCU("+rcuaddr+")",Toast.LENGTH_LONG).show();
+ break;
+ case RTKBT_AUTOPAIR_State_RemoveBond:
+ Toast.makeText(context,"RCU("+rcuaddr+") Remove Old RCU Bonding Info",Toast.LENGTH_LONG).show();
+ break;
+ case RTKBT_AUTOPAIR_State_BLEBond:
+ Toast.makeText(context,"RCU("+rcuaddr+") Start BLE Bonding",Toast.LENGTH_LONG).show();
+ break;
+ case RTKBT_AUTOPAIR_State_ClassicBond:
+ Toast.makeText(context,"RCU("+rcuaddr+") Start BREDR Bonding",Toast.LENGTH_LONG).show();
+ break;
+ case RTKBT_AUTOPAIR_State_SaveNewRCU:
+ Toast.makeText(context,"RCU("+rcuaddr+") Save New RCU Bonding Info",Toast.LENGTH_LONG).show();
+ break;
+ case RTKBT_AUTOPAIR_State_PairSuccess_to_connect:
+ Toast.makeText(context,"RCU("+rcuaddr+") Connecting to RCU",Toast.LENGTH_LONG).show();
+ break;
+ case RTKBT_AUTOPAIR_State_ConnectSuccess:
+ Toast.makeText(context,"RCU("+rcuaddr+") Connected to RCU, Pair success",Toast.LENGTH_LONG).show();
+ break;
+ case RTKBT_AUTOPAIR_State_PairFail:
+ Toast.makeText(context,"RCU("+rcuaddr+") Pair Failed",Toast.LENGTH_LONG).show();
+ break;
+ case RTKBT_AUTOPAIR_State_PairTimeout:
+ Toast.makeText(context,"RCU("+rcuaddr+") Pair Timeout",Toast.LENGTH_LONG).show();
+ break;
+ case RTKBT_AUTOPAIR_State_ConnectFail:
+ Toast.makeText(context,"RCU("+rcuaddr+") Connect Fail",Toast.LENGTH_LONG).show();
+ break;
+ }
+ }
+}
diff --git a/addon/vr_bee1_hidraw_daemon/Android.mk b/addon/vr_bee1_hidraw_daemon/Android.mk
new file mode 100755
index 0000000..bd30b5b
--- /dev/null
+++ b/addon/vr_bee1_hidraw_daemon/Android.mk
@@ -0,0 +1,4 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-subdir-makefiles)
+
diff --git a/addon/vr_bee1_hidraw_daemon/addon.mk b/addon/vr_bee1_hidraw_daemon/addon.mk
new file mode 100755
index 0000000..e2b21fe
--- /dev/null
+++ b/addon/vr_bee1_hidraw_daemon/addon.mk
@@ -0,0 +1,5 @@
+PRODUCT_COPY_FILES += \
+ $(LOCAL_PATH)/system/etc/hidraw_setting:system/etc/hidraw_setting \
+
+PRODUCT_PACKAGES += \
+ vr_bee1_hidraw_daemon \
diff --git a/addon/vr_bee1_hidraw_daemon/hidraw/Android.mk b/addon/vr_bee1_hidraw_daemon/hidraw/Android.mk
new file mode 100755
index 0000000..df0ac76
--- /dev/null
+++ b/addon/vr_bee1_hidraw_daemon/hidraw/Android.mk
@@ -0,0 +1,24 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES += \
+ voice_hidraw.c \
+ voice_uipc.c \
+ get_voice_app.c \
+ ./msbc/msbc.c \
+ ./sbc/sbcdec.c \
+ config.c
+
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/sbc \
+ $(LOCAL_PATH)/msbc
+
+LOCAL_CFLAGS += $(rtk_local_CFLAGS) -Wno-error=unused-parameter
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_SHARED_LIBRARIES := libcutils libc liblog libtinyalsa libandroid_runtime libutils
+LOCAL_MODULE := vr_bee1_hidraw_daemon
+LOCAL_MULTILIB := 32
+
+include $(BUILD_EXECUTABLE)
diff --git a/addon/vr_bee1_hidraw_daemon/hidraw/bee_settings.h b/addon/vr_bee1_hidraw_daemon/hidraw/bee_settings.h
new file mode 100755
index 0000000..ea2d448
--- /dev/null
+++ b/addon/vr_bee1_hidraw_daemon/hidraw/bee_settings.h
@@ -0,0 +1,35 @@
+#ifndef BEE_SETTINGS_H
+#define BEE_SETTINGS_H
+
+#define BEE_RCU_VID (0x005D)
+#define BEE_RCU_PID (0x0001)
+#define BEE_RCU_VERSION (0x0000)
+
+#define BEE_VOICEKEY_LEN 8
+
+#define BEE_VOICEKEY_REPORTID (0x01)
+
+unsigned char BEE_VOICE_KEYDOWN_DATA[BEE_VOICEKEY_LEN] = {0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00};
+unsigned char BEE_VOICE_KEYUP_DATA[BEE_VOICEKEY_LEN] = {0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+//msbc
+#define BEE_MSBC_VOICEDATA_REPORTID (0x5A)
+#define BEE_MSBC_VOICECMD_REPORTID (0x5A)
+
+
+#define BEE_MSBC_ATT_FRAME_SIZE 120
+#define BEE_MSBC_FRAME_SIZE 60
+#define BEE_MSBC_DECODE_INPUT_SIZE 58
+#define BEE_MSBC_DECODE_OUTPUT_SIZE 240
+
+//sbc
+#define BEE_SBC_VOICEDATA_REPORTID (0x5B)
+#define BEE_SBC_VOICECMD_REPORTID (0x5B)
+
+#define BEE_SBC_ATT_FRAME_SIZE 72
+#define BEE_SBC_FRAME_SIZE 36
+
+#define BEE_SBC_DECODE_INPUT_SIZE 36
+#define BEE_SBC_DECODE_OUTPUT_SIZE 256
+
+#endif \ No newline at end of file
diff --git a/addon/vr_bee1_hidraw_daemon/hidraw/config.c b/addon/vr_bee1_hidraw_daemon/hidraw/config.c
new file mode 100755
index 0000000..17e5e17
--- /dev/null
+++ b/addon/vr_bee1_hidraw_daemon/hidraw/config.c
@@ -0,0 +1,251 @@
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <cutils/log.h>
+
+#include "config.h"
+
+
+tVoice_Hidraw_Settings *gConfig = NULL;
+static char * gContent = NULL;
+
+
+static char * voice_conf_getline(char * head, char ** left)
+{
+ char * next;
+ if(*head == 0)
+ return NULL;
+ while((*head == '\r')||(*head == '\n'))
+ head++;
+ if(*head == 0)
+ return NULL;
+ next = head;
+ while((*next != '\r')&&(*next != '\n')&&(*next != 0))
+ next++;
+ if(*next != 0)
+ *next++ = 0;
+ *left = next;
+ return head;
+}
+
+static void voice_conf_parse_config(tVoice_Hidraw_Settings **items, char *content)
+{
+ char * group = NULL;
+ char * item = NULL;
+ char * val = NULL;
+ char * line = NULL;
+ int id = -1;
+ tVoice_Hidraw_Settings* entry, * head, *end;
+
+ char * p;
+ int i = 0;
+
+ head = NULL;
+ end = NULL;
+
+ ALOGD("voice_conf_parse_config\n");
+ while((line = voice_conf_getline(content, &content)) != NULL)
+ {
+ ALOGD("voice_conf_parse_config line:%s\n", line);
+ switch(line[0])
+ {
+ case '[':
+ {
+ p = strstr(line,"]");
+ if(p)
+ {
+ *p = 0;
+ group = &(line[1]);
+ ALOGI("voice_conf_parse_config Find Group[%s]\n", group);
+ }else{
+ ALOGW("voice_conf_parse_config Expected ']' end of Group(%s)!\n", line);
+ }
+ break;
+ }
+ case '#':
+ {
+ break;
+ }
+ default:
+ {
+ p = strstr(line,"=");
+ if(p)
+ {
+ *p++ = 0;
+ item = line;
+ val = p;
+ if((item[0]==0)||(val[0]==0))
+ {
+ ALOGI("voice_conf_parse_config ignore(item:%s val:%s)\n", item[0]?item:"(null)", val[0]?val:"(null)");
+ break;
+ }
+ ALOGI("voice_conf_parse_config Find Item[%s:%s=%s]\n", group, item, val);
+ entry = malloc(sizeof(tVoice_Hidraw_Settings));
+ if(entry)
+ {
+ entry->next = NULL;
+ entry->group = group;
+ entry->item = item;
+ entry->val = val;
+ if(end)
+ {
+ end->next = entry;
+ end = entry;
+ }else
+ end = entry;
+ if(head == NULL)
+ head = entry;
+ }
+ }
+ }
+ }
+ }
+ *items = head;
+}
+
+
+int voice_loadconfig(char * path)
+{
+ int i,res,fd;
+ struct stat st;
+ char * content = NULL;
+ struct tVoice_Hidraw_Settings* config = NULL;
+
+ ALOGI("voice_loadconfig(%s) load!\n", path);
+ fd = open(path, O_RDONLY);
+ if(fd < 0)
+ {
+ ALOGW("voice_loadconfig(%s) open fail!\n", path);
+ return -1;
+ }
+ res = fstat(fd, &st);
+ if(res)
+ {
+ ALOGW("voice_loadconfig(%s) stat fail! reason=%d\n", path, res);
+ return -1;
+ }
+ if(st.st_size <= 0)
+ {
+ ALOGW("voice_loadconfig(%s) size fail! size=%d\n", path, (int)st.st_size);
+ close(fd);
+ return -1;
+ }
+ ALOGI("voice_loadconfig(%s) size=%d!\n", path, (int)st.st_size);
+ content = malloc(st.st_size+1);
+ if(content == NULL)
+ {
+ ALOGW("voice_loadconfig(%s) malloc fail!\n", path);
+ close(fd);
+ return -1;
+ }
+ res = read(fd, content, st.st_size);
+ if(res <= 0)
+ {
+ ALOGW("voice_loadconfig(%s) read fail! res=%d\n", path, res);
+ close(fd);
+ return -1;
+ }
+ content[res] = 0;
+ voice_conf_parse_config(&config, content);
+ close(fd);
+
+ gConfig = config;
+ return 0;
+}
+
+
+
+
+static char * voice_api_GetConfig(char * group, char * item)
+{
+ int i;
+ tVoice_Hidraw_Settings * entry;
+
+ if(item == NULL)
+ return NULL;
+ entry = gConfig;
+ while(entry)
+ {
+ if(group&&(entry->group)&&(strcmp(entry->group, group)==0)&&(strcmp(entry->item, item)==0))
+ return entry->val;
+ if((group==NULL)&&(entry->group==NULL)&&(strcmp(entry->item, item)==0))
+ return entry->val;
+
+ entry = entry->next;
+ }
+ return NULL;
+}
+
+int voice_get_int_config(char *group, char *item) {
+ char *str;
+ int value = -1;
+
+ str = voice_api_GetConfig(group, item);
+ if(str == NULL) {
+ ALOGE("failed to get int value: %s-%s", group, item);
+ goto result;
+ }
+
+ value = strtol(str, NULL, 16);
+
+result:
+ return value;
+}
+
+int voice_get_byte_array_config(char *group, char *item, char* arr, int len) {
+ char *str, *front, *tail;
+ int ret = -1;
+ int i = 0;
+
+ str = voice_api_GetConfig(group, item);
+ if(str == NULL) {
+ goto retval;
+ }
+
+ front = str;
+
+ while(i < len) {
+ tail = strstr(front, ",");
+ if(tail == NULL) {
+ tail = strstr(front, ";");
+ }
+
+ if(tail == NULL) {
+ ALOGE("failed to get byte-array value: %s-%s-No%d", group, item, i + 1);
+ goto retval;
+ }
+
+ *tail++ = 0;
+ *(arr+i) = (strtol(front, NULL, 16)) & 0xff;
+ front = tail;
+ i++;
+ }
+
+ if(i == len)ret = i;
+
+retval:
+ return ret;
+}
+
+int voice_conf_exit()
+{
+ struct tVoice_Hidraw_Settings *item, *p;
+ int i;
+
+ item = gConfig;
+ while(item)
+ {
+ p = item;
+ item = item->next;
+ free(p);
+ }
+
+ if(gContent)
+ free(gContent);
+ return 0;
+}
+
+
diff --git a/addon/vr_bee1_hidraw_daemon/hidraw/config.h b/addon/vr_bee1_hidraw_daemon/hidraw/config.h
new file mode 100755
index 0000000..64f50bf
--- /dev/null
+++ b/addon/vr_bee1_hidraw_daemon/hidraw/config.h
@@ -0,0 +1,34 @@
+#ifndef CONFIG_H
+#define CONFIG_H
+
+typedef struct tVoice_Hidraw_Settings
+{
+ struct tVoice_Hidraw_Settings * next;
+ char * group;
+ char * item;
+ char * val;
+} tVoice_Hidraw_Settings;
+
+#define CONFIG_GROUP_RCU "Rcu"
+#define CONFIG_ITEM_RCU_VID "Vid"
+#define CONFIG_ITEM_RCU_PID "Pid"
+#define CONFIG_ITEM_RCU_VER "Ver"
+
+#define CONFIG_GROUP_REPORTID "ReportID"
+#define CONFIG_ITEM_REPORTID_KEY "Key"
+#define CONFIG_ITEM_REPORTID_DATA "Data"
+#define CONFIG_ITEM_REPORTID_CMD "Cmd"
+
+#define CONFIG_GROUP_REPORTVALUE "ReportValue"
+#define CONFIG_ITEM_REPORTVALUE_KEYDOWNLEN "KeyDownLen"
+#define CONFIG_ITEM_REPORTVALUE_KEYDOWN "KeyDown"
+#define CONFIG_ITEM_REPORTVALUE_KEYUPLEN "KeyUpLen"
+#define CONFIG_ITEM_REPORTVALUE_KEYUP "KeyUp"
+
+#define CONFIG_GROUP_SETTINGS "Settings"
+#define CONFIG_ITEM_SETTINGS_DECODETYPE "DecodeType"
+#define CONFIG_ITEM_SETTINGS_DATAMASK "DataMask"
+#define CONFIG_ITEM_SETTINGS_AUTOCMD "AutoCmd"
+
+
+#endif
diff --git a/addon/vr_bee1_hidraw_daemon/hidraw/get_voice_app.c b/addon/vr_bee1_hidraw_daemon/hidraw/get_voice_app.c
new file mode 100755
index 0000000..fe2160f
--- /dev/null
+++ b/addon/vr_bee1_hidraw_daemon/hidraw/get_voice_app.c
@@ -0,0 +1,234 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "string.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <cutils/log.h>
+#include "get_voice_app.h"
+#include "msbc.h"
+
+
+#define DECODE_SIZE 58
+#define VOICE_MTU 60
+#define VOICDE_DECODE_UNIT (VOICE_MTU*4)
+
+
+static uint8* _pVoiceBuf = NULL;
+static uint8* _pdecodeBuf = NULL;
+static uint8* _pdecodeFrameBuf = NULL;
+int voice_fd = -1;
+int voice_fd_origin = -1;
+int voice_fd_wav = -1;
+sbc_t t_sbc;
+static int file_index = 0;
+
+struct wavfile
+{
+ char id[4]; // should always contain "RIFF"
+ int totallength; // total file length minus 8
+ char wavefmt[8]; // should be "WAVEfmt "
+ int format; // 16 for PCM format
+ short pcm; // 1 for PCM format
+ short channels; // channels
+ int frequency; // sampling frequency, 16000 in this case
+ int bytes_per_second;
+ short bytes_by_capture;
+ short bits_per_sample;
+ char data[4]; // should always contain "data"
+ int bytes_in_data;
+};
+
+void write_wav_header(char* name, int samples, int channels){
+ struct wavfile filler;
+ FILE *pcm_fd;
+ FILE *wav_fd;
+ char record_name[50] = {0};
+ int size;
+ char ch;
+
+ ALOGE("Start to convert pcm to wav\n");
+ strncpy(filler.id, "RIFF", 4);
+// filler.totallength = (samples * channels) + sizeof(struct wavfile) - 8; //81956
+ strncpy(filler.wavefmt, "WAVEfmt ", 8);
+ filler.format = 16;
+ filler.pcm = 1;
+ filler.channels = channels;
+ filler.frequency = 16000;
+ filler.bits_per_sample = 16;
+ filler.bytes_per_second = filler.channels * filler.frequency * filler.bits_per_sample/8;
+ filler.bytes_by_capture = filler.channels*filler.bits_per_sample/8;
+// filler.bytes_in_data = samples * filler.channels * filler.bits_per_sample/8;
+ strncpy(filler.data, "data", 4);
+
+ pcm_fd = fopen(name, "rb");
+ fseek(pcm_fd, 0, SEEK_END);
+ size = ftell(pcm_fd);
+ fseek(pcm_fd, 0, SEEK_SET);
+
+ filler.bytes_in_data = size;
+ filler.totallength = size + sizeof(filler) - 8;
+#if 0 // just print data
+ printf("File description header: %s\n", filler.id);
+ printf("Size of file: %d\n", filler.totallength);
+ printf("WAV Format description header: %s\n", filler.wavefmt);
+ printf("Size of WAVE section chunck: %d\n", filler.format);
+ printf("WAVE type format: %d\n", filler.pcm);
+ printf("Number of channels: %d\n", filler.channels);
+ printf("Samples per second: %d\n", filler.frequency);
+ printf("Bytes per second: %d\n", filler.bytes_per_second);
+ printf("Block alignment: %d\n", filler.bytes_by_capture);
+ printf("Bits per sample: %d\n", filler.bits_per_sample);
+ printf("Data description header: %s\n", filler.data);
+ printf("Size of data: %d\n", filler.bytes_in_data);
+#endif
+
+
+ sprintf(record_name,"voice_msbc_wav%d.wav",file_index);
+
+ // store wav header
+ wav_fd = fopen(record_name, "wb");
+ fwrite(&filler, 1, sizeof(filler), wav_fd);
+ fclose(wav_fd);
+
+ // store voice data
+ wav_fd = fopen(record_name, "ab");
+ while(!feof(pcm_fd)) {
+ fread(&ch, 1, 1, pcm_fd);
+
+ if(!feof(pcm_fd)) {
+ fwrite(&ch, 1, 1, wav_fd);
+ }
+ }
+
+ fclose(pcm_fd);
+ fclose(wav_fd);
+}
+
+void RS_init_sbc()
+{
+ //msbc
+ sbc_init (&t_sbc, 0L);
+}
+
+void RS_voice_app_create_origin_output()
+{
+ char record_name[50] = {0};
+
+ sprintf(record_name,"/data/vr/voice_msbc_origin%d",file_index);
+
+ voice_fd_origin = open (record_name, O_WRONLY | O_CREAT |O_TRUNC, 0644);
+
+
+ if(voice_fd_origin < 0)
+ {
+ ALOGE("can't open record origin file:%s ",record_name);
+ }
+
+ RS_init_sbc();
+
+ return;
+}
+
+void RS_voice_app_create_output()
+{
+ char record_name[50] = {0};
+ sprintf(record_name,"/data/vr/voice_msbc%d",file_index);
+
+ voice_fd = open (record_name, O_WRONLY | O_CREAT |O_TRUNC, 0644);
+
+ if(voice_fd < 0)
+ {
+ ALOGE("can't open record file:%s ",record_name);
+ }
+
+
+ return;
+}
+
+int RS_stop_voice_stream_data (void)
+{
+ char record_name[50] = {0};
+
+ ALOGE ("in\r\n");
+
+ if (voice_fd > 0 && -1 == close (voice_fd) )
+ {
+ ALOGE ("close voice file fail\r\n");
+ }
+
+ if (voice_fd_origin > 0 && -1 == close (voice_fd_origin) )
+ {
+ ALOGE ("close voice file fail\r\n");
+ }
+
+ voice_fd = 0;
+ voice_fd_origin = 0;
+
+ sprintf(record_name,"voice_msbc%d",file_index);
+
+ //write_wav_header(record_name, 16000, 1);
+
+ sbc_finish (&t_sbc);
+
+ file_index = ((++file_index)>= 10) ? 0 : file_index;
+
+ return 0;
+}
+
+int RS_write_decode_buf(uint8* pu_decode, ssize_t len)
+{
+ if (voice_fd > 0)
+ {
+ write (voice_fd, pu_decode, len);
+ return 0;
+ }
+ return -1;
+}
+
+int RS_deal_voice_stream_data(const uint8* input, size_t voice_buf_size, unsigned char* output, size_t output_buf_size, int* frame_len)
+{
+ int framelen;
+
+// RS_init_sbc();
+
+
+
+ if (NULL == input || 0 == voice_buf_size)
+ {
+ ALOGE ("input is null \r\n");
+ return -1;
+ }
+
+
+ if (NULL == output || 0 == output_buf_size)
+ {
+ ALOGE ("output is null");
+ return -1;
+ }
+
+ if(voice_buf_size != VOICE_MTU) {
+ ALOGE ("input size error: %d", voice_buf_size);
+ return -1;
+ }
+
+
+ if (input[0] == 0x01 && input[2] == 0xad)
+ {
+ write(voice_fd_origin, input, voice_buf_size);
+ framelen = sbc_decode (&t_sbc, &input[2], DECODE_SIZE, output, output_buf_size,frame_len);
+ if (framelen <= 0)
+ {
+ ALOGE("fail to decode");
+ return -1;
+ }
+ RS_write_decode_buf(output, *frame_len);
+ return 0;
+ }else {
+ ALOGE("msbc format error !!!");
+ return -1;
+ }
+}
+
+
diff --git a/addon/vr_bee1_hidraw_daemon/hidraw/get_voice_app.h b/addon/vr_bee1_hidraw_daemon/hidraw/get_voice_app.h
new file mode 100755
index 0000000..a55b100
--- /dev/null
+++ b/addon/vr_bee1_hidraw_daemon/hidraw/get_voice_app.h
@@ -0,0 +1,22 @@
+
+//#define MSBC_SUPPORT
+#define VOICE_KEY_DOWN 0x3e
+#define VOICE_BUFFER_REPORT_ID 0x5a
+#define ADD_FOR_VOICE_CONTROL
+#define VOICE_FILE_WITH_MSBC "/tmp/voice_msbc"
+#define VOICE_FILE_WITH_NO_MSBC "/tmp/voice_no_msbc"
+
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned int uint32;
+typedef signed char int8;
+typedef signed short int16;
+typedef signed int int32;
+
+void RS_voice_app_create_origin_output();
+
+int RS_deal_voice_stream_data(const uint8* input, size_t voice_buf_size, unsigned char* output, size_t output_buf_size, int* frame_len);
+
+int RS_stop_voice_stream_data (void);
+
+void RS_voice_app_create_output(); \ No newline at end of file
diff --git a/addon/vr_bee1_hidraw_daemon/hidraw/msbc/msbc.c b/addon/vr_bee1_hidraw_daemon/hidraw/msbc/msbc.c
new file mode 100755
index 0000000..9ee5045
--- /dev/null
+++ b/addon/vr_bee1_hidraw_daemon/hidraw/msbc/msbc.c
@@ -0,0 +1,1766 @@
+/*
+ *
+ * Bluetooth low-complexity, subband codec (SBC) library
+ *
+ * Copyright (C) 2004-2006 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2004-2005 Henryk Ploetz <henryk@ploetzli.ch>
+ * Copyright (C) 2005-2006 Brad Midgley <bmidgley@xmission.com>
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+/* todo items:
+
+ use a log2 table for byte integer scale factors calculation (sum log2 results for high and low bytes)
+ fill bitpool by 16 bits instead of one at a time in bits allocation/bitpool generation
+ port to the dsp
+ don't consume more bytes than passed into the encoder
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+
+#include <errno.h>
+
+//#include <stdint.h>
+#include <malloc.h>
+#include <string.h>
+//#include <stdlib.h>
+#include <sys/types.h>
+
+#include "msbc.h"
+#include "msbc_math.h"
+#include "msbc_tables.h"
+#include "cutils/log.h"
+
+
+#define SBC_SYNCWORD 0xAD
+#define SBC_POOLTAG 'CBSR'
+
+/* sampling frequency */
+#define SBC_FS_16 0x00
+#define SBC_FS_32 0x01
+#define SBC_FS_44 0x02
+#define SBC_FS_48 0x03
+
+/* nrof_blocks */
+#define SBC_NB_4 0x00
+#define SBC_NB_8 0x01
+#define SBC_NB_12 0x02
+#define SBC_NB_16 0x03
+
+/* channel mode */
+#define SBC_CM_MONO 0x00
+#define SBC_CM_DUAL_CHANNEL 0x01
+#define SBC_CM_STEREO 0x02
+#define SBC_CM_JOINT_STEREO 0x03
+
+/* allocation mode */
+#define SBC_AM_LOUDNESS 0x00
+#define SBC_AM_SNR 0x01
+
+/* subbands */
+#define SBC_SB_4 0x00
+#define SBC_SB_8 0x01
+
+#define SBC_ALIGN_BITS 4
+#define SBC_ALIGN_MASK ((1 << (SBC_ALIGN_BITS)) - 1)
+
+
+typedef unsigned short uint16_t;
+typedef unsigned char uint8_t;
+typedef short int16_t;
+typedef unsigned int u_int32_t;
+
+#ifndef UINT
+typedef unsigned int UINT;
+#endif
+
+
+#if defined(WIN32) && !defined(__cplusplus)
+
+#define inline __inline
+
+#endif
+
+
+/*
+static __inline void sbc_synthesize_four(struct sbc_decoder_state *state,
+ struct sbc_frame *frame, int ch, int blk);
+*/
+
+
+/* This structure contains an unpacked SBC frame.
+ Yes, there is probably quite some unused space herein */
+struct sbc_frame
+{
+ uint16_t sampling_frequency; /* in kHz */
+ unsigned char blocks;
+ enum {
+ MONO = SBC_CM_MONO,
+ DUAL_CHANNEL = SBC_CM_DUAL_CHANNEL,
+ STEREO = SBC_CM_STEREO,
+ JOINT_STEREO = SBC_CM_JOINT_STEREO
+ } channel_mode;
+ uint8_t channels;
+ enum {
+ LOUDNESS = SBC_AM_LOUDNESS,
+ SNR = SBC_AM_SNR
+ } allocation_method;
+ uint8_t subbands;
+ uint8_t bitpool;
+ uint8_t join; /* bit number x set means joint stereo has been used in subband x */
+ int scale_factor[2][8]; /* only the lower 4 bits of every element are to be used */
+ uint16_t audio_sample[16][2][8]; /* raw integer subband samples in the frame */
+
+ int sb_sample_f[16][2][8];
+ int sb_sample[16][2][8]; /* modified subband samples */
+ short pcm_sample[2][16*8]; /* original pcm audio samples */
+};
+
+struct sbc_decoder_state {
+ int subbands;
+ long long V[2][170];
+ int offset[2][16];
+};
+
+struct sbc_encoder_state {
+ int subbands;
+ int32_t X[2][80];
+};
+
+/*
+ * Calculates the CRC-8 of the first len bits in data
+ */
+static const uint8_t crc_table[256] = {
+ 0x00, 0x1D, 0x3A, 0x27, 0x74, 0x69, 0x4E, 0x53,
+ 0xE8, 0xF5, 0xD2, 0xCF, 0x9C, 0x81, 0xA6, 0xBB,
+ 0xCD, 0xD0, 0xF7, 0xEA, 0xB9, 0xA4, 0x83, 0x9E,
+ 0x25, 0x38, 0x1F, 0x02, 0x51, 0x4C, 0x6B, 0x76,
+ 0x87, 0x9A, 0xBD, 0xA0, 0xF3, 0xEE, 0xC9, 0xD4,
+ 0x6F, 0x72, 0x55, 0x48, 0x1B, 0x06, 0x21, 0x3C,
+ 0x4A, 0x57, 0x70, 0x6D, 0x3E, 0x23, 0x04, 0x19,
+ 0xA2, 0xBF, 0x98, 0x85, 0xD6, 0xCB, 0xEC, 0xF1,
+ 0x13, 0x0E, 0x29, 0x34, 0x67, 0x7A, 0x5D, 0x40,
+ 0xFB, 0xE6, 0xC1, 0xDC, 0x8F, 0x92, 0xB5, 0xA8,
+ 0xDE, 0xC3, 0xE4, 0xF9, 0xAA, 0xB7, 0x90, 0x8D,
+ 0x36, 0x2B, 0x0C, 0x11, 0x42, 0x5F, 0x78, 0x65,
+ 0x94, 0x89, 0xAE, 0xB3, 0xE0, 0xFD, 0xDA, 0xC7,
+ 0x7C, 0x61, 0x46, 0x5B, 0x08, 0x15, 0x32, 0x2F,
+ 0x59, 0x44, 0x63, 0x7E, 0x2D, 0x30, 0x17, 0x0A,
+ 0xB1, 0xAC, 0x8B, 0x96, 0xC5, 0xD8, 0xFF, 0xE2,
+ 0x26, 0x3B, 0x1C, 0x01, 0x52, 0x4F, 0x68, 0x75,
+ 0xCE, 0xD3, 0xF4, 0xE9, 0xBA, 0xA7, 0x80, 0x9D,
+ 0xEB, 0xF6, 0xD1, 0xCC, 0x9F, 0x82, 0xA5, 0xB8,
+ 0x03, 0x1E, 0x39, 0x24, 0x77, 0x6A, 0x4D, 0x50,
+ 0xA1, 0xBC, 0x9B, 0x86, 0xD5, 0xC8, 0xEF, 0xF2,
+ 0x49, 0x54, 0x73, 0x6E, 0x3D, 0x20, 0x07, 0x1A,
+ 0x6C, 0x71, 0x56, 0x4B, 0x18, 0x05, 0x22, 0x3F,
+ 0x84, 0x99, 0xBE, 0xA3, 0xF0, 0xED, 0xCA, 0xD7,
+ 0x35, 0x28, 0x0F, 0x12, 0x41, 0x5C, 0x7B, 0x66,
+ 0xDD, 0xC0, 0xE7, 0xFA, 0xA9, 0xB4, 0x93, 0x8E,
+ 0xF8, 0xE5, 0xC2, 0xDF, 0x8C, 0x91, 0xB6, 0xAB,
+ 0x10, 0x0D, 0x2A, 0x37, 0x64, 0x79, 0x5E, 0x43,
+ 0xB2, 0xAF, 0x88, 0x95, 0xC6, 0xDB, 0xFC, 0xE1,
+ 0x5A, 0x47, 0x60, 0x7D, 0x2E, 0x33, 0x14, 0x09,
+ 0x7F, 0x62, 0x45, 0x58, 0x0B, 0x16, 0x31, 0x2C,
+ 0x97, 0x8A, 0xAD, 0xB0, 0xE3, 0xFE, 0xD9, 0xC4
+};
+
+static uint8_t sbc_crc8(const uint8_t * data, size_t len)
+{
+ uint8_t crc = 0x0f;
+ size_t i;
+ uint8_t octet;
+
+ for (i = 0; i < len / 8; i++)
+ crc = crc_table[crc ^ data[i]];
+
+ octet = data[i];
+ for (i = 0; i < len % 8; i++)
+ {
+ char bit = ((octet ^ crc) & 0x80) >> 7;
+
+ crc = ((crc & 0x7f) << 1) ^ (bit ? 0x1d : 0);
+
+ octet = octet << 1;
+ }
+
+ return crc;
+}
+
+/*
+ * Code straight from the spec to calculate the bits array
+ * Takes a pointer to the frame in question, a pointer to the bits array and the sampling frequency (as 2 bit integer)
+ */
+static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8], uint8_t sf)
+{
+ if (frame->channel_mode == MONO || frame->channel_mode == DUAL_CHANNEL)
+ {
+ int bitneed[2][8], loudness, max_bitneed, bitcount, slicecount, bitslice;
+ int ch, sb;
+
+ for (ch = 0; ch < frame->channels; ch++)
+ {
+ if (frame->allocation_method == SNR)
+ {
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ bitneed[ch][sb] = frame->scale_factor[ch][sb];
+ }
+ }
+
+ else
+ {
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ if (frame->scale_factor[ch][sb] == 0)
+ {
+ bitneed[ch][sb] = -5;
+ }
+ else
+ {
+ if (frame->subbands == 4)
+ {
+ loudness = frame->scale_factor[ch][sb] - sbc_offset4[sf][sb];
+ }
+
+ else
+ {
+ loudness = frame->scale_factor[ch][sb] - sbc_offset8[sf][sb];
+ }
+
+ if (loudness > 0)
+ {
+ bitneed[ch][sb] = loudness / 2;
+ }
+
+ else
+ {
+ bitneed[ch][sb] = loudness;
+ }
+ }
+ }
+ }
+
+ max_bitneed = 0;
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ if (bitneed[ch][sb] > max_bitneed)
+ max_bitneed = bitneed[ch][sb];
+ }
+
+ bitcount = 0;
+ slicecount = 0;
+ bitslice = max_bitneed + 1;
+ do
+ {
+ bitslice--;
+ bitcount += slicecount;
+ slicecount = 0;
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ if ((bitneed[ch][sb] > bitslice + 1) && (bitneed[ch][sb] < bitslice + 16))
+ {
+ slicecount++;
+ }
+
+ else if (bitneed[ch][sb] == bitslice + 1)
+ {
+ slicecount += 2;
+ }
+ }
+ } while (bitcount + slicecount < frame->bitpool);
+
+ if (bitcount + slicecount == frame->bitpool)
+ {
+ bitcount += slicecount;
+ bitslice--;
+ }
+
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ if (bitneed[ch][sb] < bitslice + 2)
+ {
+ bits[ch][sb] = 0;
+ }
+
+ else
+ {
+ bits[ch][sb] = bitneed[ch][sb] - bitslice;
+ if (bits[ch][sb] > 16)
+ bits[ch][sb] = 16;
+ }
+ }
+
+ sb = 0;
+ while (bitcount < frame->bitpool && sb < frame->subbands)
+ {
+ if ((bits[ch][sb] >= 2) && (bits[ch][sb] < 16))
+ {
+ bits[ch][sb]++;
+ bitcount++;
+ }
+
+ else if ((bitneed[ch][sb] == bitslice + 1) && (frame->bitpool > bitcount + 1))
+ {
+ bits[ch][sb] = 2;
+ bitcount += 2;
+ }
+ sb++;
+ }
+
+ sb = 0;
+ while (bitcount < frame->bitpool && sb < frame->subbands)
+ {
+ if (bits[ch][sb] < 16)
+ {
+ bits[ch][sb]++;
+ bitcount++;
+ }
+ sb++;
+ }
+
+ }
+
+ }
+
+ else if (frame->channel_mode == STEREO || frame->channel_mode == JOINT_STEREO)
+ {
+ int bitneed[2][8], loudness, max_bitneed, bitcount, slicecount, bitslice;
+ int ch, sb;
+
+ if (frame->allocation_method == SNR)
+ {
+ for (ch = 0; ch < 2; ch++) {
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ bitneed[ch][sb] = frame->scale_factor[ch][sb];
+ }
+ }
+ }
+
+ else
+ {
+ for (ch = 0; ch < 2; ch++)
+ {
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ if (frame->scale_factor[ch][sb] == 0)
+ {
+ bitneed[ch][sb] = -5;
+ }
+
+ else
+ {
+ if (frame->subbands == 4)
+ {
+ loudness = frame->scale_factor[ch][sb] - sbc_offset4[sf][sb];
+ }
+
+ else
+ {
+ loudness = frame->scale_factor[ch][sb] - sbc_offset8[sf][sb];
+ }
+
+ if (loudness > 0)
+ {
+ bitneed[ch][sb] = loudness / 2;
+ }
+
+ else
+ {
+ bitneed[ch][sb] = loudness;
+ }
+ }
+ }
+ }
+ }
+
+ max_bitneed = 0;
+ for (ch = 0; ch < 2; ch++)
+ {
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ if (bitneed[ch][sb] > max_bitneed)
+ max_bitneed = bitneed[ch][sb];
+ }
+ }
+
+ bitcount = 0;
+ slicecount = 0;
+ bitslice = max_bitneed + 1;
+ do {
+ bitslice--;
+ bitcount += slicecount;
+ slicecount = 0;
+ for (ch = 0; ch < 2; ch++)
+ {
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ if ((bitneed[ch][sb] > bitslice + 1) && (bitneed[ch][sb] < bitslice + 16))
+ {
+ slicecount++;
+ }
+
+ else if (bitneed[ch][sb] == bitslice + 1)
+ {
+ slicecount += 2;
+ }
+ }
+ }
+ } while (bitcount + slicecount < frame->bitpool);
+
+ if (bitcount + slicecount == frame->bitpool)
+ {
+ bitcount += slicecount;
+ bitslice--;
+ }
+
+ for (ch = 0; ch < 2; ch++)
+ {
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ if (bitneed[ch][sb] < bitslice + 2)
+ {
+ bits[ch][sb] = 0;
+ }
+
+ else
+ {
+ bits[ch][sb] = bitneed[ch][sb] - bitslice;
+ if (bits[ch][sb] > 16)
+ bits[ch][sb] = 16;
+ }
+ }
+ }
+
+ ch = 0;
+ sb = 0;
+ while ((bitcount < frame->bitpool) && (sb < frame->subbands))
+ {
+ if ((bits[ch][sb] >= 2) && (bits[ch][sb] < 16))
+ {
+ bits[ch][sb]++;
+ bitcount++;
+ }
+
+ else if ((bitneed[ch][sb] == bitslice + 1) && (frame->bitpool > bitcount + 1))
+ {
+ bits[ch][sb] = 2;
+ bitcount += 2;
+ }
+ if (ch == 1)
+ {
+ ch = 0;
+ sb++;
+ }
+ else
+ {
+ ch = 1;
+ }
+ }
+
+ ch = 0;
+ sb = 0;
+ while ((bitcount < frame->bitpool) && (sb < frame->subbands))
+ {
+ if (bits[ch][sb] < 16)
+ {
+ bits[ch][sb]++;
+ bitcount++;
+ }
+ if (ch == 1)
+ {
+ ch = 0;
+ sb++;
+ }
+
+ else
+ {
+ ch = 1;
+ }
+ }
+
+ }
+}
+
+/*
+ * Unpacks a SBC frame at the beginning of the stream in data,
+ * which has at most len bytes into frame.
+ * Returns the length in bytes of the packed frame, or a negative
+ * value on error. The error codes are:
+ *
+ * -1 Data stream too short
+ * -2 Sync byte incorrect
+ * -3 CRC8 incorrect
+ * -4 Bitpool value out of bounds
+ */
+static int sbc_unpack_frame(const uint8_t * data, struct sbc_frame *frame, size_t len)
+{
+ UINT consumed;
+ /* Will copy the parts of the header that are relevant to crc calculation here */
+ uint8_t crc_header[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ int crc_pos = 0;
+ int32_t temp;
+
+ uint8_t sf; /* sampling_frequency, temporarily needed as array index */
+
+// int audio_sample;
+ int ch, sb, blk, bit; /* channel, subband, block and bit standard counters */
+ int bits[2][8]; /* bits distribution */
+ int levels[2][8]; /* levels derived from that */
+
+ if (len < 4)
+ {
+ //DbgPrint("Exit when len < 4\n");
+ return -1;
+ }
+
+ if (data[0] != SBC_SYNCWORD)
+ {
+ //DbgPrint("Exit when data[0] != SBC_SYNCWORD\n");
+ return -2;
+ }
+
+#if 0
+ sf = (data[1] >> 6) & 0x03;
+ switch (sf) {
+ case SBC_FS_16:
+ frame->sampling_frequency = 16000;
+ break;
+ case SBC_FS_32:
+ frame->sampling_frequency = 32000;
+ break;
+ case SBC_FS_44:
+ frame->sampling_frequency = 44100;
+ break;
+ case SBC_FS_48:
+ frame->sampling_frequency = 48000;
+ break;
+ }
+
+ switch ((data[1] >> 4) & 0x03) {
+ case SBC_NB_4:
+ frame->blocks = 4;
+ break;
+ case SBC_NB_8:
+ frame->blocks = 8;
+ break;
+ case SBC_NB_12:
+ frame->blocks = 12;
+ break;
+ case SBC_NB_16:
+ frame->blocks = 16;
+ break;
+ }
+
+ frame->channel_mode = (data[1] >> 2) & 0x03;
+ switch (frame->channel_mode) {
+ case MONO:
+ frame->channels = 1;
+ break;
+ case DUAL_CHANNEL: /* fall-through */
+ case STEREO:
+ case JOINT_STEREO:
+ frame->channels = 2;
+ break;
+ }
+
+ frame->allocation_method = (data[1] >> 1) & 0x01;
+ frame->subbands = (data[1] & 0x01) ? 8 : 4;
+ frame->bitpool = data[2];
+#endif
+
+ frame->sampling_frequency = 16000;
+ frame->blocks = 15;
+ frame->channel_mode = MONO;
+ frame->channels = 1;
+ frame->allocation_method = SBC_AM_LOUDNESS;
+ frame->subbands = 8;
+ frame->bitpool = 26;
+
+
+ if (((frame->channel_mode == MONO || frame->channel_mode == DUAL_CHANNEL)
+ && frame->bitpool > 16 * frame->subbands)
+ || ((frame->channel_mode == STEREO || frame->channel_mode == JOINT_STEREO)
+ && frame->bitpool > 32 * frame->subbands))
+ {
+ //DbgPrint("Exit when frame->mode == MONO || frame->mode == DUAL_CHANNEL) &&"
+ // "frame->bitpool > 16 * frame->subbands\n");
+ return -4;
+ }
+
+ /* data[3] is crc, we're checking it later */
+ consumed = 32;
+#if 1
+ crc_header[0] = data[1];
+ crc_header[1] = data[2];
+#endif
+
+#if 0
+ crc_header[0] = 0x31;
+ crc_header[1] = 0x1a;
+#endif
+
+ crc_pos = 16;
+
+ if (frame->channel_mode == JOINT_STEREO)
+ {
+ if (len * 8 < consumed + frame->subbands)
+ return -1;
+
+ frame->join = 0x00;
+ for (sb = 0; sb < frame->subbands - 1; sb++) {
+ frame->join |= ((data[4] >> (7 - sb)) & 0x01) << sb;
+ }
+ if (frame->subbands == 4) {
+ crc_header[crc_pos / 8] = data[4] & 0xf0;
+ } else {
+ crc_header[crc_pos / 8] = data[4];
+ }
+
+ consumed += frame->subbands;
+ crc_pos += frame->subbands;
+ }
+
+ if (len * 8 < consumed + (4 * frame->subbands * frame->channels))
+ {
+ //DbgPrint("len * 8 < consumed + (4 * frame->subbands * frame->channels\n");
+ return -1;
+ }
+
+ for (ch = 0; ch < frame->channels; ch++)
+ {
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ /* FIXME assert(consumed % 4 == 0); */
+ frame->scale_factor[ch][sb] = (data[consumed >> 3] >> (4 - (consumed & 0x7))) & 0x0F;
+ crc_header[crc_pos >> 3] |= frame->scale_factor[ch][sb] << (4 - (crc_pos & 0x7));
+
+ consumed += 4;
+ crc_pos += 4;
+ }
+ }
+
+ if (data[3] != sbc_crc8(crc_header, crc_pos))
+ {
+ ALOGD("sbc_crc %02x -> %02x\n",data[3],sbc_crc8(crc_header, crc_pos));
+ return -3;
+ }
+
+ sf = SBC_FS_16;
+ sbc_calculate_bits(frame, bits, sf);
+
+ for (ch = 0; ch < frame->channels; ch++)
+ {
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ levels[ch][sb] = (1 << bits[ch][sb]) - 1;
+ }
+ }
+#if 0
+ for (blk = 0; blk < frame->blocks; blk++)
+ {
+ for (ch = 0; ch < frame->channels; ch++)
+ {
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ if (levels[ch][sb] > 0)
+ {
+ audio_sample = 0;
+ for (bit = 0; bit < bits[ch][sb]; bit++)
+ {
+ if (consumed > len * 8)
+ {
+ LogEvent("Exit when consumed > len * 8\n");
+ return -1;
+ }
+
+ if ((data[consumed >> 3] >> (7 - (consumed & 0x7))) & 0x01)
+ audio_sample |= 1 << (bits[ch][sb] - bit - 1);
+
+ consumed++;
+ }
+
+ frame->sb_sample[blk][ch][sb] =
+ (((audio_sample << 1) | 1) << frame->scale_factor[ch][sb]) /
+ levels[ch][sb] - (1 << frame->scale_factor[ch][sb]);
+ }
+
+ else
+ frame->sb_sample[blk][ch][sb] = 0;
+ }
+ }
+ }
+#endif
+
+#if 1
+
+ for (blk = 0; blk < frame->blocks; blk++)
+ {
+ for (ch = 0; ch < frame->channels; ch++)
+ {
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ frame->audio_sample[blk][ch][sb] = 0;
+ if (bits[ch][sb] == 0)
+ continue;
+
+ for (bit = 0; bit < bits[ch][sb]; bit++)
+ {
+ int b; /* A bit */
+ if (consumed > len * 8)
+ return -1;
+
+ b = (data[consumed >> 3] >> (7 - (consumed & 0x7))) & 0x01;
+ frame->audio_sample[blk][ch][sb] |= b << (bits[ch][sb] - bit - 1);
+
+ consumed++;
+ }
+ }
+ }
+ }
+
+ for (blk = 0; blk < frame->blocks; blk++)
+ {
+ for (ch = 0; ch < frame->channels; ch++)
+ {
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ if (levels[ch][sb] > 0)
+ {
+ frame->sb_sample[blk][ch][sb] =
+ (((frame->audio_sample[blk][ch][sb] << 16) | 0x8000) / levels[ch][sb]) - 0x8000;
+
+ frame->sb_sample[blk][ch][sb] >>= 3;
+ frame->sb_sample[blk][ch][sb] = (frame->sb_sample[blk][ch][sb] << (frame->scale_factor[ch][sb] + 1)); // Q13
+ }
+ else
+ {
+ frame->sb_sample[blk][ch][sb] = 0;
+ }
+ }
+ }
+ }
+#endif
+
+ if (frame->channel_mode == JOINT_STEREO)
+ {
+ for (blk = 0; blk < frame->blocks; blk++)
+ {
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ if (frame->join & (0x01 << sb)) {
+ temp = frame->sb_sample[blk][0][sb] + frame->sb_sample[blk][1][sb];
+ frame->sb_sample[blk][1][sb] = frame->sb_sample[blk][0][sb] - frame->sb_sample[blk][1][sb];
+ frame->sb_sample[blk][0][sb] = temp;
+ }
+ }
+ }
+ }
+
+ if ((consumed & 0x7) != 0)
+ consumed += 8 - (consumed & 0x7);
+
+
+ return consumed >> 3;
+}
+
+static void sbc_decoder_init(struct sbc_decoder_state *state, const struct sbc_frame *frame)
+{
+ int i, ch;
+
+ memset(state->V, 0, sizeof(state->V));
+ state->subbands = frame->subbands;
+
+ for (ch = 0; ch < 2; ch++)
+ for (i = 0; i < frame->subbands * 2; i++)
+ state->offset[ch][i] = (10 * i + 10);
+}
+
+static __inline void sbc_synthesize_four(struct sbc_decoder_state *state,
+ struct sbc_frame *frame, int ch, int blk)
+{
+ int i, j, k, idx;
+ sbc_extended_t res;
+
+ for(i = 0; i < 8; i++) {
+ /* Shifting */
+ state->offset[ch][i]--;
+ if(state->offset[ch][i] < 0) {
+ state->offset[ch][i] = 79;
+ for(j = 0; j < 9; j++) {
+ state->V[ch][j+80] = state->V[ch][j];
+ }
+ }
+ }
+
+
+ for(i = 0; i < 8; i++) {
+ /* Distribute the new matrix value to the shifted position */
+ SBC_FIXED_0(res);
+ for (j = 0; j < 4; j++) {
+ MULA(res, synmatrix4[i][j], frame->sb_sample[blk][ch][j]);
+ }
+ state->V[ch][state->offset[ch][i]] = SCALE4_STAGED1(res);
+ }
+
+ /* Compute the samples */
+ for(idx = 0, i = 0; i < 4; i++) {
+ k = (i + 4) & 0xf;
+ SBC_FIXED_0(res);
+ for(j = 0; j < 10; idx++) {
+ MULA(res, state->V[ch][state->offset[ch][i]+j++], sbc_proto_4_40m0[idx]);
+ MULA(res, state->V[ch][state->offset[ch][k]+j++], sbc_proto_4_40m1[idx]);
+ }
+ /* Store in output */
+ frame->pcm_sample[ch][blk * 4 + i] = (short)SCALE4_STAGED2(res); // Q0
+ }
+}
+
+static __inline void sbc_synthesize_eight(struct sbc_decoder_state *state,
+ struct sbc_frame *frame, int ch, int blk)
+{
+ int i, j, k, idx;
+ sbc_extended_t res;
+
+ for(i = 0; i < 16; i++) {
+ /* Shifting */
+ state->offset[ch][i]--;
+ if(state->offset[ch][i] < 0) {
+ state->offset[ch][i] = 159;
+ for(j = 0; j < 9; j++) {
+ state->V[ch][j+160] = state->V[ch][j];
+ }
+ }
+ }
+
+ for(i = 0; i < 16; i++) {
+ /* Distribute the new matrix value to the shifted position */
+ SBC_FIXED_0(res);
+ for (j = 0; j < 8; j++) {
+ MULA(res, synmatrix8[i][j], frame->sb_sample[blk][ch][j]); // Q28 = Q15 * Q13
+ }
+ state->V[ch][state->offset[ch][i]] = SCALE8_STAGED1(res); // Q10
+ }
+
+
+ /* Compute the samples */
+ for(idx = 0, i = 0; i < 8; i++) {
+ k = (i + 8) & 0xf;
+ SBC_FIXED_0(res);
+ for(j = 0; j < 10; idx++) {
+ MULA(res, state->V[ch][state->offset[ch][i]+j++], sbc_proto_8_80m0[idx]);
+ MULA(res, state->V[ch][state->offset[ch][k]+j++], sbc_proto_8_80m1[idx]);
+ }
+ /* Store in output */
+ frame->pcm_sample[ch][blk * 8 + i] = (short)SCALE8_STAGED2(res); // Q0
+
+ }
+}
+
+static int sbc_synthesize_audio(struct sbc_decoder_state *state, struct sbc_frame *frame)
+{
+ int ch, blk;
+
+ switch (frame->subbands) {
+ case 4:
+ for (ch = 0; ch < frame->channels; ch++) {
+ for (blk = 0; blk < frame->blocks; blk++)
+ sbc_synthesize_four(state, frame, ch, blk);
+ }
+ return frame->blocks * 4;
+
+ case 8:
+ for (ch = 0; ch < frame->channels; ch++) {
+ for (blk = 0; blk < frame->blocks; blk++)
+ sbc_synthesize_eight(state, frame, ch, blk);
+ }
+ return frame->blocks * 8;
+
+ default:
+ return -EIO;
+ }
+}
+
+static void sbc_encoder_init(struct sbc_encoder_state *state, const struct sbc_frame *frame)
+{
+ memset(&state->X, 0, sizeof(state->X));
+ state->subbands = frame->subbands;
+}
+
+static __inline void _sbc_analyze_four(const int32_t *in, int32_t *out)
+{
+
+ sbc_extended_t res;
+ sbc_extended_t t[8];
+
+ out[0] = out[1] = out[2] = out[3] = 0;
+
+ MUL(res, _sbc_proto_4[0], (in[8] - in[32])); // Q18
+ MULA(res, _sbc_proto_4[1], (in[16] - in[24]));
+ t[0] = SCALE4_STAGE1(res); // Q8
+
+ MUL(res, _sbc_proto_4[2], in[1]);
+ MULA(res, _sbc_proto_4[3], in[9]);
+ MULA(res, _sbc_proto_4[4], in[17]);
+ MULA(res, _sbc_proto_4[5], in[25]);
+ MULA(res, _sbc_proto_4[6], in[33]);
+ t[1] = SCALE4_STAGE1(res);
+
+ MUL(res, _sbc_proto_4[7], in[2]);
+ MULA(res, _sbc_proto_4[8], in[10]);
+ MULA(res, _sbc_proto_4[9], in[18]);
+ MULA(res, _sbc_proto_4[10], in[26]);
+ MULA(res, _sbc_proto_4[11], in[34]);
+ t[2] = SCALE4_STAGE1(res);
+
+ MUL(res, _sbc_proto_4[12], in[3]);
+ MULA(res, _sbc_proto_4[13], in[11]);
+ MULA(res, _sbc_proto_4[14], in[19]);
+ MULA(res, _sbc_proto_4[15], in[27]);
+ MULA(res, _sbc_proto_4[16], in[35]);
+ t[3] = SCALE4_STAGE1(res);
+
+ MUL(res, _sbc_proto_4[17], in[4]);
+ MULA(res, _sbc_proto_4[18], (in[12] + in[28]));
+ MULA(res, _sbc_proto_4[19], in[20]);
+ MULA(res, _sbc_proto_4[17], in[36]);
+ t[4] = SCALE4_STAGE1(res);
+
+ MUL(res, _sbc_proto_4[16], in[5]);
+ MULA(res, _sbc_proto_4[15], in[13]);
+ MULA(res, _sbc_proto_4[14], in[21]);
+ MULA(res, _sbc_proto_4[13], in[29]);
+ MULA(res, _sbc_proto_4[12], in[37]);
+ t[5] = SCALE4_STAGE1(res);
+
+ MUL(res, _sbc_proto_4[11], in[6]);
+ MULA(res, _sbc_proto_4[10], in[14]);
+ MULA(res, _sbc_proto_4[9], in[22]);
+ MULA(res, _sbc_proto_4[8], in[30]);
+ MULA(res, _sbc_proto_4[7], in[38]);
+ t[6] = SCALE4_STAGE1(res);
+
+ MUL(res, _sbc_proto_4[6], in[7]);
+ MULA(res, _sbc_proto_4[5], in[15]);
+ MULA(res, _sbc_proto_4[4], in[23]);
+ MULA(res, _sbc_proto_4[3], in[31]);
+ MULA(res, _sbc_proto_4[2], in[39]);
+ t[7] = SCALE4_STAGE1(res);
+
+ MUL(res, _anamatrix4[0], t[0]);
+ MULA(res, _anamatrix4[1], t[1]);
+ MULA(res, _anamatrix4[2], t[2]);
+ MULA(res, _anamatrix4[1], t[3]);
+ MULA(res, _anamatrix4[0], t[4]);
+ MULA(res, _anamatrix4[3], t[5]);
+ MULA(res, -_anamatrix4[3], t[7]);
+ out[0] = (int)SCALE4_STAGE2(res); // Q0
+
+ MUL(res, -_anamatrix4[0], t[0]);
+ MULA(res, _anamatrix4[3], t[1]);
+ MULA(res, _anamatrix4[2], t[2]);
+ MULA(res, _anamatrix4[3], t[3]);
+ MULA(res, -_anamatrix4[0], t[4]);
+ MULA(res, -_anamatrix4[1], t[5]);
+ MULA(res, _anamatrix4[1], t[7]);
+ out[1] = (int)SCALE4_STAGE2(res);
+
+
+ MUL(res, -_anamatrix4[0], t[0]);
+ MULA(res, -_anamatrix4[3], t[1]);
+ MULA(res, _anamatrix4[2], t[2]);
+ MULA(res, -_anamatrix4[3], t[3]);
+ MULA(res, -_anamatrix4[0], t[4]);
+ MULA(res, _anamatrix4[1], t[5]);
+ MULA(res, -_anamatrix4[1], t[7]);
+ out[2] = (int)SCALE4_STAGE2(res);
+
+ MUL(res, _anamatrix4[0], t[0]);
+ MULA(res, -_anamatrix4[1], t[1]);
+ MULA(res, _anamatrix4[2], t[2]);
+ MULA(res, -_anamatrix4[1], t[3]);
+ MULA(res, _anamatrix4[0], t[4]);
+ MULA(res, -_anamatrix4[3], t[5]);
+ MULA(res, _anamatrix4[3], t[7]);
+ out[3] = (int)SCALE4_STAGE2(res);
+}
+static __inline void sbc_analyze_four(struct sbc_encoder_state *state,
+ struct sbc_frame *frame, int ch, int blk)
+{
+ int i;
+ /* Input 4 New Audio Samples */
+ for (i = 39; i >= 4; i--)
+ state->X[ch][i] = state->X[ch][i - 4];
+ for (i = 3; i >= 0; i--)
+ state->X[ch][i] = frame->pcm_sample[ch][blk * 4 + (3 - i)];
+ _sbc_analyze_four(state->X[ch], frame->sb_sample_f[blk][ch]);
+}
+
+static __inline void _sbc_analyze_eight(const int32_t *in, int32_t *out)
+{
+ sbc_extended_t res;
+ sbc_extended_t t[8];
+
+ out[0] = out[1] = out[2] = out[3] = out[4] = out[5] = out[6] = out[7] = 0;
+
+ MUL(res, _sbc_proto_8[0], (in[16] - in[64])); // Q18 = Q18 * Q0
+ MULA(res, _sbc_proto_8[1], (in[32] - in[48]));
+ MULA(res, _sbc_proto_8[2], in[4]);
+ MULA(res, _sbc_proto_8[3], in[20]);
+ MULA(res, _sbc_proto_8[4], in[36]);
+ MULA(res, _sbc_proto_8[5], in[52]);
+ t[0] = SCALE8_STAGE1(res); // Q10
+
+ MUL(res, _sbc_proto_8[6], in[2]);
+ MULA(res, _sbc_proto_8[7], in[18]);
+ MULA(res, _sbc_proto_8[8], in[34]);
+ MULA(res, _sbc_proto_8[9], in[50]);
+ MULA(res, _sbc_proto_8[10], in[66]);
+ t[1] = SCALE8_STAGE1(res);
+
+ MUL(res, _sbc_proto_8[11], in[1]);
+ MULA(res, _sbc_proto_8[12], in[17]);
+ MULA(res, _sbc_proto_8[13], in[33]);
+ MULA(res, _sbc_proto_8[14], in[49]);
+ MULA(res, _sbc_proto_8[15], in[65]);
+ MULA(res, _sbc_proto_8[16], in[3]);
+ MULA(res, _sbc_proto_8[17], in[19]);
+ MULA(res, _sbc_proto_8[18], in[35]);
+ MULA(res, _sbc_proto_8[19], in[51]);
+ MULA(res, _sbc_proto_8[20], in[67]);
+ t[2] = SCALE8_STAGE1(res);
+
+ MUL(res, _sbc_proto_8[21], in[5]);
+ MULA(res, _sbc_proto_8[22], in[21]);
+ MULA(res, _sbc_proto_8[23], in[37]);
+ MULA(res, _sbc_proto_8[24], in[53]);
+ MULA(res, _sbc_proto_8[25], in[69]);
+ MULA(res, -_sbc_proto_8[15], in[15]);
+ MULA(res, -_sbc_proto_8[14], in[31]);
+ MULA(res, -_sbc_proto_8[13], in[47]);
+ MULA(res, -_sbc_proto_8[12], in[63]);
+ MULA(res, -_sbc_proto_8[11], in[79]);
+ t[3] = SCALE8_STAGE1(res);
+
+ MUL(res, _sbc_proto_8[26], in[6]);
+ MULA(res, _sbc_proto_8[27], in[22]);
+ MULA(res, _sbc_proto_8[28], in[38]);
+ MULA(res, _sbc_proto_8[29], in[54]);
+ MULA(res, _sbc_proto_8[30], in[70]);
+ MULA(res, -_sbc_proto_8[10], in[14]);
+ MULA(res, -_sbc_proto_8[9], in[30]);
+ MULA(res, -_sbc_proto_8[8], in[46]);
+ MULA(res, -_sbc_proto_8[7], in[62]);
+ MULA(res, -_sbc_proto_8[6], in[78]);
+ t[4] = SCALE8_STAGE1(res);
+
+ MUL(res, _sbc_proto_8[31], in[7]);
+ MULA(res, _sbc_proto_8[32], in[23]);
+ MULA(res, _sbc_proto_8[33], in[39]);
+ MULA(res, _sbc_proto_8[34], in[55]);
+ MULA(res, _sbc_proto_8[35], in[71]);
+ MULA(res, -_sbc_proto_8[20], in[13]);
+ MULA(res, -_sbc_proto_8[19], in[29]);
+ MULA(res, -_sbc_proto_8[18], in[45]);
+ MULA(res, -_sbc_proto_8[17], in[61]);
+ MULA(res, -_sbc_proto_8[16], in[77]);
+ t[5] = SCALE8_STAGE1(res);
+
+ MUL(res, _sbc_proto_8[36], (in[8] + in[72]));
+ MULA(res, _sbc_proto_8[37], in[24]);
+ MULA(res, _sbc_proto_8[38], in[40]);
+ MULA(res, _sbc_proto_8[37], in[56]);
+ MULA(res, -_sbc_proto_8[39], in[12]);
+ MULA(res, -_sbc_proto_8[5], in[28]);
+ MULA(res, -_sbc_proto_8[4], in[44]);
+ MULA(res, -_sbc_proto_8[3], in[60]);
+ MULA(res, -_sbc_proto_8[2], in[76]);
+ t[6] = SCALE8_STAGE1(res);
+
+ MUL(res, _sbc_proto_8[35], in[9]);
+ MULA(res, _sbc_proto_8[34], in[25]);
+ MULA(res, _sbc_proto_8[33], in[41]);
+ MULA(res, _sbc_proto_8[32], in[57]);
+ MULA(res, _sbc_proto_8[31], in[73]);
+ MULA(res, -_sbc_proto_8[25], in[11]);
+ MULA(res, -_sbc_proto_8[24], in[27]);
+ MULA(res, -_sbc_proto_8[23], in[43]);
+ MULA(res, -_sbc_proto_8[22], in[59]);
+ MULA(res, -_sbc_proto_8[21], in[75]);
+ t[7] = SCALE8_STAGE1(res);
+
+ MUL(res, _anamatrix8[0], t[0]); // = Q14 * Q10
+ MULA(res, _anamatrix8[7], t[1]);
+ MULA(res, _anamatrix8[2], t[2]);
+ MULA(res, _anamatrix8[3], t[3]);
+ MULA(res, _anamatrix8[6], t[4]);
+ MULA(res, _anamatrix8[4], t[5]);
+ MULA(res, _anamatrix8[1], t[6]);
+ MULA(res, _anamatrix8[5], t[7]);
+ out[0] = (int)SCALE8_STAGE2(res); // Q0
+
+ MUL(res, _anamatrix8[1], t[0]);
+ MULA(res, _anamatrix8[7], t[1]);
+ MULA(res, _anamatrix8[3], t[2]);
+ MULA(res, -_anamatrix8[5], t[3]);
+ MULA(res, -_anamatrix8[6], t[4]);
+ MULA(res, -_anamatrix8[2], t[5]);
+ MULA(res, -_anamatrix8[0], t[6]);
+ MULA(res, -_anamatrix8[4], t[7]);
+ out[1] = (int)SCALE8_STAGE2(res);
+
+ MUL(res, -_anamatrix8[1], t[0]);
+ MULA(res, _anamatrix8[7], t[1]);
+ MULA(res, _anamatrix8[4], t[2]);
+ MULA(res, -_anamatrix8[2], t[3]);
+ MULA(res, -_anamatrix8[6], t[4]);
+ MULA(res, _anamatrix8[5], t[5]);
+ MULA(res, _anamatrix8[0], t[6]);
+ MULA(res, _anamatrix8[3], t[7]);
+ out[2] = (int)SCALE8_STAGE2(res);
+
+ MUL(res, -_anamatrix8[0], t[0]);
+ MULA(res, _anamatrix8[7], t[1]);
+ MULA(res, _anamatrix8[5], t[2]);
+ MULA(res, -_anamatrix8[4], t[3]);
+ MULA(res, _anamatrix8[6], t[4]);
+ MULA(res, _anamatrix8[3], t[5]);
+ MULA(res, -_anamatrix8[1], t[6]);
+ MULA(res, -_anamatrix8[2], t[7]);
+ out[3] = (int)SCALE8_STAGE2(res);
+
+ MUL(res, -_anamatrix8[0], t[0]);
+ MULA(res, _anamatrix8[7], t[1]);
+ MULA(res, -_anamatrix8[5], t[2]);
+ MULA(res, _anamatrix8[4], t[3]);
+ MULA(res, _anamatrix8[6], t[4]);
+ MULA(res, -_anamatrix8[3], t[5]);
+ MULA(res, -_anamatrix8[1], t[6]);
+ MULA(res, _anamatrix8[2], t[7]);
+ out[4] = (int)SCALE8_STAGE2(res);
+
+ MUL(res, -_anamatrix8[1], t[0]);
+ MULA(res, _anamatrix8[7], t[1]);
+ MULA(res, -_anamatrix8[4], t[2]);
+ MULA(res, _anamatrix8[2], t[3]);
+ MULA(res, -_anamatrix8[6], t[4]);
+ MULA(res, -_anamatrix8[5], t[5]);
+ MULA(res, _anamatrix8[0], t[6]);
+ MULA(res, -_anamatrix8[3], t[7]);
+ out[5] = (int)SCALE8_STAGE2(res);
+
+ MUL(res, _anamatrix8[1], t[0]);
+ MULA(res, _anamatrix8[7], t[1]);
+ MULA(res, -_anamatrix8[3], t[2]);
+ MULA(res, _anamatrix8[5], t[3]);
+ MULA(res, -_anamatrix8[6], t[4]);
+ MULA(res, _anamatrix8[2], t[5]);
+ MULA(res, -_anamatrix8[0], t[6]);
+ MULA(res, _anamatrix8[4], t[7]);
+ out[6] = (int)SCALE8_STAGE2(res);
+
+ MUL(res, _anamatrix8[0], t[0]);
+ MULA(res, _anamatrix8[7], t[1]);
+ MULA(res, -_anamatrix8[2], t[2]);
+ MULA(res, -_anamatrix8[3], t[3]);
+ MULA(res, _anamatrix8[6], t[4]);
+ MULA(res, -_anamatrix8[4], t[5]);
+ MULA(res, _anamatrix8[1], t[6]);
+ MULA(res, -_anamatrix8[5], t[7]);
+ out[7] = (int)SCALE8_STAGE2(res);
+}
+
+static __inline void sbc_analyze_eight(struct sbc_encoder_state *state,
+ struct sbc_frame *frame, int ch, int blk)
+{
+ int i;
+
+ /* Input 8 Audio Samples */
+ for (i = 79; i >= 8; i--)
+ state->X[ch][i] = state->X[ch][i - 8];
+ for (i = 7; i >= 0; i--)
+ state->X[ch][i] = frame->pcm_sample[ch][blk * 8 + (7 - i)];
+ _sbc_analyze_eight(state->X[ch], frame->sb_sample_f[blk][ch]);
+}
+
+static int sbc_analyze_audio(struct sbc_encoder_state *state, struct sbc_frame *frame)
+{
+ int ch, blk;
+
+ switch (frame->subbands)
+ {
+ case 4:
+ for (ch = 0; ch < frame->channels; ch++)
+ for (blk = 0; blk < frame->blocks; blk++) {
+ sbc_analyze_four(state, frame, ch, blk);
+ }
+ return frame->blocks * 4;
+
+ case 8:
+ for (ch = 0; ch < frame->channels; ch++)
+ for (blk = 0; blk < frame->blocks; blk++) {
+ sbc_analyze_eight(state, frame, ch, blk);
+ }
+ return frame->blocks * 8;
+
+ default:
+ return -EIO;
+ }
+}
+
+/*
+ * Packs the SBC frame from frame into the memory at data. At most len
+ * bytes will be used, should more memory be needed an appropriate
+ * error code will be returned. Returns the length of the packed frame
+ * on success or a negative value on error.
+ *
+ * The error codes are:
+ * -1 Not enough memory reserved
+ * -2 Unsupported sampling rate
+ * -3 Unsupported number of blocks
+ * -4 Unsupported number of subbands
+ * -5 Bitpool value out of bounds
+ * -99 not implemented
+ */
+
+static int sbc_pack_frame(uint8_t * data, struct sbc_frame *frame, size_t len)
+{
+ size_t produced;
+ /* Will copy the header parts for CRC-8 calculation here */
+ uint8_t crc_header[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ int crc_pos = 0;
+
+ uint8_t sf; /* Sampling frequency as temporary value for table lookup */
+
+ int ch, sb, blk, bit; /* channel, subband, block and bit counters */
+ int bits[2][8]; /* bits distribution */
+ int levels[2][8]; /* levels are derived from that */
+
+ u_int32_t scalefactor[2][8]; /* derived from frame->scale_factor */
+
+ if (len < 4)
+ {
+ return -1;
+ }
+
+ /* Clear first 4 bytes of data (that's the constant length part of the SBC header) */
+ memset(data, 0, 4);
+
+ data[0] = SBC_SYNCWORD;
+
+ if (frame->sampling_frequency == 16000)
+ {
+ data[1] |= (SBC_FS_16 & 0x03) << 6;
+ sf = SBC_FS_16;
+ }
+ else if (frame->sampling_frequency == 32000)
+ {
+ data[1] |= (SBC_FS_32 & 0x03) << 6;
+ sf = SBC_FS_32;
+ }
+ else if (frame->sampling_frequency == 44100)
+ {
+ data[1] |= (SBC_FS_44 & 0x03) << 6;
+ sf = SBC_FS_44;
+ }
+ else if (frame->sampling_frequency == 48000)
+ {
+ data[1] |= (SBC_FS_48 & 0x03) << 6;
+ sf = SBC_FS_48;
+ }
+ else
+ {
+ return -2;
+ }
+
+ switch (frame->blocks)
+ {
+ case 4:
+ data[1] |= (SBC_NB_4 & 0x03) << 4;
+ break;
+ case 8:
+ data[1] |= (SBC_NB_8 & 0x03) << 4;
+ break;
+ case 12:
+ data[1] |= (SBC_NB_12 & 0x03) << 4;
+ break;
+ case 15:
+ data[1] |= (SBC_NB_16 & 0x03) << 4;
+ break;
+ default:
+ return -3;
+ break;
+ }
+
+ data[1] |= (frame->channel_mode & 0x03) << 2;
+
+ data[1] |= (frame->allocation_method & 0x01) << 1;
+
+ switch (frame->subbands) {
+ case 4:
+ /* Nothing to do */
+ break;
+ case 8:
+ data[1] |= 0x01;
+ break;
+ default:
+ return -4;
+ break;
+ }
+
+ data[2] = frame->bitpool;
+ if (((frame->channel_mode == MONO || frame->channel_mode == DUAL_CHANNEL)
+ && frame->bitpool > 16 * frame->subbands)
+ || ((frame->channel_mode == STEREO || frame->channel_mode == JOINT_STEREO)
+ && frame->bitpool > 32 * frame->subbands)) {
+ return -5;
+ }
+
+ /* Can't fill in crc yet */
+
+ produced = 32;
+
+ // evan.
+ data[1] = 0x00;
+ data[2] = 0x00;
+
+ crc_header[0] = data[1];
+ crc_header[1] = data[2];
+ crc_pos = 16;
+
+
+ for (ch = 0; ch < frame->channels; ch++) {
+ for (sb = 0; sb < frame->subbands; sb++) {
+ frame->scale_factor[ch][sb] = 0;
+ scalefactor[ch][sb] = 2;
+ for (blk = 0; blk < frame->blocks; blk++) {
+ while (scalefactor[ch][sb] < (u_int32_t)fabs(frame->sb_sample_f[blk][ch][sb])) {
+ frame->scale_factor[ch][sb]++;
+ scalefactor[ch][sb] *= 2;
+ }
+ }
+ }
+ }
+
+ if (frame->channel_mode == JOINT_STEREO) {
+ int32_t sb_sample_j[16][2][7]; /* like frame->sb_sample but joint stereo */
+ u_int32_t scalefactor_j[2][7], scale_factor_j[2][7]; /* scalefactor and scale_factor in joint case */
+
+ /* Calculate joint stereo signal */
+ for (sb = 0; sb < frame->subbands - 1; sb++) {
+ for (blk = 0; blk < frame->blocks; blk++) {
+ sb_sample_j[blk][0][sb] = (frame->sb_sample_f[blk][0][sb] + frame->sb_sample_f[blk][1][sb]) >> 1;
+ sb_sample_j[blk][1][sb] = (frame->sb_sample_f[blk][0][sb] - frame->sb_sample_f[blk][1][sb]) >> 1;
+ }
+ }
+
+ /* calculate scale_factor_j and scalefactor_j for joint case */
+ for (ch = 0; ch < 2; ch++) {
+ for (sb = 0; sb < frame->subbands - 1; sb++) {
+ scale_factor_j[ch][sb] = 0;
+ scalefactor_j[ch][sb] = 2;
+ for (blk = 0; blk < frame->blocks; blk++) {
+ while (scalefactor_j[ch][sb] < (u_int32_t)fabs(sb_sample_j[blk][ch][sb])) {
+ scale_factor_j[ch][sb]++;
+ scalefactor_j[ch][sb] *= 2;
+ }
+ }
+ }
+ }
+
+ /* decide which subbands to join */
+ frame->join = 0;
+ for (sb = 0; sb < frame->subbands - 1; sb++) {
+ if ((scalefactor[0][sb] + scalefactor[1][sb]) >
+ (scalefactor_j[0][sb] + scalefactor_j[1][sb]) ) {
+ /* use joint stereo for this subband */
+ frame->join |= 1 << sb;
+ frame->scale_factor[0][sb] = scale_factor_j[0][sb];
+ frame->scale_factor[1][sb] = scale_factor_j[1][sb];
+ scalefactor[0][sb] = scalefactor_j[0][sb];
+ scalefactor[1][sb] = scalefactor_j[1][sb];
+ for (blk = 0; blk < frame->blocks; blk++) {
+ frame->sb_sample_f[blk][0][sb] = sb_sample_j[blk][0][sb];
+ frame->sb_sample_f[blk][1][sb] = sb_sample_j[blk][1][sb];
+ }
+ }
+ }
+
+ if (len * 8 < produced + frame->subbands)
+ return -1;
+
+ data[4] = 0;
+ for (sb = 0; sb < frame->subbands - 1; sb++) {
+ data[4] |= ((frame->join >> sb) & 0x01) << (7 - sb);
+ }
+ if (frame->subbands == 4) {
+ crc_header[crc_pos / 8] = data[4] & 0xf0;
+ } else {
+ crc_header[crc_pos / 8] = data[4];
+ }
+
+ produced += frame->subbands;
+ crc_pos += frame->subbands;
+ }
+
+ if (len * 8 < produced + (4 * frame->subbands * frame->channels))
+ return -1;
+
+ for (ch = 0; ch < frame->channels; ch++) {
+ for (sb = 0; sb < frame->subbands; sb++) {
+ if (produced % 8 == 0)
+ data[produced / 8] = 0;
+ data[produced / 8] |= ((frame->scale_factor[ch][sb] & 0x0F) << (4 - (produced % 8)));
+ crc_header[crc_pos / 8] |= ((frame->scale_factor[ch][sb] & 0x0F) << (4 - (crc_pos % 8)));
+
+ produced += 4;
+ crc_pos += 4;
+ }
+ }
+
+ data[3] = sbc_crc8(crc_header, crc_pos);
+
+
+
+ sbc_calculate_bits(frame, bits, sf);
+
+ for (ch = 0; ch < frame->channels; ch++) {
+ for (sb = 0; sb < frame->subbands; sb++) {
+ levels[ch][sb] = (1 << bits[ch][sb]) - 1;
+ }
+ }
+
+ for (blk = 0; blk < frame->blocks; blk++) {
+ for (ch = 0; ch < frame->channels; ch++) {
+ for (sb = 0; sb < frame->subbands; sb++) {
+ if (levels[ch][sb] > 0) {
+ frame->audio_sample[blk][ch][sb] =
+ (uint16_t) ((((frame->sb_sample_f[blk][ch][sb]*levels[ch][sb]) >> (frame->scale_factor[ch][sb] + 1)) +
+ levels[ch][sb]) >> 1);
+ } else {
+ frame->audio_sample[blk][ch][sb] = 0;
+ }
+ }
+ }
+ }
+
+ for (blk = 0; blk < frame->blocks; blk++) {
+ for (ch = 0; ch < frame->channels; ch++) {
+ for (sb = 0; sb < frame->subbands; sb++) {
+ if (bits[ch][sb] != 0) {
+ for (bit = 0; bit < bits[ch][sb]; bit++) {
+ int b; /* A bit */
+ if (produced > len * 8) {
+ return -1;
+ }
+ if (produced % 8 == 0) {
+ data[produced / 8] = 0;
+ }
+ b = ((frame->audio_sample[blk][ch][sb]) >> (bits[ch][sb] - bit -
+ 1)) & 0x01;
+ data[produced / 8] |= b << (7 - (produced % 8));
+ produced++;
+ }
+ }
+ }
+ }
+ }
+
+ if (produced % 8 != 0) {
+ produced += 8 - (produced % 8);
+ }
+
+ return (int)(produced / 8);
+}
+
+struct sbc_priv {
+ int init;
+ struct sbc_frame frame;
+ struct sbc_decoder_state dec_state;
+ struct sbc_encoder_state enc_state;
+};
+
+int sbc_init(sbc_t *sbc, unsigned long flags)
+{
+ if (!sbc)
+ return -EIO;
+
+ flags = flags;
+
+ memset(sbc, 0, sizeof(sbc_t));
+
+ sbc->priv = malloc(sizeof(struct sbc_priv) + SBC_ALIGN_MASK);
+ if (!sbc->priv)
+ return -ENOMEM;
+ memset(sbc->priv, 0, sizeof(struct sbc_priv));
+
+ sbc->rate = 16000;
+ sbc->channels = 1;
+ sbc->joint = 0;
+ sbc->subbands = 8;
+ sbc->blocks = 15;
+ sbc->bitpool = 26;
+
+ return 0;
+}
+
+int sbc_reinit(sbc_t *sbc, unsigned long flags)
+{
+ struct sbc_priv *priv;
+
+ if (!sbc || !sbc->priv)
+ return -EIO;
+
+ flags = flags;
+ priv = sbc->priv;
+
+ if (priv->init == 1)
+ memset(sbc->priv, 0, sizeof(struct sbc_priv));
+
+ return 0;
+}
+
+
+int sbc_decode(sbc_t *sbc, void *input, int input_len, void *output,
+ int output_len, int *written)
+{
+ struct sbc_priv *priv;
+ char *ptr;
+ int i, ch, framelen, samples;
+
+ if (!sbc)
+ {
+ //DbgPrint("Exit.when sbc is NULL.\n");
+ return -EIO;
+ }
+
+ if (!sbc && !input)
+ {
+ //DbgPrint("!sbc && !input\n");
+ return -EIO;
+ }
+
+ priv = sbc->priv;
+ if(!priv)
+ return -99;
+
+ framelen = sbc_unpack_frame(input, &priv->frame, input_len);
+
+ if (!priv->init)
+ {
+ sbc_decoder_init(&priv->dec_state, &priv->frame);
+ priv->init = 1;
+
+ sbc->rate = priv->frame.sampling_frequency;
+ sbc->channels = priv->frame.channels;
+ sbc->subbands = priv->frame.subbands;
+ sbc->blocks = priv->frame.blocks;
+ sbc->bitpool = priv->frame.bitpool;
+ }
+
+ if (!output)
+ {
+ //DbgPrint("!output\n");
+ return framelen;
+ }
+
+ if (written)
+ *written = 0;
+
+ if (framelen <= 0)
+ {
+ //DbgPrint("Exit when framelen <= 0\n");
+ return framelen;
+ }
+
+ samples = sbc_synthesize_audio(&priv->dec_state, &priv->frame);
+
+ ptr = output;
+ if (output_len < samples * priv->frame.channels * 2)
+ samples = output_len / (priv->frame.channels * 2);
+
+/*
+ if (!sbc->data)
+ {
+ sbc->size = samples * priv->frame.channels * 2;
+ sbc->data = malloc(sbc->size);
+ }
+
+
+ if (sbc->size < samples * priv->frame.channels * 2)
+ {
+ sbc->size = samples * priv->frame.channels * 2;
+ sbc->data = realloc(sbc->data, sbc->size);
+ }
+
+ if (!sbc->data)
+ {
+ sbc->size = 0;
+ return -ENOMEM;
+ }
+*/
+
+ for (i = 0; i < samples; i++)
+ {
+ for (ch = 0; ch < priv->frame.channels; ch++)
+ {
+ int16_t s;
+ s = priv->frame.pcm_sample[ch][i];
+ /*
+ *ptr++ = (s & 0xff00) >> 8;
+ *ptr++ = (s & 0x00ff);
+ */
+ *ptr++ = (s & 0x00ff);
+ *ptr++ = (s & 0xff00) >> 8;
+ }
+ }
+
+ if (written)
+ *written = samples * priv->frame.channels * 2;
+
+ return framelen;
+}
+
+int sbc_encode(sbc_t *sbc, void *input, int input_len, void *output,
+ int output_len, int *written)
+{
+ struct sbc_priv *priv;
+ char *ptr;
+ int i, ch, framelen, samples;
+
+ if (!sbc)
+ {
+ //DbgPrint("Exit, when !sbc.\n");
+ return -EIO;
+ }
+
+
+ if (!sbc && !input)
+ {
+ //DbgPrint("Exit, when !sbc && !input.\n");
+ return -EIO;
+ }
+
+ /// make sure sbc has been initialized
+ priv = sbc->priv;
+ if(priv == NULL){
+ //DbgPrint("priv == NULL\n");
+ return -EIO;
+ }
+
+ if (written)
+ *written = 0;
+
+ if (!priv->init)
+ {
+ //DbgPrint("Initial priv->frame ,when priv->init is null\n");
+ priv->frame.sampling_frequency = sbc->rate;
+ priv->frame.channels = sbc->channels;
+ priv->frame.channel_mode = MONO;
+ priv->frame.allocation_method = LOUDNESS;
+ priv->frame.subbands = sbc->subbands;
+ priv->frame.blocks = sbc->blocks;
+ priv->frame.bitpool = sbc->bitpool;
+
+ sbc_encoder_init(&priv->enc_state, &priv->frame);
+ priv->init = 1;
+ }
+
+ /* input must be large enough to encode a complete frame */
+ if (input_len < 240)
+ {
+ //DbgPrint("Exit, when input_len < priv->frame.codesize..\n");
+ return 0;
+ }
+
+ /* output must be large enough to receive the encoded frame */
+ if (!output || output_len < 57)
+ {
+ //DbgPrint("Exit, when !output || output_len < priv->frame.length\n");
+ return -ENOSPC;
+ }
+
+ ptr = input;
+ for (i = 0; i < priv->frame.subbands * priv->frame.blocks; i++)
+ {
+ for (ch = 0; ch < sbc->channels; ch++)
+ {
+ // int16_t s = (ptr[0] & 0xff) << 8 | (ptr[1] & 0xff);
+ int16_t s = (ptr[1] & 0xff) << 8 | (ptr[0] & 0xff);
+ ptr += 2;
+ priv->frame.pcm_sample[ch][i] = s;
+ }
+ }
+
+ samples = 0;
+ samples = sbc_analyze_audio(&priv->enc_state, &priv->frame);
+
+ if (!sbc->data)
+ {
+ sbc->size = 1024;
+// sbc->data = malloc(sbc->size);
+ sbc->data = malloc(sbc->size);
+ if (!sbc->data)
+ {
+ //DbgPrint("sbc->data allocate failed!!!\n");
+ return -ENOMEM;
+ }
+ memset(sbc->data, 0, sbc->size);
+ }
+
+ if (!sbc->data)
+ {
+ sbc->size = 0;
+ //DbgPrint("sbc->data is null, so exit!!!\n");
+ return -ENOMEM;
+ }
+
+ framelen = sbc_pack_frame(output, &priv->frame, output_len);
+ if (written)
+ {
+ *written = (int)framelen;//in 64 bit os, it should be okay.
+ }
+
+ sbc->len = framelen;
+ sbc->duration = (1000000 * priv->frame.subbands * priv->frame.blocks) / sbc->rate;
+
+ return samples * sbc->channels * 2;
+}
+
+
+void sbc_finish(sbc_t *sbc)
+{
+ if (!sbc)
+ return;
+
+ if (sbc->data)
+ free(sbc->data);
+
+
+ if (sbc->priv)
+ {
+ free(sbc->priv);
+ }
+ memset(sbc, 0, sizeof(sbc_t));
+}
diff --git a/addon/vr_bee1_hidraw_daemon/hidraw/msbc/msbc.h b/addon/vr_bee1_hidraw_daemon/hidraw/msbc/msbc.h
new file mode 100755
index 0000000..bd46bf6
--- /dev/null
+++ b/addon/vr_bee1_hidraw_daemon/hidraw/msbc/msbc.h
@@ -0,0 +1,79 @@
+/*
+ *
+ * Bluetooth low-complexity, subband codec (SBC) library
+ *
+ * Copyright (C) 2004-2006 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2004-2005 Henryk Ploetz <henryk@ploetzli.ch>
+ * Copyright (C) 2005-2006 Brad Midgley <bmidgley@xmission.com>
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef __SBC_H
+#define __SBC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+struct sbc_struct {
+ unsigned long flags;
+ unsigned short rate;
+ unsigned char channels;
+ unsigned char joint;
+ unsigned char blocks;
+ unsigned char subbands;
+ unsigned char bitpool;
+
+ void *data;
+ int size;
+ int len;
+
+ unsigned long duration;
+
+ void *priv;
+};
+
+typedef struct sbc_struct sbc_t;
+
+int sbc_init(sbc_t *sbc, unsigned long flags);
+
+int sbc_reinit(sbc_t *sbc, unsigned long flags);
+
+
+int sbc_encode(sbc_t *sbc,
+ void *input,
+ int input_len,
+ void *output,
+ int output_len,
+ int *written);
+
+int sbc_decode(sbc_t *sbc,
+ void *input,
+ int input_len,
+ void *output,
+ int output_len,
+ int *written);
+
+void sbc_finish(sbc_t *sbc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SBC_H */
diff --git a/addon/vr_bee1_hidraw_daemon/hidraw/msbc/msbc_math.h b/addon/vr_bee1_hidraw_daemon/hidraw/msbc/msbc_math.h
new file mode 100755
index 0000000..3ccadd8
--- /dev/null
+++ b/addon/vr_bee1_hidraw_daemon/hidraw/msbc/msbc_math.h
@@ -0,0 +1,70 @@
+/*
+ *
+ * Bluetooth low-complexity, subband codec (SBC) library
+ *
+ * Copyright (C) 2004-2006 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2004-2005 Henryk Ploetz <henryk@ploetzli.ch>
+ * Copyright (C) 2005-2006 Brad Midgley <bmidgley@xmission.com>
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#define fabs(x) ((x) < 0 ? -(x) : (x))
+/* C does not provide an explicit arithmetic shift right but this will
+ always be correct and every compiler *should* generate optimal code */
+#define ASR(val, bits) ((-2 >> 1 == -1) ? \
+ ((int32_t)(val)) >> (bits) : ((int32_t) (val)) / (1 << (bits)))
+#define ASR_64(val, bits) ((-2 >> 1 == -1) ? \
+ ((long long)(val)) >> (bits) : ((long long) (val)) / (1 << (bits)))
+
+#define SCALE_PROTO4_TBL 15
+#define SCALE_ANA4_TBL 16
+#define SCALE_PROTO8_TBL 15
+#define SCALE_ANA8_TBL 16
+#define SCALE_SPROTO4_TBL 16
+#define SCALE_SPROTO8_TBL 16
+#define SCALE_NPROTO4_TBL 10
+#define SCALE_NPROTO8_TBL 12
+#define SCALE_SAMPLES 14
+#define SCALE4_STAGE1_BITS 10
+#define SCALE4_STAGE2_BITS 21
+#define SCALE4_STAGED1_BITS 18
+#define SCALE4_STAGED2_BITS 23
+#define SCALE8_STAGE1_BITS 8
+#define SCALE8_STAGE2_BITS 24
+#define SCALE8_STAGED1_BITS 18
+#define SCALE8_STAGED2_BITS 23
+
+typedef int int32_t;
+typedef int32_t sbc_fixed_t;
+typedef long long sbc_extended_t;
+
+#define SCALE4_STAGE1(src) ASR_64(src, SCALE4_STAGE1_BITS)
+#define SCALE4_STAGE2(src) ASR_64(src, SCALE4_STAGE2_BITS)
+#define SCALE4_STAGED1(src) ASR_64(src, SCALE4_STAGED1_BITS)
+#define SCALE4_STAGED2(src) ASR_64(src, SCALE4_STAGED2_BITS)
+#define SCALE8_STAGE1(src) ASR_64(src, SCALE8_STAGE1_BITS)
+#define SCALE8_STAGE2(src) ASR_64(src, SCALE8_STAGE2_BITS)
+#define SCALE8_STAGED1(src) ASR_64(src, SCALE8_STAGED1_BITS)
+#define SCALE8_STAGED2(src) ASR_64(src, SCALE8_STAGED2_BITS)
+
+#define SBC_FIXED_0(val) { val = 0; }
+#define ADD(dst, src) { dst += src; }
+#define SUB(dst, src) { dst -= src; }
+#define MUL(dst, a, b) { dst = (sbc_extended_t) (a) * (b); }
+#define MULA(dst, a, b) { dst += (sbc_extended_t) (a) * (b); }
+#define DIV2(dst, src) { dst = ASR(src, 1); }
diff --git a/addon/vr_bee1_hidraw_daemon/hidraw/msbc/msbc_tables.h b/addon/vr_bee1_hidraw_daemon/hidraw/msbc/msbc_tables.h
new file mode 100755
index 0000000..98e8e43
--- /dev/null
+++ b/addon/vr_bee1_hidraw_daemon/hidraw/msbc/msbc_tables.h
@@ -0,0 +1,169 @@
+/*
+ *
+ * Bluetooth low-complexity, subband codec (SBC) library
+ *
+ * Copyright (C) 2004-2006 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2004-2005 Henryk Ploetz <henryk@ploetzli.ch>
+ * Copyright (C) 2005-2006 Brad Midgley <bmidgley@xmission.com>
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "msbc_math.h"
+
+/* A2DP specification: Appendix B, page 69 */
+static const int sbc_offset4[4][4] = {
+ { -1, 0, 0, 0 },
+ { -2, 0, 0, 1 },
+ { -2, 0, 0, 1 },
+ { -2, 0, 0, 1 }
+};
+
+/* A2DP specification: Appendix B, page 69 */
+static const int sbc_offset8[4][8] = {
+ { -2, 0, 0, 0, 0, 0, 0, 1 },
+ { -3, 0, 0, 0, 0, 0, 1, 2 },
+ { -4, 0, 0, 0, 0, 0, 1, 2 },
+ { -4, 0, 0, 0, 0, 0, 1, 2 }
+};
+
+#define SP4(val) ASR(val, SCALE_PROTO4_TBL)
+#define SA4(val) ASR(val, SCALE_ANA4_TBL)
+#define SP8(val) ASR(val, SCALE_PROTO8_TBL)
+#define SA8(val) ASR(val, SCALE_ANA8_TBL)
+#define SS4(val) ASR(val, SCALE_SPROTO4_TBL)
+#define SS8(val) ASR(val, SCALE_SPROTO8_TBL)
+#define SN4(val) ASR(val, SCALE_NPROTO4_TBL)
+#define SN8(val) ASR(val, SCALE_NPROTO8_TBL)
+
+static const int32_t _sbc_proto_4[20] = {
+ SP4(0x02cb3e8c), SP4(0x22b63dc0), SP4(0x002329cc), SP4(0x053b7548),
+ SP4(0x31eab940), SP4(0xec1f5e60), SP4(0xff3773a8), SP4(0x0061c5a7),
+ SP4(0x07646680), SP4(0x3f239480), SP4(0xf89f23a8), SP4(0x007a4737),
+ SP4(0x00b32807), SP4(0x083ddc80), SP4(0x4825e480), SP4(0x0191e578),
+ SP4(0x00ff11ca), SP4(0x00fb7991), SP4(0x069fdc58), SP4(0x4b584000)
+};
+
+static const int32_t _anamatrix4[4] = {
+ SA4(0x2d413cc0), SA4(0x3b20d780), SA4(0x40000000), SA4(0x187de2a0)
+};
+
+static const int32_t _sbc_proto_8[40] = {
+ SP8(0x02e5cd20), SP8(0x22d0c200), SP8(0x006bfe27), SP8(0x07808930),
+ SP8(0x3f1c8800), SP8(0xf8810d70), SP8(0x002cfdc6), SP8(0x055acf28),
+ SP8(0x31f566c0), SP8(0xebfe57e0), SP8(0xff27c437), SP8(0x001485cc),
+ SP8(0x041c6e58), SP8(0x2a7cfa80), SP8(0xe4c4a240), SP8(0xfe359e4c),
+ SP8(0x0048b1f8), SP8(0x0686ce30), SP8(0x38eec5c0), SP8(0xf2a1b9f0),
+ SP8(0xffe8904a), SP8(0x0095698a), SP8(0x0824a480), SP8(0x443b3c00),
+ SP8(0xfd7badc8), SP8(0x00d3e2d9), SP8(0x00c183d2), SP8(0x084e1950),
+ SP8(0x4810d800), SP8(0x017f43fe), SP8(0x01056dd8), SP8(0x00e9cb9f),
+ SP8(0x07d7d090), SP8(0x4a708980), SP8(0x0488fae8), SP8(0x0113bd20),
+ SP8(0x0107b1a8), SP8(0x069fb3c0), SP8(0x4b3db200), SP8(0x00763f48)
+};
+
+static const int32_t sbc_proto_4_40m0[] = {
+ SS4(0x00000000), SS4(0xffa6982f), SS4(0xfba93848), SS4(0x0456c7b8),
+ SS4(0x005967d1), SS4(0xfffb9ac7), SS4(0xff589157), SS4(0xf9c2a8d8),
+ SS4(0x027c1434), SS4(0x0019118b), SS4(0xfff3c74c), SS4(0xff137330),
+ SS4(0xf81b8d70), SS4(0x00ec1b8b), SS4(0xfff0b71a), SS4(0xffe99b00),
+ SS4(0xfef84470), SS4(0xf6fb4370), SS4(0xffcdc351), SS4(0xffe01dc7)
+};
+
+static const int32_t sbc_proto_4_40m1[] = {
+ SS4(0xffe090ce), SS4(0xff2c0475), SS4(0xf694f800), SS4(0xff2c0475),
+ SS4(0xffe090ce), SS4(0xffe01dc7), SS4(0xffcdc351), SS4(0xf6fb4370),
+ SS4(0xfef84470), SS4(0xffe99b00), SS4(0xfff0b71a), SS4(0x00ec1b8b),
+ SS4(0xf81b8d70), SS4(0xff137330), SS4(0xfff3c74c), SS4(0x0019118b),
+ SS4(0x027c1434), SS4(0xf9c2a8d8), SS4(0xff589157), SS4(0xfffb9ac7)
+};
+
+static const int32_t sbc_proto_8_80m0[] = {
+ SS8(0x00000000), SS8(0xfe8d1970), SS8(0xee979f00), SS8(0x11686100),
+ SS8(0x0172e690), SS8(0xfff5bd1a), SS8(0xfdf1c8d4), SS8(0xeac182c0),
+ SS8(0x0d9daee0), SS8(0x00e530da), SS8(0xffe9811d), SS8(0xfd52986c),
+ SS8(0xe7054ca0), SS8(0x0a00d410), SS8(0x006c1de4), SS8(0xffdba705),
+ SS8(0xfcbc98e8), SS8(0xe3889d20), SS8(0x06af2308), SS8(0x000bb7db),
+ SS8(0xffca00ed), SS8(0xfc3fbb68), SS8(0xe071bc00), SS8(0x03bf7948),
+ SS8(0xffc4e05c), SS8(0xffb54b3b), SS8(0xfbedadc0), SS8(0xdde26200),
+ SS8(0x0142291c), SS8(0xff960e94), SS8(0xff9f3e17), SS8(0xfbd8f358),
+ SS8(0xdbf79400), SS8(0xff405e01), SS8(0xff7d4914), SS8(0xff8b1a31),
+ SS8(0xfc1417b8), SS8(0xdac7bb40), SS8(0xfdbb828c), SS8(0xff762170)
+};
+
+static const int32_t sbc_proto_8_80m1[] = {
+ SS8(0xff7c272c), SS8(0xfcb02620), SS8(0xda612700), SS8(0xfcb02620),
+ SS8(0xff7c272c), SS8(0xff762170), SS8(0xfdbb828c), SS8(0xdac7bb40),
+ SS8(0xfc1417b8), SS8(0xff8b1a31), SS8(0xff7d4914), SS8(0xff405e01),
+ SS8(0xdbf79400), SS8(0xfbd8f358), SS8(0xff9f3e17), SS8(0xff960e94),
+ SS8(0x0142291c), SS8(0xdde26200), SS8(0xfbedadc0), SS8(0xffb54b3b),
+ SS8(0xffc4e05c), SS8(0x03bf7948), SS8(0xe071bc00), SS8(0xfc3fbb68),
+ SS8(0xffca00ed), SS8(0x000bb7db), SS8(0x06af2308), SS8(0xe3889d20),
+ SS8(0xfcbc98e8), SS8(0xffdba705), SS8(0x006c1de4), SS8(0x0a00d410),
+ SS8(0xe7054ca0), SS8(0xfd52986c), SS8(0xffe9811d), SS8(0x00e530da),
+ SS8(0x0d9daee0), SS8(0xeac182c0), SS8(0xfdf1c8d4), SS8(0xfff5bd1a)
+};
+
+static const int32_t _anamatrix8[8] = {
+ SA8(0x3b20d780), SA8(0x187de2a0), SA8(0x3ec52f80), SA8(0x3536cc40),
+ SA8(0x238e7680), SA8(0x0c7c5c20), SA8(0x2d413cc0), SA8(0x40000000)
+};
+
+static const int32_t synmatrix4[8][4] = {
+ { SN4(0x05a82798), SN4(0xfa57d868), SN4(0xfa57d868), SN4(0x05a82798) },
+ { SN4(0x030fbc54), SN4(0xf89be510), SN4(0x07641af0), SN4(0xfcf043ac) },
+ { SN4(0x00000000), SN4(0x00000000), SN4(0x00000000), SN4(0x00000000) },
+ { SN4(0xfcf043ac), SN4(0x07641af0), SN4(0xf89be510), SN4(0x030fbc54) },
+ { SN4(0xfa57d868), SN4(0x05a82798), SN4(0x05a82798), SN4(0xfa57d868) },
+ { SN4(0xf89be510), SN4(0xfcf043ac), SN4(0x030fbc54), SN4(0x07641af0) },
+ { SN4(0xf8000000), SN4(0xf8000000), SN4(0xf8000000), SN4(0xf8000000) },
+ { SN4(0xf89be510), SN4(0xfcf043ac), SN4(0x030fbc54), SN4(0x07641af0) }
+};
+
+static const int32_t synmatrix8[16][8] = {
+ { SN8(0x05a82798), SN8(0xfa57d868), SN8(0xfa57d868), SN8(0x05a82798),
+ SN8(0x05a82798), SN8(0xfa57d868), SN8(0xfa57d868), SN8(0x05a82798) },
+ { SN8(0x0471ced0), SN8(0xf8275a10), SN8(0x018f8b84), SN8(0x06a6d988),
+ SN8(0xf9592678), SN8(0xfe70747c), SN8(0x07d8a5f0), SN8(0xfb8e3130) },
+ { SN8(0x030fbc54), SN8(0xf89be510), SN8(0x07641af0), SN8(0xfcf043ac),
+ SN8(0xfcf043ac), SN8(0x07641af0), SN8(0xf89be510), SN8(0x030fbc54) },
+ { SN8(0x018f8b84), SN8(0xfb8e3130), SN8(0x06a6d988), SN8(0xf8275a10),
+ SN8(0x07d8a5f0), SN8(0xf9592678), SN8(0x0471ced0), SN8(0xfe70747c) },
+ { SN8(0x00000000), SN8(0x00000000), SN8(0x00000000), SN8(0x00000000),
+ SN8(0x00000000), SN8(0x00000000), SN8(0x00000000), SN8(0x00000000) },
+ { SN8(0xfe70747c), SN8(0x0471ced0), SN8(0xf9592678), SN8(0x07d8a5f0),
+ SN8(0xf8275a10), SN8(0x06a6d988), SN8(0xfb8e3130), SN8(0x018f8b84) },
+ { SN8(0xfcf043ac), SN8(0x07641af0), SN8(0xf89be510), SN8(0x030fbc54),
+ SN8(0x030fbc54), SN8(0xf89be510), SN8(0x07641af0), SN8(0xfcf043ac) },
+ { SN8(0xfb8e3130), SN8(0x07d8a5f0), SN8(0xfe70747c), SN8(0xf9592678),
+ SN8(0x06a6d988), SN8(0x018f8b84), SN8(0xf8275a10), SN8(0x0471ced0) },
+ { SN8(0xfa57d868), SN8(0x05a82798), SN8(0x05a82798), SN8(0xfa57d868),
+ SN8(0xfa57d868), SN8(0x05a82798), SN8(0x05a82798), SN8(0xfa57d868) },
+ { SN8(0xf9592678), SN8(0x018f8b84), SN8(0x07d8a5f0), SN8(0x0471ced0),
+ SN8(0xfb8e3130), SN8(0xf8275a10), SN8(0xfe70747c), SN8(0x06a6d988) },
+ { SN8(0xf89be510), SN8(0xfcf043ac), SN8(0x030fbc54), SN8(0x07641af0),
+ SN8(0x07641af0), SN8(0x030fbc54), SN8(0xfcf043ac), SN8(0xf89be510) },
+ { SN8(0xf8275a10), SN8(0xf9592678), SN8(0xfb8e3130), SN8(0xfe70747c),
+ SN8(0x018f8b84), SN8(0x0471ced0), SN8(0x06a6d988), SN8(0x07d8a5f0) },
+ { SN8(0xf8000000), SN8(0xf8000000), SN8(0xf8000000), SN8(0xf8000000),
+ SN8(0xf8000000), SN8(0xf8000000), SN8(0xf8000000), SN8(0xf8000000) },
+ { SN8(0xf8275a10), SN8(0xf9592678), SN8(0xfb8e3130), SN8(0xfe70747c),
+ SN8(0x018f8b84), SN8(0x0471ced0), SN8(0x06a6d988), SN8(0x07d8a5f0) },
+ { SN8(0xf89be510), SN8(0xfcf043ac), SN8(0x030fbc54), SN8(0x07641af0),
+ SN8(0x07641af0), SN8(0x030fbc54), SN8(0xfcf043ac), SN8(0xf89be510) },
+ { SN8(0xf9592678), SN8(0x018f8b84), SN8(0x07d8a5f0), SN8(0x0471ced0),
+ SN8(0xfb8e3130), SN8(0xf8275a10), SN8(0xfe70747c), SN8(0x06a6d988) }
+};
diff --git a/addon/vr_bee1_hidraw_daemon/hidraw/sbc/sbc.h b/addon/vr_bee1_hidraw_daemon/hidraw/sbc/sbc.h
new file mode 100755
index 0000000..af8021c
--- /dev/null
+++ b/addon/vr_bee1_hidraw_daemon/hidraw/sbc/sbc.h
@@ -0,0 +1,85 @@
+#ifndef _SBC_H_
+#define _SBC_H_
+
+/* defines */
+#define SBC_SUCCESS 0
+#define SBC_NOT_ENOUGH_DATA -1
+#define SBC_BUFFER_TOO_SMALL -2
+#define SBC_NO_SYNCBYTE -3
+#define SBC_CHECKSUM_ERROR -4
+
+#define SBC_SYNCBYTE 0x9c
+#define SBC_MAX_SUBBANDS 8
+#define SBC_MAX_CHANNELS 2
+#define SBC_TERMINATOR -1
+
+/* structs, typedefs */
+#define SBC_FREQU16000 0x0
+#define SBC_FREQU32000 0x1
+#define SBC_FREQU44100 0x2
+#define SBC_FREQU48000 0x3
+typedef unsigned short TSBCSamplingFrequency;
+
+#define SBC_BLOCKS4 0x0
+#define SBC_BLOCKS8 0x1
+#define SBC_BLOCKS12 0x2
+#define SBC_BLOCKS16 0x3
+typedef unsigned short TSBCBlockNumber;
+
+#define SBC_MODE_MONO 0x0
+#define SBC_MODE_DUAL 0x1
+#define SBC_MODE_STEREO 0x2
+#define SBC_MODE_JOINT 0x3
+typedef unsigned short TSBCChannelMode;
+
+#define SBC_ALLOCLOUDNESS 0x0
+#define SBC_ALLOCSNR 0x1
+typedef unsigned short TSBCAllocMethod;
+
+#define SBC_SUBBANDS4 0x0
+#define SBC_SUBBANDS8 0x1
+typedef unsigned short TSBCSubbandNumber;
+
+typedef struct tagSBCParams
+{
+ TSBCSamplingFrequency samplingFrequency;
+ TSBCBlockNumber blockNumber;
+ TSBCChannelMode channelMode;
+ TSBCAllocMethod allocMethod;
+ TSBCSubbandNumber subbandNumber;
+ unsigned char bitpool;
+} TSBCParams;
+
+typedef struct taglist TList;
+
+struct taglist
+ {
+ TList *pNext; /* next/first element */
+ TList *pPrevious; /* previous/last element */
+ };
+
+typedef TList * PList;
+#define LIST_IS_EMPTY(pList) ((pList)->pNext == pList)
+#define LIST_QUEUE_OUT(pList) (pList)->pNext; listRemove((pList)->pNext)
+
+void listInit ( PList pList );
+void listInsert( PList pElement, PList pDestinationList );
+void listRemove( PList pElement );
+void listMove ( PList pElement, PList pDestinationList );
+int listElementCount( PList pList );
+
+
+/* public sbc interface */
+void sbcInitEncoder(void); /* initializes internal buffers */
+int sbcEncode(unsigned char* inputBuffer, int inputSize, TSBCParams* params, unsigned char* outputBuffer, int* pOutputSize);
+/* returns number of processed input bytes; *pOutputSize contains number of output bytes */
+/* or required output buffer size */
+
+void sbcInitDecoder(void); /* initializes internal buffers */
+int sbcDecode(unsigned char* pInputBuffer, int inputSize, unsigned char* pOutputBuffer, int* pOutputSize);
+/* returns number of processed input bytes; *pOutputSize contains number of output bytes */
+/* or required output buffer size */
+int sbcGetParams(unsigned char* pInputBuffer, int inputSize, TSBCParams* pParams);
+/* fill TSBCParams with data or first SBC frame in pInputBuffer */
+
+#endif
diff --git a/addon/vr_bee1_hidraw_daemon/hidraw/sbc/sbcdec.c b/addon/vr_bee1_hidraw_daemon/hidraw/sbc/sbcdec.c
new file mode 100755
index 0000000..2c49690
--- /dev/null
+++ b/addon/vr_bee1_hidraw_daemon/hidraw/sbc/sbcdec.c
@@ -0,0 +1,1279 @@
+/******************************************************
+* Project : SBC
+* FileName : $RCSfile: sbcdec.c,v $
+* Created : April 2005
+* Version : $Revision: 1.10 $
+* Last access : $Date: 2005/10/27 06:06:23 $
+* Archive : $Source: /var/lib/cvs/sw/src/codec/sbc/sbcdec.c,v $
+* Copyright : (C) Stollmann E+V GmbH 2005
+* Author : Klaus Muehle (km@stollmann.de)
+* Compiler : ANSI C compatible
+* Environment : Windows NT 2000 user mode
+* Contents : implementation of SBC decoder
+* Note :
+* History :
+* : $Log: sbcdec.c,v $
+* : Revision 1.10 2005/10/27 06:06:23 lv
+* : fixed high level distortion problems
+* : various optimizations
+* : added sbcGetParams
+* :
+* : Revision 1.9 2005/10/26 08:06:40 jz
+* : moved constant data to "const" memory
+* :
+* : Revision 1.8 2005/07/28 10:14:54 jz
+* : Avoid castings
+* :
+* : Revision 1.7 2005/06/01 06:00:28 lv
+* : integrated internal headers
+* : fixed joint decoding bug
+* :
+* : Revision 1.6 2005/05/12 09:27:19 lv
+* : eliminated bracket warning
+* :
+* : Revision 1.5 2005/05/12 08:05:32 lv
+* : improved precision by using GUARD_HALFBIT
+* : non optimized fix for JOint distortion
+* :
+* : Revision 1.4 2005/04/27 07:58:17 lv
+* : changed internal sample representation from short to int
+* :
+* : Revision 1.3 2005/04/26 08:37:11 lv
+* : formatting
+* :
+* : Revision 1.2 2005/04/26 08:21:06 lv
+* : added crc creation
+* :
+* : Revision 1.1 2005/04/21 09:52:28 lv
+* : first checkin
+* :
+*******************************************************
+* sbcdec.c
+******************************************************/
+
+#if 1
+
+#include <string.h>
+#include <stdio.h>
+#include "sbc.h"
+
+
+
+/* arm compiler */
+#ifdef __arm
+# define INLINE __inline
+# define VALUE_IN_REGS __value_in_regs
+# define PURE
+#else
+# define INLINE
+# define VALUE_IN_REGS
+# define PURE
+#endif
+
+/* macros and types */
+#if !defined min
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#define limit(a) \
+ if (a > 1073709056)\
+ a = 1073709056;\
+ if (a < -1073741824)\
+ a = -1073741824;
+/* limit to 32767 << GUARD resp. -32768 << GUARD */
+
+/* sbc defines */
+#define GUARD 15
+#define GUARD_MINUS_2 13
+#define GUARD_HALFBIT 16384 /* must equal (1 << (GUARD - 1)) */
+
+
+/* structs, typedefs */
+typedef struct tagSBCData
+{
+ unsigned channel_mode;
+ unsigned allocation_method;
+ unsigned nrof_subbands;
+ unsigned nrof_blocks;
+ unsigned nrof_channels;
+ unsigned sampling_frequency; /* 0..3 */
+ int bitpool;
+ unsigned join;
+} TSBCData;
+
+typedef struct tagSampleData
+{
+ int bits;
+ int scale_factor;
+ int sb_sample;
+#if defined F_SBC_DEBUG_FILE
+ int qs;
+#endif
+} TSampleData;
+
+/* global variables */
+static TSBCData SBCData;
+static TSampleData sampleData[SBC_MAX_CHANNELS + 1][SBC_MAX_SUBBANDS]; /* one additional line for terminator */
+static int v[2][200]; /* size 200 instead of 160 for optimized pointer management */
+
+/* global constants */
+static const unsigned blockNumbers[4] = {4, 8, 12, 16};
+static const unsigned subbandNumbers[2] = {4, 8};
+static const int offset4[4][4] = {{-1, 0, 0, 0}, {-2, 0, 0, 1}, {-2, 0, 0, 1}, {-2, 0, 0, 1}};
+static const int offset8[4][8] = {{-2, 0, 0, 0, 0, 0, 0, 1}, {-3, 0, 0, 0, 0, 0, 1, 2}, {-4, 0, 0, 0, 0, 0, 1, 2}, {-4, 0, 0, 0, 0, 0, 1, 2}};
+
+static const int divTable[32] =
+{
+ 0, 65536, 43691, 37449, 34953, 33825, 33288, 33026,
+ 32897, 32832, 32800, 32784, 32776, 32772, 32770, 32769,
+ 32769, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
+ 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
+};
+
+static const signed char matrixingTable[20] =
+{
+ 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14, 17, 16, 19, 18, 1, 0
+};
+
+static const int d4[40] =
+{
+ 0, -70, -196, -358, -503, -510, -245, 401,
+ -1430, -2679, -3785, -4220, -3392, -804, 3778, 10177,
+ -17772, -25557, -32327, -36940, -38576, -36940, -32327, -25557,
+ 17772, 10177, 3778, -804, -3392, -4220, -3785, -2679,
+ 1430, 401, -245, -510, -503, -358, -196, -70,
+};
+
+static const int d8[80] =
+{
+ 0, -41, -90, -145, -527, -551, -523, -424,
+ -1484, -2105, -2742, -3342, -3391, -2322, -767, 1289,
+ -17826, -21754, -25579, -29150, -38523, -38113, -36898, -34934,
+ 17826, 13943, 10243, 6845, -3391, -4016, -4252, -4169,
+ 1484, 917, 432, 47, -527, -468, -387, -299,
+ -216, -299, -387, -468, -236, 47, 432, 917,
+ -3841, -4169, -4252, -4016, 3838, 6845, 10243, 13943,
+ -32313, -34934, -36898, -38113, -32313, -29150, -25579, -21754,
+ 3838, 1289, -767, -2322, -3841, -3342, -2742, -2105,
+ -236, -424, -523, -551, -216, -145, -90, -41,
+};
+
+static const int nik4[4][8] =
+{
+ 23170, 12540, 0, -12540, -23170, -30274, -32768, -30274,
+ -23170, -30274, 0, 30274, 23170, -12540, -32768, -12540,
+ -23170, 30274, 0, -30274, 23170, 12540, -32768, 12540,
+ 23170, -12540, 0, 12540, -23170, 30274, -32768, 30274,
+};
+
+static const int nik8[8][16] =
+{
+ 23170, 18205, 12540, 6393, 0, -6393, -12540, -18205, -23170, -32138, -30274, -18205, 0, 18205, 30274, 32138,
+ -23170, 6393, 30274, 27246, 0, -27246, -30274, -6393, 23170, 27246, -12540, -32138, 0, 32138, 12540, -27246,
+ 23170, -27246, -12540, 32138, 0, -32138, 12540, 27246, -23170, -6393, 30274, -27246, 0, 27246, -30274, 6393,
+ -23170, 32138, -30274, 18205, 0, -18205, 30274, -32138, 23170, -18205, 12540, -6393, 0, 6393, -12540, 18205,
+ -23170, -27246, -30274, -32138, -32768, -32138, -30274, -27246, 23170, 6393, -12540, -27246, -32768, -27246, -12540, 6393,
+ 23170, 32138, 12540, -18205, -32768, -18205, 12540, 32138, -23170, 18205, 30274, -6393, -32768, -6393, 30274, 18205,
+ -23170, -18205, 30274, 6393, -32768, 6393, 30274, -18205, 23170, -32138, 12540, 18205, -32768, 18205, 12540, -32138,
+ 23170, -6393, -12540, 27246, -32768, 27246, -12540, -6393, -23170, 27246, -30274, 32138, -32768, 32138, -30274, 27246,
+};
+
+static const unsigned char crcTable[256] =
+{
+ 0x00, 0x1D, 0x3A, 0x27, 0x74, 0x69, 0x4E, 0x53,
+ 0xE8, 0xF5, 0xD2, 0xCF, 0x9C, 0x81, 0xA6, 0xBB,
+ 0xCD, 0xD0, 0xF7, 0xEA, 0xB9, 0xA4, 0x83, 0x9E,
+ 0x25, 0x38, 0x1F, 0x02, 0x51, 0x4C, 0x6B, 0x76,
+ 0x87, 0x9A, 0xBD, 0xA0, 0xF3, 0xEE, 0xC9, 0xD4,
+ 0x6F, 0x72, 0x55, 0x48, 0x1B, 0x06, 0x21, 0x3C,
+ 0x4A, 0x57, 0x70, 0x6D, 0x3E, 0x23, 0x04, 0x19,
+ 0xA2, 0xBF, 0x98, 0x85, 0xD6, 0xCB, 0xEC, 0xF1,
+ 0x13, 0x0E, 0x29, 0x34, 0x67, 0x7A, 0x5D, 0x40,
+ 0xFB, 0xE6, 0xC1, 0xDC, 0x8F, 0x92, 0xB5, 0xA8,
+ 0xDE, 0xC3, 0xE4, 0xF9, 0xAA, 0xB7, 0x90, 0x8D,
+ 0x36, 0x2B, 0x0C, 0x11, 0x42, 0x5F, 0x78, 0x65,
+ 0x94, 0x89, 0xAE, 0xB3, 0xE0, 0xFD, 0xDA, 0xC7,
+ 0x7C, 0x61, 0x46, 0x5B, 0x08, 0x15, 0x32, 0x2F,
+ 0x59, 0x44, 0x63, 0x7E, 0x2D, 0x30, 0x17, 0x0A,
+ 0xB1, 0xAC, 0x8B, 0x96, 0xC5, 0xD8, 0xFF, 0xE2,
+ 0x26, 0x3B, 0x1C, 0x01, 0x52, 0x4F, 0x68, 0x75,
+ 0xCE, 0xD3, 0xF4, 0xE9, 0xBA, 0xA7, 0x80, 0x9D,
+ 0xEB, 0xF6, 0xD1, 0xCC, 0x9F, 0x82, 0xA5, 0xB8,
+ 0x03, 0x1E, 0x39, 0x24, 0x77, 0x6A, 0x4D, 0x50,
+ 0xA1, 0xBC, 0x9B, 0x86, 0xD5, 0xC8, 0xEF, 0xF2,
+ 0x49, 0x54, 0x73, 0x6E, 0x3D, 0x20, 0x07, 0x1A,
+ 0x6C, 0x71, 0x56, 0x4B, 0x18, 0x05, 0x22, 0x3F,
+ 0x84, 0x99, 0xBE, 0xA3, 0xF0, 0xED, 0xCA, 0xD7,
+ 0x35, 0x28, 0x0F, 0x12, 0x41, 0x5C, 0x7B, 0x66,
+ 0xDD, 0xC0, 0xE7, 0xFA, 0xA9, 0xB4, 0x93, 0x8E,
+ 0xF8, 0xE5, 0xC2, 0xDF, 0x8C, 0x91, 0xB6, 0xAB,
+ 0x10, 0x0D, 0x2A, 0x37, 0x64, 0x79, 0x5E, 0x43,
+ 0xB2, 0xAF, 0x88, 0x95, 0xC6, 0xDB, 0xFC, 0xE1,
+ 0x5A, 0x47, 0x60, 0x7D, 0x2E, 0x33, 0x14, 0x09,
+ 0x7F, 0x62, 0x45, 0x58, 0x0B, 0x16, 0x31, 0x2C,
+ 0x97, 0x8A, 0xAD, 0xB0, 0xE3, 0xFE, 0xD9, 0xC4
+};
+
+
+/* internal functions declarations */
+static void initVTab(int* v);
+
+static void processMatrixing4(const int* fnik, int* s, int* v, int iter);
+static void calcAudioSamples4(int* v, const int* d4, short* x, int mono, int channels);
+static void processMatrixing8(const int* nik, int* s, int* v, int iter);
+static void calcAudioSamples8(int* v, const int* d8, short* x, int iter, int mono, int channels);
+
+static int checkCRC(unsigned char* pInput);
+
+static void computeBits(void);
+static void computeSlicesInPoolStereo( int max_bitneed, int bitneed[SBC_MAX_CHANNELS][SBC_MAX_SUBBANDS]);
+
+/**
+* @brief init sbc decoder
+*
+* @param
+*
+* @return
+*
+*/
+void sbcInitDecoder(void)
+{
+ memset(&SBCData, 0, sizeof(SBCData));
+ memset(&v[0][0], 0, 2*200*4);
+ initVTab(v[0]);
+ initVTab(v[1]);
+}
+
+/**
+* @brief sbc decode
+*
+* @param pInputBuffer
+* @param inputSize
+* @param pOutputBuffer
+* @param pOutputSize
+*
+* @return
+*
+*/
+int sbcDecode(unsigned char* pInputBuffer, int inputSize, unsigned char* pOutputBuffer, int* pOutputSize)
+{
+ unsigned ch;
+ unsigned blk;
+ unsigned int c;
+ int frameSize;
+ TSBCData* pSBCData = &SBCData;
+ unsigned char* pIn = pInputBuffer;
+ unsigned char* pOut = pOutputBuffer;
+
+ /* read header */
+ c = *pIn++;
+ if (c != SBC_SYNCBYTE)
+ {
+ *pOutputSize = 0;
+ return SBC_NO_SYNCBYTE;
+ }
+
+ c = *pIn++;
+ pSBCData->sampling_frequency = (c >> 6) & 0x03;
+ pSBCData->nrof_blocks = blockNumbers[(c >> 4) & 0x03];
+ pSBCData->channel_mode = (c >> 2) & 0x03;
+ pSBCData->allocation_method = (c >> 1) & 0x01;
+ pSBCData->nrof_subbands = subbandNumbers[(c >> 0) & 0x01];
+ pSBCData->bitpool = *pIn++;
+ *pIn++; /* crc */
+ pSBCData->nrof_channels = pSBCData->channel_mode == SBC_MODE_MONO ? 1 : 2;
+
+ /* check for sufficient input data */
+ {
+ int sb, bb;
+ frameSize = 4;
+ sb = pSBCData->nrof_subbands;
+ bb = pSBCData->nrof_blocks * pSBCData->bitpool;
+
+ switch (pSBCData->channel_mode)
+ {
+ case SBC_MODE_MONO:
+ frameSize += (sb >>1 ) + (bb >> 3);
+ /* (bb)>>3 must be rounded towards plus infinity */
+ if (bb & 0x7)
+ frameSize++;
+ break;
+ case SBC_MODE_DUAL:
+ frameSize += sb + (bb >> 2);
+ break;
+ case SBC_MODE_STEREO:
+ frameSize += sb + (bb >> 3);
+ /* (bb)>>3 must be rounded towards plus infinity */
+ if (bb & 0x7)
+ frameSize++;
+ break;
+ case SBC_MODE_JOINT:
+ frameSize += sb + ((sb + bb) >> 3);
+ /* (sb + bb)>>3 must be rounded towards plus infinity */
+ if ((sb + bb) & 0x7)
+ frameSize++;
+ break;
+ }
+
+ if (inputSize < frameSize)
+ return SBC_NOT_ENOUGH_DATA;
+ }
+
+ /* check for sufficient output buffer size */
+ {
+ int ns = pSBCData->nrof_channels * pSBCData->nrof_blocks * pSBCData->nrof_subbands;
+
+ if (*pOutputSize < ns * 2)
+ {
+ *pOutputSize = ns;
+ return SBC_BUFFER_TOO_SMALL;
+ }
+ }
+
+ /* check checksum */
+ if (checkCRC(pInputBuffer) != 0)
+ {
+ *pOutputSize = 0;
+ return SBC_CHECKSUM_ERROR;
+ }
+
+ if (pSBCData->channel_mode == SBC_MODE_JOINT)
+ {
+ pSBCData->join = *pIn++;
+ /* filtering of join bits is not required if appropriate iteration is applied */
+ if (pSBCData->nrof_subbands == 4)
+ {
+ pSBCData->join &= 0xe0;
+ }
+ else
+ {
+ pSBCData->join &= 0xfe;
+ }
+ }
+
+ /* read scale factors */
+ {
+ TSampleData* pd = &sampleData[0][0];
+ if (pSBCData->nrof_subbands == 4)
+ {
+ if (pSBCData->channel_mode == SBC_MODE_JOINT)
+ {
+ /* data pointer adjustment required due to just 4 join bits in header */
+ for (ch = 2; ch > 0; ch--)
+ {
+ c = pIn[-1];
+ pd[0].scale_factor = c & 0x0f;
+ c = pIn[0];
+ pd[1].scale_factor = c >> 4;
+ pd[2].scale_factor = c & 0x0f;
+ c = pIn[1];
+ pd[3].scale_factor = c >> 4;
+ pd += 8;
+ pIn += 2;
+ }
+ } /* if joint */
+ else
+ {
+ for (ch = pSBCData->nrof_channels; ch > 0; ch--)
+ {
+ c = pIn[0];
+ pd[0].scale_factor = c >> 4;
+ pd[1].scale_factor = c & 0x0f;
+ c = pIn[1];
+ pd[2].scale_factor = c >> 4;
+ pd[3].scale_factor = c & 0x0f;
+ pd += 8;
+ pIn += 2;
+ }
+ }
+ } /* if 4 subbands */
+ else
+ {
+ for (ch = pSBCData->nrof_channels; ch > 0; ch--)
+ {
+ c = pIn[0];
+ pd[0].scale_factor = c >> 4;
+ pd[1].scale_factor = c & 0x0f;
+ c = pIn[1];
+ pd[2].scale_factor = c >> 4;
+ pd[3].scale_factor = c & 0x0f;
+ c = pIn[2];
+ pd[4].scale_factor = c >> 4;
+ pd[5].scale_factor = c & 0x0f;
+ c = pIn[3];
+ pd[6].scale_factor = c >> 4;
+ pd[7].scale_factor = c & 0x0f;
+ pd += 8;
+ pIn += 4;
+ }
+ }
+ }
+
+ computeBits();
+
+ {
+ int nrof_samples = pSBCData->nrof_channels * pSBCData->nrof_subbands;
+ TSampleData* pd = &sampleData[0][0];
+ int bits;
+ unsigned int acc = 0;
+ int resBits = 0;
+ int sb = 0;
+
+ if (pSBCData->nrof_subbands == 4)
+ {
+ if (pSBCData->channel_mode == SBC_MODE_JOINT)
+ {
+ /* data pointer adjustment required due to just 4 join bits in header */
+ resBits = 4;
+ acc = pIn[-1] & 0x0f;
+ }
+ }
+
+ if (pSBCData->nrof_channels == 2)
+ {
+ if (pSBCData->nrof_subbands == 4)
+ {
+ /* move TSampleData structs into one row within sampleData array */
+ memcpy(&pd[4], &pd[8], 4 * sizeof(TSampleData));
+ }
+ }
+
+ /* set terminator */
+ pd[nrof_samples].bits = SBC_TERMINATOR; /* terminator cannot be 1 because legal bit lengths of 1 may occur ! */
+
+ /* reconstruct frequency subband samples */
+ for (blk = pSBCData->nrof_blocks; blk > 0; blk--)
+ {
+ pd = &sampleData[0][0];
+ for (;;)
+ {
+ /* advantages of this loop optimizing:
+ - testing only done if bits != 0, i.e. for less than half of the iterations
+ - no updating of a loop variable
+ - no use of a register
+ - no entry test */
+ if ((bits = (*pd++).bits) != 0)
+ {
+ int qs;
+ int msk;
+ /* break on terminator */
+ if (bits < 0) /* arm assembler optimization; saves 3 cycles compared to bits == SBC_TERMINATOR ! */
+ break;
+ while (bits > resBits)
+ {
+ /* load 16 new bits into accumulator */
+ acc <<= 16;
+ acc |= *pIn++ << 8;
+ acc |= *pIn++;
+ resBits += 16;
+ }
+ resBits -= bits;
+ msk = (1 << bits) - 1;
+ qs = ((acc >> resBits) & msk);
+#if defined F_SBC_DEBUG_FILE
+ pd[-1].qs = qs;
+#endif
+ /* use value precomputed with divTable; this leads to a value guarded by GUARD + bits - scale_factor - 2 */
+ /* (msk >> 1) is a short form of (1 << (bits - ) - 1) */
+ pd[-1].sb_sample = ((qs - (msk >> 1)) * divTable[bits]) >> (GUARD_MINUS_2 + pd[-1].bits - pd[-1].scale_factor);
+ if (pd[-1].sb_sample < 0)
+ pd[-1].sb_sample++;
+
+ } /* if bits != 0 */
+ else
+ {
+#if defined F_SBC_DEBUG_FILE
+ pd[-1].qs = 0;
+#endif
+ pd[-1].sb_sample = 0;
+ }
+ } /* for samples */
+
+ /* decode joint samples */
+ if (pSBCData->channel_mode == SBC_MODE_JOINT)
+ {
+ int nsb;
+ pd = &sampleData[0][0];
+ nsb = pSBCData->nrof_subbands;
+ for (sb = nsb - 2; sb >= 0; sb--)
+ {
+ if (pSBCData->join & (0x80 >> sb))
+ {
+ int sbR = sb + nsb;
+ int temp = pd[sb].sb_sample;
+ pd[sb].sb_sample = temp + pd[sbR].sb_sample;
+ pd[sbR].sb_sample = temp - pd[sbR].sb_sample;
+ } /* if subband joint*/
+ } /* for sb */
+ } /* if joint */
+
+ /* reconstruct audio samples */
+ {
+ static int offset = 0;
+ int* pv;
+
+ if (offset <= 0)
+ offset = 180;
+ else
+ offset -= 20;
+
+ pv = &v[0][0] + offset;
+
+ if (pSBCData->nrof_subbands == 4)
+ {
+ processMatrixing4( &nik4[0][0], &sampleData[0][0].sb_sample, pv, pSBCData->nrof_channels);
+ calcAudioSamples4(pv, d4, (short*) pOut, pSBCData->channel_mode == SBC_MODE_MONO, pSBCData->nrof_channels);
+ }
+ else
+ {
+ processMatrixing8( &nik8[0][0], &sampleData[0][0].sb_sample, pv, pSBCData->nrof_channels);
+ calcAudioSamples8(pv, d8, (short*) pOut, 2, pSBCData->channel_mode == SBC_MODE_MONO, pSBCData->nrof_channels);
+ } /* if 4 subbands */
+
+ pOut += 2 * nrof_samples;
+
+#if defined F_SBC_DEBUG_FILE
+ {
+ int sb, nsb;
+ short* pAudio;
+ pAudio = (short*) pOut;
+ nsb = pSBCData->nrof_subbands;
+ pd = &sampleData[0][0];
+ for (sb = 0; sb < nsb; sb++)
+ {
+ printf("%d, %d, %u, %d, %d\n",
+ pd[sb].bits, pd[sb].scale_factor, pd[sb].qs, pd[sb].sb_sample, pAudio[sb * 2]);
+ printf("%d, %d, %u, %d, %d\n",
+ pd[sb+8].bits, pd[sb+nsb].scale_factor, pd[sb+nsb].qs, pd[sb+nsb].sb_sample, pAudio[sb * 2 + 1]);
+ }
+ }
+#endif
+
+ }
+ } /* for blk */
+
+ /* adjust read pointer */
+ if (resBits >= 8)
+ {
+ pIn--;
+ if (resBits >= 16)
+ pIn--;
+ }
+
+#if defined F_SBC_DEBUG_FILE
+ if (pIn - pInputBuffer != frameSize)
+ printf("! decoded bytes mismatch: frameSize %d, read %d\n", frameSize, (pIn - pInputBuffer));
+#endif
+
+ }
+
+ *pOutputSize = pOut - pOutputBuffer;
+ return (pIn - pInputBuffer);
+}
+
+/**
+* @brief initialize v array
+*
+* @param v
+*
+* @return
+*
+*/
+static void initVTab(int* v)
+{
+ int i;
+ for (i = 0; i < 20; i++)
+ {
+ v[10 * i + 4] = (int) &v[10 * matrixingTable[i]]; /**< set pointer to successor group, first 4 */
+ v[10 * i + 5 + 4] = (int) &v[10 * matrixingTable[i] + 5]; /**< set pointer to successor group, second 4 */
+ }
+}
+
+
+/******************************* checkCRC *******************************/
+/* */
+/************************************************************************/
+static int checkCRC(unsigned char* pInput)
+{
+ int bits = 0;
+ unsigned char data[11];
+ TSBCData* pSBCData = &SBCData;
+ unsigned readCRC = pInput[3];
+ unsigned crc = 0x0f;
+ int i;
+ unsigned octet;
+ int len = 2;
+
+ /* copy relevant data to local array */
+ memcpy(data, pInput + 1, len); /* first two bytes */
+ if (pSBCData->nrof_channels == 2)
+ len *= 2;
+ if (pSBCData->nrof_subbands == 8)
+ len *= 2;
+ if (pSBCData->channel_mode == SBC_MODE_JOINT)
+ len += 1;
+ memcpy(data + 2, pInput + 4, len); /* joint and scale bytes */
+ bits = len * 8; /* joint and scale bits */
+ if (len == 5)
+ bits -= 4; /* only 4 joint bits for 4 subbands */
+ bits += 16; /* header bits */
+
+ for (i = 0; i < bits / 8; i++)
+ crc = crcTable[crc ^ data[i]];
+
+ octet = data[i];
+ for (i = 0; i < bits % 8; i++)
+ {
+ char bit = ((octet ^ crc) & 0x80) >> 7;
+ crc = ((crc & 0x7f) << 1) ^ (bit ? 0x1d : 0);
+ octet = octet << 1;
+ }
+
+ if (crc != readCRC)
+ return - 1;
+
+ return 0;
+}
+
+
+/****************************** processMatrixing4 **************************/
+/**/
+/************************************************************************/
+static void processMatrixing4(const int* fnik, int* s, int* v, int iter)
+{
+ int i, si;
+ int v0, v1, v2, v3, v4, v5, v6, v7;
+ while (--iter >= 0) /* for one or two channels */
+ {
+ const int * nik = fnik;
+ v0 = v1 = v2 = v3 = v4 = v5 = v6 = v7 = GUARD_HALFBIT;
+ for (i = 0; i < 4; i++) /* iterate through samples */
+ {
+ int k = sizeof(TSampleData) / sizeof(int); /* size of TSampleData in units of 'short' */
+ si = s[i * k]; /* current frequency sample */
+ if (si) /* don't waste time on zero sample */
+ {
+ /* process 8 MACs */
+ v0 += *nik++ * si;
+ v1 += *nik++ * si;
+ v2 += *nik++ * si;
+ v3 += *nik++ * si;
+ v4 += *nik++ * si;
+ v5 += *nik++ * si;
+ v6 += *nik++ * si;
+ v7 += *nik++ * si;
+ } /* if (si) */
+ else
+ nik += 8;
+ } /* for i */
+ /* fill v array with MAC results */
+ *v++ = v0 >> GUARD;
+ *v++ = v1 >> GUARD;
+ *v++ = v2 >> GUARD;
+ *v++ = v3 >> GUARD;
+ v += 6; /* skip fields reserved for pointer management and for 8 subbands */
+ *v++ = v4 >> GUARD;
+ *v++ = v5 >> GUARD;
+ *v++ = v6 >> GUARD;
+ *v++ = v7 >> GUARD;
+ v += 6; /* skip fields reserved for pointer management and for 8 subbands */
+
+ /* adjust pointers for second channel */
+ v -= 20;
+ v += 200;
+ s += ((sizeof(TSampleData) / sizeof(int)) << 2);
+ } /* while iter */
+}
+
+
+/*************************** calcAudioSamples4 ****************************/
+/**/
+/************************************************************************/
+static void calcAudioSamples4(int* v, const int* d4, short* x, int mono, int channels)
+{
+ int* pv;
+ const int* pd;
+ int x0,x1,x2,x3;
+
+ while (--channels >= 0)
+ {
+ pd = d4;
+ pv = v;
+
+ x0 = *pd++ * pv[0] + GUARD_HALFBIT;
+ x1 = *pd++ * pv[1] + GUARD_HALFBIT;
+ x2 = *pd++ * pv[2] + GUARD_HALFBIT;
+ x3 = *pd++ * pv[3] + GUARD_HALFBIT;
+ pv = (int *)(pv[4]);
+ x0 += *pd++ * pv[0];
+ x1 += *pd++ * pv[1];
+ x2 += *pd++ * pv[2];
+ x3 += *pd++ * pv[3];
+ pv = (int *)(pv[4]);
+ x0 += *pd++ * pv[0];
+ x1 += *pd++ * pv[1];
+ x2 += *pd++ * pv[2];
+ x3 += *pd++ * pv[3];
+ pv = (int *)(pv[4]);
+ x0 += *pd++ * pv[0];
+ x1 += *pd++ * pv[1];
+ x2 += *pd++ * pv[2];
+ x3 += *pd++ * pv[3];
+ pv = (int *)(pv[4]);
+ x0 += *pd++ * pv[0];
+ x1 += *pd++ * pv[1];
+ x2 += *pd++ * pv[2];
+ x3 += *pd++ * pv[3];
+ pv = (int *)(pv[4]);
+ x0 += *pd++ * pv[0];
+ x1 += *pd++ * pv[1];
+ x2 += *pd++ * pv[2];
+ x3 += *pd++ * pv[3];
+ pv = (int *)(pv[4]);
+ x0 += *pd++ * pv[0];
+ x1 += *pd++ * pv[1];
+ x2 += *pd++ * pv[2];
+ x3 += *pd++ * pv[3];
+ pv = (int *)(pv[4]);
+ x0 += *pd++ * pv[0];
+ x1 += *pd++ * pv[1];
+ x2 += *pd++ * pv[2];
+ x3 += *pd++ * pv[3];
+ pv = (int *)(pv[4]);
+ x0 += *pd++ * pv[0];
+ x1 += *pd++ * pv[1];
+ x2 += *pd++ * pv[2];
+ x3 += *pd++ * pv[3];
+ pv = (int *)(pv[4]);
+ x0 += *pd++ * pv[0];
+ x1 += *pd++ * pv[1];
+ x2 += *pd++ * pv[2];
+ x3 += *pd++ * pv[3];
+
+ limit(x0);
+ limit(x1);
+ limit(x2);
+ limit(x3);
+
+ if (mono)
+ {
+ /* store result in every output byte */
+ x[0] = x0 >> GUARD;
+ x[1] = x1 >> GUARD;
+ x[2] = x2 >> GUARD;
+ x[3] = x3 >> GUARD;
+ }
+ else
+ {
+ /* store result in every second output byte */
+ x[0] = x0 >> GUARD;
+ x[2] = x1 >> GUARD;
+ x[4] = x2 >> GUARD;
+ x[6] = x3 >> GUARD;
+ }
+ x += 1; /* go from left to right channel */
+ v += 200; /* goto next v group */
+ } /* while channels */
+}
+
+
+/****************************** processMatrixing8 **************************/
+/**/
+/************************************************************************/
+static void processMatrixing8(const int* fnik, int* s, int* v, int iter)
+{
+ int i, si;
+ int v0, v1, v2, v3, v4, v5, v6, v7;
+ while (--iter >= 0) /* for one or two channels */
+ {
+ const int* nik = fnik;
+ v0 = v1 = v2 = v3 = v4 = v5 = v6 = v7 = GUARD_HALFBIT; /* using 8 registers for speed */
+ for (i = 0; i < 8; i++) /* iterate through samples */
+ {
+ int k = sizeof(TSampleData) / sizeof(int); /* size of TSampleData in units of 'int' */
+ si = s[i * k]; /* current frequency sample */
+ if (si) /* don't waste time on zero sample */
+ {
+ /* process 8 MACs */
+ v0 += *nik++ * si;
+ v1 += *nik++ * si;
+ v2 += *nik++ * si;
+ v3 += *nik++ * si;
+ v4 += *nik++ * si;
+ v5 += *nik++ * si;
+ v6 += *nik++ * si;
+ v7 += *nik++ * si;
+ } /* if (si) */
+ else
+ nik += 8;
+ } /* for i */
+
+ /* fill v array with MAC results */
+ *v++ = v0 >> GUARD;
+ *v++ = v1 >> GUARD;
+ *v++ = v2 >> GUARD;
+ *v++ = v3 >> GUARD;
+ v++; /* skip field reserved for pointer management */
+ *v++ = v4 >> GUARD;
+ *v++ = v5 >> GUARD;
+ *v++ = v6 >> GUARD;
+ *v++ = v7 >> GUARD;
+ v++; /* skip field reserved for pointer management */
+
+ /* process the second group of 8 v fields */
+ v0 = v1 = v2 = v3 = v4 = v5 = v6 = v7 = GUARD_HALFBIT;
+ for (i = 0; i < 8; i++)
+ {
+ int k = sizeof(TSampleData) / sizeof(int);
+ si = s[i * k];
+ if (si)
+ {
+ v0 += *nik++ * si;
+ v1 += *nik++ * si;
+ v2 += *nik++ * si;
+ v3 += *nik++ * si;
+ v4 += *nik++ * si;
+ v5 += *nik++ * si;
+ v6 += *nik++ * si;
+ v7 += *nik++ * si;
+ } /* if */
+ else
+ nik += 8;
+ } /* for */
+ *v++ = v0 >> GUARD;
+ *v++ = v1 >> GUARD;
+ *v++ = v2 >> GUARD;
+ *v++ = v3 >> GUARD;
+ v++;
+ *v++ = v4 >> GUARD;
+ *v++ = v5 >> GUARD;
+ *v++ = v6 >> GUARD;
+ *v++ = v7 >> GUARD;
+ v++;
+ /* adjust pointers for second channel */
+ v -= 20;
+ v += 200;
+ s += ((sizeof(TSampleData) / sizeof(int)) << 3);
+ } /* while iter */
+}
+
+
+/*************************** calcAudioSamples8 ****************************/
+/**/
+/************************************************************************/
+static void calcAudioSamples8(int* v, const int* d8, short* x, int iter, int mono, int channels)
+{
+ int* pv;
+ const int* pd;
+ int x0, x1, x2, x3;
+
+ while (--channels >= 0)
+ {
+ pd = d8;
+ pv = v;
+ while (--iter >= 0)
+ {
+ x0 = *pd++ * pv[0] + GUARD_HALFBIT;
+ x1 = *pd++ * pv[1] + GUARD_HALFBIT;
+ x2 = *pd++ * pv[2] + GUARD_HALFBIT;
+ x3 = *pd++ * pv[3] + GUARD_HALFBIT;
+ pv = (int *)(pv[4]);
+ x0 += *pd++ * pv[0];
+ x1 += *pd++ * pv[1];
+ x2 += *pd++ * pv[2];
+ x3 += *pd++ * pv[3];
+ pv = (int *)(pv[4]);
+ x0 += *pd++ * pv[0];
+ x1 += *pd++ * pv[1];
+ x2 += *pd++ * pv[2];
+ x3 += *pd++ * pv[3];
+ pv = (int *)(pv[4]);
+ x0 += *pd++ * pv[0];
+ x1 += *pd++ * pv[1];
+ x2 += *pd++ * pv[2];
+ x3 += *pd++ * pv[3];
+ pv = (int *)(pv[4]);
+ x0 += *pd++ * pv[0];
+ x1 += *pd++ * pv[1];
+ x2 += *pd++ * pv[2];
+ x3 += *pd++ * pv[3];
+ pv = (int *)(pv[4]);
+ x0 += *pd++ * pv[0];
+ x1 += *pd++ * pv[1];
+ x2 += *pd++ * pv[2];
+ x3 += *pd++ * pv[3];
+ pv = (int *)(pv[4]);
+ x0 += *pd++ * pv[0];
+ x1 += *pd++ * pv[1];
+ x2 += *pd++ * pv[2];
+ x3 += *pd++ * pv[3];
+ pv = (int *)(pv[4]);
+ x0 += *pd++ * pv[0];
+ x1 += *pd++ * pv[1];
+ x2 += *pd++ * pv[2];
+ x3 += *pd++ * pv[3];
+ pv = (int *)(pv[4]);
+ x0 += *pd++ * pv[0];
+ x1 += *pd++ * pv[1];
+ x2 += *pd++ * pv[2];
+ x3 += *pd++ * pv[3];
+ pv = (int *)(pv[4]);
+ x0 += *pd++ * pv[0];
+ x1 += *pd++ * pv[1];
+ x2 += *pd++ * pv[2];
+ x3 += *pd++ * pv[3];
+
+ limit(x0);
+ limit(x1);
+ limit(x2);
+ limit(x3);
+
+ if (mono)
+ {
+ /* store result in every output byte */
+ x[0] = x0 >> GUARD;
+ x[1] = x1 >> GUARD;
+ x[2] = x2 >> GUARD;
+ x[3] = x3 >> GUARD;
+ }
+ else
+ {
+ /* store result in every second output byte */
+ x[0] = x0 >> GUARD;
+ x[2] = x1 >> GUARD;
+ x[4] = x2 >> GUARD;
+ x[6] = x3 >> GUARD;
+ }
+ x += (mono ? 4 : 8); /* step to next group */
+ pv = v + 5;
+ } /* while iter */
+ x -= 16;
+ x += 1; /* go from left to right channel */
+ v += 200; /* goto next v group */
+ iter = 2;
+ } /* while channels */
+}
+
+
+/*************************** computeBits *********************************/
+/* this implementation has been taken directly from the specification */
+/************************************************************************/
+static void computeBits(void)
+{
+ int loudness;
+ int max_bitneed = 0;
+ unsigned ch;
+ unsigned sb;
+ int bitneed[SBC_MAX_CHANNELS][SBC_MAX_SUBBANDS];
+ TSBCData* pSBCData= &SBCData;
+
+ if (pSBCData->channel_mode == SBC_MODE_MONO || pSBCData->channel_mode == SBC_MODE_DUAL)
+ {
+ for (ch=0; ch < pSBCData->nrof_channels; ch++)
+ {
+ /* Mono and Dual_Channel Bit Allocation */
+ if (pSBCData->allocation_method == SBC_ALLOCSNR)
+ {
+ for (sb = 0; sb < pSBCData->nrof_subbands; sb++)
+ {
+ int b = bitneed[ch][sb] = sampleData[ch][sb].scale_factor;
+ if (max_bitneed < b)
+ max_bitneed = b;
+ }
+ }
+ else
+ {
+ for (sb = 0;sb < pSBCData->nrof_subbands; sb++)
+ {
+ if (sampleData[ch][sb].scale_factor == 0)
+ {
+ int b = bitneed[ch][sb] = -5;
+ if (max_bitneed < b)
+ max_bitneed = b;
+ }
+ else
+ {
+ if (pSBCData->nrof_subbands == 4)
+ {
+ loudness = sampleData[ch][sb].scale_factor - offset4[pSBCData->sampling_frequency][sb];
+ }
+ else
+ {
+ loudness = sampleData[ch][sb].scale_factor - offset8[pSBCData->sampling_frequency][sb];
+ }
+ if (loudness > 0)
+ {
+ bitneed[ch][sb] = loudness / 2;
+ if (max_bitneed < loudness / 2)
+ max_bitneed = loudness / 2;
+
+ }
+ else
+ {
+ bitneed[ch][sb] = loudness;
+ if (max_bitneed < loudness)
+ max_bitneed = loudness;
+ }
+ }
+ }
+ }
+
+ /* Next an iterative process finds out how many bitslices fit into the bitpool */
+ {
+ int bitcount = 0;
+ int slicecount = 0;
+ int bitslice = max_bitneed + 1; /* init just above the largest sf */
+ do
+ {
+ bitslice--;
+ bitcount += slicecount;
+ slicecount = 0;
+ for (sb = 0;sb < pSBCData->nrof_subbands; sb++)
+ {
+ if((bitneed[ch][sb] > bitslice + 1) && (bitneed[ch][sb] < bitslice + 16))
+ slicecount++;
+ else if(bitneed[ch][sb] == bitslice + 1)
+ slicecount += 2;
+ }
+ } while (bitcount + slicecount < pSBCData->bitpool);
+
+ if (bitcount + slicecount == pSBCData->bitpool)
+ {
+ bitcount += slicecount;
+ bitslice--;
+ }
+
+ /* Thereafter, bits are distributed until the last bitslice is reached */
+ for (sb=0;sb<pSBCData->nrof_subbands;sb++)
+ {
+ if(bitneed[ch][sb]<bitslice+2)
+ sampleData[ch][sb].bits=0;
+ else
+ sampleData[ch][sb].bits=min(bitneed[ch][sb]-bitslice,16);
+ }
+
+ /* The remaining bits are allocated starting at subband 0 */
+ sb=0;
+ while(bitcount < pSBCData->bitpool && sb < pSBCData->nrof_subbands)
+ {
+ if((sampleData[ch][sb].bits>=2)&&(sampleData[ch][sb].bits<16))
+ {
+ sampleData[ch][sb].bits++; bitcount++;
+ }
+ else
+ if((bitneed[ch][sb]==bitslice+1)&&(pSBCData->bitpool>bitcount+1))
+ {
+ sampleData[ch][sb].bits=2; bitcount+=2;
+ }
+ sb++;
+ }
+ sb=0;
+ while(bitcount < pSBCData->bitpool && sb < pSBCData->nrof_subbands)
+ {
+ if (sampleData[ch][sb].bits < 16)
+ {
+ sampleData[ch][sb].bits++;
+ bitcount++;
+ }
+ sb++;
+ }
+ }
+ } /* for ch */
+ } /* MONO and DUAL */
+ else
+ {
+ /* Stereo and Joint_Stereo Bit Allocation */
+ if (pSBCData->allocation_method == SBC_ALLOCSNR)
+ {
+ for (ch = 0;ch < 2; ch++)
+ {
+ for (sb = 0; sb < pSBCData->nrof_subbands; sb++)
+ {
+ int b = bitneed[ch][sb] = sampleData[ch][sb].scale_factor;
+ if (b > max_bitneed)
+ max_bitneed = b;
+ }
+ }
+ }
+ else
+ {
+ for (ch = 0;ch < 2; ch++)
+ {
+ for (sb=0;sb<pSBCData->nrof_subbands;sb++)
+ {
+ if (sampleData[ch][sb].scale_factor == 0)
+ {
+ bitneed[ch][sb] = -5;
+ if (max_bitneed < -5)
+ max_bitneed = -5;
+ }
+ else
+ {
+ if (pSBCData->nrof_subbands == 4)
+ {
+ loudness = sampleData[ch][sb].scale_factor - offset4[pSBCData->sampling_frequency][sb];
+ }
+ else
+ {
+ loudness = sampleData[ch][sb].scale_factor - offset8[pSBCData->sampling_frequency][sb];
+ }
+ if (loudness > 0)
+ {
+ bitneed[ch][sb] = (loudness >> 1);
+ if ((loudness >> 1) > max_bitneed)
+ max_bitneed = (loudness >> 1);
+ }
+ else
+ {
+ bitneed[ch][sb] = loudness;
+ if (max_bitneed < loudness)
+ max_bitneed = loudness;
+ }
+ }
+ }
+ }
+ }
+ /* Next an iterative process finds out how many bitslices fit into the bitpool */
+ computeSlicesInPoolStereo(max_bitneed, bitneed);
+ } /* Joint and Stereo Allocation */
+} /* computeBits */
+
+
+/*************************** computeSlicesInPoolStereo ******************/
+/* An iterative process finds out how many bitslices fit into the bitpool */
+/* The result is stored in the global array "bits" */
+/* this implementation has been taken directly from the specification */
+/************************************************************************/
+static void computeSlicesInPoolStereo( int max_bitneed, int bitneed[SBC_MAX_CHANNELS][SBC_MAX_SUBBANDS])
+{
+
+ int bitcount = 0;
+ int slicecount = 0;
+ int bitslice = max_bitneed + 1; /* init just above the largest sf */
+ int sb, ch;
+ TSBCData* pSBCData= &SBCData;
+ int bitpool = pSBCData->bitpool;
+ int nrof_subbands = pSBCData->nrof_subbands;
+
+ int* bn0 = bitneed[0];
+ int* bn1 = bitneed[1];
+
+ do
+ {
+ bitcount += slicecount;
+ slicecount = 0;
+
+ sb = nrof_subbands - 1;
+ do
+ {
+ int bitn;
+ /* channel 0 */
+ bitn = bn0[sb];
+ if((bitn >= bitslice) && (bitn < bitslice + 15))
+ slicecount++;
+ if(bitn == bitslice)
+ slicecount++;
+
+ /* channel 1 */
+ bitn = bn1[sb];
+ if((bitn >= bitslice) && (bitn < bitslice + 15))
+ slicecount++;
+ if(bitn == bitslice)
+ slicecount++;
+
+ } while (sb--);
+ bitslice--;
+ } while (bitcount + slicecount < bitpool);
+
+ if (bitcount + slicecount == bitpool)
+ {
+ bitcount += slicecount;
+ bitslice--;
+ }
+
+ /* Thereafter bits are distributed until the last bitslice is reached */
+ for (ch = 0; ch < 2; ch++)
+ {
+ for (sb=0;sb<nrof_subbands;sb++)
+ {
+ if(bitneed[ch][sb] < bitslice + 2)
+ sampleData[ch][sb].bits = 0;
+ else
+ sampleData[ch][sb].bits = min(bitneed[ch][sb] - bitslice, 16);
+ }
+ }
+
+ /* The remaining bits are allocated starting with subband 0 of the first channel */
+ {
+ unsigned ch = 0;
+ sb=0;
+ while(bitcount < pSBCData->bitpool && sb < (int)pSBCData->nrof_subbands)
+ {
+ if((sampleData[ch][sb].bits>=2)&&(sampleData[ch][sb].bits<16))
+ {
+ sampleData[ch][sb].bits++; bitcount++;
+ }
+ else if((bitneed[ch][sb]==bitslice+1)&&(pSBCData->bitpool>bitcount+1))
+ {
+ sampleData[ch][sb].bits=2; bitcount+=2;
+ }
+ if (ch == 1)
+ {
+ ch = 0;
+ sb++;
+ }
+ else
+ {
+ ch = 1;
+ }
+ }
+ ch=0;
+ sb=0;
+ while(bitcount < pSBCData->bitpool && sb < (int)pSBCData->nrof_subbands)
+ {
+ if (sampleData[ch][sb].bits < 16)
+ {
+ sampleData[ch][sb].bits++;
+ bitcount++;
+ }
+ if (ch == 1)
+ {
+ ch = 0;
+ sb++;
+ }
+ else
+ {
+ ch = 1;
+ }
+ }
+ }
+}
+
+/*************************** sbcGetParams ********************************/
+/**/
+/************************************************************************/
+int sbcGetParams(unsigned char* pInputBuffer, int inputSize, TSBCParams* pParams)
+{
+ unsigned int c;
+ unsigned char* pIn = pInputBuffer;
+
+ if (inputSize < 3)
+ return SBC_NOT_ENOUGH_DATA;
+
+ /* read header */
+ c = *pIn++;
+ if (c != SBC_SYNCBYTE)
+ return SBC_NO_SYNCBYTE;
+
+ c = *pIn++;
+ pParams->samplingFrequency = (c >> 6) & 0x03;
+ pParams->blockNumber = (c >> 4) & 0x03;
+ pParams->channelMode = (c >> 2) & 0x03;
+ pParams->allocMethod = (c >> 1) & 0x01;
+ pParams->subbandNumber = (c >> 0) & 0x01;
+ pParams->bitpool = *pIn++;
+
+ return SBC_SUCCESS;
+}
+
+#endif /*F_BT_MPA_A2DP_SINK*/
diff --git a/addon/vr_bee1_hidraw_daemon/hidraw/sbc/sbcenc.c b/addon/vr_bee1_hidraw_daemon/hidraw/sbc/sbcenc.c
new file mode 100755
index 0000000..17c7277
--- /dev/null
+++ b/addon/vr_bee1_hidraw_daemon/hidraw/sbc/sbcenc.c
@@ -0,0 +1,1705 @@
+/******************************************************
+* Project : SBC
+* FileName : $RCSfile: sbcenc.c,v $
+* Created : April 2005
+* Version : $Revision: 1.10 $
+* Last access : $Date: 2005/10/27 06:31:28 $
+* Archive : $Source: /var/lib/cvs/sw/src/codec/sbc/sbcenc.c,v $
+* Copyright : (C) Stollmann E+V GmbH 2005
+* Author : Lutz Vogelsang (lv@stollmann.de)
+* Compiler : ANSI C compatible
+* Environment : Windows NT 2000 user mode
+* Contents : implementation of SBC encoder
+* Note :
+* History :
+* : $Log: sbcenc.c,v $
+* : Revision 1.10 2005/10/27 06:31:28 lv
+* : corrected sample buffer size
+* :
+* : Revision 1.9 2005/10/27 06:06:34 lv
+* : fixed high level distortion problems
+* : various optimizations
+* :
+* : Revision 1.8 2005/10/26 08:06:40 jz
+* : moved constant data to "const" memory
+* :
+* : Revision 1.7 2005/07/07 08:37:34 jz
+* : Cosmetics
+* :
+* : Revision 1.6 2005/06/01 06:00:28 lv
+* : integrated internal headers
+* : fixed joint decoding bug
+* :
+* : Revision 1.5 2005/04/27 07:48:41 lv
+* : tiny optimizations
+* :
+* : Revision 1.4 2005/04/26 08:37:11 lv
+* : formatting
+* :
+* : Revision 1.3 2005/04/26 08:20:47 lv
+* : added 4 subband implementation, crc creation,
+* : joint mode
+* :
+* : Revision 1.2 2005/04/21 12:07:14 lv
+* : 4 subband encoding implemented
+* :
+* : Revision 1.1 2005/04/21 09:52:54 lv
+* : first checkin; 4 subbands not yet functional
+* :
+*******************************************************
+* sbcenc.c
+******************************************************/
+
+#include <flags.h>
+#if 1
+
+#include <string.h>
+#include <stdio.h>
+#include <sbc.h>
+
+
+
+/* arm compiler */
+#ifdef __arm
+# define INLINE __inline
+# define VALUE_IN_REGS __value_in_regs
+# define PURE
+#else
+# define INLINE
+# define VALUE_IN_REGS
+# define PURE
+#endif
+
+/* macros and types */
+#if !defined min
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#define limit(a) \
+ if (a > 32767)\
+ a = 32767;\
+ if (a < -32768)\
+ a = -32768;
+
+/* sbc defines */
+#define GUARD_QUANT 16
+#define GUARD_QUANT_HALFBIT 32768 /* must equal (1 << (GUARD_QUANT - 1)) */
+#define GUARD_PAR 17
+#define GUARD_PAR_HALFBIT 65536 /* must equal (1 << (GUARD_QUANT - 1)) */
+#define GUARD_SUB 15
+#define GUARD_SUB_HALFBIT 16384 /* must equal (1 << (GUARD_QUANT - 1)) */
+
+/*#define F_SBC_ENC_USE_FLOAT*/
+/* forces floating point arithmetic for debugging purposes */
+
+#if defined F_SBC_ENC_USE_FLOAT
+#if defined F_SBC_ENC_REUSE_INPUT_BUFFER
+#undef F_SBC_ENC_REUSE_INPUT_BUFFER
+#endif
+#endif
+
+
+/* structs, typedefs */
+typedef struct tagSBCData
+{
+ unsigned channel_mode;
+ unsigned allocation_method;
+ unsigned nrof_subbands;
+ unsigned nrof_blocks;
+ unsigned nrof_channels;
+ unsigned sampling_frequency; /* 0..3 */
+ int bitpool;
+} TSBCData;
+
+typedef struct tagSampleData
+{
+ int bits;
+ int scale_factor;
+ int calc1;
+ int calc2;
+#if defined F_SBC_DEBUG_FILE
+ int sb_sample;
+ unsigned qs;
+#endif
+} TSampleData;
+
+/* global variables */
+static TSBCData SBCData;
+static TSampleData sampleData[SBC_MAX_CHANNELS + 1][SBC_MAX_SUBBANDS]; /* one additional line for terminator */
+static TSampleData jointSampleData[SBC_MAX_CHANNELS + 1][SBC_MAX_SUBBANDS];
+static unsigned x[SBC_MAX_CHANNELS][(SBC_MAX_SUBBANDS + 1) * 11];
+static unsigned y[SBC_MAX_CHANNELS][SBC_MAX_SUBBANDS * 2];
+
+#if !defined F_SBC_ENC_REUSE_INPUT_BUFFER
+static int samples[256];
+#endif
+
+#if defined F_SBC_ENC_USE_FLOAT
+static int X[2][80] = {0};
+static double Z[2][80] = {0.0};
+static double Y[2][16] = {0.0};
+static double S[2][16] = {0.0};
+#endif
+
+/* global constants */
+static const unsigned blockNumbers[4] = {4, 8, 12, 16};
+static const unsigned subbandNumbers[2] = {4, 8};
+static const char matrixingTable[11] = {18, 27, 36, 45, 54, 63, 72, 81, 0, 9, 18};
+static const int offset4[4][4] = {{-1,0,0,0},{-2,0,0,1},{-2,0,0,1},{-2,0,0,1}};
+static const int offset8[4][8] = {{-2,0,0,0,0,0,0,1},{-3,0,0,0,0,0,1,2},{-4,0,0,0,0,0,1,2},{-4,0,0,0,0,0,1,2}};
+
+static const int c4[40] =
+{
+ /* ik iteration 2 * 5 groups @ 4 */
+ 0, 70, 196, 358, 1430, 2679, 3785, 4220,
+ 17772, 25557, 32327, 36940, -17772, -10177, -3778, 804,
+ -1430, -401, 245, 510, 503, 510, 245, -401,
+ 3392, 804, -3778, -10177, 38576, 36940, 32327, 25557,
+ 3392, 4220, 3785, 2679, 503, 358, 196, 70,
+};
+
+static const int c8[80] =
+{
+ /* ik iteration 2 * 5 groups @ 8 */
+ 0, 21, 45, 73, 108, 149, 194, 234,
+ 742, 1052, 1371, 1671, 1921, 2085, 2126, 2008,
+ 8913, 10877, 12789, 14575, 16157, 17467, 18449, 19057,
+ -8913, -6971, -5122, -3422, -1919, -644, 383, 1161,
+ -742, -458, -216, -23, 118, 212, 261, 276,
+ 264, 276, 261, 212, 118, -23, -216, -458,
+ 1696, 1161, 383, -644, -1919, -3422, -5122, -6971,
+ 19262, 19057, 18449, 17467, 16157, 14575, 12789, 10877,
+ 1696, 2008, 2126, 2085, 1921, 1671, 1371, 1052,
+ 264, 234, 194, 149, 108, 73, 45, 21,
+};
+
+static const int mik4[4][8] =
+{
+ 23170, 30274, 32768, 30274, 23170, 12540, 0, -12540,
+ -23170, 12540, 32768, 12540, -23170, -30274, 0, 30274,
+ -23170, -12540, 32768, -12540, -23170, 30274, 0, -30274,
+ 23170, -30274, 32768, -30274, 23170, -12540, 0, 12540,
+};
+
+static const int mik8[8][16] =
+{
+ 23170, 27246, 30274, 32138, 32768, 32138, 30274, 27246, 23170, 18205, 12540, 6393, 0, -6393, -12540, -18205,
+ -23170, -6393, 12540, 27246, 32768, 27246, 12540, -6393, -23170, -32138, -30274, -18205, 0, 18205, 30274, 32138,
+ -23170, -32138, -12540, 18205, 32768, 18205, -12540, -32138, -23170, 6393, 30274, 27246, 0, -27246, -30274, -6393,
+ 23170, -18205, -30274, 6393, 32768, 6393, -30274, -18205, 23170, 27246, -12540, -32138, 0, 32138, 12540, -27246,
+ 23170, 18205, -30274, -6393, 32768, -6393, -30274, 18205, 23170, -27246, -12540, 32138, 0, -32138, 12540, 27246,
+ -23170, 32138, -12540, -18205, 32768, -18205, -12540, 32138, -23170, -6393, 30274, -27246, 0, 27246, -30274, 6393,
+ -23170, 6393, 12540, -27246, 32768, -27246, 12540, 6393, -23170, 32138, -30274, 18205, 0, -18205, 30274, -32138,
+ 23170, -27246, 30274, -32138, 32768, -32138, 30274, -27246, 23170, -18205, 12540, -6393, 0, 6393, -12540, 18205,
+};
+
+static const unsigned char crcTable[256] =
+{
+ 0x00, 0x1D, 0x3A, 0x27, 0x74, 0x69, 0x4E, 0x53,
+ 0xE8, 0xF5, 0xD2, 0xCF, 0x9C, 0x81, 0xA6, 0xBB,
+ 0xCD, 0xD0, 0xF7, 0xEA, 0xB9, 0xA4, 0x83, 0x9E,
+ 0x25, 0x38, 0x1F, 0x02, 0x51, 0x4C, 0x6B, 0x76,
+ 0x87, 0x9A, 0xBD, 0xA0, 0xF3, 0xEE, 0xC9, 0xD4,
+ 0x6F, 0x72, 0x55, 0x48, 0x1B, 0x06, 0x21, 0x3C,
+ 0x4A, 0x57, 0x70, 0x6D, 0x3E, 0x23, 0x04, 0x19,
+ 0xA2, 0xBF, 0x98, 0x85, 0xD6, 0xCB, 0xEC, 0xF1,
+ 0x13, 0x0E, 0x29, 0x34, 0x67, 0x7A, 0x5D, 0x40,
+ 0xFB, 0xE6, 0xC1, 0xDC, 0x8F, 0x92, 0xB5, 0xA8,
+ 0xDE, 0xC3, 0xE4, 0xF9, 0xAA, 0xB7, 0x90, 0x8D,
+ 0x36, 0x2B, 0x0C, 0x11, 0x42, 0x5F, 0x78, 0x65,
+ 0x94, 0x89, 0xAE, 0xB3, 0xE0, 0xFD, 0xDA, 0xC7,
+ 0x7C, 0x61, 0x46, 0x5B, 0x08, 0x15, 0x32, 0x2F,
+ 0x59, 0x44, 0x63, 0x7E, 0x2D, 0x30, 0x17, 0x0A,
+ 0xB1, 0xAC, 0x8B, 0x96, 0xC5, 0xD8, 0xFF, 0xE2,
+ 0x26, 0x3B, 0x1C, 0x01, 0x52, 0x4F, 0x68, 0x75,
+ 0xCE, 0xD3, 0xF4, 0xE9, 0xBA, 0xA7, 0x80, 0x9D,
+ 0xEB, 0xF6, 0xD1, 0xCC, 0x9F, 0x82, 0xA5, 0xB8,
+ 0x03, 0x1E, 0x39, 0x24, 0x77, 0x6A, 0x4D, 0x50,
+ 0xA1, 0xBC, 0x9B, 0x86, 0xD5, 0xC8, 0xEF, 0xF2,
+ 0x49, 0x54, 0x73, 0x6E, 0x3D, 0x20, 0x07, 0x1A,
+ 0x6C, 0x71, 0x56, 0x4B, 0x18, 0x05, 0x22, 0x3F,
+ 0x84, 0x99, 0xBE, 0xA3, 0xF0, 0xED, 0xCA, 0xD7,
+ 0x35, 0x28, 0x0F, 0x12, 0x41, 0x5C, 0x7B, 0x66,
+ 0xDD, 0xC0, 0xE7, 0xFA, 0xA9, 0xB4, 0x93, 0x8E,
+ 0xF8, 0xE5, 0xC2, 0xDF, 0x8C, 0x91, 0xB6, 0xAB,
+ 0x10, 0x0D, 0x2A, 0x37, 0x64, 0x79, 0x5E, 0x43,
+ 0xB2, 0xAF, 0x88, 0x95, 0xC6, 0xDB, 0xFC, 0xE1,
+ 0x5A, 0x47, 0x60, 0x7D, 0x2E, 0x33, 0x14, 0x09,
+ 0x7F, 0x62, 0x45, 0x58, 0x0B, 0x16, 0x31, 0x2C,
+ 0x97, 0x8A, 0xAD, 0xB0, 0xE3, 0xFE, 0xD9, 0xC4
+};
+
+#if defined F_SBC_ENC_USE_FLOAT
+static const double MIK[8][16] =
+{
+ 0.707106781, 0.831469612, 0.923879533, 0.98078528, 1, 0.98078528, 0.923879533, 0.831469612, 0.707106781, 0.555570233, 0.382683432, 0.195090322, 0.0, -0.195090322, -0.382683432, -0.555570233,
+ -0.707106781, -0.195090322, 0.382683432, 0.831469612, 1, 0.831469612, 0.382683432, -0.195090322, -0.707106781, -0.98078528, -0.923879533, -0.555570233, 0.0, 0.555570233, 0.923879533, 0.98078528,
+ -0.707106781, -0.98078528, -0.382683432, 0.555570233, 1, 0.555570233, -0.382683432, -0.98078528, -0.707106781, 0.195090322, 0.923879533, 0.831469612, 0.0, -0.831469612, -0.923879533, -0.195090322,
+ 0.707106781, -0.555570233, -0.923879533, 0.195090322, 1, 0.195090322, -0.923879533, -0.555570233, 0.707106781, 0.831469612, -0.382683432, -0.98078528, 0.0, 0.98078528, 0.382683432, -0.831469612,
+ 0.707106781, 0.555570233, -0.923879533, -0.195090322, 1, -0.195090322, -0.923879533, 0.555570233, 0.707106781, -0.831469612, -0.382683432, 0.98078528, 0.0, -0.98078528, 0.382683432, 0.831469612,
+ -0.707106781, 0.98078528, -0.382683432, -0.555570233, 1, -0.555570233, -0.382683432, 0.98078528, -0.707106781, -0.195090322, 0.923879533, -0.831469612, 0.0, 0.831469612, -0.923879533, 0.195090322,
+ -0.707106781, 0.195090322, 0.382683432, -0.831469612, 1, -0.831469612, 0.382683432, 0.195090322, -0.707106781, 0.98078528, -0.923879533, 0.555570233, 0.0, -0.555570233, 0.923879533, -0.98078528,
+ 0.707106781, -0.831469612, 0.923879533, -0.98078528, 1, -0.98078528, 0.923879533, -0.831469612, 0.707106781, -0.555570233, 0.382683432, -0.195090322, 0.0, 0.195090322, -0.382683432, 0.555570233,
+};
+
+static const double C[80] =
+{
+ 0.00000000E+00, 1.56575398E-04, 3.43256425E-04, 5.54620202E-04,
+ 8.23919506E-04, 1.13992507E-03, 1.47640169E-03, 1.78371725E-03,
+ 2.01182542E-03, 2.10371989E-03, 1.99454554E-03, 1.61656283E-03,
+ 9.02154502E-04, -1.78805361E-04, -1.64973098E-03, -3.49717454E-03,
+ 5.65949473E-03, 8.02941163E-03, 1.04584443E-02, 1.27472335E-02,
+ 1.46525263E-02, 1.59045603E-02, 1.62208471E-02, 1.53184106E-02,
+ 1.29371806E-02, 8.85757540E-03, 2.92408442E-03, -4.91578024E-03,
+ -1.46404076E-02, -2.61098752E-02, -3.90751381E-02, -5.31873032E-02,
+ 6.79989431E-02, 8.29847578E-02, 9.75753918E-02, 1.11196689E-01,
+ 1.23264548E-01, 1.33264415E-01, 1.40753505E-01, 1.45389847E-01,
+ 1.46955068E-01, 1.45389847E-01, 1.40753505E-01, 1.33264415E-01,
+ 1.23264548E-01, 1.11196689E-01, 9.75753918E-02, 8.29847578E-02,
+ -6.79989431E-02, -5.31873032E-02, -3.90751381E-02, -2.61098752E-02,
+ -1.46404076E-02, -4.91578024E-03, 2.92408442E-03, 8.85757540E-03,
+ 1.29371806E-02, 1.53184106E-02, 1.62208471E-02, 1.59045603E-02,
+ 1.46525263E-02, 1.27472335E-02, 1.04584443E-02, 8.02941163E-03,
+ -5.65949473E-03, -3.49717454E-03, -1.64973098E-03, -1.78805361E-04,
+ 9.02154502E-04, 1.61656283E-03, 1.99454554E-03, 2.10371989E-03,
+ 2.01182542E-03, 1.78371725E-03, 1.47640169E-03, 1.13992507E-03,
+ 8.23919506E-04, 5.54620202E-04, 3.43256425E-04, 1.56575398E-04,
+};
+#endif
+
+/* internal functions declarations */
+static void initXTab(int* pTab);
+
+static void calcPartials4(int* pAudio, const int* pFactors, int channels, int* pMatrix);
+static void createSubbandSamples4(int* pMatrix, const int* pFactors, int channels, int* pSamples, TSampleData* pSampleData);
+static void calcPartials8(int* pAudio, const int* pFactors, int channels, int* pMatrix);
+static void createSubbandSamples8(int* pMatrix, const int* pFactors, int channels, int* pSamples, TSampleData* pSampleData);
+static void joinSubbands4(int* pSamples, TSBCData* pSBCData, TSampleData* pSampleData, unsigned char* pJoint);
+static void joinSubbands8(int* pSamples, TSBCData* pSBCData, TSampleData* pSampleData, unsigned char* pJoint);
+
+static void createCRC(unsigned char* pOutput);
+
+static void computeBits(void);
+static void computeSlicesInPoolStereo( int max_bitneed, int bitneed[SBC_MAX_CHANNELS][SBC_MAX_SUBBANDS]);
+
+#if defined F_SBC_DEBUG_FILE
+static void dumpXTab(int* pTab);
+static void dumpYTab(int* pTab);
+static void dumpSampleData(TSampleData* pTab);
+static void dumpInputBuffer(short* pBuffer, int index);
+#endif
+
+/***************************** sbcInit ************************************/
+/**/
+/************************************************************************/
+void sbcInitEncoder(void)
+{
+ initXTab(&x[0][0]);
+}
+
+/**************************** sbcEncode **********************************/
+/**/
+/************************************************************************/
+int sbcEncode(unsigned char* pInputBuffer, int inputSize, TSBCParams* params, unsigned char* pOutputBuffer, int* pOutputSize)
+{
+ int blk;
+ TSBCData* pSBCData = &SBCData;
+ unsigned char* pScaleFactors;
+ unsigned char* pJoint;
+ unsigned char* pCRC;
+ int frameSize;
+ int reqInSize;
+ TSampleData* pSampleData = &sampleData[0][0];
+ unsigned char* pOut = pOutputBuffer;
+ short* pIn = (short*) pInputBuffer;
+#if defined F_SBC_ENC_REUSE_INPUT_BUFFER
+ short* pSamples;
+#else
+ int* pSamples;
+#endif
+
+ /* transfer public params to internal values */
+ pSBCData->sampling_frequency = (unsigned) params->samplingFrequency;
+ pSBCData->nrof_blocks = blockNumbers[params->blockNumber];
+ pSBCData->channel_mode = params->channelMode;
+ pSBCData->nrof_channels = (params->channelMode == SBC_MODE_MONO) ? 1 : 2;
+ pSBCData->allocation_method = params->allocMethod;
+ pSBCData->nrof_subbands = subbandNumbers[params->subbandNumber];
+ pSBCData->bitpool = params->bitpool;
+
+ /* check for sufficient input buffer size */
+ reqInSize = pSBCData->nrof_subbands * pSBCData->nrof_channels * (pSBCData->nrof_blocks << 1);
+ if (inputSize < reqInSize)
+ {
+ *pOutputSize = 0;
+ return SBC_NOT_ENOUGH_DATA;
+ }
+
+ /* check for sufficient output buffer size */
+ {
+ int sb, bb;
+ frameSize = 4;
+ sb = pSBCData->nrof_subbands;
+ bb = pSBCData->nrof_blocks * pSBCData->bitpool;
+
+ switch (pSBCData->channel_mode)
+ {
+ case SBC_MODE_MONO:
+ frameSize += (sb >>1 ) + (bb >> 3);
+ /* (bb)>>3 must be rounded towards plus infinity */
+ if (bb & 0x7)
+ frameSize++;
+ break;
+ case SBC_MODE_DUAL:
+ frameSize += sb + (bb >> 2);
+ break;
+ case SBC_MODE_STEREO:
+ frameSize += sb + (bb >> 3);
+ /* (bb)>>3 must be rounded towards plus infinity */
+ if (bb & 0x7)
+ frameSize++;
+ break;
+ case SBC_MODE_JOINT:
+ frameSize += sb + ((sb + bb) >> 3);
+ /* (sb + bb)>>3 must be rounded towards plus infinity */
+ if ((sb + bb) & 0x7)
+ frameSize++;
+ break;
+ }
+
+ if (*pOutputSize < frameSize)
+ {
+ *pOutputSize = frameSize;
+ return SBC_BUFFER_TOO_SMALL;
+ }
+ }
+
+ /* create frame header */
+ {
+ unsigned char c = 0;
+ *pOut++ = SBC_SYNCBYTE;
+ c |= (params->samplingFrequency << 6);
+ c |= (params->blockNumber << 4);
+ c |= (params->channelMode << 2);
+ c |= (params->allocMethod << 1);
+ c |= params->subbandNumber;
+ *pOut++ = c;
+ *pOut++ = params->bitpool;
+ pCRC = pOut++;
+
+ if (params->channelMode == SBC_MODE_JOINT)
+ {
+ pJoint = pOut++;
+ *pJoint = 0;
+ }
+ }
+
+ /* reserve space for scale factors */
+ pScaleFactors = pOut;
+ pOut += (pSBCData->nrof_channels * (pSBCData->nrof_subbands >> 1));
+
+ /* initialize sample data */
+ {
+ int i;
+ for (i = 0; i < 16; i++)
+ pSampleData[i].calc1 = pSampleData[i].calc2 = 0;
+ }
+
+
+#if ! defined F_SBC_ENC_USE_FLOAT
+ /* create subband samples */
+ {
+#if ! defined F_SBC_ENC_REUSE_INPUT_BUFFER
+ pSamples = &samples[0];
+#endif
+ for (blk = pSBCData->nrof_blocks; blk > 0; blk--)
+ {
+ static int offset = 0;
+ int* pxLeft, *pxRight;
+ int sb, ns;
+#if defined F_SBC_ENC_REUSE_INPUT_BUFFER
+ pSamples = pIn; /* input buffer is used as temporary memory for subband samples */
+#endif
+
+ /* update audio ring buffer position */
+ if (offset <= 0)
+ offset = 81;
+ else
+ offset -= 9;
+ pxLeft = &x[0][0] + offset;
+ pxRight = pxLeft + 99;
+
+ /* fill in new audio samples */
+ {
+ ns = pSBCData->nrof_subbands;
+ for (sb = 0; sb < ns; sb++)
+ {
+ pxLeft[ns - sb - 1] = *pIn++;
+ if (pSBCData->nrof_channels == 2)
+ {
+ pxRight[ns - sb - 1] = *pIn++;
+ }
+ }
+ }
+
+ /* frequency band analysis */
+ if (pSBCData->nrof_subbands == 4)
+ {
+ calcPartials4(pxLeft, &c4[0], pSBCData->nrof_channels, &y[0][0]);
+ createSubbandSamples4(&y[0][0], &mik4[0][0], pSBCData->nrof_channels, (int*) pSamples, &sampleData[0][0]);
+ }
+ else
+ {
+ calcPartials8(pxLeft, &c8[0], pSBCData->nrof_channels, &y[0][0]);
+ createSubbandSamples8(&y[0][0], &mik8[0][0], pSBCData->nrof_channels, (int*) pSamples, &sampleData[0][0]);
+ } /* if subbands */
+
+#if ! defined F_SBC_ENC_REUSE_INPUT_BUFFER
+ pSamples += pSBCData->nrof_subbands * pSBCData->nrof_channels;
+#endif
+ } /* for blk */
+ }
+
+#else
+
+ /* use floating point arithmetic; for debugging only, for stereo 8 subbands only */
+ {
+#if ! defined F_SBC_ENC_REUSE_INPUT_BUFFER
+ pSamples = &samples[0];
+#endif
+
+ for (blk = pSBCData->nrof_blocks; blk > 0; blk--)
+ {
+ int i, k;
+
+ /* shift audio samples */
+ for (i = 79; i >= 8; i--)
+ {
+ X[0][i] = X[0][i - 8];
+ X[1][i] = X[1][i - 8];
+ }
+
+ /* fill in new samples */
+ for (i = 7; i >= 0; i--)
+ {
+ X[0][i] = *pIn++;
+ X[1][i] = *pIn++;
+ }
+
+ /* multiply with filter coeffs */
+ for (i = 0; i < 80 ; i++)
+ {
+ Z[0][i] = X[0][i] * C[i];
+ Z[1][i] = X[1][i] * C[i];
+ }
+
+ /* init Y */
+ for (i = 0; i < 16; i++)
+ {
+ Y[0][i] = 0;
+ Y[1][i] = 0;
+ }
+ /* partial calc */
+ for (i = 0; i < 16; i++)
+ {
+ for (k = 0; k < 5; k++)
+ {
+ Y[0][i] += Z[0][i + k * 16];
+ Y[1][i] += Z[1][i + k * 16];
+ }
+ }
+
+ /* init S */
+ for (i = 0; i < 16; i++)
+ {
+ S[0][i] = 0;
+ S[1][i] = 0;
+ }
+ /* subband samples */
+ for (i = 0; i < 8; i++)
+ {
+ for (k = 0; k < 16; k++)
+ {
+ S[0][i] += MIK[i][k] * Y[0][k];
+ S[1][i] += MIK[i][k] * Y[1][k];
+ }
+ }
+
+ for (i = 0; i < 8; i++)
+ {
+ if (S[0][i] >= 0)
+ *pSamples++ = (int) (S[0][i] + 0.5);
+ else
+ *pSamples++ = (int) (S[0][i] - 0.5);
+
+ if (pSamples[-1] > sampleData[0][i].calc1)
+ sampleData[0][i].calc1 = pSamples[-1];
+ if (pSamples[-1] < sampleData[0][i].calc2)
+ sampleData[0][i].calc2 = pSamples[-1];
+ }
+
+ for (i = 0; i < 8; i++)
+ {
+ if (S[1][i] >= 0)
+ *pSamples++ = (int) (S[1][i] + 0.5);
+ else
+ *pSamples++ = (int) (S[1][i] - 0.5);
+
+ if (pSamples[-1] > sampleData[1][i].calc1)
+ sampleData[1][i].calc1 = pSamples[-1];
+ if (pSamples[-1] < sampleData[1][i].calc2)
+ sampleData[1][i].calc2 = pSamples[-1];
+ }
+
+ } /* for blk */
+ }
+#endif
+
+ /* calculate scale factors */
+ {
+ int i = 0;
+ for (i = pSBCData->nrof_channels * pSBCData->nrof_subbands - 1; i >= 0; i--)
+ {
+ int sf;
+ int mx = pSampleData[i].calc1;
+ int mn = pSampleData[i].calc2 * -1;
+ if (mn > mx)
+ mx = mn;
+
+ if (mx > 255) if (mx > 4095) if (mx > 16383) if (mx > 32767) sf = 15; else sf = 14; else if (mx > 8191) sf = 13; else sf = 12;
+ else if (mx > 1023) if (mx > 2047) sf = 11; else sf = 10; else if (mx > 511) sf = 9; else sf = 8;
+ else if (mx > 15) if (mx > 63) if (mx > 127) sf = 7; else sf = 6; else if (mx > 31) sf = 5; else sf = 4;
+ else if (mx > 3) if (mx > 7) sf = 3; else sf = 2; else if (mx > 1) sf = 1; else sf = 0;
+
+ pSampleData[i].scale_factor = sf;
+ } /* for i */
+ }
+
+ /* join subband samples */
+#if defined F_SBC_ENC_REUSE_INPUT_BUFFER
+ pSamples = (short*) pInputBuffer;
+#else
+ pSamples = &samples[0];
+#endif
+ if (pSBCData->channel_mode == SBC_MODE_JOINT)
+ {
+ if (pSBCData->nrof_subbands == 4)
+ joinSubbands4((int*) pSamples, pSBCData, &sampleData[0][0], pJoint);
+ else
+ joinSubbands8((int*) pSamples, pSBCData, &sampleData[0][0], pJoint);
+ } /* if joint */
+
+ /* write scale factors */
+ {
+ unsigned char c = 0;
+ int ch;
+
+ if (pSBCData->nrof_subbands == 4)
+ {
+ if (pSBCData->channel_mode == SBC_MODE_JOINT)
+ {
+ /* data pointer adjustment required due to just 4 join bits in header */
+ for (ch = 2; ch > 0; ch--)
+ {
+ c = pSampleData[0].scale_factor;
+ pScaleFactors[-1] |= c; /* write to output buffer */
+ c = pSampleData[1].scale_factor << 4;
+ c |= pSampleData[2].scale_factor;
+ pScaleFactors[0] = c; /* write to output buffer */
+ c = pSampleData[3].scale_factor << 4;
+ pScaleFactors[1] = c; /* write to output buffer */
+ pSampleData += 4;
+ pScaleFactors += 2;
+ }
+ }
+ else
+ {
+ for (ch = pSBCData->nrof_channels; ch > 0; ch--)
+ {
+ c = pSampleData[0].scale_factor << 4;
+ c |= pSampleData[1].scale_factor;
+ pScaleFactors[0] = c; /* write to output buffer */
+ c = pSampleData[2].scale_factor << 4;
+ c |= pSampleData[3].scale_factor;
+ pScaleFactors[1] = c; /* write to output buffer */
+ pSampleData += 4;
+ pScaleFactors += 2;
+ }
+ }
+ }
+ else
+ {
+ for (ch = pSBCData->nrof_channels; ch > 0; ch--)
+ {
+ c = pSampleData[0].scale_factor << 4;
+ c |= pSampleData[1].scale_factor;
+ pScaleFactors[0] = c; /* write to output buffer */
+ c = pSampleData[2].scale_factor << 4;
+ c |= pSampleData[3].scale_factor;
+ pScaleFactors[1] = c; /* write to output buffer */
+ c = pSampleData[4].scale_factor << 4;
+ c |= pSampleData[5].scale_factor;
+ pScaleFactors[2] = c; /* write to output buffer */
+ c = pSampleData[6].scale_factor << 4;
+ c |= pSampleData[7].scale_factor;
+ pScaleFactors[3] = c; /* write to output buffer */
+ pSampleData += 8;
+ pScaleFactors += 4;
+ }
+ } /* if subbands */
+ pSampleData = &sampleData[0][0];
+ } /* write scale factors */
+
+ /* create checksum */
+ createCRC(pOutputBuffer);
+
+ /* adjust sample data for computeBits function */
+ if (pSBCData->nrof_channels == 2)
+ {
+ if (pSBCData->nrof_subbands == 4)
+ {
+ /* move TSampleData structs into second row of sampleData array */
+ memcpy(&pSampleData[8], &pSampleData[4], 4 * sizeof(TSampleData));
+ }
+ }
+
+ /* calculate bit allocation */
+ computeBits();
+
+ /* re-adjust sample data */
+ if (pSBCData->nrof_channels == 2)
+ {
+ if (pSBCData->nrof_subbands == 4)
+ {
+ /* move TSampleData structs into one row within sampleData array */
+ memcpy(&pSampleData[4], &pSampleData[8], 4 * sizeof(TSampleData));
+ }
+ }
+ /* set terminator */
+ pSampleData[pSBCData->nrof_channels * pSBCData->nrof_subbands].bits = SBC_TERMINATOR;
+
+ /* quantize, normalize and write subband samples */
+ {
+ unsigned out = 0;
+ int resBits = 0;
+#if defined F_SBC_ENC_REUSE_INPUT_BUFFER
+ pSamples = (short*) pInputBuffer; /* input buffer is storing the unquantized subband samples */
+#else
+ pSamples = &samples[0];
+#endif
+
+ if (pSBCData->nrof_subbands == 4)
+ {
+ if (pSBCData->channel_mode == SBC_MODE_JOINT)
+ {
+ /* data pointer adjustment required due to just 4 joint bits in header */
+ pOut--;
+ resBits = 4;
+ out = (*pOut & 0xf0) >> 4;
+ }
+ }
+
+ /* precalculate fixed factors */
+ for (;;)
+ {
+ int bits;
+
+ if ((bits = (*pSampleData++).bits) != 0)
+ {
+ /* break on terminator */
+ if (bits < 0) /* arm assembler optimization; saves 3 cycles compared to 'if (bits == SBC_TERMINATOR)' ! */
+ break;
+ pSampleData[-1].calc1 = ((1 << bits) - 1) << (GUARD_QUANT - 1); /* levels including factor 1/2, guarded */
+ pSampleData[-1].calc2 = (pSampleData[-1].calc1) >> (pSampleData[-1].scale_factor + 1); /* levels/scale factors, guarded via calc1 */
+ }
+ }
+
+ /* quantize, normalize and write subband samples */
+ for (blk = pSBCData->nrof_blocks; blk > 0; blk--)
+ {
+ pSampleData = &sampleData[0][0];
+
+ for (;;)
+ {
+ int bits;
+
+ if ((bits = (*pSampleData++).bits) != 0)
+ {
+ int qs;
+ int msk;
+ /* break on terminator */
+ if (bits < 0) /* arm assembler optimization; saves 3 cycles compared to 'if (bits == SBC_TERMINATOR)' ! */
+ break;
+ /* calculate subband sample */
+ qs = (*pSamples++ * pSampleData[-1].calc2 + pSampleData[-1].calc1) >> (GUARD_QUANT); /* un-guard (= round towards minus infinity) */
+ /* qs is a 32 bit integer holding the data to be written within the [bits] LSBs */
+
+#if defined F_SBC_ENC_USE_FLOAT
+ {
+ double should;
+ should = ((((double) pSamples[-1]) / (1 <<(pSampleData[-1].scale_factor + 1)) + 1) * ((1 << pSampleData[-1].bits) - 1.0) - 1.0) / 2.0;
+ if (should > 0)
+ should += 0.5;
+ else if (should < 0)
+ should -= 0.5;
+ qs = (int) should;
+ }
+#endif
+
+ msk = (1 << bits) - 1;
+ qs &= msk;
+#if defined F_SBC_DEBUG_FILE
+ pSampleData[-1].qs = qs;
+#endif
+
+ /* write subband sample */
+ out <<= bits;
+ out |= qs;
+ resBits += bits;
+ while (resBits >= 8)
+ {
+ *pOut++ = (unsigned char) (out >> (resBits - 8));
+ resBits -= 8;
+ } /* while */
+ } /* if bits */
+ else
+ {
+#if defined F_SBC_DEBUG_FILE
+ pSampleData[-1].qs = 0;
+#endif
+ pSamples++;
+ }
+#if defined F_SBC_DEBUG_FILE
+ pSampleData[-1].sb_sample = *pSamples;
+#endif
+ } /* for */
+
+#if defined F_SBC_DEBUG_FILE
+ {
+ int sb, nsb;
+ TSampleData* pd;
+ nsb = pSBCData->nrof_subbands;
+ pd = &sampleData[0][0];
+ for (sb = 0; sb < nsb; sb++)
+ {
+ printf("%d, %d, %d, %u\n",
+ pd[sb].sb_sample, pd[sb].bits, pd[sb].scale_factor, pd[sb].qs);
+ printf("%d, %d, %d, %u\n",
+ pd[sb+nsb].sb_sample, pd[sb+nsb].bits, pd[sb+nsb].scale_factor, pd[sb+nsb].qs);
+ }
+ }
+#endif
+
+ } /* for blk */
+
+ /* padding */
+ if (resBits > 0)
+ {
+ *pOut++ = (unsigned char) (out >> (8 - resBits));
+ }
+ }
+
+ *pOutputSize = pOut - pOutputBuffer;
+
+#if defined F_SBC_DEBUG_FILE
+ if (*pOutputSize != frameSize)
+ printf("! output size mismatch: frameSize %d, created %d\n", frameSize, *pOutputSize);
+ if ((unsigned char*) pIn - pInputBuffer != reqInSize)
+ printf("! input size mismatch: requested input %d, read %d\n", reqInSize, ((unsigned char*) pIn - pInputBuffer));
+#endif
+
+ return ((unsigned char*) pIn - pInputBuffer);
+}
+
+
+/***************************** initXTab ***********************************/
+/* initialize x array */
+/************************************************************************/
+static void initXTab(int* pTab)
+{
+ int i;
+ int* px = pTab;
+ int* px1 = pTab + 99;
+
+ memset(px, 0, 198);
+ for (i = 0; i < 11; i++)
+ {
+ px [i * 9 + 8] = (int) &px [matrixingTable[i]]; /* set pointer to successor group, first channel */
+ px1[i * 9 + 8] = (int) &px1[matrixingTable[i]]; /* set pointer to successor group, second channel */
+ }
+} /* initXTab */
+
+
+/******************************** calcPartials4 *****************************/
+/* */
+/************************************************************************/
+static void calcPartials4(int* pAudio, const int* pFactors, int channels, int* pMatrix)
+{
+ int y0, y1, y2, y3;
+ int iter = 2;
+ int* px = pAudio;
+ const int* pc = pFactors;
+ int* py = pMatrix;
+
+ while (--channels >= 0)
+ {
+ while (--iter >= 0)
+ {
+ y0 = y1 = y2 = y3 = GUARD_PAR_HALFBIT;
+
+ y0 += *pc++ * px[0];
+ y1 += *pc++ * px[1];
+ y2 += *pc++ * px[2];
+ y3 += *pc++ * px[3];
+ px = (int*) px[8]; /* jump to next group */
+
+ y0 += *pc++ * px[0];
+ y1 += *pc++ * px[1];
+ y2 += *pc++ * px[2];
+ y3 += *pc++ * px[3];
+ px = (int*) px[8];
+
+ y0 += *pc++ * px[0];
+ y1 += *pc++ * px[1];
+ y2 += *pc++ * px[2];
+ y3 += *pc++ * px[3];
+ px = (int*) px[8];
+
+ y0 += *pc++ * px[0];
+ y1 += *pc++ * px[1];
+ y2 += *pc++ * px[2];
+ y3 += *pc++ * px[3];
+ px = (int*) px[8];
+
+ y0 += *pc++ * px[0];
+ y1 += *pc++ * px[1];
+ y2 += *pc++ * px[2];
+ y3 += *pc++ * px[3];
+ px += 9;
+ px = (int*) px[8];
+
+ *py++ = y0 >> (GUARD_PAR);
+ *py++ = y1 >> (GUARD_PAR);
+ *py++ = y2 >> (GUARD_PAR);
+ *py++ = y3 >> (GUARD_PAR);
+
+ } /* iter */
+ iter = 2;
+ pc -= 40;
+ px = pAudio + 99;
+ } /* channels */
+} /* calcPartials4 */
+
+
+/********************* createSubbandSamples4 *****************************/
+/* */
+/************************************************************************/
+static void createSubbandSamples4(int* pMatrix, const int* pFactors, int channels, int* pSamples, TSampleData* pSampleData)
+{
+ int i, s;
+ int* py = pMatrix;
+ const int* pmik = pFactors;
+#if defined F_SBC_ENC_REUSE_INPUT_BUFFER
+ short* ps = (short*) pSamples;
+#else
+ int* ps = pSamples;
+#endif
+ TSampleData* pd = pSampleData;
+
+ while (--channels >= 0)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ s = GUARD_SUB_HALFBIT;
+ s += *pmik++ * py[0];
+ s += *pmik++ * py[1];
+ s += *pmik++ * py[2];
+ s += *pmik++ * py[3];
+ s += *pmik++ * py[4];
+ s += *pmik++ * py[5];
+ s += *pmik++ * py[6];
+ s += *pmik++ * py[7];
+ s >>= (GUARD_SUB);
+
+ /* save to sample buffer */
+#if defined F_SBC_ENC_REUSE_INPUT_BUFFER
+ limit(s);
+ *ps++ = (short) s; /* save to sample buffer */
+#else
+ *ps++ = s;
+#endif
+
+ if (s > (*pd++).calc1)
+ pd[-1].calc1 = s; /* save maximum */
+ else
+ {
+ if (s < pd[-1].calc2)
+ pd[-1].calc2 = s; /* save minimum */
+ }
+ }
+
+ py += 8;
+ pmik -= 32;
+ } /* channels */
+} /* createSubbandSamples4 */
+
+
+/******************************** calcPartials8 *****************************/
+/* */
+/************************************************************************/
+static void calcPartials8(int* pAudio, const int* pFactors, int channels, int* pMatrix)
+{
+ int y0, y1, y2, y3, y4, y5, y6, y7;
+ int iter = 2;
+ int* px = pAudio;
+ const int* pc = pFactors;
+ int* py = pMatrix;
+
+ while (--channels >= 0)
+ {
+ while (--iter >= 0)
+ {
+ y0 = y1 = y2 = y3 = y4 = y5 = y6 = y7 = GUARD_PAR_HALFBIT;
+
+ y0 += *pc++ * px[0];
+ y1 += *pc++ * px[1];
+ y2 += *pc++ * px[2];
+ y3 += *pc++ * px[3];
+ y4 += *pc++ * px[4];
+ y5 += *pc++ * px[5];
+ y6 += *pc++ * px[6];
+ y7 += *pc++ * px[7];
+ px = (int*) px[8]; /* jump to next group */
+
+ y0 += *pc++ * px[0];
+ y1 += *pc++ * px[1];
+ y2 += *pc++ * px[2];
+ y3 += *pc++ * px[3];
+ y4 += *pc++ * px[4];
+ y5 += *pc++ * px[5];
+ y6 += *pc++ * px[6];
+ y7 += *pc++ * px[7];
+ px = (int*) px[8];
+
+ y0 += *pc++ * px[0];
+ y1 += *pc++ * px[1];
+ y2 += *pc++ * px[2];
+ y3 += *pc++ * px[3];
+ y4 += *pc++ * px[4];
+ y5 += *pc++ * px[5];
+ y6 += *pc++ * px[6];
+ y7 += *pc++ * px[7];
+ px = (int*) px[8];
+
+ y0 += *pc++ * px[0];
+ y1 += *pc++ * px[1];
+ y2 += *pc++ * px[2];
+ y3 += *pc++ * px[3];
+ y4 += *pc++ * px[4];
+ y5 += *pc++ * px[5];
+ y6 += *pc++ * px[6];
+ y7 += *pc++ * px[7];
+ px = (int*) px[8];
+
+ y0 += *pc++ * px[0];
+ y1 += *pc++ * px[1];
+ y2 += *pc++ * px[2];
+ y3 += *pc++ * px[3];
+ y4 += *pc++ * px[4];
+ y5 += *pc++ * px[5];
+ y6 += *pc++ * px[6];
+ y7 += *pc++ * px[7];
+ px += 9;
+ px = (int*) px[8];
+
+ *py++ = y0 >> (GUARD_PAR);
+ *py++ = y1 >> (GUARD_PAR);
+ *py++ = y2 >> (GUARD_PAR);
+ *py++ = y3 >> (GUARD_PAR);
+ *py++ = y4 >> (GUARD_PAR);
+ *py++ = y5 >> (GUARD_PAR);
+ *py++ = y6 >> (GUARD_PAR);
+ *py++ = y7 >> (GUARD_PAR);
+
+ } /* iter */
+ iter = 2;
+ pc -= 80;
+ px = pAudio + 99;
+ } /* channels */
+} /* calcPartials8 */
+
+
+/********************* createSubbandSamples8 *****************************/
+/* */
+/************************************************************************/
+static void createSubbandSamples8(int* pMatrix, const int* pFactors, int channels, int* pSamples, TSampleData* pSampleData)
+{
+ int i, s;
+ int* py = pMatrix;
+ const int* pmik = pFactors;
+#if defined F_SBC_ENC_REUSE_INPUT_BUFFER
+ short* ps = (short*) pSamples;
+#else
+ int* ps = pSamples;
+#endif
+ TSampleData* pd = pSampleData;
+
+ while (--channels >= 0)
+ {
+ for (i = 0; i < 8; i++)
+ {
+ s = GUARD_SUB_HALFBIT;
+ s += *pmik++ * py[0];
+ s += *pmik++ * py[1];
+ s += *pmik++ * py[2];
+ s += *pmik++ * py[3];
+ s += *pmik++ * py[4];
+ s += *pmik++ * py[5];
+ s += *pmik++ * py[6];
+ s += *pmik++ * py[7];
+ s += *pmik++ * py[8];
+ s += *pmik++ * py[9];
+ s += *pmik++ * py[10];
+ s += *pmik++ * py[11];
+ s += *pmik++ * py[12];
+ s += *pmik++ * py[13];
+ s += *pmik++ * py[14];
+ s += *pmik++ * py[15];
+ s >>= (GUARD_SUB);
+
+ /* save to sample buffer */
+#if defined F_SBC_ENC_REUSE_INPUT_BUFFER
+ limit(s);
+ *ps++ = (short) s; /* save to sample buffer */
+#else
+ *ps++ = s;
+#endif
+
+ if (s > (*pd++).calc1)
+ pd[-1].calc1 = s; /* save maximum */
+ else
+ {
+ if (s < pd[-1].calc2)
+ pd[-1].calc2 = s; /* save minimum */
+ }
+ }
+
+ py += 16;
+ pmik -= 128;
+ } /* channels */
+} /* createSubbandSamples8 */
+
+
+/*************************** joinSubbands4 *********************************/
+/* */
+/************************************************************************/
+static void joinSubbands4(int* pSamples, TSBCData* pSBCData, TSampleData* pSampleData, unsigned char* pJoint)
+{
+ int join = 0;
+ int jointSamples[32];
+ TSampleData jointData[8];
+ int sb, blk, blkR, iL, iR;
+#if defined F_SBC_ENC_REUSE_INPUT_BUFFER
+ short* ps = (short*) pSamples;
+#else
+ int* ps = pSamples;
+#endif
+
+ /* initialize joint data */
+ for (sb = 7; sb >= 0; sb--)
+ jointData[sb].calc1 = jointData[sb].calc2 = 0;
+
+ /* iterate through subbands; the highest subband is never joint */
+ for (sb = 2; sb >= 0; sb--)
+ {
+ int sbR, mx, sf, sumN, sumJ;
+ sbR = sb + 4;
+ iL = sb + ((pSBCData->nrof_blocks) << 3);
+ iR = iL + 4;
+ for (blk = pSBCData->nrof_blocks - 1; blk >= 0; blk--)
+ {
+ /* calculate sum and difference signals */
+ iL -= 8;
+ iR -= 8;
+ blkR = blk + pSBCData->nrof_blocks;
+ jointSamples[blk] = (ps[iL] + ps[iR]) >> 1;
+ jointSamples[blkR] = (ps[iL] - ps[iR]) >> 1;
+
+ /* sum (left) channel maximum */
+ if (jointSamples[blk] > jointData[sb].calc1)
+ jointData[sb].calc1 = jointSamples[blk];
+ else
+ {
+ /* sum (left) channel minimum */
+ if (jointSamples[blk] < jointData[sb].calc2)
+ jointData[sb].calc2 = jointSamples[blk];
+ }
+
+ /* difference (right) channel maximum */
+ if (jointSamples[blkR] > jointData[sbR].calc1)
+ jointData[sbR].calc1 = jointSamples[blkR];
+ else
+ {
+ /* difference (right) channel minimum */
+ if (jointSamples[blkR] < jointData[sbR].calc2)
+ jointData[sbR].calc2 = jointSamples[blkR];
+ }
+ } /* for blk */
+
+ /* calculate scale factors */
+ mx = jointData[sb].calc1;
+ jointData[sb].calc2 *= -1;
+ if (jointData[sb].calc2 > mx)
+ mx = jointData[sb].calc2;
+ if (mx > 255) if (mx > 4095) if (mx > 16383) if (mx > 32767) sf = 15; else sf = 14; else if (mx > 8191) sf = 13; else sf = 12;
+ else if (mx > 1023) if (mx > 2047) sf = 11; else sf = 10; else if (mx > 511) sf = 9; else sf = 8;
+ else if (mx > 15) if (mx > 63) if (mx > 127) sf = 7; else sf = 6; else if (mx > 31) sf = 5; else sf = 4;
+ else if (mx > 3) if (mx > 7) sf = 3; else sf = 2; else if (mx > 1) sf = 1; else sf = 0;
+ jointData[sb].scale_factor = sf;
+
+ mx = jointData[sbR].calc1;
+ jointData[sbR].calc2 *= -1;
+ if (jointData[sbR].calc2 > mx)
+ mx = jointData[sbR].calc2;
+ if (mx > 255) if (mx > 4095) if (mx > 16383) if (mx > 32767) sf = 15; else sf = 14; else if (mx > 8191) sf = 13; else sf = 12;
+ else if (mx > 1023) if (mx > 2047) sf = 11; else sf = 10; else if (mx > 511) sf = 9; else sf = 8;
+ else if (mx > 15) if (mx > 63) if (mx > 127) sf = 7; else sf = 6; else if (mx > 31) sf = 5; else sf = 4;
+ else if (mx > 3) if (mx > 7) sf = 3; else sf = 2; else if (mx > 1) sf = 1; else sf = 0;
+ jointData[sbR].scale_factor = sf;
+
+ /* make joint decision */
+ sumN = pSampleData[sb].scale_factor + pSampleData[sbR].scale_factor;
+ sumJ = jointData[sb].scale_factor + jointData[sbR].scale_factor;
+ if (sumJ < sumN)
+ {
+ /* add joint bit */
+ join |= (0x80 >> sb);
+
+ /* replace samples */
+ iL = sb + ((pSBCData->nrof_blocks) << 3);
+ iR = iL + 4;
+ for (blk = pSBCData->nrof_blocks - 1; blk >= 0; blk--)
+ {
+ iL -= 8;
+ iR -= 8;
+#if defined F_SBC_ENC_REUSE_INPUT_BUFFER
+ ps[iL] = (short) jointSamples[blk];
+ ps[iR] = (short) jointSamples[blk + pSBCData->nrof_blocks];
+#else
+ ps[iL] = jointSamples[blk];
+ ps[iR] = jointSamples[blk + pSBCData->nrof_blocks];
+#endif
+ } /* for blk */
+
+ /* replace scale factors */
+ pSampleData[sb].scale_factor = jointData[sb].scale_factor;
+ pSampleData[sbR].scale_factor = jointData[sbR].scale_factor;
+ } /* if join */
+ } /* for subband */
+
+ *pJoint = join;
+}
+
+
+/*************************** joinSubbands8 *********************************/
+/* */
+/************************************************************************/
+static void joinSubbands8(int* pSamples, TSBCData* pSBCData, TSampleData* pSampleData, unsigned char* pJoint)
+{
+ int join = 0;
+ int jointSamples[32];
+ TSampleData jointData[16];
+ int sb, blk, blkR, iL, iR;
+#if defined F_SBC_ENC_REUSE_INPUT_BUFFER
+ short* ps = (short*) pSamples;
+#else
+ int* ps = pSamples;
+#endif
+
+ /* initialize joint data */
+ for (sb = 15; sb >= 0; sb--)
+ jointData[sb].calc1 = jointData[sb].calc2 = 0;
+
+ /* iterate through subbands; the highest subband is never joint */
+ for (sb = 6; sb >= 0; sb--)
+ {
+ int sbR, mx, sf, sumN, sumJ;
+ sbR = sb + 8;
+ iL = sb + ((pSBCData->nrof_blocks) << 4);
+ iR = iL + 8;
+ for (blk = pSBCData->nrof_blocks - 1; blk >= 0; blk--)
+ {
+ /* calculate sum and difference signals */
+ iL -= 16;
+ iR -= 16;
+ blkR = blk + pSBCData->nrof_blocks;
+ jointSamples[blk] = (ps[iL] + ps[iR]) >> 1;
+ jointSamples[blkR] = (ps[iL] - ps[iR]) >> 1;
+
+ /* sum (left) channel maximum */
+ if (jointSamples[blk] > jointData[sb].calc1)
+ jointData[sb].calc1 = jointSamples[blk];
+ else
+ {
+ /* sum (left) channel minimum */
+ if (jointSamples[blk] < jointData[sb].calc2)
+ jointData[sb].calc2 = jointSamples[blk];
+ }
+
+ /* difference (right) channel maximum */
+ if (jointSamples[blkR] > jointData[sbR].calc1)
+ jointData[sbR].calc1 = jointSamples[blkR];
+ else
+ {
+ /* difference (right) channel minimum */
+ if (jointSamples[blkR] < jointData[sbR].calc2)
+ jointData[sbR].calc2 = jointSamples[blkR];
+ }
+ } /* for blk */
+
+ /* calculate scale factors */
+ mx = jointData[sb].calc1;
+ jointData[sb].calc2 *= -1;
+ if (jointData[sb].calc2 > mx)
+ mx = jointData[sb].calc2;
+ if (mx > 255) if (mx > 4095) if (mx > 16383) if (mx > 32767) sf = 15; else sf = 14; else if (mx > 8191) sf = 13; else sf = 12;
+ else if (mx > 1023) if (mx > 2047) sf = 11; else sf = 10; else if (mx > 511) sf = 9; else sf = 8;
+ else if (mx > 15) if (mx > 63) if (mx > 127) sf = 7; else sf = 6; else if (mx > 31) sf = 5; else sf = 4;
+ else if (mx > 3) if (mx > 7) sf = 3; else sf = 2; else if (mx > 1) sf = 1; else sf = 0;
+ jointData[sb].scale_factor = sf;
+
+ mx = jointData[sbR].calc1;
+ jointData[sbR].calc2 *= -1;
+ if (jointData[sbR].calc2 > mx)
+ mx = jointData[sbR].calc2;
+ if (mx > 255) if (mx > 4095) if (mx > 16383) if (mx > 32767) sf = 15; else sf = 14; else if (mx > 8191) sf = 13; else sf = 12;
+ else if (mx > 1023) if (mx > 2047) sf = 11; else sf = 10; else if (mx > 511) sf = 9; else sf = 8;
+ else if (mx > 15) if (mx > 63) if (mx > 127) sf = 7; else sf = 6; else if (mx > 31) sf = 5; else sf = 4;
+ else if (mx > 3) if (mx > 7) sf = 3; else sf = 2; else if (mx > 1) sf = 1; else sf = 0;
+ jointData[sbR].scale_factor = sf;
+
+ /* make joint decision */
+ sumN = pSampleData[sb].scale_factor + pSampleData[sbR].scale_factor;
+ sumJ = jointData[sb].scale_factor + jointData[sbR].scale_factor;
+ if (sumJ < sumN)
+ {
+ /* add join bit */
+ join |= (1 << (7 - sb));
+
+ /* replace samples */
+ iL = sb + ((pSBCData->nrof_blocks) << 4);
+ iR = iL + 8;
+ for (blk = pSBCData->nrof_blocks - 1; blk >= 0; blk--)
+ {
+ iL -= 16;
+ iR -= 16;
+#if defined F_SBC_ENC_REUSE_INPUT_BUFFER
+ ps[iL] = (short) jointSamples[blk];
+ ps[iR] = (short) jointSamples[blk + pSBCData->nrof_blocks];
+#else
+ ps[iL] = jointSamples[blk];
+ ps[iR] = jointSamples[blk + pSBCData->nrof_blocks];
+#endif
+ }
+
+ /* replace scale factors */
+ pSampleData[sb].scale_factor = jointData[sb].scale_factor;
+ pSampleData[sbR].scale_factor = jointData[sbR].scale_factor;
+ } /* if join */
+ } /* for subband */
+
+ *pJoint = join;
+}
+
+
+/******************************* createCRC *******************************/
+/* */
+/************************************************************************/
+static void createCRC(unsigned char* pOutput)
+{
+ int bits = 0;
+ unsigned char data[11];
+ TSBCData* pSBCData = &SBCData;
+ unsigned crc = 0x0f;
+ int i;
+ unsigned octet;
+ int len = 2;
+
+ /* copy relevant data to local array */
+ memcpy(data, pOutput + 1, len); /* first two bytes */
+ if (pSBCData->nrof_channels == 2)
+ len *= 2;
+ if (pSBCData->nrof_subbands == 8)
+ len *= 2;
+ if (pSBCData->channel_mode == SBC_MODE_JOINT)
+ len += 1;
+ memcpy(data + 2, pOutput + 4, len); /* joint and scale bytes */
+ bits = len * 8; /* joint and scale bits */
+ if (len == 5)
+ bits -= 4; /* only 4 joint bits for 4 subbands */
+ bits += 16; /* header bits */
+
+ for (i = 0; i < bits / 8; i++)
+ crc = crcTable[crc ^ data[i]];
+
+ octet = data[i];
+ for (i = 0; i < bits % 8; i++)
+ {
+ char bit = ((octet ^ crc) & 0x80) >> 7;
+ crc = ((crc & 0x7f) << 1) ^ (bit ? 0x1d : 0);
+ octet = octet << 1;
+ }
+
+ pOutput[3] = (unsigned char) crc;
+}
+
+
+/*************************** computeBits *********************************/
+/* this implementation has been taken directly from the specification */
+/************************************************************************/
+static void computeBits(void)
+{
+ int loudness;
+ int max_bitneed = 0;
+ unsigned ch;
+ unsigned sb;
+ int bitneed[SBC_MAX_CHANNELS][SBC_MAX_SUBBANDS];
+ TSBCData* pSBCData= &SBCData;
+
+ if (pSBCData->channel_mode == SBC_MODE_MONO || pSBCData->channel_mode == SBC_MODE_DUAL)
+ {
+ for (ch=0; ch < pSBCData->nrof_channels; ch++)
+ {
+ /* Mono and Dual_Channel Bit Allocation */
+ if (pSBCData->allocation_method == SBC_ALLOCSNR)
+ {
+ for (sb = 0; sb < pSBCData->nrof_subbands; sb++)
+ {
+ int b = bitneed[ch][sb] = sampleData[ch][sb].scale_factor;
+ if (max_bitneed < b)
+ max_bitneed = b;
+ }
+ }
+ else
+ {
+ for (sb = 0;sb < pSBCData->nrof_subbands; sb++)
+ {
+ if (sampleData[ch][sb].scale_factor == 0)
+ {
+ int b = bitneed[ch][sb] = -5;
+ if (max_bitneed < b)
+ max_bitneed = b;
+ }
+ else
+ {
+ if (pSBCData->nrof_subbands == 4)
+ {
+ loudness = sampleData[ch][sb].scale_factor - offset4[pSBCData->sampling_frequency][sb];
+ }
+ else
+ {
+ loudness = sampleData[ch][sb].scale_factor - offset8[pSBCData->sampling_frequency][sb];
+ }
+ if (loudness > 0)
+ {
+ bitneed[ch][sb] = loudness / 2;
+ if (max_bitneed < loudness / 2)
+ max_bitneed = loudness / 2;
+
+ }
+ else
+ {
+ bitneed[ch][sb] = loudness;
+ if (max_bitneed < loudness)
+ max_bitneed = loudness;
+ }
+ }
+ }
+ }
+
+ /* Next an iterative process finds out how many bitslices fit into the bitpool */
+ {
+ int bitcount = 0;
+ int slicecount = 0;
+ int bitslice = max_bitneed + 1; /* init just above the largest sf */
+ do
+ {
+ bitslice--;
+ bitcount += slicecount;
+ slicecount = 0;
+ for (sb = 0;sb < pSBCData->nrof_subbands; sb++)
+ {
+ if((bitneed[ch][sb] > bitslice + 1) && (bitneed[ch][sb] < bitslice + 16))
+ slicecount++;
+ else if(bitneed[ch][sb] == bitslice + 1)
+ slicecount += 2;
+ }
+ } while (bitcount + slicecount < pSBCData->bitpool);
+
+ if (bitcount + slicecount == pSBCData->bitpool)
+ {
+ bitcount += slicecount;
+ bitslice--;
+ }
+
+ /* Thereafter, bits are distributed until the last bitslice is reached */
+ for (sb=0;sb<pSBCData->nrof_subbands;sb++)
+ {
+ if(bitneed[ch][sb]<bitslice+2)
+ sampleData[ch][sb].bits=0;
+ else
+ sampleData[ch][sb].bits=min(bitneed[ch][sb]-bitslice,16);
+ }
+
+ /* The remaining bits are allocated starting at subband 0 */
+ sb=0;
+ while(bitcount < pSBCData->bitpool && sb < pSBCData->nrof_subbands)
+ {
+ if((sampleData[ch][sb].bits>=2)&&(sampleData[ch][sb].bits<16))
+ {
+ sampleData[ch][sb].bits++; bitcount++;
+ }
+ else
+ if((bitneed[ch][sb]==bitslice+1)&&(pSBCData->bitpool>bitcount+1))
+ {
+ sampleData[ch][sb].bits=2; bitcount+=2;
+ }
+ sb++;
+ }
+ sb=0;
+ while(bitcount < pSBCData->bitpool && sb < pSBCData->nrof_subbands)
+ {
+ if (sampleData[ch][sb].bits < 16)
+ {
+ sampleData[ch][sb].bits++;
+ bitcount++;
+ }
+ sb++;
+ }
+ }
+ } /* for ch */
+ } /* MONO and DUAL */
+ else
+ {
+ /* Stereo and Joint_Stereo Bit Allocation */
+ if (pSBCData->allocation_method == SBC_ALLOCSNR)
+ {
+ for (ch = 0;ch < 2; ch++)
+ {
+ for (sb = 0; sb < pSBCData->nrof_subbands; sb++)
+ {
+ int b = bitneed[ch][sb] = sampleData[ch][sb].scale_factor;
+ if (b > max_bitneed)
+ max_bitneed = b;
+ }
+ }
+ }
+ else
+ {
+ for (ch = 0;ch < 2; ch++)
+ {
+ for (sb=0;sb<pSBCData->nrof_subbands;sb++)
+ {
+ if (sampleData[ch][sb].scale_factor == 0)
+ {
+ bitneed[ch][sb] = -5;
+ if (max_bitneed < -5)
+ max_bitneed = -5;
+ }
+ else
+ {
+ if (pSBCData->nrof_subbands == 4)
+ {
+ loudness = sampleData[ch][sb].scale_factor - offset4[pSBCData->sampling_frequency][sb];
+ }
+ else
+ {
+ loudness = sampleData[ch][sb].scale_factor - offset8[pSBCData->sampling_frequency][sb];
+ }
+ if (loudness > 0)
+ {
+ bitneed[ch][sb] = (loudness >> 1);
+ if ((loudness >> 1) > max_bitneed)
+ max_bitneed = (loudness >> 1);
+ }
+ else
+ {
+ bitneed[ch][sb] = loudness;
+ if (max_bitneed < loudness)
+ max_bitneed = loudness;
+ }
+ }
+ }
+ }
+ }
+ /* Next an iterative process finds out how many bitslices fit into the bitpool */
+ computeSlicesInPoolStereo(max_bitneed, bitneed);
+ } /* Joint and Stereo Allocation */
+} /* computeBits */
+
+
+/*************************** computeSlicesInPoolStereo ******************/
+/* An iterative process finds out how many bitslices fit into the bitpool */
+/* The result is stored in the global array "bits" */
+/* this implementation has been taken directly from the specification */
+/************************************************************************/
+static void computeSlicesInPoolStereo( int max_bitneed, int bitneed[SBC_MAX_CHANNELS][SBC_MAX_SUBBANDS])
+{
+ static int n = 0;
+
+ int bitcount = 0;
+ int slicecount = 0;
+ int bitslice = max_bitneed + 1; /* init just above the largest sf */
+ int sb, ch;
+ TSBCData* pSBCData= &SBCData;
+ int bitpool = pSBCData->bitpool;
+ int nrof_subbands = pSBCData->nrof_subbands;
+
+ int* bn0 = bitneed[0];
+ int* bn1 = bitneed[1];
+
+ do
+ {
+ bitcount += slicecount;
+ slicecount = 0;
+
+ sb = nrof_subbands - 1;
+ do
+ {
+ int bitn;
+ /* channel 0 */
+ bitn = bn0[sb];
+ if((bitn >= bitslice) && (bitn < bitslice + 15))
+ slicecount++;
+ if(bitn == bitslice)
+ slicecount++;
+
+ /* channel 1 */
+ bitn = bn1[sb];
+ if((bitn >= bitslice) && (bitn < bitslice + 15))
+ slicecount++;
+ if(bitn == bitslice)
+ slicecount++;
+
+ } while (sb--);
+ bitslice--;
+ } while (bitcount + slicecount < bitpool);
+
+ if (bitcount + slicecount == bitpool)
+ {
+ bitcount += slicecount;
+ bitslice--;
+ }
+
+ /* Thereafter bits are distributed until the last bitslice is reached */
+ for (ch = 0; ch < 2; ch++)
+ {
+ for (sb=0;sb<nrof_subbands;sb++)
+ {
+ if(bitneed[ch][sb] < bitslice + 2)
+ sampleData[ch][sb].bits = 0;
+ else
+ sampleData[ch][sb].bits = min(bitneed[ch][sb] - bitslice, 16);
+ }
+ }
+
+ /* The remaining bits are allocated starting with subband 0 of the first channel */
+ {
+ unsigned ch = 0;
+ sb=0;
+ while(bitcount < pSBCData->bitpool && sb < (int)pSBCData->nrof_subbands)
+ {
+ if((sampleData[ch][sb].bits>=2)&&(sampleData[ch][sb].bits<16))
+ {
+ sampleData[ch][sb].bits++; bitcount++;
+ }
+ else if((bitneed[ch][sb]==bitslice+1)&&(pSBCData->bitpool>bitcount+1))
+ {
+ sampleData[ch][sb].bits=2; bitcount+=2;
+ }
+ if (ch == 1)
+ {
+ ch = 0;
+ sb++;
+ }
+ else
+ {
+ ch = 1;
+ }
+ }
+ ch=0;
+ sb=0;
+ while(bitcount < pSBCData->bitpool && sb < (int)pSBCData->nrof_subbands)
+ {
+ if (sampleData[ch][sb].bits < 16)
+ {
+ sampleData[ch][sb].bits++;
+ bitcount++;
+ }
+ if (ch == 1)
+ {
+ ch = 0;
+ sb++;
+ }
+ else
+ {
+ ch = 1;
+ }
+ }
+ }
+}
+
+#if defined F_SBC_DEBUG_FILE
+/************************************************************************/
+/* various debug helper functions */
+/************************************************************************/
+static void dumpXTab(int* pTab)
+{
+ int i;
+ int* px = pTab;
+
+ printf("x dump\n");
+ for (i = 0; i < 180; i++)
+ {
+ if ((i % 9) == 8)
+ continue;
+ printf("x[%d] = val %4d\n", i, px[i]);
+ }
+ printf("\n");
+}
+
+static void dumpYTab(int* pTab)
+{
+ int i;
+ int* py = pTab;
+
+ printf("y dump\n");
+ for (i = 0; i < 32; i++)
+ printf("value of y[%2d] = %6d\n", i, py[i]);
+ printf("\n");
+}
+
+static void dumpSampleData(TSampleData* pTab)
+{
+ int i;
+ TSampleData* pd = pTab;
+
+ printf("sample data dump\n");
+ for (i = 0; i < 16; i++)
+ printf("scale_factor[ ][ ] = %2d bits[][] = %2d max[][] = %2d\n", pd[i].scale_factor, pd[i].bits, pd[i].calc1);
+ printf("\n");
+}
+
+static void dumpInputBuffer(short* pBuffer, int index)
+{
+ int i;
+ short* pb = pBuffer;
+
+ printf("in buffer dump\n");
+ for (i = index; i < index + 16; i++)
+ printf("in[%2d] = %6d\n", i - index, pb[i]);
+ printf("\n");
+}
+#endif
+
+#endif /*F_BT_MPA_A2DP_SOURCE*/
diff --git a/addon/vr_bee1_hidraw_daemon/hidraw/voice_hidraw.c b/addon/vr_bee1_hidraw_daemon/hidraw/voice_hidraw.c
new file mode 100755
index 0000000..05c41fb
--- /dev/null
+++ b/addon/vr_bee1_hidraw_daemon/hidraw/voice_hidraw.c
@@ -0,0 +1,1138 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/inotify.h>
+#include <sys/poll.h>
+#include <linux/input.h>
+#include <linux/hidraw.h>
+#include <errno.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <pthread.h>
+
+
+#include "voice_hidraw.h"
+#include "bee_settings.h"
+#include "get_voice_app.h"
+#include "sbc.h"
+#include "voice_uipc.h"
+#include "config.h"
+
+#define RAW_DATA_PATH "/data/vr/raw_data"
+static int file_counter = 0;
+int raw_fd;
+int gSocket_Running = 0;
+int gTarget_fd = 0;
+
+
+
+typedef struct {
+ int vid;
+ int pid;
+ int vers;
+ unsigned char voice_key_reportID;
+ unsigned char voice_data_reportID;
+ unsigned char voice_cmd_reportID;
+ int voice_keypress_data_len;
+ unsigned char *voice_keypress_data;
+ int voice_keyrelease_data_len;
+ unsigned char *voice_keyrelease_data;
+ int decode_type;
+ int data_mask;
+ int autocmd;
+
+}VOICE_SETTING;
+
+static struct pollfd *ufds;
+static char **device_names;
+static int nfds;
+
+static int *unused_bt_hid_fds;
+static int nunusedfds;
+static char **unused_device_names;
+
+
+VOICE_SETTING global_voice_setting;
+pthread_mutex_t mutex_voice_settings;
+
+int frame_counter = 0;
+
+int set_rcu_info(int vid, int pid, int vers) {
+ pthread_mutex_lock(&mutex_voice_settings);
+ if(vid != -1)
+ global_voice_setting.vid = vid;
+
+ if(pid != -1)
+ global_voice_setting.pid = pid;
+
+ if(vers != -1)
+ global_voice_setting.vers = vers;
+
+ pthread_mutex_unlock(&mutex_voice_settings);
+
+ return 0;
+}
+
+int set_voice_data_reportID(unsigned char reportID) {
+ pthread_mutex_lock(&mutex_voice_settings);
+ global_voice_setting.voice_data_reportID = reportID;
+ pthread_mutex_unlock(&mutex_voice_settings);
+ return 0;
+}
+
+int set_voice_cmd_reportID(unsigned char reportID) {
+ pthread_mutex_lock(&mutex_voice_settings);
+ global_voice_setting.voice_cmd_reportID = reportID;
+ pthread_mutex_unlock(&mutex_voice_settings);
+ return 0;
+}
+
+int set_voice_key_reportID(unsigned char reportID) {
+ pthread_mutex_lock(&mutex_voice_settings);
+ global_voice_setting.voice_key_reportID = reportID;
+ pthread_mutex_unlock(&mutex_voice_settings);
+ return 0;
+}
+
+int set_voice_keypress_data(int len, unsigned char *data) {
+ if(len > 0) {
+ pthread_mutex_lock(&mutex_voice_settings);
+ if(global_voice_setting.voice_keypress_data != NULL) {
+ if(global_voice_setting.voice_keypress_data_len < len) {
+
+ unsigned char *buf = (unsigned char *)realloc(global_voice_setting.voice_keypress_data, len);
+ if(buf == NULL) {
+ //log
+ pthread_mutex_unlock(&mutex_voice_settings);
+ error("Failed to realloc for voice_keypress_data");
+ return -1;
+ }else {
+ global_voice_setting.voice_keypress_data = buf;
+ }
+ }
+ }else {
+ global_voice_setting.voice_keypress_data = (unsigned char *)malloc(len);
+ if(global_voice_setting.voice_keypress_data == NULL) {
+ //log
+ pthread_mutex_unlock(&mutex_voice_settings);
+ error("Failed to malloc for voice_keypress_data");
+ return -2;
+ }
+ }
+
+ memcpy(global_voice_setting.voice_keypress_data, data, len);
+ global_voice_setting.voice_keypress_data_len = len;
+ pthread_mutex_unlock(&mutex_voice_settings);
+ return 0;
+ }else {
+ warn("len is negative for voice_keypress_data");
+ return -3;
+ }
+}
+
+int set_voice_keyrelease_data(int len, unsigned char *data) {
+ if(len > 0) {
+ pthread_mutex_lock(&mutex_voice_settings);
+ if(global_voice_setting.voice_keyrelease_data != NULL) {
+ if(global_voice_setting.voice_keyrelease_data_len < len) {
+ unsigned char *buf = (unsigned char *)realloc(global_voice_setting.voice_keyrelease_data, len);
+ if(buf == NULL) {
+ //log
+ pthread_mutex_unlock(&mutex_voice_settings);
+ error("Failed to realloc for voice_keypress_data");
+ return -1;
+ }else {
+ global_voice_setting.voice_keyrelease_data = buf;
+ }
+ }
+ }else {
+ global_voice_setting.voice_keyrelease_data = (unsigned char *)malloc(len);
+ if(global_voice_setting.voice_keyrelease_data == NULL) {
+ pthread_mutex_unlock(&mutex_voice_settings);
+ error("Failed to malloc for voice_keyrelease_data");
+ return -2;
+ }
+ }
+
+ memcpy(global_voice_setting.voice_keyrelease_data, data, len);
+ global_voice_setting.voice_keyrelease_data_len = len;
+ pthread_mutex_unlock(&mutex_voice_settings);
+ return 0;
+ }else {
+ //log
+ warn("len is negative for voice_keyrelease_data");
+ return -3;
+ }
+}
+
+int set_encode_type(int type) {
+ if(type <= DECODE_TYPE_MAX) {
+ pthread_mutex_lock(&mutex_voice_settings);
+ global_voice_setting.decode_type = type;
+ pthread_mutex_unlock(&mutex_voice_settings);
+ return 0;
+ }else {
+ warn("Unknown Decode Type !!!");
+ return -1;
+ }
+}
+
+int data_type_mask(int mask) {
+ //log
+ debug("Set Data Type Mask 0x%04x", mask);
+
+ pthread_mutex_lock(&mutex_voice_settings);
+
+ if(mask & DATA_TYPE_MASK_RAW) {
+ global_voice_setting.data_mask = DATA_TYPE_MASK_RAW;
+ }else {
+ if(mask & DATA_TYPE_MASK_VOICE) {
+ global_voice_setting.data_mask |= DATA_TYPE_MASK_VOICE;
+ }
+ }
+
+ pthread_mutex_unlock(&mutex_voice_settings);
+ return 0;
+}
+
+int set_auto_cmd(int autocmd) {
+ pthread_mutex_lock(&mutex_voice_settings);
+ if(autocmd == 1) {
+ global_voice_setting.autocmd = AUTOCMD_AUTO;
+ }else if(autocmd == 2){
+ global_voice_setting.autocmd = AUTOCMD_NONE;
+ }
+ pthread_mutex_unlock(&mutex_voice_settings);
+
+ return 0;
+}
+
+
+
+int voice_msbc_init() {
+
+ int ivalue, i;
+
+ voice_loadconfig(CONFIG_PATH);
+
+ pthread_mutex_lock(&mutex_voice_settings);
+
+ memset(&global_voice_setting, 0, sizeof(global_voice_setting));
+
+ ivalue = voice_get_int_config(CONFIG_GROUP_RCU, CONFIG_ITEM_RCU_VID);
+ if(ivalue >= 0) {
+ global_voice_setting.vid = ivalue;
+ ALOGD("use config VID: %04x", global_voice_setting.vid);
+ } else {
+ global_voice_setting.vid = BEE_RCU_VID;
+ ALOGD("use default VID: %04x", global_voice_setting.vid);
+ }
+
+ ivalue = voice_get_int_config(CONFIG_GROUP_RCU, CONFIG_ITEM_RCU_PID);
+ if(ivalue >= 0) {
+ global_voice_setting.pid = ivalue;
+ ALOGD("use config PID: %04x", global_voice_setting.pid);
+ } else {
+ global_voice_setting.pid = BEE_RCU_PID;
+ ALOGD("use default PID: %04x", global_voice_setting.pid);
+ }
+
+ ivalue = voice_get_int_config(CONFIG_GROUP_RCU, CONFIG_ITEM_RCU_VER);
+ if(ivalue >= 0) {
+ global_voice_setting.vers = ivalue;
+ ALOGD("use config version: %04x", global_voice_setting.vers);
+ } else {
+ global_voice_setting.vers = BEE_RCU_VERSION;
+ ALOGD("use default VERSION: %04x", global_voice_setting.vers);
+ }
+
+ ivalue = voice_get_int_config(CONFIG_GROUP_REPORTID, CONFIG_ITEM_REPORTID_KEY);
+ if(ivalue > 0) {
+ global_voice_setting.voice_key_reportID = ivalue & 0xff;
+ ALOGD("use config key report id: %02x", global_voice_setting.voice_key_reportID);
+ } else {
+ global_voice_setting.voice_key_reportID = BEE_VOICEKEY_REPORTID;
+ ALOGD("use default key report id: %02x", global_voice_setting.voice_key_reportID);
+ }
+
+
+ ivalue = voice_get_int_config(CONFIG_GROUP_REPORTID, CONFIG_ITEM_REPORTID_DATA);
+ if(ivalue > 0) {
+ global_voice_setting.voice_data_reportID = ivalue & 0xff;
+ ALOGD("use config data report id: %02x", global_voice_setting.voice_data_reportID);
+ } else {
+ global_voice_setting.voice_data_reportID = BEE_MSBC_VOICEDATA_REPORTID;
+ ALOGD("use default data report id: %02x", global_voice_setting.voice_data_reportID);
+ }
+
+ ivalue = voice_get_int_config(CONFIG_GROUP_REPORTID, CONFIG_ITEM_REPORTID_CMD);
+ if(ivalue > 0) {
+ global_voice_setting.voice_cmd_reportID = ivalue & 0xff;
+ ALOGD("use config cmd report id: %02x", global_voice_setting.voice_cmd_reportID);
+ } else {
+ global_voice_setting.voice_cmd_reportID = BEE_MSBC_VOICECMD_REPORTID;
+ ALOGD("use default cmd report id: %02x", global_voice_setting.voice_cmd_reportID);
+ }
+
+ ivalue = voice_get_int_config(CONFIG_GROUP_REPORTVALUE, CONFIG_ITEM_REPORTVALUE_KEYDOWNLEN);
+ if(ivalue > 0) {
+ global_voice_setting.voice_keypress_data_len = ivalue;
+ ALOGD("use config keydown len: %d", global_voice_setting.voice_keypress_data_len);
+ } else {
+ global_voice_setting.voice_keypress_data_len = BEE_VOICEKEY_LEN;
+ ALOGD("use default keydown len: %d", global_voice_setting.voice_keypress_data_len);
+ }
+
+ global_voice_setting.voice_keypress_data = (unsigned char *)malloc(global_voice_setting.voice_keypress_data_len);
+ if(global_voice_setting.voice_keypress_data == NULL) {
+ //log
+ error("failed to get buf for keydown");
+ pthread_mutex_unlock(&mutex_voice_settings);
+ return -1;
+ }else {
+ if(ivalue > 0) {
+ if(voice_get_byte_array_config(CONFIG_GROUP_REPORTVALUE, CONFIG_ITEM_REPORTVALUE_KEYDOWN,
+ global_voice_setting.voice_keypress_data, global_voice_setting.voice_keypress_data_len)
+ != global_voice_setting.voice_keypress_data_len) {
+
+ global_voice_setting.voice_keypress_data_len = BEE_VOICEKEY_LEN;
+ if(ivalue < BEE_VOICEKEY_LEN) {
+ global_voice_setting.voice_keypress_data = (unsigned char *)realloc(global_voice_setting.voice_keypress_data, BEE_VOICEKEY_LEN);
+ if(global_voice_setting.voice_keypress_data == NULL) {
+ error("failed to realloc buf for keydown");
+ pthread_mutex_unlock(&mutex_voice_settings);
+ return -1;
+ }
+ }
+ memcpy(global_voice_setting.voice_keypress_data, BEE_VOICE_KEYDOWN_DATA, global_voice_setting.voice_keypress_data_len);
+ ALOGD("use default keydown data");
+ }
+ }else {
+ memcpy(global_voice_setting.voice_keypress_data, BEE_VOICE_KEYDOWN_DATA, global_voice_setting.voice_keypress_data_len);
+ ALOGD("use default keydown data");
+ }
+ ALOGD("key down data:");
+ for(i = 0; i < global_voice_setting.voice_keypress_data_len; i++) {
+ ALOGD("data[%d] = %02x", i, *(global_voice_setting.voice_keypress_data + i));
+ }
+ }
+
+ ivalue = voice_get_int_config(CONFIG_GROUP_REPORTVALUE, CONFIG_ITEM_REPORTVALUE_KEYUPLEN);
+ if(ivalue > 0) {
+ global_voice_setting.voice_keyrelease_data_len = ivalue;
+ ALOGD("use config keyup len: %d", global_voice_setting.voice_keyrelease_data_len);
+ } else {
+ global_voice_setting.voice_keyrelease_data_len = BEE_VOICEKEY_LEN;
+ ALOGD("use default keyup len: %d", global_voice_setting.voice_keyrelease_data_len);
+ }
+
+ global_voice_setting.voice_keyrelease_data = (unsigned char *)malloc(global_voice_setting.voice_keyrelease_data_len);
+ if(global_voice_setting.voice_keyrelease_data == NULL) {
+ //log
+ error("failed to get buf for keyup");
+ pthread_mutex_unlock(&mutex_voice_settings);
+ return -1;
+ }else {
+ if(ivalue > 0) {
+ if(voice_get_byte_array_config(CONFIG_GROUP_REPORTVALUE, CONFIG_ITEM_REPORTVALUE_KEYUP,
+ global_voice_setting.voice_keyrelease_data, global_voice_setting.voice_keyrelease_data_len)
+ != global_voice_setting.voice_keyrelease_data_len) {
+
+ global_voice_setting.voice_keyrelease_data_len = BEE_VOICEKEY_LEN;
+ if(ivalue < BEE_VOICEKEY_LEN) {
+ global_voice_setting.voice_keyrelease_data = (unsigned char *)realloc(global_voice_setting.voice_keyrelease_data, BEE_VOICEKEY_LEN);
+ if(global_voice_setting.voice_keyrelease_data == NULL) {
+ error("failed to realloc buf for keyup");
+ pthread_mutex_unlock(&mutex_voice_settings);
+ return -1;
+ }
+ }
+ memcpy(global_voice_setting.voice_keyrelease_data, BEE_VOICE_KEYUP_DATA, global_voice_setting.voice_keyrelease_data_len);
+ ALOGD("use default keyup data");
+ }
+ }else {
+ memcpy(global_voice_setting.voice_keyrelease_data, BEE_VOICE_KEYUP_DATA, global_voice_setting.voice_keyrelease_data_len);
+ ALOGD("use default keyup data");
+ }
+ ALOGD("key up data:");
+ for(i = 0; i < global_voice_setting.voice_keyrelease_data_len; i++) {
+ ALOGD("data[%d] = %02x", i, *(global_voice_setting.voice_keyrelease_data + i));
+ }
+ }
+
+ ivalue = voice_get_int_config(CONFIG_GROUP_SETTINGS, CONFIG_ITEM_SETTINGS_DECODETYPE);
+ if(ivalue > 0) {
+ global_voice_setting.decode_type = ivalue;
+ ALOGD("use config decode type: %d", global_voice_setting.decode_type);
+ } else {
+ global_voice_setting.decode_type = DECODE_TYPE_MSBC;
+ ALOGD("use default decode type: %d", global_voice_setting.decode_type);
+ }
+
+ ivalue = voice_get_int_config(CONFIG_GROUP_SETTINGS, CONFIG_ITEM_SETTINGS_DATAMASK);
+ if(ivalue > 0) {
+ global_voice_setting.data_mask = ivalue;
+ ALOGD("use config data mask: %d", global_voice_setting.data_mask);
+ } else {
+ global_voice_setting.data_mask = DATA_TYPE_MASK_VOICE;
+ ALOGD("use default decode type: %d", global_voice_setting.data_mask);
+ }
+
+ ivalue = voice_get_int_config(CONFIG_GROUP_SETTINGS, CONFIG_ITEM_SETTINGS_AUTOCMD);
+ if(ivalue > 0) {
+ global_voice_setting.autocmd = ivalue;
+ ALOGD("use config decode type: %d", global_voice_setting.autocmd);
+ } else {
+ global_voice_setting.autocmd = AUTOCMD_AUTO;
+ ALOGD("use default decode type: %d", global_voice_setting.autocmd);
+ }
+
+ pthread_mutex_unlock(&mutex_voice_settings);
+ voice_conf_exit();
+ return 0;
+}
+
+void voice_open_store_file()
+{
+ char record_name[50] = {0};
+ sprintf(record_name, "%s%d", RAW_DATA_PATH, file_counter);
+
+ raw_fd = open (record_name, O_WRONLY | O_CREAT |O_TRUNC, 0644);
+
+ if(raw_fd < 0)
+ {
+ ALOGE("can't open record file:%s ", record_name);
+ }
+
+
+ return;
+}
+
+int voice_write_decode_buf(uint8* pu_decode, ssize_t len)
+{
+ if (raw_fd > 0)
+ {
+ write (raw_fd, pu_decode, len);
+ return 0;
+ }
+ return -1;
+}
+
+
+/**********************************************
+*
+* hidraw node related
+*
+***********************************************/
+const char *bus_str(int bus){
+ switch (bus) {
+ case BUS_USB:
+ return "USB";
+
+ case BUS_HIL:
+ return "HIL";
+
+ case BUS_BLUETOOTH:
+ return "Bluetooth";
+
+ case BUS_VIRTUAL:
+ return "Virtual";
+
+ default:
+ return "Other";
+ }
+}
+
+static int get_hidraw_info(int fd)
+{
+ int i, res, desc_size = 0;
+ char buf[256];
+ struct hidraw_report_descriptor rpt_desc;
+ struct hidraw_devinfo info;
+
+ memset(&rpt_desc, 0x0, sizeof(rpt_desc));
+ memset(&info, 0x0, sizeof(info));
+ memset(buf, 0x0, sizeof(buf));
+ debug("-----------------------------------------------\n");
+
+ /* Get Raw Name */
+ res = ioctl(fd, HIDIOCGRAWNAME(256), buf);
+ if (res < 0)
+ perror("HIDIOCGRAWNAME");
+ else
+ debug("Raw Name: %s\n", buf);
+ /* Get Physical Location */
+ res = ioctl(fd, HIDIOCGRAWPHYS(256), buf);
+ if (res < 0)
+ perror("HIDIOCGRAWPHYS");
+ else
+ debug("Raw Phys: %s\n", buf);
+ /* Get Raw Info */
+ res = ioctl(fd, HIDIOCGRAWINFO, &info);
+ if (res < 0) {
+ perror("HIDIOCGRAWINFO");
+ } else {
+ debug("Raw Info:");
+ debug(" bustype: %d (%s)", info.bustype, bus_str(info.bustype));
+ debug(" vendor: 0x%04x", info.vendor);
+ debug(" product: 0x%04x\n", info.product);
+ }
+ /* Get Report Descriptor Size */
+ res = ioctl(fd, HIDIOCGRDESCSIZE, &desc_size);
+ if (res < 0)
+ perror("HIDIOCGRDESCSIZE");
+ else
+ debug("Report Descriptor Size: %d\n", desc_size);
+ /* Get Report Descriptor */
+ rpt_desc.size = desc_size;
+ res = ioctl(fd, HIDIOCGRDESC, &rpt_desc);
+ if (res < 0) {
+ perror("HIDIOCGRDESC");
+ } else {
+ debug("Report Descriptor:");
+ for (i = 0; i < rpt_desc.size; i++)
+ {
+ if((i%16)==0)
+ debug("\n");
+ debug("%02x ", rpt_desc.value[i]);
+ }
+ debug("\n");
+ }
+ info("-----------------------------------------------\n");
+
+ return 0;
+}
+
+static int send_message(int fd, unsigned char * buf, int len)
+{
+ int res = 0;
+ res = write(fd, buf, len);
+ debug("send_message res=%d\n",res);
+ return res;
+}
+
+static void process_voice_data(unsigned char reportID, unsigned char *buf, int len) {
+ int ret = -1;
+ int offset = 0;
+ int i;
+ int decode_len = 0;
+
+ unsigned char output_buf[1024] = {0x00};
+
+ //debug("reportID=%d, decode_type=%d, global_reportID=%d, len=%d",
+ //reportID, global_voice_setting.decode_type, global_voice_setting.voice_data_reportID, len);
+
+ if(global_voice_setting.decode_type == DECODE_TYPE_MSBC) {
+ while(offset + BEE_MSBC_FRAME_SIZE <= len) {
+ //debug("offset is %d now, len is %d", offset, len);
+ ret = RS_deal_voice_stream_data(buf + offset, BEE_MSBC_FRAME_SIZE, output_buf, 1024, &decode_len);
+ if(ret < 0) {
+ offset++;
+ }else {
+ UIPC_Send_noblock(UIPC_CH_ID_VOICE_DATA, 0, output_buf, decode_len);
+ offset += BEE_MSBC_FRAME_SIZE;
+ }
+ }
+ }else if(global_voice_setting.decode_type == DECODE_TYPE_SBC) {
+ decode_len = 1024;
+ while(offset + BEE_SBC_FRAME_SIZE <= len) {
+ ret = sbcDecode(buf + offset, BEE_SBC_FRAME_SIZE, output_buf, &decode_len);
+ if(ret < 0) {
+ debug("fail to decode: %d", ret);
+ offset++;
+ }else {
+ UIPC_Send_noblock(UIPC_CH_ID_VOICE_DATA, 0, output_buf, decode_len);
+ offset += BEE_SBC_FRAME_SIZE;
+ }
+ }
+ }
+}
+
+static int read_message(int fd)
+{
+ unsigned char buf[4096];
+ int res,i;
+
+ unsigned char start_rec_command[] = {global_voice_setting.voice_cmd_reportID, 0x01};
+ unsigned char stop_rec_command[] = {global_voice_setting.voice_cmd_reportID, 0x00};
+ static int voice_kpressed = 0;
+
+/*
+ struct hidraw_devinfo info;
+
+ res = ioctl(fd, HIDIOCGRAWINFO, &info);
+ if (res < 0) {
+ perror("HIDIOCGRAWINFO");
+ }
+*/
+
+ //if( (info.vendor==global_voice_setting.vid) && (info.product==global_voice_setting.pid) )
+ //{
+ res = read(fd, buf, sizeof(buf));
+ if(res > 0)
+ {
+ //debug("Receive From :%04x,%04x number: %d", info.vendor, info.product, res);
+ if( (global_voice_setting.data_mask & DATA_TYPE_MASK_RAW) == DATA_TYPE_MASK_RAW) {
+ //just callback and return
+ UIPC_Send_noblock(UIPC_CH_ID_VOICE_DATA, 0, buf + 1, res - 1);
+ return 0;
+ }else if( (global_voice_setting.data_mask & DATA_TYPE_MASK_VOICE) == DATA_TYPE_MASK_VOICE) {
+ if((voice_kpressed == 0) && (buf[0] == global_voice_setting.voice_key_reportID) &&
+ (res == global_voice_setting.voice_keypress_data_len + 1) &&
+ (memcmp(buf + 1, global_voice_setting.voice_keypress_data, global_voice_setting.voice_keypress_data_len) == 0))
+ {
+ //debug("voice key pressed");
+ if(global_voice_setting.autocmd == AUTOCMD_AUTO) {
+ RS_voice_app_create_output();
+ RS_voice_app_create_origin_output();
+ voice_open_store_file();
+
+ send_message(fd, start_rec_command,sizeof(start_rec_command));
+ voice_kpressed = 1;
+ frame_counter = 0;
+ }
+ return 0;
+ }
+
+ // when voice key is released
+ if ((voice_kpressed == 1) && (buf[0] == global_voice_setting.voice_key_reportID) &&
+ (res == global_voice_setting.voice_keyrelease_data_len + 1) &&
+ (memcmp(buf + 1, global_voice_setting.voice_keyrelease_data, global_voice_setting.voice_keyrelease_data_len) == 0))
+ {
+ //debug("voice key relesed");
+
+ if(global_voice_setting.autocmd == AUTOCMD_AUTO) {
+ RS_stop_voice_stream_data();
+ send_message(fd, stop_rec_command,sizeof(stop_rec_command));
+ voice_kpressed = 0;
+ debug("total frame: %d", frame_counter);
+ close(raw_fd);
+ file_counter++;
+ raw_fd = -1;
+ }
+ return 0;
+ }
+
+ // store voice data
+ if ((voice_kpressed == 1 ) && (buf[0] == global_voice_setting.voice_data_reportID))
+ {
+ //debug("deal with voice data");
+ process_voice_data(buf[0], buf + 1, res-1);
+ voice_write_decode_buf(buf + 1, res - 1);
+ frame_counter++;
+ return 0;
+ }
+ }
+ }else {
+ warn("Read fd %d failed: %s", fd, strerror(errno));
+ return -1;
+ }
+
+ //}
+
+ return 0;
+}
+
+int get_dev_vid_pid_info(int fd, short* vid, short* pid) {
+ int res = -1;
+ struct hidraw_devinfo info;
+
+ memset(&info, 0x0, sizeof(info));
+
+ res = ioctl(fd, HIDIOCGRAWINFO, &info);
+ if (res < 0) {
+ debug("failed to get HIDIOCGRAWINFO");
+ } else {
+ //debug("Raw Info:");
+ //debug(" bustype: %d (%s)", info.bustype, bus_str(info.bustype));
+ debug(" vendor: 0x%04x, product: 0x%04x", info.vendor, info.product);
+ *vid = info.vendor;
+ *pid = info.product;
+ res = 1;
+ }
+ return res;
+}
+
+static int open_device(const char *device)
+{
+ int version;
+ int fd;
+ int clkid = CLOCK_MONOTONIC;
+ struct pollfd *new_ufds;
+ int *unfds;
+ char **new_device_names;
+ char **new_unused_device_names;
+ char name[80];
+ char location[80];
+ char idstr[80];
+ struct input_id id;
+ int res = -1;
+ struct hidraw_devinfo info;
+
+ fd = open(device, O_RDWR);
+ if(fd < 0) {
+ debug("could not open %s, %s\n", device, strerror(errno));
+ return -1;
+ }
+ debug("new fd is %d", fd);
+
+ res = ioctl(fd, HIDIOCGRAWINFO, &info);
+ if(res < 0) {
+ debug("failed to get hidraw_devinfo, add for now");
+ }else if(info.bustype != BUS_BLUETOOTH){
+ debug("ingore this device");
+ close(fd);
+ return -1;
+ }else if((info.vendor != global_voice_setting.vid) || (info.product != global_voice_setting.pid)) {
+ //res = unlink(fd);
+ debug("Not the device we care, add to unused fds");
+ unfds = realloc(unused_bt_hid_fds, sizeof(unused_bt_hid_fds[0]) * (nunusedfds + 1));
+ if(unfds == NULL) {
+ error("unused fds: out of memory");
+ return -1;
+ }
+
+ new_unused_device_names = realloc(unused_device_names, sizeof(unused_device_names[0]) * (nunusedfds + 1));
+ if(new_unused_device_names == NULL) {
+ error("unused device_names: out of memory");
+ return -1;
+ }
+
+ unused_bt_hid_fds = unfds;
+ unused_device_names = new_unused_device_names;
+
+ unused_bt_hid_fds[nunusedfds] = fd;
+ unused_device_names[nunusedfds] = strdup(device);
+ nunusedfds++;
+ return 0;
+ }
+
+ new_ufds = realloc(ufds, sizeof(ufds[0]) * (nfds + 1));
+ if(new_ufds == NULL) {
+ error("out of memory\n");
+ return -1;
+ }
+
+ ufds = new_ufds;
+ new_device_names = realloc(device_names, sizeof(device_names[0]) * (nfds + 1));
+ if(new_device_names == NULL) {
+ debug("out of memory\n");
+ return -1;
+ }
+ device_names = new_device_names;
+ //get_hidraw_info(fd);
+ ufds[nfds].fd = fd;
+ ufds[nfds].events = POLLIN;
+ device_names[nfds] = strdup(device);
+ nfds++;
+
+ return 0;
+}
+
+int close_device(const char *device)
+{
+ int i;
+ for(i = 1; i < nfds; i++) {
+ if(strcmp(device_names[i], device) == 0) {
+ int count = nfds - i - 1;
+ debug("remove device %d: %s\n", i, device);
+ free(device_names[i]);
+ memmove(device_names + i, device_names + i + 1, sizeof(device_names[0]) * count);
+ close(ufds[i].fd);
+ memmove(ufds + i, ufds + i + 1, sizeof(ufds[0]) * count);
+ nfds--;
+ return 0;
+ }
+ }
+
+ for(i = 0; i < nunusedfds; i++) {
+ if(strcmp(unused_device_names[i], device) == 0) {
+ int count = nunusedfds - i;
+ debug("remove unused device %d: %s\n", i, device);
+ free(unused_device_names[i]);
+ memmove(unused_device_names + i, unused_device_names + i + 1, sizeof(unused_device_names[0]) * count);
+ close(unused_bt_hid_fds[i]);
+ memmove(unused_bt_hid_fds + i, unused_bt_hid_fds + i + 1, sizeof(unused_bt_hid_fds[0]) * count);
+ nunusedfds--;
+ return 0;
+ }
+ }
+
+ error("remote device: %s not found\n", device);
+ return -1;
+}
+
+static int read_notify(const char *dirname, int nfd)
+{
+ int res;
+ char devname[PATH_MAX];
+ char *filename;
+ char event_buf[512];
+ int event_size;
+ int event_pos = 0;
+ struct inotify_event *event;
+
+ res = read(nfd, event_buf, sizeof(event_buf));
+ if(res < (int)sizeof(*event)) {
+ if(errno == EINTR)
+ return 0;
+ error("could not get event, %s\n", strerror(errno));
+ return 1;
+ }
+ //printf("got %d bytes of event information\n", res);
+
+ strcpy(devname, dirname);
+ filename = devname + strlen(devname);
+ *filename++ = '/';
+
+ while(res >= (int)sizeof(*event)) {
+ event = (struct inotify_event *)(event_buf + event_pos);
+ //debug("%d: %08x \"%s\"\n", event->wd, event->mask, event->len ? event->name : "");
+ if((event->len)&&(memcmp(event->name, "hidraw", strlen("hidraw"))==0)) {
+ debug("read_notify: %d: %08x \"%s\"\n", event->wd, event->mask, event->len ? event->name : "");
+ strcpy(filename, event->name);
+ if(event->mask & IN_CREATE) {
+ open_device(devname);
+ }
+ else {
+ close_device(devname);
+ }
+ }
+ event_size = sizeof(*event) + event->len;
+ res -= event_size;
+ event_pos += event_size;
+ }
+ return 0;
+}
+
+
+static int scan_dir(const char *dirname)
+{
+ char devname[PATH_MAX];
+ char *filename;
+ DIR *dir;
+ struct dirent *de;
+ dir = opendir(dirname);
+ if(dir == NULL)
+ return -1;
+ strcpy(devname, dirname);
+ filename = devname + strlen(devname);
+ *filename++ = '/';
+ while((de = readdir(dir))) {
+ if(de->d_name[0] == '.' &&
+ (de->d_name[1] == '\0' ||
+ (de->d_name[1] == '.' && de->d_name[2] == '\0')))
+ continue;
+ if(memcmp(de->d_name,"hidraw",strlen("hidraw")))
+ continue;
+ strcpy(filename, de->d_name);
+ //debug("scan_dir: %s\n",devname);
+ open_device(devname);
+ }
+ closedir(dir);
+ return 0;
+}
+
+static void voice_ctrl_recv(void)
+{
+ unsigned char cmd[256], opcode = 0xFF;
+ int n, i;
+
+ n = UIPC_Read(UIPC_CH_ID_VOICE_CTRL, NULL, cmd, 256);
+
+ /* detach on ctrl channel means audioflinger process was terminated */
+ if (n == 0)
+ {
+ debug("CTRL CH DETACHED");
+ //the ctrl channel will re-open automatically
+ UIPC_Close(UIPC_CH_ID_VOICE_CTRL);
+ return;
+ }
+
+ debug("receive voice-ctrl-cmd read num_of_data = %d ", n);
+ for (i=0; i< n; i++)
+ info("data[%d] = %d ", i, cmd[i]);
+ //receive start or stop cmd from service
+ if( cmd[0] <= OPCODE_MAX)
+ {
+ opcode = cmd[0];
+ }
+ else
+ {
+ //clear the memory
+ UIPC_Ioctl(UIPC_CH_ID_VOICE_CTRL, UIPC_REQ_RX_FLUSH,NULL);
+ info("it is wrong cmd send from service");
+ }
+
+ info("opcode = %d",opcode);
+ switch(opcode)
+ {
+ case OPCODE_SETTING_RESET: //0 cmd(1)
+ break;
+
+ case OPCODE_VOICE_START_CMD: //1 cmd(1)
+ debug("start, len=%d", n);
+ break;
+
+ case OPCODE_VOICE_STOP_CMD: //2 cmd(1)
+ debug("stop, len=%d", n);
+ break;
+
+ case OPCODE_SET_RCU_INFO: //3 cmd(1) + vid(2) + pid(2) + vers(2)
+ if(n == 7) {
+ int vid = (cmd[1] << 8) + cmd[2];
+ int pid = (cmd[3] << 8) + cmd[4];
+ int vers = (cmd[5] << 8) + cmd[6];
+ set_rcu_info(vid,pid,vers);
+ }
+ break;
+
+ case OPCODE_SET_VOICE_DATA_REPORT_ID: //4 cmd(1) + reportID(1)
+ if(n == 2) {
+ set_voice_data_reportID(cmd[1]);
+ }
+ break;
+
+ case OPCODE_SET_VOICE_CMD_REPORT_ID: //5 cmd(1) + reportID(1)
+ if(n == 2) {
+ set_voice_cmd_reportID(cmd[1]);
+ }
+ break;
+
+ case OPCODE_SET_VOICE_KEY_REPORT_ID: //6 cmd(1) + reportID(1)
+ if(n == 2) {
+ set_voice_key_reportID(cmd[1]);
+ }
+ break;
+
+ case OPCODE_SET_VOICE_KEYPRESS_DATA: //7 cmd(1) + len(1) + data(n)
+ if(n > 2) {
+ int len = cmd[1];
+ set_voice_keypress_data(len, cmd + 2);
+ }
+ break;
+
+ case OPCODE_SET_VOICE_KEYRELEASE_DATA: //8 cmd(1) + len(1) + data(n)
+ if(n > 2) {
+ int len = cmd[1];
+ set_voice_keyrelease_data(len, cmd + 2);
+ }
+ break;
+
+ case OPCODE_SET_VOICE_STARTCMD_DATA: //9 cmd(1) + len(1) + data(n)
+ debug("set voice start data, len=%d", cmd[1]);
+ break;
+
+ case OPCODE_SET_VOICE_STOPCMD_DATA: //10 cmd(1) + len(1) + data(n)
+ debug("set voice stop data, len=%d", cmd[1]);
+ break;
+
+ case OPCODE_SET_ENCODE_TYPE: //11 cmd(1) + type(1)
+ if(n == 2) {
+ set_encode_type(cmd[1]);
+ }
+ break;
+
+ case OPCODE_SET_DATA_TYPE_MASK: //12 cmd(1) + type(1)
+ debug("set type mask: 0x%02x", cmd[1]);
+ break;
+
+ case OPCODE_SET_AUTO_CMD: //13 cmd(1) + auto(1)
+ if(n == 2) {
+ set_auto_cmd(cmd[1]);
+ }
+ break;
+
+ case OPCODESEND_HIDRAW_DATA: //14 cmd(1) + reportID(1) + len(1) + data(n)
+ debug("send raw data, reportID=0x%02x, len=0x%02x", cmd[1], cmd[2]);
+ break;
+
+ case OPCODE_EXIT:
+ debug("exit");
+ gSocket_Running = 0;
+ }
+
+ info("voice-ctrl-cmd DOWN!");
+}
+
+static void voice_data_recv(void)
+{
+ unsigned char cmd[256], opcode = 0xFF;
+ int n, i;
+
+ n = UIPC_Read(UIPC_CH_ID_VOICE_DATA, NULL, cmd, 256);
+
+ /* detach on ctrl channel means audioflinger process was terminated */
+ if (n == 0)
+ {
+ debug("DATA CH DETACHED");
+ //the ctrl channel will re-open automatically
+ UIPC_Close(UIPC_CH_ID_VOICE_DATA);
+ return;
+ }
+
+ debug("receive voice-data read num_of_data = %d ", n);
+}
+
+
+static void ctrl_socket_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event)
+{
+
+ switch(event)
+ {
+ case UIPC_OPEN_EVT:
+ /*
+ in certain case, hid status msg must be sent upon ctrl chan opened
+ */
+ debug("Jim@control_socket_cb: sending hid status msg upon open");
+ break;
+
+ case UIPC_CLOSE_EVT:
+ if (gSocket_Running) {
+ debug("jim@control_socket_cb: re-open ctrl chan");
+ UIPC_Open(UIPC_CH_ID_VOICE_CTRL, ctrl_socket_cb);
+ }
+ break;
+
+ case UIPC_RX_DATA_EVT:
+ info("btif_voice_ctrl_cb, the event is UIPC_RX_DATA_EVT");
+
+ case UIPC_RX_DATA_READY_EVT:
+ voice_ctrl_recv();
+ break;
+
+ default :
+ info("### VOICE-CTRL-CHANNEL EVENT %d NOT HANDLED ###", event);
+ break;
+ }
+}
+
+static void data_socket_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event)
+{
+
+ debug("data_socket_cb");
+ switch(event)
+ {
+ case UIPC_OPEN_EVT:
+ debug("Jim@data_socket_cb: sending hid status msg upon open");
+ break;
+
+ case UIPC_CLOSE_EVT:
+ if (gSocket_Running) {
+ debug("jim@data_socket_cb: re-open data chan");
+ UIPC_Open(UIPC_CH_ID_VOICE_DATA, data_socket_cb);
+ }
+ break;
+
+ case UIPC_RX_DATA_EVT:
+ info("data_socket_cb, the event is UIPC_RX_DATA_EVT");
+
+ case UIPC_RX_DATA_READY_EVT:
+ voice_data_recv();
+ info("data_socket_cb, the event is UIPC_RX_DATA_READY_EVT");
+ break;
+
+ default :
+ info("### VOICE-DATA-CHANNEL EVENT %d NOT HANDLED ###", event);
+ break;
+ }
+}
+
+
+
+int init(void) {
+
+ pthread_mutex_init(&mutex_voice_settings, NULL);
+ voice_msbc_init();
+ sbcInitDecoder();
+
+ gSocket_Running = 1;
+ UIPC_Init(NULL);
+ UIPC_Open(UIPC_CH_ID_VOICE_CTRL, ctrl_socket_cb);
+ UIPC_Open(UIPC_CH_ID_VOICE_DATA, data_socket_cb);
+
+ return 0;
+}
+
+void cleanup(void) {
+
+ gSocket_Running = 0;
+ UIPC_Close(UIPC_CH_ID_VOICE_DATA);
+ UIPC_Close(UIPC_CH_ID_VOICE_CTRL);
+
+ pthread_mutex_lock(&mutex_voice_settings);
+
+
+ if(global_voice_setting.voice_keypress_data != NULL)
+ free(global_voice_setting.voice_keypress_data);
+
+ if(global_voice_setting.voice_keyrelease_data != NULL)
+ free(global_voice_setting.voice_keyrelease_data);
+
+ pthread_mutex_unlock(&mutex_voice_settings);
+ //release other resources here
+}
+
+
+int main(void) {
+ const char *device_path = "/dev";
+ int res;
+ int i;
+
+ init();
+
+ nfds = 1;
+ ufds = calloc(1, sizeof(ufds[0]));
+ ufds[0].fd = inotify_init();
+ ufds[0].events = POLLIN;
+
+ res = inotify_add_watch(ufds[0].fd, device_path, IN_DELETE | IN_CREATE);
+ if(res < 0) {
+ error("could not add watch for %s, %s\n", device_path, strerror(errno));
+ return -1;
+ }
+
+ res = scan_dir(device_path);
+ if(res < 0) {
+ error("scan dir failed for %s\n", device_path);
+ return -2;
+ }
+
+ while(gSocket_Running) {
+ poll(ufds, nfds, -1);
+ if(ufds[0].revents & POLLIN) {
+ //debug("new notify event!!!");
+ read_notify(device_path, ufds[0].fd);
+ }
+
+ for(i = 1; i < nfds; i++) {
+ if(ufds[i].revents) {
+ /*
+ //debug("new message event, fd = %d, event = %04x.", ufds[i].fd, ufds[i].revents);
+ if((ufds[i].revents & POLLHUP) && (ufds[i].revents & POLLERR)) {
+ debug("close, fd=%d, events=0x%04x", ufds[i].fd, ufds[i].revents);
+ close(ufds[i].fd);
+
+ }else if(ufds[i].revents & POLLIN) {
+ //debug("new message event!!!");
+ read_message(ufds[i].fd);
+ }
+ */
+ if(ufds[i].revents & POLLIN) {
+ //debug("new message event!!!");
+ read_message(ufds[i].fd);
+ }
+ }
+ }
+ }
+ cleanup();
+
+ return 0;
+
+}
+
diff --git a/addon/vr_bee1_hidraw_daemon/hidraw/voice_hidraw.h b/addon/vr_bee1_hidraw_daemon/hidraw/voice_hidraw.h
new file mode 100755
index 0000000..7e96138
--- /dev/null
+++ b/addon/vr_bee1_hidraw_daemon/hidraw/voice_hidraw.h
@@ -0,0 +1,55 @@
+#ifndef VOICE_HIDRAW_H
+#define VOICE_HIDRAW_H
+
+#include <cutils/log.h>
+
+
+#define DECODE_TYPE_MSBC 1
+#define DECODE_TYPE_SBC 2
+#define DECODE_TYPE_MAX 2
+
+#define DATA_TYPE_MASK_VOICE (0x01)
+#define DATA_TYPE_MASK_RAW (0x02)
+
+#define AUTOCMD_AUTO 1
+#define AUTOCMD_NONE 2
+
+#define SW_VERSION (0x0000)
+
+#define CONFIG_PATH "/system/etc/hidraw_setting"
+
+
+#define warn(fmt, ...) ALOGW ("## WARNING : %s(L%d): " fmt "##",__FUNCTION__, __LINE__, ## __VA_ARGS__)
+#define error(fmt, ...) ALOGE ("## ERROR : %s(L%d): " fmt "##",__FUNCTION__, __LINE__, ## __VA_ARGS__)
+
+#define info(fmt, ...) ALOGI ("%s(L%d): " fmt,__FUNCTION__, __LINE__, ## __VA_ARGS__)
+#define debug(fmt, ...) ALOGD ("%s(L%d): " fmt,__FUNCTION__, __LINE__, ## __VA_ARGS__)
+
+
+#define VOICE_DATA_PATH "/data/misc/bluedroid/.voice_data"
+#define VOICE_CTRL_PATH "/data/misc/bluedroid/.voice_ctrl"
+
+
+
+//supported opcode
+
+#define OPCODE_SETTING_RESET 0 //cmd(1)
+#define OPCODE_VOICE_START_CMD 1 //cmd(1)
+#define OPCODE_VOICE_STOP_CMD 2 //cmd(1)
+#define OPCODE_SET_RCU_INFO 3 //cmd(1) + vid(2) + pid(2) + vers(2)
+#define OPCODE_SET_VOICE_DATA_REPORT_ID 4 //cmd(1) + reportID(1)
+#define OPCODE_SET_VOICE_CMD_REPORT_ID 5 //cmd(1) + reportID(1)
+#define OPCODE_SET_VOICE_KEY_REPORT_ID 6 //cmd(1) + reportID(1)
+#define OPCODE_SET_VOICE_KEYPRESS_DATA 7 //cmd(1) + len(1) + data(n)
+#define OPCODE_SET_VOICE_KEYRELEASE_DATA 8 //cmd(1) + len(1) + data(n)
+#define OPCODE_SET_VOICE_STARTCMD_DATA 9 //cmd(1) + len(1) + data(n)
+#define OPCODE_SET_VOICE_STOPCMD_DATA 10 //cmd(1) + len(1) + data(n)
+#define OPCODE_SET_ENCODE_TYPE 11 //cmd(1) + type(1)
+#define OPCODE_SET_DATA_TYPE_MASK 12 //cmd(1) + type(1)
+#define OPCODE_SET_AUTO_CMD 13 //cmd(1) + auto(1)
+#define OPCODESEND_HIDRAW_DATA 14 //cmd(1) + reportID(1) + len(1) + data(n)
+#define OPCODE_EXIT 15 //cmd(1)
+
+#define OPCODE_MAX 15
+
+#endif
diff --git a/addon/vr_bee1_hidraw_daemon/hidraw/voice_uipc.c b/addon/vr_bee1_hidraw_daemon/hidraw/voice_uipc.c
new file mode 100755
index 0000000..567dd85
--- /dev/null
+++ b/addon/vr_bee1_hidraw_daemon/hidraw/voice_uipc.c
@@ -0,0 +1,916 @@
+/*****************************************************************************
+ *
+ * Filename: uipc.c
+ *
+ * Description: UIPC implementation for bluedroid
+ *
+ *****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <signal.h>
+#include <errno.h>
+#include <pthread.h>
+#include <sys/select.h>
+#include <sys/poll.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/prctl.h>
+
+
+#include "voice_uipc.h"
+#include "voice_hidraw.h"
+
+#include <cutils/sockets.h>
+
+volatile int uipc_inited = 0;
+
+
+/*****************************************************************************
+** Constants & Macros
+******************************************************************************/
+
+#define MAX(a,b) ((a)>(b)?(a):(b))
+
+#define CASE_RETURN_STR(const) case const: return #const;
+
+#define UIPC_DISCONNECTED (-1)
+
+#define UIPC_LOCK() /*BTIF_TRACE_EVENT(" %s lock", __FUNCTION__);*/ pthread_mutex_lock(&uipc_main.mutex);
+#define UIPC_UNLOCK() /*BTIF_TRACE_EVENT("%s unlock", __FUNCTION__);*/ pthread_mutex_unlock(&uipc_main.mutex);
+
+#define SAFE_FD_ISSET(fd, set) (((fd) == -1) ? 0 : FD_ISSET((fd), (set)))
+
+#define UIPC_FLUSH_BUFFER_SIZE 1024
+
+/*****************************************************************************
+** Local type definitions
+******************************************************************************/
+
+typedef enum {
+ UIPC_TASK_FLAG_DISCONNECT_CHAN = 0x1,
+} tUIPC_TASK_FLAGS;
+
+typedef struct {
+ int srvfd;
+ int fd;
+ int read_poll_tmo_ms;
+ int task_evt_flags; /* event flags pending to be processed in read task */
+ tUIPC_EVENT cond_flags;
+ pthread_mutex_t cond_mutex;
+ pthread_cond_t cond;
+ tUIPC_RCV_CBACK *cback;
+} tUIPC_CHAN;
+
+typedef struct {
+ pthread_t tid; /* main thread id */
+ int running;
+ pthread_mutex_t mutex;
+
+ fd_set active_set;
+ fd_set read_set;
+ int max_fd;
+ int signal_fds[2];
+
+ tUIPC_CHAN ch[UIPC_CH_NUM];
+} tUIPC_MAIN;
+
+
+/*****************************************************************************
+** Static variables
+******************************************************************************/
+
+static tUIPC_MAIN uipc_main;
+
+
+/*****************************************************************************
+** Static functions
+******************************************************************************/
+
+static int uipc_close_ch_locked(tUIPC_CH_ID ch_id);
+
+/*****************************************************************************
+** Externs
+******************************************************************************/
+
+
+/*****************************************************************************
+** Helper functions
+******************************************************************************/
+
+
+const char* dump_uipc_event(tUIPC_EVENT event)
+{
+ switch(event)
+ {
+ CASE_RETURN_STR(UIPC_OPEN_EVT)
+ CASE_RETURN_STR(UIPC_CLOSE_EVT)
+ CASE_RETURN_STR(UIPC_RX_DATA_EVT)
+ CASE_RETURN_STR(UIPC_RX_DATA_READY_EVT)
+ CASE_RETURN_STR(UIPC_TX_DATA_READY_EVT)
+ default:
+ return "UNKNOWN MSG ID";
+ }
+}
+
+/*****************************************************************************
+** socket helper functions
+*****************************************************************************/
+
+static inline int create_server_socket(const char* name)
+{
+ int s = socket(AF_LOCAL, SOCK_STREAM, 0);
+ if (s < 0)
+ return -1;
+
+ info("create_server_socket %s", name);
+
+ if(socket_local_server_bind(s, name, ANDROID_SOCKET_NAMESPACE_ABSTRACT) < 0)
+ {
+ error("socket failed to create (%s)", strerror(errno));
+ close(s);
+ return -1;
+ }
+
+ if(listen(s, 5) < 0)
+ {
+ error("listen failed", strerror(errno));
+ close(s);
+ return -1;
+ }
+
+ info("created socket fd %d", s);
+ return s;
+}
+
+static int accept_server_socket(int sfd)
+{
+ struct sockaddr_un remote;
+ struct pollfd pfd;
+ int fd;
+ socklen_t len = sizeof(struct sockaddr_un);
+
+ info("accept fd %d", sfd);
+
+ /* make sure there is data to process */
+ pfd.fd = sfd;
+ pfd.events = POLLIN;
+
+ if (poll(&pfd, 1, 0) == 0)
+ {
+ error("accept poll timeout");
+ return -1;
+ }
+
+ //BTIF_TRACE_EVENT("poll revents 0x%x", pfd.revents);
+
+ if ((fd = accept(sfd, (struct sockaddr *)&remote, &len)) == -1)
+ {
+ error("sock accept failed (%s)", strerror(errno));
+ return -1;
+ }
+
+ //BTIF_TRACE_EVENT("new fd %d", fd);
+
+ return fd;
+}
+
+/*****************************************************************************
+**
+** uipc helper functions
+**
+*****************************************************************************/
+
+static int uipc_main_init(void)
+{
+ int i;
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(&uipc_main.mutex, &attr);
+
+ debug("### uipc_main_init ###");
+
+ /* setup interrupt socket pair */
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, uipc_main.signal_fds) < 0)
+ {
+ return -1;
+ }
+
+ FD_SET(uipc_main.signal_fds[0], &uipc_main.active_set);
+ uipc_main.max_fd = MAX(uipc_main.max_fd, uipc_main.signal_fds[0]);
+
+ for (i=0; i< UIPC_CH_NUM; i++)
+ {
+ tUIPC_CHAN *p = &uipc_main.ch[i];
+ p->srvfd = UIPC_DISCONNECTED;
+ p->fd = UIPC_DISCONNECTED;
+ p->task_evt_flags = 0;
+ pthread_cond_init(&p->cond, NULL);
+ pthread_mutex_init(&p->cond_mutex, NULL);
+ p->cback = NULL;
+ }
+
+ return 0;
+}
+
+void uipc_main_cleanup(void)
+{
+ int i;
+
+ info("uipc_main_cleanup");
+
+ close(uipc_main.signal_fds[0]);
+ close(uipc_main.signal_fds[1]);
+
+ /* close any open channels */
+ for (i=0; i<UIPC_CH_NUM; i++)
+ uipc_close_ch_locked(i);
+}
+
+
+
+/* check pending events in read task */
+static void uipc_check_task_flags_locked(void)
+{
+ int i;
+
+ for (i=0; i<UIPC_CH_NUM; i++)
+ {
+ //BTIF_TRACE_EVENT("CHECK TASK FLAGS %x %x", uipc_main.ch[i].task_evt_flags, UIPC_TASK_FLAG_DISCONNECT_CHAN);
+ if (uipc_main.ch[i].task_evt_flags & UIPC_TASK_FLAG_DISCONNECT_CHAN)
+ {
+ uipc_main.ch[i].task_evt_flags &= ~UIPC_TASK_FLAG_DISCONNECT_CHAN;
+ uipc_close_ch_locked(i);
+ }
+
+ /* add here */
+
+ }
+}
+
+
+static int uipc_check_fd_locked(tUIPC_CH_ID ch_id)
+{
+ if (ch_id >= UIPC_CH_NUM)
+ return -1;
+
+ //BTIF_TRACE_EVENT("CHECK SRVFD %d (ch %d)", uipc_main.ch[ch_id].srvfd, ch_id);
+
+ if (SAFE_FD_ISSET(uipc_main.ch[ch_id].srvfd, &uipc_main.read_set))
+ {
+ debug("INCOMING CONNECTION ON CH %d", ch_id);
+
+ uipc_main.ch[ch_id].fd = accept_server_socket(uipc_main.ch[ch_id].srvfd);
+
+ debug("NEW FD %d", uipc_main.ch[ch_id].fd);
+
+ if ((uipc_main.ch[ch_id].fd > 0) && uipc_main.ch[ch_id].cback)
+ {
+ /* if we have a callback we should add this fd to the active set
+ and notify user with callback event */
+ debug("ADD FD %d TO ACTIVE SET", uipc_main.ch[ch_id].fd);
+ FD_SET(uipc_main.ch[ch_id].fd, &uipc_main.active_set);
+ uipc_main.max_fd = MAX(uipc_main.max_fd, uipc_main.ch[ch_id].fd);
+ }
+
+ if (uipc_main.ch[ch_id].fd < 0)
+ {
+ error("FAILED TO ACCEPT CH %d (%s)", ch_id, strerror(errno));
+ return -1;
+ }
+
+ if (uipc_main.ch[ch_id].cback)
+ uipc_main.ch[ch_id].cback(ch_id, UIPC_OPEN_EVT);
+ }
+
+ //BTIF_TRACE_EVENT("CHECK FD %d (ch %d)", uipc_main.ch[ch_id].fd, ch_id);
+
+ if (SAFE_FD_ISSET(uipc_main.ch[ch_id].fd, &uipc_main.read_set))
+ {
+ //BTIF_TRACE_EVENT("INCOMING DATA ON CH %d", ch_id);
+
+ if (uipc_main.ch[ch_id].cback)
+ uipc_main.ch[ch_id].cback(ch_id, UIPC_RX_DATA_READY_EVT);
+ }
+ return 0;
+}
+
+static void uipc_check_interrupt_locked(void)
+{
+ if (SAFE_FD_ISSET(uipc_main.signal_fds[0], &uipc_main.read_set))
+ {
+ char sig_recv = 0;
+ //BTIF_TRACE_EVENT("UIPC INTERRUPT");
+ recv(uipc_main.signal_fds[0], &sig_recv, sizeof(sig_recv), MSG_WAITALL);
+ }
+}
+
+static inline void uipc_wakeup_locked(void)
+{
+ char sig_on = 1;
+ info("UIPC SEND WAKE UP");
+ send(uipc_main.signal_fds[1], &sig_on, sizeof(sig_on), 0);
+}
+
+static int uipc_setup_server_locked(tUIPC_CH_ID ch_id, char *name, tUIPC_RCV_CBACK *cback)
+{
+ int fd;
+
+ debug("SETUP CHANNEL SERVER %d", ch_id);
+
+ if (ch_id >= UIPC_CH_NUM)
+ return -1;
+
+ UIPC_LOCK();
+
+ fd = create_server_socket(name);
+
+ if (fd < 0)
+ {
+ error("failed to setup %s", name, strerror(errno));
+ UIPC_UNLOCK();
+ return -1;
+ }
+
+ debug("ADD SERVER FD TO ACTIVE SET %d", fd);
+ FD_SET(fd, &uipc_main.active_set);
+ uipc_main.max_fd = MAX(uipc_main.max_fd, fd);
+
+ uipc_main.ch[ch_id].srvfd = fd;
+ uipc_main.ch[ch_id].cback = cback;
+ uipc_main.ch[ch_id].read_poll_tmo_ms = DEFAULT_READ_POLL_TMO_MS;
+
+ /* trigger main thread to update read set */
+ uipc_wakeup_locked();
+
+ UIPC_UNLOCK();
+
+ return 0;
+}
+
+static void uipc_flush_ch_locked(tUIPC_CH_ID ch_id)
+{
+ char buf[UIPC_FLUSH_BUFFER_SIZE];
+ struct pollfd pfd;
+ int ret;
+
+ pfd.events = POLLIN;
+ pfd.fd = uipc_main.ch[ch_id].fd;
+
+ if (uipc_main.ch[ch_id].fd == UIPC_DISCONNECTED)
+ {
+ debug("%s() - fd disconnected. Exiting", __FUNCTION__);
+ return;
+ }
+
+ while (1)
+ {
+ ret = poll(&pfd, 1, 1);
+ info("%s() - polling fd %d, revents: 0x%x, ret %d",
+ __FUNCTION__, pfd.fd, pfd.revents, ret);
+
+ if (pfd.revents & (POLLERR|POLLHUP))
+ {
+ debug("%s() - POLLERR or POLLHUP. Exiting", __FUNCTION__);
+ return;
+ }
+
+ if (ret <= 0)
+ {
+ error("%s() - error (%d). Exiting", __FUNCTION__, ret);
+ return;
+ }
+
+ /* read sufficiently large buffer to ensure flush empties socket faster than
+ it is getting refilled */
+ read(pfd.fd, &buf, UIPC_FLUSH_BUFFER_SIZE);
+ }
+}
+
+
+static void uipc_flush_locked(tUIPC_CH_ID ch_id)
+{
+ if (ch_id >= UIPC_CH_NUM)
+ return;
+
+ switch(ch_id)
+ {
+ case UIPC_CH_ID_VOICE_DATA:
+ uipc_flush_ch_locked(UIPC_CH_ID_VOICE_DATA);
+ break;
+
+ case UIPC_CH_ID_VOICE_CTRL:
+ uipc_flush_ch_locked(UIPC_CH_ID_VOICE_CTRL);
+ break;
+ }
+}
+
+
+static int uipc_close_ch_locked(tUIPC_CH_ID ch_id)
+{
+ int wakeup = 0;
+
+ debug("CLOSE CHANNEL %d", ch_id);
+
+ if (ch_id >= UIPC_CH_NUM)
+ return -1;
+
+ if (uipc_main.ch[ch_id].srvfd != UIPC_DISCONNECTED)
+ {
+ info("CLOSE SERVER (FD %d)", uipc_main.ch[ch_id].srvfd);
+ close(uipc_main.ch[ch_id].srvfd);
+ FD_CLR(uipc_main.ch[ch_id].srvfd, &uipc_main.active_set);
+ uipc_main.ch[ch_id].srvfd = UIPC_DISCONNECTED;
+ wakeup = 1;
+ }
+
+ if (uipc_main.ch[ch_id].fd != UIPC_DISCONNECTED)
+ {
+ info("CLOSE CONNECTION (FD %d)", uipc_main.ch[ch_id].fd);
+ close(uipc_main.ch[ch_id].fd);
+ FD_CLR(uipc_main.ch[ch_id].fd, &uipc_main.active_set);
+ uipc_main.ch[ch_id].fd = UIPC_DISCONNECTED;
+ wakeup = 1;
+ }
+
+ /* notify this connection is closed */
+ if (uipc_main.ch[ch_id].cback)
+ uipc_main.ch[ch_id].cback(ch_id, UIPC_CLOSE_EVT);
+
+ /* trigger main thread update if something was updated */
+ if (wakeup)
+ uipc_wakeup_locked();
+
+ return 0;
+}
+
+
+void uipc_close_locked(tUIPC_CH_ID ch_id)
+{
+ if (uipc_main.ch[ch_id].srvfd == UIPC_DISCONNECTED)
+ {
+ warn("CHANNEL %d ALREADY CLOSED", ch_id);
+ return;
+ }
+
+ /* schedule close on this channel */
+ uipc_main.ch[ch_id].task_evt_flags |= UIPC_TASK_FLAG_DISCONNECT_CHAN;
+ uipc_wakeup_locked();
+}
+
+
+static void uipc_read_task(void *arg)
+{
+ int ch_id;
+ int result;
+
+ prctl(PR_SET_NAME, (unsigned long)"uipc-main", 0, 0, 0);
+
+
+ while (uipc_main.running)
+ {
+ uipc_main.read_set = uipc_main.active_set;
+
+ result = select(uipc_main.max_fd+1, &uipc_main.read_set, NULL, NULL, NULL);
+
+ if (result == 0)
+ {
+ info("select timeout");
+ continue;
+ }
+ else if (result < 0)
+ {
+ warn("select failed %s", strerror(errno));
+ continue;
+ }
+
+ UIPC_LOCK();
+
+ /* clear any wakeup interrupt */
+ uipc_check_interrupt_locked();
+
+ /* check pending task events */
+ uipc_check_task_flags_locked();
+
+
+ /* check for other connections */
+ for (ch_id = 0; ch_id < UIPC_CH_NUM; ch_id++)
+ {
+ uipc_check_fd_locked(ch_id);
+ }
+
+ UIPC_UNLOCK();
+ }
+
+ debug("UIPC READ THREAD EXITING");
+
+ uipc_main_cleanup();
+
+ uipc_main.tid = 0;
+
+ debug("UIPC READ THREAD DONE");
+}
+
+
+int uipc_start_main_server_thread(void)
+{
+ uipc_main.running = 1;
+
+ if (pthread_create(&uipc_main.tid, (const pthread_attr_t *) NULL, (void*)uipc_read_task, NULL) < 0)
+ {
+ error("uipc_thread_create pthread_create failed:%d", errno);
+ return -1;
+ }
+
+ return 0;
+}
+
+/* blocking call */
+void uipc_stop_main_server_thread(void)
+{
+ /* request shutdown of read thread */
+ UIPC_LOCK();
+ uipc_main.running = 0;
+ uipc_wakeup_locked();
+ UIPC_UNLOCK();
+
+ /* wait until read thread is fully terminated */
+ /* tid might hold pointer value where it's value
+ is negative vaule with singed bit is set, so
+ corrected the logic to check zero or non zero */
+ if (uipc_main.tid)
+ pthread_join(uipc_main.tid, NULL);
+}
+
+/*******************************************************************************
+ **
+ ** Function UIPC_Init
+ **
+ ** Description Initialize UIPC module
+ **
+ ** Returns void
+ **
+ *******************************************************************************/
+
+void UIPC_Init(void *p_data)
+{
+ debug("UIPC_Init");
+ if (uipc_inited == 1)
+ {
+ return;
+ }
+ uipc_inited = 1;
+
+ memset(&uipc_main, 0, sizeof(tUIPC_MAIN));
+
+ uipc_main_init();
+
+ uipc_start_main_server_thread();
+}
+
+/*******************************************************************************
+ **
+ ** Function UIPC_Open
+ **
+ ** Description Open UIPC interface
+ **
+ ** Returns TRUE in case of success, FALSE in case of failure.
+ **
+ *******************************************************************************/
+int UIPC_Open(tUIPC_CH_ID ch_id, tUIPC_RCV_CBACK *p_cback)
+{
+ debug("UIPC_Open : ch_id %d, p_cback %x", ch_id, p_cback);
+
+ UIPC_LOCK();
+
+ if (ch_id >= UIPC_CH_NUM)
+ {
+ UIPC_UNLOCK();
+ return -1;
+ }
+
+ if (uipc_main.ch[ch_id].srvfd != UIPC_DISCONNECTED)
+ {
+ debug("CHANNEL %d ALREADY OPEN", ch_id);
+
+ if(uipc_main.ch[ch_id].fd > 0)
+ {
+ debug("the client socket is not disconnect");
+ }
+
+ UIPC_UNLOCK();
+ return 0;
+ }
+
+ switch(ch_id)
+ {
+ case UIPC_CH_ID_VOICE_CTRL:
+ uipc_setup_server_locked(ch_id, VOICE_CTRL_PATH, p_cback);
+ break;
+
+ case UIPC_CH_ID_VOICE_DATA:
+ uipc_setup_server_locked(ch_id, VOICE_DATA_PATH, p_cback);
+ break;
+
+ }
+
+ UIPC_UNLOCK();
+
+ return 0;
+}
+
+/*******************************************************************************
+ **
+ ** Function UIPC_Close
+ **
+ ** Description Close UIPC interface
+ **
+ ** Returns void
+ **
+ *******************************************************************************/
+
+void UIPC_Close(tUIPC_CH_ID ch_id)
+{
+ debug("UIPC_Close : ch_id %d", ch_id);
+
+ /* special case handling uipc shutdown */
+ if (ch_id != UIPC_CH_ID_ALL)
+ {
+ UIPC_LOCK();
+ uipc_close_locked(ch_id);
+ UIPC_UNLOCK();
+ }
+ else
+ {
+
+ int i;
+ for (i=0; i<UIPC_CH_NUM; i++)
+ uipc_close_ch_locked(i);
+
+ info("UIPC_Close : waiting for shutdown to complete");
+ uipc_stop_main_server_thread();
+ debug("UIPC_Close : shutdown complete");
+ }
+}
+
+/*******************************************************************************
+ **
+ ** Function UIPC_Send
+ **
+ ** Description Called to transmit a message over UIPC.
+ **
+ ** Returns TRUE in case of success, FALSE in case of failure.
+ **
+ *******************************************************************************/
+int UIPC_Send(tUIPC_CH_ID ch_id, unsigned short msg_evt, unsigned char *p_buf,
+ unsigned short msglen)
+{
+ int ret = false;
+
+ info("UIPC_Send : ch_id:%d %d bytes", ch_id, msglen);
+
+ UIPC_LOCK();
+
+ if (write(uipc_main.ch[ch_id].fd, p_buf, msglen) < 0)
+ {
+ error("failed to write (%s)", strerror(errno));
+ ret = errno;
+ }
+
+ UIPC_UNLOCK();
+
+ return ret;
+
+}
+int UIPC_Send_noblock(tUIPC_CH_ID ch_id, unsigned short msg_evt, unsigned char *p_buf, unsigned short msglen)
+{
+ int res = 0;
+ struct pollfd pfd;
+ int fd = uipc_main.ch[ch_id].fd;
+
+ UIPC_LOCK();
+
+ pfd.fd = fd;
+ pfd.events = POLLOUT|POLLHUP;
+ if (poll(&pfd, 1, 0) == 0)
+ {
+ goto unlock;
+ }
+
+ if (pfd.revents & (POLLHUP|POLLNVAL) )
+ {
+ debug("poll : channel detached remotely");
+ uipc_close_locked(ch_id);
+ goto unlock;
+ }
+
+ res = send(uipc_main.ch[ch_id].fd, p_buf, msglen, MSG_DONTWAIT);
+ if (res < 0)
+ {
+ error("failed to write (%s)", strerror(errno));
+ }
+
+unlock:
+ UIPC_UNLOCK();
+
+ return res;
+}
+
+
+int UIPC_Read_noblock(tUIPC_CH_ID ch_id, unsigned short *p_msg_evt, unsigned char *p_buf, unsigned int len)
+{
+ int n;
+ int n_read = 0;
+ int fd = uipc_main.ch[ch_id].fd;
+ struct pollfd pfd;
+
+ if (ch_id >= UIPC_CH_NUM)
+ {
+ error("UIPC_Read_noblock : invalid ch id %d", ch_id);
+ return 0;
+ }
+
+ if (fd == UIPC_DISCONNECTED)
+ {
+ error("UIPC_Read_noblock : channel %d closed", ch_id);
+ return 0;
+ }
+
+ pfd.fd = fd;
+ pfd.events = POLLIN|POLLHUP;
+
+ if (poll(&pfd, 1, 0) == 0)
+ {
+ return 0;
+ }
+
+ if (pfd.revents & (POLLHUP|POLLNVAL) )
+ {
+ debug("poll : channel detached remotely");
+ UIPC_LOCK();
+ uipc_close_locked(ch_id);
+ UIPC_UNLOCK();
+ return 0;
+ }
+
+ n_read = recv(fd, p_buf, len, MSG_DONTWAIT|MSG_NOSIGNAL);
+
+ return n_read;
+}
+
+/*******************************************************************************
+ **
+ ** Function UIPC_Read
+ **
+ ** Description Called to read a message from UIPC.
+ **
+ ** Returns return the number of bytes read.
+ **
+ *******************************************************************************/
+
+int UIPC_Read(tUIPC_CH_ID ch_id, unsigned short *p_msg_evt, unsigned char *p_buf, unsigned int len)
+{
+ int n;
+ int n_read = 0;
+ int fd = uipc_main.ch[ch_id].fd;
+ struct pollfd pfd;
+
+
+ if (ch_id >= UIPC_CH_NUM)
+ {
+ error("UIPC_Read : invalid ch id %d", ch_id);
+ return 0;
+ }
+
+ if (fd == UIPC_DISCONNECTED)
+ {
+ error("UIPC_Read : channel %d closed", ch_id);
+ return 0;
+ }
+
+ //BTIF_TRACE_DEBUG("UIPC_Read : ch_id %d, len %d, fd %d, polltmo %d", ch_id, len,
+ // fd, uipc_main.ch[ch_id].read_poll_tmo_ms);
+
+ while (n_read < (int)len)
+ {
+ pfd.fd = fd;
+ pfd.events = POLLIN|POLLHUP;
+
+ /* make sure there is data prior to attempting read to avoid blocking
+ a read for more than poll timeout */
+ if (poll(&pfd, 1, uipc_main.ch[ch_id].read_poll_tmo_ms) == 0)
+ {
+ debug("poll timeout (%d ms)", uipc_main.ch[ch_id].read_poll_tmo_ms);
+ break;
+ }
+
+ //BTIF_TRACE_EVENT("poll revents %x", pfd.revents);
+
+ if (pfd.revents & (POLLHUP|POLLNVAL) )
+ {
+ debug("poll : channel detached remotely");
+ UIPC_LOCK();
+ uipc_close_locked(ch_id);
+ UIPC_UNLOCK();
+ return 0;
+ }
+
+ n = recv(fd, p_buf+n_read, len-n_read, 0);
+
+ //BTIF_TRACE_EVENT("read %d bytes", n);
+
+ if (n == 0)
+ {
+ debug("UIPC_Read : channel detached remotely");
+ UIPC_LOCK();
+ uipc_close_locked(ch_id);
+ UIPC_UNLOCK();
+ return 0;
+ }
+
+ if (n < 0)
+ {
+ warn("UIPC_Read : read failed (%s)", strerror(errno));
+ return 0;
+ }
+
+ n_read+=n;
+
+ }
+
+ return n_read;
+}
+
+/*******************************************************************************
+**
+** Function UIPC_Ioctl
+**
+** Description Called to control UIPC.
+**
+** Returns void
+**
+*******************************************************************************/
+
+extern int UIPC_Ioctl(tUIPC_CH_ID ch_id, unsigned int request, void *param)
+{
+ info("#### UIPC_Ioctl : ch_id %d, request %d ####", ch_id, request);
+
+ UIPC_LOCK();
+
+ switch(request)
+ {
+ case UIPC_REQ_RX_FLUSH:
+ uipc_flush_locked(ch_id);
+ break;
+
+ case UIPC_REG_CBACK:
+ //BTIF_TRACE_EVENT("register callback ch %d srvfd %d, fd %d", ch_id, uipc_main.ch[ch_id].srvfd, uipc_main.ch[ch_id].fd);
+ uipc_main.ch[ch_id].cback = (tUIPC_RCV_CBACK*)param;
+ break;
+
+ case UIPC_REG_REMOVE_ACTIVE_READSET:
+
+ /* user will read data directly and not use select loop */
+ if (uipc_main.ch[ch_id].fd != UIPC_DISCONNECTED)
+ {
+ /* remove this channel from active set */
+ FD_CLR(uipc_main.ch[ch_id].fd, &uipc_main.active_set);
+
+ /* refresh active set */
+ uipc_wakeup_locked();
+ }
+ break;
+
+ case UIPC_SET_READ_POLL_TMO:
+ uipc_main.ch[ch_id].read_poll_tmo_ms = (intptr_t)param;
+ debug("UIPC_SET_READ_POLL_TMO : CH %d, TMO %d ms", ch_id, uipc_main.ch[ch_id].read_poll_tmo_ms );
+ break;
+
+ case UIPC_SET_SNDBUFSIZE:
+ info("UIPC_SET_SNDBUFSIZE : CH %d, size %d", ch_id, (int)param);
+ if (uipc_main.ch[ch_id].fd != UIPC_DISCONNECTED)
+ {
+ setsockopt(uipc_main.ch[ch_id].fd , SOL_SOCKET, SO_SNDBUF, (char*)&param, (int)sizeof(int));
+ }
+ break;
+
+
+ default:
+ debug("UIPC_Ioctl : request not handled (%d)", request);
+ break;
+ }
+
+ UIPC_UNLOCK();
+
+ return -1;
+}
+
diff --git a/addon/vr_bee1_hidraw_daemon/hidraw/voice_uipc.h b/addon/vr_bee1_hidraw_daemon/hidraw/voice_uipc.h
new file mode 100755
index 0000000..bfc1975
--- /dev/null
+++ b/addon/vr_bee1_hidraw_daemon/hidraw/voice_uipc.h
@@ -0,0 +1,108 @@
+#ifndef VOICE_UIPC_H
+#define VOICE_UIPC_H
+
+#define UIPC_CH_ID_VOICE_CTRL 0
+#define UIPC_CH_ID_VOICE_DATA 1
+#define UIPC_CH_NUM 2
+#define UIPC_CH_ID_ALL 3 /* used to address all the ch id at once */
+
+
+#define DEFAULT_READ_POLL_TMO_MS 100
+
+typedef unsigned char tUIPC_CH_ID;
+
+/* Events generated */
+typedef enum {
+ UIPC_OPEN_EVT = 0x0001,
+ UIPC_CLOSE_EVT = 0x0002,
+ UIPC_RX_DATA_EVT = 0x0004,
+ UIPC_RX_DATA_READY_EVT = 0x0008,
+ UIPC_TX_DATA_READY_EVT = 0x0010
+} tUIPC_EVENT;
+
+/*
+ * UIPC IOCTL Requests
+ */
+
+#define UIPC_REQ_RX_FLUSH 1
+#define UIPC_REG_CBACK 2
+#define UIPC_REG_REMOVE_ACTIVE_READSET 3
+#define UIPC_SET_READ_POLL_TMO 4
+
+#define UIPC_SET_SNDBUFSIZE 5
+
+
+typedef void (tUIPC_RCV_CBACK)(tUIPC_CH_ID ch_id, tUIPC_EVENT event); /* points to BT_HDR which describes event type and length of data; len contains the number of bytes of entire message (sizeof(BT_HDR) + offset + size of data) */
+
+const char* dump_uipc_event(tUIPC_EVENT event);
+
+/*******************************************************************************
+**
+** Function UIPC_Init
+**
+** Description Initialize UIPC module
+**
+** Returns void
+**
+*******************************************************************************/
+void UIPC_Init(void *);
+
+/*******************************************************************************
+**
+** Function UIPC_Open
+**
+** Description Open UIPC interface
+**
+** Returns void
+**
+*******************************************************************************/
+int UIPC_Open(tUIPC_CH_ID ch_id, tUIPC_RCV_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function UIPC_Close
+**
+** Description Close UIPC interface
+**
+** Returns void
+**
+*******************************************************************************/
+void UIPC_Close(tUIPC_CH_ID ch_id);
+
+/*******************************************************************************
+**
+** Function UIPC_Send
+**
+** Description Called to transmit a message over UIPC.
+**
+** Returns void
+**
+*******************************************************************************/
+int UIPC_Send(tUIPC_CH_ID ch_id, unsigned short msg_evt, unsigned char *p_buf, unsigned short msglen);
+int UIPC_Send_noblock(tUIPC_CH_ID ch_id, unsigned short msg_evt, unsigned char *p_buf, unsigned short msglen);
+
+/*******************************************************************************
+**
+** Function UIPC_Read
+**
+** Description Called to read a message from UIPC.
+**
+** Returns void
+**
+*******************************************************************************/
+int UIPC_Read(tUIPC_CH_ID ch_id, unsigned short *p_msg_evt, unsigned char *p_buf, unsigned int len);
+extern int UIPC_Read_noblock(tUIPC_CH_ID ch_id, unsigned short *p_msg_evt, unsigned char *p_buf, unsigned int len);
+
+
+/*******************************************************************************
+**
+** Function UIPC_Ioctl
+**
+** Description Called to control UIPC.
+**
+** Returns void
+**
+*******************************************************************************/
+int UIPC_Ioctl(tUIPC_CH_ID ch_id, unsigned int request, void *param);
+
+#endif /* UIPC_H */
diff --git a/addon/vr_bee1_hidraw_daemon/system/etc/hidraw_setting b/addon/vr_bee1_hidraw_daemon/system/etc/hidraw_setting
new file mode 100755
index 0000000..086f385
--- /dev/null
+++ b/addon/vr_bee1_hidraw_daemon/system/etc/hidraw_setting
@@ -0,0 +1,20 @@
+[Rcu]
+Vid=005d
+Pid=0001
+Ver=0000
+
+[ReportID]
+Key=1
+Data=5a
+Cmd=5a
+
+[ReportValue]
+KeyDownLen=8
+KeyDown=0,0,3e,0,0,0,0,0;
+KeyUpLen=8
+KeyUp=0,64,0,0,0,0,0,0;
+
+[Settings]
+DecodeType=1
+DataMask=1
+AutoCmd=1 \ No newline at end of file
diff --git a/addon/vr_bee2_hidraw_daemon/Android.mk b/addon/vr_bee2_hidraw_daemon/Android.mk
new file mode 100755
index 0000000..bd30b5b
--- /dev/null
+++ b/addon/vr_bee2_hidraw_daemon/Android.mk
@@ -0,0 +1,4 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-subdir-makefiles)
+
diff --git a/addon/vr_bee2_hidraw_daemon/addon.mk b/addon/vr_bee2_hidraw_daemon/addon.mk
new file mode 100755
index 0000000..9fcdeee
--- /dev/null
+++ b/addon/vr_bee2_hidraw_daemon/addon.mk
@@ -0,0 +1,5 @@
+PRODUCT_COPY_FILES += \
+ $(LOCAL_PATH)/system/etc/hidraw_setting:system/etc/hidraw_setting \
+
+PRODUCT_PACKAGES += \
+ vr_bee2_hidraw_daemon \
diff --git a/addon/vr_bee2_hidraw_daemon/hidraw/Android.mk b/addon/vr_bee2_hidraw_daemon/hidraw/Android.mk
new file mode 100755
index 0000000..7bf44c4
--- /dev/null
+++ b/addon/vr_bee2_hidraw_daemon/hidraw/Android.mk
@@ -0,0 +1,24 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES += \
+ voice_hidraw.c \
+ voice_uipc.c \
+ get_voice_app.c \
+ ./msbc/msbc.c \
+ ./sbc/sbcdec.c \
+ config.c
+
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/sbc \
+ $(LOCAL_PATH)/msbc
+
+LOCAL_CFLAGS += $(rtk_local_CFLAGS) -Wno-error=unused-parameter
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_SHARED_LIBRARIES := libcutils libc liblog libtinyalsa libandroid_runtime libutils
+LOCAL_MODULE := vr_bee2_hidraw_daemon
+LOCAL_MULTILIB := 32
+
+include $(BUILD_EXECUTABLE)
diff --git a/addon/vr_bee2_hidraw_daemon/hidraw/bee_settings.h b/addon/vr_bee2_hidraw_daemon/hidraw/bee_settings.h
new file mode 100755
index 0000000..ea2d448
--- /dev/null
+++ b/addon/vr_bee2_hidraw_daemon/hidraw/bee_settings.h
@@ -0,0 +1,35 @@
+#ifndef BEE_SETTINGS_H
+#define BEE_SETTINGS_H
+
+#define BEE_RCU_VID (0x005D)
+#define BEE_RCU_PID (0x0001)
+#define BEE_RCU_VERSION (0x0000)
+
+#define BEE_VOICEKEY_LEN 8
+
+#define BEE_VOICEKEY_REPORTID (0x01)
+
+unsigned char BEE_VOICE_KEYDOWN_DATA[BEE_VOICEKEY_LEN] = {0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00};
+unsigned char BEE_VOICE_KEYUP_DATA[BEE_VOICEKEY_LEN] = {0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+//msbc
+#define BEE_MSBC_VOICEDATA_REPORTID (0x5A)
+#define BEE_MSBC_VOICECMD_REPORTID (0x5A)
+
+
+#define BEE_MSBC_ATT_FRAME_SIZE 120
+#define BEE_MSBC_FRAME_SIZE 60
+#define BEE_MSBC_DECODE_INPUT_SIZE 58
+#define BEE_MSBC_DECODE_OUTPUT_SIZE 240
+
+//sbc
+#define BEE_SBC_VOICEDATA_REPORTID (0x5B)
+#define BEE_SBC_VOICECMD_REPORTID (0x5B)
+
+#define BEE_SBC_ATT_FRAME_SIZE 72
+#define BEE_SBC_FRAME_SIZE 36
+
+#define BEE_SBC_DECODE_INPUT_SIZE 36
+#define BEE_SBC_DECODE_OUTPUT_SIZE 256
+
+#endif \ No newline at end of file
diff --git a/addon/vr_bee2_hidraw_daemon/hidraw/config.c b/addon/vr_bee2_hidraw_daemon/hidraw/config.c
new file mode 100755
index 0000000..17e5e17
--- /dev/null
+++ b/addon/vr_bee2_hidraw_daemon/hidraw/config.c
@@ -0,0 +1,251 @@
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <cutils/log.h>
+
+#include "config.h"
+
+
+tVoice_Hidraw_Settings *gConfig = NULL;
+static char * gContent = NULL;
+
+
+static char * voice_conf_getline(char * head, char ** left)
+{
+ char * next;
+ if(*head == 0)
+ return NULL;
+ while((*head == '\r')||(*head == '\n'))
+ head++;
+ if(*head == 0)
+ return NULL;
+ next = head;
+ while((*next != '\r')&&(*next != '\n')&&(*next != 0))
+ next++;
+ if(*next != 0)
+ *next++ = 0;
+ *left = next;
+ return head;
+}
+
+static void voice_conf_parse_config(tVoice_Hidraw_Settings **items, char *content)
+{
+ char * group = NULL;
+ char * item = NULL;
+ char * val = NULL;
+ char * line = NULL;
+ int id = -1;
+ tVoice_Hidraw_Settings* entry, * head, *end;
+
+ char * p;
+ int i = 0;
+
+ head = NULL;
+ end = NULL;
+
+ ALOGD("voice_conf_parse_config\n");
+ while((line = voice_conf_getline(content, &content)) != NULL)
+ {
+ ALOGD("voice_conf_parse_config line:%s\n", line);
+ switch(line[0])
+ {
+ case '[':
+ {
+ p = strstr(line,"]");
+ if(p)
+ {
+ *p = 0;
+ group = &(line[1]);
+ ALOGI("voice_conf_parse_config Find Group[%s]\n", group);
+ }else{
+ ALOGW("voice_conf_parse_config Expected ']' end of Group(%s)!\n", line);
+ }
+ break;
+ }
+ case '#':
+ {
+ break;
+ }
+ default:
+ {
+ p = strstr(line,"=");
+ if(p)
+ {
+ *p++ = 0;
+ item = line;
+ val = p;
+ if((item[0]==0)||(val[0]==0))
+ {
+ ALOGI("voice_conf_parse_config ignore(item:%s val:%s)\n", item[0]?item:"(null)", val[0]?val:"(null)");
+ break;
+ }
+ ALOGI("voice_conf_parse_config Find Item[%s:%s=%s]\n", group, item, val);
+ entry = malloc(sizeof(tVoice_Hidraw_Settings));
+ if(entry)
+ {
+ entry->next = NULL;
+ entry->group = group;
+ entry->item = item;
+ entry->val = val;
+ if(end)
+ {
+ end->next = entry;
+ end = entry;
+ }else
+ end = entry;
+ if(head == NULL)
+ head = entry;
+ }
+ }
+ }
+ }
+ }
+ *items = head;
+}
+
+
+int voice_loadconfig(char * path)
+{
+ int i,res,fd;
+ struct stat st;
+ char * content = NULL;
+ struct tVoice_Hidraw_Settings* config = NULL;
+
+ ALOGI("voice_loadconfig(%s) load!\n", path);
+ fd = open(path, O_RDONLY);
+ if(fd < 0)
+ {
+ ALOGW("voice_loadconfig(%s) open fail!\n", path);
+ return -1;
+ }
+ res = fstat(fd, &st);
+ if(res)
+ {
+ ALOGW("voice_loadconfig(%s) stat fail! reason=%d\n", path, res);
+ return -1;
+ }
+ if(st.st_size <= 0)
+ {
+ ALOGW("voice_loadconfig(%s) size fail! size=%d\n", path, (int)st.st_size);
+ close(fd);
+ return -1;
+ }
+ ALOGI("voice_loadconfig(%s) size=%d!\n", path, (int)st.st_size);
+ content = malloc(st.st_size+1);
+ if(content == NULL)
+ {
+ ALOGW("voice_loadconfig(%s) malloc fail!\n", path);
+ close(fd);
+ return -1;
+ }
+ res = read(fd, content, st.st_size);
+ if(res <= 0)
+ {
+ ALOGW("voice_loadconfig(%s) read fail! res=%d\n", path, res);
+ close(fd);
+ return -1;
+ }
+ content[res] = 0;
+ voice_conf_parse_config(&config, content);
+ close(fd);
+
+ gConfig = config;
+ return 0;
+}
+
+
+
+
+static char * voice_api_GetConfig(char * group, char * item)
+{
+ int i;
+ tVoice_Hidraw_Settings * entry;
+
+ if(item == NULL)
+ return NULL;
+ entry = gConfig;
+ while(entry)
+ {
+ if(group&&(entry->group)&&(strcmp(entry->group, group)==0)&&(strcmp(entry->item, item)==0))
+ return entry->val;
+ if((group==NULL)&&(entry->group==NULL)&&(strcmp(entry->item, item)==0))
+ return entry->val;
+
+ entry = entry->next;
+ }
+ return NULL;
+}
+
+int voice_get_int_config(char *group, char *item) {
+ char *str;
+ int value = -1;
+
+ str = voice_api_GetConfig(group, item);
+ if(str == NULL) {
+ ALOGE("failed to get int value: %s-%s", group, item);
+ goto result;
+ }
+
+ value = strtol(str, NULL, 16);
+
+result:
+ return value;
+}
+
+int voice_get_byte_array_config(char *group, char *item, char* arr, int len) {
+ char *str, *front, *tail;
+ int ret = -1;
+ int i = 0;
+
+ str = voice_api_GetConfig(group, item);
+ if(str == NULL) {
+ goto retval;
+ }
+
+ front = str;
+
+ while(i < len) {
+ tail = strstr(front, ",");
+ if(tail == NULL) {
+ tail = strstr(front, ";");
+ }
+
+ if(tail == NULL) {
+ ALOGE("failed to get byte-array value: %s-%s-No%d", group, item, i + 1);
+ goto retval;
+ }
+
+ *tail++ = 0;
+ *(arr+i) = (strtol(front, NULL, 16)) & 0xff;
+ front = tail;
+ i++;
+ }
+
+ if(i == len)ret = i;
+
+retval:
+ return ret;
+}
+
+int voice_conf_exit()
+{
+ struct tVoice_Hidraw_Settings *item, *p;
+ int i;
+
+ item = gConfig;
+ while(item)
+ {
+ p = item;
+ item = item->next;
+ free(p);
+ }
+
+ if(gContent)
+ free(gContent);
+ return 0;
+}
+
+
diff --git a/addon/vr_bee2_hidraw_daemon/hidraw/config.h b/addon/vr_bee2_hidraw_daemon/hidraw/config.h
new file mode 100755
index 0000000..64f50bf
--- /dev/null
+++ b/addon/vr_bee2_hidraw_daemon/hidraw/config.h
@@ -0,0 +1,34 @@
+#ifndef CONFIG_H
+#define CONFIG_H
+
+typedef struct tVoice_Hidraw_Settings
+{
+ struct tVoice_Hidraw_Settings * next;
+ char * group;
+ char * item;
+ char * val;
+} tVoice_Hidraw_Settings;
+
+#define CONFIG_GROUP_RCU "Rcu"
+#define CONFIG_ITEM_RCU_VID "Vid"
+#define CONFIG_ITEM_RCU_PID "Pid"
+#define CONFIG_ITEM_RCU_VER "Ver"
+
+#define CONFIG_GROUP_REPORTID "ReportID"
+#define CONFIG_ITEM_REPORTID_KEY "Key"
+#define CONFIG_ITEM_REPORTID_DATA "Data"
+#define CONFIG_ITEM_REPORTID_CMD "Cmd"
+
+#define CONFIG_GROUP_REPORTVALUE "ReportValue"
+#define CONFIG_ITEM_REPORTVALUE_KEYDOWNLEN "KeyDownLen"
+#define CONFIG_ITEM_REPORTVALUE_KEYDOWN "KeyDown"
+#define CONFIG_ITEM_REPORTVALUE_KEYUPLEN "KeyUpLen"
+#define CONFIG_ITEM_REPORTVALUE_KEYUP "KeyUp"
+
+#define CONFIG_GROUP_SETTINGS "Settings"
+#define CONFIG_ITEM_SETTINGS_DECODETYPE "DecodeType"
+#define CONFIG_ITEM_SETTINGS_DATAMASK "DataMask"
+#define CONFIG_ITEM_SETTINGS_AUTOCMD "AutoCmd"
+
+
+#endif
diff --git a/addon/vr_bee2_hidraw_daemon/hidraw/get_voice_app.c b/addon/vr_bee2_hidraw_daemon/hidraw/get_voice_app.c
new file mode 100755
index 0000000..748fb8d
--- /dev/null
+++ b/addon/vr_bee2_hidraw_daemon/hidraw/get_voice_app.c
@@ -0,0 +1,234 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "string.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <cutils/log.h>
+#include "get_voice_app.h"
+#include "msbc.h"
+
+
+#define DECODE_SIZE 58
+#define VOICE_MTU 60
+#define VOICDE_DECODE_UNIT (VOICE_MTU*4)
+
+
+static uint8* _pVoiceBuf = NULL;
+static uint8* _pdecodeBuf = NULL;
+static uint8* _pdecodeFrameBuf = NULL;
+int voice_fd = -1;
+int voice_fd_origin = -1;
+int voice_fd_wav = -1;
+sbc_t t_sbc;
+static int file_index = 0;
+
+struct wavfile
+{
+ char id[4]; // should always contain "RIFF"
+ int totallength; // total file length minus 8
+ char wavefmt[8]; // should be "WAVEfmt "
+ int format; // 16 for PCM format
+ short pcm; // 1 for PCM format
+ short channels; // channels
+ int frequency; // sampling frequency, 16000 in this case
+ int bytes_per_second;
+ short bytes_by_capture;
+ short bits_per_sample;
+ char data[4]; // should always contain "data"
+ int bytes_in_data;
+};
+
+void write_wav_header(char* name, int samples, int channels){
+ struct wavfile filler;
+ FILE *pcm_fd;
+ FILE *wav_fd;
+ char record_name[50] = {0};
+ int size;
+ char ch;
+
+ ALOGE("Start to convert pcm to wav\n");
+ strncpy(filler.id, "RIFF", 4);
+// filler.totallength = (samples * channels) + sizeof(struct wavfile) - 8; //81956
+ strncpy(filler.wavefmt, "WAVEfmt ", 8);
+ filler.format = 16;
+ filler.pcm = 1;
+ filler.channels = channels;
+ filler.frequency = 16000;
+ filler.bits_per_sample = 16;
+ filler.bytes_per_second = filler.channels * filler.frequency * filler.bits_per_sample/8;
+ filler.bytes_by_capture = filler.channels*filler.bits_per_sample/8;
+// filler.bytes_in_data = samples * filler.channels * filler.bits_per_sample/8;
+ strncpy(filler.data, "data", 4);
+
+ pcm_fd = fopen(name, "rb");
+ fseek(pcm_fd, 0, SEEK_END);
+ size = ftell(pcm_fd);
+ fseek(pcm_fd, 0, SEEK_SET);
+
+ filler.bytes_in_data = size;
+ filler.totallength = size + sizeof(filler) - 8;
+#if 0 // just print data
+ printf("File description header: %s\n", filler.id);
+ printf("Size of file: %d\n", filler.totallength);
+ printf("WAV Format description header: %s\n", filler.wavefmt);
+ printf("Size of WAVE section chunck: %d\n", filler.format);
+ printf("WAVE type format: %d\n", filler.pcm);
+ printf("Number of channels: %d\n", filler.channels);
+ printf("Samples per second: %d\n", filler.frequency);
+ printf("Bytes per second: %d\n", filler.bytes_per_second);
+ printf("Block alignment: %d\n", filler.bytes_by_capture);
+ printf("Bits per sample: %d\n", filler.bits_per_sample);
+ printf("Data description header: %s\n", filler.data);
+ printf("Size of data: %d\n", filler.bytes_in_data);
+#endif
+
+
+ sprintf(record_name,"voice_msbc_wav%d.wav",file_index);
+
+ // store wav header
+ wav_fd = fopen(record_name, "wb");
+ fwrite(&filler, 1, sizeof(filler), wav_fd);
+ fclose(wav_fd);
+
+ // store voice data
+ wav_fd = fopen(record_name, "ab");
+ while(!feof(pcm_fd)) {
+ fread(&ch, 1, 1, pcm_fd);
+
+ if(!feof(pcm_fd)) {
+ fwrite(&ch, 1, 1, wav_fd);
+ }
+ }
+
+ fclose(pcm_fd);
+ fclose(wav_fd);
+}
+
+void RS_init_sbc()
+{
+ //msbc
+ sbc_init (&t_sbc, 0L);
+}
+
+void RS_voice_app_create_origin_output()
+{
+ char record_name[50] = {0};
+
+ sprintf(record_name,"/data/vr/voice_msbc_origin%d",file_index);
+
+ voice_fd_origin = open (record_name, O_WRONLY | O_CREAT |O_TRUNC, 0644);
+
+
+ if(voice_fd_origin < 0)
+ {
+ ALOGE("can't open record origin file:%s ",record_name);
+ }
+
+ RS_init_sbc();
+
+ return;
+}
+
+void RS_voice_app_create_output()
+{
+ char record_name[50] = {0};
+ sprintf(record_name,"/data/vr/voice_msbc%d",file_index);
+
+ voice_fd = open (record_name, O_WRONLY | O_CREAT |O_TRUNC, 0644);
+
+ if(voice_fd < 0)
+ {
+ ALOGE("can't open record file:%s ",record_name);
+ }
+
+
+ return;
+}
+
+int RS_stop_voice_stream_data (void)
+{
+ char record_name[50] = {0};
+
+ ALOGE ("in\r\n");
+
+ if (voice_fd > 0 && -1 == close (voice_fd) )
+ {
+ ALOGE ("close voice file fail\r\n");
+ }
+
+ if (voice_fd_origin > 0 && -1 == close (voice_fd_origin) )
+ {
+ ALOGE ("close voice file fail\r\n");
+ }
+
+ voice_fd = 0;
+ voice_fd_origin = 0;
+
+ sprintf(record_name,"voice_msbc%d",file_index);
+
+ //write_wav_header(record_name, 16000, 1);
+
+ sbc_finish (&t_sbc);
+
+ file_index = ((++file_index)>= 10) ? 0 : file_index;
+
+ return 0;
+}
+
+int RS_write_decode_buf(uint8* pu_decode, ssize_t len)
+{
+ if (voice_fd > 0)
+ {
+ write (voice_fd, pu_decode, len);
+ return 0;
+ }
+ return -1;
+}
+
+int RS_deal_voice_stream_data(const uint8* input, size_t voice_buf_size, unsigned char* output, size_t output_buf_size, int* frame_len)
+{
+ int framelen;
+
+// RS_init_sbc();
+
+
+
+ if (NULL == input || 0 == voice_buf_size)
+ {
+ ALOGE ("input is null \r\n");
+ return -1;
+ }
+
+
+ if (NULL == output || 0 == output_buf_size)
+ {
+ ALOGE ("output is null");
+ return -1;
+ }
+
+ if(voice_buf_size != VOICE_MTU) {
+ ALOGE ("input size error: %d", voice_buf_size);
+ return -1;
+ }
+
+
+ write(voice_fd_origin, input, voice_buf_size);
+ if (input[0] == 0x01 && input[2] == 0xad)
+ {
+ framelen = sbc_decode (&t_sbc, &input[2], DECODE_SIZE, output, output_buf_size,frame_len);
+ if (framelen <= 0)
+ {
+ ALOGE("fail to decode");
+ return -1;
+ }
+ RS_write_decode_buf(output, *frame_len);
+ return 0;
+ }else {
+ ALOGE("msbc format error !!!");
+ return -1;
+ }
+}
+
+
diff --git a/addon/vr_bee2_hidraw_daemon/hidraw/get_voice_app.h b/addon/vr_bee2_hidraw_daemon/hidraw/get_voice_app.h
new file mode 100755
index 0000000..a55b100
--- /dev/null
+++ b/addon/vr_bee2_hidraw_daemon/hidraw/get_voice_app.h
@@ -0,0 +1,22 @@
+
+//#define MSBC_SUPPORT
+#define VOICE_KEY_DOWN 0x3e
+#define VOICE_BUFFER_REPORT_ID 0x5a
+#define ADD_FOR_VOICE_CONTROL
+#define VOICE_FILE_WITH_MSBC "/tmp/voice_msbc"
+#define VOICE_FILE_WITH_NO_MSBC "/tmp/voice_no_msbc"
+
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned int uint32;
+typedef signed char int8;
+typedef signed short int16;
+typedef signed int int32;
+
+void RS_voice_app_create_origin_output();
+
+int RS_deal_voice_stream_data(const uint8* input, size_t voice_buf_size, unsigned char* output, size_t output_buf_size, int* frame_len);
+
+int RS_stop_voice_stream_data (void);
+
+void RS_voice_app_create_output(); \ No newline at end of file
diff --git a/addon/vr_bee2_hidraw_daemon/hidraw/msbc/msbc.c b/addon/vr_bee2_hidraw_daemon/hidraw/msbc/msbc.c
new file mode 100755
index 0000000..9ee5045
--- /dev/null
+++ b/addon/vr_bee2_hidraw_daemon/hidraw/msbc/msbc.c
@@ -0,0 +1,1766 @@
+/*
+ *
+ * Bluetooth low-complexity, subband codec (SBC) library
+ *
+ * Copyright (C) 2004-2006 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2004-2005 Henryk Ploetz <henryk@ploetzli.ch>
+ * Copyright (C) 2005-2006 Brad Midgley <bmidgley@xmission.com>
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+/* todo items:
+
+ use a log2 table for byte integer scale factors calculation (sum log2 results for high and low bytes)
+ fill bitpool by 16 bits instead of one at a time in bits allocation/bitpool generation
+ port to the dsp
+ don't consume more bytes than passed into the encoder
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+
+#include <errno.h>
+
+//#include <stdint.h>
+#include <malloc.h>
+#include <string.h>
+//#include <stdlib.h>
+#include <sys/types.h>
+
+#include "msbc.h"
+#include "msbc_math.h"
+#include "msbc_tables.h"
+#include "cutils/log.h"
+
+
+#define SBC_SYNCWORD 0xAD
+#define SBC_POOLTAG 'CBSR'
+
+/* sampling frequency */
+#define SBC_FS_16 0x00
+#define SBC_FS_32 0x01
+#define SBC_FS_44 0x02
+#define SBC_FS_48 0x03
+
+/* nrof_blocks */
+#define SBC_NB_4 0x00
+#define SBC_NB_8 0x01
+#define SBC_NB_12 0x02
+#define SBC_NB_16 0x03
+
+/* channel mode */
+#define SBC_CM_MONO 0x00
+#define SBC_CM_DUAL_CHANNEL 0x01
+#define SBC_CM_STEREO 0x02
+#define SBC_CM_JOINT_STEREO 0x03
+
+/* allocation mode */
+#define SBC_AM_LOUDNESS 0x00
+#define SBC_AM_SNR 0x01
+
+/* subbands */
+#define SBC_SB_4 0x00
+#define SBC_SB_8 0x01
+
+#define SBC_ALIGN_BITS 4
+#define SBC_ALIGN_MASK ((1 << (SBC_ALIGN_BITS)) - 1)
+
+
+typedef unsigned short uint16_t;
+typedef unsigned char uint8_t;
+typedef short int16_t;
+typedef unsigned int u_int32_t;
+
+#ifndef UINT
+typedef unsigned int UINT;
+#endif
+
+
+#if defined(WIN32) && !defined(__cplusplus)
+
+#define inline __inline
+
+#endif
+
+
+/*
+static __inline void sbc_synthesize_four(struct sbc_decoder_state *state,
+ struct sbc_frame *frame, int ch, int blk);
+*/
+
+
+/* This structure contains an unpacked SBC frame.
+ Yes, there is probably quite some unused space herein */
+struct sbc_frame
+{
+ uint16_t sampling_frequency; /* in kHz */
+ unsigned char blocks;
+ enum {
+ MONO = SBC_CM_MONO,
+ DUAL_CHANNEL = SBC_CM_DUAL_CHANNEL,
+ STEREO = SBC_CM_STEREO,
+ JOINT_STEREO = SBC_CM_JOINT_STEREO
+ } channel_mode;
+ uint8_t channels;
+ enum {
+ LOUDNESS = SBC_AM_LOUDNESS,
+ SNR = SBC_AM_SNR
+ } allocation_method;
+ uint8_t subbands;
+ uint8_t bitpool;
+ uint8_t join; /* bit number x set means joint stereo has been used in subband x */
+ int scale_factor[2][8]; /* only the lower 4 bits of every element are to be used */
+ uint16_t audio_sample[16][2][8]; /* raw integer subband samples in the frame */
+
+ int sb_sample_f[16][2][8];
+ int sb_sample[16][2][8]; /* modified subband samples */
+ short pcm_sample[2][16*8]; /* original pcm audio samples */
+};
+
+struct sbc_decoder_state {
+ int subbands;
+ long long V[2][170];
+ int offset[2][16];
+};
+
+struct sbc_encoder_state {
+ int subbands;
+ int32_t X[2][80];
+};
+
+/*
+ * Calculates the CRC-8 of the first len bits in data
+ */
+static const uint8_t crc_table[256] = {
+ 0x00, 0x1D, 0x3A, 0x27, 0x74, 0x69, 0x4E, 0x53,
+ 0xE8, 0xF5, 0xD2, 0xCF, 0x9C, 0x81, 0xA6, 0xBB,
+ 0xCD, 0xD0, 0xF7, 0xEA, 0xB9, 0xA4, 0x83, 0x9E,
+ 0x25, 0x38, 0x1F, 0x02, 0x51, 0x4C, 0x6B, 0x76,
+ 0x87, 0x9A, 0xBD, 0xA0, 0xF3, 0xEE, 0xC9, 0xD4,
+ 0x6F, 0x72, 0x55, 0x48, 0x1B, 0x06, 0x21, 0x3C,
+ 0x4A, 0x57, 0x70, 0x6D, 0x3E, 0x23, 0x04, 0x19,
+ 0xA2, 0xBF, 0x98, 0x85, 0xD6, 0xCB, 0xEC, 0xF1,
+ 0x13, 0x0E, 0x29, 0x34, 0x67, 0x7A, 0x5D, 0x40,
+ 0xFB, 0xE6, 0xC1, 0xDC, 0x8F, 0x92, 0xB5, 0xA8,
+ 0xDE, 0xC3, 0xE4, 0xF9, 0xAA, 0xB7, 0x90, 0x8D,
+ 0x36, 0x2B, 0x0C, 0x11, 0x42, 0x5F, 0x78, 0x65,
+ 0x94, 0x89, 0xAE, 0xB3, 0xE0, 0xFD, 0xDA, 0xC7,
+ 0x7C, 0x61, 0x46, 0x5B, 0x08, 0x15, 0x32, 0x2F,
+ 0x59, 0x44, 0x63, 0x7E, 0x2D, 0x30, 0x17, 0x0A,
+ 0xB1, 0xAC, 0x8B, 0x96, 0xC5, 0xD8, 0xFF, 0xE2,
+ 0x26, 0x3B, 0x1C, 0x01, 0x52, 0x4F, 0x68, 0x75,
+ 0xCE, 0xD3, 0xF4, 0xE9, 0xBA, 0xA7, 0x80, 0x9D,
+ 0xEB, 0xF6, 0xD1, 0xCC, 0x9F, 0x82, 0xA5, 0xB8,
+ 0x03, 0x1E, 0x39, 0x24, 0x77, 0x6A, 0x4D, 0x50,
+ 0xA1, 0xBC, 0x9B, 0x86, 0xD5, 0xC8, 0xEF, 0xF2,
+ 0x49, 0x54, 0x73, 0x6E, 0x3D, 0x20, 0x07, 0x1A,
+ 0x6C, 0x71, 0x56, 0x4B, 0x18, 0x05, 0x22, 0x3F,
+ 0x84, 0x99, 0xBE, 0xA3, 0xF0, 0xED, 0xCA, 0xD7,
+ 0x35, 0x28, 0x0F, 0x12, 0x41, 0x5C, 0x7B, 0x66,
+ 0xDD, 0xC0, 0xE7, 0xFA, 0xA9, 0xB4, 0x93, 0x8E,
+ 0xF8, 0xE5, 0xC2, 0xDF, 0x8C, 0x91, 0xB6, 0xAB,
+ 0x10, 0x0D, 0x2A, 0x37, 0x64, 0x79, 0x5E, 0x43,
+ 0xB2, 0xAF, 0x88, 0x95, 0xC6, 0xDB, 0xFC, 0xE1,
+ 0x5A, 0x47, 0x60, 0x7D, 0x2E, 0x33, 0x14, 0x09,
+ 0x7F, 0x62, 0x45, 0x58, 0x0B, 0x16, 0x31, 0x2C,
+ 0x97, 0x8A, 0xAD, 0xB0, 0xE3, 0xFE, 0xD9, 0xC4
+};
+
+static uint8_t sbc_crc8(const uint8_t * data, size_t len)
+{
+ uint8_t crc = 0x0f;
+ size_t i;
+ uint8_t octet;
+
+ for (i = 0; i < len / 8; i++)
+ crc = crc_table[crc ^ data[i]];
+
+ octet = data[i];
+ for (i = 0; i < len % 8; i++)
+ {
+ char bit = ((octet ^ crc) & 0x80) >> 7;
+
+ crc = ((crc & 0x7f) << 1) ^ (bit ? 0x1d : 0);
+
+ octet = octet << 1;
+ }
+
+ return crc;
+}
+
+/*
+ * Code straight from the spec to calculate the bits array
+ * Takes a pointer to the frame in question, a pointer to the bits array and the sampling frequency (as 2 bit integer)
+ */
+static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8], uint8_t sf)
+{
+ if (frame->channel_mode == MONO || frame->channel_mode == DUAL_CHANNEL)
+ {
+ int bitneed[2][8], loudness, max_bitneed, bitcount, slicecount, bitslice;
+ int ch, sb;
+
+ for (ch = 0; ch < frame->channels; ch++)
+ {
+ if (frame->allocation_method == SNR)
+ {
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ bitneed[ch][sb] = frame->scale_factor[ch][sb];
+ }
+ }
+
+ else
+ {
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ if (frame->scale_factor[ch][sb] == 0)
+ {
+ bitneed[ch][sb] = -5;
+ }
+ else
+ {
+ if (frame->subbands == 4)
+ {
+ loudness = frame->scale_factor[ch][sb] - sbc_offset4[sf][sb];
+ }
+
+ else
+ {
+ loudness = frame->scale_factor[ch][sb] - sbc_offset8[sf][sb];
+ }
+
+ if (loudness > 0)
+ {
+ bitneed[ch][sb] = loudness / 2;
+ }
+
+ else
+ {
+ bitneed[ch][sb] = loudness;
+ }
+ }
+ }
+ }
+
+ max_bitneed = 0;
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ if (bitneed[ch][sb] > max_bitneed)
+ max_bitneed = bitneed[ch][sb];
+ }
+
+ bitcount = 0;
+ slicecount = 0;
+ bitslice = max_bitneed + 1;
+ do
+ {
+ bitslice--;
+ bitcount += slicecount;
+ slicecount = 0;
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ if ((bitneed[ch][sb] > bitslice + 1) && (bitneed[ch][sb] < bitslice + 16))
+ {
+ slicecount++;
+ }
+
+ else if (bitneed[ch][sb] == bitslice + 1)
+ {
+ slicecount += 2;
+ }
+ }
+ } while (bitcount + slicecount < frame->bitpool);
+
+ if (bitcount + slicecount == frame->bitpool)
+ {
+ bitcount += slicecount;
+ bitslice--;
+ }
+
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ if (bitneed[ch][sb] < bitslice + 2)
+ {
+ bits[ch][sb] = 0;
+ }
+
+ else
+ {
+ bits[ch][sb] = bitneed[ch][sb] - bitslice;
+ if (bits[ch][sb] > 16)
+ bits[ch][sb] = 16;
+ }
+ }
+
+ sb = 0;
+ while (bitcount < frame->bitpool && sb < frame->subbands)
+ {
+ if ((bits[ch][sb] >= 2) && (bits[ch][sb] < 16))
+ {
+ bits[ch][sb]++;
+ bitcount++;
+ }
+
+ else if ((bitneed[ch][sb] == bitslice + 1) && (frame->bitpool > bitcount + 1))
+ {
+ bits[ch][sb] = 2;
+ bitcount += 2;
+ }
+ sb++;
+ }
+
+ sb = 0;
+ while (bitcount < frame->bitpool && sb < frame->subbands)
+ {
+ if (bits[ch][sb] < 16)
+ {
+ bits[ch][sb]++;
+ bitcount++;
+ }
+ sb++;
+ }
+
+ }
+
+ }
+
+ else if (frame->channel_mode == STEREO || frame->channel_mode == JOINT_STEREO)
+ {
+ int bitneed[2][8], loudness, max_bitneed, bitcount, slicecount, bitslice;
+ int ch, sb;
+
+ if (frame->allocation_method == SNR)
+ {
+ for (ch = 0; ch < 2; ch++) {
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ bitneed[ch][sb] = frame->scale_factor[ch][sb];
+ }
+ }
+ }
+
+ else
+ {
+ for (ch = 0; ch < 2; ch++)
+ {
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ if (frame->scale_factor[ch][sb] == 0)
+ {
+ bitneed[ch][sb] = -5;
+ }
+
+ else
+ {
+ if (frame->subbands == 4)
+ {
+ loudness = frame->scale_factor[ch][sb] - sbc_offset4[sf][sb];
+ }
+
+ else
+ {
+ loudness = frame->scale_factor[ch][sb] - sbc_offset8[sf][sb];
+ }
+
+ if (loudness > 0)
+ {
+ bitneed[ch][sb] = loudness / 2;
+ }
+
+ else
+ {
+ bitneed[ch][sb] = loudness;
+ }
+ }
+ }
+ }
+ }
+
+ max_bitneed = 0;
+ for (ch = 0; ch < 2; ch++)
+ {
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ if (bitneed[ch][sb] > max_bitneed)
+ max_bitneed = bitneed[ch][sb];
+ }
+ }
+
+ bitcount = 0;
+ slicecount = 0;
+ bitslice = max_bitneed + 1;
+ do {
+ bitslice--;
+ bitcount += slicecount;
+ slicecount = 0;
+ for (ch = 0; ch < 2; ch++)
+ {
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ if ((bitneed[ch][sb] > bitslice + 1) && (bitneed[ch][sb] < bitslice + 16))
+ {
+ slicecount++;
+ }
+
+ else if (bitneed[ch][sb] == bitslice + 1)
+ {
+ slicecount += 2;
+ }
+ }
+ }
+ } while (bitcount + slicecount < frame->bitpool);
+
+ if (bitcount + slicecount == frame->bitpool)
+ {
+ bitcount += slicecount;
+ bitslice--;
+ }
+
+ for (ch = 0; ch < 2; ch++)
+ {
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ if (bitneed[ch][sb] < bitslice + 2)
+ {
+ bits[ch][sb] = 0;
+ }
+
+ else
+ {
+ bits[ch][sb] = bitneed[ch][sb] - bitslice;
+ if (bits[ch][sb] > 16)
+ bits[ch][sb] = 16;
+ }
+ }
+ }
+
+ ch = 0;
+ sb = 0;
+ while ((bitcount < frame->bitpool) && (sb < frame->subbands))
+ {
+ if ((bits[ch][sb] >= 2) && (bits[ch][sb] < 16))
+ {
+ bits[ch][sb]++;
+ bitcount++;
+ }
+
+ else if ((bitneed[ch][sb] == bitslice + 1) && (frame->bitpool > bitcount + 1))
+ {
+ bits[ch][sb] = 2;
+ bitcount += 2;
+ }
+ if (ch == 1)
+ {
+ ch = 0;
+ sb++;
+ }
+ else
+ {
+ ch = 1;
+ }
+ }
+
+ ch = 0;
+ sb = 0;
+ while ((bitcount < frame->bitpool) && (sb < frame->subbands))
+ {
+ if (bits[ch][sb] < 16)
+ {
+ bits[ch][sb]++;
+ bitcount++;
+ }
+ if (ch == 1)
+ {
+ ch = 0;
+ sb++;
+ }
+
+ else
+ {
+ ch = 1;
+ }
+ }
+
+ }
+}
+
+/*
+ * Unpacks a SBC frame at the beginning of the stream in data,
+ * which has at most len bytes into frame.
+ * Returns the length in bytes of the packed frame, or a negative
+ * value on error. The error codes are:
+ *
+ * -1 Data stream too short
+ * -2 Sync byte incorrect
+ * -3 CRC8 incorrect
+ * -4 Bitpool value out of bounds
+ */
+static int sbc_unpack_frame(const uint8_t * data, struct sbc_frame *frame, size_t len)
+{
+ UINT consumed;
+ /* Will copy the parts of the header that are relevant to crc calculation here */
+ uint8_t crc_header[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ int crc_pos = 0;
+ int32_t temp;
+
+ uint8_t sf; /* sampling_frequency, temporarily needed as array index */
+
+// int audio_sample;
+ int ch, sb, blk, bit; /* channel, subband, block and bit standard counters */
+ int bits[2][8]; /* bits distribution */
+ int levels[2][8]; /* levels derived from that */
+
+ if (len < 4)
+ {
+ //DbgPrint("Exit when len < 4\n");
+ return -1;
+ }
+
+ if (data[0] != SBC_SYNCWORD)
+ {
+ //DbgPrint("Exit when data[0] != SBC_SYNCWORD\n");
+ return -2;
+ }
+
+#if 0
+ sf = (data[1] >> 6) & 0x03;
+ switch (sf) {
+ case SBC_FS_16:
+ frame->sampling_frequency = 16000;
+ break;
+ case SBC_FS_32:
+ frame->sampling_frequency = 32000;
+ break;
+ case SBC_FS_44:
+ frame->sampling_frequency = 44100;
+ break;
+ case SBC_FS_48:
+ frame->sampling_frequency = 48000;
+ break;
+ }
+
+ switch ((data[1] >> 4) & 0x03) {
+ case SBC_NB_4:
+ frame->blocks = 4;
+ break;
+ case SBC_NB_8:
+ frame->blocks = 8;
+ break;
+ case SBC_NB_12:
+ frame->blocks = 12;
+ break;
+ case SBC_NB_16:
+ frame->blocks = 16;
+ break;
+ }
+
+ frame->channel_mode = (data[1] >> 2) & 0x03;
+ switch (frame->channel_mode) {
+ case MONO:
+ frame->channels = 1;
+ break;
+ case DUAL_CHANNEL: /* fall-through */
+ case STEREO:
+ case JOINT_STEREO:
+ frame->channels = 2;
+ break;
+ }
+
+ frame->allocation_method = (data[1] >> 1) & 0x01;
+ frame->subbands = (data[1] & 0x01) ? 8 : 4;
+ frame->bitpool = data[2];
+#endif
+
+ frame->sampling_frequency = 16000;
+ frame->blocks = 15;
+ frame->channel_mode = MONO;
+ frame->channels = 1;
+ frame->allocation_method = SBC_AM_LOUDNESS;
+ frame->subbands = 8;
+ frame->bitpool = 26;
+
+
+ if (((frame->channel_mode == MONO || frame->channel_mode == DUAL_CHANNEL)
+ && frame->bitpool > 16 * frame->subbands)
+ || ((frame->channel_mode == STEREO || frame->channel_mode == JOINT_STEREO)
+ && frame->bitpool > 32 * frame->subbands))
+ {
+ //DbgPrint("Exit when frame->mode == MONO || frame->mode == DUAL_CHANNEL) &&"
+ // "frame->bitpool > 16 * frame->subbands\n");
+ return -4;
+ }
+
+ /* data[3] is crc, we're checking it later */
+ consumed = 32;
+#if 1
+ crc_header[0] = data[1];
+ crc_header[1] = data[2];
+#endif
+
+#if 0
+ crc_header[0] = 0x31;
+ crc_header[1] = 0x1a;
+#endif
+
+ crc_pos = 16;
+
+ if (frame->channel_mode == JOINT_STEREO)
+ {
+ if (len * 8 < consumed + frame->subbands)
+ return -1;
+
+ frame->join = 0x00;
+ for (sb = 0; sb < frame->subbands - 1; sb++) {
+ frame->join |= ((data[4] >> (7 - sb)) & 0x01) << sb;
+ }
+ if (frame->subbands == 4) {
+ crc_header[crc_pos / 8] = data[4] & 0xf0;
+ } else {
+ crc_header[crc_pos / 8] = data[4];
+ }
+
+ consumed += frame->subbands;
+ crc_pos += frame->subbands;
+ }
+
+ if (len * 8 < consumed + (4 * frame->subbands * frame->channels))
+ {
+ //DbgPrint("len * 8 < consumed + (4 * frame->subbands * frame->channels\n");
+ return -1;
+ }
+
+ for (ch = 0; ch < frame->channels; ch++)
+ {
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ /* FIXME assert(consumed % 4 == 0); */
+ frame->scale_factor[ch][sb] = (data[consumed >> 3] >> (4 - (consumed & 0x7))) & 0x0F;
+ crc_header[crc_pos >> 3] |= frame->scale_factor[ch][sb] << (4 - (crc_pos & 0x7));
+
+ consumed += 4;
+ crc_pos += 4;
+ }
+ }
+
+ if (data[3] != sbc_crc8(crc_header, crc_pos))
+ {
+ ALOGD("sbc_crc %02x -> %02x\n",data[3],sbc_crc8(crc_header, crc_pos));
+ return -3;
+ }
+
+ sf = SBC_FS_16;
+ sbc_calculate_bits(frame, bits, sf);
+
+ for (ch = 0; ch < frame->channels; ch++)
+ {
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ levels[ch][sb] = (1 << bits[ch][sb]) - 1;
+ }
+ }
+#if 0
+ for (blk = 0; blk < frame->blocks; blk++)
+ {
+ for (ch = 0; ch < frame->channels; ch++)
+ {
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ if (levels[ch][sb] > 0)
+ {
+ audio_sample = 0;
+ for (bit = 0; bit < bits[ch][sb]; bit++)
+ {
+ if (consumed > len * 8)
+ {
+ LogEvent("Exit when consumed > len * 8\n");
+ return -1;
+ }
+
+ if ((data[consumed >> 3] >> (7 - (consumed & 0x7))) & 0x01)
+ audio_sample |= 1 << (bits[ch][sb] - bit - 1);
+
+ consumed++;
+ }
+
+ frame->sb_sample[blk][ch][sb] =
+ (((audio_sample << 1) | 1) << frame->scale_factor[ch][sb]) /
+ levels[ch][sb] - (1 << frame->scale_factor[ch][sb]);
+ }
+
+ else
+ frame->sb_sample[blk][ch][sb] = 0;
+ }
+ }
+ }
+#endif
+
+#if 1
+
+ for (blk = 0; blk < frame->blocks; blk++)
+ {
+ for (ch = 0; ch < frame->channels; ch++)
+ {
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ frame->audio_sample[blk][ch][sb] = 0;
+ if (bits[ch][sb] == 0)
+ continue;
+
+ for (bit = 0; bit < bits[ch][sb]; bit++)
+ {
+ int b; /* A bit */
+ if (consumed > len * 8)
+ return -1;
+
+ b = (data[consumed >> 3] >> (7 - (consumed & 0x7))) & 0x01;
+ frame->audio_sample[blk][ch][sb] |= b << (bits[ch][sb] - bit - 1);
+
+ consumed++;
+ }
+ }
+ }
+ }
+
+ for (blk = 0; blk < frame->blocks; blk++)
+ {
+ for (ch = 0; ch < frame->channels; ch++)
+ {
+ for (sb = 0; sb < frame->subbands; sb++)
+ {
+ if (levels[ch][sb] > 0)
+ {
+ frame->sb_sample[blk][ch][sb] =
+