在调试蓝牙传输文件时,当电脑连接成功后,发送文件卡住不动,且obexd提示:disconnected: Unicode conversion failed: Conversion from character set 'UTF-16BE' to 'UTF-8' is not supported
解决方案
使用buildroot编译bluez时,需要把gconv libs选上,这样额外编译出gconv编码相关库:
编译完成后,gconv库的位置在output/target/usr/lib/gconv/下面,需要手动拷贝UTF-16.so和gconv-modules到目标板的/usr/lib/gconv/目录,这样obexd运行时才会支持UTF-16编码。
另外,网上其他文章说打开了gconv配置重新编译bluez会生效,但事实证明这个gconv库与bluez没有关联,如果程序缺库会在运行时报错,但obexd是怎么用到gconv库的呢?为何缺库时只提示不支持编码转换呢?
[wangyb@wangyb-VirtualBox:buildroot-2017.02.3]$ ls output/target/usr/lib/gconv/
ANSI_X3.110.so CWI.so GBBIG5.so IBM1122.so IBM1162.so IBM424.so IBM871.so INIS.so ISO8859-5.so MAC-UK.so
ARMSCII-8.so DEC-MCS.so GBGBK.so IBM1123.so IBM1163.so IBM437.so IBM874.so ISIRI-3342.so ISO8859-6.so MIK.so
ASMO_449.so EBCDIC-AT-DE-A.so GBK.so IBM1124.so IBM1164.so IBM4517.so IBM875.so ISO_10367-BOX.so ISO8859-7.so NATS-DANO.so
BIG5HKSCS.so EBCDIC-AT-DE.so gconv-modules IBM1129.so IBM1166.so IBM4899.so IBM880.so ISO_11548-1.so ISO8859-8.so NATS-SEFI.so
BIG5.so EBCDIC-CA-FR.so GEORGIAN-ACADEMY.so IBM1130.so IBM1167.so IBM4909.so IBM891.so ISO-2022-CN-EXT.so ISO8859-9E.so PT154.so
BRF.so EBCDIC-DK-NO-A.so GEORGIAN-PS.so IBM1132.so IBM12712.so IBM4971.so IBM901.so ISO-2022-CN.so ISO8859-9.so RK1048.so
CP10007.so EBCDIC-DK-NO.so GOST_19768-74.so IBM1133.so IBM1364.so IBM500.so IBM902.so ISO-2022-JP-3.so ISO-IR-197.so SAMI-WS2.so
CP1125.so EBCDIC-ES-A.so GREEK7-OLD.so IBM1137.so IBM1371.so IBM5347.so IBM9030.so ISO-2022-JP.so ISO-IR-209.so SHIFT_JISX0213.so
CP1250.so EBCDIC-ES.so GREEK7.so IBM1140.so IBM1388.so IBM803.so IBM903.so ISO-2022-KR.so JOHAB.so SJIS.so
CP1251.so EBCDIC-ES-S.so GREEK-CCITT.so IBM1141.so IBM1390.so IBM850.so IBM904.so ISO_2033.so KOI8-R.so T.61.so
CP1252.so EBCDIC-FI-SE-A.so HP-GREEK8.so IBM1142.so IBM1399.so IBM851.so IBM905.so ISO_5427-EXT.so KOI8-RU.so TCVN5712-1.so
CP1253.so EBCDIC-FI-SE.so HP-ROMAN8.so IBM1143.so IBM16804.so IBM852.so IBM9066.so ISO_5427.so KOI-8.so TIS-620.so
CP1254.so EBCDIC-FR.so HP-ROMAN9.so IBM1144.so IBM256.so IBM855.so IBM918.so ISO_5428.so KOI8-T.so TSCII.so
CP1255.so EBCDIC-IS-FRISS.so HP-THAI8.so IBM1145.so IBM273.so IBM856.so IBM921.so ISO646.so KOI8-U.so UHC.so
CP1256.so EBCDIC-IT.so HP-TURKISH8.so IBM1146.so IBM274.so IBM857.so IBM922.so ISO_6937-2.so LATIN-GREEK-1.so UNICODE.so
CP1257.so EBCDIC-PT.so IBM037.so IBM1147.so IBM275.so IBM860.so IBM930.so ISO_6937.so LATIN-GREEK.so UTF-16.so
CP1258.so EBCDIC-UK.so IBM038.so IBM1148.so IBM277.so IBM861.so IBM932.so ISO8859-10.so libCNS.so UTF-32.so
CP737.so EBCDIC-US.so IBM1004.so IBM1149.so IBM278.so IBM862.so IBM933.so ISO8859-11.so libGB.so UTF-7.so
CP770.so ECMA-CYRILLIC.so IBM1008_420.so IBM1153.so IBM280.so IBM863.so IBM935.so ISO8859-13.so libISOIR165.so VISCII.so
CP771.so EUC-CN.so IBM1008.so IBM1154.so IBM281.so IBM864.so IBM937.so ISO8859-14.so libJIS.so
CP772.so EUC-JISX0213.so IBM1025.so IBM1155.so IBM284.so IBM865.so IBM939.so ISO8859-15.so libJISX0213.so
CP773.so EUC-JP-MS.so IBM1026.so IBM1156.so IBM285.so IBM866NAV.so IBM943.so ISO8859-16.so libKSC.so
CP774.so EUC-JP.so IBM1046.so IBM1157.so IBM290.so IBM866.so IBM9448.so ISO8859-1.so MAC-CENTRALEUROPE.so
CP775.so EUC-KR.so IBM1047.so IBM1158.so IBM297.so IBM868.so IEC_P27-1.so ISO8859-2.so MACINTOSH.so
CP932.so EUC-TW.so IBM1097.so IBM1160.so IBM420.so IBM869.so INIS-8.so ISO8859-3.so MAC-IS.so
CSN_369103.so GB18030.so IBM1112.so IBM1161.so IBM423.so IBM870.so INIS-CYRILLIC.so ISO8859-4.so MAC-SAMI.so
obexd的RPATH不为空,RPATH全称run-time search path,说明程序运行时会搜索相关的库文件。而RPATH指定的路径下就有gconv库。
[wangyb@wangyb-VirtualBox:bluez5_utils-5.43]$ readelf -d obexd/src/obexd
Dynamic section at offset 0x4b304 contains 28 entries:
标记 类型 名称/值
0x00000001 (NEEDED) 共享库:[libdbus-1.so.3]
0x00000001 (NEEDED) 共享库:[libglib-2.0.so.0]
0x00000001 (NEEDED) 共享库:[libdl.so.2]
0x00000001 (NEEDED) 共享库:[libc.so.6]
0x0000000f (RPATH) Library rpath: [/buildroot-2017.02.3/output/host/usr/arm-buildroot-linux-gnueabi/sysroot/usr/lib]
应该是在编译时通过am_lib_libbluetooth_la_rpath = -rpath $(libdir)设置的RPATH。
调试过程【仅记录可忽略】
1、使用-d打开obexd和bluetoothd的debug信息:没看到有用的异常信息。
bluetoothd[19288]: src/adapter.c:connected_callback() hci0 device C0:B5:D7:A3:98:90 connected eir_len 22
bluetoothd[19288]: src/device.c:device_create() dst C0:B5:D7:A3:98:90
bluetoothd[19288]: src/device.c:device_new() address C0:B5:D7:A3:98:90
bluetoothd[19288]: src/device.c:device_new() Creating device /org/bluez/hci0/dev_C0_B5_D7_A3_98_90
bluetoothd[19288]: src/device.c:device_set_class() /org/bluez/hci0/dev_C0_B5_D7_A3_98_90 0x0A0104
bluetoothd[19288]: src/device.c:btd_device_device_set_name() /org/bluez/hci0/dev_C0_B5_D7_A3_98_90 DESKTOP-9TIPO5R
[NEW] Device C0:B5:D7:A3:98:90 DESKTOP-9TIPO5R
[bluetooth]# bluetoothd[19288]: src/adapter.c:user_confirm_request_callback() hci0 C0:B5:D7:A3:98:90 confirm_hint 0
bluetoothd[19288]: src/device.c:new_auth() Requesting agent authentication for C0:B5:D7:A3:98:90
bluetoothd[19288]: src/agent.c:agent_ref() 0xe5180: ref=2
bluetoothd[19288]: src/agent.c:agent_request_confirmation() Calling Agent.RequestConfirmation: name=:1.2, path=/org/bluez/agent, passkey=362723
Request confirmation
[agent] Confirm passkey 362723 (yes/no): yes
[DESKTOP-9TIPO5R]# bluetoothd[19288]: src/agent.c:agent_ref() 0xe5180: ref=3
bluetoothd[19288]: src/adapter.c:btd_adapter_confirm_reply() hci0 addr C0:B5:D7:A3:98:90 success 1
bluetoothd[19288]: src/agent.c:agent_unref() 0xe5180: ref=2
bluetoothd[19288]: src/agent.c:agent_unref() 0xe5180: ref=1
bluetoothd[19288]: src/adapter.c:new_link_key_callback() hci0 new key for C0:B5:D7:A3:98:90 type 5 pin_len 0 store_hint 1
bluetoothd[19288]: src/device.c:device_set_bonded()
bluetoothd[19288]: src/device.c:btd_device_set_temporary() temporary 0
bluetoothd[19288]: src/device.c:device_bonding_complete() bonding (nil) status 0x00
bluetoothd[19288]: src/device.c:device_bonding_complete() setting timer for reverse service discovery
bluetoothd[19288]: src/adapter.c:resume_discovery()
bluetoothd[19288]: src/device.c:device_probe_profiles() Probing profiles for device C0:B5:D7:A3:98:90
bluetoothd[19288]: src/profile.c:ext_device_probe() Object Push probed with UUID 00001105-0000-1000-8000-00805f9b34fb
bluetoothd[19288]: src/service.c:change_state() 0xdd4e8: device C0:B5:D7:A3:98:90 profile Object Push state changed: unavailable -> disconnected (0)
bluetoothd[19288]: src/service.c:btd_service_ref() 0xdd4e8: ref=2
bluetoothd[19288]: src/profile.c:ext_connect() Object Push connected to C0:B5:D7:A3:98:90
bluetoothd[19288]: src/service.c:change_state() 0xdd4e8: device C0:B5:D7:A3:98:90 profile Object Push state changed: disconnected -> connecting (0)
[CHG] Device C0:B5:D7:A3:98:90 UUIDs: 00001105-0000-1000-8000-00805f9b34fb
[DESKTOP-9TIPO5R]# bluetoothd[19288]: src/service.c:change_state() 0xdd4e8: device C0:B5:D7:A3:98:90 profile Object Push state changed: connecting -> connected (0)
bluetoothd[19288]: src/device.c:device_profile_connected() Object Push Success (0)
bluetoothd[19288]: profiles/audio/avctp.c:avctp_confirm_cb() AVCTP: incoming connect from C0:B5:D7:A3:98:90
bluetoothd[19288]: src/device.c:device_probe_profiles() Probing profiles for device C0:B5:D7:A3:98:90
bluetoothd[19288]: profiles/audio/avrcp.c:avrcp_controller_probe() path /org/bluez/hci0/dev_C0_B5_D7_A3_98_90
bluetoothd[19288]: profiles/audio/control.c:control_init() Registered interface org.bluez.MediaControl1 on path /org/bluez/hci0/dev_C0_B5_D7_A3_98_90
bluetoothd[19288]: src/service.c:btd_service_ref() 0xd92d8: ref=2
bluetoothd[19288]: src/service.c:change_state() 0xd92d8: device C0:B5:D7:A3:98:90 profile avrcp-controller state changed: unavailable -> disconnected (0)
bluetoothd[19288]: src/device.c:device_probe_profiles() Probing profiles for device C0:B5:D7:A3:98:90
bluetoothd[19288]: profiles/audio/avrcp.c:avrcp_target_probe() path /org/bluez/hci0/dev_C0_B5_D7_A3_98_90
bluetoothd[19288]: src/service.c:btd_service_ref() 0xdda28: ref=2
bluetoothd[19288]: src/service.c:change_state() 0xdda28: device C0:B5:D7:A3:98:90 profile audio-avrcp-target state changed: unavailable -> disconnected (0)
bluetoothd[19288]: profiles/audio/avctp.c:avctp_set_state() AVCTP Connecting
[CHG] Device C0:B5:D7:A3:98:90 UUIDs: 00001105-0000-1000-8000-00805f9b34fb
[CHG] Device C0:B5:D7:A3:98:90 UUIDs: 0000110c-0000-1000-8000-00805f9b34fb
[CHG] Device C0:B5:D7:A3:98:90 UUIDs: 0000110e-0000-1000-8000-00805f9b34fb
[DESKTOP-9TIPO5R]# obexd[20498]: CONNECT(0x0), (null)(0xffffffff)
obexd[20498]: CONNECT(0x0), (null)(0x0)
obexd[20498]: disconnected: Unicode conversion failed: Conversion from character set 'UTF-16BE' to 'UTF-8' is not supported【不支持】
[CHG] Device C0:B5:D7:A3:98:90 Modalias: bluetooth:v0006p0001d0A00
[DESKTOP-9TIPO5R]# bluetoothd[19288]: src/device.c:device_probe_profiles() Probing profiles for device C0:B5:D7:A3:98:90
bluetoothd[19288]: profiles/network/connection.c:connection_register() /org/bluez/hci0/dev_C0_B5_D7_A3_98_90 id 4373
bluetoothd[19288]: profiles/network/connection.c:create_peer() Registered interface org.bluez.Network1 on path /org/bluez/hci0/dev_C0_B5_D7_A3_98_90
bluetoothd[19288]: src/service.c:btd_service_ref() 0xfd420: ref=2
bluetoothd[19288]: profiles/network/connection.c:connection_register() id 4373 registered
bluetoothd[19288]: src/service.c:change_state() 0xfd420: device C0:B5:D7:A3:98:90 profile network-panu state changed: unavailable -> disconnected (0)
bluetoothd[19288]: profiles/audio/a2dp.c:a2dp_source_probe() path /org/bluez/hci0/dev_C0_B5_D7_A3_98_90
bluetoothd[19288]: profiles/audio/source.c:source_init() /org/bluez/hci0/dev_C0_B5_D7_A3_98_90
bluetoothd[19288]: src/service.c:btd_service_ref() 0xfd468: ref=2
bluetoothd[19288]: src/service.c:change_state() 0xfd468: device C0:B5:D7:A3:98:90 profile a2dp-source state changed: unavailable -> disconnected (0)
bluetoothd[19288]: profiles/audio/a2dp.c:a2dp_sink_probe() path /org/bluez/hci0/dev_C0_B5_D7_A3_98_90
bluetoothd[19288]: profiles/audio/sink.c:sink_init() /org/bluez/hci0/dev_C0_B5_D7_A3_98_90
bluetoothd[19288]: src/service.c:btd_service_ref() 0xfcb00: ref=2
bluetoothd[19288]: src/service.c:change_state() 0xfcb00: device C0:B5:D7:A3:98:90 profile a2dp-sink state changed: unavailable -> disconnected (0)
bluetoothd[19288]: src/device.c:device_svc_resolved() /org/bluez/hci0/dev_C0_B5_D7_A3_98_90 err 0
[CHG] Device C0:B5:D7:A3:98:90 UUIDs: 00001000-0000-1000-8000-00805f9b34fb
[CHG] Device C0:B5:D7:A3:98:90 UUIDs: 00001105-0000-1000-8000-00805f9b34fb
[CHG] Device C0:B5:D7:A3:98:90 UUIDs: 0000110a-0000-1000-8000-00805f9b34fb
[CHG] Device C0:B5:D7:A3:98:90 UUIDs: 0000110b-0000-1000-8000-00805f9b34fb
[CHG] Device C0:B5:D7:A3:98:90 UUIDs: 0000110c-0000-1000-8000-00805f9b34fb
[CHG] Device C0:B5:D7:A3:98:90 UUIDs: 0000110e-0000-1000-8000-00805f9b34fb
[CHG] Device C0:B5:D7:A3:98:90 UUIDs: 00001115-0000-1000-8000-00805f9b34fb
[CHG] Device C0:B5:D7:A3:98:90 UUIDs: 0000111f-0000-1000-8000-00805f9b34fb
[CHG] Device C0:B5:D7:A3:98:90 UUIDs: 00001200-0000-1000-8000-00805f9b34fb
[CHG] Device C0:B5:D7:A3:98:90 UUIDs: c7f94713-891e-496a-a0e7-983a0946126e
[DESKTOP-9TIPO5R]# bluetoothd[19288]: src/agent.c:agent_authorize_service() authorize service request was sent for /org/bluez/hci0/dev_C0_B5_D7_A3_98_90
[CHG] Device C0:B5:D7:A3:98:90 ServicesResolved: yes
[CHG] Device C0:B5:D7:A3:98:90 Paired: yes
Authorize service
Authorize service 0000110e-0000-1000-8000-00805f9b34fb (yes/no): yes
[DESKTOP-9TIPO5R]# bluetoothd[19288]: src/agent.c:agent_ref() 0xe5180: ref=3
bluetoothd[19288]: src/agent.c:agent_unref() 0xe5180: ref=2
bluetoothd[19288]: src/agent.c:agent_unref() 0xe5180: ref=1
bluetoothd[19288]: profiles/audio/avctp.c:avctp_connect_cb() AVCTP: connected to C0:B5:D7:A3:98:90
--------usb state=0
[ 764.996253]{1} input: C0:B5:D7:A3:98:90 as /devices/virtual/input/input1
--------usb state=0
bluetoothd[19288]: profiles/audio/avctp.c:init_uinput() AVRCP: uinput initialized for C0:B5:D7:A3:98:90
bluetoothd[19288]: profiles/audio/avrcp.c:controller_init() 0xfe868 version 0x0106
bluetoothd[19288]: src/service.c:change_state() 0xdda28: device C0:B5:D7:A3:98:90 profile audio-avrcp-target state changed: disconnected -> connected (0)
bluetoothd[19288]: profiles/audio/player.c:media_player_controller_create() /org/bluez/hci0/dev_C0_B5_D7_A3_98_90/player0
bluetoothd[19288]: profiles/audio/avrcp.c:target_init() 0xe6aa0 version 0x0106
bluetoothd[19288]: src/service.c:change_state() 0xd92d8: device C0:B5:D7:A3:98:90 profile avrcp-controller state changed: disconnected -> connected (0)
bluetoothd[19288]: profiles/audio/avctp.c:avctp_set_state() AVCTP Connected
bluetoothd[19288]: profiles/audio/avctp.c:avctp_confirm_cb() AVCTP: incoming connect from C0:B5:D7:A3:98:90
bluetoothd[19288]: profiles/audio/avctp.c:avctp_set_state() AVCTP Browsing Connecting
bluetoothd[19288]: profiles/audio/avrcp.c:handle_vendordep_pdu() AVRCP PDU 0x10, company 0x001958 len 0x0001
bluetoothd[19288]: profiles/audio/avrcp.c:avrcp_handle_get_capabilities() id=3
bluetoothd[19288]: profiles/audio/avctp.c:avctp_connect_browsing_cb() AVCTP Browsing: connected to C0:B5:D7:A3:98:90
bluetoothd[19288]: profiles/audio/avctp.c:avctp_set_state() AVCTP Browsing Connected
bluetoothd[19288]: profiles/audio/avrcp.c:handle_vendordep_pdu() AVRCP PDU 0x31, company 0x001958 len 0x0005
bluetoothd[19288]: profiles/audio/player.c:media_player_set_type() Audio
bluetoothd[19288]: profiles/audio/player.c:media_player_set_subtype() None
bluetoothd[19288]: profiles/audio/player.c:media_player_set_status() stopped
bluetoothd[19288]: profiles/audio/player.c:media_player_set_name() Windows
bluetoothd[19288]: profiles/audio/player.c:media_player_set_setting() Repeat: off
bluetoothd[19288]: profiles/audio/player.c:media_player_set_setting() Shuffle: off
bluetoothd[19288]: profiles/audio/player.c:media_player_set_playlist_item() 18446744073709551615
bluetoothd[19288]: profiles/audio/player.c:media_player_set_metadata() Title:
bluetoothd[19288]: profiles/audio/player.c:media_player_set_duration() 4294967295
bluetoothd[19288]: profiles/audio/player.c:media_player_set_position() 4294967295
bluetoothd[19288]: profiles/audio/player.c:media_player_set_status() stopped
bluetoothd[19288]: profiles/audio/player.c:media_player_set_duration() 4294967295
bluetoothd[19288]: profiles/audio/player.c:media_player_set_position() 4294967295
bluetoothd[19288]: profiles/audio/player.c:media_player_set_status() stopped
2、打开obexd代码函数调试开关
obexd代码使用加载环境变量的方式设置debug信息:
GObex *g_obex_new(GIOChannel *io, GObexTransportType transport_type,
gssize io_rx_mtu, gssize io_tx_mtu)
{
GObex *obex;
GIOCondition cond;
if (gobex_debug == 0) {
const char *env = g_getenv("GOBEX_DEBUG");
if (env) {
gobex_debug = g_parse_debug_string(env, keys, 7);
g_setenv("G_MESSAGES_DEBUG", "gobex", FALSE);
} else
gobex_debug = G_OBEX_DEBUG_NONE;
}
debug等级描述:
static GDebugKey keys[] = {
{ "error", G_OBEX_DEBUG_ERROR },
{ "command", G_OBEX_DEBUG_COMMAND },
{ "transfer", G_OBEX_DEBUG_TRANSFER },
{ "header", G_OBEX_DEBUG_HEADER },
{ "packet", G_OBEX_DEBUG_PACKET },
{ "data", G_OBEX_DEBUG_DATA },
{ "apparam", G_OBEX_DEBUG_APPARAM },
};
设置debug等级为header
export GOBEX_DEBUG=header
出现'UTF-16BE' to 'UTF-8' is not supported打印的函数:使用g_convert转码提示不支持。
GObexHeader *g_obex_header_decode(const void *data, gsize len,
GObexDataPolicy data_policy, gsize *parsed,
GError **err)
{
GObexHeader *header;
const guint8 *ptr = data;
guint16 hdr_len;
gsize str_len;
GError *conv_err = NULL;
if (len < 2) {
if (!err)
return NULL;
g_set_error(err, G_OBEX_ERROR, G_OBEX_ERROR_PARSE_ERROR,
"Too short header in packet");
g_obex_debug(G_OBEX_DEBUG_ERROR, "%s", (*err)->message);
return NULL;
}
header = g_new0(GObexHeader, 1);
ptr = get_bytes(&header->id, ptr, sizeof(header->id));
g_obex_debug(G_OBEX_DEBUG_HEADER, "header 0x%02x",
G_OBEX_HDR_ENC(header->id));
switch (G_OBEX_HDR_ENC(header->id)) {
case G_OBEX_HDR_ENC_UNICODE:
if (len < 3) {
g_set_error(err, G_OBEX_ERROR,
G_OBEX_ERROR_PARSE_ERROR,
"Not enough data for unicode header (0x%02x)",
header->id);
goto failed;
}
ptr = get_bytes(&hdr_len, ptr, sizeof(hdr_len));
hdr_len = g_ntohs(hdr_len);
if (hdr_len == 3) {
header->v.string = g_strdup("");
header->vlen = 0;
header->hlen = hdr_len;
*parsed = hdr_len;
break;
}
if (hdr_len > len || hdr_len < 5) {
g_set_error(err, G_OBEX_ERROR,
G_OBEX_ERROR_PARSE_ERROR,
"Invalid unicode header (0x%02x) length (%u)",
header->id, hdr_len);
goto failed;
}
header->v.string = g_convert((const char *) ptr, hdr_len - 5,
"UTF-8", "UTF-16BE",
NULL, &str_len, &conv_err);
if (header->v.string == NULL) {
g_set_error(err, G_OBEX_ERROR,
G_OBEX_ERROR_PARSE_ERROR,
"Unicode conversion failed: %s",
conv_err->message);
g_error_free(conv_err);
goto failed;
}
header->vlen = (gsize) str_len;
header->hlen = hdr_len;
*parsed = hdr_len;
break;
打印出编码和解码时header的类型:
# obexd[4015]: obexd/plugins/bluetooth.c:profile_new_connection() device /org/bluez/hci0/dev_C0_B5_D7_A3_98_90
obexd[4015]: obexd/src/obex.c:obex_session_start()
bluetoothd[3493]: src/service.c:change_state() 0xdde18: device C0:B5:D7:A3:98:90 profile Object Push state changed: connecting -> connected (0)
bluetoothd[3493]: src/device.c:device_profile_connected() Object Push Success (0)
(obexd:4015): gobex-DEBUG: gobex/gobex-header.c:g_obex_header_create_list()
obexd[4015]: obexd/src/obex.c:cmd_connect()
obexd[4015]: CONNECT(0x0), (null)(0xffffffff)
obexd[4015]: obexd/src/obex.c:cmd_connect() Selected driver: Object Push server
(obexd:4015): gobex-DEBUG: gobex/gobex-header.c:g_obex_header_create_list()
(obexd:4015): gobex-DEBUG: gobex/gobex-header.c:g_obex_header_new_uint32() header 0xc0
(obexd:4015): gobex-DEBUG: gobex/gobex-header.c:g_obex_header_new_uint32() 1
(obexd:4015): gobex-DEBUG: gobex/gobex-header.c:g_obex_header_get_length() header 0xc0 length 5
obexd[4015]: CONNECT(0x0), (null)(0x0)
(obexd:4015): gobex-DEBUG: gobex/gobex-header.c:g_obex_header_encode() header 0xc0
(obexd:4015): gobex-DEBUG: gobex/gobex-header.c:g_obex_header_free() header 0xc0
(obexd:4015): gobex-DEBUG: gobex/gobex-header.c:g_obex_header_create_list()
(obexd:4015): gobex-DEBUG: gobex/gobex-header.c:g_obex_header_decode() header 0x00【为何为0了?】【xml和txt,bin相同现象】
(obexd:4015): gobex-DEBUG: gobex/gobex-header.c:g_obex_header_free() header 0x00
obexd[4015]: disconnected: Unicode conversion failed: Conversion from character set 'UTF-16BE' to 'UTF-8' is not supported
obexd[4015]: obexd/src/obex.c:obex_session_destroy()
与IMX8平台正常的obexd对比打印:明显看到ecode() header 0x00时就提示转码不支持就停止了运行。说明是收到了数据但转码失败。
root@genvict_imx8qxp:~#
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_create_list()
obexd[10342]: CONNECT(0x0), <unknown>(0xff)
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_create_list()
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_new_uint32() header 0xc0
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_new_uint32() 1
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_length() header 0xc0 length 5
obexd[10342]: CONNECT(0x0), <unknown>(0x0)
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_encode() header 0xc0
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_free() header 0xc0
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_create_list()
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_decode() header 0x00
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_decode() header 0xc0 【没有执行这里的流程】
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_decode() header 0x40
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_id() header 0x00 id 0x01
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_id() header 0xc0 id 0xc3
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_id() header 0x40 id 0x49
obexd[10342]: PUT(0x2), <unknown>(0xff)
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_id() header 0x00 id 0x01
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_id() header 0xc0 id 0xc3
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_id() header 0x40 id 0x49
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_id() header 0x00 id 0x01
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_id() header 0xc0 id 0xc3
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_id() header 0x40 id 0x49
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_id() header 0x00 id 0x01
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_id() header 0xc0 id 0xc3
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_id() header 0x40 id 0x49
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_id() header 0x00 id 0x01
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_unicode() header 0x00
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_unicode() bt.txt
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_id() header 0x00 id 0x01
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_id() header 0xc0 id 0xc3
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_uint32() header 0xc0
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_uint32() 7
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_id() header 0x00 id 0x01
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_id() header 0xc0 id 0xc3
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_id() header 0x40 id 0x49
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_id() header 0x00 id 0x01
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_id() header 0xc0 id 0xc3
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_id() header 0x40 id 0x49
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_id() header 0x00 id 0x01
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_id() header 0xc0 id 0xc3
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_id() header 0x40 id 0x49
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_id() header 0x00 id 0x01
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_id() header 0xc0 id 0xc3
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_id() header 0x40 id 0x49
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_get_bytes() header 0x40
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_create_list()
obexd[10342]: PUT(0x2), Continue(0x10)
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_free() header 0x00
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_free() header 0xc0
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_free() header 0x40
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_create_list()
obexd[10342]: DISCONNECT(0x1), <unknown>(0xff)
obexd[10342]: DISCONNECT(0x1), Success(0x20)
(obexd:10342): gobex-DEBUG: ../bluez-5.54/gobex/gobex-header.c:g_obex_header_create_list()
obexd[10342]: disconnected: Transport got disconnected
3、查看GCONV_LIBS怎么使用
看编译链中的GCONV配置,toolchain/toolchain.mk,里面描述了如果打开配置,就会编译生成对应的动态库放到/usr/lib/gconv/目录下面。
# Install the gconv modules
ifeq ($(BR2_TOOLCHAIN_GLIBC_GCONV_LIBS_COPY),y)
GCONV_LIBS = $(call qstrip,$(BR2_TOOLCHAIN_GLIBC_GCONV_LIBS_LIST))
define COPY_GCONV_LIBS
$(Q)found_gconv=no; \
for d in $(TOOLCHAIN_EXTERNAL_PREFIX) ''; do \
[ -d "$(STAGING_DIR)/usr/lib/$${d}/gconv" ] || continue; \
found_gconv=yes; \
break; \
done; \
if [ "$${found_gconv}" = "no" ]; then \
printf "Unable to find gconv modules\n" >&2; \
exit 1; \
fi; \
if [ -z "$(GCONV_LIBS)" ]; then \
$(INSTALL) -m 0644 -D $(STAGING_DIR)/usr/lib/$${d}/gconv/gconv-modules \
$(TARGET_DIR)/usr/lib/gconv/gconv-modules && \
$(INSTALL) -m 0644 $(STAGING_DIR)/usr/lib/$${d}/gconv/*.so \
$(TARGET_DIR)/usr/lib/gconv \
|| exit 1; \
else \
for l in $(GCONV_LIBS); do \
$(INSTALL) -m 0644 -D $(STAGING_DIR)/usr/lib/$${d}/gconv/$${l}.so \
$(TARGET_DIR)/usr/lib/gconv/$${l}.so \
|| exit 1; \
$(TARGET_READELF) -d $(STAGING_DIR)/usr/lib/$${d}/gconv/$${l}.so |\
sort -u |\
sed -e '/.*(NEEDED).*\[\(.*\.so\)\]$$/!d; s//\1/;' |\
while read lib; do \
$(INSTALL) -m 0644 -D $(STAGING_DIR)/usr/lib/$${d}/gconv/$${lib} \
$(TARGET_DIR)/usr/lib/gconv/$${lib} \
|| exit 1; \
done; \
done; \
./support/scripts/expunge-gconv-modules "$(GCONV_LIBS)" \
<$(STAGING_DIR)/usr/lib/$${d}/gconv/gconv-modules \
>$(TARGET_DIR)/usr/lib/gconv/gconv-modules; \
fi
endef
TOOLCHAIN_TARGET_FINALIZE_HOOKS += COPY_GCONV_LIBS
endif
对比查看IMX8下面是有/usr/lib/gconv/目录文件的:但由于只用buildroot编译bluez工具,所以没有拷贝/usr/lib/gconv/下面的文件,导致了编码库的缺失,这里确实是一个很隐蔽的bug。
root@genvict_imx8qxp:~# ls /usr/lib/gconv/ -l
total 72
-rwxr-xr-x 1 root root 14184 May 26 22:24 UTF-16.so
-rw-r--r-- 1 root root 56282 May 26 22:05 gconv-modules
拷贝/usr/lib/gconv/的UTF-16.so和gconv-modules文件,obexd接收文件成功没有报错。
4、obexd UTF16BE to UTF8编码补丁
通过Google搜索,发现有ti公司的人发了一个补丁,用于UTF16BE to UTF8编码。
Bluetooth file receive failure
0001-obexd-fix-UTF-conversions.patch
Bluetooth: Receiving files failure
补丁实现了一个utf16be_to_utf8转换函数,替代g_convert函数,但是由于我的bluez版本是5.43比较高,与补丁函数参数差异较大,没有验证这个补丁的可行性,给有条件的童鞋验证。
- os->name = g_convert((const char *) hd.bs, hlen,
- "UTF8", "UTF16BE", NULL, NULL, NULL);
+ os->name = utf16be_to_utf8((const char *) hd.bs, hlen);
header->v.string = g_convert((const char *) ptr, hdr_len - 5,
"UTF-8", "UTF-16BE",
NULL, &str_len, &conv_err);