diff --git a/config/HAFE/splits.txt b/config/HAFE/splits.txt index eb1a6b0..250fae9 100644 --- a/config/HAFE/splits.txt +++ b/config/HAFE/splits.txt @@ -1766,9 +1766,6 @@ revolution/BTE/stack/btm/btm_devctl.c: .data start:0x801D1A80 end:0x801D1CDA .sdata start:0x803308F8 end:0x8033090A -revolution/BTE/stack/gap/gap_conn.c: - .sdata start:0x80330910 end:0x80330918 - revolution/BTE/stack/btm/btm_inq.c: .text start:0x8014038C end:0x80141F58 .data start:0x801D1CE0 end:0x801D1EEA @@ -1778,9 +1775,6 @@ revolution/BTE/stack/btm/btm_main.c: .text start:0x80141F58 end:0x80141FB4 .bss start:0x80324978 end:0x8032713C -revolution/BTE/stack/gap/gap_utils.c: - .bss start:0x80327140 end:0x803274F0 - revolution/BTE/stack/btm/btm_pm.c: .text start:0x80141FB4 end:0x80142C48 .rodata start:0x80197838 end:0x80197848 @@ -1805,6 +1799,73 @@ revolution/BTE/stack/btu/btu_init.c: .text start:0x80147CA0 end:0x80147D18 .sdata2 start:0x80333140 end:0x80333146 +revolution/BTE/wbt_ext.c: + .text start:0x80147D18 end:0x80147DF8 + +revolution/BTE/stack/gap/gap_api.c: + .text start:0x80147DF8 end:0x80147E58 + +revolution/BTE/stack/gap/gap_conn.c: + .text start:0x80147E58 end:0x80148994 + .data start:0x801D2CD0 end:0x801D2DA0 + .sdata start:0x80330910 end:0x80330918 + +revolution/BTE/stack/gap/gap_utils.c: + .text start:0x80148994 end:0x80148FB0 + .data start:0x801D2DA0 end:0x801D3090 + .bss start:0x80327140 end:0x803274F0 + +revolution/BTE/stack/hcic/hcicmds.c: + .text start:0x80148FB0 end:0x8014B6CC + .rodata start:0x80197858 end:0x80197868 + +revolution/BTE/stack/hid/hidd_api.c: + .text start:0x8014B6CC end:0x8014B734 + +revolution/BTE/stack/hid/hidd_conn.c: + .text start:0x8014B734 end:0x8014B7F4 + .data start:0x801D3090 end:0x801D30C0 + +revolution/BTE/stack/hid/hidd_mgmt.c: + .text start:0x8014B7F4 end:0x8014B8BC + .data start:0x801D30C0 end:0x801D30E0 + .bss start:0x803274F0 end:0x80327638 + +revolution/BTE/stack/hid/hidd_pm.c: + .text start:0x8014B8BC end:0x8014BC38 + +revolution/BTE/stack/hid/hidh_api.c: + .text start:0x8014BC38 end:0x8014C9B8 + .data start:0x801D30E0 end:0x801D31F8 + .bss start:0x80327638 end:0x80327A3C + +revolution/BTE/stack/hid/hidh_conn.c: + .text start:0x8014C9B8 end:0x8014E9F8 + .rodata start:0x80197868 end:0x80197890 + .data start:0x801D31F8 end:0x801D35E0 + +revolution/BTE/stack/l2cap/l2c_api.c: + .text start:0x8014E9F8 end:0x8014F5C4 + .data start:0x801D35E0 end:0x801D3D70 + +revolution/BTE/stack/l2cap/l2c_csm.c: + .text start:0x8014F5C4 end:0x80150AA0 + .data start:0x801D3D70 end:0x801D45A8 + +revolution/BTE/stack/l2cap/l2c_link.c: + .text start:0x80150AA0 end:0x80151C2C + .data start:0x801D45A8 end:0x801D4818 + +revolution/BTE/stack/l2cap/l2c_main.c: + .text start:0x80151C2C end:0x80152C5C + .data start:0x801D4818 end:0x801D4B18 + .bss start:0x80327A40 end:0x80328228 + +revolution/BTE/stack/l2cap/l2c_utils.c: + .text start:0x80152C5C end:0x80154B20 + .data start:0x801D4B18 end:0x801D4C00 + .sdata start:0x80330918 end:0x80330928 + revolution/BTE/stack/rfcomm/port_api.c: .text start:0x80154B20 end:0x80154B70 diff --git a/config/HAFE/symbols.txt b/config/HAFE/symbols.txt index 6dc3cd5..7bf80f3 100644 --- a/config/HAFE/symbols.txt +++ b/config/HAFE/symbols.txt @@ -5097,8 +5097,8 @@ gap_disconnect_ind = .text:0x80148558; // type:function size:0x1F8 scope:global gap_data_ind = .text:0x80148750; // type:function size:0x110 scope:global gap_congestion_ind = .text:0x80148860; // type:function size:0x134 scope:global btm_cback = .text:0x80148994; // type:function size:0x1D8 scope:global -fn_80148B6C = .text:0x80148B6C; // type:function size:0xC -fn_80148B78 = .text:0x80148B78; // type:function size:0xC +gap_btm_cback0 = .text:0x80148B6C; // type:function size:0xC +gap_btm_cback1 = .text:0x80148B78; // type:function size:0xC gap_find_addr_name_cb = .text:0x80148B84; // type:function size:0x218 scope:global gap_find_addr_inq_cb = .text:0x80148D9C; // type:function size:0x1B4 scope:global gap_convert_btm_status = .text:0x80148F50; // type:function size:0x60 scope:global @@ -5243,7 +5243,7 @@ l2c_process_held_packets = .text:0x80152B30; // type:function size:0x12C scope:g l2cu_allocate_lcb = .text:0x80152C5C; // type:function size:0xD4 scope:global l2cu_release_lcb = .text:0x80152D30; // type:function size:0x100 scope:global l2cu_find_lcb_by_bd_addr = .text:0x80152E30; // type:function size:0x88 scope:global -fn_80152EB8 = .text:0x80152EB8; // type:function size:0x90 +l2cu_find_lcb_by_handle = .text:0x80152EB8; // type:function size:0x90 l2cu_get_conn_role = .text:0x80152F48; // type:function size:0x10 scope:global l2cu_build_header = .text:0x80152F58; // type:function size:0xC4 scope:global l2cu_send_peer_cmd_reject = .text:0x8015301C; // type:function size:0xFC scope:global @@ -6255,8 +6255,9 @@ lbl_80197810 = .rodata:0x80197810; // type:object size:0x18 lbl_80197828 = .rodata:0x80197828; // type:object size:0x10 lbl_80197838 = .rodata:0x80197838; // type:object size:0x10 lbl_80197848 = .rodata:0x80197848; // type:object size:0x10 data:4byte -lbl_80197858 = .rodata:0x80197858; // type:object size:0x10 data:byte -lbl_80197868 = .rodata:0x80197868; // type:object size:0x28 +@1234 = .rodata:0x80197858; // type:object size:0xA scope:local data:byte +hcicmds_rodata_pad = .rodata:0x80197864; // type:object size:0x4 scope:local +hst_reg_info = .rodata:0x80197868; // type:object size:0x28 scope:local rfc_crctable = .rodata:0x80197890; // type:object size:0x100 scope:local lbl_80197990 = .rodata:0x80197990; // type:object size:0x10 __ptmf_null = .rodata:0x801979A0; // type:object size:0x10 data:4byte @@ -8076,92 +8077,164 @@ lbl_801D2C24 = .data:0x801D2C24; // type:object size:0x1C scope:local data:strin @2610 = .data:0x801D2C58; // type:object size:0x27 scope:local data:string @2626 = .data:0x801D2C80; // type:object size:0x1D scope:local data:string @2627 = .data:0x801D2CA0; // type:object size:0x30 scope:local data:string -lbl_801D2CD0 = .data:0x801D2CD0; // type:object size:0x44 data:string -lbl_801D2D14 = .data:0x801D2D14; // type:object size:0x2A data:string -lbl_801D2D40 = .data:0x801D2D40; // type:object size:0x26 data:string -lbl_801D2D68 = .data:0x801D2D68; // type:object size:0x33 data:string -lbl_801D2DA0 = .data:0x801D2DA0; // type:object size:0xCC -jumptable_801D2E6C = .data:0x801D2E6C; // type:object size:0x24 scope:local -lbl_801D2E90 = .data:0x801D2E90; // type:object size:0x88 -lbl_801D2F18 = .data:0x801D2F18; // type:object size:0x44 data:string -lbl_801D2F5C = .data:0x801D2F5C; // type:object size:0x39 data:string -jumptable_801D2F98 = .data:0x801D2F98; // type:object size:0x24 scope:local -jumptable_801D2FBC = .data:0x801D2FBC; // type:object size:0x24 scope:local -lbl_801D2FE0 = .data:0x801D2FE0; // type:object size:0x42 data:string -jumptable_801D3024 = .data:0x801D3024; // type:object size:0x24 scope:local -jumptable_801D3048 = .data:0x801D3048; // type:object size:0x24 scope:local -jumptable_801D306C = .data:0x801D306C; // type:object size:0x24 scope:local -lbl_801D3090 = .data:0x801D3090; // type:object size:0x18 data:string -lbl_801D30A8 = .data:0x801D30A8; // type:object size:0x17 data:string -lbl_801D30C0 = .data:0x801D30C0; // type:object size:0x19 data:string -lbl_801D30E0 = .data:0x801D30E0; // type:object size:0x118 -lbl_801D31F8 = .data:0x801D31F8; // type:object size:0x20 data:string -lbl_801D3218 = .data:0x801D3218; // type:object size:0x22 data:string -lbl_801D323C = .data:0x801D323C; // type:object size:0x120 -lbl_801D335C = .data:0x801D335C; // type:object size:0xB8 -lbl_801D3414 = .data:0x801D3414; // type:object size:0x2C data:string -lbl_801D3440 = .data:0x801D3440; // type:object size:0x58 -lbl_801D3498 = .data:0x801D3498; // type:object size:0x29 data:string -lbl_801D34C4 = .data:0x801D34C4; // type:object size:0x21 data:string -lbl_801D34E8 = .data:0x801D34E8; // type:object size:0x2D data:string -lbl_801D3518 = .data:0x801D3518; // type:object size:0x25 data:string -lbl_801D3540 = .data:0x801D3540; // type:object size:0x36 data:string -lbl_801D3578 = .data:0x801D3578; // type:object size:0x38 data:string -lbl_801D35B0 = .data:0x801D35B0; // type:object size:0x29 data:string -lbl_801D35E0 = .data:0x801D35E0; // type:object size:0xA8 -lbl_801D3688 = .data:0x801D3688; // type:object size:0x31 data:string -lbl_801D36BC = .data:0x801D36BC; // type:object size:0x27C -lbl_801D3938 = .data:0x801D3938; // type:object size:0x1E data:string -lbl_801D3958 = .data:0x801D3958; // type:object size:0x29 data:string -lbl_801D3984 = .data:0x801D3984; // type:object size:0x2A data:string -lbl_801D39B0 = .data:0x801D39B0; // type:object size:0x29 data:string -lbl_801D39DC = .data:0x801D39DC; // type:object size:0x22 data:string -lbl_801D3A00 = .data:0x801D3A00; // type:object size:0x2A data:string -lbl_801D3A2C = .data:0x801D3A2C; // type:object size:0x22 data:string -lbl_801D3A50 = .data:0x801D3A50; // type:object size:0x160 -lbl_801D3BB0 = .data:0x801D3BB0; // type:object size:0x1C0 -jumptable_801D3D70 = .data:0x801D3D70; // type:object size:0x24 scope:local -lbl_801D3D94 = .data:0x801D3D94; // type:object size:0x1B data:string -lbl_801D3DB0 = .data:0x801D3DB0; // type:object size:0x80 -jumptable_801D3E30 = .data:0x801D3E30; // type:object size:0x7C scope:local -lbl_801D3EAC = .data:0x801D3EAC; // type:object size:0x25 data:string -jumptable_801D3ED4 = .data:0x801D3ED4; // type:object size:0x6C scope:local -lbl_801D3F40 = .data:0x801D3F40; // type:object size:0x25 data:string -lbl_801D3F68 = .data:0x801D3F68; // type:object size:0x2E data:string -jumptable_801D3F98 = .data:0x801D3F98; // type:object size:0x6C scope:local -lbl_801D4004 = .data:0x801D4004; // type:object size:0xFC -jumptable_801D4100 = .data:0x801D4100; // type:object size:0x70 scope:local -lbl_801D4170 = .data:0x801D4170; // type:object size:0x24 data:string -jumptable_801D4194 = .data:0x801D4194; // type:object size:0x70 scope:local -lbl_801D4204 = .data:0x801D4204; // type:object size:0x124 -jumptable_801D4328 = .data:0x801D4328; // type:object size:0x70 scope:local -lbl_801D4398 = .data:0x801D4398; // type:object size:0x19 data:string -jumptable_801D43B4 = .data:0x801D43B4; // type:object size:0x6C scope:local -lbl_801D4420 = .data:0x801D4420; // type:object size:0x58 -jumptable_801D4478 = .data:0x801D4478; // type:object size:0x70 scope:local -lbl_801D44E8 = .data:0x801D44E8; // type:object size:0x25 data:string -jumptable_801D4510 = .data:0x801D4510; // type:object size:0x70 scope:local -lbl_801D4580 = .data:0x801D4580; // type:object size:0x27 data:string -lbl_801D45A8 = .data:0x801D45A8; // type:object size:0x1D data:string -lbl_801D45C8 = .data:0x801D45C8; // type:object size:0x23 data:string -lbl_801D45F0 = .data:0x801D45F0; // type:object size:0x28 data:string -lbl_801D4618 = .data:0x801D4618; // type:object size:0x33 data:string -lbl_801D464C = .data:0x801D464C; // type:object size:0x27 data:string -lbl_801D4674 = .data:0x801D4674; // type:object size:0xE4 -lbl_801D4758 = .data:0x801D4758; // type:object size:0x47 data:string -lbl_801D47A0 = .data:0x801D47A0; // type:object size:0x20 data:string -lbl_801D47C0 = .data:0x801D47C0; // type:object size:0x1E data:string -lbl_801D47E0 = .data:0x801D47E0; // type:object size:0x32 data:string -lbl_801D4818 = .data:0x801D4818; // type:object size:0x2A4 -jumptable_801D4ABC = .data:0x801D4ABC; // type:object size:0x30 scope:local -lbl_801D4AEC = .data:0x801D4AEC; // type:object size:0x14 data:string -lbl_801D4B00 = .data:0x801D4B00; // type:object size:0x13 data:string -lbl_801D4B18 = .data:0x801D4B18; // type:object size:0x1A data:string -lbl_801D4B34 = .data:0x801D4B34; // type:object size:0x1F data:string -lbl_801D4B54 = .data:0x801D4B54; // type:object size:0x1E data:string -lbl_801D4B74 = .data:0x801D4B74; // type:object size:0x1F data:string -lbl_801D4B94 = .data:0x801D4B94; // type:object size:0x44 data:string -lbl_801D4BD8 = .data:0x801D4BD8; // type:object size:0x27 data:string +gap_conn_trace_unexpected_addr = .data:0x801D2CD0; // type:object size:0x44 data:string +gap_conn_trace_connect_ind = .data:0x801D2D14; // type:object size:0x2A data:string +gap_conn_trace_disconnect_ind = .data:0x801D2D40; // type:object size:0x26 data:string +gap_conn_trace_congestion_ind = .data:0x801D2D68; // type:object size:0x38 data:string +@1333 = .data:0x801D2DA0; // type:object size:0x3C scope:local data:string +@1334 = .data:0x801D2DDC; // type:object size:0x34 scope:local data:string +@1335 = .data:0x801D2E10; // type:object size:0x28 scope:local data:string +@1336 = .data:0x801D2E38; // type:object size:0x32 scope:local data:string +@1338 = .data:0x801D2E6C; // type:object size:0x24 scope:local +gap_utils_inq_results_traces = .data:0x801D2E90; // type:object size:0x88 +gap_utils_trace_find_name = .data:0x801D2F18; // type:object size:0x44 data:string +gap_utils_trace_find_name_status = .data:0x801D2F5C; // type:object size:0x39 data:string +@1379 = .data:0x801D2F98; // type:object size:0x24 scope:local +@1378 = .data:0x801D2FBC; // type:object size:0x24 scope:local +gap_utils_trace_find_inq = .data:0x801D2FE0; // type:object size:0x42 data:string +@1414 = .data:0x801D3024; // type:object size:0x24 scope:local +@1413 = .data:0x801D3048; // type:object size:0x24 scope:local +@1425 = .data:0x801D306C; // type:object size:0x24 scope:local +hidd_conn_trace_originate = .data:0x801D3090; // type:object size:0x18 data:string +hidd_conn_trace_originate_failed = .data:0x801D30A8; // type:object size:0x18 data:string +hidd_mgmt_trace_repage = .data:0x801D30C0; // type:object size:0x20 data:string +@1335 = .data:0x801D30E0; // type:object size:0x17 scope:local data:string +@1336 = .data:0x801D30F8; // type:object size:0x16 scope:local data:string +@1337 = .data:0x801D3110; // type:object size:0x24 scope:local data:string +@1367 = .data:0x801D3134; // type:object size:0x1F scope:local data:string +@1368 = .data:0x801D3154; // type:object size:0x1F scope:local data:string +@1369 = .data:0x801D3174; // type:object size:0x1F scope:local data:string +@1370 = .data:0x801D3194; // type:object size:0x1F scope:local data:string +@1371 = .data:0x801D31B4; // type:object size:0x1F scope:local data:string +@1372 = .data:0x801D31D4; // type:object size:0x24 scope:local data:string +@1843 = .data:0x801D31F8; // type:object size:0x20 scope:local data:string +@1844 = .data:0x801D3218; // type:object size:0x22 scope:local data:string +@1855 = .data:0x801D323C; // type:object size:0x11 scope:local data:string +@1901 = .data:0x801D3250; // type:object size:0x31 scope:local data:string +@1902 = .data:0x801D3284; // type:object size:0x33 scope:local data:string +@1903 = .data:0x801D32B8; // type:object size:0x30 scope:local data:string +@1904 = .data:0x801D32E8; // type:object size:0x2F scope:local data:string +@1905 = .data:0x801D3318; // type:object size:0x42 scope:local data:string +@1915 = .data:0x801D335C; // type:object size:0x17 scope:local data:string +@1945 = .data:0x801D3378; // type:object size:0x20 scope:local data:string +@1946 = .data:0x801D3398; // type:object size:0x1C scope:local data:string +@1987 = .data:0x801D33B4; // type:object size:0x2A scope:local data:string +@1988 = .data:0x801D33E0; // type:object size:0x31 scope:local data:string +@2010 = .data:0x801D3414; // type:object size:0x2C scope:local data:string +@2011 = .data:0x801D3440; // type:object size:0x2C scope:local data:string +@2039 = .data:0x801D346C; // type:object size:0x2A scope:local data:string +@2061 = .data:0x801D3498; // type:object size:0x29 scope:local data:string +@2062 = .data:0x801D34C4; // type:object size:0x21 scope:local data:string +@2079 = .data:0x801D34E8; // type:object size:0x2D scope:local data:string +@2080 = .data:0x801D3518; // type:object size:0x25 scope:local data:string +@2096 = .data:0x801D3540; // type:object size:0x36 scope:local data:string +@2097 = .data:0x801D3578; // type:object size:0x38 scope:local data:string +@2137 = .data:0x801D35B0; // type:object size:0x30 scope:local data:string +@1185 = .data:0x801D35E0; // type:object size:0x2F scope:local data:string +@1186 = .data:0x801D3610; // type:object size:0x26 scope:local data:string +@1187 = .data:0x801D3638; // type:object size:0x27 scope:local data:string +@1188 = .data:0x801D3660; // type:object size:0x26 scope:local data:string +@1195 = .data:0x801D3688; // type:object size:0x31 scope:local data:string +@1196 = .data:0x801D36BC; // type:object size:0x31 scope:local data:string +@1214 = .data:0x801D36F0; // type:object size:0x1F scope:local data:string +@1215 = .data:0x801D3710; // type:object size:0x36 scope:local data:string +@1216 = .data:0x801D3748; // type:object size:0x22 scope:local data:string +@1217 = .data:0x801D376C; // type:object size:0x2E scope:local data:string +@1218 = .data:0x801D379C; // type:object size:0x21 scope:local data:string +@1219 = .data:0x801D37C0; // type:object size:0x38 scope:local data:string +@1220 = .data:0x801D37F8; // type:object size:0x21 scope:local data:string +@1221 = .data:0x801D381C; // type:object size:0x2D scope:local data:string +@1238 = .data:0x801D384C; // type:object size:0x37 scope:local data:string +@1239 = .data:0x801D3884; // type:object size:0x36 scope:local data:string +@1240 = .data:0x801D38BC; // type:object size:0x21 scope:local data:string +@1241 = .data:0x801D38E0; // type:object size:0x21 scope:local data:string +@1242 = .data:0x801D3904; // type:object size:0x32 scope:local data:string +@1248 = .data:0x801D3938; // type:object size:0x1E scope:local data:string +@1249 = .data:0x801D3958; // type:object size:0x29 scope:local data:string +@1257 = .data:0x801D3984; // type:object size:0x2A scope:local data:string +@1258 = .data:0x801D39B0; // type:object size:0x29 scope:local data:string +@1264 = .data:0x801D39DC; // type:object size:0x22 scope:local data:string +@1265 = .data:0x801D3A00; // type:object size:0x2A scope:local data:string +@1270 = .data:0x801D3A2C; // type:object size:0x22 scope:local data:string +@1271 = .data:0x801D3A50; // type:object size:0x2A scope:local data:string +@1279 = .data:0x801D3A7C; // type:object size:0x27 scope:local data:string +@1280 = .data:0x801D3AA4; // type:object size:0x2B scope:local data:string +@1281 = .data:0x801D3AD0; // type:object size:0x38 scope:local data:string +l2c_api_ping_traces = .data:0x801D3B08; // type:object size:0xA8 scope:local +@1290 = .data:0x801D3BB0; // type:object size:0x30 scope:local data:string +l2c_api_dead_traces = .data:0x801D3BE0; // type:object size:0x190 scope:local +@1547 = .data:0x801D3D70; // type:object size:0x24 scope:local +@1574 = .data:0x801D3D94; // type:object size:0x1B scope:local data:string +@1575 = .data:0x801D3DB0; // type:object size:0x41 scope:local data:string +@1576 = .data:0x801D3DF4; // type:object size:0x39 scope:local data:string +@1579 = .data:0x801D3E30; // type:object size:0x7C scope:local +@1593 = .data:0x801D3EAC; // type:object size:0x25 scope:local data:string +@1596 = .data:0x801D3ED4; // type:object size:0x6C scope:local +@1610 = .data:0x801D3F40; // type:object size:0x25 scope:local data:string +@1611 = .data:0x801D3F68; // type:object size:0x2E scope:local data:string +@1614 = .data:0x801D3F98; // type:object size:0x6C scope:local +@1633 = .data:0x801D4004; // type:object size:0x25 scope:local data:string +@1634 = .data:0x801D402C; // type:object size:0x37 scope:local data:string +@1635 = .data:0x801D4064; // type:object size:0x21 scope:local data:string +@1636 = .data:0x801D4088; // type:object size:0x40 scope:local data:string +@1637 = .data:0x801D40C8; // type:object size:0x37 scope:local data:string +@1640 = .data:0x801D4100; // type:object size:0x70 scope:local +@1659 = .data:0x801D4170; // type:object size:0x24 scope:local data:string +@1662 = .data:0x801D4194; // type:object size:0x70 scope:local +@1689 = .data:0x801D4204; // type:object size:0x1B scope:local data:string +@1690 = .data:0x801D4220; // type:object size:0x2D scope:local data:string +@1691 = .data:0x801D4250; // type:object size:0x2D scope:local data:string +@1692 = .data:0x801D4280; // type:object size:0x3A scope:local data:string +@1693 = .data:0x801D42BC; // type:object size:0x3E scope:local data:string +@1694 = .data:0x801D42FC; // type:object size:0x2A scope:local data:string +@1697 = .data:0x801D4328; // type:object size:0x70 scope:local +@1718 = .data:0x801D4398; // type:object size:0x19 scope:local data:string +@1721 = .data:0x801D43B4; // type:object size:0x6C scope:local +@1737 = .data:0x801D4420; // type:object size:0x26 scope:local data:string +@1738 = .data:0x801D4448; // type:object size:0x30 scope:local data:string +@1741 = .data:0x801D4478; // type:object size:0x70 scope:local +@1752 = .data:0x801D44E8; // type:object size:0x25 scope:local data:string +@1755 = .data:0x801D4510; // type:object size:0x70 scope:local +@1772 = .data:0x801D4580; // type:object size:0x28 scope:local data:string +@2009 = .data:0x801D45A8; // type:object size:0x1D scope:local data:string +@2010 = .data:0x801D45C8; // type:object size:0x23 scope:local data:string +@2036 = .data:0x801D45F0; // type:object size:0x28 scope:local data:string +@2037 = .data:0x801D4618; // type:object size:0x33 scope:local data:string +@2048 = .data:0x801D464C; // type:object size:0x27 scope:local data:string +@2087 = .data:0x801D4674; // type:object size:0x15 scope:local data:string +@2135 = .data:0x801D468C; // type:object size:0x2C scope:local data:string +@2136 = .data:0x801D46B8; // type:object size:0x3E scope:local data:string +@2137 = .data:0x801D46F8; // type:object size:0x1B scope:local data:string +@2138 = .data:0x801D4718; // type:object size:0x40 scope:local data:string +@2172 = .data:0x801D4758; // type:object size:0x47 scope:local data:string +@2214 = .data:0x801D47A0; // type:object size:0x20 scope:local data:string +@2215 = .data:0x801D47C0; // type:object size:0x1E scope:local data:string +@2248 = .data:0x801D47E0; // type:object size:0x38 scope:local data:string +...data.0 = .data:0x801D4818; // type:label hidden +@1851 = .data:0x801D483C; // type:object size:0x4E scope:local data:string +@1852 = .data:0x801D4890; // type:object size:0x18 scope:local data:string +@1853 = .data:0x801D48A8; // type:object size:0x21 scope:local data:string +@1854 = .data:0x801D48CC; // type:object size:0x2C scope:local data:string +@1855 = .data:0x801D48F8; // type:object size:0x1F scope:local data:string +@1949 = .data:0x801D4918; // type:object size:0x34 scope:local data:string +@1950 = .data:0x801D494C; // type:object size:0x23 scope:local data:string +@1951 = .data:0x801D4970; // type:object size:0x30 scope:local data:string +@1952 = .data:0x801D49A0; // type:object size:0x2A scope:local data:string +@1953 = .data:0x801D49CC; // type:object size:0x1F scope:local data:string +@1954 = .data:0x801D49EC; // type:object size:0x2F scope:local data:string +@1955 = .data:0x801D4A1C; // type:object size:0x2A scope:local data:string +@1956 = .data:0x801D4A48; // type:object size:0x2A scope:local data:string +@1957 = .data:0x801D4A74; // type:object size:0x29 scope:local data:string +@1958 = .data:0x801D4AA0; // type:object size:0x19 scope:local data:string +@1961 = .data:0x801D4ABC; // type:object size:0x30 scope:local +@1979 = .data:0x801D4AEC; // type:object size:0x14 scope:local data:string +@1980 = .data:0x801D4B00; // type:object size:0x18 scope:local data:string +@2216 = .data:0x801D4B18; // type:object size:0x1A scope:local data:string +@2221 = .data:0x801D4B34; // type:object size:0x1F scope:local data:string +@2279 = .data:0x801D4B54; // type:object size:0x1E scope:local data:string +@2313 = .data:0x801D4B74; // type:object size:0x1F scope:local data:string +@2475 = .data:0x801D4B94; // type:object size:0x44 scope:local data:string +@2486 = .data:0x801D4BD8; // type:object size:0x28 scope:local lbl_801D4C00 = .data:0x801D4C00; // type:object size:0x13 data:string lbl_801D4C14 = .data:0x801D4C14; // type:object size:0x21 data:string lbl_801D4C38 = .data:0x801D4C38; // type:object size:0x18 data:string @@ -8705,8 +8778,10 @@ bta_dm_cb = .bss:0x80324614; // type:object size:0x104 bta_dm_conn_srvcs = .bss:0x80324718; // type:object size:0x2E data:byte bta_hh_cb = .bss:0x80324748; // type:object size:0x230 btm_cb = .bss:0x80324978; // type:object size:0x27C4 -gap_cb = .bss:0x80327140; // type:object size:0x3B0 -lbl_803274F0 = .bss:0x803274F0; // type:object size:0x148 +gap_cb = .bss:0x80327140; // type:object size:0x3AC +..bss_pad_gap_utils = .bss:0x803274EC; // type:label size:0x4 hidden +hd_cb = .bss:0x803274F0; // type:object size:0x144 +..bss_pad_hidd = .bss:0x80327634; // type:label size:0x4 hidden hh_cb = .bss:0x80327638; // type:object size:0x404 data:byte l2cb = .bss:0x80327A40; // type:object size:0x7E8 data:byte rfc_cb = .bss:0x80328228; // type:object size:0x418 data:byte @@ -9486,9 +9561,9 @@ lbl_803308F0 = .sdata:0x803308F0; // type:object size:0x8 lbl_803308F8 = .sdata:0x803308F8; // type:object size:0x4 scope:local lbl_803308FC = .sdata:0x803308FC; // type:object size:0x5 scope:local data:string lbl_80330904 = .sdata:0x80330904; // type:object size:0x6 scope:local data:string -lbl_80330910 = .sdata:0x80330910; // type:object size:0x8 data:string -lbl_80330918 = .sdata:0x80330918; // type:object size:0x5 data:string -lbl_80330920 = .sdata:0x80330920; // type:object size:0x6 data:string +gap_conn_trace_separator = .sdata:0x80330910; // type:object size:0x8 data:string +@2476 = .sdata:0x80330918; // type:object size:0x5 scope:local data:string +@2477 = .sdata:0x80330920; // type:object size:0x8 scope:local lbl_80330928 = .sdata:0x80330928; // type:object size:0x7 scope:local data:string lbl_80330930 = .sdata:0x80330930; // type:object size:0x7 scope:local data:string lbl_80330938 = .sdata:0x80330938; // type:object size:0x6 data:string diff --git a/configure.py b/configure.py index 098d7e8..fe69950 100755 --- a/configure.py +++ b/configure.py @@ -483,23 +483,31 @@ def MatchingFor(*versions): Object(Matching, "revolution/BTE/stack/btu/btu_init.c"), Object(Matching, "revolution/BTE/stack/btu/btu_task.c"), - # BTE/stack/gap (only their data is split so far) - Object(NonMatching, "revolution/BTE/stack/gap/gap_conn.c"), - Object(NonMatching, "revolution/BTE/stack/gap/gap_utils.c"), + # BTE/wbt + Object(Matching, "revolution/BTE/wbt_ext.c"), + + # BTE/stack/gap + Object(Matching, "revolution/BTE/stack/gap/gap_api.c"), + Object(Matching, "revolution/BTE/stack/gap/gap_conn.c"), + Object(Matching, "revolution/BTE/stack/gap/gap_utils.c"), # BTE/stack/hcic - Object(NonMatching, "revolution/BTE/stack/hcic/hcicmds.c"), + Object(Matching, "revolution/BTE/stack/hcic/hcicmds.c", mw_version="GC/3.0a5.2"), # BTE/stack/hid - Object(NonMatching, "revolution/BTE/stack/hid/hidh_api.c"), - Object(NonMatching, "revolution/BTE/stack/hid/hidh_conn.c"), + Object(Matching, "revolution/BTE/stack/hid/hidd_api.c"), + Object(Matching, "revolution/BTE/stack/hid/hidd_conn.c"), + Object(Matching, "revolution/BTE/stack/hid/hidd_mgmt.c"), + Object(Matching, "revolution/BTE/stack/hid/hidd_pm.c"), + Object(Matching, "revolution/BTE/stack/hid/hidh_api.c"), + Object(Matching, "revolution/BTE/stack/hid/hidh_conn.c"), # BTE/stack/l2cap - Object(NonMatching, "revolution/BTE/stack/l2cap/l2c_api.c"), - Object(NonMatching, "revolution/BTE/stack/l2cap/l2c_csm.c"), - Object(NonMatching, "revolution/BTE/stack/l2cap/l2c_link.c"), - Object(NonMatching, "revolution/BTE/stack/l2cap/l2c_main.c"), - Object(NonMatching, "revolution/BTE/stack/l2cap/l2c_utils.c"), + Object(Matching, "revolution/BTE/stack/l2cap/l2c_api.c"), + Object(Matching, "revolution/BTE/stack/l2cap/l2c_csm.c"), + Object(Matching, "revolution/BTE/stack/l2cap/l2c_link.c"), + Object(Matching, "revolution/BTE/stack/l2cap/l2c_main.c"), + Object(Matching, "revolution/BTE/stack/l2cap/l2c_utils.c"), # BTE/stack/rfcomm Object(Matching, "revolution/BTE/stack/rfcomm/port_api.c"), diff --git a/include/revolution/BTE/include/bt_target.h b/include/revolution/BTE/include/bt_target.h index 4e81a6a..f3bf829 100644 --- a/include/revolution/BTE/include/bt_target.h +++ b/include/revolution/BTE/include/bt_target.h @@ -1356,12 +1356,12 @@ and USER_HW_DISABLE_API macros */ /* The maximum number of simultaneous applications that can register with L2CAP. */ #ifndef MAX_L2CAP_CLIENTS -#define MAX_L2CAP_CLIENTS 15 +#define MAX_L2CAP_CLIENTS 8 #endif /* The number of seconds of link inactivity before a link is disconnected. */ #ifndef L2CAP_LINK_INACTIVITY_TOUT -#define L2CAP_LINK_INACTIVITY_TOUT 4 +#define L2CAP_LINK_INACTIVITY_TOUT 2 #endif /* The number of seconds of link inactivity after bonding before a link is disconnected. */ diff --git a/include/revolution/BTE/stack/gap/gap_int.h b/include/revolution/BTE/stack/gap/gap_int.h index e962688..f49bae6 100644 --- a/include/revolution/BTE/stack/gap/gap_int.h +++ b/include/revolution/BTE/stack/gap/gap_int.h @@ -1,17 +1,157 @@ -#ifndef GAP_INT_H -#define GAP_INT_H +#ifndef BTE_GAP_INT_H +#define BTE_GAP_INT_H +/* Original source: + * bluedroid + * stack/gap/gap_int.h + * + * NOTE: This file only appears in bluedroid since commit ead3cde. + */ + +/****************************************************************************** + * + * Copyright (C) 2009-2013 Broadcom Corporation + * + * 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. + * + ******************************************************************************/ + +/* Includes changes by muff1n1634 and for this repository (KoopTheKoopa) */ + +#include "bt_target.h" +#include "bt_types.h" +#include "data_types.h" + +#include "btm_api.h" +#include "btm_int.h" #include "gap_api.h" #include "gki.h" +#include "l2c_api.h" + +#define GAP_MAX_BLOCKS 2 + +#define GAP_MIN_INQUIRY_LENGTH BTM_MIN_INQUIRY_LENGTH +#define GAP_MAX_INQUIRY_LENGTH BTM_MAX_INQUIRY_LENGTH + +#define GAP_PER_INQ_MIN_MIN_PERIOD BTM_PER_INQ_MIN_MIN_PERIOD +#define GAP_PER_INQ_MAX_MIN_PERIOD BTM_PER_INQ_MAX_MIN_PERIOD + +#define GAP_PER_INQ_MIN_MAX_PERIOD BTM_PER_INQ_MIN_MAX_PERIOD +#define GAP_PER_INQ_MAX_MAX_PERIOD BTM_PER_INQ_MAX_MAX_PERIOD #ifdef __cplusplus -extern "C" { + extern "C" { #endif -void gap_proc_btu_event(BT_HDR *p_msg); +typedef UINT8 tGAP_CCB_STATE; +enum +{ + GAP_CCB_STATE_IDLE = 0, + GAP_CCB_STATE_LISTENING = 1, + GAP_CCB_STATE_CONN_SETUP = 2, + GAP_CCB_STATE_CFG_SETUP = 3, + GAP_CCB_STATE_CONNECTED = 4, // was 5 +}; + +typedef UINT8 tGAP_CCB_FLAGS; +enum +{ + GAP_CCB_FLAGS_THEIR_CFG_DONE = 1 << 1, + GAP_CCB_FLAGS_OUR_CFG_DONE = 1 << 2, +}; + +typedef struct +{ + void *p_data; // 0x00 + tGAP_CALLBACK *gap_cback; // 0x04 + tGAP_CALLBACK *gap_inq_rslt_cback; // 0x08 + UINT16 event; // 0x0c + UINT8 index; // 0x0e + BOOLEAN in_use; // 0x0f +} tGAP_INFO; // size 0x10 + +typedef struct +{ + tGAP_CALLBACK *p_cback; // 0x00 + tBTM_INQ_INFO *p_cur_inq; // 0x04 + tGAP_FINDADDR_RESULTS results; // 0x08 + BOOLEAN in_use; // 0x52 + /* 1 byte padding */ +} tGAP_FINDADDR_CB; // size 0x54 + +typedef struct +{ + tGAP_CCB_STATE con_state; // 0x00 + tGAP_CCB_FLAGS con_flags; // 0x01 + UINT8 security_flags; // 0x02 + /* 1 byte padding */ + UINT16 gap_handle; // 0x04 + UINT16 connection_id; // 0x06 + BOOLEAN rem_addr_specified; // 0x08 + BD_ADDR rem_dev_address; // 0x09 + /* 1 byte padding */ + UINT16 psm; // 0x10 + UINT16 rem_mtu_size; // 0x12 + BUFFER_Q rx_queue; // 0x14 + tGAP_CONN_CALLBACK *p_callback; // 0x20 + tL2CAP_CFG_INFO cfg; // 0x24 +} tGAP_CCB; // size 0x60 + +typedef struct +{ + tL2CAP_APPL_INFO reg_info; // 0x000 + tGAP_CCB ccb_pool[GAP_MAX_CONNECTIONS]; // 0x028 +} tGAP_CONN; // size 0x328 + +typedef struct +{ + tGAP_INFO blk[GAP_MAX_BLOCKS]; // 0x000 + tBTM_CMPL_CB *btm_cback[GAP_MAX_BLOCKS]; // 0x020 + UINT8 trace_level; // 0x028 + /* 3 bytes padding */ + tGAP_FINDADDR_CB findaddr_cb; // 0x02c + tBTM_INQ_INFO *cur_inqptr; // 0x080 + tGAP_CONN conn; // 0x084 +} tGAP_CB; // size 0x3ac + +extern tGAP_CB gap_cb; + +/* 2006 trace helper: GAP_TRACE(LEVEL, fmt, ...) -> GAP_TRACE_LEVELn(fmt, ...) */ +#define GAP_TRACE_CAT(a, b) GAP_TRACE_CAT_(a, b) +#define GAP_TRACE_CAT_(a, b) a##b +#define GAP_TRACE_NARG(...) GAP_TRACE_NARG_(__VA_ARGS__, 6, 5, 4, 3, 2, 1, 0) +#define GAP_TRACE_NARG_(_1, _2, _3, _4, _5, _6, N, ...) N +#define GAP_TRACE_DEC_1 0 +#define GAP_TRACE_DEC_2 1 +#define GAP_TRACE_DEC_3 2 +#define GAP_TRACE_DEC_4 3 +#define GAP_TRACE_DEC_5 4 +#define GAP_TRACE_DEC_6 5 +#define GAP_TRACE(type_, ...) \ + GAP_TRACE_CAT(GAP_TRACE_CAT(GAP_TRACE_, type_), \ + GAP_TRACE_CAT(GAP_TRACE_DEC_, GAP_TRACE_NARG(__VA_ARGS__)))(__VA_ARGS__) + +UINT16 gap_convert_btm_status(tBTM_STATUS btm_status); +void gap_btm_cback0(void *p1); +void gap_btm_cback1(void *p1); +void gap_conn_init(void); +tGAP_INFO *gap_allocate_cb(void); +void gap_inq_results_cb(tBTM_INQ_RESULTS *p_results); +UINT16 gap_find_local_addr_by_name(tBTM_BD_NAME const devname, BD_ADDR bd_addr); +void gap_find_addr_inq_cb(tBTM_INQUIRY_CMPL *p); #ifdef __cplusplus -} + } #endif -#endif /* GAP_INT_H */ +#endif // BTE_GAP_INT_H diff --git a/include/revolution/BTE/stack/hid/hid_conn.h b/include/revolution/BTE/stack/hid/hid_conn.h index 79bb496..9b7dae1 100644 --- a/include/revolution/BTE/stack/hid/hid_conn.h +++ b/include/revolution/BTE/stack/hid/hid_conn.h @@ -1,3 +1,8 @@ +/* Original source: + * bluedroid + * stack/hid/hid_conn.h + */ + /****************************************************************************** * * Copyright (C) 2002-2012 Broadcom Corporation @@ -16,54 +21,81 @@ * ******************************************************************************/ +/* Includes changes by muff1n1634 and for this repository (KoopTheKoopa) */ + /****************************************************************************** * - * This file contains HID connection internal definitions + * This file contains HID connection internal definitions. * ******************************************************************************/ -#ifndef HID_CONN_H -#define HID_CONN_H +#ifndef BTE_HID_CONN_H +#define BTE_HID_CONN_H + +#include "data_types.h" + +#include "gki.h" + +#ifdef __cplusplus + extern "C" { +#endif + +typedef UINT8 tHID_CONN_STATE; +enum +{ + HID_CONN_STATE_UNUSED, + HID_CONN_STATE_CONNECTING_CTRL, + HID_CONN_STATE_CONNECTING_INTR, + HID_CONN_STATE_CONFIG, + HID_CONN_STATE_CONNECTED, + HID_CONN_STATE_DISCONNECTING, + HID_CONN_STATE_SECURITY, +}; + +typedef UINT8 tHID_CONN_FLAGS; +enum +{ + HID_CONN_FLAGS_IS_ORIG = 1 << 0, + + HID_CONN_FLAGS_THEIR_CTRL_CFG_DONE = 1 << 1, + HID_CONN_FLAGS_OUR_CTRL_CFG_DONE = 1 << 2, + HID_CONN_FLAGS_THEIR_INTR_CFG_DONE = 1 << 3, + HID_CONN_FLAGS_OUR_INTR_CFG_DONE = 1 << 4, + + HID_CONN_FLAGS_ALL_CONFIGURED = HID_CONN_FLAGS_THEIR_CTRL_CFG_DONE + | HID_CONN_FLAGS_OUR_CTRL_CFG_DONE + | HID_CONN_FLAGS_THEIR_INTR_CFG_DONE + | HID_CONN_FLAGS_OUR_INTR_CFG_DONE, + + HID_CONN_FLAGS_CONGESTED = 1 << 5, + HID_CONN_FLAGS_INACTIVE = 1 << 6, +}; + +enum +{ + HID_SEC_CHN = 1, + HID_NOSEC_CHN = 2, + +#define HID_SEC_CHN (HID_SEC_CHN + 0) +#define HID_NOSEC_CHN (HID_NOSEC_CHN + 0) +}; -/* Define the HID Connection Block -*/ typedef struct hid_conn { -#define HID_CONN_STATE_UNUSED (0) -#define HID_CONN_STATE_CONNECTING_CTRL (1) -#define HID_CONN_STATE_CONNECTING_INTR (2) -#define HID_CONN_STATE_CONFIG (3) -#define HID_CONN_STATE_CONNECTED (4) -#define HID_CONN_STATE_DISCONNECTING (5) -#define HID_CONN_STATE_SECURITY (6) - - UINT8 conn_state; - -#define HID_CONN_FLAGS_IS_ORIG (0x01) -#define HID_CONN_FLAGS_HIS_CTRL_CFG_DONE (0x02) -#define HID_CONN_FLAGS_MY_CTRL_CFG_DONE (0x04) -#define HID_CONN_FLAGS_HIS_INTR_CFG_DONE (0x08) -#define HID_CONN_FLAGS_MY_INTR_CFG_DONE (0x10) -#define HID_CONN_FLAGS_ALL_CONFIGURED (0x1E) /* All the config done */ -#define HID_CONN_FLAGS_CONGESTED (0x20) -#define HID_CONN_FLAGS_INACTIVE (0x40) - - UINT8 conn_flags; - - UINT8 ctrl_id; - UINT16 ctrl_cid; - UINT16 intr_cid; - UINT16 rem_mtu_size; - UINT16 disc_reason; /* Reason for disconnecting (for HID_HDEV_EVT_CLOSE) */ - TIMER_LIST_ENT timer_entry; - -} tHID_CONN; - -#define HID_SEC_CHN 1 -#define HID_NOSEC_CHN 2 - -#define HIDD_SEC_CHN 3 -#define HIDD_NOSEC_CHN 4 + tHID_CONN_STATE conn_state; // 0x00 + UINT8 conn_flags; // 0x01 + UINT8 ctrl_id; // 0x02 + /* 1 byte padding */ + UINT16 ctrl_cid; // 0x04 + UINT16 intr_cid; // 0x06 + UINT16 rem_mtu_size; // 0x08 + UINT16 disc_reason; // 0x0a + TIMER_LIST_ENT timer_entry; // 0x0c +} tHID_CONN; // size 0x24 +#ifdef __cplusplus + } #endif + +#endif // BTE_HID_CONN_H diff --git a/include/revolution/BTE/stack/hid/hidd_int.h b/include/revolution/BTE/stack/hid/hidd_int.h index ce9a691..76b5428 100644 --- a/include/revolution/BTE/stack/hid/hidd_int.h +++ b/include/revolution/BTE/stack/hid/hidd_int.h @@ -1,7 +1,117 @@ -#ifndef HIDD_INT_H -#define HIDD_INT_H +/****************************************************************************** + * + * Copyright (C) 2002-2012 Broadcom Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +/****************************************************************************** + * + * This file contains HID device internal definitions. + * + ******************************************************************************/ + +#ifndef BTE_HID_DEVICE_INT_H +#define BTE_HID_DEVICE_INT_H + + +#include "bt_types.h" +#include "data_types.h" -#include "hidd_api.h" #include "gki.h" +#include "hiddefs.h" +#include "hidd_api.h" +#include "hid_conn.h" +#include "l2c_api.h" + +#ifdef __cplusplus + extern "C" { +#endif + +typedef tHID_STATUS tHID_DEV_PROC_EVT(UINT8 event, void *p_data); + +typedef struct hid_control_block +{ + BD_ADDR host_addr; // 0x000 + BOOLEAN host_known; // 0x006 + UINT8 virtual_cable; // 0x007 + UINT8 dev_state; // 0x008 + UINT8 conn_tries; // 0x009 + UINT8 sec_mask; // 0x00a + UINT16 get_rep_buf_sz; // 0x00c + tHID_CONN conn; // 0x010 + TIMER_LIST_ENT idle_tle; // 0x034 + tHID_DEV_PWR_MD pm_params[3]; // 0x04c + tHID_DEV_CURR_PM_SETTING curr_pm; // 0x06a + BOOLEAN pm_ctrl_busy; // 0x06e + UINT8 conn_substate; // 0x06f + tHID_DEV_PWR_MD final_pm; // 0x070 + BOOLEAN use_qos_flg; // 0x07a + BOOLEAN unplug_on; // 0x07b + tQOS_INFO qos_info; // 0x07c + tHID_DEV_REG_INFO_CBACK *callback; // 0x0c4 + tL2CAP_CFG_INFO l2cap_ctrl_cfg; // 0x0c8 + tL2CAP_CFG_INFO l2cap_int_cfg; // 0x104 + BOOLEAN reg_flag; // 0x140 + UINT8 trace_level; // 0x141 +} tHID_DEV_CTB; // size 0x144 + +extern tHID_DEV_CTB hd_cb; +extern tHID_DEV_PROC_EVT * const hidd_sm_proc_evt[]; + +tHID_STATUS hidd_conn_reg(void); +void hidd_conn_dereg(void); +void hidd_conn_disconnect(void); +tHID_STATUS hidd_conn_initiate(void); +void hidd_sec_check_complete_term(BD_ADDR bd_addr, void *p_ref_data, UINT8 res); +void hidd_sec_check_complete_orig(BD_ADDR bd_addr, void *p_ref_data, UINT8 res); +void hidd_l2c_connected(tHID_CONN *p_hcon); +tHID_STATUS hidd_conn_snd_data(tSND_DATA_PARAMS *p_data); + +tHID_STATUS hidd_mgmt_process_evt(UINT8 event, void *p_data); +void hidd_proc_repage_timeout(void); +void hidd_mgmt_conn_closed(UINT16 reason); + +UINT8 hidd_pm_set_power_mode(tHID_DEV_PWR_MD *p_req_mode); +UINT8 hidd_pm_stop(void); +void hidd_pm_init(void); +UINT8 hidd_pm_start(void); +UINT8 hidd_pm_suspend_evt(void); + +// --- + +void hidd_pm_proc_mode_change(UINT8 hci_status, UINT8 mode, UINT16 interval); + + +#ifdef __cplusplus + } +#endif + + +/* 2006 trace helper: HIDD_TRACE(LEVEL, fmt, ...) -> HIDD_TRACE_LEVELn(fmt, ...) */ +#define HIDD_TRACE_CAT(a, b) HIDD_TRACE_CAT_(a, b) +#define HIDD_TRACE_CAT_(a, b) a##b +#define HIDD_TRACE_NARG(...) HIDD_TRACE_NARG_(__VA_ARGS__, 6, 5, 4, 3, 2, 1, 0) +#define HIDD_TRACE_NARG_(_1, _2, _3, _4, _5, _6, N, ...) N +#define HIDD_TRACE_DEC_1 0 +#define HIDD_TRACE_DEC_2 1 +#define HIDD_TRACE_DEC_3 2 +#define HIDD_TRACE_DEC_4 3 +#define HIDD_TRACE_DEC_5 4 +#define HIDD_TRACE_DEC_6 5 +#define HIDD_TRACE(type_, ...) \ + HIDD_TRACE_CAT(HIDD_TRACE_CAT(HIDD_TRACE_, type_), \ + HIDD_TRACE_CAT(HIDD_TRACE_DEC_, HIDD_TRACE_NARG(__VA_ARGS__)))(__VA_ARGS__) -#endif /* HIDD_INT_H */ +#endif // BTE_HID_DEVICE_INT_H diff --git a/include/revolution/BTE/stack/hid/hidh_int.h b/include/revolution/BTE/stack/hid/hidh_int.h index ad07412..8a896e8 100644 --- a/include/revolution/BTE/stack/hid/hidh_int.h +++ b/include/revolution/BTE/stack/hid/hidh_int.h @@ -90,5 +90,21 @@ HID_API extern tHID_HOST_CTB *hidh_cb_ptr; } #endif + +/* 2006 trace helper: HIDH_TRACE(LEVEL, fmt, ...) -> HIDH_TRACE_LEVELn(fmt, ...) */ +#define HIDH_TRACE_CAT(a, b) HIDH_TRACE_CAT_(a, b) +#define HIDH_TRACE_CAT_(a, b) a##b +#define HIDH_TRACE_NARG(...) HIDH_TRACE_NARG_(__VA_ARGS__, 6, 5, 4, 3, 2, 1, 0) +#define HIDH_TRACE_NARG_(_1, _2, _3, _4, _5, _6, N, ...) N +#define HIDH_TRACE_DEC_1 0 +#define HIDH_TRACE_DEC_2 1 +#define HIDH_TRACE_DEC_3 2 +#define HIDH_TRACE_DEC_4 3 +#define HIDH_TRACE_DEC_5 4 +#define HIDH_TRACE_DEC_6 5 +#define HIDH_TRACE(type_, ...) \ + HIDH_TRACE_CAT(HIDH_TRACE_CAT(HIDH_TRACE_, type_), \ + HIDH_TRACE_CAT(HIDH_TRACE_DEC_, HIDH_TRACE_NARG(__VA_ARGS__)))(__VA_ARGS__) + #endif diff --git a/include/revolution/BTE/stack/include/hcidefs.h b/include/revolution/BTE/stack/include/hcidefs.h index 570b0ca..91978b3 100644 --- a/include/revolution/BTE/stack/include/hcidefs.h +++ b/include/revolution/BTE/stack/include/hcidefs.h @@ -40,6 +40,7 @@ #define HCI_GRP_TESTING_CMDS (0x06 << 10) /* 0x1800 */ #define HCI_GRP_VENDOR_SPECIFIC (0x3F << 10) /* 0xFC00 */ +#define HCI_GROUP_VENDOR_SPECIFIC HCI_GRP_VENDOR_SPECIFIC /* Group occupies high 6 bits of the HCI command rest is opcode itself */ #define HCI_OGF(p) (UINT8)((0xFC00 & (p)) >> 10) diff --git a/include/revolution/BTE/stack/include/hcimsgs.h b/include/revolution/BTE/stack/include/hcimsgs.h index 3d3f63e..83f2bab 100644 --- a/include/revolution/BTE/stack/include/hcimsgs.h +++ b/include/revolution/BTE/stack/include/hcimsgs.h @@ -154,7 +154,7 @@ HCI_API extern BOOLEAN btsnd_hcic_create_conn_cancel(BD_ADDR dest); /* Accept Connection Request */ #ifdef REVOLUTION -HCI_API extern BOOLEAN btsnd_hcic_accept_conn (BT_HDR *p, BD_ADDR bd_addr, UINT8 role); +HCI_API extern void btsnd_hcic_accept_conn (void *buffer, BD_ADDR bd_addr, UINT8 role); #else HCI_API extern BOOLEAN btsnd_hcic_accept_conn (BD_ADDR bd_addr, UINT8 role); #endif @@ -167,7 +167,7 @@ HCI_API extern BOOLEAN btsnd_hcic_accept_conn (BD_ADDR bd_addr, UINT8 role); /* Reject Connection Request */ #ifdef REVOLUTION -HCI_API extern BOOLEAN btsnd_hcic_reject_conn (BT_HDR *p, BD_ADDR bd_addr, UINT8 reason); +HCI_API extern void btsnd_hcic_reject_conn (void *buffer, BD_ADDR bd_addr, UINT8 reason); #else HCI_API extern BOOLEAN btsnd_hcic_reject_conn (BD_ADDR bd_addr, UINT8 reason); #endif @@ -314,12 +314,12 @@ HCI_API extern BOOLEAN btsnd_hcic_setup_esco_conn (UINT16 handle, #ifdef REVOLUTION -HCI_API extern BOOLEAN btsnd_hcic_accept_esco_conn (BT_HDR *p, BD_ADDR bd_addr, - UINT32 tx_bw, UINT32 rx_bw, - UINT16 max_latency, - UINT16 content_fmt, - UINT8 retrans_effort, - UINT16 packet_types); +HCI_API extern void btsnd_hcic_accept_esco_conn (void *buffer, BD_ADDR bd_addr, + UINT32 tx_bw, UINT32 rx_bw, + UINT16 max_latency, + UINT16 content_fmt, + UINT8 retrans_effort, + UINT16 packet_types); #else HCI_API extern BOOLEAN btsnd_hcic_accept_esco_conn (BD_ADDR bd_addr, UINT32 tx_bw, UINT32 rx_bw, @@ -340,9 +340,9 @@ HCI_API extern BOOLEAN btsnd_hcic_accept_esco_conn (BD_ADDR bd_addr, #ifdef REVOLUTION -HCI_API extern BOOLEAN btsnd_hcic_reject_esco_conn (BT_HDR *p, BD_ADDR bd_addr, UINT8 reason); +HCI_API extern void btsnd_hcic_reject_esco_conn (void *buffer, BD_ADDR bd_addr, UINT8 reason); #else -HCI_API extern BOOLEAN btsnd_hcic_reject_esco_conn (BD_ADDR bd_addr, UINT8 reason); +HCI_API extern void btsnd_hcic_reject_esco_conn (BD_ADDR bd_addr, UINT8 reason); #endif #define HCIC_PARAM_SIZE_REJECT_ESCO 7 @@ -351,7 +351,7 @@ HCI_API extern BOOLEAN btsnd_hcic_reject_esco_conn (BD_ADDR bd_addr, UINT8 reaso /* Hold Mode */ #ifdef REVOLUTION -HCI_API extern BOOLEAN btsnd_hcic_hold_mode(BT_HDR *p, UINT16 handle, UINT16 max_hold_period, +HCI_API extern BOOLEAN btsnd_hcic_hold_mode(void *buffer, UINT16 handle, UINT16 max_hold_period, UINT16 min_hold_period); #else HCI_API extern BOOLEAN btsnd_hcic_hold_mode(UINT16 handle, UINT16 max_hold_period, @@ -367,7 +367,7 @@ HCI_API extern BOOLEAN btsnd_hcic_hold_mode(UINT16 handle, UINT16 max_hold_perio /* Sniff Mode */ #ifdef REVOLUTION -HCI_API extern BOOLEAN btsnd_hcic_sniff_mode(BT_HDR *p, UINT16 handle, +HCI_API extern BOOLEAN btsnd_hcic_sniff_mode(void *buffer, UINT16 handle, UINT16 max_sniff_period, UINT16 min_sniff_period, UINT16 sniff_attempt, @@ -391,14 +391,14 @@ HCI_API extern BOOLEAN btsnd_hcic_sniff_mode(UINT16 handle, /* Sniff Mode */ #ifdef REVOLUTION -HCI_API extern BOOLEAN btsnd_hcic_exit_sniff_mode(BT_HDR *p, UINT16 handle); +HCI_API extern BOOLEAN btsnd_hcic_exit_sniff_mode(void *buffer, UINT16 handle); #else HCI_API extern BOOLEAN btsnd_hcic_exit_sniff_mode(UINT16 handle); /* Exit Sniff Mode */ #endif /* Park Mode */ #ifdef REVOLUTION -HCI_API extern BOOLEAN btsnd_hcic_park_mode (BT_HDR *p, UINT16 handle, +HCI_API extern BOOLEAN btsnd_hcic_park_mode (void *buffer, UINT16 handle, UINT16 beacon_max_interval, UINT16 beacon_min_interval); #else @@ -415,7 +415,7 @@ HCI_API extern BOOLEAN btsnd_hcic_park_mode (UINT16 handle, /* Park Mode */ #ifdef REVOLUTION -HCI_API extern BOOLEAN btsnd_hcic_exit_park_mode(BT_HDR *p, UINT16 handle); +HCI_API extern BOOLEAN btsnd_hcic_exit_park_mode(void *buffer, UINT16 handle); #else HCI_API extern BOOLEAN btsnd_hcic_exit_park_mode(UINT16 handle); /* Exit Park Mode */ #endif @@ -685,12 +685,12 @@ HCI_API extern BOOLEAN btsnd_hcic_reset(UINT8 local_controller_id); #define MAX_FILT_COND (sizeof (BD_ADDR) + 1) #ifdef REVOLUTION -HCI_API extern BOOLEAN btsnd_hcic_set_event_filter(BT_HDR *p, UINT8 filt_type, +HCI_API extern void btsnd_hcic_set_event_filter(void *buffer, UINT8 filt_type, UINT8 filt_cond_type, UINT8 *filt_cond, UINT8 filt_cond_len); #else -HCI_API extern BOOLEAN btsnd_hcic_set_event_filter(UINT8 filt_type, +HCI_API extern void btsnd_hcic_set_event_filter(UINT8 filt_type, UINT8 filt_cond_type, UINT8 *filt_cond, UINT8 filt_cond_len); @@ -713,10 +713,10 @@ HCI_API extern BOOLEAN btsnd_hcic_new_unit_key(void); /* Read Stored Key */ #ifdef REVOLUTION -HCI_API extern BOOLEAN btsnd_hcic_read_stored_key (BT_HDR *p, BD_ADDR bd_addr, +HCI_API extern void btsnd_hcic_read_stored_key (void *buffer, BD_ADDR bd_addr, BOOLEAN read_all_flag); #else -HCI_API extern BOOLEAN btsnd_hcic_read_stored_key (BD_ADDR bd_addr, +HCI_API extern void btsnd_hcic_read_stored_key (BD_ADDR bd_addr, BOOLEAN read_all_flag); #endif @@ -729,11 +729,11 @@ HCI_API extern BOOLEAN btsnd_hcic_read_stored_key (BD_ADDR bd_addr, #define MAX_WRITE_KEYS 10 /* Write Stored Key */ #ifdef REVOLUTION -HCI_API extern BOOLEAN btsnd_hcic_write_stored_key (BT_HDR *p, UINT8 num_keys, +HCI_API extern void btsnd_hcic_write_stored_key (void *buffer, UINT8 num_keys, BD_ADDR *bd_addr, LINK_KEY *link_key); #else -HCI_API extern BOOLEAN btsnd_hcic_write_stored_key (UINT8 num_keys, BD_ADDR *bd_addr, +HCI_API extern void btsnd_hcic_write_stored_key (UINT8 num_keys, BD_ADDR *bd_addr, LINK_KEY *link_key); #endif @@ -744,6 +744,7 @@ HCI_API extern BOOLEAN btsnd_hcic_write_stored_key (UINT8 num_keys, BD_ADDR *bd_ #define HCI_WRITE_KEY_KEY_OFF 7 /* only 0x0b keys cab be sent in one HCI command */ #define HCI_MAX_NUM_OF_LINK_KEYS_PER_CMMD 0x0b +#define HCI_MAX_NUM_OF_LINK_KEYS_PER_CMD 0x0b /* Write Stored Key */ /* Delete Stored Key */ @@ -757,9 +758,9 @@ HCI_API extern BOOLEAN btsnd_hcic_delete_stored_key (BD_ADDR bd_addr, BOOLEAN de /* Change Local Name */ #ifdef REVOLUTION -HCI_API extern BOOLEAN btsnd_hcic_change_name(void *buffer, BD_NAME name); +HCI_API extern void btsnd_hcic_change_name(void *buffer, BD_NAME name); #else -HCI_API extern BOOLEAN btsnd_hcic_change_name(BD_NAME name); +HCI_API extern void btsnd_hcic_change_name(BD_NAME name); #endif #define HCIC_PARAM_SIZE_CHANGE_NAME BD_NAME_LEN @@ -793,23 +794,23 @@ HCI_API extern BOOLEAN btsnd_hcic_read_conn_acc_tout(UINT8 local_controller_id); HCI_API extern BOOLEAN btsnd_hcic_write_conn_acc_tout(UINT8 local_controller_id, UINT16 tout); /* Write Connection Accept Timout */ HCI_API extern BOOLEAN btsnd_hcic_read_page_tout(void); /* Read Page Timout */ #ifdef REVOLUTION -HCI_API extern BOOLEAN btsnd_hcic_write_page_tout(BT_HDR *p, UINT16 timeout); +HCI_API extern void btsnd_hcic_write_page_tout(void *buffer, UINT16 timeout); #else -HCI_API extern BOOLEAN btsnd_hcic_write_page_tout(UINT16 timeout); /* Write Page Timout */ +HCI_API extern void btsnd_hcic_write_page_tout(UINT16 timeout); /* Write Page Timout */ #endif HCI_API extern BOOLEAN btsnd_hcic_read_scan_enable(void); /* Read Scan Enable */ #ifdef REVOLUTION -HCI_API extern BOOLEAN btsnd_hcic_write_scan_enable(BT_HDR *p, UINT8 flag); +HCI_API extern void btsnd_hcic_write_scan_enable(void *buffer, UINT8 flag); #else -HCI_API extern BOOLEAN btsnd_hcic_write_scan_enable(UINT8 flag); /* Write Scan Enable */ +HCI_API extern void btsnd_hcic_write_scan_enable(UINT8 flag); /* Write Scan Enable */ #endif HCI_API extern BOOLEAN btsnd_hcic_read_pagescan_cfg(void); /* Read Page Scan Activity */ #ifdef REVOLUTION -HCI_API extern BOOLEAN btsnd_hcic_write_pagescan_cfg(BT_HDR *p, UINT16 interval, +HCI_API extern void btsnd_hcic_write_pagescan_cfg(void *buffer, UINT16 interval, UINT16 window); #else -HCI_API extern BOOLEAN btsnd_hcic_write_pagescan_cfg(UINT16 interval, +HCI_API extern void btsnd_hcic_write_pagescan_cfg(UINT16 interval, UINT16 window); /* Write Page Scan Activity */ #endif @@ -823,9 +824,9 @@ HCI_API extern BOOLEAN btsnd_hcic_read_inqscan_cfg(void); /* Read Inquiry /* Write Inquiry Scan Activity */ #ifdef REVOLUTION -HCI_API extern BOOLEAN btsnd_hcic_write_inqscan_cfg(BT_HDR *p, UINT16 interval, UINT16 window); +HCI_API extern void btsnd_hcic_write_inqscan_cfg(void *buffer, UINT16 interval, UINT16 window); #else -HCI_API extern BOOLEAN btsnd_hcic_write_inqscan_cfg(UINT16 interval, UINT16 window); +HCI_API extern void btsnd_hcic_write_inqscan_cfg(UINT16 interval, UINT16 window); #endif #define HCIC_PARAM_SIZE_WRITE_INQSCAN_CFG 4 @@ -840,9 +841,9 @@ HCI_API extern BOOLEAN btsnd_hcic_read_encr_mode (void); HCI_API extern BOOLEAN btsnd_hcic_write_encr_mode (UINT8 mode); /* Write encryption mode */ HCI_API extern BOOLEAN btsnd_hcic_read_dev_class(void); /* Read Class of Device */ #ifdef REVOLUTION -HCI_API extern BOOLEAN btsnd_hcic_write_dev_class(BT_HDR *p, DEV_CLASS dev); +HCI_API extern void btsnd_hcic_write_dev_class(void *buffer, DEV_CLASS dev); #else -HCI_API extern BOOLEAN btsnd_hcic_write_dev_class(DEV_CLASS dev); /* Write Class of Device */ +HCI_API extern void btsnd_hcic_write_dev_class(DEV_CLASS dev); /* Write Class of Device */ #endif HCI_API extern BOOLEAN btsnd_hcic_read_voice_settings(void); /* Read Voice Settings */ HCI_API extern BOOLEAN btsnd_hcic_write_voice_settings(UINT16 flags); /* Write Voice Settings */ @@ -859,10 +860,10 @@ HCI_API extern BOOLEAN btsnd_hcic_set_host_flow_ctrl (UINT8 value); /* E HCI_API extern BOOLEAN btsnd_hcic_read_auto_flush_tout(UINT16 handle); /* Read Retransmit Timout */ #ifdef REVOLUTION -HCI_API extern BOOLEAN btsnd_hcic_write_auto_flush_tout(BT_HDR *p, UINT16 handle, +HCI_API extern void btsnd_hcic_write_auto_flush_tout(void *buffer, UINT16 handle, UINT16 timeout); #else -HCI_API extern BOOLEAN btsnd_hcic_write_auto_flush_tout(UINT16 handle, +HCI_API extern void btsnd_hcic_write_auto_flush_tout(UINT16 handle, UINT16 timeout); /* Write Retransmit Timout */ #endif @@ -936,10 +937,10 @@ HCI_API extern BOOLEAN btsnd_hcic_read_max_iac (void); /* R HCI_API extern BOOLEAN btsnd_hcic_read_cur_iac_lap (void); /* Read Current IAC LAP */ #ifdef REVOLUTION -HCI_API extern BOOLEAN btsnd_hcic_write_cur_iac_lap (BT_HDR *p, UINT8 num_cur_iac, +HCI_API extern void btsnd_hcic_write_cur_iac_lap (void *buffer, UINT8 num_cur_iac, LAP * const iac_lap); #else -HCI_API extern BOOLEAN btsnd_hcic_write_cur_iac_lap (UINT8 num_cur_iac, +HCI_API extern void btsnd_hcic_write_cur_iac_lap (UINT8 num_cur_iac, LAP * const iac_lap); /* Write Current IAC LAP */ #endif @@ -989,9 +990,9 @@ HCI_API extern BOOLEAN btsnd_hcic_read_local_ver (UINT8 local_controller_id); HCI_API extern BOOLEAN btsnd_hcic_read_local_supported_cmds (UINT8 local_controller_id); /* Read Local Supported Commands */ HCI_API extern BOOLEAN btsnd_hcic_read_local_features (void); /* Read Local Supported Features */ #ifdef REVOLUTION -HCI_API extern BOOLEAN btsnd_hcic_read_buffer_size (BT_HDR *p); /* Read Local buffer sizes */ +HCI_API extern void btsnd_hcic_read_buffer_size (void *buffer); /* Read Local buffer sizes */ #else -HCI_API extern BOOLEAN btsnd_hcic_read_buffer_size (void); /* Read Local buffer sizes */ +HCI_API extern void btsnd_hcic_read_buffer_size (void); /* Read Local buffer sizes */ #endif HCI_API extern BOOLEAN btsnd_hcic_read_country_code (void); /* Read Country Code */ HCI_API extern BOOLEAN btsnd_hcic_read_bd_addr (void); /* Read Local BD_ADDR */ @@ -1003,21 +1004,21 @@ HCI_API extern BOOLEAN btsnd_hcic_read_loopback_mode (void); / HCI_API extern BOOLEAN btsnd_hcic_write_loopback_mode (UINT8 mode); /* Write Loopback Mode */ HCI_API extern BOOLEAN btsnd_hcic_enable_test_mode (void); /* Enable Device Under Test Mode */ #ifdef REVOLUTION -HCI_API extern BOOLEAN btsnd_hcic_write_pagescan_type(BT_HDR *p, UINT8 type); +HCI_API extern void btsnd_hcic_write_pagescan_type(void *buffer, UINT8 type); #else -HCI_API extern BOOLEAN btsnd_hcic_write_pagescan_type(UINT8 type); /* Write Page Scan Type */ +HCI_API extern void btsnd_hcic_write_pagescan_type(UINT8 type); /* Write Page Scan Type */ #endif HCI_API extern BOOLEAN btsnd_hcic_read_pagescan_type(void); /* Read Page Scan Type */ #ifdef REVOLUTION -HCI_API extern BOOLEAN btsnd_hcic_write_inqscan_type(BT_HDR *p, UINT8 type); +HCI_API extern void btsnd_hcic_write_inqscan_type(void *buffer, UINT8 type); #else -HCI_API extern BOOLEAN btsnd_hcic_write_inqscan_type(UINT8 type); /* Write Inquiry Scan Type */ +HCI_API extern void btsnd_hcic_write_inqscan_type(UINT8 type); /* Write Inquiry Scan Type */ #endif HCI_API extern BOOLEAN btsnd_hcic_read_inqscan_type(void); /* Read Inquiry Scan Type */ #ifdef REVOLUTION -HCI_API extern BOOLEAN btsnd_hcic_write_inquiry_mode(BT_HDR *p, UINT8 type); +HCI_API extern void btsnd_hcic_write_inquiry_mode(void *buffer, UINT8 type); #else -HCI_API extern BOOLEAN btsnd_hcic_write_inquiry_mode(UINT8 type); /* Write Inquiry Mode */ +HCI_API extern void btsnd_hcic_write_inquiry_mode(UINT8 type); /* Write Inquiry Mode */ #endif HCI_API extern BOOLEAN btsnd_hcic_read_inquiry_mode(void); /* Read Inquiry Mode */ HCI_API extern BOOLEAN btsnd_hcic_set_afh_channels (UINT8 first, UINT8 last); @@ -1054,7 +1055,7 @@ HCI_API extern void btsnd_hcic_data (BT_HDR *p_buf, UINT16 len, UINT16 handle, U #define HCID_GET_SCO_LEN(p) (*((UINT8 *)((p) + 1) + p->offset + 2)) #ifdef REVOLUTION -HCI_API extern BOOLEAN btsnd_hcic_vendor_spec_cmd (BT_HDR *p, UINT16 opcode, +HCI_API extern void btsnd_hcic_vendor_spec_cmd (void *buffer, UINT16 opcode, UINT8 len, UINT8 *p_data); #else HCI_API extern void btsnd_hcic_vendor_spec_cmd ( diff --git a/include/revolution/BTE/stack/include/hidd_api.h b/include/revolution/BTE/stack/include/hidd_api.h index e40ceaf..7175718 100644 --- a/include/revolution/BTE/stack/include/hidd_api.h +++ b/include/revolution/BTE/stack/include/hidd_api.h @@ -16,245 +16,103 @@ * limitations under the License. * ******************************************************************************/ -#ifndef HIDD_API_H -#define HIDD_API_H -#include "hiddefs.h" -#include "sdp_api.h" - -/***************************************************************************** - * Type Definitions - ****************************************************************************/ - -enum { HID_CHANNEL_INTR, HID_CHANNEL_CTRL }; - -/* - HID_DHOST_EVT_OPEN - connected to host device (CTRL and INTR), data = n/a - HID_DHOST_EVT_CLOSE - disconnected from host device, data=reason - HID_DHOST_EVT_GET_REPORT - got GET_REPORT from host - HID_DHOST_EVT_SET_REPORT - got SET_REPORT from host - HID_DHOST_EVT_SET_PROTOCOL - got SET_PROTOCOL from host -*/ - -enum { - HID_DHOST_EVT_OPEN, - HID_DHOST_EVT_CLOSE, - HID_DHOST_EVT_GET_REPORT, - HID_DHOST_EVT_SET_REPORT, - HID_DHOST_EVT_SET_PROTOCOL, - HID_DHOST_EVT_INTR_DATA, - HID_DHOST_EVT_VC_UNPLUG, - HID_DHOST_EVT_SUSPEND, - HID_DHOST_EVT_EXIT_SUSPEND, -}; -typedef void(tHID_DEV_HOST_CALLBACK)(BD_ADDR bd_addr, UINT8 event, - UINT32 data, BT_HDR* p_buf); - -/***************************************************************************** - * External Function Declarations - ****************************************************************************/ -#ifdef __cplusplus -extern "C" { -#endif - -/******************************************************************************* - * - * Function HID_DevInit - * - * Description Initializes control block - * - * Returns void - * - ******************************************************************************/ -extern void HID_DevInit(void); - -/******************************************************************************* - * - * Function HID_DevRegister - * - * Description Registers HID device with lower layers - * - * Returns tHID_STATUS - * - ******************************************************************************/ -extern tHID_STATUS HID_DevRegister(tHID_DEV_HOST_CALLBACK* host_cback); - -/******************************************************************************* - * - * Function HID_DevDeregister - * - * Description Deregisters HID device with lower layers - * - * Returns tHID_STATUS - * - ******************************************************************************/ -extern tHID_STATUS HID_DevDeregister(void); - -/******************************************************************************* - * - * Function HID_DevSetSecurityLevel - * - * Description Sets security level for HID device connections - * - * Returns tHID_STATUS - * - ******************************************************************************/ -extern tHID_STATUS HID_DevSetSecurityLevel(UINT8 sec_lvl); - -/******************************************************************************* - * - * Function HID_DevAddRecord - * - * Description Creates SDP record for HID device - * - * Returns tHID_STATUS - * - ******************************************************************************/ -extern tHID_STATUS HID_DevAddRecord(UINT32 handle, char* p_name, - char* p_description, char* p_provider, - UINT16 subclass, UINT16 desc_len, - UINT8* p_desc_data); - -/******************************************************************************* - * - * Function HID_DevSendReport - * - * Description Sends report - * - * Returns tHID_STATUS - * - ******************************************************************************/ -extern tHID_STATUS HID_DevSendReport(UINT8 channel, UINT8 type, UINT8 id, - UINT16 len, UINT8* p_data); - -/******************************************************************************* - * - * Function HID_DevVirtualCableUnplug - * - * Description Sends Virtual Cable Unplug - * - * Returns tHID_STATUS - * - ******************************************************************************/ -extern tHID_STATUS HID_DevVirtualCableUnplug(void); - -/******************************************************************************* - * - * Function HID_DevPlugDevice - * - * Description Establishes virtual cable to given host +/****************************************************************************** * - * Returns tHID_STATUS + * This file contains the HID device API definitions. * ******************************************************************************/ -extern tHID_STATUS HID_DevPlugDevice(BD_ADDR addr); -/******************************************************************************* - * - * Function HID_DevUnplugDevice - * - * Description Unplugs virtual cable from given host - * - * Returns tHID_STATUS - * - ******************************************************************************/ -extern tHID_STATUS HID_DevUnplugDevice(BD_ADDR addr); +#ifndef BTE_HID_DEVICE_API_H +#define BTE_HID_DEVICE_API_H -/******************************************************************************* - * - * Function HID_DevConnect - * - * Description Connects to device - * - * Returns tHID_STATUS - * - ******************************************************************************/ -extern tHID_STATUS HID_DevConnect(void); +#include "bt_types.h" +#include "data_types.h" -/******************************************************************************* - * - * Function HID_DevDisconnect - * - * Description Disconnects from device - * - * Returns tHID_STATUS - * - ******************************************************************************/ -extern tHID_STATUS HID_DevDisconnect(void); - -/******************************************************************************* - * - * Function HID_DevSetIncomingPolicy - * - * Description Sets policy for incoming connections (allowed/disallowed) - * - * Returns tHID_STATUS - * - ******************************************************************************/ -extern tHID_STATUS HID_DevSetIncomingPolicy(BOOLEAN allow); - -/******************************************************************************* - * - * Function HID_DevReportError - * - * Description Reports error for Set Report via HANDSHAKE - * - * Returns tHID_STATUS - * - ******************************************************************************/ -extern tHID_STATUS HID_DevReportError(UINT8 error); - -/******************************************************************************* - * - * Function HID_DevGetDevice - * - * Description Returns the BD Address of virtually cabled device - * - * Returns tHID_STATUS - * - ******************************************************************************/ -extern tHID_STATUS HID_DevGetDevice(BD_ADDR* addr); +#include "hiddefs.h" -/******************************************************************************* - * - * Function HID_DevSetIncomingQos - * - * Description Sets Incoming QoS values for Interrupt L2CAP Channel - * - * Returns tHID_STATUS - * - ******************************************************************************/ -extern tHID_STATUS HID_DevSetIncomingQos( - UINT8 service_type, UINT32 token_rate, UINT32 token_bucket_size, - UINT32 peak_bandwidth, UINT32 latency, UINT32 delay_variation); +#ifdef __cplusplus + extern "C" { +#endif -/******************************************************************************* - * - * Function HID_DevSetOutgoingQos - * - * Description Sets Outgoing QoS values for Interrupt L2CAP Channel - * - * Returns tHID_STATUS - * - ******************************************************************************/ -extern tHID_STATUS HID_DevSetOutgoingQos( - UINT8 service_type, UINT32 token_rate, UINT32 token_bucket_size, - UINT32 peak_bandwidth, UINT32 latency, UINT32 delay_variation); +typedef UINT8 tHID_CHANNEL; +enum +{ + HID_CHANNEL_INTR, + HID_CHANNEL_CTRL, +}; -/******************************************************************************* - * - * Function HID_DevSetTraceLevel - * - * Description This function sets the trace level for HID Dev. If called - * with a value of 0xFF, it simply reads the current trace level. - * - * Returns the new (current) trace level - * - ******************************************************************************/ -extern UINT8 HID_DevSetTraceLevel(UINT8 new_level); +typedef struct rep_data +{ + UINT8 rep_type; // 0x00 + UINT8 rep_id; // 0x01 +} tHID_DEV_REP_DATA; // size 0x02 + +typedef struct snd_data_params +{ + UINT8 ctrl_ch; // 0x00 + UINT8 trans_type; // 0x01 + UINT8 param; // 0x02 + BT_HDR *buf; // 0x04 +} tSND_DATA_PARAMS; // size 0x08 + +typedef struct pwr_md +{ + UINT16 max; // 0x00 + UINT16 min; // 0x02 + UINT16 attempt; // 0x04 + UINT16 timeout; // 0x06 + UINT8 mode; // 0x08 +} tHID_DEV_PWR_MD; // size 0x0a + +typedef struct curr_pm_setting +{ + UINT8 mode; // 0x00 + UINT16 interval; // 0x02 +} tHID_DEV_CURR_PM_SETTING; // size 0x04 + +typedef struct +{ + FLOW_SPEC ctrl_ch; // 0x00 + FLOW_SPEC int_ch; // 0x18 + FLOW_SPEC hci; // 0x30 +} tQOS_INFO; // size 0x048 + +typedef union +{ + BD_ADDR host_bdaddr; // 0x00 + BT_HDR *buffer; // 0x00 + tHID_DEV_REP_DATA get_rep; // 0x00 + UINT8 pm_err_code; // 0x00 + UINT16 pm_interval; // 0x00 +} tHID_DEV_REG_INFO_CBACK_DATA; + +typedef void tHID_DEV_REG_INFO_CBACK(UINT8 event, UINT32 data, + tHID_DEV_REG_INFO_CBACK_DATA *pdata); + +typedef struct +{ + BD_ADDR host_addr; // 0x00 + tQOS_INFO *qos_info; // 0x08 + tHID_DEV_REG_INFO_CBACK *app_cback; // 0x0C +} tHID_DEV_REG_INFO; // size 0x010 + +UINT32 HID_DevSetSDPRecord(tHID_DEV_SDP_INFO *p_sdp_info); +void HID_DevInit(void); +tHID_STATUS HID_DevRegister(tHID_DEV_REG_INFO *p_reg_info); +tHID_STATUS HID_DevDeregister(void); +tHID_STATUS HID_DevConnect(void); +tHID_STATUS HID_DevDisconnect(void); +tHID_STATUS HID_DevHandShake(UINT8 res_code); +tHID_STATUS HID_DevVirtualUnplug(void); +tHID_STATUS HID_DevSendData(tHID_CHANNEL control_ch, UINT8 rep_type, + BT_HDR *data_buf); +tHID_STATUS HID_DevSetSecurityLevel(char *serv_name, UINT8 sec_lvl); +tHID_STATUS HID_DevSetPowerMgmtParams(UINT8 conn_substate, + tHID_DEV_PWR_MD pm_params); #ifdef __cplusplus -} + } #endif -#endif /* HIDD_API_H */ +#endif // BTE_HID_DEVICE_API_H diff --git a/include/revolution/BTE/stack/include/l2c_api.h b/include/revolution/BTE/stack/include/l2c_api.h index 7a9f285..7d93d56 100644 --- a/include/revolution/BTE/stack/include/l2c_api.h +++ b/include/revolution/BTE/stack/include/l2c_api.h @@ -172,7 +172,9 @@ typedef struct #ifdef REVOLUTION /* RVL: sizeof is 0x3C (rfc_mx_fsm memsets 0x3C, hh_cb.sdp_busy follows at +0x3C). The members in 0x32..0x3C are not identified yet. */ - UINT8 reserved0[10]; + UINT8 reserved0[6]; + UINT16 flags; + UINT8 reserved1[2]; #else BOOLEAN ext_flow_spec_present; tHCI_EXT_FLOW_SPEC ext_flow_spec; diff --git a/include/revolution/BTE/stack/l2cap/l2c_int.h b/include/revolution/BTE/stack/l2cap/l2c_int.h index 562dadb..8a13e45 100644 --- a/include/revolution/BTE/stack/l2cap/l2c_int.h +++ b/include/revolution/BTE/stack/l2cap/l2c_int.h @@ -1,3 +1,8 @@ +/* Original source: + * bluedroid + * stack/l2cap/l2c_int.h + */ + /****************************************************************************** * * Copyright (C) 1999-2012 Broadcom Corporation @@ -16,67 +21,58 @@ * ******************************************************************************/ +/* Includes changes by muff1n1634 and for this repository (KoopTheKoopa) */ + /****************************************************************************** * - * This file contains L2CAP internal definitions + * This file contains L2CAP internal definitions. * ******************************************************************************/ -#ifndef L2C_INT_H -#define L2C_INT_H -#include "l2c_api.h" -#include "l2cdefs.h" +#ifndef BTE_L2CAP_INT_H +#define BTE_L2CAP_INT_H + +#include "bt_target.h" +#include "bt_types.h" +#include "data_types.h" + #include "gki.h" -#include "btm_api.h" +#include "l2c_api.h" -#define L2CAP_MIN_MTU 48 /* Minimum acceptable MTU is 48 bytes */ +#define L2CAP_MIN_MTU 48 /* Minimum acceptable MTU is 48 bytes */ -/* Timeouts. Since L2CAP works off a 1-second list, all are in seconds. -*/ -#define L2CAP_LINK_ROLE_SWITCH_TOUT 10 /* 10 seconds */ -#define L2CAP_LINK_CONNECT_TOUT 60 /* 30 seconds */ -#define L2CAP_LINK_CONNECT_TOUT_EXT 120 /* 120 seconds */ -#define L2CAP_ECHO_RSP_TOUT 30 /* 30 seconds */ -#define L2CAP_LINK_FLOW_CONTROL_TOUT 2 /* 2 seconds */ -#define L2CAP_LINK_DISCONNECT_TOUT 30 /* 30 seconds */ +/* Timeouts. Since L2CAP works off a 1-second list, all are in seconds. */ +#define L2CAP_ECHO_RSP_TOUT 30 /* 30 seconds */ +#define L2CAP_CHNL_CONNECT_TOUT 60 /* 60 seconds */ +#define L2CAP_CHNL_CFG_TOUT 30 /* 30 seconds */ +#define L2CAP_CHNL_CONNECT_TOUT_EXT 120 /* 120 seconds */ +#define L2CAP_CHNL_DISCONNECT_TOUT 30 /* 30 seconds */ +#define L2CAP_LINK_CONNECT_TOUT 60 /* 60 seconds */ +#define L2CAP_DELAY_CHECK_SM4 2 /* 2 seconds */ +#define L2CAP_LINK_DISCONNECT_TOUT 30 /* 30 seconds */ +#define L2CAP_LINK_FLOW_CONTROL_TOUT 2 /* 2 seconds */ +#define L2CAP_LINK_CONNECT_TOUT_EXT 120 /* 120 seconds */ +#define L2CAP_LINK_ROLE_SWITCH_TOUT 10 /* 10 seconds */ -#ifndef L2CAP_CHNL_CONNECT_TOUT /* BTIF needs to override for internal project needs */ -#define L2CAP_CHNL_CONNECT_TOUT 60 /* 60 seconds */ +#define L2CAP_SEND_CMD_OFFSET 0 + +#ifdef __cplusplus + extern "C" { #endif -#define L2CAP_CHNL_CONNECT_TOUT_EXT 120 /* 120 seconds */ -#define L2CAP_CHNL_CFG_TIMEOUT 30 /* 30 seconds */ -#define L2CAP_CHNL_DISCONNECT_TOUT 10 /* 10 seconds */ -#define L2CAP_DELAY_CHECK_SM4 2 /* 2 seconds */ -#define L2CAP_WAIT_INFO_RSP_TOUT 3 /* 3 seconds */ -#define L2CAP_WAIT_UNPARK_TOUT 2 /* 2 seconds */ -#define L2CAP_LINK_INFO_RESP_TOUT 2 /* 2 seconds */ -#define L2CAP_BLE_LINK_CONNECT_TOUT 30 /* 30 seconds */ - -/* quick timer uses millisecond unit */ -#define L2CAP_DEFAULT_RETRANS_TOUT 2000 /* 2000 milliseconds */ -#define L2CAP_DEFAULT_MONITOR_TOUT 12000 /* 12000 milliseconds */ -#define L2CAP_FCR_ACK_TOUT 200 /* 200 milliseconds */ - -/* Define the possible L2CAP channel states. The names of -** the states may seem a bit strange, but they are taken from -** the Bluetooth specification. -*/ typedef enum { - CST_CLOSED, /* Channel is in clodes state */ - CST_ORIG_W4_SEC_COMP, /* Originator waits security clearence */ - CST_TERM_W4_SEC_COMP, /* Acceptor waits security clearence */ - CST_W4_L2CAP_CONNECT_RSP, /* Waiting for peer conenct response */ - CST_W4_L2CA_CONNECT_RSP, /* Waiting for upper layer connect rsp */ - CST_CONFIG, /* Negotiating configuration */ - CST_OPEN, /* Data transfer state */ - CST_W4_L2CAP_DISCONNECT_RSP, /* Waiting for peer disconnect rsp */ - CST_W4_L2CA_DISCONNECT_RSP /* Waiting for upper layer disc rsp */ + CST_CLOSED, + CST_ORIG_W4_SEC_COMP, + CST_TERM_W4_SEC_COMP, + CST_W4_L2CAP_CONNECT_RSP, + CST_W4_L2CA_CONNECT_RSP, + CST_CONFIG, + CST_OPEN, + CST_W4_L2CAP_DISCONNECT_RSP, + CST_W4_L2CA_DISCONNECT_RSP, } tL2C_CHNL_STATE; -/* Define the possible L2CAP link states -*/ typedef enum { LST_DISCONNECTED, @@ -84,741 +80,266 @@ typedef enum LST_CONNECTING_WAIT_SWITCH, LST_CONNECTING, LST_CONNECTED, - LST_DISCONNECTING + LST_DISCONNECTING, } tL2C_LINK_STATE; - - -/* Define input events to the L2CAP link and channel state machines. The names -** of the events may seem a bit strange, but they are taken from -** the Bluetooth specification. -*/ -#define L2CEVT_LP_CONNECT_CFM 0 /* Lower layer connect confirm */ -#define L2CEVT_LP_CONNECT_CFM_NEG 1 /* Lower layer connect confirm (failed) */ -#define L2CEVT_LP_CONNECT_IND 2 /* Lower layer connect indication */ -#define L2CEVT_LP_DISCONNECT_IND 3 /* Lower layer disconnect indication */ -#define L2CEVT_LP_QOS_CFM 4 /* Lower layer QOS confirmation */ -#define L2CEVT_LP_QOS_CFM_NEG 5 /* Lower layer QOS confirmation (failed)*/ -#define L2CEVT_LP_QOS_VIOLATION_IND 6 /* Lower layer QOS violation indication */ - -#define L2CEVT_SEC_COMP 7 /* Security cleared successfully */ -#define L2CEVT_SEC_COMP_NEG 8 /* Security procedure failed */ - -#define L2CEVT_L2CAP_CONNECT_REQ 10 /* Peer connection request */ -#define L2CEVT_L2CAP_CONNECT_RSP 11 /* Peer connection response */ -#define L2CEVT_L2CAP_CONNECT_RSP_PND 12 /* Peer connection response pending */ -#define L2CEVT_L2CAP_CONNECT_RSP_NEG 13 /* Peer connection response (failed) */ -#define L2CEVT_L2CAP_CONFIG_REQ 14 /* Peer configuration request */ -#define L2CEVT_L2CAP_CONFIG_RSP 15 /* Peer configuration response */ -#define L2CEVT_L2CAP_CONFIG_RSP_NEG 16 /* Peer configuration response (failed) */ -#define L2CEVT_L2CAP_DISCONNECT_REQ 17 /* Peer disconnect request */ -#define L2CEVT_L2CAP_DISCONNECT_RSP 18 /* Peer disconnect response */ -#define L2CEVT_L2CAP_INFO_RSP 19 /* Peer information response */ -#define L2CEVT_L2CAP_DATA 20 /* Peer data */ - -#define L2CEVT_L2CA_CONNECT_REQ 21 /* Upper layer connect request */ -#define L2CEVT_L2CA_CONNECT_RSP 22 /* Upper layer connect response */ -#define L2CEVT_L2CA_CONNECT_RSP_NEG 23 /* Upper layer connect response (failed)*/ -#define L2CEVT_L2CA_CONFIG_REQ 24 /* Upper layer config request */ -#define L2CEVT_L2CA_CONFIG_RSP 25 /* Upper layer config response */ -#define L2CEVT_L2CA_CONFIG_RSP_NEG 26 /* Upper layer config response (failed) */ -#define L2CEVT_L2CA_DISCONNECT_REQ 27 /* Upper layer disconnect request */ -#define L2CEVT_L2CA_DISCONNECT_RSP 28 /* Upper layer disconnect response */ -#define L2CEVT_L2CA_DATA_READ 29 /* Upper layer data read */ -#define L2CEVT_L2CA_DATA_WRITE 30 /* Upper layer data write */ -#define L2CEVT_L2CA_FLUSH_REQ 31 /* Upper layer flush */ - -#define L2CEVT_TIMEOUT 32 /* Timeout */ -#define L2CEVT_SEC_RE_SEND_CMD 33 /* btm_sec has enough info to proceed */ - -#define L2CEVT_ACK_TIMEOUT 34 /* RR delay timeout */ - - -/* Bitmask to skip over Broadcom feature reserved (ID) to avoid sending two - successive ID values, '0' id only or both */ -#define L2CAP_ADJ_BRCM_ID 0x1 -#define L2CAP_ADJ_ZERO_ID 0x2 -#define L2CAP_ADJ_ID 0x3 - -/* Return values for l2cu_process_peer_cfg_req() */ -#define L2CAP_PEER_CFG_UNACCEPTABLE 0 -#define L2CAP_PEER_CFG_OK 1 -#define L2CAP_PEER_CFG_DISCONNECT 2 - -/* eL2CAP option constants */ -#define L2CAP_MIN_RETRANS_TOUT 2000 /* Min retransmission timeout if no flush timeout or PBF */ -#define L2CAP_MIN_MONITOR_TOUT 12000 /* Min monitor timeout if no flush timeout or PBF */ - -#define L2CAP_MAX_FCR_CFG_TRIES 2 /* Config attempts before disconnecting */ - -/* Only compiled in when in test mode. Production devices must not include -*/ -#if L2CAP_CORRUPT_ERTM_PKTS == TRUE - -/* These are used for conformance and corruption testing only */ -typedef struct +enum { - BOOLEAN in_use; /* TRUE if test in progress */ - UINT8 type; /* Type of test to run or turns off random test */ - UINT8 freq; /* One-shot or random */ - BOOLEAN is_rx; /* TRUE if incoming packets */ - UINT16 count; /* How many I-frames to drop in a row; used only with one-shot tests */ -} tL2C_FCR_TEST_CFG; - -typedef struct + L2CEVT_LP_CONNECT_CFM = 0, + L2CEVT_LP_CONNECT_CFM_NEG = 1, + L2CEVT_LP_DISCONNECT_IND = 3, + L2CEVT_LP_QOS_VIOLATION_IND = 6, + L2CEVT_SEC_COMP = 7, + L2CEVT_SEC_COMP_NEG = 8, + L2CEVT_L2CAP_CONNECT_REQ = 10, + L2CEVT_L2CAP_CONNECT_RSP = 11, + L2CEVT_L2CAP_CONNECT_RSP_PND = 12, + L2CEVT_L2CAP_CONNECT_RSP_NEG = 13, + L2CEVT_L2CAP_CONFIG_REQ = 14, + L2CEVT_L2CAP_CONFIG_RSP = 15, + L2CEVT_L2CAP_CONFIG_RSP_NEG = 16, + L2CEVT_L2CAP_DISCONNECT_REQ = 17, + L2CEVT_L2CAP_DISCONNECT_RSP = 18, + + L2CEVT_L2CAP_DATA = 19, + L2CEVT_L2CA_CONNECT_REQ = 20, + L2CEVT_L2CA_CONNECT_RSP = 21, + L2CEVT_L2CA_CONNECT_RSP_NEG = 22, + L2CEVT_L2CA_CONFIG_REQ = 23, + L2CEVT_L2CA_CONFIG_RSP = 24, + L2CEVT_L2CA_CONFIG_RSP_NEG = 25, + L2CEVT_L2CA_DISCONNECT_REQ = 26, + L2CEVT_L2CA_DISCONNECT_RSP = 27, + L2CEVT_L2CA_DATA_WRITE = 29, + + L2CEVT_TIMEOUT = 30, + L2CEVT_SEC_RE_SEND_CMD = 31, + L2CEVT_ACK_TIMEOUT = 32, + +#define L2CEVT_SEC_COMP (L2CEVT_SEC_COMP + 0) +#define L2CEVT_SEC_COMP_NEG (L2CEVT_SEC_COMP_NEG + 0) +}; + +enum { - BOOLEAN in_use; /* TRUE if test in progress */ - UINT8 skip_sframe_count; /* Number of S-Frames to skip sending */ -} tL2C_FCR_CFM_TEST_CB; + L2CAP_ADJ_ID = 0x03, +}; -typedef struct +enum { - tL2C_FCR_TEST_CFG cfg; /* Current corruption test configuration */ - tL2C_FCR_CFM_TEST_CB cfm; /* Conformance test structure */ -} tL2C_FCR_TEST_CB; + L2CAP_PEER_CFG_UNACCEPTABLE, + L2CAP_PEER_CFG_OK, + L2CAP_PEER_CFG_DISCONNECT, +}; -#endif /* L2CAP_CORRUPT_ERTM_PKTS == TRUE */ - -typedef struct +typedef UINT8 tL2C_CCB_CFG_FLAGS; +enum { - UINT8 next_tx_seq; /* Next sequence number to be Tx'ed */ - UINT8 last_rx_ack; /* Last sequence number ack'ed by the peer */ - UINT8 next_seq_expected; /* Next peer sequence number expected */ - UINT8 last_ack_sent; /* Last peer sequence number ack'ed */ - UINT8 num_tries; /* Number of retries to send a packet */ - UINT8 max_held_acks; /* Max acks we can hold before sending */ - - BOOLEAN remote_busy; /* TRUE if peer has flowed us off */ - BOOLEAN local_busy; /* TRUE if we have flowed off the peer */ - - BOOLEAN rej_sent; /* Reject was sent */ - BOOLEAN srej_sent; /* Selective Reject was sent */ - BOOLEAN wait_ack; /* Transmitter is waiting ack (poll sent) */ - BOOLEAN rej_after_srej; /* Send a REJ when SREJ clears */ - - BOOLEAN send_f_rsp; /* We need to send an F-bit response */ - - UINT16 rx_sdu_len; /* Length of the SDU being received */ - BT_HDR *p_rx_sdu; /* Buffer holding the SDU being received */ - BUFFER_Q waiting_for_ack_q; /* Buffers sent and waiting for peer to ack */ - BUFFER_Q srej_rcv_hold_q; /* Buffers rcvd but held pending SREJ rsp */ - BUFFER_Q retrans_q; /* Buffers being retransmitted */ - - TIMER_LIST_ENT ack_timer; /* Timer delaying RR */ - TIMER_LIST_ENT mon_retrans_timer; /* Timer Monitor or Retransmission */ - -#if (L2CAP_ERTM_STATS == TRUE) - UINT32 connect_tick_count; /* Time channel was established */ - UINT32 ertm_pkt_counts[2]; /* Packets sent and received */ - UINT32 ertm_byte_counts[2]; /* Bytes sent and received */ - UINT32 s_frames_sent[4]; /* S-frames sent (RR, REJ, RNR, SREJ) */ - UINT32 s_frames_rcvd[4]; /* S-frames rcvd (RR, REJ, RNR, SREJ) */ - UINT32 xmit_window_closed; /* # of times the xmit window was closed */ - UINT32 controller_idle; /* # of times less than 2 packets in controller */ - /* when the xmit window was closed */ - UINT32 pkts_retransmitted; /* # of packets that were retransmitted */ - UINT32 retrans_touts; /* # of retransmission timouts */ - UINT32 xmit_ack_touts; /* # of xmit ack timouts */ - -#define L2CAP_ERTM_STATS_NUM_AVG 10 -#define L2CAP_ERTM_STATS_AVG_NUM_SAMPLES 100 - UINT32 ack_delay_avg_count; - UINT32 ack_delay_avg_index; - UINT32 throughput_start; - UINT32 throughput[L2CAP_ERTM_STATS_NUM_AVG]; - UINT32 ack_delay_avg[L2CAP_ERTM_STATS_NUM_AVG]; - UINT32 ack_delay_min[L2CAP_ERTM_STATS_NUM_AVG]; - UINT32 ack_delay_max[L2CAP_ERTM_STATS_NUM_AVG]; - UINT32 ack_q_count_avg[L2CAP_ERTM_STATS_NUM_AVG]; - UINT32 ack_q_count_min[L2CAP_ERTM_STATS_NUM_AVG]; - UINT32 ack_q_count_max[L2CAP_ERTM_STATS_NUM_AVG]; -#endif - -#if L2CAP_CORRUPT_ERTM_PKTS == TRUE - tL2C_FCR_TEST_CB test_cb; /* Used for SVT and UPF testing */ -#endif - -} tL2C_FCRB; + IB_CFG_DONE = 1 << 0, + OB_CFG_DONE = 1 << 1, + RECONFIG_FLAG = 1 << 2, - -/* Define a registration control block. Every application (e.g. RFCOMM, SDP, -** TCS etc) that registers with L2CAP is assigned one of these. -*/ -#if (L2CAP_UCD_INCLUDED == TRUE) -#define L2C_UCD_RCB_ID 0x00 -#define L2C_UCD_STATE_UNUSED 0x00 -#define L2C_UCD_STATE_W4_DATA 0x01 -#define L2C_UCD_STATE_W4_RECEPTION 0x02 -#define L2C_UCD_STATE_W4_MTU 0x04 + CFG_DONE_MASK = IB_CFG_DONE | OB_CFG_DONE +}; typedef struct { - UINT8 state; - tL2CAP_UCD_CB_INFO cb_info; -} tL2C_UCD_REG; -#endif + BD_ADDR bd_addr; // 0x00 + UINT8 status; // 0x06 + /* 1 byte padding */ + UINT16 psm; // 0x08 + UINT16 l2cap_result; // 0x0a + UINT16 l2cap_status; // 0x0c + UINT16 remote_cid; // 0x0e +} tL2C_CONN_INFO; // size 0x10 typedef struct { - BOOLEAN in_use; - UINT16 psm; - UINT16 real_psm; /* This may be a dummy RCB for an o/b connection but */ - /* this is the real PSM that we need to connect to */ -#if (L2CAP_UCD_INCLUDED == TRUE) - tL2C_UCD_REG ucd; -#endif - - tL2CAP_APPL_INFO api; -} tL2C_RCB; + BOOLEAN in_use; // 0x00 + /* 1 byte padding */ + UINT16 psm; // 0x02 + tL2CAP_APPL_INFO api; // 0x04 +} tL2C_RCB; // size 0x2c - -/* Define a channel control block (CCB). There may be many channel control blocks -** between the same two Bluetooth devices (i.e. on the same link). -** Each CCB has unique local and remote CIDs. All channel control blocks on -** the same physical link and are chained together. -*/ typedef struct t_l2c_ccb { - BOOLEAN in_use; /* TRUE when in use, FALSE when not */ - tL2C_CHNL_STATE chnl_state; /* Channel state */ - - struct t_l2c_ccb *p_next_ccb; /* Next CCB in the chain */ - struct t_l2c_ccb *p_prev_ccb; /* Previous CCB in the chain */ - struct t_l2c_linkcb *p_lcb; /* Link this CCB is assigned to */ - - UINT16 local_cid; /* Local CID */ - UINT16 remote_cid; /* Remote CID */ - - TIMER_LIST_ENT timer_entry; /* CCB Timer List Entry */ - - tL2C_RCB *p_rcb; /* Registration CB for this Channel */ - -#define IB_CFG_DONE 0x01 -#define OB_CFG_DONE 0x02 -#define RECONFIG_FLAG 0x04 /* True after initial configuration */ -#define CFG_DONE_MASK (IB_CFG_DONE | OB_CFG_DONE) - - UINT8 config_done; /* Configuration flag word */ - UINT8 local_id; /* Transaction ID for local trans */ - UINT8 remote_id; /* Transaction ID for local */ - -#define CCB_FLAG_NO_RETRY 0x01 /* no more retry */ -#define CCB_FLAG_SENT_PENDING 0x02 /* already sent pending response */ - UINT8 flags; - - tL2CAP_CFG_INFO our_cfg; /* Our saved configuration options */ - tL2CAP_CH_CFG_BITS peer_cfg_bits; /* Store what peer wants to configure */ - tL2CAP_CFG_INFO peer_cfg; /* Peer's saved configuration options */ - - BUFFER_Q xmit_hold_q; /* Transmit data hold queue */ - - BOOLEAN cong_sent; /* Set when congested status sent */ - UINT16 buff_quota; /* Buffer quota before sending congestion */ - - tL2CAP_CHNL_PRIORITY ccb_priority; /* Channel priority */ - tL2CAP_CHNL_DATA_RATE tx_data_rate; /* Channel Tx data rate */ - tL2CAP_CHNL_DATA_RATE rx_data_rate; /* Channel Rx data rate */ - - /* Fields used for eL2CAP */ - tL2CAP_ERTM_INFO ertm_info; - tL2C_FCRB fcrb; - UINT16 tx_mps; /* TX MPS adjusted based on current controller */ - UINT16 max_rx_mtu; - UINT8 fcr_cfg_tries; /* Max number of negotiation attempts */ - BOOLEAN peer_cfg_already_rejected; /* If mode rejected once, set to TRUE */ - BOOLEAN out_cfg_fcr_present; /* TRUE if cfg response shoulkd include fcr options */ - -#define L2CAP_CFG_FCS_OUR 0x01 /* Our desired config FCS option */ -#define L2CAP_CFG_FCS_PEER 0x02 /* Peer's desired config FCS option */ -#define L2CAP_BYPASS_FCS (L2CAP_CFG_FCS_OUR | L2CAP_CFG_FCS_PEER) - UINT8 bypass_fcs; - -#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE) - BOOLEAN is_flushable; /* TRUE if channel is flushable */ -#endif - -#if (L2CAP_NUM_FIXED_CHNLS > 0) || (L2CAP_UCD_INCLUDED == TRUE) - UINT16 fixed_chnl_idle_tout; /* Idle timeout to use for the fixed channel */ -#endif - -} tL2C_CCB; - -/*********************************************************************** -** Define a queue of linked CCBs. -*/ -typedef struct -{ - tL2C_CCB *p_first_ccb; /* The first channel in this queue */ - tL2C_CCB *p_last_ccb; /* The last channel in this queue */ -} tL2C_CCB_Q; - -#if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) - -/* Round-Robin service for the same priority channels */ -#define L2CAP_NUM_CHNL_PRIORITY 3 /* Total number of priority group (high, medium, low)*/ -#define L2CAP_CHNL_PRIORITY_WEIGHT 5 /* weight per priority for burst transmission quota */ -#define L2CAP_GET_PRIORITY_QUOTA(pri) ((L2CAP_NUM_CHNL_PRIORITY - (pri)) * L2CAP_CHNL_PRIORITY_WEIGHT) - -/* CCBs within the same LCB are served in round robin with priority */ -/* It will make sure that low priority channel (for example, HF signaling on RFCOMM) */ -/* can be sent to headset even if higher priority channel (for example, AV media channel) */ -/* is congested. */ - -typedef struct -{ - tL2C_CCB *p_serve_ccb; /* current serving ccb within priority group */ - tL2C_CCB *p_first_ccb; /* first ccb of priority group */ - UINT8 num_ccb; /* number of channels in priority group */ - UINT8 quota; /* burst transmission quota */ -} tL2C_RR_SERV; + BOOLEAN in_use; // 0x00 + /* 3 bytes padding */ + tL2C_CHNL_STATE chnl_state; // 0x04 + struct t_l2c_ccb *p_next_ccb; // 0x08 + struct t_l2c_ccb *p_prev_ccb; // 0x0c + struct t_l2c_linkcb *p_lcb; // 0x10 + UINT16 local_cid; // 0x14 + UINT16 remote_cid; // 0x16 + TIMER_LIST_ENT timer_entry; // 0x18 + tL2C_RCB *p_rcb; // 0x30 + tL2C_CCB_CFG_FLAGS config_done; // 0x34 + UINT8 local_id; // 0x35 + UINT8 remote_id; // 0x36 + BOOLEAN rtry_flag; // 0x37 + UINT16 in_mtu; // 0x38 + UINT16 out_mtu; // 0x3a + UINT16 our_flush_to; // 0x3c + /* 2 bytes padding */ + FLOW_SPEC in_flow; // 0x40 + FLOW_SPEC out_flow; // 0x58 + BUFFER_Q xmit_hold_q; // 0x70 +} tL2C_CCB; // size 0x7c -#endif /* (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) */ - -/* Define a link control block. There is one link control block between -** this device and any other device (i.e. BD ADDR). -*/ typedef struct t_l2c_linkcb { - BOOLEAN in_use; /* TRUE when in use, FALSE when not */ - tL2C_LINK_STATE link_state; - -#ifdef REVOLUTION - tL2C_CCB_Q ccb_queue; /* Queue of CCBs on this LCB */ - TIMER_LIST_ENT timer_entry; /* Timer list entry for timeout evt */ - UINT16 handle; /* The handle used with LM */ - BD_ADDR remote_bd_addr; /* The BD address of the remote */ - UINT8 link_role; /* Master or slave */ - UINT8 id; - UINT16 link_flush_tout; /* Flush timeout used */ - UINT16 link_xmit_quota; /* Num outstanding pkts allowed */ - UINT16 link_xmit_window; - UINT16 sent_not_acked; /* Num packets sent but not acked */ - UINT16 link_cong_start; - UINT16 link_cong_end; - UINT16 link_cong_discard; - BOOLEAN partial_segment_being_sent; /* Set TRUE when a partial segment */ - /* is being sent. */ - BOOLEAN cong_sent; - BUFFER_Q link_xmit_data_q; /* Transmit data buffer queue */ - BT_HDR *p_hcit_rcv_acl; /* Current HCIT ACL buf being rcvd */ - tL2CA_ECHO_RSP_CB *p_echo_rsp_cb; /* Echo response callback */ - UINT16 idle_timeout; /* Idle timeout */ - UINT8 acl_priority; /* L2C_PRIORITY_NORMAL or L2C_PRIORITY_HIGH */ - BOOLEAN is_bonding; /* True - link active only for bonding */ -#else - TIMER_LIST_ENT timer_entry; /* Timer list entry for timeout evt */ - UINT16 handle; /* The handle used with LM */ - - tL2C_CCB_Q ccb_queue; /* Queue of CCBs on this LCB */ - - tL2C_CCB *p_pending_ccb; /* ccb of waiting channel during link disconnect */ - TIMER_LIST_ENT info_timer_entry; /* Timer entry for info resp timeout evt */ - BD_ADDR remote_bd_addr; /* The BD address of the remote */ - - UINT8 link_role; /* Master or slave */ - UINT8 id; - tL2CA_ECHO_RSP_CB *p_echo_rsp_cb; /* Echo response callback */ - UINT16 idle_timeout; /* Idle timeout */ - BOOLEAN is_bonding; /* True - link active only for bonding */ - - UINT16 link_flush_tout; /* Flush timeout used */ - - UINT16 link_xmit_quota; /* Num outstanding pkts allowed */ - UINT16 sent_not_acked; /* Num packets sent but not acked */ - - BOOLEAN partial_segment_being_sent; /* Set TRUE when a partial segment */ - /* is being sent. */ - BOOLEAN w4_info_rsp; /* TRUE when info request is active */ - UINT8 info_rx_bits; /* set 1 if received info type */ - UINT32 peer_ext_fea; /* Peer's extended features mask */ - BUFFER_Q link_xmit_data_q; /* Transmit data buffer queue */ - - UINT8 peer_chnl_mask[L2CAP_FIXED_CHNL_ARRAY_SIZE]; -#if (L2CAP_UCD_INCLUDED == TRUE) - UINT16 ucd_mtu; /* peer MTU on UCD */ - BUFFER_Q ucd_out_sec_pending_q; /* Security pending outgoing UCD packet */ - BUFFER_Q ucd_in_sec_pending_q; /* Security pending incoming UCD packet */ -#endif - -#if (L2CAP_HOST_FLOW_CTRL == TRUE) - UINT16 link_pkts_unacked; /* Packets received but not acked */ - UINT16 link_ack_thresh; /* Threshold at which to ack pkts */ -#endif - - BT_HDR *p_hcit_rcv_acl; /* Current HCIT ACL buf being rcvd */ - UINT16 idle_timeout_sv; /* Save current Idle timeout */ - UINT8 acl_priority; /* L2C_PRIORITY_NORMAL or L2C_PRIORITY_HIGH */ - tL2CA_NOCP_CB *p_nocp_cb; /* Num Cmpl pkts callback */ - -#if (L2CAP_NUM_FIXED_CHNLS > 0) - tL2C_CCB *p_fixed_ccbs[L2CAP_NUM_FIXED_CHNLS]; - UINT16 disc_reason; -#endif - -#if (BLE_INCLUDED == TRUE) - BOOLEAN is_ble_link; - tBLE_ADDR_TYPE ble_addr_type; - -#define UPD_ENABLED 0 /* If peer requests update, we will change params */ -#define UPD_DISABLED 1 /* application requested not to update */ -#define UPD_PENDING 2 /* while updates are disabled, peer requested new parameters */ -#define UPD_UPDATED 3 /* peer updated connection parameters */ - UINT8 upd_disabled; - - UINT16 min_interval; /* parameters as requested by peripheral */ - UINT16 max_interval; - UINT16 latency; - UINT16 timeout; - -#endif + BOOLEAN in_use; // 0x00 + /* 3 bytes padding */ + tL2C_LINK_STATE link_state; // 0x04 + tL2C_CCB *p_first_ccb; // 0x08 + tL2C_CCB *p_last_ccb; // 0x0c + TIMER_LIST_ENT timer_entry; // 0x10 + UINT16 handle; // 0x28 + BD_ADDR remote_bd_addr; // 0x2a + UINT8 link_role; // 0x30 + UINT8 id; // 0x31 + UINT16 link_flush_tout; // 0x32 + UINT16 link_xmit_quota; // 0x34 + UINT16 link_xmit_window; // 0x36 + UINT16 sent_not_acked; // 0x38 + UINT16 link_cong_start; // 0x3a + UINT16 link_cong_end; // 0x3c + UINT16 link_cong_discard; // 0x3e + BOOLEAN partial_segment_being_sent; // 0x40 + BOOLEAN cong_sent; // 0x41 + /* 2 bytes padding */ + BUFFER_Q link_xmit_data_q; // 0x44 + BT_HDR *p_hcit_rcv_acl; // 0x50 + tL2CA_ECHO_RSP_CB *p_echo_rsp_cb; // 0x54 + UINT16 idle_timeout; // 0x58 + UINT8 acl_priority; // 0x5a + /* 1 byte padding */ +} tL2C_LCB; // size 0x5c -#if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) - /* each priority group is limited burst transmission */ - /* round robin service for the same priority channels */ - tL2C_RR_SERV rr_serv[L2CAP_NUM_CHNL_PRIORITY]; - UINT8 rr_pri; /* current serving priority group */ -#endif -#endif /* REVOLUTION */ - -} tL2C_LCB; - -/* Define the L2CAP control structure -*/ -typedef struct -{ - UINT8 l2cap_trace_level; -#ifdef REVOLUTION - UINT8 desire_role; /* desire to be master/slave when accepting a connection */ - UINT16 num_lm_acl_bufs; /* # of ACL buffers on controller */ - UINT16 controller_xmit_window; /* Total ACL window for all links */ - BOOLEAN check_round_robin; /* Do a round robin check */ - - tL2C_LCB lcb_pool[MAX_L2CAP_LINKS]; /* Link Control Block pool */ - tL2C_CCB ccb_pool[MAX_L2CAP_CHANNELS]; /* Channel Control Block pool */ - tL2C_RCB rcb_pool[MAX_L2CAP_CLIENTS]; /* Registration info pool */ - - tL2C_CCB *p_free_ccb_first; /* Pointer to first free CCB */ - tL2C_CCB *p_free_ccb_last; /* Pointer to last free CCB */ - - UINT16 num_links_active; /* Number of links active */ - UINT16 idle_timeout; /* Idle timeout */ - - tL2C_LCB *p_cur_hcit_lcb; /* Current HCI Transport buffer */ - - BUFFER_Q rcv_hold_q; /* Recv pending queue */ - TIMER_LIST_ENT rcv_hold_tle; /* Timer list entry for rcv hold */ - - tL2CA_ECHO_DATA_CB *p_echo_data_cb; /* Echo data callback */ -#else - UINT16 controller_xmit_window; /* Total ACL window for all links */ - - UINT16 round_robin_quota; /* Round-robin link quota */ - UINT16 round_robin_unacked; /* Round-robin unacked */ - BOOLEAN check_round_robin; /* Do a round robin check */ - - BOOLEAN is_cong_cback_context; - - tL2C_LCB lcb_pool[MAX_L2CAP_LINKS]; /* Link Control Block pool */ - tL2C_CCB ccb_pool[MAX_L2CAP_CHANNELS]; /* Channel Control Block pool */ - tL2C_RCB rcb_pool[MAX_L2CAP_CLIENTS]; /* Registration info pool */ - - tL2C_CCB *p_free_ccb_first; /* Pointer to first free CCB */ - tL2C_CCB *p_free_ccb_last; /* Pointer to last free CCB */ - - UINT8 desire_role; /* desire to be master/slave when accepting a connection */ - BOOLEAN disallow_switch; /* FALSE, to allow switch at create conn */ - UINT16 num_lm_acl_bufs; /* # of ACL buffers on controller */ - UINT16 idle_timeout; /* Idle timeout */ - - BUFFER_Q rcv_hold_q; /* Recv pending queue */ - TIMER_LIST_ENT rcv_hold_tle; /* Timer list entry for rcv hold */ - - tL2C_LCB *p_cur_hcit_lcb; /* Current HCI Transport buffer */ - UINT16 num_links_active; /* Number of links active */ - -#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE) - UINT16 non_flushable_pbf; /* L2CAP_PKT_START_NON_FLUSHABLE if controller supports */ - /* Otherwise, L2CAP_PKT_START */ - BOOLEAN is_flush_active; /* TRUE if an HCI_Enhanced_Flush has been sent */ -#endif - -#if L2CAP_CONFORMANCE_TESTING == TRUE - UINT32 test_info_resp; /* Conformance testing needs a dynamic response */ -#endif - -#if (L2CAP_NUM_FIXED_CHNLS > 0) - tL2CAP_FIXED_CHNL_REG fixed_reg[L2CAP_NUM_FIXED_CHNLS]; /* Reg info for fixed channels */ -#endif - -#if (BLE_INCLUDED == TRUE) - BOOLEAN is_ble_connecting; - BD_ADDR ble_connecting_bda; - UINT16 controller_le_xmit_window; /* Total ACL window for all links */ - UINT16 num_lm_ble_bufs; /* # of ACL buffers on controller */ -#endif - - tL2CA_ECHO_DATA_CB *p_echo_data_cb; /* Echo data callback */ - -#if (defined(L2CAP_HIGH_PRI_CHAN_QUOTA_IS_CONFIGURABLE) && (L2CAP_HIGH_PRI_CHAN_QUOTA_IS_CONFIGURABLE == TRUE)) - UINT16 high_pri_min_xmit_quota; /* Minimum number of ACL credit for high priority link */ -#endif /* (L2CAP_HIGH_PRI_CHAN_QUOTA_IS_CONFIGURABLE == TRUE) */ - - UINT16 dyn_psm; -#endif /* REVOLUTION */ -} tL2C_CB; - - - -/* Define a structure that contains the information about a connection. -** This structure is used to pass between functions, and not all the -** fields will always be filled in. -*/ typedef struct { - BD_ADDR bd_addr; /* Remote BD address */ - UINT8 status; /* Connection status */ - UINT16 psm; /* PSM of the connection */ - UINT16 l2cap_result; /* L2CAP result */ - UINT16 l2cap_status; /* L2CAP status */ - UINT16 remote_cid; /* Remote CID */ -} tL2C_CONN_INFO; - - -typedef void (tL2C_FCR_MGMT_EVT_HDLR) (UINT8, tL2C_CCB *); - -/* The offset in a buffer that L2CAP will use when building commands. -*/ -#define L2CAP_SEND_CMD_OFFSET 0 - - -/* Number of ACL buffers to use for high priority channel -*/ -#if (!defined(L2CAP_HIGH_PRI_CHAN_QUOTA_IS_CONFIGURABLE) || (L2CAP_HIGH_PRI_CHAN_QUOTA_IS_CONFIGURABLE == FALSE)) -#define L2CAP_HIGH_PRI_MIN_XMIT_QUOTA_A (L2CAP_HIGH_PRI_MIN_XMIT_QUOTA) -#else -#define L2CAP_HIGH_PRI_MIN_XMIT_QUOTA_A (l2cb.high_pri_min_xmit_quota) -#endif + UINT8 l2cap_trace_level; // 0x000 + UINT8 desire_role; // 0x001 + UINT16 num_lm_acl_bufs; // 0x002 + UINT16 controller_xmit_window; // 0x004 + /* 2 bytes padding */ + tL2C_LCB lcb_pool[MAX_L2CAP_LINKS]; // 0x008 + tL2C_CCB ccb_pool[MAX_L2CAP_CHANNELS]; // 0x178 + tL2C_RCB rcb_pool[MAX_L2CAP_CLIENTS]; // 0x650 + tL2C_CCB *p_free_ccb_first; // 0x7b0 + tL2C_CCB *p_free_ccb_last; // 0x7b4 + UINT16 num_links_active; // 0x7b8 + UINT16 idle_timeout; // 0x7ba + tL2C_LCB *p_cur_hcit_lcb; // 0x7bc + BUFFER_Q rcv_hold_q; // 0x7c0 + TIMER_LIST_ENT rcv_hold_tle; // 0x7cc + UINT8 compress_pool_id; // 0x7e4 + /* 3 bytes padding */ +} tL2C_CB; // size 0x7e8 + +extern tL2C_CB l2cb; + +void l2c_csm_execute(tL2C_CCB *p_ccb, UINT16 event, void *p_data); +void forward_peer_data(tL2C_CCB *p_ccb, BT_HDR *p_buf); + +void l2c_link_hci_conn_req(BD_ADDR bd_addr); +BOOLEAN l2c_link_hci_conn_comp(UINT8 status, UINT16 handle, BD_ADDR p_bda); +void l2c_link_sec_comp(BD_ADDR p_bda, void *p_ref_data, UINT8 status); +BOOLEAN l2c_link_hci_disc_comp(UINT16 handle, UINT8 reason); +BOOLEAN l2c_link_hci_qos_violation(UINT16 handle); +void l2c_link_timeout(tL2C_LCB *p_lcb); +BOOLEAN l2c_link_send_to_lower(tL2C_LCB *p_lcb, BT_HDR *p_buf); +void l2c_link_check_send_pkts(tL2C_LCB *p_lcb, + tL2C_CCB *p_ccb, + BT_HDR *p_buf); +void l2c_link_adjust_allocation(void); +void l2c_link_process_num_completed_pkts(UINT8 *p); +/* NOTE the misspelling of process */ +void l2c_link_processs_num_bufs(UINT16 num_lm_acl_bufs); +BT_HDR *l2cap_link_chk_pkt_start(BT_HDR *p_cur_buf); +BOOLEAN l2cap_link_chk_pkt_end(void); +BT_HDR *l2c_link_get_decompressed_pkt(BT_HDR *p_cur); +UINT8 l2c_link_pkts_rcvd(UINT16 *num_pkts, UINT16 *handles); +void l2c_link_role_changed(BD_ADDR bd_addr, UINT8 new_role); +void l2c_link_role_change_failed(void); +void l2c_link_segments_xmitted(BT_HDR *p_msg); +void l2c_pin_code_request(BD_ADDR bd_addr); + +void l2c_init(void); +void l2c_rcv_acl_data(BT_HDR *p_msg); +void l2c_process_compress_setup_timeout(TIMER_LIST_ENT *p_tle); +void l2c_process_timeout(TIMER_LIST_ENT *p_tle); +void l2c_process_held_packets(BOOLEAN timed_out); + +tL2C_LCB *l2cu_allocate_lcb(BD_ADDR p_bd_addr); +void l2cu_release_lcb(tL2C_LCB *p_lcb); +tL2C_LCB *l2cu_find_lcb_by_bd_addr(BD_ADDR p_bd_addr); +tL2C_LCB *l2cu_find_lcb_by_handle(UINT16 handle); +UINT8 l2cu_get_conn_role (tL2C_LCB *p_this_lcb); +BT_HDR *l2cu_build_header(UINT16 hci_handle, UINT16 len, UINT8 cmd, UINT8 id); +void l2cu_send_peer_cmd_reject(tL2C_LCB *p_lcb, UINT16 reason, UINT8 rem_id, + UINT16 p1, UINT16 p2); +void l2cu_send_peer_connect_req(tL2C_CCB *p_ccb); +void l2cu_send_peer_connect_rsp(tL2C_CCB *p_ccb, UINT16 result, UINT16 status); +void l2cu_reject_connection(tL2C_LCB *p_lcb, UINT16 remote_cid, UINT8 rem_id, + UINT16 result); +void l2cu_send_peer_config_req(tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg); +void l2cu_send_peer_config_rsp(tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg); +void l2cu_send_peer_config_rej(tL2C_CCB *p_ccb, UINT8 *p_data, UINT16 data_len, + UINT16 rej_len); +void l2cu_send_peer_disc_req(tL2C_CCB *p_ccb); +void l2cu_send_peer_disc_rsp(tL2C_LCB *p_lcb, UINT8 remote_id, UINT16 local_cid, + UINT16 remote_cid); +void l2cu_send_peer_echo_req(tL2C_LCB *p_lcb, UINT8 *p_data, UINT16 data_len); +void l2cu_send_peer_echo_rsp(tL2C_LCB *p_lcb, UINT8 id, UINT8 *p_data, + UINT16 data_len); +void l2cu_send_peer_info_req(tL2C_LCB *p_lcb, UINT16 info_type); +void l2cu_send_peer_info_rsp(tL2C_LCB *p_lcb, UINT8 remote_id, UINT16 info_type); +tL2C_CCB *l2cu_allocate_ccb(tL2C_LCB *p_lcb); +void l2cu_release_ccb(tL2C_CCB *p_ccb); +tL2C_CCB *l2cu_find_ccb_by_cid(tL2C_LCB *p_lcb, UINT16 local_cid); +tL2C_CCB *l2cu_find_ccb_by_remote_cid(tL2C_LCB *p_lcb, UINT16 remote_cid); +tL2C_RCB *l2cu_allocate_rcb(UINT16 psm); +void l2cu_release_rcb(tL2C_RCB *p_rcb); +tL2C_RCB *l2cu_find_rcb_by_psm(UINT16 psm); +BOOLEAN l2cu_process_peer_cfg_req(tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg); +void l2cu_process_peer_cfg_rsp(tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg); +void l2cu_process_our_cfg_req(tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg); +void l2cu_process_our_cfg_rsp(tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg); +void l2cu_device_reset(void); +BOOLEAN l2cu_create_conn(tL2C_LCB *p_lcb); +BOOLEAN l2cu_create_conn_after_switch(tL2C_LCB *p_lcb); +tL2C_LCB *l2cu_find_lcb_by_state(tL2C_LINK_STATE state); +BOOLEAN l2cu_lcb_disconnecting(void); +void l2cu_send_feature_req(tL2C_CCB *p_ccb); +BOOLEAN l2cu_check_feature_req(tL2C_LCB *p_lcb, UINT8 id, UINT8 *p_data, + UINT16 data_len); +void l2cu_check_feature_rsp(tL2C_LCB *p_lcb, UINT8 id, UINT8 *p_data, + UINT16 data_len); +void l2cu_stop_compression(/* void? */); +BOOLEAN l2cu_lcb_has_feature_enable(/* tL2C_LCB *p_lcb? */); +BOOLEAN l2cu_ccb_has_compression_enable(/* tL2C_CCB *p_ccb? */); +UINT32 L2CA_GetCompressionFixMemoryPoolSize(/* void? */); #ifdef __cplusplus -extern "C" { -#endif - - -/* L2CAP global data -************************************ -*/ -#if (!defined L2C_DYNAMIC_MEMORY) || (L2C_DYNAMIC_MEMORY == FALSE) -L2C_API extern tL2C_CB l2cb; -#else -L2C_API extern tL2C_CB *l2c_cb_ptr; -#define l2cb (*l2c_cb_ptr) -#endif - - -/* Functions provided by l2c_main.c -************************************ -*/ -extern void l2c_init (void); -extern void l2c_process_timeout (TIMER_LIST_ENT *p_tle); -extern UINT8 l2c_data_write (UINT16 cid, BT_HDR *p_data, UINT16 flag); -extern void l2c_rcv_acl_data (BT_HDR *p_msg); -extern void l2c_process_held_packets (BOOLEAN timed_out); - -/* Functions provided by l2c_utils.c -************************************ -*/ -#ifdef REVOLUTION -extern tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr); -#else -extern tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding); -#endif -extern BOOLEAN l2cu_start_post_bond_timer (UINT16 handle); -extern void l2cu_release_lcb (tL2C_LCB *p_lcb); -extern tL2C_LCB *l2cu_find_lcb_by_bd_addr (BD_ADDR p_bd_addr); -extern tL2C_LCB *l2cu_find_lcb_by_handle (UINT16 handle); -extern void l2cu_update_lcb_4_bonding (BD_ADDR p_bd_addr, BOOLEAN is_bonding); - -extern UINT8 l2cu_get_conn_role (tL2C_LCB *p_this_lcb); -extern BOOLEAN l2cu_set_acl_priority (BD_ADDR bd_addr, UINT8 priority, BOOLEAN reset_after_rs); - -extern void l2cu_enqueue_ccb (tL2C_CCB *p_ccb); -extern void l2cu_dequeue_ccb (tL2C_CCB *p_ccb); -extern void l2cu_change_pri_ccb (tL2C_CCB *p_ccb, tL2CAP_CHNL_PRIORITY priority); - -extern tL2C_CCB *l2cu_allocate_ccb (tL2C_LCB *p_lcb, UINT16 cid); -extern void l2cu_release_ccb (tL2C_CCB *p_ccb); -extern tL2C_CCB *l2cu_find_ccb_by_cid (tL2C_LCB *p_lcb, UINT16 local_cid); -extern tL2C_CCB *l2cu_find_ccb_by_remote_cid (tL2C_LCB *p_lcb, UINT16 remote_cid); -extern void l2cu_adj_id (tL2C_LCB *p_lcb, UINT8 adj_mask); - -extern void l2cu_send_peer_cmd_reject (tL2C_LCB *p_lcb, UINT16 reason, - UINT8 rem_id,UINT16 p1, UINT16 p2); -extern void l2cu_send_peer_connect_req (tL2C_CCB *p_ccb); -extern void l2cu_send_peer_connect_rsp (tL2C_CCB *p_ccb, UINT16 result, UINT16 status); -extern void l2cu_send_peer_config_req (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg); -extern void l2cu_send_peer_config_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg); -extern void l2cu_send_peer_config_rej (tL2C_CCB *p_ccb, UINT8 *p_data, UINT16 data_len, UINT16 rej_len); -extern void l2cu_send_peer_disc_req (tL2C_CCB *p_ccb); -extern void l2cu_send_peer_disc_rsp (tL2C_LCB *p_lcb, UINT8 remote_id, UINT16 local_cid, UINT16 remote_cid); -extern void l2cu_send_peer_echo_req (tL2C_LCB *p_lcb, UINT8 *p_data, UINT16 data_len); -extern void l2cu_send_peer_echo_rsp (tL2C_LCB *p_lcb, UINT8 id, UINT8 *p_data, UINT16 data_len); -extern void l2cu_send_peer_info_rsp (tL2C_LCB *p_lcb, UINT8 id, UINT16 info_type); -extern void l2cu_reject_connection (tL2C_LCB *p_lcb, UINT16 remote_cid, UINT8 rem_id, UINT16 result); -extern void l2cu_send_peer_info_req (tL2C_LCB *p_lcb, UINT16 info_type); -extern void l2cu_set_acl_hci_header (BT_HDR *p_buf, tL2C_CCB *p_ccb); -extern void l2cu_check_channel_congestion (tL2C_CCB *p_ccb); -extern void l2cu_disconnect_chnl (tL2C_CCB *p_ccb); - -#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE) -extern void l2cu_set_non_flushable_pbf(BOOLEAN); -#endif - -#if (BLE_INCLUDED == TRUE) -extern void l2cu_send_peer_ble_par_req (tL2C_LCB *p_lcb, UINT16 min_int, UINT16 max_int, UINT16 latency, UINT16 timeout); -extern void l2cu_send_peer_ble_par_rsp (tL2C_LCB *p_lcb, UINT16 reason, UINT8 rem_id); + } #endif -extern BOOLEAN l2cu_initialize_fixed_ccb (tL2C_LCB *p_lcb, UINT16 fixed_cid, tL2CAP_FCR_OPTS *p_fcr); -extern void l2cu_no_dynamic_ccbs (tL2C_LCB *p_lcb); -extern void l2cu_process_fixed_chnl_resp (tL2C_LCB *p_lcb); - -/* Functions provided by l2c_ucd.c -************************************ -*/ -#if (L2CAP_UCD_INCLUDED == TRUE) -void l2c_ucd_delete_sec_pending_q(tL2C_LCB *p_lcb); -void l2c_ucd_enqueue_pending_out_sec_q(tL2C_CCB *p_ccb, void *p_data); -BOOLEAN l2c_ucd_check_pending_info_req(tL2C_CCB *p_ccb); -BOOLEAN l2c_ucd_check_pending_out_sec_q(tL2C_CCB *p_ccb); -void l2c_ucd_send_pending_out_sec_q(tL2C_CCB *p_ccb); -void l2c_ucd_discard_pending_out_sec_q(tL2C_CCB *p_ccb); -BOOLEAN l2c_ucd_check_pending_in_sec_q(tL2C_CCB *p_ccb); -void l2c_ucd_send_pending_in_sec_q(tL2C_CCB *p_ccb); -void l2c_ucd_discard_pending_in_sec_q(tL2C_CCB *p_ccb); -BOOLEAN l2c_ucd_check_rx_pkts(tL2C_LCB *p_lcb, BT_HDR *p_msg); -BOOLEAN l2c_ucd_process_event(tL2C_CCB *p_ccb, UINT16 event, void *p_data); -#endif -#if (BLE_INCLUDED == TRUE) -extern void l2cu_send_peer_ble_par_req (tL2C_LCB *p_lcb, UINT16 min_int, UINT16 max_int, UINT16 latency, UINT16 timeout); -extern void l2cu_send_peer_ble_par_rsp (tL2C_LCB *p_lcb, UINT16 reason, UINT8 rem_id); -#endif - -extern BOOLEAN l2cu_initialize_fixed_ccb (tL2C_LCB *p_lcb, UINT16 fixed_cid, tL2CAP_FCR_OPTS *p_fcr); -extern void l2cu_no_dynamic_ccbs (tL2C_LCB *p_lcb); -extern void l2cu_process_fixed_chnl_resp (tL2C_LCB *p_lcb); - - -/* Functions provided for Broadcom Aware -**************************************** -*/ -extern BOOLEAN l2cu_check_feature_req (tL2C_LCB *p_lcb, UINT8 id, UINT8 *p_data, UINT16 data_len); -extern void l2cu_check_feature_rsp (tL2C_LCB *p_lcb, UINT8 id, UINT8 *p_data, UINT16 data_len); -extern void l2cu_send_feature_req (tL2C_CCB *p_ccb); - -extern tL2C_RCB *l2cu_allocate_rcb (UINT16 psm); -extern tL2C_RCB *l2cu_find_rcb_by_psm (UINT16 psm); -extern void l2cu_release_rcb (tL2C_RCB *p_rcb); - -extern UINT8 l2cu_process_peer_cfg_req (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg); -extern void l2cu_process_peer_cfg_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg); -extern void l2cu_process_our_cfg_req (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg); -extern void l2cu_process_our_cfg_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg); - -extern void l2cu_device_reset (void); -extern tL2C_LCB *l2cu_find_lcb_by_state (tL2C_LINK_STATE state); -extern BOOLEAN l2cu_lcb_disconnecting (void); - -extern BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb); -extern BOOLEAN l2cu_create_conn_after_switch (tL2C_LCB *p_lcb); -extern BT_HDR *l2cu_get_next_buffer_to_send (tL2C_LCB *p_lcb); -extern void l2cu_resubmit_pending_sec_req (BD_ADDR p_bda); -extern void l2cu_initialize_amp_ccb (tL2C_LCB *p_lcb); -extern void l2cu_adjust_out_mps (tL2C_CCB *p_ccb); - -/* Functions provided by l2c_link.c -************************************ -*/ -extern BOOLEAN l2c_link_hci_conn_req (BD_ADDR bd_addr); -extern BOOLEAN l2c_link_hci_conn_comp (UINT8 status, UINT16 handle, BD_ADDR p_bda); -extern BOOLEAN l2c_link_hci_disc_comp (UINT16 handle, UINT8 reason); -extern BOOLEAN l2c_link_hci_qos_violation (UINT16 handle); -extern void l2c_link_timeout (tL2C_LCB *p_lcb); -extern void l2c_info_timeout (tL2C_LCB *p_lcb); -extern void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_HDR *p_buf); -extern void l2c_link_adjust_allocation (void); -extern void l2c_link_process_num_completed_pkts (UINT8 *p); -extern void l2c_link_process_num_completed_blocks (UINT8 controller_id, UINT8 *p, UINT16 evt_len); -extern void l2c_link_processs_num_bufs (UINT16 num_lm_acl_bufs); -extern UINT8 l2c_link_pkts_rcvd (UINT16 *num_pkts, UINT16 *handles); -extern void l2c_link_role_changed (BD_ADDR bd_addr, UINT8 new_role); -extern void l2c_link_sec_comp (BD_ADDR p_bda, void *p_ref_data, UINT8 status); -extern void l2c_link_segments_xmitted (BT_HDR *p_msg); -extern void l2c_pin_code_request (BD_ADDR bd_addr); -extern void l2c_link_adjust_chnl_allocation (void); - -#if (BLE_INCLUDED == TRUE) -extern void l2c_link_processs_ble_num_bufs (UINT16 num_lm_acl_bufs); -#endif - -#if ((BTM_PWR_MGR_INCLUDED == TRUE) && L2CAP_WAKE_PARKED_LINK == TRUE) -extern BOOLEAN l2c_link_check_power_mode ( tL2C_LCB *p_lcb ); -#define L2C_LINK_CHECK_POWER_MODE(x) l2c_link_check_power_mode ((x)) -#else -#define L2C_LINK_CHECK_POWER_MODE(x) (FALSE) -#endif - -#if L2CAP_CONFORMANCE_TESTING == TRUE -/* Used only for conformance testing */ -L2C_API extern void l2cu_set_info_rsp_mask (UINT32 mask); -#endif - -/* Functions provided by l2c_csm.c -************************************ -*/ -extern void l2c_csm_execute (tL2C_CCB *p_ccb, UINT16 event, void *p_data); - -L2C_API extern BT_HDR *l2cap_link_chk_pkt_start(BT_HDR *); /* Called at start of rcv to check L2CAP segmentation */ -L2C_API extern BOOLEAN l2cap_link_chk_pkt_end (void); /* Called at end of rcv to check L2CAP segmentation */ - -L2C_API extern void l2c_enqueue_peer_data (tL2C_CCB *p_ccb, BT_HDR *p_buf); - - -/* Functions provided by l2c_fcr.c -************************************ -*/ -extern void l2c_fcr_cleanup (tL2C_CCB *p_ccb); -extern void l2c_fcr_proc_pdu (tL2C_CCB *p_ccb, BT_HDR *p_buf); -extern void l2c_fcr_proc_tout (tL2C_CCB *p_ccb); -extern void l2c_fcr_proc_ack_tout (tL2C_CCB *p_ccb); -extern void l2c_fcr_send_S_frame (tL2C_CCB *p_ccb, UINT16 function_code, UINT16 pf_bit); -extern BT_HDR *l2c_fcr_clone_buf (BT_HDR *p_buf, UINT16 new_offset, UINT16 no_of_bytes, UINT8 pool); -extern BOOLEAN l2c_fcr_is_flow_controlled (tL2C_CCB *p_ccb); -extern BT_HDR *l2c_fcr_get_next_xmit_sdu_seg (tL2C_CCB *p_ccb, UINT16 max_packet_length); -extern void l2c_fcr_start_timer (tL2C_CCB *p_ccb); - -/* Configuration negotiation */ -extern UINT8 l2c_fcr_chk_chan_modes (tL2C_CCB *p_ccb); -extern BOOLEAN l2c_fcr_adj_our_req_options (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg); -extern void l2c_fcr_adj_our_rsp_options (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_peer_cfg); -extern BOOLEAN l2c_fcr_renegotiate_chan(tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg); -extern UINT8 l2c_fcr_process_peer_cfg_req(tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg); -extern void l2c_fcr_adj_monitor_retran_timeout (tL2C_CCB *p_ccb); -extern void l2c_fcr_stop_timer (tL2C_CCB *p_ccb); - -/* Functions provided by l2c_ble.c -************************************ -*/ -#if (BLE_INCLUDED == TRUE) -extern BOOLEAN l2cble_create_conn (tL2C_LCB *p_lcb); -extern void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len); -extern void l2cble_conn_comp (UINT16 handle, UINT8 role, BD_ADDR bda, tBLE_ADDR_TYPE type, - UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout); - -#endif - -#ifdef __cplusplus -} -#endif - -#endif +/* 2006 trace helper: L2CAP_TRACE(LEVEL, fmt, ...) -> L2CAP_TRACE_LEVELn(fmt, ...) */ +#define L2CAP_TRACE_CAT(a, b) L2CAP_TRACE_CAT_(a, b) +#define L2CAP_TRACE_CAT_(a, b) a##b +#define L2CAP_TRACE_NARG(...) L2CAP_TRACE_NARG_(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0) +#define L2CAP_TRACE_NARG_(_1, _2, _3, _4, _5, _6, _7, N, ...) N +#define L2CAP_TRACE_DEC_1 0 +#define L2CAP_TRACE_DEC_2 1 +#define L2CAP_TRACE_DEC_3 2 +#define L2CAP_TRACE_DEC_4 3 +#define L2CAP_TRACE_DEC_5 4 +#define L2CAP_TRACE_DEC_6 5 +#define L2CAP_TRACE_DEC_7 6 +#define L2CAP_TRACE(type_, ...) \ + L2CAP_TRACE_CAT(L2CAP_TRACE_CAT(L2CAP_TRACE_, type_), \ + L2CAP_TRACE_CAT(L2CAP_TRACE_DEC_, L2CAP_TRACE_NARG(__VA_ARGS__)))(__VA_ARGS__) + +#endif // BTE_L2CAP_INT_H diff --git a/src/btu_hcif_data.s b/src/btu_hcif_data.s new file mode 100644 index 0000000..be99a34 --- /dev/null +++ b/src/btu_hcif_data.s @@ -0,0 +1,36 @@ +.include "macros.inc" + +.data +.balign 4 + +.obj sHciControllerError, global +.string "Ctlr H/w error event" +.endobj sHciControllerError + +.obj sHciControllerErrorPad, global +.zero 3 +.endobj sHciControllerErrorPad + +.obj sHciEventMismatch, global +.string "Event mismatch opcode=%X cmd opcode=%X" +.endobj sHciEventMismatch + +.obj sHciEventMismatchPad, global +.zero 1 +.endobj sHciEventMismatchPad + +.obj sHciCommandTimeout, global +.string "Cmd timeout; no cmd in queue" +.endobj sHciCommandTimeout + +.obj sHciCommandTimeoutPad, global +.zero 3 +.endobj sHciCommandTimeoutPad + +.obj sHciCommandTimeoutOpcode, global +.string "BTU HCI command timeout - cmd opcode = 0x%02x" +.endobj sHciCommandTimeoutOpcode + +.obj sHciCommandTimeoutOpcodePad, global +.zero 2 +.endobj sHciCommandTimeoutOpcodePad diff --git a/src/revolution/BTE/gki/common/gki_buffer.c b/src/revolution/BTE/gki/common/gki_buffer.c index 613d5c6..60cd9f3 100644 --- a/src/revolution/BTE/gki/common/gki_buffer.c +++ b/src/revolution/BTE/gki/common/gki_buffer.c @@ -1045,8 +1045,8 @@ BOOLEAN GKI_queue_is_empty(BUFFER_Q *p_q) /* Not present in the retail RVL build (dead-stripped from the DOL), but the trace string it used is still part of the retail .data, so keep its bytes - (with their original position) in an explicit array. Named @1041 in - symbols.txt, after its compiler symbol in the original object. */ + (with their original position) in an explicit array. Its compiler-pool + label is recorded in symbols.txt. */ char sBadAddrMsg[] = "GKI_get_buf_start:: bad addr"; #ifndef REVOLUTION diff --git a/src/revolution/BTE/stack/btm/btm_sec.c b/src/revolution/BTE/stack/btm/btm_sec.c index 623dfe1..2f09f0a 100644 --- a/src/revolution/BTE/stack/btm/btm_sec.c +++ b/src/revolution/BTE/stack/btm/btm_sec.c @@ -4175,7 +4175,7 @@ void btm_sec_conn_req (UINT8 *bda, UINT8 *dc) memcpy (btm_cb.connecting_bda, bda, BD_ADDR_LEN); memcpy (btm_cb.connecting_dc, dc, DEV_CLASS_LEN); - if (l2c_link_hci_conn_req (bda)) + if (((BOOLEAN (*)(BD_ADDR))l2c_link_hci_conn_req)(bda)) { if (!p_dev_rec) { diff --git a/src/revolution/BTE/stack/gap/gap_api.c b/src/revolution/BTE/stack/gap/gap_api.c new file mode 100644 index 0000000..177c6d0 --- /dev/null +++ b/src/revolution/BTE/stack/gap/gap_api.c @@ -0,0 +1,56 @@ +/****************************************************************************** + * + * Copyright (C) 2009-2013 Broadcom Corporation + * + * 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. + * + ******************************************************************************/ + +/* Original source: + * bluedroid + * stack/gap/gap_api.c + */ + +/* Includes changes by muff1n1634 and for this repository (KoopTheKoopa) */ + +/****************************************************************************** + * + * This file contains the GAP API functions. + * + ******************************************************************************/ + +#include "gap_api.h" + +#include + +#include "bt_target.h" +#include "bt_trace.h" +#include "bt_types.h" +#include "data_types.h" + +#include "btm_api.h" +#include "gap_int.h" +#include "profiles_api.h" +#include "sdp_api.h" + +void GAP_Init(void) +{ + memset(&gap_cb, 0, sizeof gap_cb); + + gap_cb.btm_cback[0] = &gap_btm_cback0; + gap_cb.btm_cback[1] = &gap_btm_cback1; + + gap_cb.trace_level = BT_TRACE_LEVEL_DEBUG; + + gap_conn_init(); +} diff --git a/src/revolution/BTE/stack/gap/gap_conn.c b/src/revolution/BTE/stack/gap/gap_conn.c new file mode 100644 index 0000000..4aa105d --- /dev/null +++ b/src/revolution/BTE/stack/gap/gap_conn.c @@ -0,0 +1,331 @@ +/****************************************************************************** + * + * Copyright (C) 2009-2013 Broadcom Corporation + * + * 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. + * + ******************************************************************************/ + +/* Original source: + * bluedroid + * stack/gap/gap_conn.c + */ + +/* Includes changes by muff1n1634 and for this repository (KoopTheKoopa) */ + +/****************************************************************************** + * + * This file contains the GAP connection functions. + * + ******************************************************************************/ + +#include "gap_int.h" + +#include // NULL +#include + +#include "bt_target.h" +#include "bt_trace.h" +#include "bt_types.h" +#include "data_types.h" + +#include "btm_api.h" +#include "btu.h" +#include "gap_api.h" +#include "gki.h" +#include "l2cdefs.h" +#include "l2c_api.h" +#include "profiles_api.h" + +char gap_conn_trace_separator[] = "*******"; +char gap_conn_trace_unexpected_addr[] = "WARNING: GAP Conn Indication for Unexpected Bd Addr...Disconnecting"; +char gap_conn_trace_connect_ind[] = "GAP_CONN - Rcvd L2CAP conn ind, CID: 0x%x"; +char gap_conn_trace_disconnect_ind[] = "GAP_CONN - Rcvd L2CAP disc, CID: 0x%x"; +char gap_conn_trace_congestion_ind[0x38] = "GAP_CONN - Rcvd L2CAP Is Congested (%d), CID: 0x%x"; + + + +static void gap_connect_ind(BD_ADDR bd_addr, UINT16 l2cap_cid, UINT16 psm, + UINT8 l2cap_id); +static void gap_connect_cfm(UINT16 l2cap_cid, UINT16 result); +static void gap_config_ind(UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg); +static void gap_config_cfm(UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg); +static void gap_disconnect_ind(UINT16 l2cap_cid, BOOLEAN ack_needed); +static void gap_data_ind(UINT16 l2cap_cid, BT_HDR *p_msg); +static void gap_congestion_ind(UINT16 lcid, BOOLEAN is_congested); +static tGAP_CCB *gap_find_ccb_by_cid(UINT16 cid); +static tGAP_CCB *gap_find_ccb_by_handle(UINT16 handle); +static tGAP_CCB *gap_allocate_ccb(void); +static void gap_release_ccb(tGAP_CCB *p_ccb); + +void gap_conn_init(void) +{ + gap_cb.conn.reg_info.pL2CA_ConnectInd_Cb = &gap_connect_ind; + gap_cb.conn.reg_info.pL2CA_ConnectCfm_Cb = &gap_connect_cfm; + gap_cb.conn.reg_info.pL2CA_ConnectPnd_Cb = NULL; + gap_cb.conn.reg_info.pL2CA_ConfigInd_Cb = &gap_config_ind; + gap_cb.conn.reg_info.pL2CA_ConfigCfm_Cb = &gap_config_cfm; + gap_cb.conn.reg_info.pL2CA_DisconnectInd_Cb = &gap_disconnect_ind; + gap_cb.conn.reg_info.pL2CA_DisconnectCfm_Cb = NULL; + gap_cb.conn.reg_info.pL2CA_QoSViolationInd_Cb = NULL; + gap_cb.conn.reg_info.pL2CA_DataInd_Cb = &gap_data_ind; + gap_cb.conn.reg_info.pL2CA_CongestionStatus_Cb = &gap_congestion_ind; +} + +static void gap_connect_ind(BD_ADDR bd_addr, UINT16 l2cap_cid, UINT16 psm, + UINT8 l2cap_id) +{ + UINT16 xx; + tGAP_CCB *p_ccb; + + /* explicitly post-increment */ + for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; + xx++, p_ccb++) + { + if (p_ccb->con_state == GAP_CCB_STATE_LISTENING && p_ccb->psm == psm + && (!p_ccb->rem_addr_specified + || memcmp(bd_addr, p_ccb->rem_dev_address, BD_ADDR_LEN) == 0)) + { + break; + } + } + + if (xx == GAP_MAX_CONNECTIONS) + { + GAP_TRACE(WARNING, gap_conn_trace_separator); + GAP_TRACE(WARNING, gap_conn_trace_unexpected_addr); + GAP_TRACE(WARNING, gap_conn_trace_separator); + + L2CA_DisconnectReq(l2cap_cid); + return; + } + + p_ccb->con_state = GAP_CCB_STATE_CFG_SETUP; + + memcpy(p_ccb->rem_dev_address, bd_addr, BD_ADDR_LEN); + p_ccb->connection_id = l2cap_cid; + + L2CA_ConnectRsp(bd_addr, l2cap_id, l2cap_cid, L2CAP_CONN_OK, L2CAP_CONN_OK); + + GAP_TRACE(EVENT, gap_conn_trace_connect_ind, + p_ccb->connection_id); + + L2CA_ConfigReq(l2cap_cid, &p_ccb->cfg); +} + +static void gap_connect_cfm(UINT16 l2cap_cid, UINT16 result) +{ + tGAP_CCB *p_ccb = gap_find_ccb_by_cid(l2cap_cid); + + if (!p_ccb) + return; + + if (result == L2CAP_CONN_OK + && p_ccb->con_state == GAP_CCB_STATE_CONN_SETUP) + { + p_ccb->con_state = GAP_CCB_STATE_CFG_SETUP; + + L2CA_ConfigReq(l2cap_cid, &p_ccb->cfg); + } + else + { + if (p_ccb->p_callback) + (*p_ccb->p_callback)(p_ccb->gap_handle, GAP_EVT_CONN_CLOSED); + + gap_release_ccb(p_ccb); + } +} + +static void gap_config_ind(UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg) +{ + tGAP_CCB *p_ccb = gap_find_ccb_by_cid(l2cap_cid); + + if (!p_ccb) + return; + + if (!p_cfg->mtu_present || p_cfg->mtu > L2CAP_MTU_SIZE) + p_ccb->rem_mtu_size = L2CAP_MTU_SIZE; + else + p_ccb->rem_mtu_size = p_cfg->mtu; + + p_cfg->flush_to_present = FALSE; + p_cfg->mtu_present = FALSE; + p_cfg->result = L2CAP_CFG_OK; + + L2CA_ConfigRsp(l2cap_cid, p_cfg); + + p_ccb->con_flags |= GAP_CCB_FLAGS_THEIR_CFG_DONE; + + if (p_ccb->con_flags & GAP_CCB_FLAGS_OUR_CFG_DONE) + { + p_ccb->con_state = GAP_CCB_STATE_CONNECTED; + + (*p_ccb->p_callback)(p_ccb->gap_handle, GAP_EVT_CONN_OPENED); + } +} + +static void gap_config_cfm(UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg) +{ + tGAP_CCB *p_ccb = gap_find_ccb_by_cid(l2cap_cid); + + if (!p_ccb) + return; + + if (p_cfg->result == L2CAP_CFG_OK) + { + p_ccb->con_flags |= GAP_CCB_FLAGS_OUR_CFG_DONE; + + if (p_ccb->con_flags & GAP_CCB_FLAGS_THEIR_CFG_DONE) + { + p_ccb->con_state = GAP_CCB_STATE_CONNECTED; + + (*p_ccb->p_callback)(p_ccb->gap_handle, GAP_EVT_CONN_OPENED); + } + } + else + { + (*p_ccb->p_callback)(p_ccb->gap_handle, GAP_EVT_CONN_CLOSED); + gap_release_ccb(p_ccb); + } +} + +static void gap_disconnect_ind(UINT16 l2cap_cid, BOOLEAN ack_needed) +{ + tGAP_CCB *p_ccb; + + GAP_TRACE(EVENT, gap_conn_trace_disconnect_ind, l2cap_cid); + + if ((p_ccb = gap_find_ccb_by_cid(l2cap_cid)) == NULL) + return; + + if (ack_needed) + L2CA_DisconnectRsp(l2cap_cid); + + (*p_ccb->p_callback)(p_ccb->gap_handle, GAP_EVT_CONN_CLOSED); + gap_release_ccb(p_ccb); +} + +static void gap_data_ind(UINT16 l2cap_cid, BT_HDR *p_msg) +{ + tGAP_CCB *p_ccb = gap_find_ccb_by_cid(l2cap_cid); + + if (!p_ccb) + { + GKI_freebuf(p_msg); + return; + } + + if (p_ccb->con_state == GAP_CCB_STATE_CONNECTED) + { + GKI_enqueue(&p_ccb->rx_queue, p_msg); + + (*p_ccb->p_callback)(p_ccb->gap_handle, GAP_EVT_CONN_DATA_AVAIL); + } + else + { + GKI_freebuf(p_msg); + } +} + +static void gap_congestion_ind(UINT16 lcid, BOOLEAN is_congested) +{ + tGAP_CCB *p_ccb; + UINT16 event; + + GAP_TRACE(EVENT, gap_conn_trace_congestion_ind, + is_congested, lcid); + + if ((p_ccb = gap_find_ccb_by_cid(lcid)) == NULL) + return; + + event = is_congested ? GAP_EVT_CONN_CONGESTED : GAP_EVT_CONN_UNCONGESTED; + (*p_ccb->p_callback)(p_ccb->gap_handle, event); +} + +static tGAP_CCB *gap_find_ccb_by_cid(UINT16 cid) +{ + UINT16 xx; + tGAP_CCB *p_ccb; + + /* explicitly post-increment */ + for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; + xx++, p_ccb++) + { + if (p_ccb->con_state != GAP_CCB_STATE_IDLE + && p_ccb->connection_id == cid) + { + return p_ccb; + } + } + + return NULL; +} + +static tGAP_CCB *gap_find_ccb_by_handle(UINT16 handle) +{ + tGAP_CCB *p_ccb; + + if (handle < GAP_MAX_CONNECTIONS) + { + p_ccb = &gap_cb.conn.ccb_pool[handle]; + + if (p_ccb->con_state != GAP_CCB_STATE_IDLE) + return p_ccb; + } + + return NULL; +} + +static tGAP_CCB *gap_allocate_ccb(void) +{ + UINT16 xx; + tGAP_CCB *p_ccb; + + /* explicitly post-increment */ + for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; + xx++, p_ccb++) + { + if (p_ccb->con_state == GAP_CCB_STATE_IDLE) + { + memset(p_ccb, 0, sizeof *p_ccb); + + p_ccb->gap_handle = xx; + p_ccb->rem_mtu_size = L2CAP_MTU_SIZE; + + return p_ccb; + } + } + + return NULL; +} + +static void gap_release_ccb(tGAP_CCB *p_ccb) +{ + UINT16 xx; + UINT16 psm = p_ccb->psm; + + while (p_ccb->rx_queue.p_first) + GKI_freebuf(GKI_dequeue(&p_ccb->rx_queue)); + + p_ccb->con_state = GAP_CCB_STATE_IDLE; + + /* explicitly post-increment */ + for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; + xx++, p_ccb++) + { + if (p_ccb->con_state != GAP_CCB_STATE_IDLE && p_ccb->psm == psm) + return; + } + + L2CA_Deregister(psm); +} diff --git a/src/revolution/BTE/stack/gap/gap_utils.c b/src/revolution/BTE/stack/gap/gap_utils.c new file mode 100644 index 0000000..9a96917 --- /dev/null +++ b/src/revolution/BTE/stack/gap/gap_utils.c @@ -0,0 +1,289 @@ +/****************************************************************************** + * + * Copyright (C) 2009-2013 Broadcom Corporation + * + * 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. + * + ******************************************************************************/ + +/* Original source: + * bluedroid + * stack/gap/gap_utils.c + */ + +/* Includes changes by muff1n1634 and for this repository (KoopTheKoopa) */ + +/****************************************************************************** + * + * This file contains GAP utility functions. + * + ******************************************************************************/ + +#include "gap_int.h" + +#include + +#include + +#include "bt_trace.h" +#include "bt_types.h" +#include "data_types.h" + +#include "btm_api.h" +#include "profiles_api.h" +#include "gap_api.h" + +static void btm_cback(UINT16 index, void *p_data); +static void gap_free_cb(tGAP_INFO *p_cb); + +tGAP_CB gap_cb; + +static void btm_cback(UINT16 index, void *p_data) +{ + tGAP_INFO *p_cb; + tGAP_INQ_CMPL inq_cmpl; + + if (index >= GAP_MAX_BLOCKS) + return; + + if (!gap_cb.blk[index].in_use) + return; + + p_cb = &gap_cb.blk[index]; + + switch (p_cb->event) + { + case GAP_EVT_INQUIRY_COMPLETE: + inq_cmpl.num_results = ((tBTM_INQUIRY_CMPL *)p_data)->num_resp; + + inq_cmpl.status = + (((tBTM_INQUIRY_CMPL *)p_data)->status == BTM_SUCCESS) + ? BT_PASS + : GAP_ERR_PROCESSING; + + p_data = &inq_cmpl; + + GAP_TRACE(EVENT, + " GAP Inquiry Complete Event (Status 0x%04x, Result(s) %d)", + inq_cmpl.status, inq_cmpl.num_results); + break; + + case GAP_EVT_DISCOVERY_COMPLETE: + if (*(UINT16 *)p_data) + { + GAP_TRACE(EVENT, + " GAP Discovery Complete Event(SDP Result: 0x%04x)", + *(UINT16 *)p_data); + } + else + { + GAP_TRACE(EVENT, " GAP Discovery Successfully Completed"); + } + + break; + + case GAP_EVT_REM_NAME_COMPLETE: + ((tGAP_REMOTE_DEV_NAME *)p_data)->status = gap_convert_btm_status( + ((tBTM_REMOTE_DEV_NAME *)p_data)->status); + + GAP_TRACE(EVENT, + " GAP Remote Name Complete Event (status 0x%04x)", + ((tGAP_REMOTE_DEV_NAME *)p_data)->status); + + break; + }; + + if (p_cb->gap_cback) + (*p_cb->gap_cback)(p_cb->event, p_data); + + gap_free_cb(p_cb); + +} + + +char gap_utils_inq_results_traces[0x88] = + "GAP Inquiry Results Callback (bdaddr [%02x%02x%02x%02x%02x%02x])" + "\0\0\0\0" + " (COD [%02x%02x%02x], clkoff 0x%04x)" + "\0\0\0"; + +void gap_btm_cback0(void *p1) +{ + btm_cback(0, p1); +} + +void gap_btm_cback1(void *p1) +{ + btm_cback(1, p1); +} + +char gap_utils_trace_find_name[0x44] = " GAP: FindAddrByName Rem Name Cmpl Evt (Status 0x%04x, Name [%s])"; +char gap_utils_trace_find_name_status[0x39] = " GAP: FindAddrByName Rem Name Cmpl Evt (Status 0x%04x)"; + +void gap_find_addr_name_cb(tBTM_REMOTE_DEV_NAME *p) +{ + tGAP_FINDADDR_CB *p_cb = &gap_cb.findaddr_cb; + tGAP_FINDADDR_RESULTS *p_result = &p_cb->results; + + if (!p_cb->in_use) + return; + + if (p->status == BTM_SUCCESS) + { + GAP_TRACE(EVENT, gap_utils_trace_find_name, + p->status, p->remote_bd_name); + + if (!strncmp((char *)p_result->devname, (char *)p->remote_bd_name, + strlen((char *)p_result->devname))) + { + memcpy(p_result->bd_addr, + p_cb->p_cur_inq->results.remote_bd_addr, BD_ADDR_LEN); + + p_result->status = BT_PASS; + } + else + { + if ((p_cb->p_cur_inq = BTM_InqDbNext(p_cb->p_cur_inq)) != NULL) + { + if (BTM_ReadRemoteDeviceName( + p_cb->p_cur_inq->results.remote_bd_addr, + (tBTM_CMPL_CB *)&gap_find_addr_name_cb) + == BTM_CMD_STARTED) + { + return; + } + else + { + p_result->status = + gap_convert_btm_status((tBTM_STATUS)p->status); + } + } + else + { + p_result->status = GAP_EOINQDB; + } + } + } + else + { + GAP_TRACE(EVENT, + gap_utils_trace_find_name_status, + p->status); + p_result->status = gap_convert_btm_status((tBTM_STATUS)p->status); + } + + if (p_cb->p_cback) + (*p_cb->p_cback)(GAP_EVT_FIND_ADDR_COMPLETE, p_result); + + p_cb->in_use = FALSE; + p_cb->p_cback = NULL; +} + +char gap_utils_trace_find_inq[0x42] = " GAP: FindAddrByName Inq Cmpl Evt (Status 0x%04x, Result(s) %d)"; + +void gap_find_addr_inq_cb(tBTM_INQUIRY_CMPL *p) +{ + tGAP_FINDADDR_CB *p_cb = &gap_cb.findaddr_cb; + tGAP_FINDADDR_RESULTS *p_result = &p_cb->results; + + if (!p_cb->in_use) + return; + + GAP_TRACE( + EVENT, + gap_utils_trace_find_inq, + p->status, p->num_resp); + + if (p->status == BTM_SUCCESS) + { + if ((p_result->status = gap_find_local_addr_by_name(p_result->devname, + p_result->bd_addr)) + == GAP_NO_DATA_AVAIL) + { + if ((p_cb->p_cur_inq = BTM_InqDbFirst()) != NULL) + { + if ((BTM_ReadRemoteDeviceName( + p_cb->p_cur_inq->results.remote_bd_addr, + (tBTM_CMPL_CB *)&gap_find_addr_name_cb)) + == BTM_CMD_STARTED) + { + return; + } + else + { + p_result->status = gap_convert_btm_status(p->status); + } + } + else + { + p_result->status = GAP_EOINQDB; + } + } + } + else + { + p_result->status = gap_convert_btm_status(p->status); + } + + if (p_cb->p_cback) + (*p_cb->p_cback)(GAP_EVT_FIND_ADDR_COMPLETE, p_result); + + p_cb->in_use = FALSE; + p_cb->p_cback = NULL; +} + +static UINT16 gap_find_local_addr_by_name(tBTM_BD_NAME const devname, BD_ADDR bd_addr) +{ + return GAP_NO_DATA_AVAIL; +} + +static void gap_free_cb(tGAP_INFO *p_cb) +{ + if (p_cb) + { + p_cb->gap_cback = NULL; + p_cb->in_use = FALSE; + } +} + + +UINT16 gap_convert_btm_status(tBTM_STATUS btm_status) +{ + switch (btm_status) + { + case BTM_SUCCESS: + return BT_PASS; + + case BTM_CMD_STARTED: + return GAP_CMD_INITIATED; + + case BTM_BUSY: + return GAP_ERR_BUSY; + + case BTM_MODE_UNSUPPORTED: + case BTM_ILLEGAL_VALUE: + return GAP_ERR_ILL_PARM; + + case BTM_WRONG_MODE: + return GAP_DEVICE_NOT_UP; + + case BTM_UNKNOWN_ADDR: + return GAP_BAD_BD_ADDR; + + case BTM_DEVICE_TIMEOUT: + return GAP_ERR_TIMEOUT; + + default: + return GAP_ERR_PROCESSING; + } +} diff --git a/src/revolution/BTE/stack/hcic/hcicmds.c b/src/revolution/BTE/stack/hcic/hcicmds.c index a375368..6ffd52f 100644 --- a/src/revolution/BTE/stack/hcic/hcicmds.c +++ b/src/revolution/BTE/stack/hcic/hcicmds.c @@ -16,52 +16,55 @@ * ******************************************************************************/ +/* Original source: + * bluedroid + * stack/hcic/hcicmds.c + */ + +/* Includes changes by muff1n1634 and for this repository (KoopTheKoopa) */ + /****************************************************************************** * - * This file contains function of the HCIC unit to format and send HCI - * commands. + * This file contains the HCI command building functions. * ******************************************************************************/ -#include "bt_target.h" -#include "gki.h" -#include "hcidefs.h" #include "hcimsgs.h" -#include "hcidefs.h" -#include "btu.h" -#include #include -#if defined (LMP_TEST) -#include -#define btu_hcif_send_cmd(p1, p2) HCI_CMD_TO_LOWER((p2)) -#else -#include "btm_int.h" /* Included for UIPC_* macro definitions */ -#endif +#include // ARRAY_LENGTH + +#include "bt_target.h" +#include "bt_types.h" +#include "data_types.h" + +#include "hcidefs.h" +#include "btu.h" -BOOLEAN btsnd_hcic_inquiry(const LAP inq_lap, UINT8 duration, UINT8 response_cnt) +BOOLEAN btsnd_hcic_inquiry(LAP const inq_lap, UINT8 duration, + UINT8 response_cnt) { BT_HDR *p; UINT8 *pp; if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_INQUIRY)) == NULL) - return (FALSE); + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_INQUIRY; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_INQUIRY; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_INQUIRY); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_INQUIRY); + UINT16_TO_STREAM(pp, HCI_INQUIRY); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_INQUIRY); - LAP_TO_STREAM (pp, inq_lap); - UINT8_TO_STREAM (pp, duration); - UINT8_TO_STREAM (pp, response_cnt); + LAP_TO_STREAM(pp, inq_lap); + UINT8_TO_STREAM(pp, duration); + UINT8_TO_STREAM(pp, response_cnt); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } BOOLEAN btsnd_hcic_inq_cancel(void) @@ -70,63 +73,46 @@ BOOLEAN btsnd_hcic_inq_cancel(void) UINT8 *pp; if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_INQ_CANCEL)) == NULL) - return (FALSE); + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_INQ_CANCEL; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_INQ_CANCEL; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_INQUIRY_CANCEL); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_INQ_CANCEL); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + UINT16_TO_STREAM(pp, HCI_INQUIRY_CANCEL); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_INQ_CANCEL); + + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_per_inq_mode (UINT16 max_period, UINT16 min_period, - const LAP inq_lap, UINT8 duration, UINT8 response_cnt) +BOOLEAN btsnd_hcic_per_inq_mode(UINT16 max_period, UINT16 min_period, + LAP const inq_lap, UINT8 duration, + UINT8 response_cnt) { BT_HDR *p; UINT8 *pp; if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_PER_INQ_MODE)) == NULL) - return (FALSE); + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_PER_INQ_MODE; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_PER_INQ_MODE; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_PERIODIC_INQUIRY_MODE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_PER_INQ_MODE); - - UINT16_TO_STREAM (pp, max_period); - UINT16_TO_STREAM (pp, min_period); - LAP_TO_STREAM (pp, inq_lap); - UINT8_TO_STREAM (pp, duration); - UINT8_TO_STREAM (pp, response_cnt); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_exit_per_inq (void) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_EXIT_PER_INQ)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); + UINT16_TO_STREAM(pp, HCI_PERIODIC_INQUIRY_MODE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_PER_INQ_MODE); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_EXIT_PER_INQ; - p->offset = 0; - UINT16_TO_STREAM (pp, HCI_EXIT_PERIODIC_INQUIRY_MODE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_EXIT_PER_INQ); + UINT16_TO_STREAM(pp, max_period); + UINT16_TO_STREAM(pp, min_period); + LAP_TO_STREAM(pp, inq_lap); + UINT8_TO_STREAM(pp, duration); + UINT8_TO_STREAM(pp, response_cnt); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } @@ -138,225 +124,173 @@ BOOLEAN btsnd_hcic_create_conn(BD_ADDR dest, UINT16 packet_types, UINT8 *pp; if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_CREATE_CONN)) == NULL) - return (FALSE); + return FALSE; pp = (UINT8 *)(p + 1); -#ifndef BT_10A - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CREATE_CONN; -#else - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CREATE_CONN - 1; -#endif + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CREATE_CONN; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_CREATE_CONNECTION); -#ifndef BT_10A - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_CREATE_CONN); -#else - UINT8_TO_STREAM (pp, (HCIC_PARAM_SIZE_CREATE_CONN - 1)); -#endif - BDADDR_TO_STREAM (pp, dest); - UINT16_TO_STREAM (pp, packet_types); - UINT8_TO_STREAM (pp, page_scan_rep_mode); - UINT8_TO_STREAM (pp, page_scan_mode); - UINT16_TO_STREAM (pp, clock_offset); -#if !defined (BT_10A) - UINT8_TO_STREAM (pp, allow_switch); -#endif -/* If calling from LMP_TEST or ScriptEngine, then send HCI command immediately */ -#if (!defined (LMP_TEST) && !defined(BTISE)) - btm_acl_paging (p, dest); -#else - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); -#endif - return (TRUE); -} - -BOOLEAN btsnd_hcic_disconnect (UINT16 handle, UINT8 reason) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_DISCONNECT)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); + UINT16_TO_STREAM(pp, HCI_CREATE_CONNECTION); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_CREATE_CONN); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_DISCONNECT; - p->offset = 0; + BDADDR_TO_STREAM(pp, dest); + UINT16_TO_STREAM(pp, packet_types); + UINT8_TO_STREAM(pp, page_scan_rep_mode); + UINT8_TO_STREAM(pp, page_scan_mode); + UINT16_TO_STREAM(pp, clock_offset); + UINT8_TO_STREAM(pp, allow_switch); - UINT16_TO_STREAM (pp, HCI_DISCONNECT); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_DISCONNECT); - UINT16_TO_STREAM (pp, handle); - UINT8_TO_STREAM (pp, reason); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); -/* If calling from LMP_TEST or ScriptEngine, then send HCI command immediately */ -#if (!defined (LMP_TEST) && !defined(BTISE)) -// btla-specific ++ - // btm_acl_set_discing(TRUE); -// btla-specific -- -#endif - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -#if BTM_SCO_INCLUDED == TRUE -BOOLEAN btsnd_hcic_add_SCO_conn (UINT16 handle, UINT16 packet_types) +BOOLEAN btsnd_hcic_disconnect(UINT16 handle, UINT8 reason) { BT_HDR *p; UINT8 *pp; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_ADD_SCO_CONN)) == NULL) - return (FALSE); + if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_DISCONNECT)) == NULL) + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_ADD_SCO_CONN; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_DISCONNECT; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_ADD_SCO_CONNECTION); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_ADD_SCO_CONN); + UINT16_TO_STREAM(pp, HCI_DISCONNECT); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_DISCONNECT); - UINT16_TO_STREAM (pp, handle); - UINT16_TO_STREAM (pp, packet_types); + UINT16_TO_STREAM(pp, handle); + UINT8_TO_STREAM(pp, reason); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -#endif /* BTM_SCO_INCLUDED */ -BOOLEAN btsnd_hcic_create_conn_cancel(BD_ADDR dest) +BOOLEAN btsnd_hcic_add_SCO_conn(UINT16 handle, UINT16 packet_types) { BT_HDR *p; UINT8 *pp; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_CREATE_CONN_CANCEL)) == NULL) - return (FALSE); + if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_ADD_SCO_CONN)) == NULL) + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CREATE_CONN_CANCEL; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_ADD_SCO_CONN; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_CREATE_CONNECTION_CANCEL); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_CREATE_CONN_CANCEL); + UINT16_TO_STREAM(pp, HCI_ADD_SCO_CONNECTION); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_ADD_SCO_CONN); - BDADDR_TO_STREAM (pp, dest); + UINT16_TO_STREAM(pp, handle); + UINT16_TO_STREAM(pp, packet_types); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_accept_conn (BD_ADDR dest, UINT8 role) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_ACCEPT_CONN)) == NULL) - return (FALSE); - pp = (UINT8 *)(p + 1); +void btsnd_hcic_accept_conn(void *buffer, BD_ADDR dest, UINT8 role) +{ + BT_HDR *p = buffer; + UINT8 *pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_ACCEPT_CONN; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_ACCEPT_CONN; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_ACCEPT_CONNECTION_REQUEST); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_ACCEPT_CONN); - BDADDR_TO_STREAM (pp, dest); - UINT8_TO_STREAM (pp, role); + UINT16_TO_STREAM(pp, HCI_ACCEPT_CONNECTION_REQUEST); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_ACCEPT_CONN); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + BDADDR_TO_STREAM(pp, dest); + UINT8_TO_STREAM(pp, role); + + btu_hcif_send_cmd(p); } -BOOLEAN btsnd_hcic_reject_conn (BD_ADDR dest, UINT8 reason) +void btsnd_hcic_reject_conn(void *buffer, BD_ADDR dest, UINT8 reason) { - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_REJECT_CONN)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); + BT_HDR *p = buffer; + UINT8 *pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_REJECT_CONN; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_REJECT_CONN; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_REJECT_CONNECTION_REQUEST); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_REJECT_CONN); + UINT16_TO_STREAM(pp, HCI_REJECT_CONNECTION_REQUEST); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_REJECT_CONN); - BDADDR_TO_STREAM (pp, dest); - UINT8_TO_STREAM (pp, reason); + BDADDR_TO_STREAM(pp, dest); + UINT8_TO_STREAM(pp, reason); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); } -BOOLEAN btsnd_hcic_link_key_req_reply (BD_ADDR bd_addr, LINK_KEY link_key) +BOOLEAN btsnd_hcic_link_key_req_reply(BD_ADDR bd_addr, LINK_KEY link_key) { BT_HDR *p; UINT8 *pp; if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_LINK_KEY_REQ_REPLY)) == NULL) - return (FALSE); + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_LINK_KEY_REQ_REPLY; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_LINK_KEY_REQ_REPLY; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_LINK_KEY_REQUEST_REPLY); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_LINK_KEY_REQ_REPLY); + UINT16_TO_STREAM(pp, HCI_LINK_KEY_REQUEST_REPLY); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_LINK_KEY_REQ_REPLY); - BDADDR_TO_STREAM (pp, bd_addr); - ARRAY16_TO_STREAM (pp, link_key); + BDADDR_TO_STREAM(pp, bd_addr); + ARRAY16_TO_STREAM(pp, link_key); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_link_key_neg_reply (BD_ADDR bd_addr) +BOOLEAN btsnd_hcic_link_key_neg_reply(BD_ADDR bd_addr) { BT_HDR *p; UINT8 *pp; if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_LINK_KEY_NEG_REPLY)) == NULL) - return (FALSE); + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_LINK_KEY_NEG_REPLY; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_LINK_KEY_NEG_REPLY; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_LINK_KEY_REQUEST_NEG_REPLY); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_LINK_KEY_NEG_REPLY); + UINT16_TO_STREAM(pp, HCI_LINK_KEY_REQUEST_NEG_REPLY); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_LINK_KEY_NEG_REPLY); - BDADDR_TO_STREAM (pp, bd_addr); + BDADDR_TO_STREAM(pp, bd_addr); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_pin_code_req_reply (BD_ADDR bd_addr, UINT8 pin_code_len, - PIN_CODE pin_code) +BOOLEAN btsnd_hcic_pin_code_req_reply(BD_ADDR bd_addr, UINT8 pin_code_len, + PIN_CODE pin_code) { BT_HDR *p; - UINT8 *pp; - int i; + UINT8 *pp; + int i; if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_PIN_CODE_REQ_REPLY)) == NULL) - return (FALSE); + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_PIN_CODE_REQ_REPLY; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_PIN_CODE_REQ_REPLY; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_PIN_CODE_REQUEST_REPLY); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_PIN_CODE_REQ_REPLY); + UINT16_TO_STREAM(pp, HCI_PIN_CODE_REQUEST_REPLY); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_PIN_CODE_REQ_REPLY); - BDADDR_TO_STREAM (pp, bd_addr); - UINT8_TO_STREAM (pp, pin_code_len); + BDADDR_TO_STREAM(pp, bd_addr); + UINT8_TO_STREAM(pp, pin_code_len); for (i = 0; i < pin_code_len; i++) *pp++ = *pin_code++; @@ -364,2998 +298,1144 @@ BOOLEAN btsnd_hcic_pin_code_req_reply (BD_ADDR bd_addr, UINT8 pin_code_len, for (; i < PIN_CODE_LEN; i++) *pp++ = 0; - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_pin_code_neg_reply (BD_ADDR bd_addr) +BOOLEAN btsnd_hcic_pin_code_neg_reply(BD_ADDR bd_addr) { BT_HDR *p; UINT8 *pp; if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_PIN_CODE_NEG_REPLY)) == NULL) - return (FALSE); + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_PIN_CODE_NEG_REPLY; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_PIN_CODE_NEG_REPLY; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_PIN_CODE_REQUEST_NEG_REPLY); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_PIN_CODE_NEG_REPLY); + UINT16_TO_STREAM(pp, HCI_PIN_CODE_REQUEST_NEG_REPLY); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_PIN_CODE_NEG_REPLY); - BDADDR_TO_STREAM (pp, bd_addr); + BDADDR_TO_STREAM(pp, bd_addr); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_change_conn_type (UINT16 handle, UINT16 packet_types) +BOOLEAN btsnd_hcic_change_conn_type(UINT16 handle, UINT16 packet_types) { BT_HDR *p; UINT8 *pp; if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_CHANGE_CONN_TYPE)) == NULL) - return (FALSE); + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CHANGE_CONN_TYPE; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CHANGE_CONN_TYPE; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_CHANGE_CONN_PACKET_TYPE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_CHANGE_CONN_TYPE); + UINT16_TO_STREAM(pp, HCI_CHANGE_CONN_PACKET_TYPE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_CHANGE_CONN_TYPE); - UINT16_TO_STREAM (pp, handle); - UINT16_TO_STREAM (pp, packet_types); + UINT16_TO_STREAM(pp, handle); + UINT16_TO_STREAM(pp, packet_types); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_auth_request (UINT16 handle) +BOOLEAN btsnd_hcic_auth_request(UINT16 handle) { BT_HDR *p; UINT8 *pp; if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_CMD_HANDLE)) == NULL) - return (FALSE); + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CMD_HANDLE; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CMD_HANDLE; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_AUTHENTICATION_REQUESTED); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_CMD_HANDLE); + UINT16_TO_STREAM(pp, HCI_AUTHENTICATION_REQUESTED); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_CMD_HANDLE); - UINT16_TO_STREAM (pp, handle); + UINT16_TO_STREAM(pp, handle); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_set_conn_encrypt (UINT16 handle, BOOLEAN enable) +BOOLEAN btsnd_hcic_set_conn_encrypt(UINT16 handle, BOOLEAN enable) { BT_HDR *p; UINT8 *pp; if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_SET_CONN_ENCRYPT)) == NULL) - return (FALSE); + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_SET_CONN_ENCRYPT; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_SET_CONN_ENCRYPT; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_SET_CONN_ENCRYPTION); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_SET_CONN_ENCRYPT); + UINT16_TO_STREAM(pp, HCI_SET_CONN_ENCRYPTION); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_CONN_ENCRYPT); - UINT16_TO_STREAM (pp, handle); - UINT8_TO_STREAM (pp, enable); + UINT16_TO_STREAM(pp, handle); + UINT8_TO_STREAM(pp, enable); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_change_link_key (UINT16 handle) + + +BOOLEAN btsnd_hcic_rmt_name_req(BD_ADDR bd_addr, UINT8 page_scan_rep_mode, + UINT8 page_scan_mode, UINT16 clock_offset) { BT_HDR *p; UINT8 *pp; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_CMD_HANDLE)) == NULL) - return (FALSE); + if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_RMT_NAME_REQ)) == NULL) + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CMD_HANDLE; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_RMT_NAME_REQ; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_CHANGE_CONN_LINK_KEY); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_CMD_HANDLE); + UINT16_TO_STREAM(pp, HCI_RMT_NAME_REQUEST); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_RMT_NAME_REQ); - UINT16_TO_STREAM (pp, handle); + BDADDR_TO_STREAM(pp, bd_addr); + UINT8_TO_STREAM(pp, page_scan_rep_mode); + UINT8_TO_STREAM(pp, page_scan_mode); + UINT16_TO_STREAM(pp, clock_offset); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_master_link_key (BOOLEAN key_flag) +BOOLEAN btsnd_hcic_rmt_name_req_cancel(BD_ADDR bd_addr) { BT_HDR *p; UINT8 *pp; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_MASTER_LINK_KEY)) == NULL) - return (FALSE); + if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_RMT_NAME_REQ_CANCEL)) == NULL) + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_MASTER_LINK_KEY; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_RMT_NAME_REQ_CANCEL; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_MASTER_LINK_KEY); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_MASTER_LINK_KEY); + UINT16_TO_STREAM(pp, HCI_RMT_NAME_REQUEST_CANCEL); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_RMT_NAME_REQ_CANCEL); - UINT8_TO_STREAM (pp, key_flag); + BDADDR_TO_STREAM(pp, bd_addr); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_rmt_name_req (BD_ADDR bd_addr, UINT8 page_scan_rep_mode, - UINT8 page_scan_mode, UINT16 clock_offset) +BOOLEAN btsnd_hcic_rmt_features_req(UINT16 handle) { BT_HDR *p; UINT8 *pp; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_RMT_NAME_REQ)) == NULL) - return (FALSE); + if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_CMD_HANDLE)) == NULL) + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_RMT_NAME_REQ; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CMD_HANDLE; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_RMT_NAME_REQUEST); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_RMT_NAME_REQ); + UINT16_TO_STREAM(pp, HCI_READ_RMT_FEATURES); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_CMD_HANDLE); - BDADDR_TO_STREAM (pp, bd_addr); - UINT8_TO_STREAM (pp, page_scan_rep_mode); - UINT8_TO_STREAM (pp, page_scan_mode); - UINT16_TO_STREAM (pp, clock_offset); + UINT16_TO_STREAM(pp, handle); -/* If calling from LMP_TEST or ScriptEngine, then send HCI command immediately */ -#if (!defined (LMP_TEST) && !defined(BTISE)) - btm_acl_paging (p, bd_addr); -#else - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); -#endif - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_rmt_name_req_cancel (BD_ADDR bd_addr) + +BOOLEAN btsnd_hcic_rmt_ver_req(UINT16 handle) { BT_HDR *p; UINT8 *pp; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_RMT_NAME_REQ_CANCEL)) == NULL) - return (FALSE); + if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_CMD_HANDLE)) == NULL) + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_RMT_NAME_REQ_CANCEL; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CMD_HANDLE; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_RMT_NAME_REQUEST_CANCEL); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_RMT_NAME_REQ_CANCEL); + UINT16_TO_STREAM(pp, HCI_READ_RMT_VERSION_INFO); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_CMD_HANDLE); - BDADDR_TO_STREAM (pp, bd_addr); + UINT16_TO_STREAM(pp, handle); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_rmt_features_req (UINT16 handle) +BOOLEAN btsnd_hcic_read_rmt_clk_offset(UINT16 handle) { BT_HDR *p; UINT8 *pp; if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_CMD_HANDLE)) == NULL) - return (FALSE); + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CMD_HANDLE; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CMD_HANDLE; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_READ_RMT_FEATURES); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_CMD_HANDLE); + UINT16_TO_STREAM(pp, HCI_READ_RMT_CLOCK_OFFSET); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_CMD_HANDLE); - UINT16_TO_STREAM (pp, handle); + UINT16_TO_STREAM(pp, handle); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_rmt_ext_features (UINT16 handle, UINT8 page_num) + +BOOLEAN btsnd_hcic_setup_esco_conn(UINT16 handle, UINT32 tx_bw, UINT32 rx_bw, + UINT16 max_latency, UINT16 voice, + UINT8 retrans_effort, UINT16 packet_types) { BT_HDR *p; UINT8 *pp; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_RMT_EXT_FEATURES)) == NULL) - return (FALSE); + if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_SETUP_ESCO)) == NULL) + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_RMT_EXT_FEATURES; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_SETUP_ESCO; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_READ_RMT_EXT_FEATURES); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_RMT_EXT_FEATURES); + UINT16_TO_STREAM(pp, HCI_SETUP_ESCO_CONNECTION); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SETUP_ESCO); - UINT16_TO_STREAM (pp, handle); - UINT8_TO_STREAM (pp, page_num); + UINT16_TO_STREAM(pp, handle); + UINT32_TO_STREAM(pp, tx_bw); + UINT32_TO_STREAM(pp, rx_bw); + UINT16_TO_STREAM(pp, max_latency); + UINT16_TO_STREAM(pp, voice); + UINT8_TO_STREAM(pp, retrans_effort); + UINT16_TO_STREAM(pp, packet_types); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_rmt_ver_req (UINT16 handle) +void btsnd_hcic_accept_esco_conn(void *buffer, BD_ADDR bd_addr, UINT32 tx_bw, + UINT32 rx_bw, UINT16 max_latency, + UINT16 content_fmt, UINT8 retrans_effort, + UINT16 packet_types) { - BT_HDR *p; - UINT8 *pp; + BT_HDR *p = buffer; + UINT8 *pp = (UINT8 *)(p + 1); - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_CMD_HANDLE)) == NULL) - return (FALSE); + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_ACCEPT_ESCO; + p->offset = 0; - pp = (UINT8 *)(p + 1); + UINT16_TO_STREAM(pp, HCI_ACCEPT_ESCO_CONNECTION); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_ACCEPT_ESCO); + + BDADDR_TO_STREAM(pp, bd_addr); + UINT32_TO_STREAM(pp, tx_bw); + UINT32_TO_STREAM(pp, rx_bw); + UINT16_TO_STREAM(pp, max_latency); + UINT16_TO_STREAM(pp, content_fmt); + UINT8_TO_STREAM(pp, retrans_effort); + UINT16_TO_STREAM(pp, packet_types); + + btu_hcif_send_cmd(p); +} + +void btsnd_hcic_reject_esco_conn(void *buffer, BD_ADDR bd_addr, UINT8 reason) +{ + BT_HDR *p = buffer; + UINT8 *pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CMD_HANDLE; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_REJECT_ESCO; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_READ_RMT_VERSION_INFO); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_CMD_HANDLE); + UINT16_TO_STREAM(pp, HCI_REJECT_ESCO_CONNECTION); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_REJECT_ESCO); - UINT16_TO_STREAM (pp, handle); + BDADDR_TO_STREAM(pp, bd_addr); + UINT8_TO_STREAM(pp, reason); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); } -BOOLEAN btsnd_hcic_read_rmt_clk_offset (UINT16 handle) +BOOLEAN btsnd_hcic_hold_mode(void *buffer, UINT16 handle, + UINT16 max_hold_period, UINT16 min_hold_period) { BT_HDR *p; UINT8 *pp; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_CMD_HANDLE)) == NULL) - return (FALSE); + // ??? + if (!buffer + && (buffer = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_HOLD_MODE)) == NULL) + { + return FALSE; + } + p = buffer; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CMD_HANDLE; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_HOLD_MODE; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_READ_RMT_CLOCK_OFFSET); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_CMD_HANDLE); + UINT16_TO_STREAM(pp, HCI_HOLD_MODE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_HOLD_MODE); - UINT16_TO_STREAM (pp, handle); + UINT16_TO_STREAM(pp, handle); + UINT16_TO_STREAM(pp, max_hold_period); + UINT16_TO_STREAM(pp, min_hold_period); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_read_lmp_handle (UINT16 handle) +BOOLEAN btsnd_hcic_sniff_mode(void *buffer, UINT16 handle, + UINT16 max_sniff_period, UINT16 min_sniff_period, + UINT16 sniff_attempt, UINT16 sniff_timeout) { BT_HDR *p; UINT8 *pp; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_CMD_HANDLE)) == NULL) - return (FALSE); + if (!buffer + && (buffer = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_HOLD_MODE)) == NULL) + { + return FALSE; + } + p = buffer; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CMD_HANDLE; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_SNIFF_MODE; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_READ_LMP_HANDLE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_CMD_HANDLE); + UINT16_TO_STREAM(pp, HCI_SNIFF_MODE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SNIFF_MODE); - UINT16_TO_STREAM (pp, handle); + UINT16_TO_STREAM(pp, handle); + UINT16_TO_STREAM(pp, max_sniff_period); + UINT16_TO_STREAM(pp, min_sniff_period); + UINT16_TO_STREAM(pp, sniff_attempt); + UINT16_TO_STREAM(pp, sniff_timeout); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_setup_esco_conn (UINT16 handle, UINT32 tx_bw, - UINT32 rx_bw, UINT16 max_latency, UINT16 voice, - UINT8 retrans_effort, UINT16 packet_types) +BOOLEAN btsnd_hcic_exit_sniff_mode(void *buffer, UINT16 handle) { BT_HDR *p; UINT8 *pp; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_SETUP_ESCO)) == NULL) - return (FALSE); + if (!buffer + && (buffer = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_HOLD_MODE)) == NULL) + { + return FALSE; + } + p = buffer; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_SETUP_ESCO; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CMD_HANDLE; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_SETUP_ESCO_CONNECTION); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_SETUP_ESCO); + UINT16_TO_STREAM(pp, HCI_EXIT_SNIFF_MODE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_CMD_HANDLE); - UINT16_TO_STREAM (pp, handle); - UINT32_TO_STREAM (pp, tx_bw); - UINT32_TO_STREAM (pp, rx_bw); - UINT16_TO_STREAM (pp, max_latency); - UINT16_TO_STREAM (pp, voice); - UINT8_TO_STREAM (pp, retrans_effort); - UINT16_TO_STREAM (pp, packet_types); + UINT16_TO_STREAM(pp, handle); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_accept_esco_conn (BD_ADDR bd_addr, UINT32 tx_bw, - UINT32 rx_bw, UINT16 max_latency, - UINT16 content_fmt, UINT8 retrans_effort, - UINT16 packet_types) +BOOLEAN btsnd_hcic_park_mode(void *buffer, UINT16 handle, + UINT16 beacon_max_interval, + UINT16 beacon_min_interval) { BT_HDR *p; UINT8 *pp; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_ACCEPT_ESCO)) == NULL) - return (FALSE); + if (!buffer + && (buffer = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_HOLD_MODE)) == NULL) + { + return FALSE; + } + p = buffer; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_ACCEPT_ESCO; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_PARK_MODE; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_ACCEPT_ESCO_CONNECTION); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_ACCEPT_ESCO); + UINT16_TO_STREAM(pp, HCI_PARK_MODE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_PARK_MODE); - BDADDR_TO_STREAM (pp, bd_addr); - UINT32_TO_STREAM (pp, tx_bw); - UINT32_TO_STREAM (pp, rx_bw); - UINT16_TO_STREAM (pp, max_latency); - UINT16_TO_STREAM (pp, content_fmt); - UINT8_TO_STREAM (pp, retrans_effort); - UINT16_TO_STREAM (pp, packet_types); + UINT16_TO_STREAM(pp, handle); + UINT16_TO_STREAM(pp, beacon_max_interval); + UINT16_TO_STREAM(pp, beacon_min_interval); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_reject_esco_conn (BD_ADDR bd_addr, UINT8 reason) +BOOLEAN btsnd_hcic_exit_park_mode(void *buffer, UINT16 handle) { BT_HDR *p; UINT8 *pp; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_REJECT_ESCO)) == NULL) - return (FALSE); + if (!buffer + && (buffer = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_HOLD_MODE)) == NULL) + { + return FALSE; + } + p = buffer; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_REJECT_ESCO; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CMD_HANDLE; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_REJECT_ESCO_CONNECTION); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_REJECT_ESCO); + UINT16_TO_STREAM(pp, HCI_EXIT_PARK_MODE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_CMD_HANDLE); - BDADDR_TO_STREAM (pp, bd_addr); - UINT8_TO_STREAM (pp, reason); + UINT16_TO_STREAM(pp, handle); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_hold_mode (UINT16 handle, UINT16 max_hold_period, - UINT16 min_hold_period) + + +BOOLEAN btsnd_hcic_switch_role(BD_ADDR bd_addr, UINT8 role) { BT_HDR *p; UINT8 *pp; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_HOLD_MODE)) == NULL) - return (FALSE); + if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_SWITCH_ROLE)) == NULL) + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_HOLD_MODE; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_SWITCH_ROLE; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_HOLD_MODE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_HOLD_MODE); + UINT16_TO_STREAM(pp, HCI_SWITCH_ROLE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SWITCH_ROLE); - UINT16_TO_STREAM (pp, handle); - UINT16_TO_STREAM (pp, max_hold_period); - UINT16_TO_STREAM (pp, min_hold_period); + BDADDR_TO_STREAM(pp, bd_addr); + UINT8_TO_STREAM(pp, role); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_sniff_mode (UINT16 handle, UINT16 max_sniff_period, - UINT16 min_sniff_period, UINT16 sniff_attempt, - UINT16 sniff_timeout) + +BOOLEAN btsnd_hcic_write_policy_set(UINT16 handle, UINT16 settings) { BT_HDR *p; UINT8 *pp; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_SNIFF_MODE)) == NULL) - return (FALSE); + if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_POLICY_SET)) == NULL) + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_SNIFF_MODE; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_POLICY_SET; p->offset = 0; + UINT16_TO_STREAM(pp, HCI_WRITE_POLICY_SETTINGS); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_POLICY_SET); - UINT16_TO_STREAM (pp, HCI_SNIFF_MODE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_SNIFF_MODE); + UINT16_TO_STREAM(pp, handle); + UINT16_TO_STREAM(pp, settings); - UINT16_TO_STREAM (pp, handle); - UINT16_TO_STREAM (pp, max_sniff_period); - UINT16_TO_STREAM (pp, min_sniff_period); - UINT16_TO_STREAM (pp, sniff_attempt); - UINT16_TO_STREAM (pp, sniff_timeout); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_exit_sniff_mode (UINT16 handle) + + + + + +BOOLEAN btsnd_hcic_reset(void) { BT_HDR *p; UINT8 *pp; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_CMD_HANDLE)) == NULL) - return (FALSE); + if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_RESET)) == NULL) + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CMD_HANDLE; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_RESET; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_EXIT_SNIFF_MODE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_CMD_HANDLE); - - UINT16_TO_STREAM (pp, handle); + UINT16_TO_STREAM(pp, HCI_RESET); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_RESET); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); + btu_hcif_send_cmd(p); return TRUE; } -BOOLEAN btsnd_hcic_park_mode (UINT16 handle, UINT16 beacon_max_interval, - UINT16 beacon_min_interval) +void btsnd_hcic_set_event_filter(void *buffer, UINT8 filt_type, + UINT8 filt_cond_type, UINT8 *filt_cond, + UINT8 filt_cond_len) { - BT_HDR *p; - UINT8 *pp; + BT_HDR *p = buffer; + UINT8 *pp = (UINT8 *)(p + 1); - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_PARK_MODE)) == NULL) - return (FALSE); + p->offset = 0; - pp = (UINT8 *)(p + 1); + UINT16_TO_STREAM(pp, HCI_SET_EVENT_FILTER); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_PARK_MODE; - p->offset = 0; + if (filt_type) + { + p->len = (UINT16)(HCIC_PREAMBLE_SIZE + 2 + filt_cond_len); + UINT8_TO_STREAM(pp, (UINT8)(2 + filt_cond_len)); + + UINT8_TO_STREAM(pp, filt_type); + UINT8_TO_STREAM(pp, filt_cond_type); + + if (filt_cond_type == HCI_FILTER_COND_DEVICE_CLASS) + { + DEVCLASS_TO_STREAM(pp, filt_cond); + filt_cond += DEV_CLASS_LEN; + DEVCLASS_TO_STREAM(pp, filt_cond); + filt_cond += DEV_CLASS_LEN; + + filt_cond_len -= (2 * DEV_CLASS_LEN); + } + else if (filt_cond_type == HCI_FILTER_COND_BD_ADDR) + { + BDADDR_TO_STREAM(pp, filt_cond); + filt_cond += BD_ADDR_LEN; - UINT16_TO_STREAM (pp, HCI_PARK_MODE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_PARK_MODE); + filt_cond_len -= BD_ADDR_LEN; + } - UINT16_TO_STREAM (pp, handle); - UINT16_TO_STREAM (pp, beacon_max_interval); - UINT16_TO_STREAM (pp, beacon_min_interval); + if (filt_cond_len) + ARRAY_TO_STREAM(pp, filt_cond, filt_cond_len); + } + else + { + p->len = (UINT16)(HCIC_PREAMBLE_SIZE + 1); + UINT8_TO_STREAM(pp, 1); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + UINT8_TO_STREAM(pp, filt_type); + } + + btu_hcif_send_cmd(p); } -BOOLEAN btsnd_hcic_exit_park_mode (UINT16 handle) + + +BOOLEAN btsnd_hcic_write_pin_type(UINT8 type) { BT_HDR *p; UINT8 *pp; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_CMD_HANDLE)) == NULL) - return (FALSE); + if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_PARAM1)) == NULL) + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CMD_HANDLE; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM1; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_EXIT_PARK_MODE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_CMD_HANDLE); + UINT16_TO_STREAM(pp, HCI_WRITE_PIN_TYPE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_PARAM1); - UINT16_TO_STREAM (pp, handle); + UINT8_TO_STREAM(pp, type); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); + btu_hcif_send_cmd(p); return TRUE; } -BOOLEAN btsnd_hcic_qos_setup (UINT16 handle, UINT8 flags, UINT8 service_type, - UINT32 token_rate, UINT32 peak, UINT32 latency, - UINT32 delay_var) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_QOS_SETUP)) == NULL) - return (FALSE); - pp = (UINT8 *)(p + 1); +void btsnd_hcic_read_stored_key(void *buffer, BD_ADDR bd_addr, + BOOLEAN read_all_flag) +{ + BT_HDR *p = buffer; + UINT8 *pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_QOS_SETUP; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_STORED_KEY; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_QOS_SETUP); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_QOS_SETUP); + UINT16_TO_STREAM(pp, HCI_READ_STORED_LINK_KEY); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_READ_STORED_KEY); - UINT16_TO_STREAM (pp, handle); - UINT8_TO_STREAM (pp, flags); - UINT8_TO_STREAM (pp, service_type); - UINT32_TO_STREAM (pp, token_rate); - UINT32_TO_STREAM (pp, peak); - UINT32_TO_STREAM (pp, latency); - UINT32_TO_STREAM (pp, delay_var); + BDADDR_TO_STREAM(pp, bd_addr); + UINT8_TO_STREAM(pp, read_all_flag); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); } -BOOLEAN btsnd_hcic_role_discovery (UINT16 handle) +void btsnd_hcic_write_stored_key(void *buffer, UINT8 num_keys, BD_ADDR *bd_addr, + LINK_KEY *link_key) { - BT_HDR *p; - UINT8 *pp; + BT_HDR *p = buffer; + UINT8 *pp = (UINT8 *)(p + 1); + int j; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_CMD_HANDLE)) == NULL) - return (FALSE); + p->len = HCIC_PREAMBLE_SIZE + 1 + (num_keys * (BD_ADDR_LEN + LINK_KEY_LEN)); + p->offset = 0; - pp = (UINT8 *)(p + 1); + UINT16_TO_STREAM(pp, HCI_WRITE_STORED_LINK_KEY); + UINT8_TO_STREAM(pp, p->len - HCIC_PREAMBLE_SIZE); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CMD_HANDLE; - p->offset = 0; + if (num_keys > HCI_MAX_NUM_OF_LINK_KEYS_PER_CMD) + num_keys = HCI_MAX_NUM_OF_LINK_KEYS_PER_CMD; - UINT16_TO_STREAM (pp, HCI_ROLE_DISCOVERY); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_CMD_HANDLE); + UINT8_TO_STREAM(pp, num_keys); - UINT16_TO_STREAM (pp, handle); + for (j = 0; j < num_keys; j++) + { + BDADDR_TO_STREAM(pp, bd_addr[j]); + ARRAY16_TO_STREAM(pp, link_key[j]); + } - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); } -BOOLEAN btsnd_hcic_switch_role (BD_ADDR bd_addr, UINT8 role) +BOOLEAN btsnd_hcic_delete_stored_key(BD_ADDR bd_addr, BOOLEAN delete_all_flag) { BT_HDR *p; UINT8 *pp; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_SWITCH_ROLE)) == NULL) - return (FALSE); + if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_DELETE_STORED_KEY)) == NULL) + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_SWITCH_ROLE; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_DELETE_STORED_KEY; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_SWITCH_ROLE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_SWITCH_ROLE); + UINT16_TO_STREAM(pp, HCI_DELETE_STORED_LINK_KEY); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_DELETE_STORED_KEY); - BDADDR_TO_STREAM (pp, bd_addr); - UINT8_TO_STREAM (pp, role); + BDADDR_TO_STREAM(pp, bd_addr); + UINT8_TO_STREAM(pp, delete_all_flag); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_read_policy_set (UINT16 handle) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_CMD_HANDLE)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CMD_HANDLE; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_POLICY_SETTINGS); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_CMD_HANDLE); - - UINT16_TO_STREAM (pp, handle); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_write_policy_set (UINT16 handle, UINT16 settings) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_POLICY_SET)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_POLICY_SET; - p->offset = 0; - UINT16_TO_STREAM (pp, HCI_WRITE_POLICY_SETTINGS); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_WRITE_POLICY_SET); - - UINT16_TO_STREAM (pp, handle); - UINT16_TO_STREAM (pp, settings); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_read_def_policy_set (void) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_DEF_POLICY_SET)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_DEF_POLICY_SET; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_DEF_POLICY_SETTINGS); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_DEF_POLICY_SET); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_write_def_policy_set (UINT16 settings) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_DEF_POLICY_SET)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_DEF_POLICY_SET; - p->offset = 0; - UINT16_TO_STREAM (pp, HCI_WRITE_DEF_POLICY_SETTINGS); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_WRITE_DEF_POLICY_SET); - - UINT16_TO_STREAM (pp, settings); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_flow_specification(UINT16 handle, UINT8 flags, UINT8 flow_direct, - UINT8 service_type, UINT32 token_rate, - UINT32 token_bucket_size, UINT32 peak, - UINT32 latency) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_FLOW_SPEC)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_FLOW_SPEC; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_FLOW_SPECIFICATION); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_FLOW_SPEC); - - UINT16_TO_STREAM (pp, handle); - UINT8_TO_STREAM (pp, flags); - UINT8_TO_STREAM (pp, flow_direct); - UINT8_TO_STREAM (pp, service_type); - UINT32_TO_STREAM (pp, token_rate); - UINT32_TO_STREAM (pp, token_bucket_size); - UINT32_TO_STREAM (pp, peak); - UINT32_TO_STREAM (pp, latency); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_set_event_mask(UINT8 local_controller_id, BT_EVENT_MASK event_mask) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_SET_EVENT_MASK)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_SET_EVENT_MASK; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_SET_EVENT_MASK); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_SET_EVENT_MASK); - ARRAY8_TO_STREAM (pp, event_mask); - - btu_hcif_send_cmd (local_controller_id, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_set_event_mask_page_2 (UINT8 local_controller_id, BT_EVENT_MASK event_mask) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_SET_EVENT_MASK_PAGE_2)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_SET_EVENT_MASK_PAGE_2; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_SET_EVENT_MASK_PAGE_2); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_SET_EVENT_MASK_PAGE_2); - ARRAY8_TO_STREAM (pp, event_mask); - - btu_hcif_send_cmd (local_controller_id, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_reset (UINT8 local_controller_id) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_RESET)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_RESET; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_RESET); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_RESET); - - btu_hcif_send_cmd (local_controller_id, p); -/* If calling from LMP_TEST or ScriptEngine, then send HCI command immediately */ -#if (!defined (LMP_TEST) && !defined(BTISE)) - if (local_controller_id == LOCAL_BR_EDR_CONTROLLER_ID) - { - btm_acl_reset_paging (); - btm_acl_set_discing (FALSE); - } -#endif - return (TRUE); -} - -BOOLEAN btsnd_hcic_set_event_filter (UINT8 filt_type, UINT8 filt_cond_type, - UINT8 *filt_cond, UINT8 filt_cond_len) -{ - BT_HDR *p; - UINT8 *pp; - - /* Use buffer large enough to hold all sizes in this command */ - if ((p = HCI_GET_CMD_BUF(2 + filt_cond_len)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_SET_EVENT_FILTER); - - if (filt_type) - { - p->len = (UINT16)(HCIC_PREAMBLE_SIZE + 2 + filt_cond_len); - UINT8_TO_STREAM (pp, (UINT8)(2 + filt_cond_len)); - - UINT8_TO_STREAM (pp, filt_type); - UINT8_TO_STREAM (pp, filt_cond_type); - - if (filt_cond_type == HCI_FILTER_COND_DEVICE_CLASS) - { - DEVCLASS_TO_STREAM (pp, filt_cond); - filt_cond += DEV_CLASS_LEN; - DEVCLASS_TO_STREAM (pp, filt_cond); - filt_cond += DEV_CLASS_LEN; - - filt_cond_len -= (2 * DEV_CLASS_LEN); - } - else if (filt_cond_type == HCI_FILTER_COND_BD_ADDR) - { - BDADDR_TO_STREAM (pp, filt_cond); - filt_cond += BD_ADDR_LEN; - - filt_cond_len -= BD_ADDR_LEN; - } - - if (filt_cond_len) - ARRAY_TO_STREAM (pp, filt_cond, filt_cond_len); - } - else - { - p->len = (UINT16)(HCIC_PREAMBLE_SIZE + 1); - UINT8_TO_STREAM (pp, 1); - - UINT8_TO_STREAM (pp, filt_type); - } - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_flush (UINT8 local_controller_id, UINT16 handle) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_CMD_HANDLE)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CMD_HANDLE; - p->offset = 0; - UINT16_TO_STREAM (pp, HCI_FLUSH); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_CMD_HANDLE); - - UINT16_TO_STREAM (pp, handle); - - btu_hcif_send_cmd (local_controller_id, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_read_pin_type (void) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_PIN_TYPE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_write_pin_type (UINT8 type) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_PARAM1)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM1; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_WRITE_PIN_TYPE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_WRITE_PARAM1); - - UINT8_TO_STREAM (pp, type); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_new_unit_key (void) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_NEW_UNIT_KEY)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_NEW_UNIT_KEY; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_CREATE_NEW_UNIT_KEY); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_NEW_UNIT_KEY); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_read_stored_key (BD_ADDR bd_addr, BOOLEAN read_all_flag) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_STORED_KEY)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_STORED_KEY; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_STORED_LINK_KEY); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_STORED_KEY); - - BDADDR_TO_STREAM (pp, bd_addr); - UINT8_TO_STREAM (pp, read_all_flag); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_write_stored_key (UINT8 num_keys, BD_ADDR *bd_addr, - LINK_KEY *link_key) -{ - BT_HDR *p; - UINT8 *pp; - int j; - - if ((p = HCI_GET_CMD_BUF(1 + (num_keys * (BD_ADDR_LEN + LINK_KEY_LEN)))) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - - p->len = HCIC_PREAMBLE_SIZE + 1 + (num_keys * (BD_ADDR_LEN + LINK_KEY_LEN)); - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_WRITE_STORED_LINK_KEY); - UINT8_TO_STREAM (pp, p->len - HCIC_PREAMBLE_SIZE); - - if(num_keys > HCI_MAX_NUM_OF_LINK_KEYS_PER_CMMD) - num_keys = HCI_MAX_NUM_OF_LINK_KEYS_PER_CMMD; - - UINT8_TO_STREAM (pp, num_keys); - - for (j = 0; j < num_keys; j++) - { - BDADDR_TO_STREAM (pp, bd_addr[j]); - ARRAY16_TO_STREAM (pp, link_key[j]); - } - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_delete_stored_key (BD_ADDR bd_addr, BOOLEAN delete_all_flag) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_DELETE_STORED_KEY)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_DELETE_STORED_KEY; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_DELETE_STORED_LINK_KEY); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_DELETE_STORED_KEY); - - BDADDR_TO_STREAM (pp, bd_addr); - UINT8_TO_STREAM (pp, delete_all_flag); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_change_name (BD_NAME name) -{ - BT_HDR *p; - UINT8 *pp; - UINT16 len = strlen ((char *)name) + 1; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_CHANGE_NAME)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CHANGE_NAME; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_CHANGE_LOCAL_NAME); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_CHANGE_NAME); - - ARRAY_TO_STREAM (pp, name, len); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_read_name (void) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_LOCAL_NAME); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_read_conn_acc_tout (UINT8 local_controller_id) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_CONN_ACCEPT_TOUT); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); - - btu_hcif_send_cmd (local_controller_id, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_write_conn_acc_tout (UINT8 local_controller_id, UINT16 timeout) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_PARAM2)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM2; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_WRITE_CONN_ACCEPT_TOUT); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_WRITE_PARAM2); - - UINT16_TO_STREAM (pp, timeout); - - btu_hcif_send_cmd (local_controller_id, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_read_page_tout (void) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_PAGE_TOUT); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_write_page_tout (UINT16 timeout) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_PARAM2)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM2; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_WRITE_PAGE_TOUT); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_WRITE_PARAM2); - - UINT16_TO_STREAM (pp, timeout); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_read_scan_enable (void) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_SCAN_ENABLE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_write_scan_enable (UINT8 flag) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_PARAM1)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM1; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_WRITE_SCAN_ENABLE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_WRITE_PARAM1); - - UINT8_TO_STREAM (pp, flag); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_read_pagescan_cfg(void) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_PAGESCAN_CFG); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_write_pagescan_cfg(UINT16 interval, UINT16 window) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_PAGESCAN_CFG)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PAGESCAN_CFG; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_WRITE_PAGESCAN_CFG); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_WRITE_PAGESCAN_CFG); - - UINT16_TO_STREAM (pp, interval); - UINT16_TO_STREAM (pp, window); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_read_inqscan_cfg(void) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_INQUIRYSCAN_CFG); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_write_inqscan_cfg(UINT16 interval, UINT16 window) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_INQSCAN_CFG)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_INQSCAN_CFG; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_WRITE_INQUIRYSCAN_CFG); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_WRITE_INQSCAN_CFG); - - UINT16_TO_STREAM (pp, interval); - UINT16_TO_STREAM (pp, window); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_read_auth_enable (void) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_AUTHENTICATION_ENABLE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_write_auth_enable (UINT8 flag) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_PARAM1)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM1; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_WRITE_AUTHENTICATION_ENABLE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_WRITE_PARAM1); - - UINT8_TO_STREAM (pp, flag); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_read_encr_mode (void) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_ENCRYPTION_MODE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_write_encr_mode (UINT8 mode) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_PARAM1)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM1; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_WRITE_ENCRYPTION_MODE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_WRITE_PARAM1); - - UINT8_TO_STREAM (pp, mode); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_read_dev_class(void) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_CLASS_OF_DEVICE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_write_dev_class(DEV_CLASS dev_class) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_PARAM3)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM3; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_WRITE_CLASS_OF_DEVICE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_WRITE_PARAM3); - - DEVCLASS_TO_STREAM (pp, dev_class); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_read_voice_settings(void) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_VOICE_SETTINGS); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_write_voice_settings(UINT16 flags) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_PARAM2)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM2; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_WRITE_VOICE_SETTINGS); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_WRITE_PARAM2); - - UINT16_TO_STREAM (pp, flags); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_read_auto_flush_tout (UINT16 handle) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_CMD_HANDLE)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CMD_HANDLE; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_AUTO_FLUSH_TOUT); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_CMD_HANDLE); - - UINT16_TO_STREAM (pp, handle); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_write_auto_flush_tout (UINT16 handle, UINT16 tout) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_AUTO_FLUSH_TOUT)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_AUTO_FLUSH_TOUT; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_WRITE_AUTO_FLUSH_TOUT); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_WRITE_AUTO_FLUSH_TOUT); - - UINT16_TO_STREAM (pp, handle); - UINT16_TO_STREAM (pp, tout); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_read_num_bcast_xmit (void) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_NUM_BCAST_REXMITS); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_write_num_bcast_xmit (UINT8 num) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_PARAM1)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM1; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_WRITE_NUM_BCAST_REXMITS); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_WRITE_PARAM1); - - UINT8_TO_STREAM (pp, num); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_read_hold_mode_act (void) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_HOLD_MODE_ACTIVITY); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_write_hold_mode_act (UINT8 flags) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_PARAM1)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM1; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_WRITE_HOLD_MODE_ACTIVITY); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_WRITE_PARAM1); - - UINT8_TO_STREAM (pp, flags); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_read_tx_power (UINT16 handle, UINT8 type) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_TX_POWER)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_TX_POWER; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_TRANSMIT_POWER_LEVEL); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_TX_POWER); - - UINT16_TO_STREAM (pp, handle); - UINT8_TO_STREAM (pp, type); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_read_sco_flow_enable (void) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_SCO_FLOW_CTRL_ENABLE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_write_sco_flow_enable (UINT8 flag) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_PARAM1)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM1; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_WRITE_SCO_FLOW_CTRL_ENABLE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_WRITE_PARAM1); - - UINT8_TO_STREAM (pp, flag); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_set_host_flow_ctrl (UINT8 value) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_PARAM1)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM1; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_SET_HC_TO_HOST_FLOW_CTRL); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_WRITE_PARAM1); - - UINT8_TO_STREAM (pp, value); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_set_host_buf_size (UINT16 acl_len, UINT8 sco_len, - UINT16 acl_num, UINT16 sco_num) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_SET_HOST_BUF_SIZE)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_SET_HOST_BUF_SIZE; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_HOST_BUFFER_SIZE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_SET_HOST_BUF_SIZE); - - UINT16_TO_STREAM (pp, acl_len); - UINT8_TO_STREAM (pp, sco_len); - UINT16_TO_STREAM (pp, acl_num); - UINT16_TO_STREAM (pp, sco_num); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_host_num_xmitted_pkts (UINT8 num_handles, UINT16 *handle, - UINT16 *num_pkts) -{ - BT_HDR *p; - UINT8 *pp; - int j; - - if ((p = HCI_GET_CMD_BUF(1 + (num_handles * 4))) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + 1 + (num_handles * 4); - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_HOST_NUM_PACKETS_DONE); - UINT8_TO_STREAM (pp, p->len - HCIC_PREAMBLE_SIZE); - - UINT8_TO_STREAM (pp, num_handles); - - for (j = 0; j < num_handles; j++) - { - UINT16_TO_STREAM (pp, handle[j]); - UINT16_TO_STREAM (pp, num_pkts[j]); - } - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_read_link_super_tout (UINT8 local_controller_id, UINT16 handle) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_CMD_HANDLE)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CMD_HANDLE; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_LINK_SUPER_TOUT); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_CMD_HANDLE); - - UINT16_TO_STREAM (pp, handle); - - btu_hcif_send_cmd (local_controller_id, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_write_link_super_tout (UINT8 local_controller_id, UINT16 handle, UINT16 timeout) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_LINK_SUPER_TOUT)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_LINK_SUPER_TOUT; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_WRITE_LINK_SUPER_TOUT); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_WRITE_LINK_SUPER_TOUT); - - UINT16_TO_STREAM (pp, handle); - UINT16_TO_STREAM (pp, timeout); - - btu_hcif_send_cmd (local_controller_id, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_read_max_iac (void) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_NUM_SUPPORTED_IAC); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_read_cur_iac_lap (void) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_CURRENT_IAC_LAP); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_write_cur_iac_lap (UINT8 num_cur_iac, LAP * const iac_lap) -{ - BT_HDR *p; - UINT8 *pp; - int i; - - if ((p = HCI_GET_CMD_BUF(1 + (LAP_LEN * num_cur_iac))) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + 1 + (LAP_LEN * num_cur_iac); - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_WRITE_CURRENT_IAC_LAP); - UINT8_TO_STREAM (pp, p->len - HCIC_PREAMBLE_SIZE); - - UINT8_TO_STREAM (pp, num_cur_iac); - - for (i = 0; i < num_cur_iac; i++) - LAP_TO_STREAM (pp, iac_lap[i]); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_read_page_scan_per (void) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_PAGESCAN_PERIOD_MODE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_write_page_scan_per (UINT8 mode) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_PARAM1)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM1; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_WRITE_PAGESCAN_PERIOD_MODE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_WRITE_PARAM1); - - UINT8_TO_STREAM (pp, mode); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_read_page_scan_mode (void) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_PAGESCAN_MODE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_write_page_scan_mode (UINT8 mode) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_PARAM1)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM1; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_WRITE_PAGESCAN_MODE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_WRITE_PARAM1); - - UINT8_TO_STREAM (pp, mode); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -/****************************************** -** Lisbon Features -*******************************************/ -#if BTM_SSR_INCLUDED == TRUE - -BOOLEAN btsnd_hcic_sniff_sub_rate(UINT16 handle, UINT16 max_lat, - UINT16 min_remote_lat, UINT16 min_local_lat) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_SNIFF_SUB_RATE)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_SNIFF_SUB_RATE; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_SNIFF_SUB_RATE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_SNIFF_SUB_RATE); - - UINT16_TO_STREAM (pp, handle); - UINT16_TO_STREAM (pp, max_lat); - UINT16_TO_STREAM (pp, min_remote_lat); - UINT16_TO_STREAM (pp, min_local_lat); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} -#endif /* BTM_SSR_INCLUDED */ - -#if (BTM_EIR_SERVER_INCLUDED == TRUE) -/**** Extended Inquiry Response Commands ****/ -BOOLEAN btsnd_hcic_read_ext_inquiry_response (void) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_EXT_INQ_RESPONSE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -void btsnd_hcic_write_ext_inquiry_response (void *buffer, UINT8 fec_req) -{ - BT_HDR *p = (BT_HDR *)buffer; - UINT8 *pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_EXT_INQ_RESP; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_WRITE_EXT_INQ_RESPONSE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_EXT_INQ_RESP); - - UINT8_TO_STREAM (pp, fec_req); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); -} -#endif /* BTM_EIR_SERVER_INCLUDED == TRUE */ - -/**** Simple Pairing Commands ****/ -BOOLEAN btsnd_hcic_write_simple_pairing_mode (UINT8 mode) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_W_SIMP_PAIR)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_W_SIMP_PAIR; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_WRITE_SIMPLE_PAIRING_MODE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_W_SIMP_PAIR); - - UINT8_TO_STREAM (pp, mode); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_read_simple_pairing_mode (void) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_R_SIMP_PAIR)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_R_SIMP_PAIR; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_SIMPLE_PAIRING_MODE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_R_SIMP_PAIR); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_write_simp_pair_debug_mode(UINT8 debug_mode) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_SIMP_PAIR_DBUG)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_SIMP_PAIR_DBUG; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_WRITE_SIMP_PAIR_DEBUG_MODE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_SIMP_PAIR_DBUG); - - UINT8_TO_STREAM (pp, debug_mode); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_io_cap_req_reply (BD_ADDR bd_addr, UINT8 capability, - UINT8 oob_present, UINT8 auth_req) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_IO_CAP_RESP)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_IO_CAP_RESP; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_IO_CAPABILITY_RESPONSE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_IO_CAP_RESP); - - BDADDR_TO_STREAM (pp, bd_addr); - UINT8_TO_STREAM (pp, capability); - UINT8_TO_STREAM (pp, oob_present); - UINT8_TO_STREAM (pp, auth_req); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_io_cap_req_neg_reply (BD_ADDR bd_addr, UINT8 err_code) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_IO_CAP_NEG_REPLY)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_IO_CAP_NEG_REPLY; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_IO_CAP_REQ_NEG_REPLY); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_IO_CAP_NEG_REPLY); - - BDADDR_TO_STREAM (pp, bd_addr); - UINT8_TO_STREAM (pp, err_code); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_read_local_oob_data (void) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_R_LOCAL_OOB)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_R_LOCAL_OOB; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_LOCAL_OOB_DATA); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_R_LOCAL_OOB); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_user_conf_reply (BD_ADDR bd_addr, BOOLEAN is_yes) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_UCONF_REPLY)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_UCONF_REPLY; - p->offset = 0; - - if (!is_yes) - { - /* Negative reply */ - UINT16_TO_STREAM (pp, HCI_USER_CONF_VALUE_NEG_REPLY); - } - else - { - /* Confirmation */ - UINT16_TO_STREAM (pp, HCI_USER_CONF_REQUEST_REPLY); - } - - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_UCONF_REPLY); - - BDADDR_TO_STREAM (pp, bd_addr); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_user_passkey_reply (BD_ADDR bd_addr, UINT32 value) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_U_PKEY_REPLY)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_U_PKEY_REPLY; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_USER_PASSKEY_REQ_REPLY); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_U_PKEY_REPLY); - - BDADDR_TO_STREAM (pp, bd_addr); - UINT32_TO_STREAM (pp, value); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_user_passkey_neg_reply (BD_ADDR bd_addr) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_U_PKEY_NEG_REPLY)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_U_PKEY_NEG_REPLY; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_USER_PASSKEY_REQ_NEG_REPLY); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_U_PKEY_NEG_REPLY); - - BDADDR_TO_STREAM (pp, bd_addr); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_rem_oob_reply (BD_ADDR bd_addr, UINT8 *p_c, UINT8 *p_r) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_REM_OOB_REPLY)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_REM_OOB_REPLY; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_REM_OOB_DATA_REQ_REPLY); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_REM_OOB_REPLY); - - BDADDR_TO_STREAM (pp, bd_addr); - ARRAY16_TO_STREAM (pp, p_c); - ARRAY16_TO_STREAM (pp, p_r); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_rem_oob_neg_reply (BD_ADDR bd_addr) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_REM_OOB_NEG_REPLY)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_REM_OOB_NEG_REPLY; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_REM_OOB_DATA_REQ_NEG_REPLY); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_REM_OOB_NEG_REPLY); - - BDADDR_TO_STREAM (pp, bd_addr); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - - -BOOLEAN btsnd_hcic_read_inq_tx_power (void) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_R_TX_POWER)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_R_TX_POWER; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_INQ_TX_POWER_LEVEL); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_R_TX_POWER); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_write_inq_tx_power (INT8 level) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_W_TX_POWER)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_W_TX_POWER; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_WRITE_INQ_TX_POWER_LEVEL); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_W_TX_POWER); - - INT8_TO_STREAM (pp, level); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -#if 0 /* currently not been used */ -BOOLEAN btsnd_hcic_read_default_erroneous_data_rpt (void) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_R_ERR_DATA_RPT)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_R_ERR_DATA_RPT; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_ERRONEOUS_DATA_RPT); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_R_ERR_DATA_RPT); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} -#endif - -BOOLEAN btsnd_hcic_write_default_erroneous_data_rpt (UINT8 flag) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_W_ERR_DATA_RPT)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_W_ERR_DATA_RPT; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_WRITE_ERRONEOUS_DATA_RPT); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_W_ERR_DATA_RPT); - - UINT8_TO_STREAM (pp, flag); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_send_keypress_notif (BD_ADDR bd_addr, UINT8 notif) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_SEND_KEYPRESS_NOTIF)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_SEND_KEYPRESS_NOTIF; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_SEND_KEYPRESS_NOTIF); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_SEND_KEYPRESS_NOTIF); - - BDADDR_TO_STREAM (pp, bd_addr); - UINT8_TO_STREAM (pp, notif); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} - -/**** end of Simple Pairing Commands ****/ - -#if L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE -BOOLEAN btsnd_hcic_enhanced_flush (UINT16 handle, UINT8 packet_type) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_ENHANCED_FLUSH)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_ENHANCED_FLUSH; - p->offset = 0; - UINT16_TO_STREAM (pp, HCI_ENHANCED_FLUSH); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_ENHANCED_FLUSH); - - UINT16_TO_STREAM (pp, handle); - UINT8_TO_STREAM (pp, packet_type); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} -#endif - - -BOOLEAN btsnd_hcic_refresh_encryption_key (UINT16 handle) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_CMD_HANDLE)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CMD_HANDLE; - p->offset = 0; - UINT16_TO_STREAM (pp, HCI_REFRESH_ENCRYPTION_KEY); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_CMD_HANDLE); - - UINT16_TO_STREAM (pp, handle); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} -/************************* -** End of Lisbon Commands -**************************/ - -BOOLEAN btsnd_hcic_read_local_ver (UINT8 local_controller_id) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_LOCAL_VERSION_INFO); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); - - btu_hcif_send_cmd (local_controller_id, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_read_local_supported_cmds (UINT8 local_controller_id) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_LOCAL_SUPPORTED_CMDS); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); - - btu_hcif_send_cmd (local_controller_id, p); - return (TRUE); -} - -BOOLEAN btsnd_hcic_read_local_features (void) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; - p->offset = 0; - - UINT16_TO_STREAM (pp, HCI_READ_LOCAL_FEATURES); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_read_local_ext_features (UINT8 page_num) +void btsnd_hcic_change_name(void *buffer, BD_NAME name) { - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_LOCAL_EXT_FEATURES)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); + BT_HDR *p = buffer; + UINT8 *pp = (UINT8 *)(p + 1); + UINT16 len = strlen((char *)name) + 1; - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_LOCAL_EXT_FEATURES; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CHANGE_NAME; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_READ_LOCAL_EXT_FEATURES); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_LOCAL_EXT_FEATURES); + UINT16_TO_STREAM(pp, HCI_CHANGE_LOCAL_NAME); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_CHANGE_NAME); - UINT8_TO_STREAM (pp, page_num); + ARRAY_TO_STREAM(pp, name, len); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); } -BOOLEAN btsnd_hcic_read_buffer_size (void) -{ - BT_HDR *p; - UINT8 *pp; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); - pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; + +void btsnd_hcic_write_page_tout(void *buffer, UINT16 timeout) +{ + BT_HDR *p = buffer; + UINT8 *pp = (UINT8 *)(p + 1); + + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM2; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_READ_BUFFER_SIZE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); + UINT16_TO_STREAM(pp, HCI_WRITE_PAGE_TOUT); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_PARAM2); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} + UINT16_TO_STREAM(pp, timeout); -BOOLEAN btsnd_hcic_read_country_code (void) -{ - BT_HDR *p; - UINT8 *pp; + btu_hcif_send_cmd(p); +} - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); - pp = (UINT8 *)(p + 1); +void btsnd_hcic_write_scan_enable(void *buffer, UINT8 flag) +{ + BT_HDR *p = buffer; + UINT8 *pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM1; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_READ_COUNTRY_CODE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); + UINT16_TO_STREAM(pp, HCI_WRITE_SCAN_ENABLE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_PARAM1); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} + UINT8_TO_STREAM(pp, flag); -BOOLEAN btsnd_hcic_read_bd_addr (void) -{ - BT_HDR *p; - UINT8 *pp; + btu_hcif_send_cmd(p); +} - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); - pp = (UINT8 *)(p + 1); +void btsnd_hcic_write_pagescan_cfg(void *buffer, UINT16 interval, UINT16 window) +{ + BT_HDR *p = buffer; + UINT8 *pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PAGESCAN_CFG; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_READ_BD_ADDR); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); + UINT16_TO_STREAM(pp, HCI_WRITE_PAGESCAN_CFG); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_PAGESCAN_CFG); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} + UINT16_TO_STREAM(pp, interval); + UINT16_TO_STREAM(pp, window); -BOOLEAN btsnd_hcic_read_fail_contact_count (UINT8 local_controller_id, UINT16 handle) -{ - BT_HDR *p; - UINT8 *pp; + btu_hcif_send_cmd(p); +} - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_CMD_HANDLE)) == NULL) - return (FALSE); - pp = (UINT8 *)(p + 1); +void btsnd_hcic_write_inqscan_cfg(void *buffer, UINT16 interval, UINT16 window) +{ + BT_HDR *p = buffer; + UINT8 *pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CMD_HANDLE; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_INQSCAN_CFG; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_READ_FAILED_CONTACT_COUNT); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_CMD_HANDLE); + UINT16_TO_STREAM(pp, HCI_WRITE_INQUIRYSCAN_CFG); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_INQSCAN_CFG); - UINT16_TO_STREAM (pp, handle); + UINT16_TO_STREAM(pp, interval); + UINT16_TO_STREAM(pp, window); - btu_hcif_send_cmd (local_controller_id, p); - return (TRUE); + btu_hcif_send_cmd(p); } -BOOLEAN btsnd_hcic_reset_fail_contact_count (UINT8 local_controller_id, UINT16 handle) + +BOOLEAN btsnd_hcic_write_auth_enable(UINT8 flag) { BT_HDR *p; UINT8 *pp; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_CMD_HANDLE)) == NULL) - return (FALSE); + if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_PARAM1)) == NULL) + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CMD_HANDLE; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM1; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_RESET_FAILED_CONTACT_COUNT); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_CMD_HANDLE); + UINT16_TO_STREAM(pp, HCI_WRITE_AUTHENTICATION_ENABLE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_PARAM1); - UINT16_TO_STREAM (pp, handle); + UINT8_TO_STREAM(pp, flag); - btu_hcif_send_cmd (local_controller_id, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_get_link_quality (UINT16 handle) + +BOOLEAN btsnd_hcic_write_encr_mode(UINT8 mode) { BT_HDR *p; UINT8 *pp; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_CMD_HANDLE)) == NULL) - return (FALSE); + if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_PARAM1)) == NULL) + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CMD_HANDLE; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM1; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_GET_LINK_QUALITY); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_CMD_HANDLE); + UINT16_TO_STREAM(pp, HCI_WRITE_ENCRYPTION_MODE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_PARAM1); - UINT16_TO_STREAM (pp, handle); + UINT8_TO_STREAM(pp, mode); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_read_rssi (UINT16 handle) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_CMD_HANDLE)) == NULL) - return (FALSE); - pp = (UINT8 *)(p + 1); +void btsnd_hcic_write_dev_class(void *buffer, DEV_CLASS dev_class) +{ + BT_HDR *p = buffer; + UINT8 *pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CMD_HANDLE; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM3; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_READ_RSSI); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_CMD_HANDLE); + UINT16_TO_STREAM(pp, HCI_WRITE_CLASS_OF_DEVICE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_PARAM3); - UINT16_TO_STREAM (pp, handle); + DEVCLASS_TO_STREAM(pp, dev_class); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); } -BOOLEAN btsnd_hcic_read_loopback_mode (void) -{ - BT_HDR *p; - UINT8 *pp; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); - pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; +void btsnd_hcic_write_auto_flush_tout(void *buffer, UINT16 handle, UINT16 tout) +{ + BT_HDR *p = buffer; + UINT8 *pp = (UINT8 *)(p + 1); + + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_AUTO_FLUSH_TOUT; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_READ_LOOPBACK_MODE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); + UINT16_TO_STREAM(pp, HCI_WRITE_AUTO_FLUSH_TOUT); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_AUTO_FLUSH_TOUT); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + UINT16_TO_STREAM(pp, handle); + UINT16_TO_STREAM(pp, tout); + + btu_hcif_send_cmd(p); } -BOOLEAN btsnd_hcic_write_loopback_mode (UINT8 mode) -{ - BT_HDR *p; - UINT8 *pp; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_PARAM1)) == NULL) - return (FALSE); - pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM1; - p->offset = 0; - UINT16_TO_STREAM (pp, HCI_WRITE_LOOPBACK_MODE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_WRITE_PARAM1); - UINT8_TO_STREAM (pp, mode); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} -BOOLEAN btsnd_hcic_enable_test_mode (void) + +BOOLEAN btsnd_hcic_set_host_buf_size(UINT16 acl_len, UINT8 sco_len, + UINT16 acl_num, UINT16 sco_num) { BT_HDR *p; UINT8 *pp; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); + if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_SET_HOST_BUF_SIZE)) == NULL) + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_SET_HOST_BUF_SIZE; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_ENABLE_DEV_UNDER_TEST_MODE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); + UINT16_TO_STREAM(pp, HCI_HOST_BUFFER_SIZE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_HOST_BUF_SIZE); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + UINT16_TO_STREAM(pp, acl_len); + UINT8_TO_STREAM(pp, sco_len); + UINT16_TO_STREAM(pp, acl_num); + UINT16_TO_STREAM(pp, sco_num); + + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_write_afh_channel_assessment_mode (UINT8 mode) + + +BOOLEAN btsnd_hcic_write_link_super_tout(UINT16 handle, UINT16 timeout) { BT_HDR *p; UINT8 *pp; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_PARAM1)) == NULL) - return (FALSE); + if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_LINK_SUPER_TOUT)) == NULL) + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM1; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_LINK_SUPER_TOUT; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_WRITE_AFH_ASSESSMENT_MODE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_WRITE_PARAM1); + UINT16_TO_STREAM(pp, HCI_WRITE_LINK_SUPER_TOUT); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_LINK_SUPER_TOUT); - UINT8_TO_STREAM (pp, mode); + UINT16_TO_STREAM(pp, handle); + UINT16_TO_STREAM(pp, timeout); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_read_afh_channel_assessment_mode(void) -{ - BT_HDR *p; - UINT8 *pp; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); - pp = (UINT8 *)(p + 1); +void btsnd_hcic_write_cur_iac_lap(void *buffer, UINT8 num_cur_iac, + LAP * const iac_lap) +{ + BT_HDR *p = buffer; + UINT8 *pp = (UINT8 *)(p + 1); + int i; - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; + p->len = HCIC_PREAMBLE_SIZE + 1 + (LAP_LEN * num_cur_iac); p->offset = 0; - UINT16_TO_STREAM (pp, HCI_READ_AFH_ASSESSMENT_MODE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); + UINT16_TO_STREAM(pp, HCI_WRITE_CURRENT_IAC_LAP); + UINT8_TO_STREAM(pp, p->len - HCIC_PREAMBLE_SIZE); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} + UINT8_TO_STREAM(pp, num_cur_iac); -BOOLEAN btsnd_hcic_set_afh_channels (UINT8 first, UINT8 last) -{ - BT_HDR *p; - UINT8 *pp; - UINT8 channels[10] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}; - int i; + for (i = 0; i < num_cur_iac; i++) + LAP_TO_STREAM(pp, iac_lap[i]); + + btu_hcif_send_cmd(p); +} - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_SET_AFH_CHANNELS)) == NULL) - return (FALSE); - pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_SET_AFH_CHANNELS; - p->offset = 0; - UINT16_TO_STREAM (pp, HCI_SET_AFH_CHANNELS); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_SET_AFH_CHANNELS); - /* Just make sure that caller did not exceed 79 Bluetooth channels */ - if ((first <= last) && (last <= 78)) - { - for (i = first; i <= last; i++) - { - int byte_offset = i / 8; - int bit_offset = i % 8; - channels[byte_offset] &= ~(1 << bit_offset); - } - } - for (i = 0; i < 10; i++) - *pp++ = channels[i]; - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} -BOOLEAN btsnd_hcic_set_afh_host_channel_class (UINT8 *p_afhchannelmap) +BOOLEAN btsnd_hcic_read_local_ver(void) { BT_HDR *p; UINT8 *pp; - int i; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_SET_AFH_CHANNELS)) == NULL) - return (FALSE); + if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_SET_AFH_CHANNELS; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_SET_AFH_CHANNELS); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_SET_AFH_CHANNELS); - - /* Copy and convert */ - for (i = 0; i < 10; i++) - *pp++ = p_afhchannelmap[9-i]; + UINT16_TO_STREAM(pp, HCI_READ_LOCAL_VERSION_INFO); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_READ_CMD); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_read_afh_channel_map (UINT16 handle) + +BOOLEAN btsnd_hcic_read_local_features(void) { BT_HDR *p; UINT8 *pp; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_CMD_HANDLE)) == NULL) - return (FALSE); + if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CMD_HANDLE; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_READ_AFH_CH_MAP); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_CMD_HANDLE); - - UINT16_TO_STREAM (pp, handle); + UINT16_TO_STREAM(pp, HCI_READ_LOCAL_FEATURES); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_READ_CMD); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_read_clock (UINT16 handle, UINT8 which_clock) -{ - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CLOCK)) == NULL) - return (FALSE); - pp = (UINT8 *)(p + 1); +void btsnd_hcic_read_buffer_size(void *buffer) +{ + BT_HDR *p = buffer; + UINT8 *pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CLOCK; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_READ_CLOCK); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CLOCK); + UINT16_TO_STREAM(pp, HCI_READ_BUFFER_SIZE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_READ_CMD); - UINT16_TO_STREAM (pp, handle); - UINT8_TO_STREAM (pp, which_clock); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); } -BOOLEAN btsnd_hcic_read_inqscan_type(void) + +BOOLEAN btsnd_hcic_read_bd_addr(void) { BT_HDR *p; UINT8 *pp; if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_READ_INQSCAN_TYPE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); + UINT16_TO_STREAM(pp, HCI_READ_BD_ADDR); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_READ_CMD); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_write_inqscan_type (UINT8 type) + + +BOOLEAN btsnd_hcic_get_link_quality(UINT16 handle) { BT_HDR *p; UINT8 *pp; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_PARAM1)) == NULL) - return (FALSE); + if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_CMD_HANDLE)) == NULL) + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM1; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CMD_HANDLE; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_WRITE_INQSCAN_TYPE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_WRITE_PARAM1); + UINT16_TO_STREAM(pp, HCI_GET_LINK_QUALITY); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_CMD_HANDLE); - UINT8_TO_STREAM (pp, type); + UINT16_TO_STREAM(pp, handle); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); + return TRUE; } -BOOLEAN btsnd_hcic_read_inquiry_mode (void) +BOOLEAN btsnd_hcic_read_rssi(UINT16 handle) { BT_HDR *p; UINT8 *pp; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); + if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_CMD_HANDLE)) == NULL) + return FALSE; pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CMD_HANDLE; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_READ_INQUIRY_MODE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); - - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} + UINT16_TO_STREAM(pp, HCI_READ_RSSI); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_CMD_HANDLE); -BOOLEAN btsnd_hcic_write_inquiry_mode (UINT8 mode) -{ - BT_HDR *p; - UINT8 *pp; + UINT16_TO_STREAM(pp, handle); - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_PARAM1)) == NULL) - return (FALSE); + btu_hcif_send_cmd(p); + return TRUE; +} - pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM1; - p->offset = 0; - UINT16_TO_STREAM (pp, HCI_WRITE_INQUIRY_MODE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_WRITE_PARAM1); - UINT8_TO_STREAM (pp, mode); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); -} -BOOLEAN btsnd_hcic_read_pagescan_type (void) +BOOLEAN btsnd_hcic_set_afh_channels(UINT8 first, UINT8 last) { BT_HDR *p; - UINT8 *pp; + UINT8 *pp; + UINT8 channels[10] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}; + int i; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) + if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_SET_AFH_CHANNELS)) == NULL) return (FALSE); pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_SET_AFH_CHANNELS; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_READ_PAGESCAN_TYPE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); + UINT16_TO_STREAM (pp, HCI_SET_AFH_CHANNELS); + UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_SET_AFH_CHANNELS); + + /* Just make sure that caller did not exceed 79 Bluetooth channels */ + if ((first <= last) && (last <= 78)) + { + for (i = first; i <= last; i++) + { + int byte_offset = i / 8; + int bit_offset = i % 8; + channels[byte_offset] &= ~(1 << bit_offset); + } + } + for (i = 0; i < 10; i++) + *pp++ = channels[i]; - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); + btu_hcif_send_cmd (p); return (TRUE); } -BOOLEAN btsnd_hcic_write_pagescan_type (UINT8 type) -{ - BT_HDR *p; - UINT8 *pp; - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_PARAM1)) == NULL) - return (FALSE); - pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM1; + +void btsnd_hcic_write_inqscan_type(void *buffer, UINT8 type) +{ + BT_HDR *p = buffer; + UINT8 *pp = (UINT8 *)(p + 1); + + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM1; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_WRITE_PAGESCAN_TYPE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_WRITE_PARAM1); + UINT16_TO_STREAM(pp, HCI_WRITE_INQSCAN_TYPE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_PARAM1); - UINT8_TO_STREAM (pp, type); + UINT8_TO_STREAM(pp, type); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); } -/* Must have room to store BT_HDR + max VSC length + callback pointer */ -#if !defined (LMP_TEST) && (HCI_CMD_POOL_BUF_SIZE < 268) -#error "HCI_CMD_POOL_BUF_SIZE must be larger than 268" -#endif -void btsnd_hcic_vendor_spec_cmd (void *buffer, UINT16 opcode, UINT8 len, - UINT8 *p_data, void *p_cmd_cplt_cback) +void btsnd_hcic_write_inquiry_mode(void *buffer, UINT8 mode) { - BT_HDR *p = (BT_HDR *)buffer; + BT_HDR *p = buffer; UINT8 *pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + len; - p->offset = sizeof(void *); + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM1; + p->offset = 0; - *((void **)pp) = p_cmd_cplt_cback; /* Store command complete callback in buffer */ - pp += sizeof(void *); /* Skip over callback pointer */ + UINT16_TO_STREAM(pp, HCI_WRITE_INQUIRY_MODE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_PARAM1); - UINT16_TO_STREAM (pp, HCI_GRP_VENDOR_SPECIFIC | opcode); - UINT8_TO_STREAM (pp, len); - ARRAY_TO_STREAM (pp, p_data, len); + UINT8_TO_STREAM(pp, mode); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); + btu_hcif_send_cmd(p); } -void btsnd_hcic_data (BT_HDR *p_buf, UINT16 len, UINT16 handle, UINT8 boundary, UINT8 broadcast) + +void btsnd_hcic_write_pagescan_type(void *buffer, UINT8 type) { - UINT8 *p; + BT_HDR *p = buffer; + UINT8 *pp = (UINT8 *)(p + 1); - /* Higher layer should have left 4 bytes for us to fill the header */ - p_buf->offset -= 4; - p_buf->len += 4; + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM1; + p->offset = 0; - /* Find the pointer to the beginning of the data */ - p = (UINT8 *)(p_buf + 1) + p_buf->offset; + UINT16_TO_STREAM(pp, HCI_WRITE_PAGESCAN_TYPE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_PARAM1); - UINT16_TO_STREAM (p, handle | ((boundary & 3) << 12) | ((broadcast & 3) << 14)); - UINT16_TO_STREAM (p, len); + UINT8_TO_STREAM(pp, type); - HCI_ACL_DATA_TO_LOWER (p_buf); + btu_hcif_send_cmd(p); } -BOOLEAN btsnd_hcic_nop (void) +void btsnd_hcic_vendor_spec_cmd(void *buffer, UINT16 opcode, UINT8 len, + UINT8 *p_data) { - BT_HDR *p; - UINT8 *pp; - - if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL) - return (FALSE); - - pp = (UINT8 *)(p + 1); + BT_HDR *p = buffer; + UINT8 *pp = (UINT8 *)(p + 1); - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; + p->len = HCIC_PREAMBLE_SIZE + len; p->offset = 0; - UINT16_TO_STREAM (pp, HCI_COMMAND_NONE); - UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD); + UINT16_TO_STREAM(pp, HCI_GROUP_VENDOR_SPECIFIC | opcode); + UINT8_TO_STREAM(pp, len); + ARRAY_TO_STREAM(pp, p_data, len); - btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); - return (TRUE); + btu_hcif_send_cmd(p); } + + +__declspec(section ".rodata") const UINT8 hcicmds_rodata_pad[4] = {0}; diff --git a/src/revolution/BTE/stack/hid/hidd_api.c b/src/revolution/BTE/stack/hid/hidd_api.c new file mode 100644 index 0000000..103660f --- /dev/null +++ b/src/revolution/BTE/stack/hid/hidd_api.c @@ -0,0 +1,44 @@ +#include "hidd_api.h" + +#include + +#include // ARRAY_LENGTH + +#include "bt_trace.h" +#include "bt_types.h" +#include "data_types.h" +#include "wcassert.h" // WCAssert_Line + +#include "btm_api.h" +#include "gki.h" +#include "hiddefs.h" +#include "hidd_int.h" +#include "sdp_api.h" + +static UINT8 const HidDevLangList[8] = {53, 6, 9, 4, 9, 9, 1, 0}; + + +void HID_DevInit(void) +{ + memset(&hd_cb, 0, sizeof hd_cb); + + hd_cb.l2cap_ctrl_cfg.mtu_present = TRUE; + hd_cb.l2cap_ctrl_cfg.mtu = 64; + + hd_cb.l2cap_int_cfg.mtu_present = TRUE; + hd_cb.l2cap_int_cfg.mtu = 64; + + hd_cb.conn.timer_entry.param = + (TIMER_PARAM_TYPE)&hidd_proc_repage_timeout; + + hd_cb.trace_level = BT_TRACE_LEVEL_NONE; +} + + + + + + + + + diff --git a/src/revolution/BTE/stack/hid/hidd_conn.c b/src/revolution/BTE/stack/hid/hidd_conn.c new file mode 100644 index 0000000..5486692 --- /dev/null +++ b/src/revolution/BTE/stack/hid/hidd_conn.c @@ -0,0 +1,56 @@ +#include "hidd_int.h" + +#include + +#include "bt_trace.h" +#include "bt_types.h" +#include "data_types.h" + +#include "btm_api.h" // BTM_SetQoS +#include "btm_int.h" +#include "gki.h" // GKI_freebuf +#include "hid_conn.h" +#include "hidd_api.h" +#include "hiddefs.h" +#include "l2c_api.h" + +char hidd_conn_trace_originate[0x18] = "HID - Originate started"; +char hidd_conn_trace_originate_failed[0x18] = "HID - Originate failed"; + + + + + +tHID_STATUS hidd_conn_initiate(void) +{ + tHID_CONN *p_hcon = &hd_cb.conn; + + HIDD_TRACE(EVENT, hidd_conn_trace_originate); + + p_hcon->ctrl_cid = 0; + p_hcon->intr_cid = 0; + p_hcon->conn_flags = HID_CONN_FLAGS_IS_ORIG; + + if ((p_hcon->ctrl_cid = L2CA_ConnectReq(17, hd_cb.host_addr)) == 0) + { + HIDD_TRACE(WARNING, hidd_conn_trace_originate_failed); + return HID_ERR_L2CAP_FAILED; + } + else + { + p_hcon->conn_state = HID_CONN_STATE_CONNECTING_CTRL; + return HID_SUCCESS; + } +} + + + + + + + + + + + + diff --git a/src/revolution/BTE/stack/hid/hidd_mgmt.c b/src/revolution/BTE/stack/hid/hidd_mgmt.c new file mode 100644 index 0000000..10e4f0a --- /dev/null +++ b/src/revolution/BTE/stack/hid/hidd_mgmt.c @@ -0,0 +1,51 @@ +#include "hidd_int.h" + +#include + +#include "bt_trace.h" +#include "bt_types.h" +#include "data_types.h" + +#include "btu.h" +#include "hiddefs.h" +#include "hidd_api.h" + +static tHID_STATUS hidd_no_conn_proc_evt(UINT8 event, void *p_data); +static tHID_STATUS hidd_connecting_proc_evt(UINT8 event, void *p_data); +static tHID_STATUS hidd_connected_proc_evt(UINT8 event, void *p_data); +static tHID_STATUS hidd_disc_ing_proc_evt(UINT8 event, void *p_data); + + +tHID_DEV_CTB hd_cb; + + + +char hidd_mgmt_trace_repage[0x20] = "hidd_proc_repage_timeout"; + +void hidd_proc_repage_timeout(void) +{ + HIDD_TRACE(DEBUG, hidd_mgmt_trace_repage); + + ++hd_cb.conn_tries; + + if (hidd_conn_initiate()) + { + if (hd_cb.conn_tries > 15) + { + hd_cb.dev_state = 0; + (*hd_cb.callback)(1, 0, NULL); + } + else + { + btu_start_timer(&hd_cb.conn.timer_entry, 22, 1); + } + } + else + { + (*hd_cb.callback)(2, hd_cb.conn_tries, NULL); + } +} + + + + diff --git a/src/revolution/BTE/stack/hid/hidd_pm.c b/src/revolution/BTE/stack/hid/hidd_pm.c new file mode 100644 index 0000000..07ae035 --- /dev/null +++ b/src/revolution/BTE/stack/hid/hidd_pm.c @@ -0,0 +1,169 @@ +#include "hidd_int.h" + +#include + +#include + +#include "data_types.h" + +#include "btm_api.h" +#include "btu.h" +#include "gki.h" +#include "hidd_api.h" + +static tHID_DEV_PWR_MD const pwr_modes[3] = +{ + {320, 160, 10, 20, 0}, + {320, 160, 10, 20, 2}, + {640, 320, 0, 0, 3}, +}; + + +UINT8 hidd_pm_set_now(tHID_DEV_PWR_MD *p_req_mode) +{ + tHID_DEV_PWR_MD act_pm = {0}; + tBTM_STATUS st = 0; + + if (hd_cb.pm_ctrl_busy + || (p_req_mode->mode == hd_cb.curr_pm.mode + && (p_req_mode->mode == 0 + || (hd_cb.curr_pm.interval >= p_req_mode->min + && hd_cb.curr_pm.interval <= p_req_mode->max)))) + { + hd_cb.final_pm.mode = 0xff; + return 1; + } + + switch (p_req_mode->mode) + { + case 0: + if (hd_cb.curr_pm.mode == 2) + { + st = BTM_SetPowerMode(0x80, hd_cb.host_addr, + (tBTM_PM_PWR_MD *)&act_pm); + hd_cb.pm_ctrl_busy = TRUE; + } + else if (hd_cb.curr_pm.mode == 3) + { + st = BTM_SetPowerMode(0x80, hd_cb.host_addr, + (tBTM_PM_PWR_MD *)&act_pm); + hd_cb.pm_ctrl_busy = TRUE; + } + + break; + + case 2: + if (hd_cb.curr_pm.mode != 0) + { + hidd_pm_set_now(&act_pm); + } + else + { + st = BTM_SetPowerMode(0x80, hd_cb.host_addr, + (tBTM_PM_PWR_MD *)p_req_mode); + hd_cb.pm_ctrl_busy = TRUE; + } + + break; + + case 3: + if (hd_cb.curr_pm.mode != 0) + { + hidd_pm_set_now(&act_pm); + } + else + { + st = BTM_SetPowerMode(0x80, hd_cb.host_addr, + (tBTM_PM_PWR_MD *)p_req_mode); + hd_cb.pm_ctrl_busy = TRUE; + } + + break; + } + + if (st == 0 || st == 1) + return 1; + + st += 55; + + if (hd_cb.callback) + (*hd_cb.callback)(4, hd_cb.conn_substate, + (tHID_DEV_REG_INFO_CBACK_DATA *)&st); + + return 0; +} + +static UINT8 hidd_pm_set_power_mode(tHID_DEV_PWR_MD *p_req_mode) +{ + memcpy(&hd_cb.final_pm, p_req_mode, sizeof hd_cb.final_pm); + + return hidd_pm_set_now(p_req_mode); +} + +void hidd_pm_proc_mode_change(UINT8 hci_status, UINT8 mode, UINT16 interval) +{ + if (!hd_cb.reg_flag) + return; + + hd_cb.pm_ctrl_busy = FALSE; + + if (hci_status != 0) + { + if (!hd_cb.callback) + return; + + (*hd_cb.callback)(4, hd_cb.conn_substate, + (tHID_DEV_REG_INFO_CBACK_DATA *)&hci_status); + + return; + } + + hd_cb.curr_pm.mode = mode; + hd_cb.curr_pm.interval = interval; + + if (hd_cb.final_pm.mode != 0xff) + { + if (hd_cb.final_pm.mode != hd_cb.curr_pm.mode + || (hd_cb.final_pm.mode != 0 + && (hd_cb.curr_pm.interval < hd_cb.final_pm.min + || hd_cb.curr_pm.interval > hd_cb.final_pm.max))) + { + hidd_pm_set_now(&hd_cb.final_pm); + } + else + { + hd_cb.final_pm.mode = 0xff; + } + } + else if (hd_cb.curr_pm.mode == 0) + { + hidd_pm_start(); + } + + if (hd_cb.callback) + { + (*hd_cb.callback)(3, mode, + (tHID_DEV_REG_INFO_CBACK_DATA *)&interval); + } +} + +void hidd_pm_inact_timeout(void) +{ + hidd_pm_set_power_mode(&hd_cb.pm_params[1]); + + hd_cb.conn_substate = 1; +} + +static UINT8 hidd_pm_start(void) +{ + hidd_pm_set_power_mode(&hd_cb.pm_params[0]); + + hd_cb.conn_substate = 0; + + hd_cb.idle_tle.param = (TIMER_PARAM_TYPE)&hidd_pm_inact_timeout; + btu_start_timer(&hd_cb.idle_tle, 22, 60); + + return 0; +} + + diff --git a/src/revolution/BTE/stack/hid/hidh_api.c b/src/revolution/BTE/stack/hid/hidh_api.c index eaa98f0..dc60175 100644 --- a/src/revolution/BTE/stack/hid/hidh_api.c +++ b/src/revolution/BTE/stack/hid/hidh_api.c @@ -16,531 +16,451 @@ * ******************************************************************************/ +/* Original source: + * bluedroid + * stack/hid/hidh_api.c + */ + +/* Includes changes by muff1n1634 and for this repository (KoopTheKoopa) */ + /****************************************************************************** * - * This file contains the HID HOST API entry points + * This file contains the HID host API functions. * ******************************************************************************/ -#include +#include "hidh_api.h" + #include -#include -#include "gki.h" + +#include "bt_target.h" +#include "bt_trace.h" #include "bt_types.h" -#include "hiddefs.h" -#include "hidh_api.h" -#include "hidh_int.h" +#include "data_types.h" + #include "btm_api.h" #include "btu.h" +#include "gki.h" +#include "hiddefs.h" +#include "hid_conn.h" +#include "hidh_int.h" +#include "sdp_api.h" +#include "sdpdefs.h" + +static void hidh_search_callback(UINT16 sdp_result); -#if HID_DYNAMIC_MEMORY == FALSE -tHID_HOST_CTB hh_cb; -#endif - -static void hidh_search_callback (UINT16 sdp_result); - -/******************************************************************************* -** -** Function HID_HostGetSDPRecord -** -** Description This function reads the device SDP record -** -** Returns tHID_STATUS -** -*******************************************************************************/ -tHID_STATUS HID_HostGetSDPRecord ( BD_ADDR addr, tSDP_DISCOVERY_DB *p_db, UINT32 db_len, - tHID_HOST_SDP_CALLBACK *sdp_cback ) +tHID_HOST_CTB hh_cb; + +tHID_STATUS HID_HostGetSDPRecord(BD_ADDR addr, tSDP_DISCOVERY_DB *p_db, + UINT32 db_len, + tHID_HOST_SDP_CALLBACK *sdp_cback) { - tSDP_UUID uuid_list; + tSDP_UUID uuid_list; - if( hh_cb.sdp_busy ) + if (hh_cb.sdp_busy) return HID_ERR_SDP_BUSY; - uuid_list.len = 2; + uuid_list.len = LEN_UUID_16; uuid_list.uu.uuid16 = UUID_SERVCLASS_HUMAN_INTERFACE; hh_cb.p_sdp_db = p_db; - SDP_InitDiscoveryDb (p_db, db_len, 1, &uuid_list, 0, NULL); + SDP_InitDiscoveryDb(p_db, db_len, 1, &uuid_list, 0, NULL); - if (SDP_ServiceSearchRequest (addr, p_db, hidh_search_callback)) + if (SDP_ServiceSearchRequest(addr, p_db, &hidh_search_callback)) { - hh_cb.sdp_cback = sdp_cback ; + hh_cb.sdp_cback = sdp_cback; hh_cb.sdp_busy = TRUE; + return HID_SUCCESS; } else + { return HID_ERR_NO_RESOURCES; + } } -void hidh_get_str_attr( tSDP_DISC_REC *p_rec, UINT16 attr_id, UINT16 max_len, char *str ) +static void hidh_get_str_attr(tSDP_DISC_REC *p_rec, UINT16 attr_id, UINT16 max_len, + char *str) { - tSDP_DISC_ATTR *p_attr; - UINT16 name_len; + tSDP_DISC_ATTR *p_attr; + UINT16 name_len; if ((p_attr = SDP_FindAttributeInRec(p_rec, attr_id)) != NULL) { - if((name_len = SDP_DISC_ATTR_LEN(p_attr->attr_len_type)) < max_len ) + if ((name_len = SDP_DISC_ATTR_LEN(p_attr->attr_len_type)) < max_len) { - memcpy( str, (char *) p_attr->attr_value.v.array, name_len ); + memcpy(str, p_attr->attr_value.v.array, name_len); str[name_len] = '\0'; } else { - memcpy( str, (char *) p_attr->attr_value.v.array, max_len-1 ); + memcpy(str, p_attr->attr_value.v.array, max_len - 1); str[max_len] = '\0'; } } else + { str[0] = '\0'; + } } - -static void hidh_search_callback (UINT16 sdp_result) +static void hidh_search_callback(UINT16 sdp_result) { - tSDP_DISCOVERY_DB *p_db = hh_cb.p_sdp_db; - tSDP_DISC_REC *p_rec; - tSDP_DISC_ATTR *p_attr, *p_subattr1, *p_subattr2, *p_repdesc; - tBT_UUID hid_uuid; - tHID_DEV_SDP_INFO *p_nvi = &hh_cb.sdp_rec; - UINT16 attr_mask = 0; - - hid_uuid.len = LEN_UUID_16; + tSDP_DISCOVERY_DB *p_db = hh_cb.p_sdp_db; + tSDP_DISC_REC *p_rec; + tSDP_DISC_ATTR *p_attr; + tSDP_DISC_ATTR *p_subattr1; + tSDP_DISC_ATTR *p_subattr2; + tSDP_DISC_ATTR *p_repdesc; + tBT_UUID hid_uuid; + tHID_DEV_SDP_INFO *p_nvi = &hh_cb.sdp_rec; + UINT16 attr_mask = 0; + + hid_uuid.len = LEN_UUID_16; hid_uuid.uu.uuid16 = UUID_SERVCLASS_HUMAN_INTERFACE; hh_cb.sdp_busy = FALSE; if (sdp_result != SDP_SUCCESS) { - hh_cb.sdp_cback(sdp_result, 0, NULL); + (*hh_cb.sdp_cback)(sdp_result, 0, NULL); return; } - if ((p_rec = SDP_FindServiceUUIDInDb (p_db, &hid_uuid, NULL)) == NULL) + if ((p_rec = SDP_FindServiceUUIDInDb(p_db, &hid_uuid, NULL)) == NULL) { - hh_cb.sdp_cback(HID_SDP_NO_SERV_UUID, 0, NULL); + (*hh_cb.sdp_cback)(HID_SDP_NO_SERV_UUID, 0, NULL); return; } - memset (&hh_cb.sdp_rec, 0, sizeof( tHID_DEV_SDP_INFO )); + memset(&hh_cb.sdp_rec, 0, sizeof hh_cb.sdp_rec); - /* First, verify the mandatory fields we care about */ - if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_DESCRIPTOR_LIST)) == NULL) - || (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) != DATA_ELE_SEQ_DESC_TYPE) - || ((p_subattr1 = p_attr->attr_value.v.p_sub_attr) == NULL) - || (SDP_DISC_ATTR_TYPE(p_subattr1->attr_len_type) != DATA_ELE_SEQ_DESC_TYPE) - || ((p_subattr2 = p_subattr1->attr_value.v.p_sub_attr) == NULL) - || ((p_repdesc = p_subattr2->p_next_attr) == NULL) - || (SDP_DISC_ATTR_TYPE(p_repdesc->attr_len_type) != TEXT_STR_DESC_TYPE)) + if (((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_HID_DESCRIPTOR_LIST)) + == NULL) + || SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) != DATA_ELE_SEQ_DESC_TYPE + || ((p_subattr1 = p_attr->attr_value.v.p_sub_attr) == NULL) + || SDP_DISC_ATTR_TYPE(p_subattr1->attr_len_type) + != DATA_ELE_SEQ_DESC_TYPE + || ((p_subattr2 = p_subattr1->attr_value.v.p_sub_attr) == NULL) + || ((p_repdesc = p_subattr2->p_next_attr) == NULL) + || SDP_DISC_ATTR_TYPE(p_repdesc->attr_len_type) != TEXT_STR_DESC_TYPE) { - hh_cb.sdp_cback(HID_SDP_MANDATORY_MISSING, 0, NULL); + (*hh_cb.sdp_cback)(HID_SDP_MANDATORY_MISSING, 0, NULL); return; } - if ((p_nvi->dscp_info.dl_len = SDP_DISC_ATTR_LEN(p_repdesc->attr_len_type)) != 0) - p_nvi->dscp_info.dsc_list = (UINT8 *) &p_repdesc->attr_value; + if ((p_nvi->dscp_info.dl_len = SDP_DISC_ATTR_LEN(p_repdesc->attr_len_type)) + != 0) + { + p_nvi->dscp_info.dsc_list = (UINT8 *)&p_repdesc->attr_value; + } - if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_VIRTUAL_CABLE)) != NULL) && - (p_attr->attr_value.v.u8) ) + if (((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_HID_VIRTUAL_CABLE)) + != NULL) + && p_attr->attr_value.v.u8) { attr_mask |= HID_VIRTUAL_CABLE; } - if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_RECONNECT_INITIATE)) != NULL) && - (p_attr->attr_value.v.u8) ) + if (((p_attr = + SDP_FindAttributeInRec(p_rec, ATTR_ID_HID_RECONNECT_INITIATE)) + != NULL) + && p_attr->attr_value.v.u8) { attr_mask |= HID_RECONN_INIT; } - if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_NORMALLY_CONNECTABLE)) != NULL) && - (p_attr->attr_value.v.u8) ) + if (((p_attr = + SDP_FindAttributeInRec(p_rec, ATTR_ID_HID_NORMALLY_CONNECTABLE)) + != NULL) + && p_attr->attr_value.v.u8) { attr_mask |= HID_NORMALLY_CONNECTABLE; } - if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_SDP_DISABLE)) != NULL)&& - (p_attr->attr_value.v.u8) ) + if (((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_HID_SDP_DISABLE)) + != NULL) + && p_attr->attr_value.v.u8) { attr_mask |= HID_SDP_DISABLE; } - if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_BATTERY_POWER)) != NULL)&& - (p_attr->attr_value.v.u8) ) + if (((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_HID_BATTERY_POWER)) + != NULL) + && p_attr->attr_value.v.u8) { attr_mask |= HID_BATTERY_POWER; } - if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_REMOTE_WAKE)) != NULL)&& - (p_attr->attr_value.v.u8) ) + if (((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_HID_REMOTE_WAKE)) + != NULL) + && p_attr->attr_value.v.u8) { attr_mask |= HID_REMOTE_WAKE; } - hidh_get_str_attr( p_rec, ATTR_ID_SERVICE_NAME, HID_MAX_SVC_NAME_LEN, p_nvi->svc_name ); - hidh_get_str_attr( p_rec, ATTR_ID_SERVICE_DESCRIPTION, HID_MAX_SVC_DESCR_LEN, p_nvi->svc_descr ); - hidh_get_str_attr( p_rec, ATTR_ID_PROVIDER_NAME, HID_MAX_PROV_NAME_LEN, p_nvi->prov_name ); + hidh_get_str_attr(p_rec, ATTR_ID_SERVICE_NAME, HID_MAX_SVC_NAME_LEN, + p_nvi->svc_name); + hidh_get_str_attr(p_rec, ATTR_ID_SERVICE_DESCRIPTION, HID_MAX_SVC_DESCR_LEN, + p_nvi->svc_descr); + hidh_get_str_attr(p_rec, ATTR_ID_PROVIDER_NAME, HID_MAX_PROV_NAME_LEN, + p_nvi->prov_name); - if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_DEVICE_RELNUM)) != NULL)) + if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_HID_DEVICE_RELNUM)) + != NULL) { p_nvi->rel_num = p_attr->attr_value.v.u16; } - if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_COUNTRY_CODE)) != NULL)) + if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_HID_COUNTRY_CODE)) + != NULL) { p_nvi->ctry_code = p_attr->attr_value.v.u8; } - if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_DEVICE_SUBCLASS)) != NULL)) + if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_HID_DEVICE_SUBCLASS)) + != NULL) { p_nvi->sub_class = p_attr->attr_value.v.u8; } - if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_PARSER_VERSION)) != NULL)) + if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_HID_PARSER_VERSION)) + != NULL) { p_nvi->hpars_ver = p_attr->attr_value.v.u16; } - if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_LINK_SUPERVISION_TO)) != NULL)) + if ((p_attr = + SDP_FindAttributeInRec(p_rec, ATTR_ID_HID_LINK_SUPERVISION_TO)) + != NULL) { attr_mask |= HID_SUP_TOUT_AVLBL; p_nvi->sup_timeout = p_attr->attr_value.v.u16; } - if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_SSR_HOST_MAX_LAT)) != NULL)) - { - attr_mask |= HID_SSR_MAX_LATENCY; - p_nvi->ssr_max_latency = p_attr->attr_value.v.u16; - } - else - p_nvi->ssr_max_latency = HID_SSR_PARAM_INVALID; - - if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_SSR_HOST_MIN_TOUT)) != NULL)) - { - attr_mask |= HID_SSR_MIN_TOUT; - p_nvi->ssr_min_tout = p_attr->attr_value.v.u16; - } - else - p_nvi->ssr_max_latency = HID_SSR_PARAM_INVALID; - hh_cb.sdp_rec.p_sdp_layer_rec = p_rec; - hh_cb.sdp_cback(SDP_SUCCESS, attr_mask, &hh_cb.sdp_rec); + (*hh_cb.sdp_cback)(SDP_SUCCESS, attr_mask, &hh_cb.sdp_rec); } - -/******************************************************************************* -** -** Function HID_HostInit -** -** Description This function initializes the control block and trace variable -** -** Returns void -** -*******************************************************************************/ -void HID_HostInit (void) +void HID_HostInit(void) { - memset(&hh_cb, 0, sizeof(tHID_HOST_CTB)); + memset(&hh_cb, 0, sizeof hh_cb); -#if defined(HID_INITIAL_TRACE_LEVEL) - hh_cb.trace_level = HID_INITIAL_TRACE_LEVEL; -#else hh_cb.trace_level = BT_TRACE_LEVEL_NONE; -#endif } -/******************************************************************************* -** -** Function HID_HostSetTraceLevel -** -** Description This function sets the trace level for HID Host. If called with -** a value of 0xFF, it simply reads the current trace level. -** -** Returns the new (current) trace level -** -*******************************************************************************/ -UINT8 HID_HostSetTraceLevel (UINT8 new_level) -{ - if (new_level != 0xFF) - hh_cb.trace_level = new_level; - - return (hh_cb.trace_level); -} - -/******************************************************************************* -** -** Function HID_HostRegister -** -** Description This function registers HID-Host with lower layers -** -** Returns tHID_STATUS -** -*******************************************************************************/ -tHID_STATUS HID_HostRegister (tHID_HOST_DEV_CALLBACK *dev_cback) +tHID_STATUS HID_HostRegister(tHID_HOST_DEV_CALLBACK *dev_cback) { tHID_STATUS st; - if( hh_cb.reg_flag ) + if (hh_cb.reg_flag) return HID_ERR_ALREADY_REGISTERED; - if( dev_cback == NULL ) + if (!dev_cback) return HID_ERR_INVALID_PARAM; - /* Register with L2CAP */ - if( (st = hidh_conn_reg()) != HID_SUCCESS ) - { + if ((st = hidh_conn_reg()) != HID_SUCCESS) return st; - } - hh_cb.callback = dev_cback ; + hh_cb.callback = dev_cback; hh_cb.reg_flag = TRUE; - return (HID_SUCCESS); + return HID_SUCCESS; } -/******************************************************************************* -** -** Function HID_HostDeregister -** -** Description This function is called when the host is about power down. -** -** Returns tHID_STATUS -** -*******************************************************************************/ tHID_STATUS HID_HostDeregister(void) { UINT8 i; - if( !hh_cb.reg_flag ) - return (HID_ERR_NOT_REGISTERED); + if (!hh_cb.reg_flag) + return HID_ERR_NOT_REGISTERED; - for( i=0; i= HID_HOST_MAX_DEVICES) || (!hh_cb.devices[dev_handle].in_use) ) + if (dev_handle > HID_HOST_MAX_DEVICES || !hh_cb.devices[dev_handle].in_use) return HID_ERR_INVALID_PARAM; - HID_HostCloseDev( dev_handle ) ; + HID_HostCloseDev(dev_handle); hh_cb.devices[dev_handle].in_use = FALSE; hh_cb.devices[dev_handle].conn.conn_state = HID_CONN_STATE_UNUSED; - hh_cb.devices[dev_handle].conn.ctrl_cid = hh_cb.devices[dev_handle].conn.intr_cid = 0; + hh_cb.devices[dev_handle].conn.ctrl_cid = + hh_cb.devices[dev_handle].conn.intr_cid = 0; return HID_SUCCESS; } -/******************************************************************************* -** -** Function HID_HostOpenDev -** -** Description This function is called when the user wants to initiate a -** connection attempt to a device. -** -** Returns void -** -*******************************************************************************/ -tHID_STATUS HID_HostOpenDev ( UINT8 dev_handle ) +tHID_STATUS HID_HostOpenDev(UINT8 dev_handle) { - if( !hh_cb.reg_flag ) - return (HID_ERR_NOT_REGISTERED); + if (!hh_cb.reg_flag) + return HID_ERR_NOT_REGISTERED; - if( (dev_handle >= HID_HOST_MAX_DEVICES) || (!hh_cb.devices[dev_handle].in_use) ) + if (dev_handle > HID_HOST_MAX_DEVICES || !hh_cb.devices[dev_handle].in_use) return HID_ERR_INVALID_PARAM; - if( hh_cb.devices[dev_handle].state != HID_DEV_NO_CONN ) + if (hh_cb.devices[dev_handle].state != HID_DEV_NO_CONN) return HID_ERR_ALREADY_CONN; hh_cb.devices[dev_handle].conn_tries = 1; - return hidh_conn_initiate( dev_handle ); + return hidh_conn_initiate(dev_handle); } -/******************************************************************************* -** -** Function HID_HostWriteDev -** -** Description This function is called when the host has a report to send. -** -** report_id: is only used on GET_REPORT transaction if is specified. -** only valid when it's a non-zero value. -** -** Returns void -** -*******************************************************************************/ -tHID_STATUS HID_HostWriteDev( UINT8 dev_handle, UINT8 t_type, - UINT8 param, UINT16 data, UINT8 report_id, BT_HDR *pbuf ) +tHID_STATUS HID_HostWriteDev(UINT8 dev_handle, UINT8 t_type, UINT8 param, + UINT16 data, UINT8 report_id, BT_HDR *pbuf) { tHID_STATUS status = HID_SUCCESS; - if( !hh_cb.reg_flag ) + if (!hh_cb.reg_flag) { - HIDH_TRACE_ERROR0("HID_ERR_NOT_REGISTERED"); + HIDH_TRACE(ERROR, "HID_ERR_NOT_REGISTERED"); status = HID_ERR_NOT_REGISTERED; } - if( (dev_handle >= HID_HOST_MAX_DEVICES) || (!hh_cb.devices[dev_handle].in_use) ) + if (dev_handle > HID_HOST_MAX_DEVICES || !hh_cb.devices[dev_handle].in_use) { - HIDH_TRACE_ERROR0("HID_ERR_INVALID_PARAM"); + HIDH_TRACE(ERROR, "HID_ERR_INVALID_PARAM"); status = HID_ERR_INVALID_PARAM; } - if( hh_cb.devices[dev_handle].state != HID_DEV_CONNECTED ) + if (hh_cb.devices[dev_handle].state != HID_DEV_CONNECTED) { - HIDH_TRACE_ERROR1("HID_ERR_NO_CONNECTION dev_handle %d", dev_handle); + HIDH_TRACE(ERROR, "HID_ERR_NO_CONNECTION dev_handle %d", dev_handle); status = HID_ERR_NO_CONNECTION; } if (status != HID_SUCCESS) { if (pbuf) - GKI_freebuf ((void *)pbuf); + GKI_freebuf(pbuf); } else - status = hidh_conn_snd_data( dev_handle, t_type, param, data, report_id, pbuf ) ; + { + status = hidh_conn_snd_data(dev_handle, t_type, param, data, report_id, + pbuf); + } return status; } -/******************************************************************************* -** -** Function HID_HostCloseDev -** -** Description This function disconnects the device. -** -** Returns void -** -*******************************************************************************/ -tHID_STATUS HID_HostCloseDev( UINT8 dev_handle ) +tHID_STATUS HID_HostCloseDev(UINT8 dev_handle) { - if( !hh_cb.reg_flag ) - return (HID_ERR_NOT_REGISTERED); + if (!hh_cb.reg_flag) + return HID_ERR_NOT_REGISTERED; - if( (dev_handle >= HID_HOST_MAX_DEVICES) || (!hh_cb.devices[dev_handle].in_use) ) + if (dev_handle > HID_HOST_MAX_DEVICES || !hh_cb.devices[dev_handle].in_use) return HID_ERR_INVALID_PARAM; - hh_cb.devices[dev_handle].conn_tries = HID_HOST_MAX_CONN_RETRY+1; - btu_stop_timer( &(hh_cb.devices[dev_handle].conn.timer_entry) ) ; + hh_cb.devices[dev_handle].conn_tries = HID_HOST_MAX_CONN_RETRY + 1; + btu_stop_timer(&hh_cb.devices[dev_handle].conn.timer_entry); - if( hh_cb.devices[dev_handle].state != HID_DEV_CONNECTED ) + if (hh_cb.devices[dev_handle].state != HID_DEV_CONNECTED) return HID_ERR_NO_CONNECTION; - hh_cb.devices[dev_handle].conn_tries = HID_HOST_MAX_CONN_RETRY+1; - return hidh_conn_disconnect( dev_handle ); + hh_cb.devices[dev_handle].conn_tries = HID_HOST_MAX_CONN_RETRY + 1; + return hidh_conn_disconnect(dev_handle); } -tHID_STATUS HID_HostSetSecurityLevel( char serv_name[], UINT8 sec_lvl ) +tHID_STATUS HID_HostSetSecurityLevel(char *serv_name, UINT8 sec_lvl) { - if (!BTM_SetSecurityLevel (FALSE, serv_name, BTM_SEC_SERVICE_HID_SEC_CTRL, - sec_lvl, HID_PSM_CONTROL, BTM_SEC_PROTO_HID, HID_SEC_CHN)) + if (!BTM_SetSecurityLevel(FALSE, serv_name, BTM_SEC_SERVICE_HID_SEC_CTRL, + sec_lvl, HID_PSM_CONTROL, BTM_SEC_PROTO_HID, + HID_SEC_CHN)) { - HIDH_TRACE_ERROR0 ("Security Registration 1 failed"); - return (HID_ERR_NO_RESOURCES); + HIDH_TRACE(ERROR, "Security Registration 1 failed"); + return HID_ERR_NO_RESOURCES; } - if (!BTM_SetSecurityLevel (TRUE, serv_name, BTM_SEC_SERVICE_HID_SEC_CTRL, - sec_lvl, HID_PSM_CONTROL, BTM_SEC_PROTO_HID, HID_SEC_CHN)) + if (!BTM_SetSecurityLevel(TRUE, serv_name, BTM_SEC_SERVICE_HID_SEC_CTRL, + sec_lvl, HID_PSM_CONTROL, BTM_SEC_PROTO_HID, + HID_SEC_CHN)) { - HIDH_TRACE_ERROR0 ("Security Registration 2 failed"); - return (HID_ERR_NO_RESOURCES); + HIDH_TRACE(ERROR, "Security Registration 2 failed"); + return HID_ERR_NO_RESOURCES; } - if (!BTM_SetSecurityLevel (FALSE, serv_name, BTM_SEC_SERVICE_HID_NOSEC_CTRL, - BTM_SEC_NONE, HID_PSM_CONTROL, BTM_SEC_PROTO_HID, HID_NOSEC_CHN)) + if (!BTM_SetSecurityLevel(FALSE, serv_name, BTM_SEC_SERVICE_HID_NOSEC_CTRL, + BTM_SEC_NONE, HID_PSM_CONTROL, BTM_SEC_PROTO_HID, + HID_NOSEC_CHN)) { - HIDH_TRACE_ERROR0 ("Security Registration 3 failed"); - return (HID_ERR_NO_RESOURCES); + HIDH_TRACE(ERROR, "Security Registration 3 failed"); + return HID_ERR_NO_RESOURCES; } - if (!BTM_SetSecurityLevel (TRUE, serv_name, BTM_SEC_SERVICE_HID_NOSEC_CTRL, - BTM_SEC_NONE, HID_PSM_CONTROL, BTM_SEC_PROTO_HID, HID_NOSEC_CHN)) + if (!BTM_SetSecurityLevel(TRUE, serv_name, BTM_SEC_SERVICE_HID_NOSEC_CTRL, + BTM_SEC_NONE, HID_PSM_CONTROL, BTM_SEC_PROTO_HID, + HID_NOSEC_CHN)) { - HIDH_TRACE_ERROR0 ("Security Registration 4 failed"); - return (HID_ERR_NO_RESOURCES); + HIDH_TRACE(ERROR, "Security Registration 4 failed"); + return HID_ERR_NO_RESOURCES; } - if (!BTM_SetSecurityLevel (TRUE, serv_name, BTM_SEC_SERVICE_HID_INTR, - BTM_SEC_NONE, HID_PSM_INTERRUPT, BTM_SEC_PROTO_HID, 0)) + if (!BTM_SetSecurityLevel(TRUE, serv_name, BTM_SEC_SERVICE_HID_INTR, + BTM_SEC_NONE, HID_PSM_INTERRUPT, + BTM_SEC_PROTO_HID, 0)) { - HIDH_TRACE_ERROR0 ("Security Registration 5 failed"); - return (HID_ERR_NO_RESOURCES); + HIDH_TRACE(ERROR, "Security Registration 5 failed"); + return HID_ERR_NO_RESOURCES; } - if (!BTM_SetSecurityLevel (FALSE, serv_name, BTM_SEC_SERVICE_HID_INTR, - BTM_SEC_NONE, HID_PSM_INTERRUPT, BTM_SEC_PROTO_HID, 0)) + if (!BTM_SetSecurityLevel(FALSE, serv_name, BTM_SEC_SERVICE_HID_INTR, + BTM_SEC_NONE, HID_PSM_INTERRUPT, + BTM_SEC_PROTO_HID, 0)) { - HIDH_TRACE_ERROR0 ("Security Registration 6 failed"); - return (HID_ERR_NO_RESOURCES); + HIDH_TRACE(ERROR, "Security Registration 6 failed\0\0\0\0\0"); + return HID_ERR_NO_RESOURCES; } - return( HID_SUCCESS ); + return HID_SUCCESS; } diff --git a/src/revolution/BTE/stack/hid/hidh_conn.c b/src/revolution/BTE/stack/hid/hidh_conn.c index 6026427..635542b 100644 --- a/src/revolution/BTE/stack/hid/hidh_conn.c +++ b/src/revolution/BTE/stack/hid/hidh_conn.c @@ -16,384 +16,307 @@ * ******************************************************************************/ +/* Original source: + * bluedroid + * stack/hid/hidh_conn.c + */ + +/* Includes changes by muff1n1634 and for this repository (KoopTheKoopa) */ + /****************************************************************************** * - * this file contains the connection interface functions + * This file contains HID host connection functions. * ******************************************************************************/ -#include -#include -#include +#include "hidh_int.h" +#include -#include "gki.h" +#include "bt_target.h" +#include "bt_trace.h" #include "bt_types.h" +#include "data_types.h" -#include "l2cdefs.h" -#include "l2c_api.h" - -#include "btu.h" #include "btm_api.h" #include "btm_int.h" - +#include "btu.h" +#include "gki.h" +#include "hcidefs.h" +#include "hid_conn.h" #include "hiddefs.h" - #include "hidh_api.h" -#include "hidh_int.h" +#include "l2c_api.h" +#include "l2cdefs.h" + + +static void hidh_l2cif_connect_ind(BD_ADDR bd_addr, UINT16 l2cap_cid, + UINT16 psm, UINT8 l2cap_id); +static void hidh_l2cif_connect_cfm(UINT16 l2cap_cid, UINT16 result); +static void hidh_l2cif_config_ind(UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg); +static void hidh_l2cif_config_cfm(UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg); +static void hidh_l2cif_disconnect_ind(UINT16 l2cap_cid, BOOLEAN ack_needed); +static void hidh_l2cif_disconnect_cfm(UINT16 l2cap_cid, UINT16 result); +static void hidh_l2cif_cong_ind(UINT16 l2cap_cid, BOOLEAN congested); +static void hidh_l2cif_data_ind(UINT16 l2cap_cid, BT_HDR *p_msg); + +static UINT8 find_conn_by_cid(UINT16 cid); -static UINT8 find_conn_by_cid (UINT16 cid); -static void hidh_conn_retry (UINT8 dhandle); - -/********************************************************************************/ -/* L O C A L F U N C T I O N P R O T O T Y P E S */ -/********************************************************************************/ -static void hidh_l2cif_connect_ind (BD_ADDR bd_addr, UINT16 l2cap_cid, - UINT16 psm, UINT8 l2cap_id); -static void hidh_l2cif_connect_cfm (UINT16 l2cap_cid, UINT16 result); -static void hidh_l2cif_config_ind (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg); -static void hidh_l2cif_config_cfm (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg); -static void hidh_l2cif_disconnect_ind (UINT16 l2cap_cid, BOOLEAN ack_needed); -static void hidh_l2cif_data_ind (UINT16 l2cap_cid, BT_HDR *p_msg); -static void hidh_l2cif_disconnect_cfm (UINT16 l2cap_cid, UINT16 result); -static void hidh_l2cif_cong_ind (UINT16 l2cap_cid, BOOLEAN congested); - -static const tL2CAP_APPL_INFO hst_reg_info = +// Only used if HID_HOST_MAX_CONN_RETRY > 0, but here it was 0. +static void hidh_conn_retry(UINT8 dhandle); + +static tL2CAP_APPL_INFO const hst_reg_info = { - hidh_l2cif_connect_ind, - hidh_l2cif_connect_cfm, + &hidh_l2cif_connect_ind, + &hidh_l2cif_connect_cfm, NULL, - hidh_l2cif_config_ind, - hidh_l2cif_config_cfm, - hidh_l2cif_disconnect_ind, - hidh_l2cif_disconnect_cfm, + &hidh_l2cif_config_ind, + &hidh_l2cif_config_cfm, + &hidh_l2cif_disconnect_ind, + &hidh_l2cif_disconnect_cfm, NULL, - hidh_l2cif_data_ind, - hidh_l2cif_cong_ind + &hidh_l2cif_data_ind, + &hidh_l2cif_cong_ind, }; -/******************************************************************************* -** -** Function hidh_l2cif_reg -** -** Description This function initializes the SDP unit. -** -** Returns void -** -*******************************************************************************/ -tHID_STATUS hidh_conn_reg (void) +tHID_STATUS hidh_conn_reg(void) { int xx; - /* Initialize the L2CAP configuration. We only care about MTU and flush */ - memset(&hh_cb.l2cap_cfg, 0, sizeof(tL2CAP_CFG_INFO)); - - hh_cb.l2cap_cfg.mtu_present = TRUE; - hh_cb.l2cap_cfg.mtu = HID_HOST_MTU; - hh_cb.l2cap_cfg.flush_to_present = TRUE; - hh_cb.l2cap_cfg.flush_to = HID_HOST_FLUSH_TO; + hh_cb.l2cap_cfg.mtu_present = TRUE; + hh_cb.l2cap_cfg.mtu = HID_HOST_MTU; + hh_cb.l2cap_cfg.flush_to_present = TRUE; + hh_cb.l2cap_cfg.flush_to = HID_HOST_FLUSH_TO; - /* Now, register with L2CAP */ - if (!L2CA_Register (HID_PSM_CONTROL, (tL2CAP_APPL_INFO *) &hst_reg_info)) + if (!L2CA_Register(HID_PSM_CONTROL, (tL2CAP_APPL_INFO *)&hst_reg_info)) { - HIDH_TRACE_ERROR0 ("HID Control Registration failed"); - return (HID_ERR_L2CAP_FAILED) ; + HIDH_TRACE(ERROR, "HID Control Registration failed"); + return HID_ERR_L2CAP_FAILED; } - if (!L2CA_Register (HID_PSM_INTERRUPT, (tL2CAP_APPL_INFO *) &hst_reg_info)) + + if (!L2CA_Register(HID_PSM_INTERRUPT, (tL2CAP_APPL_INFO *)&hst_reg_info)) { - L2CA_Deregister( HID_PSM_CONTROL ) ; - HIDH_TRACE_ERROR0 ("HID Interrupt Registration failed"); - return (HID_ERR_L2CAP_FAILED) ; + L2CA_Deregister(HID_PSM_CONTROL); + HIDH_TRACE(ERROR, "HID Interrupt Registration failed"); + return HID_ERR_L2CAP_FAILED; } for (xx = 0; xx < HID_HOST_MAX_DEVICES; xx++) { - hh_cb.devices[xx].in_use = FALSE ; + hh_cb.devices[xx].in_use = FALSE; hh_cb.devices[xx].conn.conn_state = HID_CONN_STATE_UNUSED; } - return (HID_SUCCESS); + return HID_SUCCESS; } -/******************************************************************************* -** -** Function hidh_conn_disconnect -** -** Description This function disconnects a connection. -** -** Returns TRUE if disconnect started, FALSE if already disconnected -** -*******************************************************************************/ -tHID_STATUS hidh_conn_disconnect (UINT8 dhandle) +tHID_STATUS hidh_conn_disconnect(UINT8 dhandle) { tHID_CONN *p_hcon = &hh_cb.devices[dhandle].conn; - HIDH_TRACE_EVENT0 ("HID - disconnect"); + HIDH_TRACE(EVENT, "HID - disconnect"); - if ((p_hcon->ctrl_cid != 0) || (p_hcon->intr_cid != 0)) + if (p_hcon->ctrl_cid || p_hcon->intr_cid) { p_hcon->conn_state = HID_CONN_STATE_DISCONNECTING; - /* Disconnect both interrupt and control channels */ if (p_hcon->intr_cid) - L2CA_DisconnectReq (p_hcon->intr_cid); + L2CA_DisconnectReq(p_hcon->intr_cid); if (p_hcon->ctrl_cid) - L2CA_DisconnectReq (p_hcon->ctrl_cid); + L2CA_DisconnectReq(p_hcon->ctrl_cid); } else { p_hcon->conn_state = HID_CONN_STATE_UNUSED; } - return (HID_SUCCESS); + return HID_SUCCESS; } -/******************************************************************************* -** -** Function hidh_sec_check_complete_term -** -** Description HID security check complete callback function. -** -** Returns Send L2CA_ConnectRsp OK if secutiry check succeed; otherwise -** send security block L2C connection response. -** -*******************************************************************************/ -void hidh_sec_check_complete_term (BD_ADDR bd_addr, void *p_ref_data, UINT8 res) +void hidh_sec_check_complete_term(BD_ADDR bd_addr, void *p_ref_data, UINT8 res) { - tHID_HOST_DEV_CTB *p_dev= (tHID_HOST_DEV_CTB *) p_ref_data; + tHID_HOST_DEV_CTB *p_dev = p_ref_data; + UINT8 dhandle = p_dev - hh_cb.devices; - if( res == BTM_SUCCESS && p_dev->conn.conn_state == HID_CONN_STATE_SECURITY ) + if (res == BTM_SUCCESS && p_dev->conn.conn_state == HID_CONN_STATE_SECURITY) { - p_dev->conn.disc_reason = HID_SUCCESS; /* Authentication passed. Reset disc_reason (from HID_ERR_AUTH_FAILED) */ - + p_dev->conn.disc_reason = HID_SUCCESS; p_dev->conn.conn_state = HID_CONN_STATE_CONNECTING_INTR; - /* Send response to the L2CAP layer. */ - L2CA_ConnectRsp (p_dev->addr, p_dev->conn.ctrl_id, p_dev->conn.ctrl_cid, L2CAP_CONN_OK, L2CAP_CONN_OK); - - /* Send a Configuration Request. */ - L2CA_ConfigReq (p_dev->conn.ctrl_cid, &hh_cb.l2cap_cfg); + L2CA_ConnectRsp(p_dev->addr, p_dev->conn.ctrl_id, p_dev->conn.ctrl_cid, + L2CAP_CONN_OK, L2CAP_CONN_OK); + L2CA_ConfigReq(p_dev->conn.ctrl_cid, &hh_cb.l2cap_cfg); } - /* security check fail */ else if (res != BTM_SUCCESS) { - p_dev->conn.disc_reason = HID_ERR_AUTH_FAILED; /* Save reason for disconnecting */ - p_dev->conn.conn_state = HID_CONN_STATE_UNUSED; - L2CA_ConnectRsp (p_dev->addr, p_dev->conn.ctrl_id, p_dev->conn.ctrl_cid, L2CAP_CONN_SECURITY_BLOCK, L2CAP_CONN_OK); + p_dev->conn.disc_reason = HID_ERR_AUTH_FAILED; + + hidh_conn_disconnect(dhandle); } } -/******************************************************************************* -** -** Function hidh_l2cif_connect_ind -** -** Description This function handles an inbound connection indication -** from L2CAP. This is the case where we are acting as a -** server. -** -** Returns void -** -*******************************************************************************/ -static void hidh_l2cif_connect_ind (BD_ADDR bd_addr, UINT16 l2cap_cid, UINT16 psm, UINT8 l2cap_id) +static void hidh_l2cif_connect_ind(BD_ADDR bd_addr, UINT16 l2cap_cid, + UINT16 psm, UINT8 l2cap_id) { - tHID_CONN *p_hcon; - BOOLEAN bAccept = TRUE; + tHID_CONN *p_hcon; + BOOLEAN bAccept = TRUE; int i; tHID_HOST_DEV_CTB *p_dev; - HIDH_TRACE_EVENT2 ("HID - Rcvd L2CAP conn ind, PSM: 0x%04x CID 0x%x", psm, l2cap_cid); + HIDH_TRACE(EVENT, "HID - Rcvd L2CAP conn ind, PSM: 0x%04x CID 0x%x", psm, + l2cap_cid); - for( i=0; i < HID_HOST_MAX_DEVICES; i++ ) + for (i = 0; i < HID_HOST_MAX_DEVICES; i++) { - if( hh_cb.devices[i].in_use && (!memcmp(bd_addr, hh_cb.devices[i].addr, sizeof(BD_ADDR))) ) + if (hh_cb.devices[i].in_use + && memcmp(bd_addr, hh_cb.devices[i].addr, BD_ADDR_LEN) == 0) + { break; + } } - if (i >= HID_HOST_MAX_DEVICES) + if (i == HID_HOST_MAX_DEVICES) { - L2CA_ConnectRsp (bd_addr, l2cap_id, l2cap_cid, L2CAP_CONN_SECURITY_BLOCK, 0); + L2CA_ConnectRsp(bd_addr, l2cap_id, l2cap_cid, L2CAP_CONN_SECURITY_BLOCK, + 0); return; } p_hcon = &hh_cb.devices[i].conn; - p_dev = &hh_cb.devices[i]; + p_dev = &hh_cb.devices[i]; - /* Check we are in the correct state for this */ if (psm == HID_PSM_INTERRUPT) { if (p_hcon->ctrl_cid == 0) { - HIDH_TRACE_WARNING0 ("HID - Rcvd INTR L2CAP conn ind, but no CTL channel"); + HIDH_TRACE(WARNING, + "HID - Rcvd INTR L2CAP conn ind, but no CTL channel"); bAccept = FALSE; } if (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_INTR) { - HIDH_TRACE_WARNING1 ("HID - Rcvd INTR L2CAP conn ind, wrong state: %d", p_hcon->conn_state); + HIDH_TRACE(WARNING, + "HID - Rcvd INTR L2CAP conn ind, wrong state: %d", + p_hcon->conn_state); bAccept = FALSE; } } - else /* CTRL channel */ + else { -#if defined(HID_HOST_ACPT_NEW_CONN) && (HID_HOST_ACPT_NEW_CONN == TRUE) - p_hcon->ctrl_cid = p_hcon->intr_cid = 0; - p_hcon->conn_state = HID_CONN_STATE_UNUSED; -#else if (p_hcon->conn_state != HID_CONN_STATE_UNUSED) { - HIDH_TRACE_WARNING1 ("HID - Rcvd CTL L2CAP conn ind, wrong state: %d", p_hcon->conn_state); + HIDH_TRACE(WARNING, + "HID - Rcvd CTL L2CAP conn ind, wrong state: %d", + p_hcon->conn_state); bAccept = FALSE; } -#endif } if (!bAccept) { - L2CA_ConnectRsp (bd_addr, l2cap_id, l2cap_cid, L2CAP_CONN_NO_RESOURCES, 0); + L2CA_ConnectRsp(bd_addr, l2cap_id, l2cap_cid, L2CAP_CONN_NO_RESOURCES, + L2CAP_CONN_OK); return; } if (psm == HID_PSM_CONTROL) { p_hcon->conn_flags = 0; - p_hcon->ctrl_cid = l2cap_cid; - p_hcon->ctrl_id = l2cap_id; - p_hcon->disc_reason = HID_L2CAP_CONN_FAIL; /* In case disconnection occurs before security is completed, then set CLOSE_EVT reason code to 'connection failure' */ + p_hcon->ctrl_cid = l2cap_cid; + p_hcon->ctrl_id = l2cap_id; + p_hcon->disc_reason = HID_L2CAP_CONN_FAIL; p_hcon->conn_state = HID_CONN_STATE_SECURITY; - if(btm_sec_mx_access_request (p_dev->addr, HID_PSM_CONTROL, - FALSE, BTM_SEC_PROTO_HID, - (p_dev->attr_mask & HID_SEC_REQUIRED) ? HID_SEC_CHN : HID_NOSEC_CHN, - &hidh_sec_check_complete_term, p_dev) == BTM_CMD_STARTED) - { - L2CA_ConnectRsp (bd_addr, l2cap_id, l2cap_cid, L2CAP_CONN_PENDING, L2CAP_CONN_OK); - } + + btm_sec_mx_access_request( + p_dev->addr, HID_PSM_CONTROL, FALSE, BTM_SEC_PROTO_HID, + p_dev->attr_mask & HID_SEC_REQUIRED ? HID_SEC_CHN : HID_NOSEC_CHN, + &hidh_sec_check_complete_term, p_dev); return; } - /* Transition to the next appropriate state, configuration */ p_hcon->conn_state = HID_CONN_STATE_CONFIG; - p_hcon->intr_cid = l2cap_cid; + p_hcon->intr_cid = l2cap_cid; - /* Send response to the L2CAP layer. */ - L2CA_ConnectRsp (bd_addr, l2cap_id, l2cap_cid, L2CAP_CONN_OK, L2CAP_CONN_OK); + L2CA_ConnectRsp(bd_addr, l2cap_id, l2cap_cid, L2CAP_CONN_OK, L2CAP_CONN_OK); - /* Send a Configuration Request. */ - L2CA_ConfigReq (l2cap_cid, &hh_cb.l2cap_cfg); + L2CA_ConfigReq(l2cap_cid, &hh_cb.l2cap_cfg); - HIDH_TRACE_EVENT2 ("HID - Rcvd L2CAP conn ind, sent config req, PSM: 0x%04x CID 0x%x", psm, l2cap_cid); + HIDH_TRACE( + EVENT, + "HID - Rcvd L2CAP conn ind, sent config req, PSM: 0x%04x CID 0x%x", + psm, l2cap_cid); } -/******************************************************************************* -** -** Function hidh_proc_repage_timeout -** -** Description This function handles timeout (to page device). -** -** Returns void -** -*******************************************************************************/ -void hidh_proc_repage_timeout (TIMER_LIST_ENT *p_tle) +void hidh_proc_repage_timeout(TIMER_LIST_ENT *p_tle) { - hidh_conn_initiate( (UINT8) p_tle->param ) ; - hh_cb.devices[p_tle->param].conn_tries++; - hh_cb.callback( (UINT8) p_tle->param, HID_HDEV_EVT_RETRYING, hh_cb.devices[p_tle->param].conn_tries, NULL ) ; + hidh_conn_initiate((UINT32)p_tle->param); + + ++hh_cb.devices[(UINT32)p_tle->param].conn_tries; + + (*hh_cb.callback)((UINT32)p_tle->param, HID_HDEV_EVT_RETRYING, + hh_cb.devices[(UINT32)p_tle->param].conn_tries, NULL); } -/******************************************************************************* -** -** Function hidh_sec_check_complete_orig -** -** Description This function checks to see if security procedures are being -** carried out or not.. -** -** Returns void -** -*******************************************************************************/ -void hidh_sec_check_complete_orig (BD_ADDR bd_addr, void *p_ref_data, UINT8 res) +void hidh_sec_check_complete_orig(BD_ADDR bd_addr, void *p_ref_data, UINT8 res) { - tHID_HOST_DEV_CTB *p_dev = (tHID_HOST_DEV_CTB *) p_ref_data; - UINT8 dhandle; -#if (HID_HOST_MAX_CONN_RETRY > 0) - UINT32 cb_res = HID_ERR_AUTH_FAILED; -#endif + tHID_HOST_DEV_CTB *p_dev = p_ref_data; + UINT8 dhandle = p_dev - hh_cb.devices; UINT32 reason; - dhandle = p_dev - &(hh_cb.devices[0]) ; - if( res == BTM_SUCCESS && p_dev->conn.conn_state == HID_CONN_STATE_SECURITY ) + if (res == BTM_SUCCESS && p_dev->conn.conn_state == HID_CONN_STATE_SECURITY) { - HIDH_TRACE_EVENT0 ("HID - Originator security pass."); - p_dev->conn.disc_reason = HID_SUCCESS; /* Authentication passed. Reset disc_reason (from HID_ERR_AUTH_FAILED) */ + HIDH_TRACE(EVENT, "HID - Originator security pass."); + p_dev->conn.disc_reason = HID_SUCCESS; - /* Check if L2CAP started the connection process for interrupt channel */ - if ((p_dev->conn.intr_cid = L2CA_ConnectReq (HID_PSM_INTERRUPT, hh_cb.devices[dhandle].addr)) == 0) + if ((p_dev->conn.intr_cid = L2CA_ConnectReq( + HID_PSM_INTERRUPT, hh_cb.devices[dhandle].addr)) + == 0) { - HIDH_TRACE_WARNING0 ("HID - INTR Originate failed"); - reason = HID_L2CAP_REQ_FAIL ; - hidh_conn_disconnect (dhandle); - hh_cb.callback( dhandle, HID_HDEV_EVT_CLOSE, reason, NULL ) ; + HIDH_TRACE(WARNING, "HID - INTR Originate failed"); + reason = HID_L2CAP_REQ_FAIL; + + hidh_conn_disconnect(dhandle); + (*hh_cb.callback)(dhandle, HID_HDEV_EVT_CLOSE, reason, NULL); return; } else { - /* Transition to the next appropriate state, waiting for connection confirm on control channel. */ p_dev->conn.conn_state = HID_CONN_STATE_CONNECTING_INTR; } } - if( res != BTM_SUCCESS && p_dev->conn.conn_state == HID_CONN_STATE_SECURITY ) + if (res != BTM_SUCCESS && p_dev->conn.conn_state == HID_CONN_STATE_SECURITY) { -#if (HID_HOST_MAX_CONN_RETRY > 0) - if( res == BTM_DEVICE_TIMEOUT ) - { - if( p_dev->conn_tries <= HID_HOST_MAX_CONN_RETRY ) - { - hidh_conn_retry (dhandle); - return; - } - else - cb_res = HID_L2CAP_CONN_FAIL | HCI_ERR_PAGE_TIMEOUT ; - } -#endif - p_dev->conn.disc_reason = HID_ERR_AUTH_FAILED; /* Save reason for disconnecting */ + p_dev->conn.disc_reason = HID_ERR_AUTH_FAILED; hidh_conn_disconnect(dhandle); } - } -/******************************************************************************* -** -** Function hidh_l2cif_connect_cfm -** -** Description This function handles the connect confirm events -** from L2CAP. This is the case when we are acting as a -** client and have sent a connect request. -** -** Returns void -** -*******************************************************************************/ -static void hidh_l2cif_connect_cfm (UINT16 l2cap_cid, UINT16 result) +static void hidh_l2cif_connect_cfm(UINT16 l2cap_cid, UINT16 result) { UINT8 dhandle; - tHID_CONN *p_hcon = NULL; - UINT32 reason; + tHID_CONN *p_hcon = NULL; + UINT32 reason; tHID_HOST_DEV_CTB *p_dev = NULL; - /* Find CCB based on CID, and verify we are in a state to accept this message */ - if( (dhandle = find_conn_by_cid(l2cap_cid)) < HID_HOST_MAX_DEVICES ) + if ((dhandle = find_conn_by_cid(l2cap_cid)) != HID_HOST_MAX_DEVICES) { p_dev = &hh_cb.devices[dhandle]; p_hcon = &hh_cb.devices[dhandle].conn; } - if ((p_hcon == NULL) - || (!(p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG)) - || ((l2cap_cid == p_hcon->ctrl_cid) && (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_CTRL)) - || ((l2cap_cid == p_hcon->intr_cid) && (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_INTR))) + if (!p_hcon || !(p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) + || (l2cap_cid == p_hcon->ctrl_cid + && p_hcon->conn_state != HID_CONN_STATE_CONNECTING_CTRL) + || (l2cap_cid == p_hcon->intr_cid + && p_hcon->conn_state != HID_CONN_STATE_CONNECTING_INTR)) { - HIDH_TRACE_WARNING1 ("HID - Rcvd unexpected conn cnf, CID 0x%x ", l2cap_cid); + HIDH_TRACE(WARNING, "HID - Rcvd unexpected conn cnf, CID 0x%x ", + l2cap_cid); return; } @@ -406,31 +329,19 @@ static void hidh_l2cif_connect_cfm (UINT16 l2cap_cid, UINT16 result) hidh_conn_disconnect(dhandle); -#if (HID_HOST_MAX_CONN_RETRY > 0) - if( (hh_cb.devices[dhandle].conn_tries <= HID_HOST_MAX_CONN_RETRY) && - (result == HCI_ERR_CONNECTION_TOUT || result == HCI_ERR_UNSPECIFIED || - result == HCI_ERR_PAGE_TIMEOUT) ) - { - hidh_conn_retry(dhandle); - } - else -#endif - { - reason = HID_L2CAP_CONN_FAIL | (UINT32) result ; - hh_cb.callback( dhandle, HID_HDEV_EVT_CLOSE, reason, NULL ) ; - } + reason = HID_L2CAP_CONN_FAIL | result; + (*hh_cb.callback)(dhandle, HID_HDEV_EVT_CLOSE, reason, NULL); return; } - /* receive Control Channel connect confirmation */ + if (l2cap_cid == p_hcon->ctrl_cid) { - /* check security requirement */ p_hcon->conn_state = HID_CONN_STATE_SECURITY; - p_hcon->disc_reason = HID_L2CAP_CONN_FAIL; /* In case disconnection occurs before security is completed, then set CLOSE_EVT reason code to "connection failure" */ + p_hcon->disc_reason = HID_L2CAP_CONN_FAIL; - btm_sec_mx_access_request (p_dev->addr, HID_PSM_CONTROL, - TRUE, BTM_SEC_PROTO_HID, - (p_dev->attr_mask & HID_SEC_REQUIRED) ? HID_SEC_CHN : HID_NOSEC_CHN, + btm_sec_mx_access_request( + p_dev->addr, HID_PSM_CONTROL, TRUE, BTM_SEC_PROTO_HID, + p_dev->attr_mask & HID_SEC_REQUIRED ? HID_SEC_CHN : HID_NOSEC_CHN, &hidh_sec_check_complete_orig, p_dev); } else @@ -438,159 +349,125 @@ static void hidh_l2cif_connect_cfm (UINT16 l2cap_cid, UINT16 result) p_hcon->conn_state = HID_CONN_STATE_CONFIG; } - /* Send a Configuration Request. */ - L2CA_ConfigReq (l2cap_cid, &hh_cb.l2cap_cfg); + L2CA_ConfigReq(l2cap_cid, &hh_cb.l2cap_cfg); - HIDH_TRACE_EVENT1 ("HID - got CTRL conn cnf, sent cfg req, CID: 0x%x", l2cap_cid); - return; + HIDH_TRACE(EVENT, "HID - got CTRL conn cnf, sent cfg req, CID: 0x%x", + l2cap_cid); } -/******************************************************************************* -** -** Function hidh_l2cif_config_ind -** -** Description This function processes the L2CAP configuration indication -** event. -** -** Returns void -** -*******************************************************************************/ -static void hidh_l2cif_config_ind (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg) +static void hidh_l2cif_config_ind(UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg) { UINT8 dhandle; - tHID_CONN *p_hcon = NULL; + tHID_CONN *p_hcon = NULL; tHID_HOST_DEV_CTB *p_dev; - /* Find CCB based on CID */ - if( (dhandle = find_conn_by_cid(l2cap_cid)) < HID_HOST_MAX_DEVICES ) + if ((dhandle = find_conn_by_cid(l2cap_cid)) != HID_HOST_MAX_DEVICES) { p_dev = &hh_cb.devices[dhandle]; p_hcon = &hh_cb.devices[dhandle].conn; } - if (p_hcon == NULL) + if (!p_hcon) { - HIDH_TRACE_WARNING1 ("HID - Rcvd L2CAP cfg ind, unknown CID: 0x%x", l2cap_cid); + HIDH_TRACE(WARNING, "HID - Rcvd L2CAP cfg ind, unknown CID: 0x%x", + l2cap_cid); return; } - HIDH_TRACE_EVENT1 ("HID - Rcvd cfg ind, sent cfg cfm, CID: 0x%x", l2cap_cid); + HIDH_TRACE(EVENT, "HID - Rcvd cfg ind, sent cfg cfm, CID: 0x%x", l2cap_cid); - /* Remember the remote MTU size */ - if ((!p_cfg->mtu_present) || (p_cfg->mtu > HID_HOST_MTU)) + if (!p_cfg->mtu_present || p_cfg->mtu > HID_HOST_MTU) p_hcon->rem_mtu_size = HID_HOST_MTU; else p_hcon->rem_mtu_size = p_cfg->mtu; - /* For now, always accept configuration from the other side */ p_cfg->flush_to_present = FALSE; - p_cfg->mtu_present = FALSE; - p_cfg->result = L2CAP_CFG_OK; + p_cfg->mtu_present = FALSE; + p_cfg->result = L2CAP_CFG_OK; - L2CA_ConfigRsp (l2cap_cid, p_cfg); + L2CA_ConfigRsp(l2cap_cid, p_cfg); if (l2cap_cid == p_hcon->ctrl_cid) - p_hcon->conn_flags |= HID_CONN_FLAGS_HIS_CTRL_CFG_DONE; + p_hcon->conn_flags |= HID_CONN_FLAGS_THEIR_CTRL_CFG_DONE; else - p_hcon->conn_flags |= HID_CONN_FLAGS_HIS_INTR_CFG_DONE; + p_hcon->conn_flags |= HID_CONN_FLAGS_THEIR_INTR_CFG_DONE; - /* If all configuration is complete, change state and tell management we are up */ - if (((p_hcon->conn_flags & HID_CONN_FLAGS_ALL_CONFIGURED) == HID_CONN_FLAGS_ALL_CONFIGURED) - && (p_hcon->conn_state == HID_CONN_STATE_CONFIG)) + if ((p_hcon->conn_flags & HID_CONN_FLAGS_ALL_CONFIGURED) + == HID_CONN_FLAGS_ALL_CONFIGURED + && p_hcon->conn_state == HID_CONN_STATE_CONFIG) { p_hcon->conn_state = HID_CONN_STATE_CONNECTED; hh_cb.devices[dhandle].state = HID_DEV_CONNECTED; - hh_cb.callback( dhandle, HID_HDEV_EVT_OPEN, 0, NULL ) ; + (*hh_cb.callback)(dhandle, HID_HDEV_EVT_OPEN, 0, NULL); } } - -/******************************************************************************* -** -** Function hidh_l2cif_config_cfm -** -** Description This function processes the L2CAP configuration confirmation -** event. -** -** Returns void -** -*******************************************************************************/ -static void hidh_l2cif_config_cfm (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg) +static void hidh_l2cif_config_cfm(UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg) { UINT8 dhandle; - tHID_CONN *p_hcon = NULL; - UINT32 reason; + tHID_CONN *p_hcon = NULL; + UINT32 reason; - HIDH_TRACE_EVENT2 ("HID - Rcvd cfg cfm, CID: 0x%x Result: %d", l2cap_cid, p_cfg->result); + HIDH_TRACE(EVENT, "HID - Rcvd cfg cfm, CID: 0x%x Result: %d", l2cap_cid, + p_cfg->result); - /* Find CCB based on CID */ - if( (dhandle = find_conn_by_cid(l2cap_cid)) < HID_HOST_MAX_DEVICES ) + if ((dhandle = find_conn_by_cid(l2cap_cid)) != HID_HOST_MAX_DEVICES) p_hcon = &hh_cb.devices[dhandle].conn; if (p_hcon == NULL) { - HIDH_TRACE_WARNING1 ("HID - Rcvd L2CAP cfg ind, unknown CID: 0x%x", l2cap_cid); + HIDH_TRACE(WARNING, "HID - Rcvd L2CAP cfg ind, unknown CID: 0x%x", + l2cap_cid); return; } - /* If configuration failed, disconnect the channel(s) */ if (p_cfg->result != L2CAP_CFG_OK) { - hidh_conn_disconnect (dhandle); - reason = HID_L2CAP_CFG_FAIL | (UINT32) p_cfg->result ; - hh_cb.callback( dhandle, HID_HDEV_EVT_CLOSE, reason, NULL ) ; + hidh_conn_disconnect(dhandle); + + reason = HID_L2CAP_CFG_FAIL | p_cfg->result; + (*hh_cb.callback)(dhandle, HID_HDEV_EVT_CLOSE, reason, NULL); return; } if (l2cap_cid == p_hcon->ctrl_cid) - p_hcon->conn_flags |= HID_CONN_FLAGS_MY_CTRL_CFG_DONE; + p_hcon->conn_flags |= HID_CONN_FLAGS_OUR_CTRL_CFG_DONE; else - p_hcon->conn_flags |= HID_CONN_FLAGS_MY_INTR_CFG_DONE; + p_hcon->conn_flags |= HID_CONN_FLAGS_OUR_INTR_CFG_DONE; - /* If all configuration is complete, change state and tell management we are up */ - if (((p_hcon->conn_flags & HID_CONN_FLAGS_ALL_CONFIGURED) == HID_CONN_FLAGS_ALL_CONFIGURED) - && (p_hcon->conn_state == HID_CONN_STATE_CONFIG)) + if ((p_hcon->conn_flags & HID_CONN_FLAGS_ALL_CONFIGURED) + == HID_CONN_FLAGS_ALL_CONFIGURED + && p_hcon->conn_state == HID_CONN_STATE_CONFIG) { p_hcon->conn_state = HID_CONN_STATE_CONNECTED; hh_cb.devices[dhandle].state = HID_DEV_CONNECTED; - hh_cb.callback( dhandle, HID_HDEV_EVT_OPEN, 0, NULL ) ; + (*hh_cb.callback)(dhandle, HID_HDEV_EVT_OPEN, 0, NULL); } } - -/******************************************************************************* -** -** Function hidh_l2cif_disconnect_ind -** -** Description This function handles a disconnect event from L2CAP. If -** requested to, we ack the disconnect before dropping the CCB -** -** Returns void -** -*******************************************************************************/ -static void hidh_l2cif_disconnect_ind (UINT16 l2cap_cid, BOOLEAN ack_needed) +static void hidh_l2cif_disconnect_ind(UINT16 l2cap_cid, BOOLEAN ack_needed) { UINT8 dhandle; - tHID_CONN *p_hcon = NULL; + tHID_CONN *p_hcon = NULL; UINT16 disc_res = HCI_SUCCESS; UINT16 hid_close_evt_reason; - /* Find CCB based on CID */ - if( (dhandle = find_conn_by_cid(l2cap_cid)) < HID_HOST_MAX_DEVICES ) + if ((dhandle = find_conn_by_cid(l2cap_cid)) != HID_HOST_MAX_DEVICES) p_hcon = &hh_cb.devices[dhandle].conn; if (p_hcon == NULL) { - HIDH_TRACE_WARNING1 ("HID - Rcvd L2CAP disc, unknown CID: 0x%x", l2cap_cid); + HIDH_TRACE(WARNING, "HID - Rcvd L2CAP disc, unknown CID: 0x%x", + l2cap_cid); return; } if (ack_needed) - L2CA_DisconnectRsp (l2cap_cid); + L2CA_DisconnectRsp(l2cap_cid); - HIDH_TRACE_EVENT1 ("HID - Rcvd L2CAP disc, CID: 0x%x", l2cap_cid); + HIDH_TRACE(EVENT, "HID - Rcvd L2CAP disc, CID: 0x%x", l2cap_cid); p_hcon->conn_state = HID_CONN_STATE_DISCONNECTING; @@ -599,242 +476,204 @@ static void hidh_l2cif_disconnect_ind (UINT16 l2cap_cid, BOOLEAN ack_needed) else p_hcon->intr_cid = 0; - if ((p_hcon->ctrl_cid == 0) && (p_hcon->intr_cid == 0)) + if (!p_hcon->ctrl_cid && !p_hcon->intr_cid) { hh_cb.devices[dhandle].state = HID_DEV_NO_CONN; p_hcon->conn_state = HID_CONN_STATE_UNUSED; - if( !ack_needed ) + if (!ack_needed) disc_res = btm_get_acl_disc_reason_code(); -#if (HID_HOST_MAX_CONN_RETRY > 0) - if( (disc_res == HCI_ERR_CONNECTION_TOUT || disc_res == HCI_ERR_UNSPECIFIED) && - (!(hh_cb.devices[dhandle].attr_mask & HID_RECONN_INIT)) && - (hh_cb.devices[dhandle].attr_mask & HID_NORMALLY_CONNECTABLE)) - { - hh_cb.devices[dhandle].conn_tries = 0; - hh_cb.devices[dhandle].conn.timer_entry.param = (UINT32) dhandle; - btu_start_timer (&(hh_cb.devices[dhandle].conn.timer_entry), BTU_TTYPE_HID_HOST_REPAGE_TO, HID_HOST_REPAGE_WIN); - } - else -#endif + hid_close_evt_reason = p_hcon->disc_reason; + + if (disc_res == HCI_ERR_AUTH_FAILURE || disc_res == HCI_ERR_KEY_MISSING + || disc_res == HCI_ERR_HOST_REJECT_SECURITY + || disc_res == HCI_ERR_PAIRING_NOT_ALLOWED + || disc_res == HCI_ERR_UNIT_KEY_USED + || disc_res == HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED + || disc_res == HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE + || disc_res == HCI_ERR_REPEATED_ATTEMPTS) { - /* Set reason code for HID_HDEV_EVT_CLOSE */ - hid_close_evt_reason = p_hcon->disc_reason; - - /* If we got baseband sent HCI_DISCONNECT_COMPLETE_EVT due to security failure, then set reason to HID_ERR_AUTH_FAILED */ - if ((disc_res == HCI_ERR_AUTH_FAILURE) || - (disc_res == HCI_ERR_KEY_MISSING) || - (disc_res == HCI_ERR_HOST_REJECT_SECURITY) || - (disc_res == HCI_ERR_PAIRING_NOT_ALLOWED) || - (disc_res == HCI_ERR_UNIT_KEY_USED) || - (disc_res == HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED) || - (disc_res == HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE) || - (disc_res == HCI_ERR_REPEATED_ATTEMPTS)) - { - hid_close_evt_reason = HID_ERR_AUTH_FAILED; - } - - hh_cb.callback( dhandle, HID_HDEV_EVT_CLOSE, hid_close_evt_reason, NULL ) ; + hid_close_evt_reason = HID_ERR_AUTH_FAILED; } + + (*hh_cb.callback)(dhandle, HID_HDEV_EVT_CLOSE, hid_close_evt_reason, + NULL); } } - -/******************************************************************************* -** -** Function hidh_l2cif_disconnect_cfm -** -** Description This function handles a disconnect confirm event from L2CAP. -** -** Returns void -** -*******************************************************************************/ -static void hidh_l2cif_disconnect_cfm (UINT16 l2cap_cid, UINT16 result) +static void hidh_l2cif_disconnect_cfm(UINT16 l2cap_cid, UINT16 result) { UINT8 dhandle; - tHID_CONN *p_hcon = NULL; + tHID_CONN *p_hcon = NULL; - /* Find CCB based on CID */ - if( (dhandle = find_conn_by_cid(l2cap_cid)) < HID_HOST_MAX_DEVICES ) + if ((dhandle = find_conn_by_cid(l2cap_cid)) != HID_HOST_MAX_DEVICES) p_hcon = &hh_cb.devices[dhandle].conn; - if (p_hcon == NULL) + if (!p_hcon) { - HIDH_TRACE_WARNING1 ("HID - Rcvd L2CAP disc cfm, unknown CID: 0x%x", l2cap_cid); + HIDH_TRACE(WARNING, "HID - Rcvd L2CAP disc cfm, unknown CID: 0x%x", + l2cap_cid); return; } - HIDH_TRACE_EVENT1 ("HID - Rcvd L2CAP disc cfm, CID: 0x%x", l2cap_cid); + HIDH_TRACE(EVENT, "HID - Rcvd L2CAP disc cfm, CID: 0x%x", l2cap_cid); if (l2cap_cid == p_hcon->ctrl_cid) p_hcon->ctrl_cid = 0; else p_hcon->intr_cid = 0; - if ((p_hcon->ctrl_cid == 0) && (p_hcon->intr_cid == 0)) + if (!p_hcon->ctrl_cid && !p_hcon->intr_cid) { hh_cb.devices[dhandle].state = HID_DEV_NO_CONN; p_hcon->conn_state = HID_CONN_STATE_UNUSED; - hh_cb.callback( dhandle, HID_HDEV_EVT_CLOSE, p_hcon->disc_reason, NULL ) ; + (*hh_cb.callback)(dhandle, HID_HDEV_EVT_CLOSE, p_hcon->disc_reason, + NULL); } } - -/******************************************************************************* -** -** Function hidh_l2cif_cong_ind -** -** Description This function handles a congestion status event from L2CAP. -** -** Returns void -** -*******************************************************************************/ -static void hidh_l2cif_cong_ind (UINT16 l2cap_cid, BOOLEAN congested) +static void hidh_l2cif_cong_ind(UINT16 l2cap_cid, BOOLEAN congested) { UINT8 dhandle; - tHID_CONN *p_hcon = NULL; + tHID_CONN *p_hcon = NULL; - /* Find CCB based on CID */ - if( (dhandle = find_conn_by_cid(l2cap_cid)) < HID_HOST_MAX_DEVICES ) + if ((dhandle = find_conn_by_cid(l2cap_cid)) != HID_HOST_MAX_DEVICES) p_hcon = &hh_cb.devices[dhandle].conn; - if (p_hcon == NULL) + if (!p_hcon) { - HIDH_TRACE_WARNING1 ("HID - Rcvd L2CAP congestion status, unknown CID: 0x%x", l2cap_cid); + HIDH_TRACE(WARNING, + "HID - Rcvd L2CAP congestion status, unknown CID: 0x%x", + l2cap_cid); return; } - HIDH_TRACE_EVENT2 ("HID - Rcvd L2CAP congestion status, CID: 0x%x Cong: %d", l2cap_cid, congested); + HIDH_TRACE(EVENT, "HID - Rcvd L2CAP congestion status, CID: 0x%x Cong: %d", + l2cap_cid, congested); if (congested) p_hcon->conn_flags |= HID_CONN_FLAGS_CONGESTED; else - { p_hcon->conn_flags &= ~HID_CONN_FLAGS_CONGESTED; - - } } - -/******************************************************************************* -** -** Function hidh_l2cif_data_ind -** -** Description This function is called when data is received from L2CAP. -** if we are the originator of the connection, we are the SDP -** client, and the received message is queued up for the client. -** -** If we are the destination of the connection, we are the SDP -** server, so the message is passed to the server processing -** function. -** -** Returns void -** -*******************************************************************************/ -static void hidh_l2cif_data_ind (UINT16 l2cap_cid, BT_HDR *p_msg) +static void hidh_l2cif_data_ind(UINT16 l2cap_cid, BT_HDR *p_msg) { - UINT8 *p_data = (UINT8 *)(p_msg + 1) + p_msg->offset; - UINT8 ttype, param, rep_type, evt; + UINT8 *p_data = (UINT8 *)(p_msg + 1) + p_msg->offset; + UINT8 ttype; + UINT8 param; + UINT8 rep_type; + UINT8 evt; UINT8 dhandle; - tHID_CONN *p_hcon = NULL; - - HIDH_TRACE_DEBUG1 ("HID - hidh_l2cif_data_ind [l2cap_cid=0x%04x]", l2cap_cid); + tHID_CONN *p_hcon = NULL; - /* Find CCB based on CID */ - if ((dhandle = find_conn_by_cid(l2cap_cid)) < HID_HOST_MAX_DEVICES) + if ((dhandle = find_conn_by_cid(l2cap_cid)) != HID_HOST_MAX_DEVICES) p_hcon = &hh_cb.devices[dhandle].conn; - if (p_hcon == NULL) + if (!p_hcon) { - HIDH_TRACE_WARNING1 ("HID - Rcvd L2CAP data, unknown CID: 0x%x", l2cap_cid); - GKI_freebuf (p_msg); + HIDH_TRACE(WARNING, "HID - Rcvd L2CAP data, unknown CID: 0x%x\0\0\0\0\0\0\0", + l2cap_cid); + GKI_freebuf(p_msg); return; } - - ttype = HID_GET_TRANS_FROM_HDR(*p_data); - param = HID_GET_PARAM_FROM_HDR(*p_data); + ttype = HID_GET_TRANS_FROM_HDR(*p_data); + param = HID_GET_PARAM_FROM_HDR(*p_data); rep_type = param & HID_PAR_REP_TYPE_MASK; - p_data++; + ++p_data; - /* Get rid of the data type */ - p_msg->len--; - p_msg->offset++; + --p_msg->len; + ++p_msg->offset; switch (ttype) { case HID_TRANS_HANDSHAKE: - hh_cb.callback(dhandle, HID_HDEV_EVT_HANDSHAKE, param, NULL); - GKI_freebuf (p_msg); + (*hh_cb.callback)(dhandle, HID_HDEV_EVT_HANDSHAKE, param, NULL); + GKI_freebuf(p_msg); break; case HID_TRANS_CONTROL: switch (param) { case HID_PAR_CONTROL_VIRTUAL_CABLE_UNPLUG: - hidh_conn_disconnect( dhandle ) ; - /* Device is unplugging from us. Tell USB */ - hh_cb.callback(dhandle, HID_HDEV_EVT_VC_UNPLUG, 0, NULL); + hidh_conn_disconnect(dhandle); + (*hh_cb.callback)(dhandle, HID_HDEV_EVT_VC_UNPLUG, 0, NULL); break; default: break; } - GKI_freebuf (p_msg); - break; + GKI_freebuf(p_msg); + break; case HID_TRANS_DATA: - evt = (hh_cb.devices[dhandle].conn.intr_cid == l2cap_cid) ? - HID_HDEV_EVT_INTR_DATA : HID_HDEV_EVT_CTRL_DATA; - hh_cb.callback(dhandle, evt, rep_type, p_msg); + evt = hh_cb.devices[dhandle].conn.intr_cid == l2cap_cid + ? HID_HDEV_EVT_INTR_DATA + : HID_HDEV_EVT_CTRL_DATA; + (*hh_cb.callback)(dhandle, evt, rep_type, p_msg); break; case HID_TRANS_DATAC: - evt = (hh_cb.devices[dhandle].conn.intr_cid == l2cap_cid) ? - HID_HDEV_EVT_INTR_DATC : HID_HDEV_EVT_CTRL_DATC; - hh_cb.callback(dhandle, evt, rep_type, p_msg); + evt = hh_cb.devices[dhandle].conn.intr_cid == l2cap_cid + ? HID_HDEV_EVT_INTR_DATC + : HID_HDEV_EVT_CTRL_DATC; + (*hh_cb.callback)(dhandle, evt, rep_type, p_msg); break; default: - GKI_freebuf (p_msg); + GKI_freebuf(p_msg); break; } +} +# if 0 + +UINT8 hidh_conn_snd_data(UINT8 dhandle /* r1+0x8 */, UINT8 trans_type /* r25 */, + UINT8 param /* r22 */, UINT16 data /* r24 */, + UINT8 report_id /* r23 */, BT_HDR *buf /* r31 */) +{ + struct hid_conn *p_hcon; // r30 + BT_HDR *p_buf; // r29 + UINT8 *p_out; // r27 + UINT16 bytes_copied; // r28 + UINT8 seg_req; // r1+0xC + UINT16 data_size; // r26 + UINT16 cid; // r1+0xE + UINT8 pool_id; // r1+0xB + UINT8 use_data; // r1+0xA + UINT8 blank_datc; // r1+0x9 + + // References + // -> struct host_ctb hh_cb; } -/******************************************************************************* -** -** Function hidh_conn_snd_data -** -** Description This function is sends out data. -** -** Returns tHID_STATUS -** -*******************************************************************************/ -tHID_STATUS hidh_conn_snd_data (UINT8 dhandle, UINT8 trans_type, UINT8 param, - UINT16 data, UINT8 report_id, BT_HDR *buf) +#endif +tHID_STATUS hidh_conn_snd_data(UINT8 dhandle, UINT8 trans_type, UINT8 param, + UINT16 data, UINT8 report_id, BT_HDR *buf) { - tHID_CONN *p_hcon = &hh_cb.devices[dhandle].conn; - BT_HDR *p_buf; - UINT8 *p_out; - UINT16 bytes_copied; - BOOLEAN seg_req = FALSE; - UINT16 data_size; - UINT16 cid; - UINT8 pool_id; - UINT8 use_data = 0 ; - BOOLEAN blank_datc = FALSE; + tHID_CONN *p_hcon = &hh_cb.devices[dhandle].conn; + BT_HDR *p_buf; + UINT8 *p_out; + UINT16 bytes_copied; + BOOLEAN seg_req = FALSE; + UINT16 data_size; + UINT16 cid; + UINT8 pool_id; + UINT8 use_data = 0; + BOOLEAN blank_datc = FALSE; if (p_hcon->conn_flags & HID_CONN_FLAGS_CONGESTED) { if (buf) - GKI_freebuf ((void *)buf); - return( HID_ERR_CONGESTED ); + GKI_freebuf(buf); + + return HID_ERR_CONGESTED; } - switch( trans_type ) + switch (trans_type) { case HID_TRANS_CONTROL: case HID_TRANS_GET_REPORT: @@ -846,25 +685,27 @@ tHID_STATUS hidh_conn_snd_data (UINT8 dhandle, UINT8 trans_type, UINT8 param, cid = p_hcon->ctrl_cid; pool_id = HID_CONTROL_POOL_ID; break; + case HID_TRANS_DATA: cid = p_hcon->intr_cid; pool_id = HID_INTERRUPT_POOL_ID; break; + default: - return (HID_ERR_INVALID_PARAM) ; + return HID_ERR_INVALID_PARAM; } - if( trans_type == HID_TRANS_SET_IDLE ) + if (trans_type == HID_TRANS_SET_IDLE) use_data = 1; - else if( (trans_type == HID_TRANS_GET_REPORT) && (param & 0x08) ) + else if (trans_type == HID_TRANS_GET_REPORT && (param & 0x08) != 0) use_data = 2; do { - if ( buf == NULL || blank_datc ) + if (buf == NULL || blank_datc) { - if((p_buf = (BT_HDR *)GKI_getpoolbuf (pool_id)) == NULL) - return (HID_ERR_NO_RESOURCES); + if ((p_buf = GKI_getpoolbuf(pool_id)) == NULL) + return HID_ERR_NO_RESOURCES; p_buf->offset = L2CAP_MIN_OFFSET; seg_req = FALSE; @@ -872,10 +713,10 @@ tHID_STATUS hidh_conn_snd_data (UINT8 dhandle, UINT8 trans_type, UINT8 param, bytes_copied = 0; blank_datc = FALSE; } - else if ( (buf->len > (p_hcon->rem_mtu_size - 1))) + else if (buf->len > p_hcon->rem_mtu_size - 1) { - if((p_buf = (BT_HDR *)GKI_getpoolbuf (pool_id)) == NULL) - return (HID_ERR_NO_RESOURCES); + if ((p_buf = GKI_getpoolbuf(pool_id)) == NULL) + return HID_ERR_NO_RESOURCES; p_buf->offset = L2CAP_MIN_OFFSET; seg_req = TRUE; @@ -884,156 +725,124 @@ tHID_STATUS hidh_conn_snd_data (UINT8 dhandle, UINT8 trans_type, UINT8 param, } else { - p_buf = buf ; + p_buf = buf; p_buf->offset -= 1; seg_req = FALSE; data_size = buf->len; bytes_copied = buf->len; } - p_out = (UINT8 *)(p_buf + 1) + p_buf->offset; - *p_out++ = HID_BUILD_HDR(trans_type, param); + p_out = (UINT8 *)(p_buf + 1) + p_buf->offset; + *p_out++ = HID_BUILD_HDR(trans_type, param); - /* If report ID required for this device */ - if( (trans_type == HID_TRANS_GET_REPORT) && (report_id != 0) ) + if (trans_type == HID_TRANS_GET_REPORT && report_id != 0) { *p_out = report_id; data_size = bytes_copied = 1; } - if (seg_req) { - memcpy (p_out, (((UINT8 *)(buf+1)) + buf->offset), bytes_copied); + memcpy(p_out, (UINT8 *)(buf + 1) + buf->offset, bytes_copied); buf->offset += bytes_copied; buf->len -= bytes_copied; } - else if( use_data == 1) + else if (use_data == 1) { - *(p_out+bytes_copied) = data & 0xff; + p_out[bytes_copied] = data & 0xff; } - else if( use_data == 2 ) + else if (use_data == 2) { - *(p_out+bytes_copied) = data & 0xff; - *(p_out+bytes_copied+1) = (data >> 8) & 0xff ; + p_out[bytes_copied] = data & 0xff; + 1[p_out + bytes_copied] = (data >> 8) & 0xff; } - p_buf->len = bytes_copied + 1 + use_data; - data_size -= bytes_copied; + p_buf->len = bytes_copied + 1 + use_data; + data_size -= bytes_copied; - /* Send the buffer through L2CAP */ - if ((p_hcon->conn_flags & HID_CONN_FLAGS_CONGESTED) || (!L2CA_DataWrite (cid, p_buf))) - return (HID_ERR_CONGESTED); + if (p_hcon->conn_flags & HID_CONN_FLAGS_CONGESTED + || !L2CA_DataWrite(cid, p_buf)) + { + return HID_ERR_CONGESTED; + } if (data_size) + { trans_type = HID_TRANS_DATAC; - else if( bytes_copied == (p_hcon->rem_mtu_size - 1) ) + } + else if (bytes_copied == p_hcon->rem_mtu_size - 1) { trans_type = HID_TRANS_DATAC; blank_datc = TRUE; } + } while (data_size || blank_datc); - } while ((data_size != 0) || blank_datc ) ; - - return (HID_SUCCESS); + return HID_SUCCESS; } -/******************************************************************************* -** -** Function hidh_conn_initiate -** -** Description This function is called by the management to create a connection. -** -** Returns void -** -*******************************************************************************/ -tHID_STATUS hidh_conn_initiate (UINT8 dhandle) -{ - UINT8 service_id = BTM_SEC_SERVICE_HID_NOSEC_CTRL; - UINT32 mx_chan_id = HID_NOSEC_CHN; +tHID_STATUS hidh_conn_initiate(UINT8 dhandle) +{ tHID_HOST_DEV_CTB *p_dev = &hh_cb.devices[dhandle]; - if( p_dev->conn.conn_state != HID_CONN_STATE_UNUSED ) - return( HID_ERR_CONN_IN_PROCESS ); + if (p_dev->conn.conn_state != HID_CONN_STATE_UNUSED) + return HID_ERR_CONN_IN_PROCESS; p_dev->conn.ctrl_cid = 0; p_dev->conn.intr_cid = 0; - p_dev->conn.disc_reason = HID_L2CAP_CONN_FAIL; /* Reset initial reason for CLOSE_EVT: Connection Attempt was made but failed */ - - /* We are the originator of this connection */ + p_dev->conn.disc_reason = HID_L2CAP_CONN_FAIL; p_dev->conn.conn_flags = HID_CONN_FLAGS_IS_ORIG; - if(p_dev->attr_mask & HID_SEC_REQUIRED) + if ((p_dev->conn.ctrl_cid = L2CA_ConnectReq(HID_PSM_CONTROL, p_dev->addr)) + == 0) { - service_id = BTM_SEC_SERVICE_HID_SEC_CTRL; - mx_chan_id = HID_SEC_CHN; - } - BTM_SetOutService (p_dev->addr, service_id, mx_chan_id); + HIDH_TRACE(WARNING, "HID - Originate failed"); - /* Check if L2CAP started the connection process */ - if ((p_dev->conn.ctrl_cid = L2CA_ConnectReq (HID_PSM_CONTROL, p_dev->addr)) == 0) - { - HIDH_TRACE_WARNING0 ("HID - Originate failed"); - dhandle = (p_dev - &(hh_cb.devices[0]))/(sizeof( tHID_HOST_DEV_CTB )) ; - hh_cb.callback( dhandle, HID_HDEV_EVT_CLOSE, HID_ERR_L2CAP_FAILED, NULL ) ; + /* ERRATUM: pointer subtraction already implicitly divides by size of + * pointed to type; doing it again manually is incorrect + */ + dhandle = (p_dev - hh_cb.devices) / sizeof *p_dev; // NOLINT + + (*hh_cb.callback)(dhandle, HID_HDEV_EVT_CLOSE, HID_ERR_L2CAP_FAILED, + NULL); } else { - /* Transition to the next appropriate state, waiting for connection confirm on control channel. */ p_dev->conn.conn_state = HID_CONN_STATE_CONNECTING_CTRL; } - return( HID_SUCCESS ); + return HID_SUCCESS; } - -/******************************************************************************* -** -** Function find_conn_by_cid -** -** Description This function finds a connection control block based on CID -** -** Returns address of control block, or NULL if not found -** -*******************************************************************************/ -static UINT8 find_conn_by_cid (UINT16 cid) +static UINT8 find_conn_by_cid(UINT16 cid) { - UINT8 xx; + UINT8 xx; for (xx = 0; xx < HID_HOST_MAX_DEVICES; xx++) { - if ((hh_cb.devices[xx].in_use) && (hh_cb.devices[xx].conn.conn_state != HID_CONN_STATE_UNUSED) - && ((hh_cb.devices[xx].conn.ctrl_cid == cid) || (hh_cb.devices[xx].conn.intr_cid == cid))) + if (hh_cb.devices[xx].in_use + && hh_cb.devices[xx].conn.conn_state != HID_CONN_STATE_UNUSED + && (hh_cb.devices[xx].conn.ctrl_cid == cid + || hh_cb.devices[xx].conn.intr_cid == cid)) + { break; + } } - return (xx); + return xx; } -void hidh_conn_dereg( void ) +void hidh_conn_dereg(void) { - L2CA_Deregister (HID_PSM_CONTROL); - L2CA_Deregister (HID_PSM_INTERRUPT); + L2CA_Deregister(HID_PSM_CONTROL); + L2CA_Deregister(HID_PSM_INTERRUPT); } -/******************************************************************************* -** -** Function hidh_conn_retry -** -** Description This function is called to retry a failed connection. -** -** Returns void -** -*******************************************************************************/ -static void hidh_conn_retry( UINT8 dhandle ) +static void hidh_conn_retry(UINT8 dhandle) { tHID_HOST_DEV_CTB *p_dev = &hh_cb.devices[dhandle]; p_dev->conn.conn_state = HID_CONN_STATE_UNUSED; - p_dev->conn.timer_entry.param = (UINT32) dhandle; -#if (HID_HOST_REPAGE_WIN > 0) - btu_start_timer (&(p_dev->conn.timer_entry), BTU_TTYPE_HID_HOST_REPAGE_TO, HID_HOST_REPAGE_WIN); -#else - hidh_proc_repage_timeout( &(p_dev->conn.timer_entry) ); -#endif + p_dev->conn.timer_entry.param = (TIMER_PARAM_TYPE)dhandle; + btu_start_timer(&p_dev->conn.timer_entry, BTU_TTYPE_HID_HOST_REPAGE_TO, + HID_HOST_REPAGE_WIN); } diff --git a/src/revolution/BTE/stack/l2cap/l2c_api.c b/src/revolution/BTE/stack/l2cap/l2c_api.c index f2e1afc..53c6d1f 100644 --- a/src/revolution/BTE/stack/l2cap/l2c_api.c +++ b/src/revolution/BTE/stack/l2cap/l2c_api.c @@ -16,715 +16,320 @@ * ******************************************************************************/ +/* Original source: + * bluedroid + * stack/l2cap/l2c_api.c + */ + +/* Includes changes by muff1n1634 and for this repository (KoopTheKoopa) */ + /****************************************************************************** * - * This file contains the L2CAP API code + * This file contains the L2CAP API functions. * ******************************************************************************/ -#include +#include "l2c_api.h" + +#include #include -#include -#include "gki.h" +#include + +#include "bt_target.h" +#include "bt_trace.h" #include "bt_types.h" +#include "data_types.h" + +#include "btm_api.h" +#include "btu.h" +#include "gki.h" #include "hcidefs.h" -#include "hcimsgs.h" #include "l2cdefs.h" #include "l2c_int.h" -#include "btu.h" -#include "btm_api.h" -/******************************************************************************* -** -** Function L2CA_Register -** -** Description Other layers call this function to register for L2CAP -** services. -** -** Returns PSM to use or zero if error. Typically, the PSM returned -** is the same as was passed in, but for an outgoing-only -** connection to a dynamic PSM, a "virtual" PSM is returned -** and should be used in the calls to L2CA_ConnectReq(), -** L2CA_ErtmConnectReq() and L2CA_Deregister() -** -*******************************************************************************/ -UINT16 L2CA_Register (UINT16 psm, tL2CAP_APPL_INFO *p_cb_info) +BOOLEAN L2CA_Register(UINT16 psm, tL2CAP_APPL_INFO *p_cb_info) { - tL2C_RCB *p_rcb; - UINT16 vpsm = psm; - - L2CAP_TRACE_API1 ("L2CAP - L2CA_Register() called for PSM: 0x%04x", psm); - - /* Verify that the required callback info has been filled in - ** Note: Connection callbacks are required but not checked - ** for here because it is possible to be only a client - ** or only a server. - */ - if ((!p_cb_info->pL2CA_ConfigCfm_Cb) - || (!p_cb_info->pL2CA_ConfigInd_Cb) - || (!p_cb_info->pL2CA_DataInd_Cb) - || (!p_cb_info->pL2CA_DisconnectInd_Cb)) - { - L2CAP_TRACE_ERROR1 ("L2CAP - no cb registering PSM: 0x%04x", psm); - return (0); - } + tL2C_RCB *p_rcb; - /* Verify PSM is valid */ - if (L2C_INVALID_PSM(psm)) + L2CAP_TRACE(API, "L2CAP - L2CA_Register() called for PSM: 0x%04x", psm); + + if (!p_cb_info->pL2CA_ConfigCfm_Cb || !p_cb_info->pL2CA_ConfigInd_Cb + || !p_cb_info->pL2CA_DataInd_Cb || !p_cb_info->pL2CA_DisconnectInd_Cb) { - L2CAP_TRACE_ERROR1 ("L2CAP - invalid PSM value, PSM: 0x%04x", psm); - return (0); + L2CAP_TRACE(ERROR, "L2CAP - no cb registering PSM: 0x%04x", psm); + return FALSE; } - /* Check if this is a registration for an outgoing-only connection to */ - /* a dynamic PSM. If so, allocate a "virtual" PSM for the app to use. */ - if ( (psm >= 0x1001) && (p_cb_info->pL2CA_ConnectInd_Cb == NULL) ) + if (L2C_INVALID_PSM(psm)) { - for (vpsm = 0x1002; vpsm < 0x8000; vpsm += 2) - { - if ((p_rcb = l2cu_find_rcb_by_psm (vpsm)) == NULL) - break; - } - - L2CAP_TRACE_API2 ("L2CA_Register - Real PSM: 0x%04x Virtual PSM: 0x%04x", psm, vpsm); + L2CAP_TRACE(ERROR, "L2CAP - invalid PSM value, PSM: 0x%04x", psm); + return FALSE; } - /* If registration block already there, just overwrite it */ - if ((p_rcb = l2cu_find_rcb_by_psm (vpsm)) == NULL) + if ((p_rcb = l2cu_find_rcb_by_psm(psm)) == NULL) { - if ((p_rcb = l2cu_allocate_rcb (vpsm)) == NULL) + if ((p_rcb = l2cu_allocate_rcb(psm)) == NULL) { - L2CAP_TRACE_WARNING2 ("L2CAP - no RCB available, PSM: 0x%04x vPSM: 0x%04x", psm, vpsm); - return (0); + L2CAP_TRACE(WARNING, "L2CAP - no RCB available, PSM: 0x%04x", psm); + return FALSE; } } - p_rcb->api = *p_cb_info; - p_rcb->real_psm = psm; + p_rcb->api = *p_cb_info; - return (vpsm); + return TRUE; } - - -/******************************************************************************* -** -** Function L2CA_Deregister -** -** Description Other layers call this function to de-register for L2CAP -** services. -** -** Returns void -** -*******************************************************************************/ -void L2CA_Deregister (UINT16 psm) +void L2CA_Deregister(UINT16 psm) { - tL2C_RCB *p_rcb; - tL2C_CCB *p_ccb; - tL2C_LCB *p_lcb; - int ii; + tL2C_RCB *p_rcb; - L2CAP_TRACE_API1 ("L2CAP - L2CA_Deregister() called for PSM: 0x%04x", psm); + L2CAP_TRACE(API, "L2CAP - L2CA_Deregister() called for PSM: 0x%04x", psm); - if ((p_rcb = l2cu_find_rcb_by_psm (psm)) != NULL) + if ((p_rcb = l2cu_find_rcb_by_psm(psm)) != NULL) { - p_lcb = &l2cb.lcb_pool[0]; - for (ii = 0; ii < MAX_L2CAP_LINKS; ii++, p_lcb++) - { - if (p_lcb->in_use) - { - if (((p_ccb = p_lcb->ccb_queue.p_first_ccb) == NULL) - || (p_lcb->link_state == LST_DISCONNECTING)) - continue; - - if ((p_ccb->in_use) && - ((p_ccb->chnl_state == CST_W4_L2CAP_DISCONNECT_RSP) || - (p_ccb->chnl_state == CST_W4_L2CA_DISCONNECT_RSP))) - continue; - - if (p_ccb->p_rcb == p_rcb) - l2c_csm_execute (p_ccb, L2CEVT_L2CA_DISCONNECT_REQ, NULL); - } - } - l2cu_release_rcb (p_rcb); + l2cu_release_rcb(p_rcb); } else { - L2CAP_TRACE_WARNING1 ("L2CAP - PSM: 0x%04x not found for deregistration", psm); + L2CAP_TRACE(WARNING, "L2CAP - PSM: 0x%04x not found for deregistration", + psm); } } -/******************************************************************************* -** -** Function L2CA_AllocatePSM -** -** Description Other layers call this function to find an unused PSM for L2CAP -** services. -** -** Returns PSM to use. -** -*******************************************************************************/ -UINT16 L2CA_AllocatePSM(void) +UINT16 L2CA_ConnectReq(UINT16 psm, BD_ADDR p_bd_addr) { - BOOLEAN done = FALSE; - UINT16 psm = l2cb.dyn_psm; + tL2C_LCB *p_lcb; + tL2C_CCB *p_ccb; + tL2C_RCB *p_rcb; - L2CAP_TRACE_API0( "L2CA_AllocatePSM"); - while (!done) - { - psm += 2; - if (psm > 0xfeff) - { - psm = 0x1001; - } - else if (psm & 0x0100) - { - /* the upper byte must be even */ - psm += 0x0100; - } - - /* if psm is in range of reserved BRCM Aware features */ - if ((BRCM_RESERVED_PSM_START <= psm)&&(psm <= BRCM_RESERVED_PSM_END)) - continue; - - /* make sure the newlly allocated psm is not used right now */ - if ((l2cu_find_rcb_by_psm (psm)) == NULL) - done = TRUE; - } - l2cb.dyn_psm = psm; - - return(psm); -} - -/******************************************************************************* -** -** Function L2CA_ConnectReq -** -** Description Higher layers call this function to create an L2CAP connection. -** Note that the connection is not established at this time, but -** connection establishment gets started. The callback function -** will be invoked when connection establishes or fails. -** -** Returns the CID of the connection, or 0 if it failed to start -** -*******************************************************************************/ -UINT16 L2CA_ConnectReq (UINT16 psm, BD_ADDR p_bd_addr) -{ - return L2CA_ErtmConnectReq (psm, p_bd_addr, NULL); -} - -/******************************************************************************* -** -** Function L2CA_ErtmConnectReq -** -** Description Higher layers call this function to create an L2CAP connection. -** Note that the connection is not established at this time, but -** connection establishment gets started. The callback function -** will be invoked when connection establishes or fails. -** -** Returns the CID of the connection, or 0 if it failed to start -** -*******************************************************************************/ -UINT16 L2CA_ErtmConnectReq (UINT16 psm, BD_ADDR p_bd_addr, tL2CAP_ERTM_INFO *p_ertm_info) -{ - tL2C_LCB *p_lcb; - tL2C_CCB *p_ccb; - tL2C_RCB *p_rcb; + L2CAP_TRACE(API, "L2CA_ConnectReq() PSM: 0x%04x", psm); - L2CAP_TRACE_API6 ("L2CA_ErtmConnectReq() PSM: 0x%04x BDA: %08x%04x p_ertm_info: 0x%08x allowed:0x%x preferred:%d", psm, - (p_bd_addr[0]<<24)+(p_bd_addr[1]<<16)+(p_bd_addr[2]<<8)+p_bd_addr[3], - (p_bd_addr[4]<<8)+p_bd_addr[5], p_ertm_info, - (p_ertm_info) ? p_ertm_info->allowed_modes : 0, (p_ertm_info) ? p_ertm_info->preferred_mode : 0); + L2CAP_TRACE(API, "L2CA_ConnectReq() BDA: %02x-%02x-%02x-%02x-%02x-%02x", + p_bd_addr[0], p_bd_addr[1], p_bd_addr[2], p_bd_addr[3], + p_bd_addr[4], p_bd_addr[5]); - /* Fail if we have not established communications with the controller */ if (!BTM_IsDeviceUp()) { - L2CAP_TRACE_WARNING0 ("L2CAP connect req - BTU not ready"); - return (0); + L2CAP_TRACE(WARNING, "L2CAP connect req - BTU not ready"); + return 0; } - /* Fail if the PSM is not registered */ - if ((p_rcb = l2cu_find_rcb_by_psm (psm)) == NULL) + + if ((p_rcb = l2cu_find_rcb_by_psm(psm)) == NULL) { - L2CAP_TRACE_WARNING1 ("L2CAP - no RCB for L2CA_conn_req, PSM: 0x%04x", psm); - return (0); + L2CAP_TRACE(WARNING, "L2CAP - no RCB for L2CA_conn_req, PSM: 0x%04x", + psm); + return 0; } - /* First, see if we already have a link to the remote */ - if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr)) == NULL) + if ((p_lcb = l2cu_find_lcb_by_bd_addr(p_bd_addr)) == NULL) { - /* No link. Get an LCB and start link establishment */ -#ifdef REVOLUTION - if ( ((p_lcb = l2cu_allocate_lcb (p_bd_addr)) == NULL) -#else - if ( ((p_lcb = l2cu_allocate_lcb (p_bd_addr, FALSE)) == NULL) -#endif - || (l2cu_create_conn(p_lcb) == FALSE) ) + if (((p_lcb = l2cu_allocate_lcb(p_bd_addr)) == NULL)) { - L2CAP_TRACE_WARNING2 ("L2CAP - conn not started for PSM: 0x%04x p_lcb: 0x%08x", psm, p_lcb); - return (0); + L2CAP_TRACE(WARNING, "L2CAP - no LCB for L2CA_conn_req"); + return 0; } - } - /* Allocate a channel control block */ - if ((p_ccb = l2cu_allocate_ccb (p_lcb, 0)) == NULL) - { - L2CAP_TRACE_WARNING1 ("L2CAP - no CCB for L2CA_conn_req, PSM: 0x%04x", psm); - return (0); + if (!l2cu_create_conn(p_lcb)) + return 0; } - /* Save registration info */ - p_ccb->p_rcb = p_rcb; - - if (p_ertm_info) + if (p_lcb->link_state == LST_DISCONNECTING) { - p_ccb->ertm_info = *p_ertm_info; - - /* Replace default indicators with the actual default pool */ - if (p_ccb->ertm_info.fcr_rx_pool_id == L2CAP_DEFAULT_ERM_POOL_ID) - p_ccb->ertm_info.fcr_rx_pool_id = L2CAP_FCR_RX_POOL_ID; - - if (p_ccb->ertm_info.fcr_tx_pool_id == L2CAP_DEFAULT_ERM_POOL_ID) - p_ccb->ertm_info.fcr_tx_pool_id = L2CAP_FCR_TX_POOL_ID; - - if (p_ccb->ertm_info.user_rx_pool_id == L2CAP_DEFAULT_ERM_POOL_ID) - p_ccb->ertm_info.user_rx_pool_id = HCI_ACL_POOL_ID; - - if (p_ccb->ertm_info.user_tx_pool_id == L2CAP_DEFAULT_ERM_POOL_ID) - p_ccb->ertm_info.user_tx_pool_id = HCI_ACL_POOL_ID; - - p_ccb->max_rx_mtu = GKI_get_pool_bufsize (p_ertm_info->user_rx_pool_id) - (L2CAP_MIN_OFFSET + L2CAP_SDU_LEN_OFFSET + L2CAP_FCS_LEN); + L2CAP_TRACE(API, + "L2CAP API - L2CA_conn_req rejected - link disconnecting"); + return 0; } - /* If link is up, start the L2CAP connection */ - if (p_lcb->link_state == LST_CONNECTED) + if ((p_ccb = l2cu_allocate_ccb(p_lcb)) == NULL) { - l2c_csm_execute (p_ccb, L2CEVT_L2CA_CONNECT_REQ, NULL); + L2CAP_TRACE(WARNING, "L2CAP - no CCB for L2CA_conn_req"); + return 0; } - /* If link is disconnecting, save link info to retry after disconnect - * Possible Race condition when a reconnect occurs - * on the channel during a disconnect of link. This - * ccb will be automatically retried after link disconnect - * arrives - */ - else if (p_lcb->link_state == LST_DISCONNECTING) - { - L2CAP_TRACE_DEBUG0 ("L2CAP API - link disconnecting: RETRY LATER"); + p_ccb->p_rcb = p_rcb; - /* Save ccb so it can be started after disconnect is finished */ - p_lcb->p_pending_ccb = p_ccb; - } + if (p_lcb->link_state == LST_CONNECTED) + l2c_csm_execute(p_ccb, L2CEVT_L2CA_CONNECT_REQ, NULL); - L2CAP_TRACE_API2 ("L2CAP - L2CA_conn_req(psm: 0x%04x) returned CID: 0x%04x", psm, p_ccb->local_cid); + L2CAP_TRACE(API, "L2CAP - L2CA_conn_req() returned CID: 0x%04x", + p_ccb->local_cid); - /* Return the local CID as our handle */ - return (p_ccb->local_cid); + return p_ccb->local_cid; } - -/******************************************************************************* -** -** Function L2CA_ConnectRsp -** -** Description Higher layers call this function to accept an incoming -** L2CAP connection, for which they had gotten an connect -** indication callback. -** -** Returns TRUE for success, FALSE for failure -** -*******************************************************************************/ -BOOLEAN L2CA_ConnectRsp (BD_ADDR p_bd_addr, UINT8 id, UINT16 lcid, UINT16 result, UINT16 status) +BOOLEAN L2CA_ConnectRsp(BD_ADDR p_bd_addr, UINT8 id, UINT16 lcid, UINT16 result, + UINT16 status) { - return L2CA_ErtmConnectRsp (p_bd_addr, id, lcid, result, status, NULL); -} - + tL2C_LCB *p_lcb; + tL2C_CCB *p_ccb; -/******************************************************************************* -** -** Function L2CA_ErtmConnectRsp -** -** Description Higher layers call this function to accept an incoming -** L2CAP connection, for which they had gotten an connect -** indication callback. -** -** Returns TRUE for success, FALSE for failure -** -*******************************************************************************/ -BOOLEAN L2CA_ErtmConnectRsp (BD_ADDR p_bd_addr, UINT8 id, UINT16 lcid, UINT16 result, - UINT16 status, tL2CAP_ERTM_INFO *p_ertm_info) -{ - tL2C_LCB *p_lcb; - tL2C_CCB *p_ccb; + L2CAP_TRACE(API, "L2CA_ConnectRsp() CID: 0x%04x Result: %d Status: %d", + lcid, result, status); - L2CAP_TRACE_API6 ("L2CA_ErtmConnectRsp() CID: 0x%04x Result: %d Status: %d BDA: %08x%04x p_ertm_info:0x%08x", - lcid, result, status, - (p_bd_addr[0]<<24)+(p_bd_addr[1]<<16)+(p_bd_addr[2]<<8)+p_bd_addr[3], - (p_bd_addr[4]<<8)+p_bd_addr[5], p_ertm_info); + L2CAP_TRACE(API, "L2CA_ConnectRsp() BDA: %02x-%02x-%02x-%02x-%02x-%02x", + p_bd_addr[0], p_bd_addr[1], p_bd_addr[2], p_bd_addr[3], + p_bd_addr[4], p_bd_addr[5]); - /* First, find the link control block */ - if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr)) == NULL) + if ((p_lcb = l2cu_find_lcb_by_bd_addr(p_bd_addr)) == NULL) { - /* No link. Get an LCB and start link establishment */ - L2CAP_TRACE_WARNING0 ("L2CAP - no LCB for L2CA_conn_rsp"); - return (FALSE); + L2CAP_TRACE(WARNING, "L2CAP - no LCB for L2CA_conn_rsp"); + return FALSE; } - /* Now, find the channel control block */ - if ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, lcid)) == NULL) + if ((p_ccb = l2cu_find_ccb_by_cid(p_lcb, lcid)) == NULL) { - L2CAP_TRACE_WARNING0 ("L2CAP - no CCB for L2CA_conn_rsp"); - return (FALSE); + L2CAP_TRACE(WARNING, "L2CAP - no CCB for L2CA_conn_rsp"); + return FALSE; } - /* The IDs must match */ if (p_ccb->remote_id != id) { - L2CAP_TRACE_WARNING2 ("L2CAP - bad id in L2CA_conn_rsp. Exp: %d Got: %d", p_ccb->remote_id, id); - return (FALSE); - } - - if (p_ertm_info) - { - p_ccb->ertm_info = *p_ertm_info; - - /* Replace default indicators with the actual default pool */ - if (p_ccb->ertm_info.fcr_rx_pool_id == L2CAP_DEFAULT_ERM_POOL_ID) - p_ccb->ertm_info.fcr_rx_pool_id = L2CAP_FCR_RX_POOL_ID; - - if (p_ccb->ertm_info.fcr_tx_pool_id == L2CAP_DEFAULT_ERM_POOL_ID) - p_ccb->ertm_info.fcr_tx_pool_id = L2CAP_FCR_TX_POOL_ID; - - if (p_ccb->ertm_info.user_rx_pool_id == L2CAP_DEFAULT_ERM_POOL_ID) - p_ccb->ertm_info.user_rx_pool_id = HCI_ACL_POOL_ID; - - if (p_ccb->ertm_info.user_tx_pool_id == L2CAP_DEFAULT_ERM_POOL_ID) - p_ccb->ertm_info.user_tx_pool_id = HCI_ACL_POOL_ID; - - p_ccb->max_rx_mtu = GKI_get_pool_bufsize (p_ertm_info->user_rx_pool_id) - (L2CAP_MIN_OFFSET + L2CAP_SDU_LEN_OFFSET + L2CAP_FCS_LEN); + L2CAP_TRACE(WARNING, + "L2CAP - bad id in L2CA_conn_rsp. Exp: %d Got: %d", + p_ccb->remote_id, id); + return FALSE; } if (result == L2CAP_CONN_OK) { - l2c_csm_execute (p_ccb, L2CEVT_L2CA_CONNECT_RSP, NULL); + l2c_csm_execute(p_ccb, L2CEVT_L2CA_CONNECT_RSP, NULL); } else { - tL2C_CONN_INFO conn_info; + tL2C_CONN_INFO conn_info; conn_info.l2cap_result = result; conn_info.l2cap_status = status; if (result == L2CAP_CONN_PENDING) - l2c_csm_execute (p_ccb, L2CEVT_L2CA_CONNECT_RSP, &conn_info); + l2c_csm_execute(p_ccb, L2CEVT_L2CA_CONNECT_RSP, &conn_info); else - l2c_csm_execute (p_ccb, L2CEVT_L2CA_CONNECT_RSP_NEG, &conn_info); + l2c_csm_execute(p_ccb, L2CEVT_L2CA_CONNECT_RSP_NEG, &conn_info); } - return (TRUE); + return TRUE; } - -/******************************************************************************* -** -** Function L2CA_ConfigReq -** -** Description Higher layers call this function to send configuration. -** -** Note: The FCR options of p_cfg are not used. -** -** Returns TRUE if configuration sent, else FALSE -** -*******************************************************************************/ -BOOLEAN L2CA_ConfigReq (UINT16 cid, tL2CAP_CFG_INFO *p_cfg) +BOOLEAN L2CA_ConfigReq(UINT16 cid, tL2CAP_CFG_INFO *p_cfg) { - tL2C_CCB *p_ccb; - - L2CAP_TRACE_API5 ("L2CA_ConfigReq() CID 0x%04x: fcr_present:%d (mode %d) mtu_present:%d (%d)", - cid, p_cfg->fcr_present, p_cfg->fcr.mode, p_cfg->mtu_present, p_cfg->mtu); + tL2C_CCB *p_ccb; - /* Find the channel control block. We don't know the link it is on. */ - if ((p_ccb = l2cu_find_ccb_by_cid (NULL, cid)) == NULL) - { - L2CAP_TRACE_WARNING1 ("L2CAP - no CCB for L2CA_cfg_req, CID: %d", cid); - return (FALSE); - } + L2CAP_TRACE(API, "L2CA_ConfigReq() CID: 0x%04x", cid); - /* We need to have at least one mode type common with the peer */ - if (!l2c_fcr_adj_our_req_options(p_ccb, p_cfg)) - return (FALSE); - - /* Don't adjust FCR options if not used */ - if ((!p_cfg->fcr_present)||(p_cfg->fcr.mode == L2CAP_FCR_BASIC_MODE)) + if ((p_ccb = l2cu_find_ccb_by_cid(NULL, cid)) == NULL) { - /* FCR and FCS options are not used in basic mode */ - p_cfg->fcs_present = FALSE; - p_cfg->ext_flow_spec_present = FALSE; - - if ( (p_cfg->mtu_present) && (p_cfg->mtu > L2CAP_MTU_SIZE) ) - { - L2CAP_TRACE_WARNING1 ("L2CAP - adjust MTU: %u too large", p_cfg->mtu); - p_cfg->mtu = L2CAP_MTU_SIZE; - } + L2CAP_TRACE(WARNING, "L2CAP - no CCB for L2CA_cfg_req, CID: %d", cid); + return FALSE; } - /* Save the adjusted configuration in case it needs to be used for renegotiation */ - p_ccb->our_cfg = *p_cfg; + p_cfg->fcr_present = FALSE; - l2c_csm_execute (p_ccb, L2CEVT_L2CA_CONFIG_REQ, p_cfg); + l2c_csm_execute(p_ccb, L2CEVT_L2CA_CONFIG_REQ, p_cfg); - return (TRUE); + return TRUE; } - -/******************************************************************************* -** -** Function L2CA_ConfigRsp -** -** Description Higher layers call this function to send a configuration -** response. -** -** Returns TRUE if configuration response sent, else FALSE -** -*******************************************************************************/ -BOOLEAN L2CA_ConfigRsp (UINT16 cid, tL2CAP_CFG_INFO *p_cfg) +BOOLEAN L2CA_ConfigRsp(UINT16 cid, tL2CAP_CFG_INFO *p_cfg) { - tL2C_CCB *p_ccb; + tL2C_CCB *p_ccb; - L2CAP_TRACE_API6 ("L2CA_ConfigRsp() CID: 0x%04x Result: %d MTU present:%d Flush TO:%d FCR:%d FCS:%d", - cid, p_cfg->result, p_cfg->mtu_present, p_cfg->flush_to_present, p_cfg->fcr_present, p_cfg->fcs_present); + L2CAP_TRACE(API, "L2CA_ConfigRsp() CID: 0x%04x Result: %d", cid, + p_cfg->result); - /* Find the channel control block. We don't know the link it is on. */ - if ((p_ccb = l2cu_find_ccb_by_cid (NULL, cid)) == NULL) + if ((p_ccb = l2cu_find_ccb_by_cid(NULL, cid)) == NULL) { - L2CAP_TRACE_WARNING1 ("L2CAP - no CCB for L2CA_cfg_rsp, CID: %d", cid); - return (FALSE); + L2CAP_TRACE(WARNING, "L2CAP - no CCB for L2CA_cfg_rsp, CID: %d", cid); + return FALSE; } - if ( (p_cfg->result == L2CAP_CFG_OK) || (p_cfg->result == L2CAP_CFG_PENDING) ) - l2c_csm_execute (p_ccb, L2CEVT_L2CA_CONFIG_RSP, p_cfg); + if (p_cfg->result == L2CAP_CFG_OK) + l2c_csm_execute(p_ccb, L2CEVT_L2CA_CONFIG_RSP, p_cfg); else - { - p_cfg->fcr_present = FALSE; /* FCR options already negotiated before this point */ - - /* Clear out any cached options that are being returned as an error (excluding FCR) */ - if (p_cfg->mtu_present) - p_ccb->peer_cfg.mtu_present = FALSE; - if (p_cfg->flush_to_present) - p_ccb->peer_cfg.flush_to_present = FALSE; - if (p_cfg->qos_present) - p_ccb->peer_cfg.qos_present = FALSE; - - l2c_csm_execute (p_ccb, L2CEVT_L2CA_CONFIG_RSP_NEG, p_cfg); - } + l2c_csm_execute(p_ccb, L2CEVT_L2CA_CONFIG_RSP_NEG, p_cfg); - return (TRUE); + return TRUE; } - -/******************************************************************************* -** -** Function L2CA_DisconnectReq -** -** Description Higher layers call this function to disconnect a channel. -** -** Returns TRUE if disconnect sent, else FALSE -** -*******************************************************************************/ -BOOLEAN L2CA_DisconnectReq (UINT16 cid) +BOOLEAN L2CA_DisconnectReq(UINT16 cid) { - tL2C_CCB *p_ccb; + tL2C_CCB *p_ccb; - L2CAP_TRACE_API1 ("L2CA_DisconnectReq() CID: 0x%04x", cid); + L2CAP_TRACE(API, "L2CA_DisconnectReq() CID: 0x%04x", cid); - /* Find the channel control block. We don't know the link it is on. */ - if ((p_ccb = l2cu_find_ccb_by_cid (NULL, cid)) == NULL) + if ((p_ccb = l2cu_find_ccb_by_cid(NULL, cid)) == NULL) { - L2CAP_TRACE_WARNING1 ("L2CAP - no CCB for L2CA_disc_req, CID: %d", cid); - return (FALSE); + L2CAP_TRACE(WARNING, "L2CAP - no CCB for L2CA_disc_req, CID: %d", cid); + return FALSE; } - l2c_csm_execute (p_ccb, L2CEVT_L2CA_DISCONNECT_REQ, NULL); + l2c_csm_execute(p_ccb, L2CEVT_L2CA_DISCONNECT_REQ, NULL); - return (TRUE); + return TRUE; } -/******************************************************************************* -** -** Function L2CA_DisconnectRsp -** -** Description Higher layers call this function to acknowledge the -** disconnection of a channel. -** -** Returns void -** -*******************************************************************************/ -BOOLEAN L2CA_DisconnectRsp (UINT16 cid) +BOOLEAN L2CA_DisconnectRsp(UINT16 cid) { - tL2C_CCB *p_ccb; + tL2C_CCB *p_ccb; - L2CAP_TRACE_API1 ("L2CA_DisconnectRsp() CID: 0x%04x", cid); + L2CAP_TRACE(API, "L2CA_DisconnectRsp() CID: 0x%04x", cid); - /* Find the channel control block. We don't know the link it is on. */ - if ((p_ccb = l2cu_find_ccb_by_cid (NULL, cid)) == NULL) + if ((p_ccb = l2cu_find_ccb_by_cid(NULL, cid)) == NULL) { - L2CAP_TRACE_WARNING1 ("L2CAP - no CCB for L2CA_disc_rsp, CID: %d", cid); - return (FALSE); + L2CAP_TRACE(WARNING, "L2CAP - no CCB for L2CA_disc_rsp, CID: %d", cid); + return FALSE; } - l2c_csm_execute (p_ccb, L2CEVT_L2CA_DISCONNECT_RSP, NULL); + l2c_csm_execute(p_ccb, L2CEVT_L2CA_DISCONNECT_RSP, NULL); - return (TRUE); + return TRUE; } -/******************************************************************************* -** -** Function L2CA_Ping -** -** Description Higher layers call this function to send an echo request. -** -** Returns TRUE if echo request sent, else FALSE. -** -*******************************************************************************/ -BOOLEAN L2CA_Ping (BD_ADDR p_bd_addr, tL2CA_ECHO_RSP_CB *p_callback) +UINT8 L2CA_DataWrite(UINT16 cid, BT_HDR *p_data) { - tL2C_LCB *p_lcb; + tL2C_CCB *p_ccb; - L2CAP_TRACE_API6 ("L2CA_Ping() BDA: %02x-%02x-%02x-%02x-%02x-%02x", - p_bd_addr[0], p_bd_addr[1], p_bd_addr[2], p_bd_addr[3], p_bd_addr[4], p_bd_addr[5]); + L2CAP_TRACE(API, "L2CA_DataWrite() CID: 0x%04x Len: %d", cid, + p_data->len); - /* Fail if we have not established communications with the controller */ - if (!BTM_IsDeviceUp()) - return (FALSE); - - /* First, see if we already have a link to the remote */ - if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr)) == NULL) + if ((p_ccb = l2cu_find_ccb_by_cid(NULL, cid)) == NULL) { - /* No link. Get an LCB and start link establishment */ -#ifdef REVOLUTION - if ((p_lcb = l2cu_allocate_lcb (p_bd_addr)) == NULL) -#else - if ((p_lcb = l2cu_allocate_lcb (p_bd_addr, FALSE)) == NULL) -#endif - { - L2CAP_TRACE_WARNING0 ("L2CAP - no LCB for L2CA_ping"); - return (FALSE); - } - if (l2cu_create_conn(p_lcb) == FALSE) - { - return (FALSE); - } - - p_lcb->p_echo_rsp_cb = p_callback; - - return (TRUE); + L2CAP_TRACE(WARNING, "L2CAP - no CCB for L2CA_DataWrite, CID: %d", cid); + GKI_freebuf(p_data); + return L2CAP_DW_FAILED; } - /* We only allow 1 ping outstanding at a time */ - if (p_lcb->p_echo_rsp_cb != NULL) + if (p_data->len <= p_ccb->out_mtu) { - L2CAP_TRACE_WARNING0 ("L2CAP - rejected second L2CA_ping"); - return (FALSE); - } + l2c_csm_execute(p_ccb, L2CEVT_L2CA_DATA_WRITE, p_data); - /* Have a link control block. If link is disconnecting, tell user to retry later */ - if (p_lcb->link_state == LST_DISCONNECTING) - { - L2CAP_TRACE_WARNING0 ("L2CAP - L2CA_ping rejected - link disconnecting"); - return (FALSE); + if (p_ccb->p_lcb->cong_sent) + return L2CAP_DW_CONGESTED; } - - /* Save address of callback */ - p_lcb->p_echo_rsp_cb = p_callback; - - if (p_lcb->link_state == LST_CONNECTED) - { - l2cu_adj_id(p_lcb, L2CAP_ADJ_BRCM_ID); /* Make sure not using Broadcom ID */ - l2cu_send_peer_echo_req (p_lcb, NULL, 0); - btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, L2CAP_ECHO_RSP_TOUT); - } - - return (TRUE); -} - -/******************************************************************************* -** -** Function L2CA_Echo -** -** Description Higher layers call this function to send an echo request -** with application-specific data. -** -** Returns TRUE if echo request sent, else FALSE. -** -*******************************************************************************/ -BOOLEAN L2CA_Echo (BD_ADDR p_bd_addr, BT_HDR *p_data, tL2CA_ECHO_DATA_CB *p_callback) -{ - tL2C_LCB *p_lcb; - UINT8 *pp; - - L2CAP_TRACE_API2 ("L2CA_Echo() BDA: %08X%04X", - ((p_bd_addr[0] << 24) + (p_bd_addr[1] << 16) + (p_bd_addr[2] << 8) + (p_bd_addr[3])), - ((p_bd_addr[4] << 8) + (p_bd_addr[5]))); - - /* Fail if we have not established communications with the controller */ - if (!BTM_IsDeviceUp()) - return (FALSE); - - if ((memcmp(BT_BD_ANY, p_bd_addr, BD_ADDR_LEN) == 0) && (p_data == NULL)) - { - /* Only register callback without sending message. */ - l2cb.p_echo_data_cb = p_callback; - return TRUE; - } - - /* We assume the upper layer will call this function only when the link is established. */ - if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr)) == NULL) + else { - L2CAP_TRACE_ERROR0 ("L2CA_Echo ERROR : link not established"); - return FALSE; - } + L2CAP_TRACE(WARNING, "L2CAP - cannot send message bigger than " + "peer's mtu size"); - if (p_lcb->link_state != LST_CONNECTED) - { - L2CAP_TRACE_ERROR0 ("L2CA_Echo ERROR : link is not connected"); - return FALSE; + GKI_freebuf(p_data); + return L2CAP_DW_FAILED; } - /* Save address of callback */ - l2cb.p_echo_data_cb = p_callback; - - /* Set the pointer to the beginning of the data */ - pp = (UINT8 *)(p_data + 1) + p_data->offset; - l2cu_adj_id(p_lcb, L2CAP_ADJ_BRCM_ID); /* Make sure not using Broadcom ID */ - l2cu_send_peer_echo_req (p_lcb, pp, p_data->len); + return L2CAP_DW_SUCCESS; +} - return (TRUE); -} +char l2c_api_ping_traces[0xA8] = + "L2CA_Ping() BDA: %02x-%02x-%02x-%02x-%02x-%02x\0" + "L2CAP - no LCB for L2CA_ping\0\0\0\0" + "L2CAP - rejected second L2CA_ping\0\0\0\0\0\0\0" + "L2CAP - L2CA_ping rejected - link disconnecting"; -/******************************************************************************* -** -** Function L2CA_SetIdleTimeout -** -** Description Higher layers call this function to set the idle timeout for -** a connection, or for all future connections. The "idle timeout" -** is the amount of time that a connection can remain up with -** no L2CAP channels on it. A timeout of zero means that the -** connection will be torn down immediately when the last channel -** is removed. A timeout of 0xFFFF means no timeout. Values are -** in seconds. -** -** Returns TRUE if command succeeded, FALSE if failed -** -** NOTE This timeout takes effect after at least 1 channel has been -** established and removed. L2CAP maintains its own timer from -** whan a connection is established till the first channel is -** set up. -*******************************************************************************/ -BOOLEAN L2CA_SetIdleTimeout (UINT16 cid, UINT16 timeout, BOOLEAN is_global) +BOOLEAN L2CA_SetIdleTimeout(UINT16 cid, UINT16 timeout, BOOLEAN is_global) { - tL2C_CCB *p_ccb; - tL2C_LCB *p_lcb; + tL2C_CCB *p_ccb; + tL2C_LCB *p_lcb; if (is_global) { @@ -732,1093 +337,76 @@ BOOLEAN L2CA_SetIdleTimeout (UINT16 cid, UINT16 timeout, BOOLEAN is_global) } else { - /* Find the channel control block. We don't know the link it is on. */ - if ((p_ccb = l2cu_find_ccb_by_cid (NULL, cid)) == NULL) + if ((p_ccb = l2cu_find_ccb_by_cid(NULL, cid)) == NULL) { - L2CAP_TRACE_WARNING1 ("L2CAP - no CCB for L2CA_SetIdleTimeout, CID: %d", cid); - return (FALSE); + L2CAP_TRACE(WARNING, + "L2CAP - no CCB for L2CA_SetIdleTimeout, CID: %d", cid); + return FALSE; } p_lcb = p_ccb->p_lcb; - if ((p_lcb) && (p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED)) + if (p_lcb && p_lcb->in_use && p_lcb->link_state == LST_CONNECTED) p_lcb->idle_timeout = timeout; else - return (FALSE); - } - - return (TRUE); -} - -/******************************************************************************* -** -** Function L2CA_SetIdleTimeoutByBdAddr -** -** Description Higher layers call this function to set the idle timeout for -** a connection. The "idle timeout" is the amount of time that -** a connection can remain up with no L2CAP channels on it. -** A timeout of zero means that the connection will be torn -** down immediately when the last channel is removed. -** A timeout of 0xFFFF means no timeout. Values are in seconds. -** A bd_addr is the remote BD address. If bd_addr = BT_BD_ANY, -** then the idle timeouts for all active l2cap links will be -** changed. -** -** Returns TRUE if command succeeded, FALSE if failed -** -** NOTE This timeout applies to all logical channels active on the -** ACL link. -*******************************************************************************/ -BOOLEAN L2CA_SetIdleTimeoutByBdAddr(BD_ADDR bd_addr, UINT16 timeout) -{ - tL2C_LCB *p_lcb; - - if (memcmp (BT_BD_ANY, bd_addr, BD_ADDR_LEN)) - { - p_lcb = l2cu_find_lcb_by_bd_addr( bd_addr ); - if ((p_lcb) && (p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED)) - p_lcb->idle_timeout = timeout; - else - return (FALSE); - } - else - { - int xx; - tL2C_LCB *p_lcb = &l2cb.lcb_pool[0]; - - for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) - { - if ((p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED)) - { - p_lcb->idle_timeout = timeout; - } - } - } - - return (TRUE); -} - -/******************************************************************************* -** -** Function L2CA_SetTraceLevel -** -** Description This function sets the trace level for L2CAP. If called with -** a value of 0xFF, it simply reads the current trace level. -** -** Returns the new (current) trace level -** -*******************************************************************************/ -UINT8 L2CA_SetTraceLevel (UINT8 new_level) -{ - if (new_level != 0xFF) - l2cb.l2cap_trace_level = new_level; - - return (l2cb.l2cap_trace_level); -} - - -/******************************************************************************* -** -** Function L2CA_SetDesireRole -** -** Description This function sets the desire role for L2CAP. -** If the new role is L2CAP_ROLE_ALLOW_SWITCH, allow switch on -** HciCreateConnection. -** If the new role is L2CAP_ROLE_DISALLOW_SWITCH, do not allow switch on -** HciCreateConnection. -** -** If the new role is a valid role (HCI_ROLE_MASTER or HCI_ROLE_SLAVE), -** the desire role is set to the new value. Otherwise, it is not changed. -** -** Returns the new (current) role -** -*******************************************************************************/ -UINT8 L2CA_SetDesireRole (UINT8 new_role) -{ - L2CAP_TRACE_API2 ("L2CA_SetDesireRole() new:x%x, disallow_switch:%d", - new_role, l2cb.disallow_switch); - - if (L2CAP_ROLE_CHECK_SWITCH != (L2CAP_ROLE_CHECK_SWITCH & new_role)) - { - /* do not process the allow_switch when both bits are set */ - if (new_role & L2CAP_ROLE_ALLOW_SWITCH) - { - l2cb.disallow_switch = FALSE; - } - if (new_role & L2CAP_ROLE_DISALLOW_SWITCH) - { - l2cb.disallow_switch = TRUE; - } - } - - if (new_role == HCI_ROLE_MASTER || new_role == HCI_ROLE_SLAVE) - l2cb.desire_role = new_role; - - return (l2cb.desire_role); -} - -/******************************************************************************* -** -** Function L2CA_LocalLoopbackReq -** -** Description This function sets up a CID for local loopback -** -** Returns CID of 0 if none. -** -*******************************************************************************/ -UINT16 L2CA_LocalLoopbackReq (UINT16 psm, UINT16 handle, BD_ADDR p_bd_addr) -{ - tL2C_LCB *p_lcb; - tL2C_CCB *p_ccb; - tL2C_RCB *p_rcb; - - L2CAP_TRACE_API2 ("L2CA_LocalLoopbackReq() PSM: %d Handle: 0x%04x", psm, handle); - - /* Fail if we have not established communications with the controller */ - if (!BTM_IsDeviceUp()) - { - L2CAP_TRACE_WARNING0 ("L2CAP loop req - BTU not ready"); - return (0); - } - - /* Fail if the PSM is not registered */ - if ((p_rcb = l2cu_find_rcb_by_psm (psm)) == NULL) - { - L2CAP_TRACE_WARNING1 ("L2CAP - no RCB for L2CA_conn_req, PSM: %d", psm); - return (0); - } - -#ifdef REVOLUTION - if ((p_lcb = l2cu_allocate_lcb (p_bd_addr)) == NULL) -#else - if ((p_lcb = l2cu_allocate_lcb (p_bd_addr, FALSE)) == NULL) -#endif - { - L2CAP_TRACE_WARNING0 ("L2CAP - no LCB for L2CA_conn_req"); - return (0); - } - - p_lcb->link_state = LST_CONNECTED; - p_lcb->handle = handle; - - /* Allocate a channel control block */ - if ((p_ccb = l2cu_allocate_ccb (p_lcb, 0)) == NULL) - { - L2CAP_TRACE_WARNING0 ("L2CAP - no CCB for L2CA_conn_req"); - return (0); - } - - /* Save registration info */ - p_ccb->p_rcb = p_rcb; - p_ccb->chnl_state = CST_OPEN; - p_ccb->remote_cid = p_ccb->local_cid; - p_ccb->config_done = CFG_DONE_MASK; - - /* Return the local CID as our handle */ - return (p_ccb->local_cid); -} - -/******************************************************************************* -** -** Function L2CA_SetAclPriority -** -** Description Sets the transmission priority for a channel. -** (For initial implementation only two values are valid. -** L2CAP_PRIORITY_NORMAL and L2CAP_PRIORITY_HIGH). -** -** Returns TRUE if a valid channel, else FALSE -** -*******************************************************************************/ -BOOLEAN L2CA_SetAclPriority (BD_ADDR bd_addr, UINT8 priority) -{ - L2CAP_TRACE_API6 ("L2CA_SetAclPriority() bdaddr: %02x%02x%02x%02x%04x, priority:%d", - bd_addr[0], bd_addr[1], bd_addr[2], - bd_addr[3], (bd_addr[4] << 8) + bd_addr[5], priority); - - return (l2cu_set_acl_priority(bd_addr, priority, FALSE)); -} - -/******************************************************************************* -** -** Function L2CA_FlowControl -** -** Description Higher layers call this function to flow control a channel. -** -** data_enabled - TRUE data flows, FALSE data is stopped -** -** Returns TRUE if valid channel, else FALSE -** -*******************************************************************************/ -BOOLEAN L2CA_FlowControl (UINT16 cid, BOOLEAN data_enabled) -{ - tL2C_CCB *p_ccb; - BOOLEAN on_off = !data_enabled; - - L2CAP_TRACE_API2 ("L2CA_FlowControl(%d) CID: 0x%04x", on_off, cid); - - /* Find the channel control block. We don't know the link it is on. */ - if ((p_ccb = l2cu_find_ccb_by_cid (NULL, cid)) == NULL) - { - L2CAP_TRACE_WARNING2 ("L2CAP - no CCB for L2CA_FlowControl, CID: 0x%04x data_enabled: %d", cid, data_enabled); - return (FALSE); - } - - if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_ERTM_MODE) - { - L2CAP_TRACE_EVENT1 ("L2CA_FlowControl() invalid mode:%d", p_ccb->peer_cfg.fcr.mode); - return (FALSE); - } - if (p_ccb->fcrb.local_busy != on_off) - { - p_ccb->fcrb.local_busy = on_off; - - if ( (p_ccb->chnl_state == CST_OPEN) && (!p_ccb->fcrb.wait_ack) ) - { - if (on_off) - l2c_fcr_send_S_frame (p_ccb, L2CAP_FCR_SUP_RNR, 0); - else - l2c_fcr_send_S_frame (p_ccb, L2CAP_FCR_SUP_RR, L2CAP_FCR_P_BIT); - } - } - - return (TRUE); -} - -/******************************************************************************* -** -** Function L2CA_SendTestSFrame -** -** Description Higher layers call this function to send a test S-frame. -** -** Returns TRUE if valid Channel, else FALSE -** -*******************************************************************************/ -BOOLEAN L2CA_SendTestSFrame (UINT16 cid, UINT8 sup_type, UINT8 back_track) -{ - tL2C_CCB *p_ccb; - - L2CAP_TRACE_API3 ("L2CA_SendTestSFrame() CID: 0x%04x Type: 0x%02x back_track: %u", cid, sup_type, back_track); - - /* Find the channel control block. We don't know the link it is on. */ - if ((p_ccb = l2cu_find_ccb_by_cid (NULL, cid)) == NULL) - { - L2CAP_TRACE_WARNING1 ("L2CAP - no CCB for L2CA_SendTestSFrame, CID: %d", cid); - return (FALSE); - } - - if ( (p_ccb->chnl_state != CST_OPEN) || (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_ERTM_MODE) ) - return (FALSE); - - p_ccb->fcrb.next_seq_expected -= back_track; - - l2c_fcr_send_S_frame (p_ccb, (UINT16)(sup_type & 3), (UINT16)(sup_type & (L2CAP_FCR_P_BIT | L2CAP_FCR_F_BIT))); - - return (TRUE); -} - - -/******************************************************************************* -** -** Function L2CA_SetTxPriority -** -** Description Sets the transmission priority for a channel. -** -** Returns TRUE if a valid channel, else FALSE -** -*******************************************************************************/ -BOOLEAN L2CA_SetTxPriority (UINT16 cid, tL2CAP_CHNL_PRIORITY priority) -{ - tL2C_CCB *p_ccb; - - L2CAP_TRACE_API2 ("L2CA_SetTxPriority() CID: 0x%04x, priority:%d", cid, priority); - - /* Find the channel control block. We don't know the link it is on. */ - if ((p_ccb = l2cu_find_ccb_by_cid (NULL, cid)) == NULL) - { - L2CAP_TRACE_WARNING1 ("L2CAP - no CCB for L2CA_SetTxPriority, CID: %d", cid); - return (FALSE); + return FALSE; } - /* it will update the order of CCB in LCB by priority and update round robin service variables */ - l2cu_change_pri_ccb (p_ccb, priority); - - return (TRUE); + return TRUE; } -/******************************************************************************* -** -** Function L2CA_SetChnlDataRate -** -** Description Sets the tx/rx data rate for a channel. -** -** Returns TRUE if a valid channel, else FALSE -** -*******************************************************************************/ -BOOLEAN L2CA_SetChnlDataRate (UINT16 cid, tL2CAP_CHNL_DATA_RATE tx, tL2CAP_CHNL_DATA_RATE rx) -{ - tL2C_CCB *p_ccb; - - L2CAP_TRACE_API3 ("L2CA_SetChnlDataRate() CID: 0x%04x, tx:%d, rx:%d", cid, tx, rx); +char l2c_api_dead_traces[0x190] = + "L2CA_SetAclPriority() bdaddr: %02x%02x%02x%02x%02x%02x\0" + "L2CAP - no LCB for L2CA_SetAclPriority\0\0" + "L2CA_SetCompression() local cid %d, direction %d, pe_type %d, mem_level %d, wbits %d, enable %d\0" + "L2CAP - no CCB for L2CA_Flush, CID: %d\0\0" + "L2CA_Flush() CID: 0x%04x flushed %d buffers\0\0\0\0" + "L2CA_GetNumQueuedBufs() CID: 0x%04x abmormally returning 0\0\0\0\0" + "L2CA_GetNumQueuedBufs() CID: 0x%04x returning %d\0\0\0\0\0"; - /* Find the channel control block. We don't know the link it is on. */ - if ((p_ccb = l2cu_find_ccb_by_cid (NULL, cid)) == NULL) - { - L2CAP_TRACE_WARNING1 ("L2CAP - no CCB for L2CA_SetChnlDataRate, CID: %d", cid); - return (FALSE); - } - p_ccb->tx_data_rate = tx; - p_ccb->rx_data_rate = rx; - /* Adjust channel buffer allocation */ - l2c_link_adjust_chnl_allocation (); - - return(TRUE); -} - -/******************************************************************************* -** -** Function L2CA_SetFlushTimeout -** -** Description This function set the automatic flush time out in Baseband -** for ACL-U packets. -** BdAddr : the remote BD address of ACL link. If it is BT_DB_ANY -** then the flush time out will be applied to all ACL link. -** FlushTimeout: flush time out in ms -** 0x0000 : No automatic flush -** L2CAP_NO_RETRANSMISSION : No retransmission -** 0x0002 - 0xFFFE : flush time out, if (flush_tout*8)+3/5) -** <= HCI_MAX_AUTO_FLUSH_TOUT (in 625us slot). -** Otherwise, return FALSE. -** L2CAP_NO_AUTOMATIC_FLUSH : No automatic flush -** -** Returns TRUE if command succeeded, FALSE if failed -** -** NOTE This flush timeout applies to all logical channels active on the -** ACL link. -*******************************************************************************/ -BOOLEAN L2CA_SetFlushTimeout (BD_ADDR bd_addr, UINT16 flush_tout) +BOOLEAN L2CA_SetIdleTimeoutByBdAddr(BD_ADDR bd_addr, UINT16 timeout) { - tL2C_LCB *p_lcb; - UINT16 hci_flush_to; - UINT32 temp; + tL2C_LCB *p_lcb; - /* no automatic flush (infinite timeout) */ - if (flush_tout == 0x0000) - { - hci_flush_to = flush_tout; - flush_tout = L2CAP_NO_AUTOMATIC_FLUSH; - } - /* no retransmission */ - else if (flush_tout == L2CAP_NO_RETRANSMISSION) - { - /* not mandatory range for controller */ - /* Packet is flushed before getting any ACK/NACK */ - /* To do this, flush timeout should be 1 baseband slot */ - hci_flush_to = flush_tout; - } - /* no automatic flush (infinite timeout) */ - else if (flush_tout == L2CAP_NO_AUTOMATIC_FLUSH) + if (memcmp(BT_BD_ANY, bd_addr, BD_ADDR_LEN) != 0) { - hci_flush_to = 0x0000; - } - else - { - /* convert L2CAP flush_to to 0.625 ms units, with round */ - temp = (((UINT32)flush_tout * 8) + 3) / 5; + p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr); - /* if L2CAP flush_to within range of HCI, set HCI flush timeout */ - if (temp > HCI_MAX_AUTO_FLUSH_TOUT) - { - L2CAP_TRACE_WARNING1("WARNING L2CA_SetFlushTimeout timeout(0x%x) is out of range", flush_tout); - return FALSE; - } - else - { - hci_flush_to = (UINT16)temp; - } - } - - if (memcmp (BT_BD_ANY, bd_addr, BD_ADDR_LEN)) - { - p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr); - - if ((p_lcb) && (p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED)) - { - if (p_lcb->link_flush_tout != flush_tout) - { - p_lcb->link_flush_tout = flush_tout; - - L2CAP_TRACE_API4 ("L2CA_SetFlushTimeout 0x%04x ms for bd_addr [...;%02x%02x%02x]", - flush_tout, bd_addr[3], bd_addr[4], bd_addr[5]); - - if (!btsnd_hcic_write_auto_flush_tout (p_lcb->handle, hci_flush_to)) - return (FALSE); - } - } + if (p_lcb && p_lcb->in_use && p_lcb->link_state == LST_CONNECTED) + p_lcb->idle_timeout = timeout; else - { - L2CAP_TRACE_WARNING3 ("WARNING L2CA_SetFlushTimeout No lcb for bd_addr [...;%02x%02x%02x]", - bd_addr[3], bd_addr[4], bd_addr[5]); - return (FALSE); - } + return FALSE; } else { - int xx; - p_lcb = &l2cb.lcb_pool[0]; + int xx; + tL2C_LCB *p_lcb = &l2cb.lcb_pool[0]; for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) { - if ((p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED)) - { - if (p_lcb->link_flush_tout != flush_tout) - { - p_lcb->link_flush_tout = flush_tout; - - L2CAP_TRACE_API4 ("L2CA_SetFlushTimeout 0x%04x ms for bd_addr [...;%02x%02x%02x]", - flush_tout, p_lcb->remote_bd_addr[3], - p_lcb->remote_bd_addr[4], p_lcb->remote_bd_addr[5]); - - if (!btsnd_hcic_write_auto_flush_tout(p_lcb->handle, hci_flush_to)) - return (FALSE); - } - } - } - } - - return (TRUE); -} - -/******************************************************************************* -** -** Function L2CA_GetPeerFeatures -** -** Description Get a peers features and fixed channel map -** -** Parameters: BD address of the peer -** Pointers to features and channel mask storage area -** -** Return value: TRUE if peer is connected -** -*******************************************************************************/ -BOOLEAN L2CA_GetPeerFeatures (BD_ADDR bd_addr, UINT32 *p_ext_feat, UINT8 *p_chnl_mask) -{ - tL2C_LCB *p_lcb; - - /* We must already have a link to the remote */ - if ((p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr)) == NULL) - { - L2CAP_TRACE_WARNING2 ("L2CA_GetPeerFeatures() No BDA: %08x%04x", - (bd_addr[0]<<24)+(bd_addr[1]<<16)+(bd_addr[2]<<8)+bd_addr[3], - (bd_addr[4]<<8)+bd_addr[5]); - return (FALSE); - } - - L2CAP_TRACE_API4 ("L2CA_GetPeerFeatures() BDA: %08x%04x ExtFea: 0x%08x Chnl_Mask[0]: 0x%02x", - (bd_addr[0]<<24)+(bd_addr[1]<<16)+(bd_addr[2]<<8)+bd_addr[3], - (bd_addr[4]<<8)+bd_addr[5], p_lcb->peer_ext_fea, p_lcb->peer_chnl_mask[0]); - - *p_ext_feat = p_lcb->peer_ext_fea; - - memcpy (p_chnl_mask, p_lcb->peer_chnl_mask, L2CAP_FIXED_CHNL_ARRAY_SIZE); - - return (TRUE); -} - -/******************************************************************************* -** -** Function L2CA_GetBDAddrbyHandle -** -** Description Get BD address for the given HCI handle -** -** Parameters: HCI handle -** BD address of the peer -** -** Return value: TRUE if found lcb for the given handle, FALSE otherwise -** -*******************************************************************************/ -BOOLEAN L2CA_GetBDAddrbyHandle (UINT16 handle, BD_ADDR bd_addr) -{ - tL2C_LCB *p_lcb = NULL; - BOOLEAN found_dev = FALSE; - - p_lcb = l2cu_find_lcb_by_handle (handle); - if (p_lcb) - { - found_dev = TRUE; - memcpy (bd_addr, p_lcb->remote_bd_addr, BD_ADDR_LEN); - } - - return found_dev; -} - -/******************************************************************************* -** -** Function L2CA_GetChnlFcrMode -** -** Description Get the channel FCR mode -** -** Parameters: Local CID -** -** Return value: Channel mode -** -*******************************************************************************/ -UINT8 L2CA_GetChnlFcrMode (UINT16 lcid) -{ - tL2C_CCB *p_ccb = l2cu_find_ccb_by_cid (NULL, lcid); - - if (p_ccb) - { - L2CAP_TRACE_API1 ("L2CA_GetChnlFcrMode() returns mode %d", p_ccb->peer_cfg.fcr.mode); - return (p_ccb->peer_cfg.fcr.mode); - } - - L2CAP_TRACE_API0 ("L2CA_GetChnlFcrMode() returns mode L2CAP_FCR_BASIC_MODE"); - return (L2CAP_FCR_BASIC_MODE); -} - -#if (L2CAP_NUM_FIXED_CHNLS > 0) -/******************************************************************************* -** -** Function L2CA_RegisterFixedChannel -** -** Description Register a fixed channel. -** -** Parameters: Fixed Channel # -** Channel Callbacks and config -** -** Return value: - -** -*******************************************************************************/ -BOOLEAN L2CA_RegisterFixedChannel (UINT16 fixed_cid, tL2CAP_FIXED_CHNL_REG *p_freg) -{ - if ( (fixed_cid < L2CAP_FIRST_FIXED_CHNL) || (fixed_cid > L2CAP_LAST_FIXED_CHNL) ) - { - L2CAP_TRACE_ERROR1 ("L2CA_RegisterFixedChannel() Invalid CID: 0x%04x", fixed_cid); - - return (FALSE); - } - - l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL] = *p_freg; - return (TRUE); -} - -/******************************************************************************* -** -** Function L2CA_ConnectFixedChnl -** -** Description Connect an fixed signalling channel to a remote device. -** -** Parameters: Fixed CID -** BD Address of remote -** -** Return value: TRUE if connection started -** -*******************************************************************************/ -BOOLEAN L2CA_ConnectFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda) -{ - tL2C_LCB *p_lcb; -#if BLE_INCLUDED == TRUE - UINT16 reason; -#endif - - L2CAP_TRACE_API3 ("L2CA_ConnectFixedChnl() CID: 0x%04x BDA: %08x%04x", fixed_cid, - (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]); - - /* Check CID is valid and registered */ - if ( (fixed_cid < L2CAP_FIRST_FIXED_CHNL) || (fixed_cid > L2CAP_LAST_FIXED_CHNL) - || (l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb == NULL) ) - { - L2CAP_TRACE_ERROR1 ("L2CA_ConnectFixedChnl() Invalid CID: 0x%04x", fixed_cid); - return (FALSE); - } - - /* Fail if BT is not yet up */ - if (!BTM_IsDeviceUp()) - { - L2CAP_TRACE_WARNING1 ("L2CA_ConnectFixedChnl(0x%04x) - BTU not ready", fixed_cid); - return (FALSE); - } - - /* If we already have a link to the remote, check if it supports that CID */ - if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) != NULL) - { - if (!(p_lcb->peer_chnl_mask[0] & (1 << fixed_cid))) - { - L2CAP_TRACE_EVENT3 ("L2CA_ConnectFixedChnl() CID: 0x%04x BDA: %08x%04x not supported", fixed_cid, - (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]); - return (FALSE); - } - /* Get a CCB and link the lcb to it */ - if (!l2cu_initialize_fixed_ccb (p_lcb, fixed_cid, &l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts)) - { - L2CAP_TRACE_WARNING1 ("L2CA_ConnectFixedChnl(0x%04x) - LCB but no CCB", fixed_cid); - return (FALSE); - } -#if BLE_INCLUDED == TRUE - reason = (p_lcb->is_ble_link) ? 1: 0; - (*l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, TRUE, reason); -#else - (*l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, TRUE, 0); -#endif - return (TRUE); - } - - /* No link. Get an LCB and start link establishment */ -#ifdef REVOLUTION - if ((p_lcb = l2cu_allocate_lcb (rem_bda)) == NULL) -#else - if ((p_lcb = l2cu_allocate_lcb (rem_bda, FALSE)) == NULL) -#endif - { - L2CAP_TRACE_WARNING1 ("L2CA_ConnectFixedChnl(0x%04x) - no LCB", fixed_cid); - return (FALSE); - } - - /* Get a CCB and link the lcb to it */ - if (!l2cu_initialize_fixed_ccb (p_lcb, fixed_cid, &l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts)) - { - p_lcb->disc_reason = L2CAP_CONN_NO_RESOURCES; - L2CAP_TRACE_WARNING1 ("L2CA_ConnectFixedChnl(0x%04x) - no CCB", fixed_cid); - l2cu_release_lcb (p_lcb); - return (FALSE); - } - - return (l2cu_create_conn(p_lcb)); -} - -/******************************************************************************* -** -** Function L2CA_SendFixedChnlData -** -** Description Write data on a fixed channel. -** -** Parameters: Fixed CID -** BD Address of remote -** Pointer to buffer of type BT_HDR -** -** Return value L2CAP_DW_SUCCESS, if data accepted -** L2CAP_DW_FAILED, if error -** -*******************************************************************************/ -UINT16 L2CA_SendFixedChnlData (UINT16 fixed_cid, BD_ADDR rem_bda, BT_HDR *p_buf) -{ - tL2C_LCB *p_lcb; - - L2CAP_TRACE_API3 ("L2CA_SendFixedChnlData() CID: 0x%04x BDA: %08x%04x", fixed_cid, - (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]); - - /* Check CID is valid and registered */ - if ( (fixed_cid < L2CAP_FIRST_FIXED_CHNL) || (fixed_cid > L2CAP_LAST_FIXED_CHNL) - || (l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb == NULL) ) - { - L2CAP_TRACE_ERROR1 ("L2CA_SendFixedChnlData() Invalid CID: 0x%04x", fixed_cid); - return (L2CAP_DW_FAILED); - } - - /* Fail if BT is not yet up */ - if (!BTM_IsDeviceUp()) - { - L2CAP_TRACE_WARNING1 ("L2CA_SendFixedChnlData(0x%04x) - BTU not ready", fixed_cid); - return (L2CAP_DW_FAILED); - } - - /* We need to have a link up */ - if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) == NULL) - { - L2CAP_TRACE_WARNING1 ("L2CA_SendFixedChnlData(0x%04x) - no LCB", fixed_cid); - return (L2CAP_DW_FAILED); - } - - if ((p_lcb->peer_chnl_mask[0] & (1 << fixed_cid)) == 0) - { - L2CAP_TRACE_WARNING1 ("L2CA_SendFixedChnlData() - peer does not support fixed chnl: 0x%04x", fixed_cid); - return (L2CAP_DW_FAILED); - } - - p_buf->event = 0; - p_buf->layer_specific = L2CAP_FLUSHABLE_CH_BASED; - - if (!p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]) - { - if (!l2cu_initialize_fixed_ccb (p_lcb, fixed_cid, &l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts)) - { - L2CAP_TRACE_WARNING1 ("L2CA_SendFixedChnlData() - no CCB for chnl: 0x%4x", fixed_cid); - return (L2CAP_DW_FAILED); + if (p_lcb->in_use && p_lcb->link_state == LST_CONNECTED) + p_lcb->idle_timeout = timeout; } } - l2c_enqueue_peer_data (p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL], p_buf); - - l2c_link_check_send_pkts (p_lcb, NULL, NULL); - - /* If there is no dynamic CCB on the link, restart the idle timer each time something is sent */ - if (p_lcb->in_use && p_lcb->link_state == LST_CONNECTED && !p_lcb->ccb_queue.p_first_ccb) - { - l2cu_no_dynamic_ccbs (p_lcb); - } - - return (L2CAP_DW_SUCCESS); -} - -/******************************************************************************* -** -** Function L2CA_RemoveFixedChnl -** -** Description Remove a fixed channel to a remote device. -** -** Parameters: Fixed CID -** BD Address of remote -** Idle timeout to use (or 0xFFFF if don't care) -** -** Return value: TRUE if channel removed -** -*******************************************************************************/ -BOOLEAN L2CA_RemoveFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda) -{ - tL2C_LCB *p_lcb; - tL2C_CCB *p_ccb; - - /* Check CID is valid and registered */ - if ( (fixed_cid < L2CAP_FIRST_FIXED_CHNL) || (fixed_cid > L2CAP_LAST_FIXED_CHNL) - || (l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb == NULL) ) - { - L2CAP_TRACE_ERROR1 ("L2CA_RemoveFixedChnl() Invalid CID: 0x%04x", fixed_cid); - return (FALSE); - } - - /* Is a fixed channel connected to the remote BDA ?*/ - p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda); - if ( ((p_lcb) == NULL) || (!p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]) ) - { - L2CAP_TRACE_WARNING3 ("L2CA_RemoveFixedChnl() CID: 0x%04x BDA: %08x%04x not connected", fixed_cid, - (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]); - return (FALSE); - } - - L2CAP_TRACE_API3 ("L2CA_RemoveFixedChnl() CID: 0x%04x BDA: %08x%04x", fixed_cid, - (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]); - - /* Release the CCB, starting an inactivity timeout on the LCB if no other CCBs exist */ - p_ccb = p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]; - - p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL] = NULL; - p_lcb->disc_reason = HCI_ERR_CONN_CAUSE_LOCAL_HOST; - l2cu_release_ccb (p_ccb); - - return (TRUE); -} - -/******************************************************************************* -** -** Function L2CA_SetFixedChannelTout -** -** Description Higher layers call this function to set the idle timeout for -** a fixed channel. The "idle timeout" is the amount of time that -** a connection can remain up with no L2CAP channels on it. -** A timeout of zero means that the connection will be torn -** down immediately when the last channel is removed. -** A timeout of 0xFFFF means no timeout. Values are in seconds. -** A bd_addr is the remote BD address. If bd_addr = BT_BD_ANY, -** then the idle timeouts for all active l2cap links will be -** changed. -** -** Returns TRUE if command succeeded, FALSE if failed -** -*******************************************************************************/ -BOOLEAN L2CA_SetFixedChannelTout (BD_ADDR rem_bda, UINT16 fixed_cid, UINT16 idle_tout) -{ - tL2C_LCB *p_lcb; - - /* Is a fixed channel connected to the remote BDA ?*/ - p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda); - if ( ((p_lcb) == NULL) || (!p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]) ) - { - L2CAP_TRACE_WARNING3 ("L2CA_SetFixedChannelTout() CID: 0x%04x BDA: %08x%04x not connected", fixed_cid, - (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]); - return (FALSE); - } - - p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->fixed_chnl_idle_tout = idle_tout; - - if (p_lcb->in_use && p_lcb->link_state == LST_CONNECTED && !p_lcb->ccb_queue.p_first_ccb) - { - /* If there are no dynamic CCBs, (re)start the idle timer in case we changed it */ - l2cu_no_dynamic_ccbs (p_lcb); - } - - return (TRUE); -} - -#endif /* #if (L2CAP_NUM_FIXED_CHNLS > 0) */ - -/******************************************************************************* -** -** Function L2CA_GetCurrentConfig -** -** Description This function returns configurations of L2CAP channel -** pp_our_cfg : pointer of our saved configuration options -** p_our_cfg_bits : valid config in bitmap -** pp_peer_cfg: pointer of peer's saved configuration options -** p_peer_cfg_bits : valid config in bitmap -** -** Returns TRUE if successful -** -*******************************************************************************/ -BOOLEAN L2CA_GetCurrentConfig (UINT16 lcid, - tL2CAP_CFG_INFO **pp_our_cfg, tL2CAP_CH_CFG_BITS *p_our_cfg_bits, - tL2CAP_CFG_INFO **pp_peer_cfg, tL2CAP_CH_CFG_BITS *p_peer_cfg_bits) -{ - tL2C_CCB *p_ccb; - - L2CAP_TRACE_API1 ("L2CA_GetCurrentConfig() CID: 0x%04x", lcid); - - p_ccb = l2cu_find_ccb_by_cid(NULL, lcid); - - if (p_ccb) - { - *pp_our_cfg = &(p_ccb->our_cfg); - - /* convert valid config items into bitmap */ - *p_our_cfg_bits = 0; - if (p_ccb->our_cfg.mtu_present) - *p_our_cfg_bits |= L2CAP_CH_CFG_MASK_MTU; - if (p_ccb->our_cfg.qos_present) - *p_our_cfg_bits |= L2CAP_CH_CFG_MASK_QOS; - if (p_ccb->our_cfg.flush_to_present) - *p_our_cfg_bits |= L2CAP_CH_CFG_MASK_FLUSH_TO; - if (p_ccb->our_cfg.fcr_present) - *p_our_cfg_bits |= L2CAP_CH_CFG_MASK_FCR; - if (p_ccb->our_cfg.fcs_present) - *p_our_cfg_bits |= L2CAP_CH_CFG_MASK_FCS; - if (p_ccb->our_cfg.ext_flow_spec_present) - *p_our_cfg_bits |= L2CAP_CH_CFG_MASK_EXT_FLOW_SPEC; - - *pp_peer_cfg = &(p_ccb->peer_cfg); - *p_peer_cfg_bits = p_ccb->peer_cfg_bits; - - return TRUE; - } - else - { - L2CAP_TRACE_ERROR1 ("No CCB for CID:0x%04x", lcid); - return FALSE; - } -} - -/******************************************************************************* -** -** Function L2CA_RegForNoCPEvt -** -** Description Register callback for Number of Completed Packets event. -** -** Input Param p_cb - callback for Number of completed packets event -** p_bda - BT address of remote device -** -** Returns TRUE if registered OK, else FALSE -** -*******************************************************************************/ -BOOLEAN L2CA_RegForNoCPEvt(tL2CA_NOCP_CB *p_cb, BD_ADDR p_bda) -{ - tL2C_LCB *p_lcb; - - /* Find the link that is associated with this remote bdaddr */ - p_lcb = l2cu_find_lcb_by_bd_addr (p_bda); - - /* If no link for this handle, nothing to do. */ - if (!p_lcb) - return FALSE; - - p_lcb->p_nocp_cb = p_cb; - return TRUE; } -/******************************************************************************* -** -** Function L2CA_DataWrite -** -** Description Higher layers call this function to write data. -** -** Returns L2CAP_DW_SUCCESS, if data accepted, else FALSE -** L2CAP_DW_CONGESTED, if data accepted and the channel is congested -** L2CAP_DW_FAILED, if error -** -*******************************************************************************/ -UINT8 L2CA_DataWrite (UINT16 cid, BT_HDR *p_data) -{ - L2CAP_TRACE_API2 ("L2CA_DataWrite() CID: 0x%04x Len: %d", cid, p_data->len); - return l2c_data_write (cid, p_data, L2CAP_FLUSHABLE_CH_BASED); -} - -/******************************************************************************* -** -** Function L2CA_SetChnlFlushability -** -** Description Higher layers call this function to set a channels -** flushability flags -** -** Returns TRUE if CID found, else FALSE -** -*******************************************************************************/ -BOOLEAN L2CA_SetChnlFlushability (UINT16 cid, BOOLEAN is_flushable) +UINT8 L2CA_SetTraceLevel(UINT8 new_level) { -#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE) - - tL2C_CCB *p_ccb; - - /* Find the channel control block. We don't know the link it is on. */ - if ((p_ccb = l2cu_find_ccb_by_cid (NULL, cid)) == NULL) - { - L2CAP_TRACE_WARNING1 ("L2CAP - no CCB for L2CA_SetChnlFlushability, CID: %d", cid); - return (FALSE); - } + if (new_level != 0xff) + l2cb.l2cap_trace_level = new_level; - p_ccb->is_flushable = is_flushable; + return l2cb.l2cap_trace_level; +} - L2CAP_TRACE_API2 ("L2CA_SetChnlFlushability() CID: 0x%04x is_flushable: %d", cid, is_flushable); -#endif - return (TRUE); -} -/******************************************************************************* -** -** Function L2CA_DataWriteEx -** -** Description Higher layers call this function to write data with extended -** flags. -** flags : L2CAP_FLUSHABLE_CH_BASED -** L2CAP_FLUSHABLE_PKT -** L2CAP_NON_FLUSHABLE_PKT -** -** Returns L2CAP_DW_SUCCESS, if data accepted, else FALSE -** L2CAP_DW_CONGESTED, if data accepted and the channel is congested -** L2CAP_DW_FAILED, if error -** -*******************************************************************************/ -UINT8 L2CA_DataWriteEx (UINT16 cid, BT_HDR *p_data, UINT16 flags) +void L2CA_RegisterCompression(tL2CA_COMPRESS_CB *param_1, int param_2) { - L2CAP_TRACE_API3 ("L2CA_DataWriteEx() CID: 0x%04x Len: %d Flags:0x%04X", - cid, p_data->len, flags); - return l2c_data_write (cid, p_data, flags); } -/******************************************************************************* -** -** Function L2CA_FlushChannel -** -** Description This function flushes none, some or all buffers queued up -** for xmission for a particular CID. If called with -** L2CAP_FLUSH_CHANS_GET (0), it simply returns the number -** of buffers queued for that CID L2CAP_FLUSH_CHANS_ALL (0xffff) -** flushes all buffers. All other values specifies the maximum -** buffers to flush. -** -** Returns Number of buffers left queued for that CID -** -*******************************************************************************/ -UINT16 L2CA_FlushChannel (UINT16 lcid, UINT16 num_to_flush) -{ - tL2C_CCB *p_ccb; - tL2C_LCB *p_lcb; - UINT16 num_left = 0, - num_flushed1 = 0, - num_flushed2 = 0; - BT_HDR *p_buf1, *p_buf; - - p_ccb = l2cu_find_ccb_by_cid(NULL, lcid); - - if ( !p_ccb || ((p_lcb = p_ccb->p_lcb) == NULL) ) - { - L2CAP_TRACE_WARNING1 ("L2CA_FlushChannel() abnormally returning 0 CID: 0x%04x", lcid); - return (0); - } - - if (num_to_flush != L2CAP_FLUSH_CHANS_GET) - { - L2CAP_TRACE_API4 ("L2CA_FlushChannel (FLUSH) CID: 0x%04x NumToFlush: %d QC: %u pFirst: 0x%08x", - lcid, num_to_flush, p_ccb->xmit_hold_q.count, p_ccb->xmit_hold_q.p_first); - } - else - { - L2CAP_TRACE_API1 ("L2CA_FlushChannel (QUERY) CID: 0x%04x", lcid); - } - - /* Cannot flush eRTM buffers once they have a sequence number */ - if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_ERTM_MODE) - { -#if L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE - if (num_to_flush != L2CAP_FLUSH_CHANS_GET) - { - /* If the controller supports enhanced flush, flush the data queued at the controller */ - if ( (HCI_NON_FLUSHABLE_PB_SUPPORTED(BTM_ReadLocalFeatures ())) - && (BTM_GetNumScoLinks() == 0) ) - { - if ( l2cb.is_flush_active == FALSE ) - { - l2cb.is_flush_active = TRUE; - - /* The only packet type defined - 0 - Automatically-Flushable Only */ - btsnd_hcic_enhanced_flush (p_lcb->handle, 0); - } - } - } -#endif - - p_buf = (BT_HDR *)p_lcb->link_xmit_data_q.p_first; - - /* First flush the number we are asked to flush */ - while ((p_buf != NULL) && (num_to_flush != 0)) - { - /* Do not flush other CIDs or partial segments */ - if ( (p_buf->layer_specific == 0) && (p_buf->event == lcid) ) - { - p_buf1 = p_buf; - p_buf = (BT_HDR *)GKI_getnext (p_buf); - num_to_flush--; - num_flushed1++; - - GKI_remove_from_queue (&p_lcb->link_xmit_data_q, p_buf1); - GKI_freebuf (p_buf1); - } - else - p_buf = (BT_HDR *)GKI_getnext (p_buf); - } - } - - /* If needed, flush buffers in the CCB xmit hold queue */ - while ( (num_to_flush != 0) && (p_ccb->xmit_hold_q.count != 0) ) - { - p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->xmit_hold_q); - if (p_buf) - GKI_freebuf (p_buf); - num_to_flush--; - num_flushed2++; - } - - /* Now count how many are left */ - p_buf = (BT_HDR *)p_lcb->link_xmit_data_q.p_first; - - while (p_buf != NULL) - { - if (p_buf->event == lcid) - num_left++; - - p_buf = (BT_HDR *)GKI_getnext (p_buf); - } - - /* Add in the number in the CCB xmit queue */ - num_left += p_ccb->xmit_hold_q.count; - - /* Return the local number of buffers left for the CID */ - L2CAP_TRACE_DEBUG3 ("L2CA_FlushChannel() flushed: %u + %u, num_left: %u", num_flushed1, num_flushed2, num_left); - - /* If we were congested, and now we are not, tell the app */ - l2cu_check_channel_congestion (p_ccb); - - return (num_left); -} diff --git a/src/revolution/BTE/stack/l2cap/l2c_csm.c b/src/revolution/BTE/stack/l2cap/l2c_csm.c index 603d1f2..fccab85 100644 --- a/src/revolution/BTE/stack/l2cap/l2c_csm.c +++ b/src/revolution/BTE/stack/l2cap/l2c_csm.c @@ -16,90 +16,89 @@ * ******************************************************************************/ +/* Original source: + * bluedroid + * stack/l2cap/l2c_csm.c + */ + +/* Includes changes by muff1n1634 and for this repository (KoopTheKoopa) */ + /****************************************************************************** * - * This file contains the L2CAP channel state machine + * This file contains the L2CAP channel state machine. * ******************************************************************************/ -#include -#include -#include +#include "l2c_int.h" + +#include -#include "bt_target.h" +#include "bt_trace.h" +#include "bt_types.h" +#include "data_types.h" + +#include "btm_api.h" +#include "btm_int.h" +#include "btu.h" #include "gki.h" #include "hcidefs.h" -#include "hcimsgs.h" +#include "l2c_api.h" #include "l2cdefs.h" -#include "l2c_int.h" -#include "btm_int.h" -#include "btu.h" -#include "hcimsgs.h" - -/********************************************************************************/ -/* L O C A L F U N C T I O N P R O T O T Y P E S */ -/********************************************************************************/ -static void l2c_csm_closed (tL2C_CCB *p_ccb, UINT16 event, void *p_data); -static void l2c_csm_orig_w4_sec_comp (tL2C_CCB *p_ccb, UINT16 event, void *p_data); -static void l2c_csm_term_w4_sec_comp (tL2C_CCB *p_ccb, UINT16 event, void *p_data); -static void l2c_csm_w4_l2cap_connect_rsp (tL2C_CCB *p_ccb, UINT16 event, void *p_data); -static void l2c_csm_w4_l2ca_connect_rsp (tL2C_CCB *p_ccb, UINT16 event, void *p_data); -static void l2c_csm_config (tL2C_CCB *p_ccb, UINT16 event, void *p_data); -static void l2c_csm_open (tL2C_CCB *p_ccb, UINT16 event, void *p_data); -static void l2c_csm_w4_l2cap_disconnect_rsp (tL2C_CCB *p_ccb, UINT16 event, void *p_data); -static void l2c_csm_w4_l2ca_disconnect_rsp (tL2C_CCB *p_ccb, UINT16 event, void *p_data); - -#if (BT_TRACE_VERBOSE == TRUE) -static char *l2c_csm_get_event_name (UINT16 event); -#endif - -/******************************************************************************* -** -** Function l2c_csm_execute -** -** Description This function executes the state machine. -** -** Returns void -** -*******************************************************************************/ -void l2c_csm_execute (tL2C_CCB *p_ccb, UINT16 event, void *p_data) + +static void l2c_csm_closed(tL2C_CCB *p_ccb, UINT16 event, void *p_data); +static void l2c_csm_orig_w4_sec_comp(tL2C_CCB *p_ccb, UINT16 event, + void *p_data); +static void l2c_csm_term_w4_sec_comp(tL2C_CCB *p_ccb, UINT16 event, + void *p_data); +static void l2c_csm_w4_l2cap_connect_rsp(tL2C_CCB *p_ccb, UINT16 event, + void *p_data); +static void l2c_csm_w4_l2ca_connect_rsp(tL2C_CCB *p_ccb, UINT16 event, + void *p_data); +static void l2c_csm_config(tL2C_CCB *p_ccb, UINT16 event, void *p_data); +static void l2c_csm_open(tL2C_CCB *p_ccb, UINT16 event, void *p_data); +static void l2c_csm_w4_l2cap_disconnect_rsp(tL2C_CCB *p_ccb, UINT16 event, + void *p_data); +static void l2c_csm_w4_l2ca_disconnect_rsp(tL2C_CCB *p_ccb, UINT16 event, + void *p_data); + +void l2c_csm_execute(tL2C_CCB *p_ccb, UINT16 event, void *p_data) { switch (p_ccb->chnl_state) { case CST_CLOSED: - l2c_csm_closed (p_ccb, event, p_data); + l2c_csm_closed(p_ccb, event, p_data); break; case CST_ORIG_W4_SEC_COMP: - l2c_csm_orig_w4_sec_comp (p_ccb, event, p_data); + l2c_csm_orig_w4_sec_comp(p_ccb, event, p_data); break; case CST_TERM_W4_SEC_COMP: - l2c_csm_term_w4_sec_comp (p_ccb, event, p_data); + l2c_csm_term_w4_sec_comp(p_ccb, event, p_data); break; case CST_W4_L2CAP_CONNECT_RSP: - l2c_csm_w4_l2cap_connect_rsp (p_ccb, event, p_data); + l2c_csm_w4_l2cap_connect_rsp(p_ccb, event, p_data); break; case CST_W4_L2CA_CONNECT_RSP: - l2c_csm_w4_l2ca_connect_rsp (p_ccb, event, p_data); + l2c_csm_w4_l2ca_connect_rsp(p_ccb, event, p_data); break; case CST_CONFIG: - l2c_csm_config (p_ccb, event, p_data); + l2c_csm_config(p_ccb, event, p_data); break; case CST_OPEN: - l2c_csm_open (p_ccb, event, p_data); + l2c_csm_open(p_ccb, event, p_data); break; case CST_W4_L2CAP_DISCONNECT_RSP: - l2c_csm_w4_l2cap_disconnect_rsp (p_ccb, event, p_data); + l2c_csm_w4_l2cap_disconnect_rsp(p_ccb, event, p_data); break; case CST_W4_L2CA_DISCONNECT_RSP: - l2c_csm_w4_l2ca_disconnect_rsp (p_ccb, event, p_data); + l2c_csm_w4_l2ca_disconnect_rsp(p_ccb, event, p_data); break; default: @@ -107,1227 +106,746 @@ void l2c_csm_execute (tL2C_CCB *p_ccb, UINT16 event, void *p_data) } } -/******************************************************************************* -** -** Function l2c_csm_closed -** -** Description This function handles events when the channel is in -** CLOSED state. This state exists only when the link is -** being initially established. -** -** Returns void -** -*******************************************************************************/ -static void l2c_csm_closed (tL2C_CCB *p_ccb, UINT16 event, void *p_data) +static void l2c_csm_closed(tL2C_CCB *p_ccb, UINT16 event, void *p_data) { - tL2C_CONN_INFO *p_ci = (tL2C_CONN_INFO *)p_data; - UINT16 local_cid = p_ccb->local_cid; - tL2CA_DISCONNECT_IND_CB *disconnect_ind; - tL2CA_CONNECT_CFM_CB *connect_cfm; - - if (p_ccb->p_rcb == NULL) - { -#if (BT_TRACE_VERBOSE == TRUE) - L2CAP_TRACE_ERROR2 ("L2CAP - LCID: 0x%04x st: CLOSED evt: %s p_rcb == NULL", p_ccb->local_cid, l2c_csm_get_event_name (event)); -#else - L2CAP_TRACE_ERROR2 ("L2CAP - LCID: 0x%04x st: CLOSED evt: 0x%04x p_rcb == NULL", p_ccb->local_cid, event); -#endif - return; - } - -#if (L2CAP_UCD_INCLUDED == TRUE) - if ( local_cid == L2CAP_CONNECTIONLESS_CID ) - { - /* check if this event can be processed by UCD */ - if ( l2c_ucd_process_event (p_ccb, event, p_data) ) - { - /* The event is processed by UCD state machine */ - return; - } - } -#endif - - disconnect_ind = p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb; - connect_cfm = p_ccb->p_rcb->api.pL2CA_ConnectCfm_Cb; + tL2C_CONN_INFO *p_ci = p_data; + tL2CA_DISCONNECT_IND_CB *disconnect_ind = + p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb; + tL2CA_CONNECT_CFM_CB *connect_cfm = p_ccb->p_rcb->api.pL2CA_ConnectCfm_Cb; + UINT16 local_cid = p_ccb->local_cid; -#if (BT_TRACE_VERBOSE == TRUE) - L2CAP_TRACE_EVENT2 ("L2CAP - LCID: 0x%04x st: CLOSED evt: %s", p_ccb->local_cid, l2c_csm_get_event_name (event)); -#else - L2CAP_TRACE_EVENT1 ("L2CAP - st: CLOSED evt: %d", event); -#endif + L2CAP_TRACE(EVENT, "L2CAP - st: CLOSED evt: %d", event); switch (event) { - case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */ - L2CAP_TRACE_API1 ("L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed", p_ccb->local_cid); - l2cu_release_ccb (p_ccb); + case L2CEVT_LP_DISCONNECT_IND: + L2CAP_TRACE( + API, + "L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed", + p_ccb->local_cid); + l2cu_release_ccb(p_ccb); (*disconnect_ind)(local_cid, FALSE); break; - case L2CEVT_LP_CONNECT_CFM: /* Link came up */ + case L2CEVT_LP_CONNECT_CFM: p_ccb->chnl_state = CST_ORIG_W4_SEC_COMP; - btm_sec_l2cap_access_req (p_ccb->p_lcb->remote_bd_addr, p_ccb->p_rcb->psm, - p_ccb->p_lcb->handle, TRUE, &l2c_link_sec_comp, p_ccb); + btm_sec_l2cap_access_req(p_ccb->p_lcb->remote_bd_addr, + p_ccb->p_rcb->psm, p_ccb->p_lcb->handle, TRUE, + &l2c_link_sec_comp); break; - case L2CEVT_LP_CONNECT_CFM_NEG: /* Link failed */ - /* Disconnect unless ACL collision and upper layer wants to handle it */ - if (p_ci->status != HCI_ERR_CONNECTION_EXISTS - || !btm_acl_notif_conn_collision(p_ccb->p_lcb->remote_bd_addr)) - { - L2CAP_TRACE_API2 ("L2CAP - Calling ConnectCfm_Cb(), CID: 0x%04x Status: %d", p_ccb->local_cid, p_ci->status); - l2cu_release_ccb (p_ccb); - (*connect_cfm)(local_cid, p_ci->status); - } + case L2CEVT_LP_CONNECT_CFM_NEG: + L2CAP_TRACE(API, + "L2CAP - Calling ConnectCfm_Cb(), CID: 0x%04x Status: %d", + p_ccb->local_cid, p_ci->status); + l2cu_release_ccb(p_ccb); + (*connect_cfm)(local_cid, p_ci->status); + break; - case L2CEVT_L2CA_CONNECT_REQ: /* API connect request */ - /* Cancel sniff mode if needed */ -#if BTM_PWR_MGR_INCLUDED == TRUE + case L2CEVT_L2CA_CONNECT_REQ: + if (btm_sec_l2cap_access_req(p_ccb->p_lcb->remote_bd_addr, + p_ccb->p_rcb->psm, p_ccb->p_lcb->handle, + TRUE, &l2c_link_sec_comp) + == BTM_CMD_STARTED) { - tBTM_PM_PWR_MD settings; -// btla-specific ++ - memset((void*)&settings, 0, sizeof(settings)); -// btla-specific -- - settings.mode = BTM_PM_MD_ACTIVE; -/* COVERITY -Event uninit_use_in_call: Using uninitialized value "settings" (field "settings".timeout uninitialized) in call to function "BTM_SetPowerMode" [details] -Event uninit_use_in_call: Using uninitialized value "settings.max" in call to function "BTM_SetPowerMode" [details] -Event uninit_use_in_call: Using uninitialized value "settings.min" in call to function "BTM_SetPowerMode" -// FALSE-POSITIVE error from Coverity test-tool. Please do NOT remove following comment. -// coverity[uninit_use_in_call] False-positive: setting the mode to BTM_PM_MD_ACTIVE only uses settings.mode the other data members of tBTM_PM_PWR_MD are ignored -*/ - BTM_SetPowerMode (BTM_PM_SET_ONLY_ID, p_ccb->p_lcb->remote_bd_addr, &settings); + p_ccb->chnl_state = CST_ORIG_W4_SEC_COMP; } -#else - BTM_CancelSniffMode (p_ccb->p_lcb->remote_bd_addr); -#endif - /* If sec access does not result in started SEC_COM or COMP_NEG are already processed */ - if (btm_sec_l2cap_access_req (p_ccb->p_lcb->remote_bd_addr, p_ccb->p_rcb->psm, - p_ccb->p_lcb->handle, TRUE, &l2c_link_sec_comp, p_ccb) == BTM_CMD_STARTED) - p_ccb->chnl_state = CST_ORIG_W4_SEC_COMP; break; case L2CEVT_SEC_COMP: + l2cu_send_peer_connect_req(p_ccb); + p_ccb->chnl_state = CST_W4_L2CAP_CONNECT_RSP; - /* Wait for the info resp in this state before sending connect req (if needed) */ - if (!p_ccb->p_lcb->w4_info_rsp) - { - /* Need to have at least one compatible channel to continue */ - if (!l2c_fcr_chk_chan_modes(p_ccb)) - { - l2cu_release_ccb (p_ccb); - (*p_ccb->p_rcb->api.pL2CA_ConnectCfm_Cb)(local_cid, L2CAP_CONN_NO_LINK); - } - else - { - l2cu_send_peer_connect_req (p_ccb); - btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, L2CAP_CHNL_CONNECT_TOUT); - } - } + btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, + L2CAP_CHNL_CONNECT_TOUT); + break; - case L2CEVT_SEC_COMP_NEG: /* something is really bad with security */ - L2CAP_TRACE_API2 ("L2CAP - Calling ConnectCfm_Cb(), CID: 0x%04x Status: %d", p_ccb->local_cid, L2CAP_CONN_TIMEOUT); - l2cu_release_ccb (p_ccb); + case L2CEVT_SEC_COMP_NEG: + L2CAP_TRACE(API, + "L2CAP - Calling ConnectCfm_Cb(), CID: 0x%04x Status: %d", + p_ccb->local_cid, L2CAP_CONN_TIMEOUT); + l2cu_release_ccb(p_ccb); (*connect_cfm)(local_cid, L2CAP_CONN_SECURITY_BLOCK); break; - case L2CEVT_L2CAP_CONNECT_REQ: /* Peer connect request */ - /* stop link timer to avoid race condition between A2MP, Security, and L2CAP */ - btu_stop_timer (&p_ccb->p_lcb->timer_entry); - - /* Cancel sniff mode if needed */ -#if BTM_PWR_MGR_INCLUDED == TRUE - { - tBTM_PM_PWR_MD settings; -// btla-specific ++ - memset((void*)&settings, 0, sizeof(settings)); -// btla-specific -- - settings.mode = BTM_PM_MD_ACTIVE; -/* COVERITY -Event uninit_use_in_call: Using uninitialized value "settings" (field "settings".timeout uninitialized) in call to function "BTM_SetPowerMode" [details] -Event uninit_use_in_call: Using uninitialized value "settings.max" in call to function "BTM_SetPowerMode" [details] -Event uninit_use_in_call: Using uninitialized value "settings.min" in call to function "BTM_SetPowerMode" -// FALSE-POSITIVE error from Coverity test-tool. Please do NOT remove following comment. -// coverity[uninit_use_in_call] False-positive: setting the mode to BTM_PM_MD_ACTIVE only uses settings.mode the other data members of tBTM_PM_PWR_MD are ignored -*/ - BTM_SetPowerMode (BTM_PM_SET_ONLY_ID, p_ccb->p_lcb->remote_bd_addr, &settings); - } -#else - BTM_CancelSniffMode (p_ccb->p_lcb->remote_bd_addr); -#endif - + case L2CEVT_L2CAP_CONNECT_REQ: p_ccb->chnl_state = CST_TERM_W4_SEC_COMP; - if (btm_sec_l2cap_access_req (p_ccb->p_lcb->remote_bd_addr, p_ccb->p_rcb->psm, - p_ccb->p_lcb->handle, FALSE, &l2c_link_sec_comp, p_ccb) == BTM_CMD_STARTED) - { - /* started the security process, tell the peer to set a longer timer */ - l2cu_send_peer_connect_rsp(p_ccb, L2CAP_CONN_PENDING, 0); - } + btm_sec_l2cap_access_req(p_ccb->p_lcb->remote_bd_addr, + p_ccb->p_rcb->psm, p_ccb->p_lcb->handle, + FALSE, &l2c_link_sec_comp); break; case L2CEVT_TIMEOUT: - L2CAP_TRACE_API2 ("L2CAP - Calling ConnectCfm_Cb(), CID: 0x%04x Status: %d", p_ccb->local_cid, L2CAP_CONN_TIMEOUT); - l2cu_release_ccb (p_ccb); + L2CAP_TRACE(API, + "L2CAP - Calling ConnectCfm_Cb(), CID: 0x%04x Status: %d", + p_ccb->local_cid, L2CAP_CONN_TIMEOUT); + l2cu_release_ccb(p_ccb); (*connect_cfm)(local_cid, L2CAP_CONN_TIMEOUT); break; - case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */ - case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */ - GKI_freebuf (p_data); + case L2CEVT_L2CAP_DATA: + case L2CEVT_L2CA_DATA_WRITE: + GKI_freebuf(p_data); break; - case L2CEVT_L2CA_DISCONNECT_REQ: /* Upper wants to disconnect */ - l2cu_release_ccb (p_ccb); + case L2CEVT_L2CA_DISCONNECT_REQ: + l2cu_release_ccb(p_ccb); break; } } - -/******************************************************************************* -** -** Function l2c_csm_orig_w4_sec_comp -** -** Description This function handles events when the channel is in -** CST_ORIG_W4_SEC_COMP state. -** -** Returns void -** -*******************************************************************************/ -static void l2c_csm_orig_w4_sec_comp (tL2C_CCB *p_ccb, UINT16 event, void *p_data) +static void l2c_csm_orig_w4_sec_comp(tL2C_CCB *p_ccb, UINT16 event, + void *p_data) { - tL2CA_DISCONNECT_IND_CB *disconnect_ind = p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb; - tL2CA_CONNECT_CFM_CB *connect_cfm = p_ccb->p_rcb->api.pL2CA_ConnectCfm_Cb; - UINT16 local_cid = p_ccb->local_cid; - -#if (BT_TRACE_VERBOSE == TRUE) - L2CAP_TRACE_EVENT2 ("L2CAP - LCID: 0x%04x st: ORIG_W4_SEC_COMP evt: %s", p_ccb->local_cid, l2c_csm_get_event_name (event)); -#else - L2CAP_TRACE_EVENT1 ("L2CAP - st: ORIG_W4_SEC_COMP evt: %d", event); -#endif - -#if (L2CAP_UCD_INCLUDED == TRUE) - if ( local_cid == L2CAP_CONNECTIONLESS_CID ) - { - /* check if this event can be processed by UCD */ - if ( l2c_ucd_process_event (p_ccb, event, p_data) ) - { - /* The event is processed by UCD state machine */ - return; - } - } -#endif + tL2CA_DISCONNECT_IND_CB *disconnect_ind = + p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb; + tL2CA_CONNECT_CFM_CB *connect_cfm = p_ccb->p_rcb->api.pL2CA_ConnectCfm_Cb; + UINT16 local_cid = p_ccb->local_cid; + + L2CAP_TRACE(EVENT, "L2CAP - st: ORIG_W4_SEC_COMP evt: %d", event); switch (event) { - case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */ - L2CAP_TRACE_API1 ("L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed", p_ccb->local_cid); - l2cu_release_ccb (p_ccb); - (*disconnect_ind)(local_cid, FALSE); - break; + case L2CEVT_LP_DISCONNECT_IND: + L2CAP_TRACE( + API, + "L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed", + p_ccb->local_cid); - case L2CEVT_SEC_RE_SEND_CMD: /* BTM has enough info to proceed */ - case L2CEVT_LP_CONNECT_CFM: /* Link came up */ - btm_sec_l2cap_access_req (p_ccb->p_lcb->remote_bd_addr, p_ccb->p_rcb->psm, - p_ccb->p_lcb->handle, TRUE, &l2c_link_sec_comp, p_ccb); + l2cu_release_ccb(p_ccb); + (*disconnect_ind)(local_cid, FALSE); break; - case L2CEVT_SEC_COMP: /* Security completed success */ - /* Wait for the info resp in this state before sending connect req (if needed) */ + case L2CEVT_SEC_COMP: p_ccb->chnl_state = CST_W4_L2CAP_CONNECT_RSP; - if (!p_ccb->p_lcb->w4_info_rsp) - { - /* Need to have at least one compatible channel to continue */ - if (!l2c_fcr_chk_chan_modes(p_ccb)) - { - l2cu_release_ccb (p_ccb); - (*connect_cfm)(local_cid, L2CAP_CONN_NO_LINK); - } - else - { - btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, L2CAP_CHNL_CONNECT_TOUT); - l2cu_send_peer_connect_req (p_ccb); /* Start Connection */ - } - } + + btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, + L2CAP_CHNL_CONNECT_TOUT); + l2cu_send_peer_connect_req(p_ccb); + + p_ccb->rtry_flag = FALSE; + break; case L2CEVT_SEC_COMP_NEG: - L2CAP_TRACE_API2 ("L2CAP - Calling ConnectCfm_Cb(), CID: 0x%04x Status: %d", p_ccb->local_cid, HCI_ERR_AUTH_FAILURE); - - /* If last channel immediately disconnect the ACL for better security. - Also prevents a race condition between BTM and L2CAP */ - if ( (p_ccb == p_ccb->p_lcb->ccb_queue.p_first_ccb) && (p_ccb == p_ccb->p_lcb->ccb_queue.p_last_ccb) ) - { - p_ccb->p_lcb->idle_timeout = 0; - } + L2CAP_TRACE(API, + "L2CAP - Calling ConnectCfm_Cb(), CID: 0x%04x Status: %d", + p_ccb->local_cid, HCI_ERR_AUTH_FAILURE); - l2cu_release_ccb (p_ccb); + l2cu_release_ccb(p_ccb); (*connect_cfm)(local_cid, HCI_ERR_AUTH_FAILURE); break; - case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */ - case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */ - GKI_freebuf (p_data); + case L2CEVT_L2CA_DATA_WRITE: + case L2CEVT_L2CAP_DATA: + GKI_freebuf(p_data); break; - case L2CEVT_L2CA_DISCONNECT_REQ: /* Upper wants to disconnect */ - /* Tell security manager to abort */ - btm_sec_abort_access_req (p_ccb->p_lcb->remote_bd_addr); + case L2CEVT_L2CA_DISCONNECT_REQ: + btm_sec_abort_access_req(p_ccb->p_lcb->remote_bd_addr); - l2cu_release_ccb (p_ccb); + l2cu_release_ccb(p_ccb); break; } } - -/******************************************************************************* -** -** Function l2c_csm_term_w4_sec_comp -** -** Description This function handles events when the channel is in -** CST_TERM_W4_SEC_COMP state. -** -** Returns void -** -*******************************************************************************/ -static void l2c_csm_term_w4_sec_comp (tL2C_CCB *p_ccb, UINT16 event, void *p_data) +static void l2c_csm_term_w4_sec_comp(tL2C_CCB *p_ccb, UINT16 event, + void *p_data) { -#if (BT_TRACE_VERBOSE == TRUE) - L2CAP_TRACE_EVENT2 ("L2CAP - LCID: 0x%04x st: TERM_W4_SEC_COMP evt: %s", p_ccb->local_cid, l2c_csm_get_event_name (event)); -#else - L2CAP_TRACE_EVENT1 ("L2CAP - st: TERM_W4_SEC_COMP evt: %d", event); -#endif - -#if (L2CAP_UCD_INCLUDED == TRUE) - if ( p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID ) - { - /* check if this event can be processed by UCD */ - if ( l2c_ucd_process_event (p_ccb, event, p_data) ) - { - /* The event is processed by UCD state machine */ - return; - } - } -#endif + L2CAP_TRACE(EVENT, "L2CAP - st: TERM_W4_SEC_COMP evt: %d", event); switch (event) { - case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */ - /* Tell security manager to abort */ - btm_sec_abort_access_req (p_ccb->p_lcb->remote_bd_addr); + case L2CEVT_LP_DISCONNECT_IND: + btm_sec_abort_access_req(p_ccb->p_lcb->remote_bd_addr); - l2cu_release_ccb (p_ccb); + l2cu_release_ccb(p_ccb); break; case L2CEVT_SEC_COMP: p_ccb->chnl_state = CST_W4_L2CA_CONNECT_RSP; - /* Wait for the info resp in next state before sending connect ind (if needed) */ - if (!p_ccb->p_lcb->w4_info_rsp) - { - /* Don't need to get info from peer or already retrieved so continue */ - btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, L2CAP_CHNL_CONNECT_TOUT); - L2CAP_TRACE_API1 ("L2CAP - Calling Connect_Ind_Cb(), CID: 0x%04x", p_ccb->local_cid); + btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, + L2CAP_CHNL_CONNECT_TOUT); + L2CAP_TRACE(API, "L2CAP - Calling Connect_Ind_Cb(), CID: 0x%04x", + p_ccb->local_cid); - (*p_ccb->p_rcb->api.pL2CA_ConnectInd_Cb) (p_ccb->p_lcb->remote_bd_addr, p_ccb->local_cid, - p_ccb->p_rcb->psm, p_ccb->remote_id); - } - else - { - /* - ** L2CAP Connect Response will be sent out by 3 sec timer expiration - ** because Bluesoleil doesn't respond to L2CAP Information Request. - ** Bluesoleil seems to disconnect ACL link as failure case, because - ** it takes too long (4~7secs) to get response. - ** product version : Bluesoleil 2.1.1.0 EDR Release 060123 - ** stack version : 05.04.11.20060119 - */ - - /* Waiting for the info resp, tell the peer to set a longer timer */ - l2cu_send_peer_connect_rsp(p_ccb, L2CAP_CONN_PENDING, 0); - } + (*p_ccb->p_rcb->api.pL2CA_ConnectInd_Cb)( + p_ccb->p_lcb->remote_bd_addr, p_ccb->local_cid, p_ccb->p_rcb->psm, + p_ccb->remote_id); break; case L2CEVT_SEC_COMP_NEG: - if (((tL2C_CONN_INFO *)p_data)->status == BTM_DELAY_CHECK) - { - /* start a timer - encryption change not received before L2CAP connect req */ - btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, L2CAP_DELAY_CHECK_SM4); - } - else - { - l2cu_send_peer_connect_rsp (p_ccb, L2CAP_CONN_SECURITY_BLOCK, 0); - l2cu_release_ccb (p_ccb); - } + l2cu_send_peer_connect_rsp(p_ccb, L2CAP_CONN_SECURITY_BLOCK, 0); + l2cu_release_ccb(p_ccb); break; - case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */ - case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */ - GKI_freebuf (p_data); + case L2CEVT_L2CA_DATA_WRITE: + case L2CEVT_L2CAP_DATA: + GKI_freebuf(p_data); break; - case L2CEVT_L2CA_DISCONNECT_REQ: /* Upper wants to disconnect */ - l2cu_release_ccb (p_ccb); + case L2CEVT_L2CA_DISCONNECT_REQ: + l2cu_release_ccb(p_ccb); break; - case L2CEVT_L2CAP_DISCONNECT_REQ: /* Peer disconnected request */ - l2cu_send_peer_disc_rsp (p_ccb->p_lcb, p_ccb->remote_id, p_ccb->local_cid, p_ccb->remote_cid); + case L2CEVT_L2CAP_DISCONNECT_REQ: + l2cu_send_peer_disc_rsp(p_ccb->p_lcb, p_ccb->remote_id, + p_ccb->local_cid, p_ccb->remote_cid); - /* Tell security manager to abort */ - btm_sec_abort_access_req (p_ccb->p_lcb->remote_bd_addr); - - l2cu_release_ccb (p_ccb); - break; + btm_sec_abort_access_req(p_ccb->p_lcb->remote_bd_addr); - case L2CEVT_TIMEOUT: - /* SM4 related. */ - if (!btsnd_hcic_disconnect (p_ccb->p_lcb->handle, HCI_ERR_AUTH_FAILURE)) - { - L2CAP_TRACE_API1 ("L2CAP - Calling btsnd_hcic_disconnect for handle %i failed", p_ccb->p_lcb->handle); - btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, 1); - } - break; - - case L2CEVT_SEC_RE_SEND_CMD: /* BTM has enough info to proceed */ - btm_sec_l2cap_access_req (p_ccb->p_lcb->remote_bd_addr, p_ccb->p_rcb->psm, - p_ccb->p_lcb->handle, FALSE, &l2c_link_sec_comp, p_ccb); + l2cu_release_ccb(p_ccb); break; } } - -/******************************************************************************* -** -** Function l2c_csm_w4_l2cap_connect_rsp -** -** Description This function handles events when the channel is in -** CST_W4_L2CAP_CONNECT_RSP state. -** -** Returns void -** -*******************************************************************************/ -static void l2c_csm_w4_l2cap_connect_rsp (tL2C_CCB *p_ccb, UINT16 event, void *p_data) +static void l2c_csm_w4_l2cap_connect_rsp(tL2C_CCB *p_ccb, UINT16 event, + void *p_data) { - tL2C_CONN_INFO *p_ci = (tL2C_CONN_INFO *)p_data; - tL2CA_DISCONNECT_IND_CB *disconnect_ind = p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb; - tL2CA_CONNECT_CFM_CB *connect_cfm = p_ccb->p_rcb->api.pL2CA_ConnectCfm_Cb; - UINT16 local_cid = p_ccb->local_cid; + tL2C_CONN_INFO *p_ci = (tL2C_CONN_INFO *)p_data; + tL2CA_DISCONNECT_IND_CB *disconnect_ind = + p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb; + tL2CA_CONNECT_CFM_CB *connect_cfm = p_ccb->p_rcb->api.pL2CA_ConnectCfm_Cb; + UINT16 local_cid = p_ccb->local_cid; -#if (BT_TRACE_VERBOSE == TRUE) - L2CAP_TRACE_EVENT2 ("L2CAP - LCID: 0x%04x st: W4_L2CAP_CON_RSP evt: %s", p_ccb->local_cid, l2c_csm_get_event_name (event)); -#else - L2CAP_TRACE_EVENT1 ("L2CAP - st: W4_L2CAP_CON_RSP evt: %d", event); -#endif + L2CAP_TRACE(EVENT, "L2CAP - st: W4_L2CAP_CON_RSP evt: %d", event); switch (event) { - case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */ - /* Send disc indication unless peer to peer race condition AND normal disconnect */ - /* *((UINT8 *)p_data) != HCI_ERR_PEER_USER happens when peer device try to disconnect for normal reason */ + case L2CEVT_LP_DISCONNECT_IND: p_ccb->chnl_state = CST_CLOSED; - if ((p_ccb->flags & CCB_FLAG_NO_RETRY) || !p_data || (*((UINT8 *)p_data) != HCI_ERR_PEER_USER)) - { - L2CAP_TRACE_API1 ("L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed", - p_ccb->local_cid); - l2cu_release_ccb (p_ccb); - (*disconnect_ind)(local_cid, FALSE); - } - p_ccb->flags |= CCB_FLAG_NO_RETRY; + L2CAP_TRACE(API, + "L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x " + " No Conf Needed", + p_ccb->local_cid); + l2cu_release_ccb(p_ccb); + (*disconnect_ind)(local_cid, FALSE); break; - case L2CEVT_L2CAP_CONNECT_RSP: /* Got peer connect confirm */ + case L2CEVT_L2CAP_CONNECT_RSP: p_ccb->remote_cid = p_ci->remote_cid; p_ccb->chnl_state = CST_CONFIG; - btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, L2CAP_CHNL_CFG_TIMEOUT); - L2CAP_TRACE_API1 ("L2CAP - Calling Connect_Cfm_Cb(), CID: 0x%04x, Success", p_ccb->local_cid); + btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, + L2CAP_CHNL_CFG_TOUT); + L2CAP_TRACE(API, + "L2CAP - Calling Connect_Cfm_Cb(), CID: 0x%04x, Success", + p_ccb->local_cid); - (*p_ccb->p_rcb->api.pL2CA_ConnectCfm_Cb)(local_cid, L2CAP_CONN_OK); + (*p_ccb->p_rcb->api.pL2CA_ConnectCfm_Cb)(p_ccb->local_cid, + L2CAP_CONN_OK); break; - case L2CEVT_L2CAP_CONNECT_RSP_PND: /* Got peer connect pending */ - p_ccb->remote_cid = p_ci->remote_cid; - btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, L2CAP_CHNL_CONNECT_TOUT_EXT); + case L2CEVT_L2CAP_CONNECT_RSP_PND: + btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, + L2CAP_CHNL_CONNECT_TOUT_EXT); if (p_ccb->p_rcb->api.pL2CA_ConnectPnd_Cb) { - L2CAP_TRACE_API1 ("L2CAP - Calling Connect_Pnd_Cb(), CID: 0x%04x", p_ccb->local_cid); - (*p_ccb->p_rcb->api.pL2CA_ConnectPnd_Cb)(p_ccb->local_cid); + L2CAP_TRACE(API, "L2CAP - Calling Connect_Pnd_Cb()"); + (*p_ccb->p_rcb->api.pL2CA_ConnectPnd_Cb)(0); } break; - case L2CEVT_L2CAP_CONNECT_RSP_NEG: /* Peer rejected connection */ - L2CAP_TRACE_API2 ("L2CAP - Calling Connect_Cfm_Cb(), CID: 0x%04x, Failure Code: %d", p_ccb->local_cid, p_ci->l2cap_result); - l2cu_release_ccb (p_ccb); + case L2CEVT_L2CAP_CONNECT_RSP_NEG: + L2CAP_TRACE( + API, + "L2CAP - Calling Connect_Cfm_Cb(), CID: 0x%04x, Failure Code: %d", + p_ccb->local_cid, p_ci->l2cap_result); + l2cu_release_ccb(p_ccb); (*connect_cfm)(local_cid, p_ci->l2cap_result); break; case L2CEVT_TIMEOUT: - L2CAP_TRACE_API1 ("L2CAP - Calling Connect_Cfm_Cb(), CID: 0x%04x, Timeout", p_ccb->local_cid); - l2cu_release_ccb (p_ccb); + L2CAP_TRACE(API, + "L2CAP - Calling Connect_Cfm_Cb(), CID: 0x%04x, Timeout", + p_ccb->local_cid); + l2cu_release_ccb(p_ccb); (*connect_cfm)(local_cid, L2CAP_CONN_TIMEOUT); break; - case L2CEVT_L2CA_DISCONNECT_REQ: /* Upper wants to disconnect */ - /* If we know peer CID from connect pending, we can send disconnect */ - if (p_ccb->remote_cid != 0) - { - l2cu_send_peer_disc_req (p_ccb); - p_ccb->chnl_state = CST_W4_L2CAP_DISCONNECT_RSP; - btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, L2CAP_CHNL_DISCONNECT_TOUT); - } - else - l2cu_release_ccb (p_ccb); - break; + case L2CEVT_L2CA_DISCONNECT_REQ: + l2cu_release_ccb(p_ccb); - case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */ - case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */ - GKI_freebuf (p_data); break; - case L2CEVT_L2CAP_INFO_RSP: - /* Need to have at least one compatible channel to continue */ - if (!l2c_fcr_chk_chan_modes(p_ccb)) - { - l2cu_release_ccb (p_ccb); - (*connect_cfm)(local_cid, L2CAP_CONN_NO_LINK); - } - else - { - /* We have feature info, so now send peer connect request */ - btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, L2CAP_CHNL_CONNECT_TOUT); - l2cu_send_peer_connect_req (p_ccb); /* Start Connection */ - } + case L2CEVT_L2CA_DATA_WRITE: + case L2CEVT_L2CAP_DATA: + GKI_freebuf(p_data); break; } } - -/******************************************************************************* -** -** Function l2c_csm_w4_l2ca_connect_rsp -** -** Description This function handles events when the channel is in -** CST_W4_L2CA_CONNECT_RSP state. -** -** Returns void -** -*******************************************************************************/ -static void l2c_csm_w4_l2ca_connect_rsp (tL2C_CCB *p_ccb, UINT16 event, void *p_data) +static void l2c_csm_w4_l2ca_connect_rsp(tL2C_CCB *p_ccb, UINT16 event, + void *p_data) { - tL2C_CONN_INFO *p_ci; - tL2CA_DISCONNECT_IND_CB *disconnect_ind = p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb; - UINT16 local_cid = p_ccb->local_cid; + tL2C_CONN_INFO *p_ci; + tL2CA_DISCONNECT_IND_CB *disconnect_ind = + p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb; + UINT16 local_cid = p_ccb->local_cid; -#if (BT_TRACE_VERBOSE == TRUE) - L2CAP_TRACE_EVENT2 ("L2CAP - LCID: 0x%04x st: W4_L2CA_CON_RSP evt: %s", p_ccb->local_cid, l2c_csm_get_event_name (event)); -#else - L2CAP_TRACE_EVENT1 ("L2CAP - st: W4_L2CA_CON_RSP evt: %d", event); -#endif + L2CAP_TRACE(EVENT, "L2CAP - st: W4_L2CA_CON_RSP evt: %d", event); switch (event) { - case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */ - L2CAP_TRACE_API1 ("L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed", p_ccb->local_cid); - l2cu_release_ccb (p_ccb); + case L2CEVT_LP_DISCONNECT_IND: + L2CAP_TRACE( + API, + "L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed", + p_ccb->local_cid); + l2cu_release_ccb(p_ccb); (*disconnect_ind)(local_cid, FALSE); break; case L2CEVT_L2CA_CONNECT_RSP: - p_ci = (tL2C_CONN_INFO *)p_data; + p_ci = p_data; - /* Result should be OK or PENDING */ - if ((!p_ci) || (p_ci->l2cap_result == L2CAP_CONN_OK)) + if (!p_ci || p_ci->l2cap_result == L2CAP_CONN_OK) { - l2cu_send_peer_connect_rsp (p_ccb, L2CAP_CONN_OK, 0); + l2cu_send_peer_connect_rsp(p_ccb, L2CAP_CONN_OK, 0); p_ccb->chnl_state = CST_CONFIG; - btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, L2CAP_CHNL_CFG_TIMEOUT); + btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, + L2CAP_CHNL_CFG_TOUT); } else { - /* If pending, stay in same state and start extended timer */ - l2cu_send_peer_connect_rsp (p_ccb, p_ci->l2cap_result, p_ci->l2cap_status); - btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, L2CAP_CHNL_CONNECT_TOUT_EXT); + l2cu_send_peer_connect_rsp(p_ccb, p_ci->l2cap_result, + p_ci->l2cap_status); + btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, + L2CAP_CHNL_CONNECT_TOUT_EXT); } break; case L2CEVT_L2CA_CONNECT_RSP_NEG: - p_ci = (tL2C_CONN_INFO *)p_data; - l2cu_send_peer_connect_rsp (p_ccb, p_ci->l2cap_result, p_ci->l2cap_status); - l2cu_release_ccb (p_ccb); + p_ci = p_data; + l2cu_send_peer_connect_rsp(p_ccb, p_ci->l2cap_result, + p_ci->l2cap_status); + l2cu_release_ccb(p_ccb); break; case L2CEVT_TIMEOUT: - l2cu_send_peer_connect_rsp (p_ccb, L2CAP_CONN_NO_PSM, 0); - L2CAP_TRACE_API1 ("L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed", p_ccb->local_cid); - l2cu_release_ccb (p_ccb); + l2cu_send_peer_connect_rsp(p_ccb, L2CAP_CONN_NO_PSM, 0); + L2CAP_TRACE( + API, + "L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed", + p_ccb->local_cid); + l2cu_release_ccb(p_ccb); (*disconnect_ind)(local_cid, FALSE); break; - case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */ - case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */ - GKI_freebuf (p_data); + case L2CEVT_L2CA_DATA_WRITE: + case L2CEVT_L2CAP_DATA: + GKI_freebuf(p_data); break; - case L2CEVT_L2CA_DISCONNECT_REQ: /* Upper wants to disconnect */ - l2cu_send_peer_disc_req (p_ccb); + case L2CEVT_L2CA_DISCONNECT_REQ: + l2cu_send_peer_disc_req(p_ccb); p_ccb->chnl_state = CST_W4_L2CAP_DISCONNECT_RSP; - btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, L2CAP_CHNL_DISCONNECT_TOUT); - break; - - case L2CEVT_L2CAP_INFO_RSP: - /* We have feature info, so now give the upper layer connect IND */ - btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, L2CAP_CHNL_CONNECT_TOUT); - L2CAP_TRACE_API1 ("L2CAP - Calling Connect_Ind_Cb(), CID: 0x%04x", p_ccb->local_cid); - - (*p_ccb->p_rcb->api.pL2CA_ConnectInd_Cb) (p_ccb->p_lcb->remote_bd_addr, - p_ccb->local_cid, - p_ccb->p_rcb->psm, - p_ccb->remote_id); + btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, + L2CAP_CHNL_DISCONNECT_TOUT); break; } } - -/******************************************************************************* -** -** Function l2c_csm_config -** -** Description This function handles events when the channel is in -** CONFIG state. -** -** Returns void -** -*******************************************************************************/ -static void l2c_csm_config (tL2C_CCB *p_ccb, UINT16 event, void *p_data) +static void l2c_csm_config(tL2C_CCB *p_ccb, UINT16 event, void *p_data) { - tL2CAP_CFG_INFO *p_cfg = (tL2CAP_CFG_INFO *)p_data; - tL2CA_DISCONNECT_IND_CB *disconnect_ind = p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb; - UINT16 local_cid = p_ccb->local_cid; - UINT8 cfg_result; + tL2CAP_CFG_INFO *p_cfg = p_data; + tL2CA_DISCONNECT_IND_CB *disconnect_ind = + p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb; + UINT16 local_cid = p_ccb->local_cid; -#if (BT_TRACE_VERBOSE == TRUE) - L2CAP_TRACE_EVENT2 ("L2CAP - LCID: 0x%04x st: CONFIG evt: %s", p_ccb->local_cid, l2c_csm_get_event_name (event)); -#else - L2CAP_TRACE_EVENT1 ("L2CAP - st: CONFIG evt: %d", event); -#endif + L2CAP_TRACE(EVENT, "L2CAP - st: CONFIG evt: %d", event); switch (event) { - case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */ - L2CAP_TRACE_API1 ("L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed", p_ccb->local_cid); - l2cu_release_ccb (p_ccb); + case L2CEVT_LP_DISCONNECT_IND: + L2CAP_TRACE( + API, + "L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed", + p_ccb->local_cid); + l2cu_release_ccb(p_ccb); (*disconnect_ind)(local_cid, FALSE); break; - case L2CEVT_L2CAP_CONFIG_REQ: /* Peer config request */ - - if ((cfg_result = l2cu_process_peer_cfg_req (p_ccb, p_cfg)) == L2CAP_PEER_CFG_OK) + case L2CEVT_L2CAP_CONFIG_REQ: + if (l2cu_process_peer_cfg_req(p_ccb, p_cfg) != 0) { - L2CAP_TRACE_EVENT2 ("L2CAP - Calling Config_Req_Cb(), CID: 0x%04x, C-bit %d", - p_ccb->local_cid, (p_cfg->flags & L2CAP_CFG_FLAGS_MASK_CONT)); + L2CAP_TRACE(API, "L2CAP - Calling Config_Req_Cb(), CID: 0x%04x", + p_ccb->local_cid); (*p_ccb->p_rcb->api.pL2CA_ConfigInd_Cb)(p_ccb->local_cid, p_cfg); } - else if (cfg_result == L2CAP_PEER_CFG_DISCONNECT) - { - /* Disconnect if channels are incompatible */ - L2CAP_TRACE_EVENT0 ("L2CAP - incompatible configurations disconnect"); - l2cu_disconnect_chnl (p_ccb); - } - else /* Return error to peer so he can renegotiate if possible */ + else { - L2CAP_TRACE_EVENT0 ("L2CAP - incompatible configurations trying reconfig"); - l2cu_send_peer_config_rsp (p_ccb, p_cfg); + l2cu_send_peer_config_rsp(p_ccb, p_cfg); } break; - case L2CEVT_L2CAP_CONFIG_RSP: /* Peer config response */ - l2cu_process_peer_cfg_rsp (p_ccb, p_cfg); - - if (p_cfg->result != L2CAP_CFG_PENDING) - { - /* TBD: When config options grow beyong minimum MTU (48 bytes) - * logic needs to be added to handle responses with - * continuation bit set in flags field. - * 1. Send additional config request out until C-bit is cleared in response - */ - p_ccb->config_done |= OB_CFG_DONE; - - if (p_ccb->config_done & IB_CFG_DONE) - { - /* Verify two sides are in compatible modes before continuing */ - if (p_ccb->our_cfg.fcr.mode != p_ccb->peer_cfg.fcr.mode) - { - l2cu_send_peer_disc_req (p_ccb); - L2CAP_TRACE_WARNING1 ("L2CAP - Calling Disconnect_Ind_Cb(Incompatible CFG), CID: 0x%04x No Conf Needed", p_ccb->local_cid); - l2cu_release_ccb (p_ccb); - (*disconnect_ind)(local_cid, FALSE); - break; - } - - p_ccb->config_done |= RECONFIG_FLAG; - p_ccb->chnl_state = CST_OPEN; - l2c_link_adjust_chnl_allocation (); - btu_stop_timer (&p_ccb->timer_entry); - - /* If using eRTM and waiting for an ACK, restart the ACK timer */ - if (p_ccb->fcrb.wait_ack) - l2c_fcr_start_timer(p_ccb); - - /* - ** check p_ccb->our_cfg.fcr.mon_tout and p_ccb->our_cfg.fcr.rtrans_tout - ** we may set them to zero when sending config request during renegotiation - */ - if ((p_ccb->our_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) - &&((p_ccb->our_cfg.fcr.mon_tout == 0)||(p_ccb->our_cfg.fcr.rtrans_tout))) - { - l2c_fcr_adj_monitor_retran_timeout (p_ccb); - } - -#if (L2CAP_ERTM_STATS == TRUE) - p_ccb->fcrb.connect_tick_count = GKI_get_os_tick_count(); -#endif - /* See if we can forward anything on the hold queue */ - if (p_ccb->xmit_hold_q.count) - { - l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, NULL); - } - } + case L2CEVT_L2CAP_CONFIG_RSP: + l2cu_process_peer_cfg_rsp(p_ccb, p_cfg); + + p_ccb->config_done |= OB_CFG_DONE; + + if (p_ccb->config_done & IB_CFG_DONE) + { + p_ccb->chnl_state = CST_OPEN; + + btu_stop_timer(&p_ccb->timer_entry); + forward_peer_data(p_ccb, 0); } - L2CAP_TRACE_API1 ("L2CAP - Calling Config_Rsp_Cb(), CID: 0x%04x", p_ccb->local_cid); + L2CAP_TRACE(API, "L2CAP - Calling Config_Rsp_Cb(), CID: 0x%04x", + p_ccb->local_cid); (*p_ccb->p_rcb->api.pL2CA_ConfigCfm_Cb)(p_ccb->local_cid, p_cfg); break; - case L2CEVT_L2CAP_CONFIG_RSP_NEG: /* Peer config error rsp */ - /* Disable the Timer */ - btu_stop_timer (&p_ccb->timer_entry); + case L2CEVT_L2CAP_CONFIG_RSP_NEG: + btu_stop_timer(&p_ccb->timer_entry); + + L2CAP_TRACE( + API, + "L2CAP - Calling Config_Rsp_Cb(), CID: 0x%04x, Failure: %d", + p_ccb->local_cid, p_cfg->result); + (*p_ccb->p_rcb->api.pL2CA_ConfigCfm_Cb)(p_ccb->local_cid, p_cfg); - /* If failure was channel mode try to renegotiate */ - if (l2c_fcr_renegotiate_chan(p_ccb, p_cfg) == FALSE) - { - L2CAP_TRACE_API2 ("L2CAP - Calling Config_Rsp_Cb(), CID: 0x%04x, Failure: %d", p_ccb->local_cid, p_cfg->result); - (*p_ccb->p_rcb->api.pL2CA_ConfigCfm_Cb)(p_ccb->local_cid, p_cfg); - } break; - case L2CEVT_L2CAP_DISCONNECT_REQ: /* Peer disconnected request */ - btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, L2CAP_CHNL_DISCONNECT_TOUT); + case L2CEVT_L2CAP_DISCONNECT_REQ: + btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, + L2CAP_CHNL_DISCONNECT_TOUT); p_ccb->chnl_state = CST_W4_L2CA_DISCONNECT_RSP; - L2CAP_TRACE_API1 ("L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x Conf Needed", p_ccb->local_cid); + L2CAP_TRACE( + API, + "L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x Conf Needed", + p_ccb->local_cid); (*p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb)(p_ccb->local_cid, TRUE); break; - case L2CEVT_L2CA_CONFIG_REQ: /* Upper layer config req */ - l2cu_process_our_cfg_req (p_ccb, p_cfg); - l2cu_send_peer_config_req (p_ccb, p_cfg); - btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, L2CAP_CHNL_CFG_TIMEOUT); + case L2CEVT_L2CA_CONFIG_REQ: + l2cu_process_our_cfg_req(p_ccb, p_cfg); + l2cu_send_peer_config_req(p_ccb, p_cfg); + btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, + L2CAP_CHNL_CFG_TOUT); break; - case L2CEVT_L2CA_CONFIG_RSP: /* Upper layer config rsp */ - l2cu_process_our_cfg_rsp (p_ccb, p_cfg); - - /* Not finished if continuation flag is set */ - if ( (p_cfg->flags & L2CAP_CFG_FLAGS_MASK_CONT) || (p_cfg->result == L2CAP_CFG_PENDING) ) - { - /* Send intermediate response; remain in cfg state */ - l2cu_send_peer_config_rsp (p_ccb, p_cfg); - break; - } - - /* Local config done; clear cached configuration in case reconfig takes place later */ - p_ccb->peer_cfg.mtu_present = FALSE; - p_ccb->peer_cfg.flush_to_present = FALSE; - p_ccb->peer_cfg.qos_present = FALSE; + case L2CEVT_L2CA_CONFIG_RSP: + l2cu_process_our_cfg_rsp(p_ccb, p_cfg); p_ccb->config_done |= IB_CFG_DONE; if (p_ccb->config_done & OB_CFG_DONE) { - /* Verify two sides are in compatible modes before continuing */ - if (p_ccb->our_cfg.fcr.mode != p_ccb->peer_cfg.fcr.mode) - { - l2cu_send_peer_disc_req (p_ccb); - L2CAP_TRACE_WARNING1 ("L2CAP - Calling Disconnect_Ind_Cb(Incompatible CFG), CID: 0x%04x No Conf Needed", p_ccb->local_cid); - l2cu_release_ccb (p_ccb); - (*disconnect_ind)(local_cid, FALSE); - break; - } - - p_ccb->config_done |= RECONFIG_FLAG; p_ccb->chnl_state = CST_OPEN; - l2c_link_adjust_chnl_allocation (); - btu_stop_timer (&p_ccb->timer_entry); + btu_stop_timer(&p_ccb->timer_entry); + forward_peer_data(p_ccb, 0); } - l2cu_send_peer_config_rsp (p_ccb, p_cfg); + l2cu_send_peer_config_rsp(p_ccb, p_cfg); - /* If using eRTM and waiting for an ACK, restart the ACK timer */ - if (p_ccb->fcrb.wait_ack) - l2c_fcr_start_timer(p_ccb); - -#if (L2CAP_ERTM_STATS == TRUE) - p_ccb->fcrb.connect_tick_count = GKI_get_os_tick_count(); -#endif - - /* See if we can forward anything on the hold queue */ - if ( (p_ccb->chnl_state == CST_OPEN) && (p_ccb->xmit_hold_q.count) ) - { - l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, NULL); - } break; - case L2CEVT_L2CA_CONFIG_RSP_NEG: /* Upper layer config reject */ - l2cu_send_peer_config_rsp (p_ccb, p_cfg); - btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, L2CAP_CHNL_CFG_TIMEOUT); + case L2CEVT_L2CA_CONFIG_RSP_NEG: + l2cu_send_peer_config_rsp(p_ccb, p_cfg); + btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, + L2CAP_CHNL_CFG_TOUT); break; - case L2CEVT_L2CA_DISCONNECT_REQ: /* Upper wants to disconnect */ - l2cu_send_peer_disc_req (p_ccb); + case L2CEVT_L2CA_DISCONNECT_REQ: + l2cu_send_peer_disc_req(p_ccb); p_ccb->chnl_state = CST_W4_L2CAP_DISCONNECT_RSP; - btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, L2CAP_CHNL_DISCONNECT_TOUT); + btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, + L2CAP_CHNL_DISCONNECT_TOUT); break; - case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */ - L2CAP_TRACE_API1 ("L2CAP - Calling DataInd_Cb(), CID: 0x%04x", p_ccb->local_cid); -#if (L2CAP_NUM_FIXED_CHNLS > 0) - if (p_ccb->local_cid < L2CAP_BASE_APPL_CID) - { - if (l2cb.fixed_reg[p_ccb->local_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb) - (*l2cb.fixed_reg[p_ccb->local_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb)(p_ccb->p_lcb->remote_bd_addr,(BT_HDR *)p_data); - else - GKI_freebuf (p_data); + case L2CEVT_L2CAP_DATA: + L2CAP_TRACE(API, "L2CAP - Calling DataInd_Cb(), CID: 0x%04x", + p_ccb->local_cid); - break; - } -#endif - (*p_ccb->p_rcb->api.pL2CA_DataInd_Cb)(p_ccb->local_cid, (BT_HDR *)p_data); + (*p_ccb->p_rcb->api.pL2CA_DataInd_Cb)(p_ccb->local_cid, p_data); break; - case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */ + case L2CEVT_L2CA_DATA_WRITE: if (p_ccb->config_done & OB_CFG_DONE) - l2c_enqueue_peer_data (p_ccb, (BT_HDR *)p_data); + GKI_enqueue(&p_ccb->xmit_hold_q, p_data); else - GKI_freebuf (p_data); + GKI_freebuf(p_data); + break; case L2CEVT_TIMEOUT: - l2cu_send_peer_disc_req (p_ccb); - L2CAP_TRACE_API1 ("L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed", p_ccb->local_cid); - l2cu_release_ccb (p_ccb); + l2cu_send_peer_disc_req(p_ccb); + L2CAP_TRACE( + API, + "L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed", + p_ccb->local_cid); + l2cu_release_ccb(p_ccb); (*disconnect_ind)(local_cid, FALSE); break; } } - -/******************************************************************************* -** -** Function l2c_csm_open -** -** Description This function handles events when the channel is in -** OPEN state. -** -** Returns void -** -*******************************************************************************/ -static void l2c_csm_open (tL2C_CCB *p_ccb, UINT16 event, void *p_data) +static void l2c_csm_open(tL2C_CCB *p_ccb, UINT16 event, void *p_data) { - UINT16 local_cid = p_ccb->local_cid; - tL2CAP_CFG_INFO *p_cfg; - tL2C_CHNL_STATE tempstate; - UINT8 tempcfgdone; - UINT8 cfg_result; - -#if (BT_TRACE_VERBOSE == TRUE) - L2CAP_TRACE_EVENT2 ("L2CAP - LCID: 0x%04x st: OPEN evt: %s", p_ccb->local_cid, l2c_csm_get_event_name (event)); -#else - L2CAP_TRACE_EVENT1 ("L2CAP - st: OPEN evt: %d", event); -#endif - -#if (L2CAP_UCD_INCLUDED == TRUE) - if ( local_cid == L2CAP_CONNECTIONLESS_CID ) - { - /* check if this event can be processed by UCD */ - if ( l2c_ucd_process_event (p_ccb, event, p_data) ) - { - /* The event is processed by UCD state machine */ - return; - } - } -#endif + tL2CA_DISCONNECT_IND_CB *disconnect_ind = + p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb; + UINT16 local_cid = p_ccb->local_cid; + tL2CAP_CFG_INFO *p_cfg; + tL2C_CHNL_STATE tempstate; + UINT8 tempcfgdone; + + L2CAP_TRACE(EVENT, "L2CAP - st: OPEN evt: %d", event); switch (event) { - case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */ - L2CAP_TRACE_API1 ("L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed", p_ccb->local_cid); - l2cu_release_ccb (p_ccb); - if (p_ccb->p_rcb) - (*p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb)(local_cid, FALSE); + case L2CEVT_LP_DISCONNECT_IND: + L2CAP_TRACE( + API, + "L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed", + p_ccb->local_cid); + + l2cu_release_ccb(p_ccb); + (*disconnect_ind)(local_cid, FALSE); break; - case L2CEVT_LP_QOS_VIOLATION_IND: /* QOS violation */ - /* Tell upper layer. If service guaranteed, then clear the channel */ + case L2CEVT_LP_QOS_VIOLATION_IND: if (p_ccb->p_rcb->api.pL2CA_QoSViolationInd_Cb) - (*p_ccb->p_rcb->api.pL2CA_QoSViolationInd_Cb)(p_ccb->p_lcb->remote_bd_addr); - break; + { + (*p_ccb->p_rcb->api.pL2CA_QoSViolationInd_Cb)( + p_ccb->p_lcb->remote_bd_addr); + } - case L2CEVT_L2CAP_CONFIG_REQ: /* Peer config request */ - p_cfg = (tL2CAP_CFG_INFO *)p_data; + break; + case L2CEVT_L2CAP_CONFIG_REQ: + p_cfg = p_data; tempstate = p_ccb->chnl_state; tempcfgdone = p_ccb->config_done; p_ccb->chnl_state = CST_CONFIG; - p_ccb->config_done &= ~CFG_DONE_MASK; + p_ccb->config_done = 0; - btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, L2CAP_CHNL_CFG_TIMEOUT); + btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, + L2CAP_CHNL_CFG_TOUT); - if ((cfg_result = l2cu_process_peer_cfg_req (p_ccb, p_cfg)) == L2CAP_PEER_CFG_OK) + if (l2cu_process_peer_cfg_req(p_ccb, p_cfg)) { (*p_ccb->p_rcb->api.pL2CA_ConfigInd_Cb)(p_ccb->local_cid, p_cfg); } - - /* Error in config parameters: reset state and config flag */ - else if (cfg_result == L2CAP_PEER_CFG_UNACCEPTABLE) + else { btu_stop_timer(&p_ccb->timer_entry); p_ccb->chnl_state = tempstate; p_ccb->config_done = tempcfgdone; - l2cu_send_peer_config_rsp (p_ccb, p_cfg); + l2cu_send_peer_config_rsp(p_ccb, p_cfg); } - else /* L2CAP_PEER_CFG_DISCONNECT */ - { - /* Disconnect if channels are incompatible - * Note this should not occur if reconfigure - * since this should have never passed original config. - */ - l2cu_disconnect_chnl (p_ccb); - } - break; - case L2CEVT_L2CAP_DISCONNECT_REQ: /* Peer disconnected request */ -// btla-specific ++ - /* Make sure we are not in sniff mode */ -#if BTM_PWR_MGR_INCLUDED == TRUE - { - tBTM_PM_PWR_MD settings; - settings.mode = BTM_PM_MD_ACTIVE; - BTM_SetPowerMode (BTM_PM_SET_ONLY_ID, p_ccb->p_lcb->remote_bd_addr, &settings); - } -#else - BTM_CancelSniffMode (p_ccb->p_lcb->remote_bd_addr); -#endif -// btla-specific -- + break; + case L2CEVT_L2CAP_DISCONNECT_REQ: p_ccb->chnl_state = CST_W4_L2CA_DISCONNECT_RSP; - btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, L2CAP_CHNL_DISCONNECT_TOUT); - L2CAP_TRACE_API1 ("L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x Conf Needed", p_ccb->local_cid); + btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, + L2CAP_CHNL_DISCONNECT_TOUT); + + L2CAP_TRACE( + API, + "L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x Conf Needed", + p_ccb->local_cid); (*p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb)(p_ccb->local_cid, TRUE); break; - case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */ - (*p_ccb->p_rcb->api.pL2CA_DataInd_Cb)(p_ccb->local_cid, (BT_HDR *)p_data); + case L2CEVT_L2CAP_DATA: + (*p_ccb->p_rcb->api.pL2CA_DataInd_Cb)(p_ccb->local_cid, + p_data); break; - case L2CEVT_L2CA_DISCONNECT_REQ: /* Upper wants to disconnect */ - /* Make sure we are not in sniff mode */ -#if BTM_PWR_MGR_INCLUDED == TRUE - { - tBTM_PM_PWR_MD settings; - settings.mode = BTM_PM_MD_ACTIVE; - BTM_SetPowerMode (BTM_PM_SET_ONLY_ID, p_ccb->p_lcb->remote_bd_addr, &settings); - } -#else - BTM_CancelSniffMode (p_ccb->p_lcb->remote_bd_addr); -#endif - - l2cu_send_peer_disc_req (p_ccb); + case L2CEVT_L2CA_DISCONNECT_REQ: + l2cu_send_peer_disc_req(p_ccb); p_ccb->chnl_state = CST_W4_L2CAP_DISCONNECT_RSP; - btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, L2CAP_CHNL_DISCONNECT_TOUT); + btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, + L2CAP_CHNL_DISCONNECT_TOUT); break; - case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */ - l2c_enqueue_peer_data (p_ccb, (BT_HDR *)p_data); - l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, NULL); + case L2CEVT_L2CA_DATA_WRITE: + ((BT_HDR *)p_data)->event = p_ccb->local_cid; + forward_peer_data(p_ccb, p_data); break; - case L2CEVT_L2CA_CONFIG_REQ: /* Upper layer config req */ - p_ccb->chnl_state = CST_CONFIG; - p_ccb->config_done &= ~CFG_DONE_MASK; - l2cu_process_our_cfg_req (p_ccb, (tL2CAP_CFG_INFO *)p_data); - l2cu_send_peer_config_req (p_ccb, (tL2CAP_CFG_INFO *)p_data); - btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, L2CAP_CHNL_CFG_TIMEOUT); - break; + case L2CEVT_L2CA_CONFIG_REQ: + l2cu_process_our_cfg_req(p_ccb, p_data); + l2cu_send_peer_config_req(p_ccb, p_data); - case L2CEVT_TIMEOUT: - /* Process the monitor/retransmission time-outs in flow control/retrans mode */ - if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) - l2c_fcr_proc_tout (p_ccb); - break; + p_ccb->chnl_state = CST_CONFIG; + p_ccb->config_done = 0; - case L2CEVT_ACK_TIMEOUT: - l2c_fcr_proc_ack_tout (p_ccb); + btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, + L2CAP_CHNL_CFG_TOUT); break; } } - -/******************************************************************************* -** -** Function l2c_csm_w4_l2cap_disconnect_rsp -** -** Description This function handles events when the channel is in -** CST_W4_L2CAP_DISCONNECT_RSP state. -** -** Returns void -** -*******************************************************************************/ -static void l2c_csm_w4_l2cap_disconnect_rsp (tL2C_CCB *p_ccb, UINT16 event, void *p_data) +static void l2c_csm_w4_l2cap_disconnect_rsp(tL2C_CCB *p_ccb, UINT16 event, + void *p_data) { - tL2CA_DISCONNECT_CFM_CB *disconnect_cfm = p_ccb->p_rcb->api.pL2CA_DisconnectCfm_Cb; - UINT16 local_cid = p_ccb->local_cid; + tL2CA_DISCONNECT_CFM_CB *disconnect_cfm = + p_ccb->p_rcb->api.pL2CA_DisconnectCfm_Cb; + tL2CA_DISCONNECT_IND_CB *disconnect_ind = + p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb; + UINT16 local_cid = p_ccb->local_cid; -#if (BT_TRACE_VERBOSE == TRUE) - L2CAP_TRACE_EVENT2 ("L2CAP - LCID: 0x%04x st: W4_L2CAP_DISC_RSP evt: %s", p_ccb->local_cid, l2c_csm_get_event_name (event)); -#else - L2CAP_TRACE_EVENT1 ("L2CAP - st: W4_L2CAP_DISC_RSP evt: %d", event); -#endif + L2CAP_TRACE(EVENT, "L2CAP - st: W4_L2CAP_DISC_RSP evt: %d", event); switch (event) { - case L2CEVT_L2CAP_DISCONNECT_RSP: /* Peer disconnect response */ - l2cu_release_ccb (p_ccb); + case L2CEVT_LP_DISCONNECT_IND: + L2CAP_TRACE( + API, + "L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed", + p_ccb->local_cid); + l2cu_release_ccb(p_ccb); + (*disconnect_ind)(local_cid, FALSE); + break; + + case L2CEVT_L2CAP_DISCONNECT_RSP: + l2cu_release_ccb(p_ccb); + if (disconnect_cfm) { - L2CAP_TRACE_API1 ("L2CAP - Calling DisconnectCfm_Cb(), CID: 0x%04x", local_cid); + L2CAP_TRACE(API, "L2CAP - Calling DisconnectCfm_Cb(), CID: 0x%04x", + local_cid); (*disconnect_cfm)(local_cid, L2CAP_DISC_OK); } + break; - case L2CEVT_L2CAP_DISCONNECT_REQ: /* Peer disconnect request */ - l2cu_send_peer_disc_rsp (p_ccb->p_lcb, p_ccb->remote_id, p_ccb->local_cid, p_ccb->remote_cid); - l2cu_release_ccb (p_ccb); + case L2CEVT_L2CAP_DISCONNECT_REQ: + l2cu_send_peer_disc_rsp(p_ccb->p_lcb, p_ccb->remote_id, + p_ccb->local_cid, p_ccb->remote_cid); + l2cu_release_ccb(p_ccb); + if (disconnect_cfm) { - L2CAP_TRACE_API1 ("L2CAP - Calling DisconnectCfm_Cb(), CID: 0x%04x", local_cid); + L2CAP_TRACE(API, "L2CAP - Calling DisconnectCfm_Cb(), CID: 0x%04x", + local_cid); (*disconnect_cfm)(local_cid, L2CAP_DISC_OK); } - break; - case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */ - case L2CEVT_TIMEOUT: /* Timeout */ - l2cu_release_ccb (p_ccb); + break; + + case L2CEVT_TIMEOUT: + l2cu_release_ccb(p_ccb); + if (disconnect_cfm) { - L2CAP_TRACE_API1 ("L2CAP - Calling DisconnectCfm_Cb(), CID: 0x%04x", local_cid); + L2CAP_TRACE(API, "L2CAP - Calling DisconnectCfm_Cb(), CID: 0x%04x", + local_cid); (*disconnect_cfm)(local_cid, L2CAP_DISC_TIMEOUT); } + break; - case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */ - case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */ - GKI_freebuf (p_data); + case L2CEVT_L2CAP_DATA: + case L2CEVT_L2CA_DATA_WRITE: + GKI_freebuf(p_data); break; } } - -/******************************************************************************* -** -** Function l2c_csm_w4_l2ca_disconnect_rsp -** -** Description This function handles events when the channel is in -** CST_W4_L2CA_DISCONNECT_RSP state. -** -** Returns void -** -*******************************************************************************/ -static void l2c_csm_w4_l2ca_disconnect_rsp (tL2C_CCB *p_ccb, UINT16 event, void *p_data) +static void l2c_csm_w4_l2ca_disconnect_rsp(tL2C_CCB *p_ccb, UINT16 event, + void *p_data) { - tL2CA_DISCONNECT_IND_CB *disconnect_ind = p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb; - UINT16 local_cid = p_ccb->local_cid; + tL2CA_DISCONNECT_IND_CB *disconnect_ind = + p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb; + UINT16 local_cid = p_ccb->local_cid; -#if (BT_TRACE_VERBOSE == TRUE) - L2CAP_TRACE_EVENT2 ("L2CAP - LCID: 0x%04x st: W4_L2CA_DISC_RSP evt: %s", p_ccb->local_cid, l2c_csm_get_event_name (event)); -#else - L2CAP_TRACE_EVENT1 ("L2CAP - st: W4_L2CA_DISC_RSP evt: %d", event); -#endif + L2CAP_TRACE(EVENT, "L2CAP - st: W4_L2CA_DISC_RSP evt: %d", event); switch (event) { - case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */ - L2CAP_TRACE_API1 ("L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed", p_ccb->local_cid); - l2cu_release_ccb (p_ccb); + case L2CEVT_LP_DISCONNECT_IND: + L2CAP_TRACE( + API, + "L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed", + p_ccb->local_cid); + l2cu_release_ccb(p_ccb); (*disconnect_ind)(local_cid, FALSE); break; case L2CEVT_TIMEOUT: - l2cu_send_peer_disc_rsp (p_ccb->p_lcb, p_ccb->remote_id, p_ccb->local_cid, p_ccb->remote_cid); - L2CAP_TRACE_API1 ("L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed", p_ccb->local_cid); - l2cu_release_ccb (p_ccb); + l2cu_send_peer_disc_rsp(p_ccb->p_lcb, p_ccb->remote_id, + p_ccb->local_cid, p_ccb->remote_cid); + L2CAP_TRACE( + API, + "L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed", + p_ccb->local_cid); + l2cu_release_ccb(p_ccb); (*disconnect_ind)(local_cid, FALSE); break; - case L2CEVT_L2CA_DISCONNECT_REQ: /* Upper disconnect request */ - case L2CEVT_L2CA_DISCONNECT_RSP: /* Upper disconnect response */ - l2cu_send_peer_disc_rsp (p_ccb->p_lcb, p_ccb->remote_id, p_ccb->local_cid, p_ccb->remote_cid); - l2cu_release_ccb (p_ccb); + case L2CEVT_L2CA_DISCONNECT_RSP: + l2cu_send_peer_disc_rsp(p_ccb->p_lcb, p_ccb->remote_id, + p_ccb->local_cid, p_ccb->remote_cid); + l2cu_release_ccb(p_ccb); break; - case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */ - case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */ - GKI_freebuf (p_data); + case L2CEVT_L2CAP_DATA: + case L2CEVT_L2CA_DATA_WRITE: + GKI_freebuf(p_data); break; } } - -#if (BT_TRACE_VERBOSE == TRUE) -/******************************************************************************* -** -** Function l2c_csm_get_event_name -** -** Description This function returns the event name. -** -** NOTE conditionally compiled to save memory. -** -** Returns pointer to the name -** -*******************************************************************************/ -static char *l2c_csm_get_event_name (UINT16 event) +void forward_peer_data(tL2C_CCB *p_ccb, BT_HDR *p_buf) { - switch (event) - { - case L2CEVT_LP_CONNECT_CFM: /* Lower layer connect confirm */ - return ("LOWER_LAYER_CONNECT_CFM"); - case L2CEVT_LP_CONNECT_CFM_NEG: /* Lower layer connect confirm (failed) */ - return ("LOWER_LAYER_CONNECT_CFM_NEG"); - case L2CEVT_LP_CONNECT_IND: /* Lower layer connect indication */ - return ("LOWER_LAYER_CONNECT_IND"); - case L2CEVT_LP_DISCONNECT_IND: /* Lower layer disconnect indication */ - return ("LOWER_LAYER_DISCONNECT_IND"); - case L2CEVT_LP_QOS_CFM: /* Lower layer QOS confirmation */ - return ("LOWER_LAYER_QOS_CFM"); - case L2CEVT_LP_QOS_CFM_NEG: /* Lower layer QOS confirmation (failed)*/ - return ("LOWER_LAYER_QOS_CFM_NEG"); - case L2CEVT_LP_QOS_VIOLATION_IND: /* Lower layer QOS violation indication */ - return ("LOWER_LAYER_QOS_VIOLATION_IND"); - - case L2CEVT_SEC_COMP: /* Security cleared successfully */ - return ("SECURITY_COMPLETE"); - case L2CEVT_SEC_COMP_NEG: /* Security procedure failed */ - return ("SECURITY_COMPLETE_NEG"); - - case L2CEVT_L2CAP_CONNECT_REQ: /* Peer connection request */ - return ("PEER_CONNECT_REQ"); - case L2CEVT_L2CAP_CONNECT_RSP: /* Peer connection response */ - return ("PEER_CONNECT_RSP"); - case L2CEVT_L2CAP_CONNECT_RSP_PND: /* Peer connection response pending */ - return ("PEER_CONNECT_RSP_PND"); - case L2CEVT_L2CAP_CONNECT_RSP_NEG: /* Peer connection response (failed) */ - return ("PEER_CONNECT_RSP_NEG"); - case L2CEVT_L2CAP_CONFIG_REQ: /* Peer configuration request */ - return ("PEER_CONFIG_REQ"); - case L2CEVT_L2CAP_CONFIG_RSP: /* Peer configuration response */ - return ("PEER_CONFIG_RSP"); - case L2CEVT_L2CAP_CONFIG_RSP_NEG: /* Peer configuration response (failed) */ - return ("PEER_CONFIG_RSP_NEG"); - case L2CEVT_L2CAP_DISCONNECT_REQ: /* Peer disconnect request */ - return ("PEER_DISCONNECT_REQ"); - case L2CEVT_L2CAP_DISCONNECT_RSP: /* Peer disconnect response */ - return ("PEER_DISCONNECT_RSP"); - case L2CEVT_L2CAP_DATA: /* Peer data */ - return ("PEER_DATA"); - - case L2CEVT_L2CA_CONNECT_REQ: /* Upper layer connect request */ - return ("UPPER_LAYER_CONNECT_REQ"); - case L2CEVT_L2CA_CONNECT_RSP: /* Upper layer connect response */ - return ("UPPER_LAYER_CONNECT_RSP"); - case L2CEVT_L2CA_CONNECT_RSP_NEG: /* Upper layer connect response (failed)*/ - return ("UPPER_LAYER_CONNECT_RSP_NEG"); - case L2CEVT_L2CA_CONFIG_REQ: /* Upper layer config request */ - return ("UPPER_LAYER_CONFIG_REQ"); - case L2CEVT_L2CA_CONFIG_RSP: /* Upper layer config response */ - return ("UPPER_LAYER_CONFIG_RSP"); - case L2CEVT_L2CA_CONFIG_RSP_NEG: /* Upper layer config response (failed) */ - return ("UPPER_LAYER_CONFIG_RSP_NEG"); - case L2CEVT_L2CA_DISCONNECT_REQ: /* Upper layer disconnect request */ - return ("UPPER_LAYER_DISCONNECT_REQ"); - case L2CEVT_L2CA_DISCONNECT_RSP: /* Upper layer disconnect response */ - return ("UPPER_LAYER_DISCONNECT_RSP"); - case L2CEVT_L2CA_DATA_READ: /* Upper layer data read */ - return ("UPPER_LAYER_DATA_READ"); - case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data write */ - return ("UPPER_LAYER_DATA_WRITE"); - case L2CEVT_TIMEOUT: /* Timeout */ - return ("TIMEOUT"); - case L2CEVT_SEC_RE_SEND_CMD: - return ("SEC_RE_SEND_CMD"); - case L2CEVT_L2CAP_INFO_RSP: /* Peer information response */ - return ("L2CEVT_L2CAP_INFO_RSP"); - case L2CEVT_ACK_TIMEOUT: - return ("L2CEVT_ACK_TIMEOUT"); + UINT8 *p; - default: - return ("???? UNKNOWN EVENT"); + if (p_buf && p_ccb->xmit_hold_q.count) + { + GKI_enqueue(&p_ccb->xmit_hold_q, p_buf); + p_buf = GKI_dequeue(&p_ccb->xmit_hold_q); } -} -#endif /* (BT_TRACE_VERBOSE == TRUE) */ - - -/******************************************************************************* -** -** Function l2c_enqueue_peer_data -** -** Description Enqueues data destined for the peer in the ccb. Handles -** FCR segmentation and checks for congestion. -** -** Returns void -** -*******************************************************************************/ -void l2c_enqueue_peer_data (tL2C_CCB *p_ccb, BT_HDR *p_buf) -{ - UINT8 *p; - - if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE) + else if (!p_buf) { - p_buf->event = 0; + p_buf = GKI_dequeue(&p_ccb->xmit_hold_q); } - else + + while (p_buf) { - /* Save the channel ID for faster counting */ - p_buf->event = p_ccb->local_cid; + if (p_buf->offset < 9) + { + L2CAP_TRACE(ERROR, "L2CAP - cannot send buffer, offset: %d\0", + p_buf->offset); - /* Step back to add the L2CAP header */ - p_buf->offset -= L2CAP_PKT_OVERHEAD; - p_buf->len += L2CAP_PKT_OVERHEAD; + GKI_freebuf(p_buf); - /* Set the pointer to the beginning of the data */ - p = (UINT8 *)(p_buf + 1) + p_buf->offset; + p_buf = GKI_dequeue(&p_ccb->xmit_hold_q); + } + else + { + p_buf->offset -= 8; + p_buf->len += 4; - /* Now the L2CAP header */ - UINT16_TO_STREAM (p, p_buf->len - L2CAP_PKT_OVERHEAD); - UINT16_TO_STREAM (p, p_ccb->remote_cid); - } + p = (UINT8 *)(p_buf + 1) + p_buf->offset; - GKI_enqueue (&p_ccb->xmit_hold_q, p_buf); + UINT16_TO_STREAM(p, 0x2000 | p_ccb->p_lcb->handle); - l2cu_check_channel_congestion (p_ccb); + if (p_buf->len > btu_cb.hcit_acl_data_size) + { + UINT16_TO_STREAM(p, btu_cb.hcit_acl_data_size); + } + else + { + UINT16_TO_STREAM(p, p_buf->len); + } -#if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) - /* if new packet is higher priority than serving ccb and it is not overrun */ - if (( p_ccb->p_lcb->rr_pri > p_ccb->ccb_priority ) - &&( p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].quota > 0)) - { - /* send out higher priority packet */ - p_ccb->p_lcb->rr_pri = p_ccb->ccb_priority; - } -#endif + UINT16_TO_STREAM(p, p_buf->len - 4); + UINT16_TO_STREAM(p, p_ccb->remote_cid); - /* if we are doing a round robin scheduling, set the flag */ - if (p_ccb->p_lcb->link_xmit_quota == 0) - l2cb.check_round_robin = TRUE; -} + p_buf->len += 4; + l2c_link_check_send_pkts(p_ccb->p_lcb, NULL, p_buf); + p_buf = GKI_dequeue(&p_ccb->xmit_hold_q); + } + } +} diff --git a/src/revolution/BTE/stack/l2cap/l2c_link.c b/src/revolution/BTE/stack/l2cap/l2c_link.c index 72e6f4b..73553ca 100644 --- a/src/revolution/BTE/stack/l2cap/l2c_link.c +++ b/src/revolution/BTE/stack/l2cap/l2c_link.c @@ -16,1708 +16,777 @@ * ******************************************************************************/ +/* Original source: + * bluedroid + * stack/l2cap/l2c_link.c + */ + +/* Includes changes by muff1n1634 and for this repository (KoopTheKoopa) */ + /****************************************************************************** * - * this file contains the functions relating to link management. A "link" - * is a connection between this device and another device. Only ACL links - * are managed. + * This file contains L2CAP link control functions. * ******************************************************************************/ -#include +#include "l2c_int.h" + +#include "misc.h" +#include #include -#include -#include "gki.h" +#include "bt_target.h" +#include "bt_trace.h" #include "bt_types.h" -#include "hcimsgs.h" -#include "l2cdefs.h" -#include "l2c_int.h" -#include "l2c_api.h" -#include "btu.h" +#include "data_types.h" + #include "btm_api.h" #include "btm_int.h" +#include "btu.h" +#include "gki.h" +#include "hcidefs.h" +#include "hcimsgs.h" +#include "l2c_api.h" +#include "l2cdefs.h" + +#define L2C_LINK_SEND_ACL_DATA(x) bte_hcisu_send((HC_BT_HDR *)(x), BT_EVT_TO_LM_HCI_ACL) -static BOOLEAN l2c_link_send_to_lower (tL2C_LCB *p_lcb, BT_HDR *p_buf); - -#define L2C_LINK_SEND_ACL_DATA(x) HCI_ACL_DATA_TO_LOWER((x)) - -#if (BLE_INCLUDED == TRUE) -#define L2C_LINK_SEND_BLE_ACL_DATA(x) HCI_BLE_ACL_DATA_TO_LOWER((x)) -#endif - -/******************************************************************************* -** -** Function l2c_link_hci_conn_req -** -** Description This function is called when an HCI Connection Request -** event is received. -** -** Returns TRUE, if accept conn -** -*******************************************************************************/ -BOOLEAN l2c_link_hci_conn_req (BD_ADDR bd_addr) +void l2c_link_hci_conn_req(BD_ADDR bd_addr) { - tL2C_LCB *p_lcb; - tL2C_LCB *p_lcb_cur; - int xx; - BOOLEAN no_links; + tL2C_LCB *p_lcb; + BT_HDR *p_msg; - /* See if we have a link control block for the remote device */ - p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr); + p_msg = GKI_getpoolbuf(2); + if (!p_msg) + return; - /* If we don't have one, create one and accept the connection. */ + p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr); if (!p_lcb) { -#ifdef REVOLUTION - p_lcb = l2cu_allocate_lcb (bd_addr); -#else - p_lcb = l2cu_allocate_lcb (bd_addr, FALSE); -#endif + p_lcb = l2cu_allocate_lcb(bd_addr); if (!p_lcb) { - btsnd_hcic_reject_conn (bd_addr, HCI_ERR_HOST_REJECT_RESOURCES); - L2CAP_TRACE_ERROR0 ("L2CAP failed to allocate LCB"); - return FALSE; - } - - no_links = TRUE; - - /* If we already have connection, accept as a master */ - for (xx = 0, p_lcb_cur = &l2cb.lcb_pool[0]; xx < MAX_L2CAP_LINKS; xx++, p_lcb_cur++) - { - if (p_lcb_cur == p_lcb) - continue; - - if (p_lcb_cur->in_use) - { - no_links = FALSE; - p_lcb->link_role = HCI_ROLE_MASTER; - break; - } + // TODO: #define HCI_ERR_HOST_REJECT_RESOURCES 13 + btsnd_hcic_reject_conn(p_msg, bd_addr, 0x14); + L2CAP_TRACE(ERROR, "L2CAP failed to allocate LCB"); + return; } - if (no_links) - { - if (!btm_dev_support_switch (bd_addr)) - p_lcb->link_role = HCI_ROLE_SLAVE; - else - p_lcb->link_role = l2cu_get_conn_role(p_lcb); - } + p_lcb->link_role = l2cu_get_conn_role(p_lcb); - /* Tell the other side we accept the connection */ - btsnd_hcic_accept_conn (bd_addr, p_lcb->link_role); + btsnd_hcic_accept_conn(p_msg, bd_addr, p_lcb->link_role); p_lcb->link_state = LST_CONNECTING; - /* Start a timer waiting for connect complete */ - btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, L2CAP_LINK_CONNECT_TOUT); - return (TRUE); + btu_start_timer(&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, + L2CAP_LINK_CONNECT_TOUT); + return; } - /* We already had a link control block to the guy. Check what state it is in */ - if ((p_lcb->link_state == LST_CONNECTING) || (p_lcb->link_state == LST_CONNECT_HOLDING)) + if (p_lcb->link_state == LST_CONNECTING + || p_lcb->link_state == LST_CONNECT_HOLDING) { - /* Connection collision. Accept the connection anyways. */ - - if (!btm_dev_support_switch (bd_addr)) - p_lcb->link_role = HCI_ROLE_SLAVE; - else - p_lcb->link_role = l2cu_get_conn_role(p_lcb); - - btsnd_hcic_accept_conn (bd_addr, p_lcb->link_role); + btsnd_hcic_accept_conn(p_msg, bd_addr, p_lcb->link_role); p_lcb->link_state = LST_CONNECTING; - return (TRUE); } else if (p_lcb->link_state == LST_DISCONNECTING) { - /* In disconnecting state, reject the connection. */ - btsnd_hcic_reject_conn (bd_addr, HCI_ERR_HOST_REJECT_DEVICE); + // TODO: #define HCI_ERR_HOST_REJECT_DEVICE 15 + btsnd_hcic_reject_conn(p_msg, bd_addr, 0x15); } else { - L2CAP_TRACE_ERROR0 ("L2CAP got conn_req while connected"); + L2CAP_TRACE(ERROR, "L2CAP got conn_req while connected"); + + GKI_freebuf(p_msg); } - return (FALSE); } -/******************************************************************************* -** -** Function l2c_link_hci_conn_comp -** -** Description This function is called when an HCI Connection Complete -** event is received. -** -** Returns void -** -*******************************************************************************/ -BOOLEAN l2c_link_hci_conn_comp (UINT8 status, UINT16 handle, BD_ADDR p_bda) +BOOLEAN l2c_link_hci_conn_comp(UINT8 status, UINT16 handle, BD_ADDR p_bda) { - tL2C_CONN_INFO ci; - tL2C_LCB *p_lcb; - tL2C_CCB *p_ccb; - tBTM_SEC_DEV_REC *p_dev_info = NULL; - -#if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE) - btm_acl_update_busy_level (BTM_BLI_PAGE_DONE_EVT); -#endif - - /* Save the parameters */ - ci.status = status; - memcpy (ci.bd_addr, p_bda, BD_ADDR_LEN); + tL2C_CONN_INFO ci; + tL2C_LCB *p_lcb; + tL2C_CCB *p_ccb; + tBTM_SEC_DEV_REC *p_dev_info = NULL; - /* See if we have a link control block for the remote device */ - p_lcb = l2cu_find_lcb_by_bd_addr (ci.bd_addr); + ci.status = status; + memcpy(ci.bd_addr, p_bda, BD_ADDR_LEN); - /* If we don't have one, this is an error */ + p_lcb = l2cu_find_lcb_by_bd_addr(ci.bd_addr); if (!p_lcb) { - L2CAP_TRACE_WARNING0 ("L2CAP got conn_comp for unknown BD_ADDR"); - return (FALSE); + if (!btm_sec_is_bonding(handle)) + L2CAP_TRACE(WARNING, "L2CAP got conn_comp for unknown BD_ADDR"); + + return FALSE; } if (p_lcb->link_state != LST_CONNECTING) { - L2CAP_TRACE_ERROR2 ("L2CAP got conn_comp in bad state: %d status: 0x%d", p_lcb->link_state, status); + L2CAP_TRACE(ERROR, "L2CAP got conn_comp in bad state: %d status: 0x%d", + p_lcb->link_state, status); if (status != HCI_SUCCESS) - l2c_link_hci_disc_comp (p_lcb->handle, status); + l2c_link_hci_disc_comp(p_lcb->handle, status); - return (FALSE); + return FALSE; } - /* Save the handle */ p_lcb->handle = handle; if (ci.status == HCI_SUCCESS) { - /* Connected OK. Change state to connected */ p_lcb->link_state = LST_CONNECTED; - /* Get the peer information if the l2cap flow-control/rtrans is supported */ - l2cu_send_peer_info_req (p_lcb, L2CAP_EXTENDED_FEATURES_INFO_TYPE); - - /* Tell BTM Acl management about the link */ - if ((p_dev_info = btm_find_dev (p_bda)) != NULL) - btm_acl_created (ci.bd_addr, p_dev_info->dev_class, - p_dev_info->sec_bd_name, handle, - p_lcb->link_role, FALSE); + if ((p_dev_info = btm_find_dev(p_bda)) != NULL) + { + ((void (*)(BD_ADDR, DEV_CLASS, BD_NAME, UINT16, UINT8))btm_acl_created)( + ci.bd_addr, p_dev_info->dev_class, + p_dev_info->sec_bd_name, handle, p_lcb->link_role); + } else - btm_acl_created (ci.bd_addr, NULL, NULL, handle, p_lcb->link_role, FALSE); - - /* If dedicated bonding do not process any further */ - if (p_lcb->is_bonding) { - if (l2cu_start_post_bond_timer(handle)) - return (TRUE); + ((void (*)(BD_ADDR, DEV_CLASS, BD_NAME, UINT16, UINT8))btm_acl_created)( + ci.bd_addr, NULL, NULL, handle, p_lcb->link_role); } - /* Update the timeouts in the hold queue */ l2c_process_held_packets(FALSE); - btu_stop_timer (&p_lcb->timer_entry); + btu_stop_timer(&p_lcb->timer_entry); - /* For all channels, send the event through their FSMs */ - for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) - { - l2c_csm_execute (p_ccb, L2CEVT_LP_CONNECT_CFM, &ci); - } + for (p_ccb = p_lcb->p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) + l2c_csm_execute(p_ccb, L2CEVT_LP_CONNECT_CFM, &ci); if (p_lcb->p_echo_rsp_cb) { - l2cu_send_peer_echo_req (p_lcb, NULL, 0); - btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, L2CAP_ECHO_RSP_TOUT); + l2cu_send_peer_echo_req(p_lcb, NULL, 0); + btu_start_timer(&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, + L2CAP_ECHO_RSP_TOUT); } - else if (!p_lcb->ccb_queue.p_first_ccb) + else if (!p_lcb->p_first_ccb) { - btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, L2CAP_LINK_STARTUP_TOUT); + btu_start_timer(&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, + L2CAP_LINK_STARTUP_TOUT); } } - /* Max number of acl connections. */ - /* If there's an lcb disconnecting set this one to holding */ - else if ((ci.status == HCI_ERR_MAX_NUM_OF_CONNECTIONS) && l2cu_lcb_disconnecting()) + else if (ci.status == HCI_ERR_MAX_NUM_OF_CONNECTIONS + && l2cu_lcb_disconnecting()) { p_lcb->link_state = LST_CONNECT_HOLDING; p_lcb->handle = HCI_INVALID_HANDLE; } else { - /* Just in case app decides to try again in the callback context */ - p_lcb->link_state = LST_DISCONNECTING; - - /* Connection failed. For all channels, send the event through */ - /* their FSMs. The CCBs should remove themselves from the LCB */ - for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; ) + for (p_ccb = p_lcb->p_first_ccb; p_ccb;) { tL2C_CCB *pn = p_ccb->p_next_ccb; - l2c_csm_execute (p_ccb, L2CEVT_LP_CONNECT_CFM_NEG, &ci); + l2c_csm_execute(p_ccb, L2CEVT_LP_CONNECT_CFM_NEG, &ci); p_ccb = pn; } - p_lcb->disc_reason = status; - /* Release the LCB */ - if (p_lcb->ccb_queue.p_first_ccb == NULL) - l2cu_release_lcb (p_lcb); - else /* there are any CCBs remaining */ - { - if (ci.status == HCI_ERR_CONNECTION_EXISTS) - { - /* we are in collision situation, wait for connecttion request from controller */ - p_lcb->link_state = LST_CONNECTING; - } - else - { - l2cu_create_conn(p_lcb); - } - } + l2cu_release_lcb(p_lcb); } - return (TRUE); -} + return TRUE; +} -/******************************************************************************* -** -** Function l2c_link_sec_comp -** -** Description This function is called when required security procedures -** are completed. -** -** Returns void -** -*******************************************************************************/ -void l2c_link_sec_comp (BD_ADDR p_bda, void *p_ref_data, UINT8 status) +void l2c_link_sec_comp(BD_ADDR p_bda, void *p_ref_data, UINT8 status) { - tL2C_CONN_INFO ci; - tL2C_LCB *p_lcb; - tL2C_CCB *p_ccb; - tL2C_CCB *p_next_ccb; - UINT8 event; - - L2CAP_TRACE_DEBUG2 ("l2c_link_sec_comp: %d, 0x%x", status, p_ref_data); - - if (status == BTM_SUCCESS_NO_SECURITY) - status = BTM_SUCCESS; - - /* Save the parameters */ - ci.status = status; - memcpy (ci.bd_addr, p_bda, BD_ADDR_LEN); + tL2C_CONN_INFO ci; + tL2C_LCB *p_lcb; + tL2C_CCB *p_ccb; + tL2C_CCB *p_next_ccb; + UINT8 event; - p_lcb = l2cu_find_lcb_by_bd_addr (p_bda); + ci.status = status; + memcpy(ci.bd_addr, p_bda, BD_ADDR_LEN); - /* If we don't have one, this is an error */ + p_lcb = l2cu_find_lcb_by_bd_addr(p_bda); if (!p_lcb) { - L2CAP_TRACE_WARNING0 ("L2CAP got sec_comp for unknown BD_ADDR"); + L2CAP_TRACE(WARNING, "L2CAP got sec_comp for unknown BD_ADDR"); return; } - /* Match p_ccb with p_ref_data returned by sec manager */ - for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_next_ccb) + for (p_ccb = p_lcb->p_first_ccb; p_ccb; p_ccb = p_next_ccb) { p_next_ccb = p_ccb->p_next_ccb; - if (p_ccb == p_ref_data) - { - switch(status) - { - case BTM_SUCCESS: - L2CAP_TRACE_DEBUG1 ("ccb timer ticks: %u", p_ccb->timer_entry.ticks); - event = L2CEVT_SEC_COMP; - break; - - case BTM_DELAY_CHECK: - /* start a timer - encryption change not received before L2CAP connect req */ - btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, L2CAP_DELAY_CHECK_SM4); - return; + event = status == BTM_SUCCESS ? L2CEVT_SEC_COMP : L2CEVT_SEC_COMP_NEG; - default: - event = L2CEVT_SEC_COMP_NEG; - } - l2c_csm_execute (p_ccb, event, &ci); - break; - } + l2c_csm_execute(p_ccb, event, &ci); } } - -/******************************************************************************* -** -** Function l2c_link_hci_disc_comp -** -** Description This function is called when an HCI Disconnect Complete -** event is received. -** -** Returns TRUE if the link is known about, else FALSE -** -*******************************************************************************/ -BOOLEAN l2c_link_hci_disc_comp (UINT16 handle, UINT8 reason) +BOOLEAN l2c_link_hci_disc_comp(UINT16 handle, UINT8 reason) { - tL2C_LCB *p_lcb; - tL2C_CCB *p_ccb; - BOOLEAN status = TRUE; - BOOLEAN lcb_is_free = TRUE; + tL2C_LCB *p_lcb; + tL2C_CCB *p_ccb; + BOOLEAN status = TRUE; - /* See if we have a link control block for the connection */ - p_lcb = l2cu_find_lcb_by_handle (handle); + p_lcb = l2cu_find_lcb_by_handle(handle); - /* If we don't have one, maybe an SCO link. Send to MM */ if (!p_lcb) { status = FALSE; } else { - /* There can be a case when we rejected PIN code authentication */ - /* otherwise save a new reason */ if (btm_cb.acl_disc_reason != HCI_ERR_HOST_REJECT_SECURITY) btm_cb.acl_disc_reason = reason; - p_lcb->disc_reason = btm_cb.acl_disc_reason; - - /* Just in case app decides to try again in the callback context */ - p_lcb->link_state = LST_DISCONNECTING; - - /* Link is disconnected. For all channels, send the event through */ - /* their FSMs. The CCBs should remove themselves from the LCB */ - for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; ) + for (p_ccb = p_lcb->p_first_ccb; p_ccb;) { tL2C_CCB *pn = p_ccb->p_next_ccb; - /* Keep connect pending control block (if exists) - * Possible Race condition when a reconnect occurs - * on the channel during a disconnect of link. This - * ccb will be automatically retried after link disconnect - * arrives - */ - if (p_ccb != p_lcb->p_pending_ccb) - { - l2c_csm_execute (p_ccb, L2CEVT_LP_DISCONNECT_IND, &reason); - } - p_ccb = pn; - } - -#if BTM_SCO_INCLUDED == TRUE - /* Tell SCO management to drop any SCOs on this ACL */ - btm_sco_acl_removed (p_lcb->remote_bd_addr); -#endif + l2c_csm_execute(p_ccb, L2CEVT_LP_DISCONNECT_IND, &reason); - /* If waiting for disconnect and reconnect is pending start the reconnect now - race condition where layer above issued connect request on link that was - disconnecting - */ - if (p_lcb->ccb_queue.p_first_ccb != NULL) - { -#if (L2CAP_NUM_FIXED_CHNLS > 0) - /* If we are going to re-use the LCB without dropping it, release all fixed channels here */ - int xx; - - for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) - { - if (p_lcb->p_fixed_ccbs[xx]) - { - (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason); - l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]); - - p_lcb->p_fixed_ccbs[xx] = NULL; - } - } -#endif - L2CAP_TRACE_DEBUG0("l2c_link_hci_disc_comp: Restarting pending ACL request"); - - if (l2cu_create_conn(p_lcb)) - lcb_is_free = FALSE; /* still using this lcb */ + p_ccb = pn; } - p_lcb->p_pending_ccb = NULL; - - /* Release the LCB */ - if (lcb_is_free) - l2cu_release_lcb (p_lcb); + btm_sco_acl_removed(p_lcb->remote_bd_addr); + l2cu_release_lcb(p_lcb); } - /* Now that we have a free acl connection, see if any lcbs are pending */ - if (lcb_is_free && ((p_lcb = l2cu_find_lcb_by_state(LST_CONNECT_HOLDING)) != NULL)) - { - /* we found one-- create a connection */ + if ((p_lcb = l2cu_find_lcb_by_state(LST_CONNECT_HOLDING)) != NULL) l2cu_create_conn(p_lcb); - } return status; } - -/******************************************************************************* -** -** Function l2c_link_hci_qos_violation -** -** Description This function is called when an HCI QOS Violation -** event is received. -** -** Returns TRUE if the link is known about, else FALSE -** -*******************************************************************************/ -BOOLEAN l2c_link_hci_qos_violation (UINT16 handle) +BOOLEAN l2c_link_hci_qos_violation(UINT16 handle) { - tL2C_LCB *p_lcb; - tL2C_CCB *p_ccb; - - /* See if we have a link control block for the connection */ - p_lcb = l2cu_find_lcb_by_handle (handle); + tL2C_LCB *p_lcb; + tL2C_CCB *p_ccb; - /* If we don't have one, maybe an SCO link. */ + p_lcb = l2cu_find_lcb_by_handle(handle); if (!p_lcb) - return (FALSE); + return FALSE; - /* For all channels, tell the upper layer about it */ - for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) + for (p_ccb = p_lcb->p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) { if (p_ccb->p_rcb->api.pL2CA_QoSViolationInd_Cb) - l2c_csm_execute (p_ccb, L2CEVT_LP_QOS_VIOLATION_IND, NULL); + l2c_csm_execute(p_ccb, L2CEVT_LP_QOS_VIOLATION_IND, NULL); } - return (TRUE); + return TRUE; } - - -/******************************************************************************* -** -** Function l2c_link_timeout -** -** Description This function is called when a link timer expires -** -** Returns void -** -*******************************************************************************/ -void l2c_link_timeout (tL2C_LCB *p_lcb) +void l2c_link_timeout(tL2C_LCB *p_lcb) { - tL2C_CCB *p_ccb; - UINT16 timeout; + tL2C_CCB *p_ccb; + UINT16 timeout; tBTM_STATUS rc; - L2CAP_TRACE_EVENT3 ("L2CAP - l2c_link_timeout() link state %d first CCB %p is_bonding:%d", - p_lcb->link_state, p_lcb->ccb_queue.p_first_ccb, p_lcb->is_bonding); - - /* If link was connecting or disconnecting, clear all channels and drop the LCB */ - if ((p_lcb->link_state == LST_CONNECTING_WAIT_SWITCH) || - (p_lcb->link_state == LST_CONNECTING) || - (p_lcb->link_state == LST_CONNECT_HOLDING) || - (p_lcb->link_state == LST_DISCONNECTING)) + if (p_lcb->link_state == LST_CONNECTING_WAIT_SWITCH + || p_lcb->link_state == LST_CONNECTING + || p_lcb->link_state == LST_CONNECT_HOLDING + || p_lcb->link_state == LST_DISCONNECTING) { - p_lcb->p_pending_ccb = NULL; - - /* For all channels, send a disconnect indication event through */ - /* their FSMs. The CCBs should remove themselves from the LCB */ - for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; ) + for (p_ccb = p_lcb->p_first_ccb; p_ccb;) { tL2C_CCB *pn = p_ccb->p_next_ccb; - l2c_csm_execute (p_ccb, L2CEVT_LP_DISCONNECT_IND, NULL); + l2c_csm_execute(p_ccb, L2CEVT_LP_DISCONNECT_IND, NULL); p_ccb = pn; } -#if (BLE_INCLUDED == TRUE) - if (p_lcb->link_state == LST_CONNECTING && - l2cb.is_ble_connecting == TRUE) - { - L2CA_CancelBleConnectReq(l2cb.ble_connecting_bda); - } -#endif - /* Release the LCB */ - l2cu_release_lcb (p_lcb); + + l2cu_release_lcb(p_lcb); } - /* If link is connected, check for inactivity timeout */ if (p_lcb->link_state == LST_CONNECTED) { - /* Check for ping outstanding */ if (p_lcb->p_echo_rsp_cb) { tL2CA_ECHO_RSP_CB *p_cb = p_lcb->p_echo_rsp_cb; - /* Zero out the callback in case app immediately calls us again */ p_lcb->p_echo_rsp_cb = NULL; - (*p_cb) (L2CAP_PING_RESULT_NO_RESP); + (*p_cb)(L2CAP_PING_RESULT_NO_RESP); - L2CAP_TRACE_WARNING0 ("L2CAP - ping timeout"); + L2CAP_TRACE(WARNING, "L2CAP - ping timeout"); - /* For all channels, send a disconnect indication event through */ - /* their FSMs. The CCBs should remove themselves from the LCB */ - for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; ) + for (p_ccb = p_lcb->p_first_ccb; p_ccb;) { tL2C_CCB *pn = p_ccb->p_next_ccb; - l2c_csm_execute (p_ccb, L2CEVT_LP_DISCONNECT_IND, NULL); + l2c_csm_execute(p_ccb, L2CEVT_LP_DISCONNECT_IND, NULL); p_ccb = pn; } } - /* If no channels in use, drop the link. */ - if (!p_lcb->ccb_queue.p_first_ccb) + if (!p_lcb->p_first_ccb) { - rc = btm_sec_disconnect (p_lcb->handle, HCI_ERR_PEER_USER); + rc = btm_sec_disconnect(p_lcb->handle, HCI_ERR_PEER_USER); - if (rc == BTM_CMD_STORED) - { - /* Security Manager will take care of disconnecting, state will be updated at that time */ - timeout = 0xFFFF; - } - else if (rc == BTM_CMD_STARTED) + if (rc == BTM_CMD_STARTED) { p_lcb->link_state = LST_DISCONNECTING; timeout = L2CAP_LINK_DISCONNECT_TOUT; } else if (rc == BTM_SUCCESS) { - /* BTM SEC will make sure that link is release (probably after pairing is done) */ p_lcb->link_state = LST_DISCONNECTING; - timeout = 0xFFFF; - } - else if (rc == BTM_BUSY) - { - /* BTM is still executing security process. Let lcb stay as connected */ - timeout = 0xFFFF; - } - else if ((p_lcb->is_bonding) - && (btsnd_hcic_disconnect (p_lcb->handle, HCI_ERR_PEER_USER))) - { - p_lcb->link_state = LST_DISCONNECTING; - timeout = L2CAP_LINK_DISCONNECT_TOUT; + timeout = 0xffff; } else { - /* probably no buffer to send disconnect */ - timeout = BT_1SEC_TIMEOUT; + timeout = 1; } - if (timeout != 0xFFFF) + if (timeout != 0xffff) { - btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, timeout); + btu_start_timer(&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, + timeout); } } else { - /* Check in case we were flow controlled */ - l2c_link_check_send_pkts (p_lcb, NULL, NULL); + l2c_link_check_send_pkts(p_lcb, NULL, NULL); } } } -/******************************************************************************* -** -** Function l2c_info_timeout -** -** Description This function is called when an info request times out -** -** Returns void -** -*******************************************************************************/ -void l2c_info_timeout (tL2C_LCB *p_lcb) +BOOLEAN l2c_link_send_to_lower(tL2C_LCB *p_lcb, BT_HDR *p_buf) { - tL2C_CCB *p_ccb; - tL2C_CONN_INFO ci; + UINT16 num_segs; - /* If we timed out waiting for info response, just continue using basic if allowed */ - if (p_lcb->w4_info_rsp) + if (p_buf->len <= btu_cb.hcit_acl_pkt_size) { - /* If waiting for security complete, restart the info response timer */ - for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) - { - if ( (p_ccb->chnl_state == CST_ORIG_W4_SEC_COMP) || (p_ccb->chnl_state == CST_TERM_W4_SEC_COMP) ) - { - btu_start_timer (&p_lcb->info_timer_entry, BTU_TTYPE_L2CAP_INFO, L2CAP_WAIT_INFO_RSP_TOUT); - return; - } - } - - p_lcb->w4_info_rsp = FALSE; - - /* If link is in process of being brought up */ - if ((p_lcb->link_state != LST_DISCONNECTED) && - (p_lcb->link_state != LST_DISCONNECTING)) - { - /* Notify active channels that peer info is finished */ - if (p_lcb->ccb_queue.p_first_ccb) - { - ci.status = HCI_SUCCESS; - memcpy (ci.bd_addr, p_lcb->remote_bd_addr, sizeof(BD_ADDR)); + --p_lcb->link_xmit_window; + ++p_lcb->sent_not_acked; + --l2cb.controller_xmit_window; - for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) - { - l2c_csm_execute (p_ccb, L2CEVT_L2CAP_INFO_RSP, &ci); - } - } - } + L2C_LINK_SEND_ACL_DATA(p_buf); } -} - -/******************************************************************************* -** -** Function l2c_link_adjust_allocation -** -** Description This function is called when a link is created or removed -** to calculate the amount of packets each link may send to -** the HCI without an ack coming back. -** -** Currently, this is a simple allocation, dividing the -** number of Controller Packets by the number of links. In -** the future, QOS configuration should be examined. -** -** Returns void -** -*******************************************************************************/ -void l2c_link_adjust_allocation (void) -{ - UINT16 qq, yy, qq_remainder; - tL2C_LCB *p_lcb; - UINT16 hi_quota, low_quota; - UINT16 num_lowpri_links = 0; - UINT16 num_hipri_links = 0; - UINT16 controller_xmit_quota = l2cb.num_lm_acl_bufs; - UINT16 high_pri_link_quota = L2CAP_HIGH_PRI_MIN_XMIT_QUOTA_A; - - /* If no links active, nothing to do. */ - if (l2cb.num_links_active == 0) + else { - l2cb.controller_xmit_window = l2cb.num_lm_acl_bufs; - l2cb.round_robin_quota = l2cb.round_robin_unacked = 0; - return; - } + num_segs = (p_buf->len - HCI_DATA_PREAMBLE_SIZE + + btu_cb.hcit_acl_data_size - 1) + / btu_cb.hcit_acl_data_size; - /* First, count the links */ - for (yy = 0, p_lcb = &l2cb.lcb_pool[0]; yy < MAX_L2CAP_LINKS; yy++, p_lcb++) - { - if (p_lcb->in_use) + if (num_segs > l2cb.controller_xmit_window) { - if (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH) - num_hipri_links++; - else - num_lowpri_links++; + num_segs = l2cb.controller_xmit_window; + p_buf->layer_specific = num_segs; + p_lcb->partial_segment_being_sent = TRUE; } - } - - /* now adjust high priority link quota */ - low_quota = num_lowpri_links ? 1 : 0; - while ( (num_hipri_links * high_pri_link_quota + low_quota) > controller_xmit_quota ) - high_pri_link_quota--; - - /* Work out the xmit quota and buffer quota high and low priorities */ - hi_quota = num_hipri_links * high_pri_link_quota; - low_quota = (hi_quota < controller_xmit_quota) ? controller_xmit_quota - hi_quota : 1; - - /* Work out and save the HCI xmit quota for each low priority link */ - /* If each low priority link cannot have at least one buffer */ - if (num_lowpri_links > low_quota) - { - l2cb.round_robin_quota = low_quota; - qq = qq_remainder = 0; - } - /* If each low priority link can have at least one buffer */ - else if (num_lowpri_links > 0) - { - l2cb.round_robin_quota = 0; - l2cb.round_robin_unacked = 0; - qq = low_quota / num_lowpri_links; - qq_remainder = low_quota % num_lowpri_links; - } - /* If no low priority link */ - else - { - l2cb.round_robin_quota = 0; - l2cb.round_robin_unacked = 0; - qq = qq_remainder = 0; - } - - L2CAP_TRACE_EVENT5 ("l2c_link_adjust_allocation num_hipri: %u num_lowpri: %u low_quota: %u round_robin_quota: %u qq: %u", - num_hipri_links, num_lowpri_links, low_quota, - l2cb.round_robin_quota, qq); - - /* Now, assign the quotas to each link */ - for (yy = 0, p_lcb = &l2cb.lcb_pool[0]; yy < MAX_L2CAP_LINKS; yy++, p_lcb++) - { - if (p_lcb->in_use) + if (num_segs > p_lcb->link_xmit_window) { - if (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH) - { - p_lcb->link_xmit_quota = high_pri_link_quota; - } - else - { - /* Safety check in case we switched to round-robin with something outstanding */ - /* if sent_not_acked is added into round_robin_unacked then don't add it again */ - /* l2cap keeps updating sent_not_acked for exiting from round robin */ - if (( p_lcb->link_xmit_quota > 0 )&&( qq == 0 )) - l2cb.round_robin_unacked += p_lcb->sent_not_acked; - - p_lcb->link_xmit_quota = qq; - if (qq_remainder > 0) - { - p_lcb->link_xmit_quota++; - qq_remainder--; - } - } - -#if L2CAP_HOST_FLOW_CTRL - p_lcb->link_ack_thresh = L2CAP_HOST_FC_ACL_BUFS / l2cb.num_links_active; -#endif - L2CAP_TRACE_EVENT3 ("l2c_link_adjust_allocation LCB %d Priority: %d XmitQuota: %d", - yy, p_lcb->acl_priority, p_lcb->link_xmit_quota); - - L2CAP_TRACE_EVENT2 (" SentNotAcked: %d RRUnacked: %d", - p_lcb->sent_not_acked, l2cb.round_robin_unacked); - - /* There is a special case where we have readjusted the link quotas and */ - /* this link may have sent anything but some other link sent packets so */ - /* so we may need a timer to kick off this link's transmissions. */ - if ( (p_lcb->link_state == LST_CONNECTED) - && (p_lcb->link_xmit_data_q.count) - && (p_lcb->sent_not_acked < p_lcb->link_xmit_quota) ) - btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, L2CAP_LINK_FLOW_CONTROL_TOUT); + num_segs = p_lcb->link_xmit_window; + p_buf->layer_specific = num_segs; + p_lcb->partial_segment_being_sent = TRUE; } + + l2cb.controller_xmit_window -= num_segs; + p_lcb->link_xmit_window -= num_segs; + p_lcb->sent_not_acked += num_segs; + + L2C_LINK_SEND_ACL_DATA(p_buf); } + return TRUE; } -/******************************************************************************* -** -** Function l2c_link_adjust_chnl_allocation -** -** Description This function is called to calculate the amount of packets each -** non-F&EC channel may have outstanding. -** -** Currently, this is a simple allocation, dividing the number -** of packets allocated to the link by the number of channels. In -** the future, QOS configuration should be examined. -** -** Returns void -** -*******************************************************************************/ -void l2c_link_adjust_chnl_allocation (void) +void l2c_link_check_send_pkts(tL2C_LCB *p_lcb, + tL2C_CCB *p_ccb, + BT_HDR *p_buf) { - tL2C_CCB *p_ccb; - UINT8 xx; - - UINT16 weighted_chnls[GKI_NUM_TOTAL_BUF_POOLS]; - UINT16 quota_per_weighted_chnls[GKI_NUM_TOTAL_BUF_POOLS]; - UINT16 reserved_buff[GKI_NUM_TOTAL_BUF_POOLS]; + tBTM_PM_MODE mode; + tBTM_PM_PWR_MD pm; - L2CAP_TRACE_DEBUG0 ("l2c_link_adjust_chnl_allocation"); - - /* initialize variables */ - for (xx = 0; xx < GKI_NUM_TOTAL_BUF_POOLS; xx++ ) - { - weighted_chnls[xx] = 0; - reserved_buff[xx] = 0; - } - - /* add up all of tx and rx data rate requirement */ - /* channel required higher data rate will get more buffer quota */ - for (xx = 0; xx < MAX_L2CAP_CHANNELS; xx++) + if (p_buf) { - p_ccb = l2cb.ccb_pool + xx; - - if (!p_ccb->in_use) - continue; - - if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE) + if (p_lcb->link_xmit_data_q.count >= p_lcb->link_cong_start + && !p_lcb->cong_sent) { - weighted_chnls[p_ccb->ertm_info.user_tx_pool_id] += p_ccb->tx_data_rate; - weighted_chnls[p_ccb->ertm_info.user_rx_pool_id] += p_ccb->rx_data_rate; - - if (p_ccb->ertm_info.fcr_tx_pool_id == HCI_ACL_POOL_ID) - { - /* reserve buffers only for wait_for_ack_q to maximize throughput */ - /* retrans_q will work based on buffer status */ - reserved_buff[HCI_ACL_POOL_ID] += p_ccb->peer_cfg.fcr.tx_win_sz; - } - - if (p_ccb->ertm_info.fcr_rx_pool_id == HCI_ACL_POOL_ID) + for (p_ccb = p_lcb->p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) { - /* reserve buffers for srej_rcv_hold_q */ - reserved_buff[HCI_ACL_POOL_ID] += p_ccb->peer_cfg.fcr.tx_win_sz; - } - } - else - { - /* low data rate is 1, medium is 2, high is 3 and no traffic is 0 */ - weighted_chnls[HCI_ACL_POOL_ID] += p_ccb->tx_data_rate + p_ccb->rx_data_rate; - } - } + L2CAP_TRACE(WARNING, + "L2CAP - Congested(), CID: 0x%04x, Congested", + p_ccb->local_cid); + if (p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb) + { + L2CAP_TRACE(API, + "L2CAP - Calling CongestionStatus_Cb(), CID: " + "0x%04x, Congested", + p_ccb->local_cid); - /* get unit quota per pool */ - for (xx = 0; xx < GKI_NUM_TOTAL_BUF_POOLS; xx++ ) - { - if ( weighted_chnls[xx] > 0 ) - { - if (GKI_poolcount(xx) > reserved_buff[xx]) - quota_per_weighted_chnls[xx] = ((GKI_poolcount(xx) - reserved_buff[xx])/weighted_chnls[xx]) + 1; - else - quota_per_weighted_chnls[xx] = 1; + (*p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)( + p_ccb->local_cid, TRUE); + } + } - L2CAP_TRACE_DEBUG5 ("POOL ID:%d, GKI_poolcount = %d, reserved_buff = %d, weighted_chnls = %d, quota_per_weighted_chnls = %d", - xx, GKI_poolcount(xx), reserved_buff[xx], weighted_chnls[xx], quota_per_weighted_chnls[xx] ); + p_lcb->cong_sent = TRUE; } - else - quota_per_weighted_chnls[xx] = 0; - } - - - /* assign buffer quota to each channel based on its data rate requirement */ - for (xx = 0; xx < MAX_L2CAP_CHANNELS; xx++) - { - p_ccb = l2cb.ccb_pool + xx; - - if (!p_ccb->in_use) - continue; - if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE) + if (p_lcb->link_xmit_data_q.count <= p_lcb->link_cong_discard) { - p_ccb->buff_quota = quota_per_weighted_chnls[p_ccb->ertm_info.user_tx_pool_id] * p_ccb->tx_data_rate; - - L2CAP_TRACE_EVENT6 ("CID:0x%04x FCR Mode:%u UserTxPool:%u Priority:%u TxDataRate:%u Quota:%u", - p_ccb->local_cid, p_ccb->peer_cfg.fcr.mode, p_ccb->ertm_info.user_tx_pool_id, - p_ccb->ccb_priority, p_ccb->tx_data_rate, p_ccb->buff_quota); - + p_buf->layer_specific = 0; + GKI_enqueue(&p_lcb->link_xmit_data_q, p_buf); } else { - p_ccb->buff_quota = quota_per_weighted_chnls[HCI_ACL_POOL_ID] * p_ccb->tx_data_rate; - - L2CAP_TRACE_EVENT4 ("CID:0x%04x Priority:%u TxDataRate:%u Quota:%u", - p_ccb->local_cid, - p_ccb->ccb_priority, p_ccb->tx_data_rate, p_ccb->buff_quota); + GKI_freebuf(p_buf); + L2CAP_TRACE(WARNING, "!!! L2CAP - buffer dropped"); } - - /* quota may be change so check congestion */ - l2cu_check_channel_congestion (p_ccb); } -} - -/******************************************************************************* -** -** Function l2c_link_processs_num_bufs -** -** Description This function is called when a "controller buffer size" -** event is first received from the controller. It updates -** the L2CAP values. -** -** Returns void -** -*******************************************************************************/ -void l2c_link_processs_num_bufs (UINT16 num_lm_acl_bufs) -{ - l2cb.num_lm_acl_bufs = l2cb.controller_xmit_window = num_lm_acl_bufs; - -} - -/******************************************************************************* -** -** Function l2c_link_pkts_rcvd -** -** Description This function is called from the HCI transport when it is time -** tto send a "Host ready for packets" command. This is only when -** host to controller flow control is used. If fills in the arrays -** of numbers of packets and handles. -** -** Returns count of number of entries filled in -** -*******************************************************************************/ -UINT8 l2c_link_pkts_rcvd (UINT16 *num_pkts, UINT16 *handles) -{ - UINT8 num_found = 0; - -#if (L2CAP_HOST_FLOW_CTRL == TRUE) - int xx; - tL2C_LCB *p_lcb = &l2cb.lcb_pool[0]; + if (p_lcb->partial_segment_being_sent) + return; - for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) + if (BTM_ReadPowerMode(p_lcb->remote_bd_addr, &mode) == BTM_SUCCESS + && mode == BTM_ACL_MODE_PARK && p_lcb->link_xmit_data_q.count != 0) { - if ((p_lcb->in_use) && (p_lcb->link_pkts_unacked)) - { - num_pkts[num_found] = p_lcb->link_pkts_unacked; - handles[num_found] = p_lcb->handle; - p_lcb->link_pkts_unacked = 0; - num_found++; - } + pm.mode = BTM_ACL_MODE_NORMAL; + BTM_SetPowerMode(0x80, p_lcb->remote_bd_addr, &pm); + btu_start_timer(&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, 1); + return; } -#endif - - return (num_found); -} - -/******************************************************************************* -** -** Function l2c_link_role_changed -** -** Description This function is called whan a link's master/slave role change -** event is received. It simply updates the link control block. -** -** Returns void -** -*******************************************************************************/ -void l2c_link_role_changed (BD_ADDR bd_addr, UINT8 new_role, UINT8 hci_status) -{ - tL2C_LCB *p_lcb; - int xx; - - /* Make sure not called from HCI Command Status (bd_addr and new_role are invalid) */ - if (bd_addr) + while (l2cb.controller_xmit_window && p_lcb->link_xmit_window) { - /* If here came form hci role change event */ - p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr); - if (p_lcb) - { - p_lcb->link_role = new_role; - - /* Reset high priority link if needed */ - if (hci_status == HCI_SUCCESS) - l2cu_set_acl_priority(bd_addr, p_lcb->acl_priority, TRUE); - } - } + if (!p_lcb->link_xmit_data_q.p_first) + break; - /* Check if any LCB was waiting for switch to be completed */ - for (xx = 0, p_lcb = &l2cb.lcb_pool[0]; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) - { - if ((p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTING_WAIT_SWITCH)) - { - l2cu_create_conn_after_switch (p_lcb); - } - } -} + if (((BT_HDR *)p_lcb->link_xmit_data_q.p_first)->layer_specific) + break; -/******************************************************************************* -** -** Function l2c_pin_code_request -** -** Description This function is called whan a pin-code request is received -** on a connection. If there are no channels active yet on the -** link, it extends the link first connection timer. Make sure -** that inactivity timer is not extended if PIN code happens -** to be after last ccb released. -** -** Returns void -** -*******************************************************************************/ -void l2c_pin_code_request (BD_ADDR bd_addr) -{ - tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr); + if (p_lcb->partial_segment_being_sent) + return; - if ( (p_lcb) && (!p_lcb->ccb_queue.p_first_ccb) ) - { - btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, L2CAP_LINK_CONNECT_TOUT_EXT); - } -} + p_buf = GKI_dequeue(&p_lcb->link_xmit_data_q); + if (!p_buf) + break; -#if ((BTM_PWR_MGR_INCLUDED == TRUE) && L2CAP_WAKE_PARKED_LINK == TRUE) -/******************************************************************************* -** -** Function l2c_link_check_power_mode -** -** Description This function is called to check power mode. -** -** Returns TRUE if link is going to be active from park -** FALSE if nothing to send or not in park mode -** -*******************************************************************************/ -BOOLEAN l2c_link_check_power_mode (tL2C_LCB *p_lcb) -{ - tBTM_PM_MODE mode; - tBTM_PM_PWR_MD pm; - tL2C_CCB *p_ccb; - BOOLEAN need_to_active = FALSE; - - /* - * We only switch park to active only if we have unsent packets - */ - if ( p_lcb->link_xmit_data_q.count == 0 ) - { - for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) - { - if (p_ccb->xmit_hold_q.count != 0) - { - need_to_active = TRUE; - break; - } - } + if (!l2c_link_send_to_lower(p_lcb, p_buf)) + break; } - else - need_to_active = TRUE; - /* if we have packets to send */ - if ( need_to_active ) - { - /* check power mode */ - if (BTM_ReadPowerMode(p_lcb->remote_bd_addr, &mode) == BTM_SUCCESS) - { - /* - if ( mode == BTM_PM_MD_PARK ) - { - L2CAP_TRACE_DEBUG1 ("LCB(0x%x) is in park mode", p_lcb->handle); -// Coverity: -// FALSE-POSITIVE error from Coverity test tool. Please do NOT remove following comment. -// coverity[uninit_use_in_call] False-positive: setting the mode to BTM_PM_MD_ACTIVE only uses settings.mode - the other data members of tBTM_PM_PWR_MD are ignored - - memset((void*)&pm, 0, sizeof(pm)); - pm.mode = BTM_PM_MD_ACTIVE; - BTM_SetPowerMode(BTM_PM_SET_ONLY_ID, p_lcb->remote_bd_addr, &pm); - btu_start_timer (&p_lcb->timer_entry, - BTU_TTYPE_L2CAP_LINK, L2CAP_WAIT_UNPARK_TOUT); - return TRUE; - } - */ - if ( mode == BTM_PM_STS_PENDING ) - { - L2CAP_TRACE_DEBUG1 ("LCB(0x%x) is in PM pending state", p_lcb->handle); - - btu_start_timer (&p_lcb->timer_entry, - BTU_TTYPE_L2CAP_LINK, L2CAP_WAIT_UNPARK_TOUT); - return TRUE; - } - } - } - return FALSE; -} -#endif /* ((BTM_PWR_MGR_INCLUDED == TRUE) && L2CAP_WAKE_PARKED_LINK == TRUE) */ - -/******************************************************************************* -** -** Function l2c_link_check_send_pkts -** -** Description This function is called to check if it can send packets -** to the Host Controller. It may be passed the address of -** a packet to send. -** -** Returns void -** -*******************************************************************************/ -void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_HDR *p_buf) -{ - int xx; - BOOLEAN single_write = FALSE; + if (p_lcb->partial_segment_being_sent) + return; - /* Save the channel ID for faster counting */ - if (p_buf) + if (p_lcb->link_xmit_data_q.count && p_lcb->link_xmit_window) { - if (p_ccb != NULL) - { - p_buf->event = p_ccb->local_cid; - single_write = TRUE; - } - else - p_buf->event = 0; - - p_buf->layer_specific = 0; - GKI_enqueue (&p_lcb->link_xmit_data_q, p_buf); - - if (p_lcb->link_xmit_quota == 0) - l2cb.check_round_robin = TRUE; + btu_start_timer(&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, + L2CAP_LINK_FLOW_CONTROL_TOUT); } - /* If this is called from uncongested callback context break recursive calling. - ** This LCB will be served when receiving number of completed packet event. - */ - if (l2cb.is_cong_cback_context) + if (!p_lcb->cong_sent) return; - /* If we are in a scenario where there are not enough buffers for each link to - ** have at least 1, then do a round-robin for all the LCBs - */ - if ( (p_lcb == NULL) || (p_lcb->link_xmit_quota == 0) ) - { - if (p_lcb == NULL) - p_lcb = l2cb.lcb_pool; - else if (!single_write) - p_lcb++; - - /* Loop through, starting at the next */ - for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) - { - /* If controller window is full, nothing to do */ - if ( (l2cb.controller_xmit_window == 0 -#if (BLE_INCLUDED == TRUE) - && !p_lcb->is_ble_link -#endif - ) -#if (BLE_INCLUDED == TRUE) - || (p_lcb->is_ble_link && l2cb.controller_le_xmit_window == 0 ) -#endif - || (l2cb.round_robin_unacked >= l2cb.round_robin_quota) ) - break; - - /* Check for wraparound */ - if (p_lcb == &l2cb.lcb_pool[MAX_L2CAP_LINKS]) - p_lcb = &l2cb.lcb_pool[0]; - - if ( (!p_lcb->in_use) - || (p_lcb->partial_segment_being_sent) - || (p_lcb->link_state != LST_CONNECTED) - || (p_lcb->link_xmit_quota != 0) - || (L2C_LINK_CHECK_POWER_MODE (p_lcb)) ) - continue; + if (p_lcb->link_xmit_data_q.count > p_lcb->link_cong_end) + return; - /* See if we can send anything from the Link Queue */ - if ((p_buf = (BT_HDR *)GKI_dequeue (&p_lcb->link_xmit_data_q)) != NULL) - { - l2c_link_send_to_lower (p_lcb, p_buf); - } - else if (single_write) - { - /* If only doing one write, break out */ - break; - } - /* If nothing on the link queue, check the channel queue */ - else if ((p_buf = l2cu_get_next_buffer_to_send (p_lcb)) != NULL) - { - l2c_link_send_to_lower (p_lcb, p_buf); - } - } + p_lcb->cong_sent = FALSE; - /* If we finished without using up our quota, no need for a safety check */ -#if (BLE_INCLUDED == TRUE) - if ( ((l2cb.controller_xmit_window > 0 && !p_lcb->is_ble_link) || - (l2cb.controller_le_xmit_window > 0 && p_lcb->is_ble_link)) - && (l2cb.round_robin_unacked < l2cb.round_robin_quota) ) -#else - if ( (l2cb.controller_xmit_window > 0) - && (l2cb.round_robin_unacked < l2cb.round_robin_quota) ) - -#endif - l2cb.check_round_robin = FALSE; - } - else /* if this is not round-robin service */ + for (p_ccb = p_lcb->p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) { - /* If a partial segment is being sent, can't send anything else */ - if ( (p_lcb->partial_segment_being_sent) - || (p_lcb->link_state != LST_CONNECTED) - || (L2C_LINK_CHECK_POWER_MODE (p_lcb)) ) - return; - - /* See if we can send anything from the link queue */ -#if (BLE_INCLUDED == TRUE) - while ( ((l2cb.controller_xmit_window != 0 && !p_lcb->is_ble_link) || - (l2cb.controller_le_xmit_window != 0 && p_lcb->is_ble_link)) - && (p_lcb->sent_not_acked < p_lcb->link_xmit_quota)) -#else - while ( (l2cb.controller_xmit_window != 0) - && (p_lcb->sent_not_acked < p_lcb->link_xmit_quota)) -#endif + if (p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb) { - if ((p_buf = (BT_HDR *)GKI_dequeue (&p_lcb->link_xmit_data_q)) == NULL) - break; + L2CAP_TRACE(API, + "L2CAP - Calling CongestionStatus_Cb(), CID: 0x%04x, " + "Uncongested", + p_ccb->local_cid); - if (!l2c_link_send_to_lower (p_lcb, p_buf)) - break; - } + (*p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)(p_ccb->local_cid, + FALSE); - if (!single_write) - { - /* See if we can send anything for any channel */ -#if (BLE_INCLUDED == TRUE) - while ( ((l2cb.controller_xmit_window != 0 && !p_lcb->is_ble_link) || - (l2cb.controller_le_xmit_window != 0 && p_lcb->is_ble_link)) - && (p_lcb->sent_not_acked < p_lcb->link_xmit_quota)) -#else - while ((l2cb.controller_xmit_window != 0) && (p_lcb->sent_not_acked < p_lcb->link_xmit_quota)) -#endif - { - if ((p_buf = l2cu_get_next_buffer_to_send (p_lcb)) == NULL) - break; - - if (!l2c_link_send_to_lower (p_lcb, p_buf)) - break; - } + if (p_lcb->cong_sent) + break; } - - /* There is a special case where we have readjusted the link quotas and */ - /* this link may have sent anything but some other link sent packets so */ - /* so we may need a timer to kick off this link's transmissions. */ - if ( (p_lcb->link_xmit_data_q.count) && (p_lcb->sent_not_acked < p_lcb->link_xmit_quota) ) - btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, L2CAP_LINK_FLOW_CONTROL_TOUT); } - } -/******************************************************************************* -** -** Function l2c_link_send_to_lower -** -** Description This function queues the buffer for HCI transmission -** -** Returns TRUE for success, FALSE for fail -** -*******************************************************************************/ -static BOOLEAN l2c_link_send_to_lower (tL2C_LCB *p_lcb, BT_HDR *p_buf) +void l2c_link_adjust_allocation(void) { - UINT16 num_segs; - UINT16 xmit_window, acl_data_size; - -#if (BLE_INCLUDED == TRUE) - if ((!p_lcb->is_ble_link && (p_buf->len <= btu_cb.hcit_acl_pkt_size)) || - (p_lcb->is_ble_link && (p_buf->len <= btu_cb.hcit_ble_acl_pkt_size))) -#else - if (p_buf->len <= btu_cb.hcit_acl_pkt_size) -#endif - { - if (p_lcb->link_xmit_quota == 0) - l2cb.round_robin_unacked++; + UINT16 qq; + UINT16 yy; + UINT16 cc; + tL2C_LCB *p_lcb; + int num_hi_pri_links = 0; - p_lcb->sent_not_acked++; - p_buf->layer_specific = 0; + if (l2cb.num_links_active == 0) + return; -#if (BLE_INCLUDED == TRUE) - if (p_lcb->is_ble_link) - { - l2cb.controller_le_xmit_window--; - L2C_LINK_SEND_BLE_ACL_DATA (p_buf); - } - else -#endif - { - l2cb.controller_xmit_window--; - L2C_LINK_SEND_ACL_DATA (p_buf); - } - } - else + /* explicitly post-increment */ + for (yy = 0, p_lcb = l2cb.lcb_pool; yy < MAX_L2CAP_LINKS; yy++, p_lcb++) { -#if BLE_INCLUDED == TRUE - if (p_lcb->is_ble_link) - { - acl_data_size = btu_cb.hcit_ble_acl_data_size; - xmit_window = l2cb.controller_le_xmit_window; + if (p_lcb->in_use && p_lcb->acl_priority == L2CAP_PRIORITY_HIGH) + ++num_hi_pri_links; + } - } - else -#endif - { - acl_data_size = btu_cb.hcit_acl_data_size; - xmit_window = l2cb.controller_xmit_window; - } - num_segs = (p_buf->len - HCI_DATA_PREAMBLE_SIZE + acl_data_size - 1) / acl_data_size; + qq = l2cb.num_lm_acl_bufs / l2cb.num_links_active + 1; + /* explicitly post-increment */ + for (yy = 0, p_lcb = l2cb.lcb_pool; yy < MAX_L2CAP_LINKS; yy++, p_lcb++) + { + if (!p_lcb->in_use) + continue; - /* If doing round-robin, then only 1 segment each time */ - if (p_lcb->link_xmit_quota == 0) + if (num_hi_pri_links == 0 || p_lcb->acl_priority == L2CAP_PRIORITY_HIGH) { - num_segs = 1; - p_lcb->partial_segment_being_sent = TRUE; + p_lcb->link_xmit_quota = qq; + p_lcb->link_xmit_window = qq; } else { - /* Multi-segment packet. Make sure it can fit */ - if (num_segs > xmit_window) - { - num_segs = xmit_window; - p_lcb->partial_segment_being_sent = TRUE; - } - - if (num_segs > (p_lcb->link_xmit_quota - p_lcb->sent_not_acked)) - { - num_segs = (p_lcb->link_xmit_quota - p_lcb->sent_not_acked); - p_lcb->partial_segment_being_sent = TRUE; - } - } - - p_buf->layer_specific = num_segs; -#if BLE_INCLUDED == TRUE - if (p_lcb->is_ble_link) - { - l2cb.controller_le_xmit_window -= num_segs; - + p_lcb->link_xmit_quota = 3; + p_lcb->link_xmit_window = 3; } - else -#endif - l2cb.controller_xmit_window -= num_segs; - if (p_lcb->link_xmit_quota == 0) - l2cb.round_robin_unacked += num_segs; + cc = p_lcb->link_xmit_quota * 120 / 100; + p_lcb->link_cong_start = cc; - p_lcb->sent_not_acked += num_segs; -#if BLE_INCLUDED == TRUE - if (p_lcb->is_ble_link) - { - L2C_LINK_SEND_BLE_ACL_DATA(p_buf); - } - else -#endif - { - L2C_LINK_SEND_ACL_DATA (p_buf); - } - } + p_lcb->link_cong_end = cc > 3 ? cc - 3 : 0; + p_lcb->link_cong_discard = cc + 2; -#if (L2CAP_HCI_FLOW_CONTROL_DEBUG == TRUE) -#if (BLE_INCLUDED == TRUE) - if (p_lcb->is_ble_link) - { - L2CAP_TRACE_DEBUG6 ("TotalWin=%d,Hndl=0x%x,Quota=%d,Unack=%d,RRQuota=%d,RRUnack=%d", - l2cb.controller_le_xmit_window, - p_lcb->handle, - p_lcb->link_xmit_quota, p_lcb->sent_not_acked, - l2cb.round_robin_quota, l2cb.round_robin_unacked); - } - else -#endif - { - L2CAP_TRACE_DEBUG6 ("TotalWin=%d,Hndl=0x%x,Quota=%d,Unack=%d,RRQuota=%d,RRUnack=%d", - l2cb.controller_xmit_window, - p_lcb->handle, - p_lcb->link_xmit_quota, p_lcb->sent_not_acked, - l2cb.round_robin_quota, l2cb.round_robin_unacked); + L2CAP_TRACE(DEBUG, + "LCB %d Priority:%d XmitWindow:%d Congestion Start:%d " + "End:%d Discard:%d", + yy, p_lcb->acl_priority, p_lcb->link_xmit_window, + p_lcb->link_cong_start, p_lcb->link_cong_end, + p_lcb->link_cong_discard); } -#endif - - return TRUE; } -/******************************************************************************* -** -** Function l2c_link_process_num_completed_pkts -** -** Description This function is called when a "number-of-completed-packets" -** event is received from the controller. It updates all the -** LCB transmit counts. -** -** Returns void -** -*******************************************************************************/ -void l2c_link_process_num_completed_pkts (UINT8 *p) +void l2c_link_process_num_completed_pkts(UINT8 *p) { - UINT8 num_handles, xx; - UINT16 handle; - UINT16 num_sent; - tL2C_LCB *p_lcb; + UINT8 num_handles; + UINT8 xx; + UINT16 handle; + UINT16 num_sent; + tL2C_LCB *p_lcb; - STREAM_TO_UINT8 (num_handles, p); + STREAM_TO_UINT8(num_handles, p); for (xx = 0; xx < num_handles; xx++) { - STREAM_TO_UINT16 (handle, p); - STREAM_TO_UINT16 (num_sent, p); + STREAM_TO_UINT16(handle, p); + STREAM_TO_UINT16(num_sent, p); - p_lcb = l2cu_find_lcb_by_handle (handle); - - /* Callback for number of completed packet event */ - /* Originally designed for [3DSG] */ - if((p_lcb != NULL) && (p_lcb->p_nocp_cb)) - { - L2CAP_TRACE_DEBUG0 ("L2CAP - calling NoCP callback"); - (*p_lcb->p_nocp_cb)(p_lcb->remote_bd_addr); - } - -#if (BLE_INCLUDED == TRUE) - if (p_lcb && p_lcb->is_ble_link) - l2cb.controller_le_xmit_window += num_sent; - else -#endif - { - - /* Maintain the total window to the controller */ - l2cb.controller_xmit_window += num_sent; - } + p_lcb = l2cu_find_lcb_by_handle(handle); if (p_lcb) { - /* If doing round-robin, adjust communal counts */ - if (p_lcb->link_xmit_quota == 0) - { - /* Don't go negative */ - if (l2cb.round_robin_unacked > num_sent) - l2cb.round_robin_unacked -= num_sent; - else - l2cb.round_robin_unacked = 0; - } + p_lcb->link_xmit_window += num_sent; + if (p_lcb->link_xmit_window > p_lcb->link_xmit_quota) + p_lcb->link_xmit_window = p_lcb->link_xmit_quota; - /* Don't go negative */ if (p_lcb->sent_not_acked > num_sent) p_lcb->sent_not_acked -= num_sent; else p_lcb->sent_not_acked = 0; - l2c_link_check_send_pkts (p_lcb, NULL, NULL); + l2cb.controller_xmit_window += num_sent; - /* If we were doing round-robin for low priority links, check 'em */ - if ( (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH) - && (l2cb.check_round_robin) - && (l2cb.round_robin_unacked < l2cb.round_robin_quota) ) - { - l2c_link_check_send_pkts (NULL, NULL, NULL); - } + l2c_link_check_send_pkts(p_lcb, NULL, NULL); } - -#if (L2CAP_HCI_FLOW_CONTROL_DEBUG == TRUE) - if (p_lcb) - { -#if (BLE_INCLUDED == TRUE) - if (p_lcb->is_ble_link) - { - L2CAP_TRACE_DEBUG5 ("TotalWin=%d,LinkUnack(0x%x)=%d,RRCheck=%d,RRUnack=%d", - l2cb.controller_le_xmit_window, - p_lcb->handle, p_lcb->sent_not_acked, - l2cb.check_round_robin, l2cb.round_robin_unacked); - } - else -#endif - { - L2CAP_TRACE_DEBUG5 ("TotalWin=%d,LinkUnack(0x%x)=%d,RRCheck=%d,RRUnack=%d", - l2cb.controller_xmit_window, - p_lcb->handle, p_lcb->sent_not_acked, - l2cb.check_round_robin, l2cb.round_robin_unacked); - - } - } - else - { -#if (BLE_INCLUDED == TRUE) - L2CAP_TRACE_DEBUG5 ("TotalWin=%d LE_Win: %d, Handle=0x%x, RRCheck=%d, RRUnack=%d", - l2cb.controller_xmit_window, - l2cb.controller_le_xmit_window, - handle, - l2cb.check_round_robin, l2cb.round_robin_unacked); -#else - L2CAP_TRACE_DEBUG4 ("TotalWin=%d Handle=0x%x RRCheck=%d RRUnack=%d", - l2cb.controller_xmit_window, - handle, - l2cb.check_round_robin, l2cb.round_robin_unacked); -#endif - } -#endif } - -#if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE) - /* only full stack can enable sleep mode */ - btu_check_bt_sleep (); -#endif } -/******************************************************************************* -** -** Function l2cap_link_chk_pkt_start -** -** Description This function is called from the HCI transport when the first -** 4 bytes of an HCI ACL packet have been received. It checks if the -** packet is the next segment of a fragmented L2CAP message. If it -** is, and the length is OK, it returns the address of the -** starting L2CAP message segment buffer. -** -** Returns the address of the receive buffer HCIT should use -** (CR419: Modified to return NULL in case of error.) -** -** NOTE This assumes that the L2CAP MTU size is less than the size -** of an HCI ACL buffer, so the maximum L2CAP message will fit -** into one buffer. -** -*******************************************************************************/ -BT_HDR *l2cap_link_chk_pkt_start (BT_HDR *p_cur_buf) +/* NOTE the misspelling of process */ +void l2c_link_processs_num_bufs(UINT16 num_lm_acl_bufs) { - UINT8 *p; - UINT16 handle; - UINT16 hci_len; - UINT16 pkt_type; - tL2C_LCB *p_lcb; - BT_HDR * p_return_buf; /* CR419: To avoid returning from too many places */ - + l2cb.num_lm_acl_bufs = num_lm_acl_bufs; + l2cb.controller_xmit_window = num_lm_acl_bufs; +} - if (p_cur_buf) - { - p = (UINT8 *)(p_cur_buf + 1) + p_cur_buf->offset; - } - else - { - return (NULL); - } +BT_HDR *l2cap_link_chk_pkt_start(BT_HDR *p_cur_buf) +{ + UINT8 *p = (UINT8 *)(p_cur_buf + 1) + p_cur_buf->offset; + UINT16 handle; + UINT16 hci_len; + UINT16 pkt_type; + tL2C_LCB *p_lcb; + BT_HDR *result; - /* L2CAP expects all rcvd packets to have a layer-specific value of 0 */ p_cur_buf->layer_specific = 0; - STREAM_TO_UINT16 (handle, p); - STREAM_TO_UINT16 (hci_len, p); + STREAM_TO_UINT16(handle, p); + STREAM_TO_UINT16(hci_len, p); - pkt_type = HCID_GET_EVENT (handle); - handle = HCID_GET_HANDLE (handle); + pkt_type = HCID_GET_EVENT(handle); + handle = HCID_GET_HANDLE(handle); l2cb.p_cur_hcit_lcb = NULL; - /* Find the link that is associated with this handle */ - p_lcb = l2cu_find_lcb_by_handle (handle); - - /* If no link for this handle, nothing to do. */ + p_lcb = l2cu_find_lcb_by_handle(handle); if (!p_lcb) - return (p_cur_buf) ; + return p_cur_buf; - if (pkt_type == L2CAP_PKT_START) /*** START PACKET ***/ + if (pkt_type == L2CAP_PKT_START) { - /* Start of packet. If we were in the middle of receiving */ - /* a packet, it is incomplete. Drop it. */ if (p_lcb->p_hcit_rcv_acl) { - L2CAP_TRACE_WARNING0 ("L2CAP - dropping incomplete pkt"); - GKI_freebuf (p_lcb->p_hcit_rcv_acl); - p_lcb->p_hcit_rcv_acl = NULL; + L2CAP_TRACE(WARNING, "L2CAP - dropping incomplete pkt"); + GKI_freebuf(p_lcb->p_hcit_rcv_acl); } - /* Save the active buffer address in the LCB */ - if ((p_return_buf = p_cur_buf) != NULL) - { - p_lcb->p_hcit_rcv_acl = p_return_buf; - l2cb.p_cur_hcit_lcb = p_lcb; - } + p_lcb->p_hcit_rcv_acl = p_cur_buf; + l2cb.p_cur_hcit_lcb = p_lcb; + result = p_cur_buf; } - else /*** CONTINUATION PACKET ***/ + else { - /* Packet continuation. Check if we were expecting it */ if (p_lcb->p_hcit_rcv_acl) { - UINT16 total_len; - BT_HDR *p_base_buf = p_lcb->p_hcit_rcv_acl; - UINT8 *p_f = (UINT8 *)(p_base_buf + 1) + p_base_buf->offset + 2; + UINT8 *p_f = (UINT8 *)(p_lcb->p_hcit_rcv_acl + 1) + + p_lcb->p_hcit_rcv_acl->offset + 2; + UINT16 total_len; - STREAM_TO_UINT16 (total_len, p_f); + STREAM_TO_UINT16(total_len, p_f); - /* We were expecting the CONTINUATION packet. If length fits, it can go in the */ - /* current buffer. */ - if ((total_len + hci_len) <= (L2CAP_MTU_SIZE + HCI_DATA_PREAMBLE_SIZE)) + if (total_len + hci_len <= L2CAP_MTU_SIZE + HCI_DATA_PREAMBLE_SIZE) { - /* GKI_freebuf (p_cur_buf); CR419:Do not free it yet */ - p_return_buf = p_lcb->p_hcit_rcv_acl; /* CR419: return base buffer */ + result = p_lcb->p_hcit_rcv_acl; l2cb.p_cur_hcit_lcb = p_lcb; - if ((p_cur_buf->len > HCI_DATA_PREAMBLE_SIZE)) + if (p_cur_buf->len > HCI_DATA_PREAMBLE_SIZE) { - UINT8 * p = (UINT8 *)(p_cur_buf + 1) - + p_cur_buf->offset - + HCI_DATA_PREAMBLE_SIZE; - UINT8 * p1 = (UINT8 *)(p_return_buf + 1) - + p_return_buf->offset - + p_return_buf->len; - - /* Copy data from new buffer into base buffer then update the data */ - /* count in the base buffer accordingly. */ - memcpy (p1, p, p_cur_buf->len - HCI_DATA_PREAMBLE_SIZE); - p_return_buf->len += (p_cur_buf->len - HCI_DATA_PREAMBLE_SIZE); + UINT8 *p = (UINT8 *)(p_cur_buf + 1) + p_cur_buf->offset + + HCI_DATA_PREAMBLE_SIZE; + UINT8 *p1 = + (UINT8 *)(result + 1) + result->offset + result->len; + + memcpy(p1, p, p_cur_buf->len - HCI_DATA_PREAMBLE_SIZE); + result->len += p_cur_buf->len - HCI_DATA_PREAMBLE_SIZE; } - GKI_freebuf (p_cur_buf); - p_cur_buf = NULL; + GKI_freebuf(p_cur_buf); - /* Update HCI header of first segment (base buffer) with new length */ total_len += hci_len; - p_f = (UINT8 *)(p_base_buf + 1) + p_base_buf->offset + 2; - UINT16_TO_STREAM (p_f, total_len); + p_f -= 2; + UINT16_TO_STREAM(p_f, total_len); } else { - /* Packet too long. Drop the base packet */ - L2CAP_TRACE_WARNING3 ("L2CAP - dropping too long pkt BufLen: %d total_len: %d hci_len: %d", - p_lcb->p_hcit_rcv_acl->len, total_len, hci_len); + L2CAP_TRACE(WARNING, "L2CAP - dropping too long pkt"); - GKI_freebuf (p_lcb->p_hcit_rcv_acl); + GKI_freebuf(p_lcb->p_hcit_rcv_acl); p_lcb->p_hcit_rcv_acl = NULL; - p_return_buf = NULL ; /* Can't hold onto it any more */ + result = NULL; } } - else /*** NEITHER START OR CONTINUATION PACKET ***/ + else { - p_return_buf = NULL ; + result = NULL; } } - if (p_return_buf == NULL) /* if error is indicated.. */ - { - if (p_cur_buf != NULL) /* ..drop input buffer */ - GKI_freebuf(p_cur_buf); /* (if present) */ - } + if (!result) + GKI_freebuf(p_cur_buf); - return (p_return_buf); + return result; } -/******************************************************************************* -** -** Function l2cap_link_chk_pkt_end -** -** Description This function is called from the HCI transport when the last -** byte of an HCI ACL packet has been received. It checks if the -** L2CAP message is complete, i.e. no more continuation packets -** are expected. -** -** Returns TRUE if message complete, FALSE if continuation expected -** -*******************************************************************************/ -BOOLEAN l2cap_link_chk_pkt_end (void) +BOOLEAN l2cap_link_chk_pkt_end(void) { - UINT8 *p; - BT_HDR *p_buf; - UINT16 l2cap_len; - tL2C_LCB *p_lcb; + UINT8 *p; + BT_HDR *p_buf; + UINT16 l2cap_len; + tL2C_LCB *p_lcb; - /* If link or buffer pointer not set up, let main line handle it */ - if (((p_lcb = l2cb.p_cur_hcit_lcb) == NULL) || ((p_buf = p_lcb->p_hcit_rcv_acl) == NULL)) - return (TRUE); + if (((p_lcb = l2cb.p_cur_hcit_lcb) == NULL) + || ((p_buf = p_lcb->p_hcit_rcv_acl) == NULL)) + { + return TRUE; + } - /* Point to the L2CAP length */ p = (UINT8 *)(p_buf + 1) + p_buf->offset + HCI_DATA_PREAMBLE_SIZE; - STREAM_TO_UINT16 (l2cap_len, p); + STREAM_TO_UINT16(l2cap_len, p); - /* If the L2CAP length has not been reached, tell HCIT not to send this buffer to BTU */ - if (l2cap_len > (p_buf->len - (HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD))) + if (l2cap_len > p_buf->len - (HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD)) { - return (FALSE); + return FALSE; } else { p_lcb->p_hcit_rcv_acl = NULL; - return (TRUE); + return TRUE; } } -/******************************************************************************* -** -** Function l2c_link_segments_xmitted -** -** Description This function is called from the HCI Interface when an ACL -** data packet segment is transmitted. -** -** Returns void -** -*******************************************************************************/ -void l2c_link_segments_xmitted (BT_HDR *p_msg) + +void l2c_link_role_changed(BD_ADDR bd_addr, UINT8 new_role) { - UINT8 *p = (UINT8 *)(p_msg + 1) + p_msg->offset; - UINT16 handle; - tL2C_LCB *p_lcb; + tL2C_LCB *p_lcb; + int xx; - /* Extract the handle */ - STREAM_TO_UINT16 (handle, p); - handle = HCID_GET_HANDLE (handle); + p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr); + if (p_lcb) + p_lcb->link_role = new_role; - /* Find the LCB based on the handle */ - if ((p_lcb = l2cu_find_lcb_by_handle (handle)) == NULL) + /* explicitly post-increment */ + for (xx = 0, p_lcb = l2cb.lcb_pool; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) { - L2CAP_TRACE_WARNING1 ("L2CAP - rcvd segment complete, unknown handle: %d", handle); - GKI_freebuf (p_msg); + if (p_lcb->in_use && p_lcb->link_state == LST_CONNECTING_WAIT_SWITCH) + l2cu_create_conn_after_switch(p_lcb); + } +} + +void l2c_link_role_change_failed(void) +{ + tL2C_LCB *p_lcb; + int xx; + + /* explicitly post-increment */ + for (xx = 0, p_lcb = l2cb.lcb_pool; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) + { + if (p_lcb->in_use && p_lcb->link_state == LST_CONNECTING_WAIT_SWITCH) + l2cu_create_conn_after_switch(p_lcb); + } +} + +void l2c_link_segments_xmitted(BT_HDR *p_msg) +{ + UINT8 *p = (UINT8 *)(p_msg + 1) + p_msg->offset; + UINT16 handle; + tL2C_LCB *p_lcb; + + STREAM_TO_UINT16(handle, p); + handle = HCID_GET_HANDLE(handle); + + if ((p_lcb = l2cu_find_lcb_by_handle(handle)) == NULL) + { + L2CAP_TRACE(WARNING, + "L2CAP - rcvd segment complete, unknown handle: %d\0\0\0\0\0\0", + handle); + GKI_freebuf(p_msg); return; } if (p_lcb->link_state == LST_CONNECTED) { - /* Enqueue the buffer to the head of the transmit queue, and see */ - /* if we can transmit anything more. */ - GKI_enqueue_head (&p_lcb->link_xmit_data_q, p_msg); + p_msg->layer_specific = 0; + GKI_enqueue_head(&p_lcb->link_xmit_data_q, p_msg); p_lcb->partial_segment_being_sent = FALSE; - l2c_link_check_send_pkts (p_lcb, NULL, NULL); + l2c_link_check_send_pkts(p_lcb, NULL, NULL); } else - GKI_freebuf (p_msg); + { + GKI_freebuf(p_msg); + } +} + +void l2c_pin_code_request(BD_ADDR bd_addr) +{ + tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr); + + if (p_lcb && !p_lcb->p_first_ccb) + { + btu_start_timer(&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, + L2CAP_LINK_CONNECT_TOUT_EXT); + } } diff --git a/src/revolution/BTE/stack/l2cap/l2c_main.c b/src/revolution/BTE/stack/l2cap/l2c_main.c index 3478cf2..8976261 100644 --- a/src/revolution/BTE/stack/l2cap/l2c_main.c +++ b/src/revolution/BTE/stack/l2cap/l2c_main.c @@ -1,3 +1,7 @@ +/* retail timer type 73 (unnamed in the 2012 headers) */ +#define BTU_TTYPE_73 73 + + /****************************************************************************** * * Copyright (C) 1999-2012 Broadcom Corporation @@ -16,414 +20,273 @@ * ******************************************************************************/ +/* Original source: + * bluedroid + * stack/l2cap/l2c_main.c + */ + +/* Includes changes by muff1n1634 and for this repository (KoopTheKoopa) */ + /****************************************************************************** * - * This file contains the main L2CAP entry points + * This file contains the L2CAP main functions. * ******************************************************************************/ -#include "bt_target.h" -#include +#include "l2c_int.h" + #include -#include +#include "bt_target.h" +#include "bt_trace.h" +#include "bt_types.h" +#include "data_types.h" + +#include "btm_int.h" +#include "btu.h" #include "gki.h" +#include "hcidefs.h" #include "hcimsgs.h" #include "l2cdefs.h" -#include "l2c_int.h" #include "l2c_api.h" -#include "btu.h" -#include "btm_int.h" -/********************************************************************************/ -/* L O C A L F U N C T I O N P R O T O T Y P E S */ -/********************************************************************************/ -static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len); +void process_l2cap_cmd(tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len); -/********************************************************************************/ -/* G L O B A L L 2 C A P D A T A */ -/********************************************************************************/ -#if L2C_DYNAMIC_MEMORY == FALSE tL2C_CB l2cb; -#endif - -/* Temporary - until l2cap implements group management */ -#if (TCS_BCST_SETUP_INCLUDED == TRUE && TCS_INCLUDED == TRUE) -extern void tcs_proc_bcst_msg( BD_ADDR addr, BT_HDR *p_msg ) ; - -/******************************************************************************* -** -** Function l2c_bcst_msg -** -** Description -** -** Returns void -** -*******************************************************************************/ -void l2c_bcst_msg( BT_HDR *p_buf, UINT16 psm ) -{ - UINT8 *p; - /* Ensure we have enough space in the buffer for the L2CAP and HCI headers */ - if (p_buf->offset < L2CAP_BCST_MIN_OFFSET) - { - L2CAP_TRACE_ERROR1 ("L2CAP - cannot send buffer, offset: %d", p_buf->offset); - GKI_freebuf (p_buf); - return; - } +void l2c_init(void) +{ + INT16 xx; - /* Step back some bytes to add the headers */ - p_buf->offset -= (HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_BCST_OVERHEAD); - p_buf->len += L2CAP_PKT_OVERHEAD + L2CAP_BCST_OVERHEAD; + memset(&l2cb, 0, sizeof l2cb); - /* Set the pointer to the beginning of the data */ - p = (UINT8 *)(p_buf + 1) + p_buf->offset; + for (xx = 0; xx < MAX_L2CAP_CHANNELS - 1; ++xx) + l2cb.ccb_pool[xx].p_next_ccb = &l2cb.ccb_pool[xx + 1]; - /* First, the HCI transport header */ - UINT16_TO_STREAM (p, 0x0050 | (L2CAP_PKT_START << 12) | (2 << 14)); + l2cb.p_free_ccb_first = &l2cb.ccb_pool[0]; + l2cb.p_free_ccb_last = &l2cb.ccb_pool[MAX_L2CAP_CHANNELS - 1]; + l2cb.desire_role = HCI_ROLE_MASTER; + l2cb.idle_timeout = L2CAP_LINK_INACTIVITY_TOUT; + l2cb.l2cap_trace_level = BT_TRACE_LEVEL_NONE; +} - /* The HCI transport will segment the buffers. */ - if (p_buf->len > btu_cb.hcit_acl_data_size) - { - UINT16_TO_STREAM (p, btu_cb.hcit_acl_data_size); - } - else +void l2c_rcv_acl_data(BT_HDR *p_msg) +{ + UINT8 *p = (UINT8 *)(p_msg + 1) + p_msg->offset; + UINT16 handle; + UINT16 hci_len; + UINT8 pkt_type; + tL2C_LCB *p_lcb; + tL2C_CCB *p_ccb = NULL; + UINT16 l2cap_len; + UINT16 rcv_cid; + UINT16 bcst_psm; + + STREAM_TO_UINT16(handle, p); + pkt_type = HCID_GET_EVENT(handle); + handle = HCID_GET_HANDLE(handle); + + if (pkt_type != L2CAP_PKT_START) { - UINT16_TO_STREAM (p, p_buf->len); + L2CAP_TRACE(WARNING, "L2CAP - expected pkt start, got: %d", + pkt_type); + GKI_freebuf(p_msg); + return; } - /* Now the L2CAP header */ - UINT16_TO_STREAM (p, p_buf->len - L2CAP_PKT_OVERHEAD); - UINT16_TO_STREAM (p, L2CAP_CONNECTIONLESS_CID); - UINT16_TO_STREAM (p, psm); - - p_buf->len += HCI_DATA_PREAMBLE_SIZE; - - if (p_buf->len <= btu_cb.hcit_acl_pkt_size) + if ((p_lcb = l2cu_find_lcb_by_handle(handle)) == NULL) { - HCI_ACL_DATA_TO_LOWER (p_buf); - } -} -#endif - -/******************************************************************************* -** -** Function l2c_rcv_acl_data -** -** Description This function is called from the HCI Interface when an ACL -** data packet is received. -** -** Returns void -** -*******************************************************************************/ -void l2c_rcv_acl_data (BT_HDR *p_msg) -{ - UINT8 *p = (UINT8 *)(p_msg + 1) + p_msg->offset; - UINT16 handle, hci_len; - UINT8 pkt_type; - tL2C_LCB *p_lcb; - tL2C_CCB *p_ccb = NULL; - UINT16 l2cap_len, rcv_cid, psm; - - /* Extract the handle */ - STREAM_TO_UINT16 (handle, p); - pkt_type = HCID_GET_EVENT (handle); - handle = HCID_GET_HANDLE (handle); - - /* Since the HCI Transport is putting segmented packets back together, we */ - /* should never get a valid packet with the type set to "continuation" */ - if (pkt_type != L2CAP_PKT_CONTINUE) - { - /* Find the LCB based on the handle */ - if ((p_lcb = l2cu_find_lcb_by_handle (handle)) == NULL) - { - UINT8 cmd_code; - - /* There is a slight possibility (specifically with USB) that we get an */ - /* L2CAP connection request before we get the HCI connection complete. */ - /* So for these types of messages, hold them for up to 2 seconds. */ - STREAM_TO_UINT16 (hci_len, p); - STREAM_TO_UINT16 (l2cap_len, p); - STREAM_TO_UINT16 (rcv_cid, p); - STREAM_TO_UINT8 (cmd_code, p); - - if ((p_msg->layer_specific == 0) && (rcv_cid == L2CAP_SIGNALLING_CID) - && (cmd_code == L2CAP_CMD_INFO_REQ || cmd_code == L2CAP_CMD_CONN_REQ)) - { - L2CAP_TRACE_WARNING5 ("L2CAP - holding ACL for unknown handle:%d ls:%d cid:%d opcode:%d cur count:%d", - handle, p_msg->layer_specific, rcv_cid, cmd_code, - l2cb.rcv_hold_q.count); - p_msg->layer_specific = 2; - GKI_enqueue (&l2cb.rcv_hold_q, p_msg); + UINT8 cmd_code; - if (l2cb.rcv_hold_q.count == 1) - btu_start_timer (&l2cb.rcv_hold_tle, BTU_TTYPE_L2CAP_HOLD, BT_1SEC_TIMEOUT); + STREAM_TO_UINT16(hci_len, p); + STREAM_TO_UINT16(l2cap_len, p); + STREAM_TO_UINT16(rcv_cid, p); + STREAM_TO_UINT8(cmd_code, p); - return; - } - else + if (p_msg->layer_specific == 0 + && rcv_cid == L2CAP_SIGNALLING_CID + && (cmd_code == L2CAP_CMD_INFO_REQ + || cmd_code == L2CAP_CMD_CONN_REQ) && !btm_sec_is_bonding(handle)) + { + L2CAP_TRACE( + WARNING, + "L2CAP - holding ACL for unknown handle:%d ls:%d cid:%d " + "opcode:%d cur count:%d", + handle, p_msg->layer_specific, rcv_cid, cmd_code, + l2cb.rcv_hold_q.count); + p_msg->layer_specific = 2; + GKI_enqueue(&l2cb.rcv_hold_q, p_msg); + + if (l2cb.rcv_hold_q.count == 1) { - L2CAP_TRACE_ERROR5 ("L2CAP - rcvd ACL for unknown handle:%d ls:%d cid:%d opcode:%d cur count:%d", - handle, p_msg->layer_specific, rcv_cid, cmd_code, l2cb.rcv_hold_q.count); + btu_start_timer(&l2cb.rcv_hold_tle, BTU_TTYPE_L2CAP_HOLD, + 1); } - GKI_freebuf (p_msg); + return; } - } - else - { - L2CAP_TRACE_WARNING1 ("L2CAP - expected pkt start or complete, got: %d", pkt_type); - GKI_freebuf (p_msg); + + GKI_freebuf(p_msg); return; } - /* Extract the length and update the buffer header */ - STREAM_TO_UINT16 (hci_len, p); + STREAM_TO_UINT16(hci_len, p); p_msg->offset += 4; -#if (L2CAP_HOST_FLOW_CTRL == TRUE) - /* Send ack if we hit the threshold */ - if (++p_lcb->link_pkts_unacked >= p_lcb->link_ack_thresh) - btu_hcif_send_host_rdy_for_data(); -#endif - - /* Extract the length and CID */ - STREAM_TO_UINT16 (l2cap_len, p); - STREAM_TO_UINT16 (rcv_cid, p); + STREAM_TO_UINT16(l2cap_len, p); + STREAM_TO_UINT16(rcv_cid, p); - /* Find the CCB for this CID */ - if (rcv_cid >= L2CAP_BASE_APPL_CID) + if (rcv_cid > 2) // TODO: L2CAP_CONNECTIONLESS_CID? { - if ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, rcv_cid)) == NULL) + if ((p_ccb = l2cu_find_ccb_by_cid(p_lcb, rcv_cid)) == NULL) { - L2CAP_TRACE_WARNING1 ("L2CAP - unknown CID: 0x%04x", rcv_cid); - GKI_freebuf (p_msg); + L2CAP_TRACE(WARNING, "L2CAP - unknown CID: %d", rcv_cid); + GKI_freebuf(p_msg); return; } } - if (hci_len >= L2CAP_PKT_OVERHEAD) /* Must receive at least the L2CAP length and CID.*/ + if (hci_len >= L2CAP_PKT_OVERHEAD) { - p_msg->len = hci_len - L2CAP_PKT_OVERHEAD; + p_msg->len = hci_len - L2CAP_PKT_OVERHEAD; p_msg->offset += L2CAP_PKT_OVERHEAD; } else { - L2CAP_TRACE_WARNING0 ("L2CAP - got incorrect hci header" ); - GKI_freebuf (p_msg); + L2CAP_TRACE(WARNING, "L2CAP - got incorrect hci header"); + GKI_freebuf(p_msg); return; } if (l2cap_len != p_msg->len) { - L2CAP_TRACE_WARNING2 ("L2CAP - bad length in pkt. Exp: %d Act: %d", - l2cap_len, p_msg->len); + L2CAP_TRACE(WARNING, "L2CAP - bad length in pkt. Exp: %d Act: %d", + l2cap_len, p_msg->len); - GKI_freebuf (p_msg); + GKI_freebuf(p_msg); return; } - /* Send the data through the channel state machine */ if (rcv_cid == L2CAP_SIGNALLING_CID) { - process_l2cap_cmd (p_lcb, p, l2cap_len); - GKI_freebuf (p_msg); + process_l2cap_cmd(p_lcb, p, l2cap_len); + GKI_freebuf(p_msg); } else if (rcv_cid == L2CAP_CONNECTIONLESS_CID) { - /* process_connectionless_data (p_lcb); */ - STREAM_TO_UINT16 (psm, p); - L2CAP_TRACE_DEBUG1( "GOT CONNECTIONLESS DATA PSM:%d", psm ) ; -#if (TCS_BCST_SETUP_INCLUDED == TRUE && TCS_INCLUDED == TRUE) - if (psm == TCS_PSM_INTERCOM || psm == TCS_PSM_CORDLESS) - { - p_msg->offset += L2CAP_BCST_OVERHEAD; - p_msg->len -= L2CAP_BCST_OVERHEAD; - tcs_proc_bcst_msg( p_lcb->remote_bd_addr, p_msg ) ; - GKI_freebuf (p_msg); - } - else -#endif + STREAM_TO_UINT16(bcst_psm, p); -#if (L2CAP_UCD_INCLUDED == TRUE) - /* if it is not broadcast, check UCD registration */ - if ( l2c_ucd_check_rx_pkts( p_lcb, p_msg ) ) - { - /* nothing to do */ - } - else -#endif - GKI_freebuf (p_msg); - } -#if (BLE_INCLUDED == TRUE) - else if (rcv_cid == L2CAP_BLE_SIGNALLING_CID) - { - l2cble_process_sig_cmd (p_lcb, p, l2cap_len); - GKI_freebuf (p_msg); - } -#endif -#if (L2CAP_NUM_FIXED_CHNLS > 0) - else if ((rcv_cid >= L2CAP_FIRST_FIXED_CHNL) && (rcv_cid <= L2CAP_LAST_FIXED_CHNL) && - (l2cb.fixed_reg[rcv_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb != NULL) ) - { - /* If no CCB for this channel, allocate one */ - if (l2cu_initialize_fixed_ccb (p_lcb, rcv_cid, &l2cb.fixed_reg[rcv_cid - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts)) - { - p_ccb = p_lcb->p_fixed_ccbs[rcv_cid - L2CAP_FIRST_FIXED_CHNL]; + p_msg->offset += 2; + p_msg->len -= 2; - if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE) - l2c_fcr_proc_pdu (p_ccb, p_msg); - else - (*l2cb.fixed_reg[rcv_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb)(p_lcb->remote_bd_addr, p_msg); - } - else - GKI_freebuf (p_msg); - } -#endif + L2CAP_TRACE(DEBUG, "GOT CONNECTIONLESS DATA PSM:%d", bcst_psm); + GKI_freebuf(p_msg); + } else { - if (p_ccb == NULL) - GKI_freebuf (p_msg); + if (!p_ccb) + GKI_freebuf(p_msg); else - { - /* Basic mode packets go straight to the state machine */ - if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_BASIC_MODE) - l2c_csm_execute (p_ccb, L2CEVT_L2CAP_DATA, p_msg); - else - { - /* eRTM or streaming mode, so we need to validate states first */ - if ((p_ccb->chnl_state == CST_OPEN) || (p_ccb->chnl_state == CST_CONFIG)) - l2c_fcr_proc_pdu (p_ccb, p_msg); - else - GKI_freebuf (p_msg); - } - } + l2c_csm_execute(p_ccb, 19, p_msg); } } -/******************************************************************************* -** -** Function process_l2cap_cmd -** -** Description This function is called when a packet is received on the -** L2CAP signalling CID -** -** Returns void -** -*******************************************************************************/ -static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len) +void process_l2cap_cmd(tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len) { - UINT8 *p_pkt_end, *p_next_cmd, *p_cfg_end, *p_cfg_start; - UINT8 cmd_code, cfg_code, cfg_len, id; - tL2C_CONN_INFO con_info; + UINT8 *p_pkt_end; + UINT8 *p_next_cmd; + UINT8 *p_cfg_end; + UINT8 *p_cfg_start; + UINT8 cmd_code; + UINT8 cfg_code; + UINT8 cfg_len; + UINT8 id; + tL2C_CONN_INFO con_info; tL2CAP_CFG_INFO cfg_info; - UINT16 rej_reason, rej_mtu, lcid, rcid, info_type; - tL2C_CCB *p_ccb; - tL2C_RCB *p_rcb; - BOOLEAN cfg_rej; - UINT16 cfg_rej_len, cmd_len; - UINT16 result; - tL2C_CONN_INFO ci; - -#if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE) - /* if l2cap command received in CID 1 on top of an LE link, ignore this command */ - if (p_lcb->is_ble_link) - return; -#endif - p_next_cmd = p; - p_pkt_end = p + pkt_len; + UINT16 rej_reason; + UINT16 rej_mtu; + UINT16 lcid; + UINT16 rcid; + UINT16 info_type; + tL2C_CCB *p_ccb; + tL2C_RCB *p_rcb; + BOOLEAN cfg_rej; + UINT16 cfg_rej_len; + UINT16 cmd_len; - memset (&cfg_info, 0, sizeof(cfg_info)); + p_next_cmd = p; + p_pkt_end = p + pkt_len; - /* An L2CAP packet may contain multiple commands */ while (TRUE) { - /* Smallest command is 4 bytes */ - if ((p = p_next_cmd) > (p_pkt_end - 4)) + if ((p = p_next_cmd) > p_pkt_end - 4) break; - STREAM_TO_UINT8 (cmd_code, p); - STREAM_TO_UINT8 (id, p); - STREAM_TO_UINT16 (cmd_len, p); + STREAM_TO_UINT8(cmd_code, p); + STREAM_TO_UINT8(id, p); + STREAM_TO_UINT16(cmd_len, p); - /* Check command length does not exceed packet length */ if ((p_next_cmd = p + cmd_len) > p_pkt_end) { - L2CAP_TRACE_WARNING3 ("Command len bad pkt_len: %d cmd_len: %d code: %d", - pkt_len, cmd_len, cmd_code); + L2CAP_TRACE(WARNING, + "Command len bad pkt_len: %d cmd_len: %d code: %d", + pkt_len, cmd_len, cmd_code); break; } switch (cmd_code) { case L2CAP_CMD_REJECT: - STREAM_TO_UINT16 (rej_reason, p); + STREAM_TO_UINT16(rej_reason, p); + if (rej_reason == L2CAP_CMD_REJ_MTU_EXCEEDED) { - STREAM_TO_UINT16 (rej_mtu, p); - /* What to do with the MTU reject ? We have negotiated an MTU. For now */ - /* we will ignore it and let a higher protocol timeout take care of it */ + STREAM_TO_UINT16(rej_mtu, p); - L2CAP_TRACE_WARNING2 ("L2CAP - MTU rej Handle: %d MTU: %d", p_lcb->handle, rej_mtu); + L2CAP_TRACE(WARNING, "L2CAP - MTU rej Handle: %d MTU: %d", + p_lcb->handle, rej_mtu); } + if (rej_reason == L2CAP_CMD_REJ_INVALID_CID) { - STREAM_TO_UINT16 (rcid, p); - STREAM_TO_UINT16 (lcid, p); + STREAM_TO_UINT16(rcid, p); + STREAM_TO_UINT16(lcid, p); - L2CAP_TRACE_WARNING2 ("L2CAP - rej with CID invalid, LCID: 0x%04x RCID: 0x%04x", lcid, rcid); + L2CAP_TRACE(WARNING, + "L2CAP - rej with CID invalid, LCID: %d RCID: %d", + lcid, rcid); - /* Remote CID invalid. Treat as a disconnect */ - if (((p_ccb = l2cu_find_ccb_by_cid (p_lcb, lcid)) != NULL) - && (p_ccb->remote_cid == rcid)) + if (((p_ccb = l2cu_find_ccb_by_cid(p_lcb, lcid)) != NULL) + && p_ccb->remote_cid == rcid) { - /* Fake link disconnect - no reply is generated */ - l2c_csm_execute (p_ccb, L2CEVT_LP_DISCONNECT_IND, NULL); + l2c_csm_execute(p_ccb, L2CEVT_LP_DISCONNECT_IND, NULL); } } - /* SonyEricsson Info request Bug workaround (Continue connection) */ - else if (rej_reason == L2CAP_CMD_REJ_NOT_UNDERSTOOD && p_lcb->w4_info_rsp) - { - btu_stop_timer (&p_lcb->info_timer_entry); - - p_lcb->w4_info_rsp = FALSE; - ci.status = HCI_SUCCESS; - memcpy (ci.bd_addr, p_lcb->remote_bd_addr, sizeof(BD_ADDR)); - - /* For all channels, send the event through their FSMs */ - for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) - { - l2c_csm_execute (p_ccb, L2CEVT_L2CAP_INFO_RSP, &ci); - } - } break; case L2CAP_CMD_CONN_REQ: - STREAM_TO_UINT16 (con_info.psm, p); - STREAM_TO_UINT16 (rcid, p); - if ((p_rcb = l2cu_find_rcb_by_psm (con_info.psm)) == NULL) + STREAM_TO_UINT16(con_info.psm, p); + STREAM_TO_UINT16(rcid, p); + + if ((p_rcb = l2cu_find_rcb_by_psm(con_info.psm)) == NULL) { - L2CAP_TRACE_WARNING1 ("L2CAP - rcvd conn req for unknown PSM: %d", con_info.psm); - l2cu_reject_connection (p_lcb, rcid, id, L2CAP_CONN_NO_PSM); + L2CAP_TRACE(WARNING, + "L2CAP - rcvd conn req for unknown PSM: %d", + con_info.psm); + l2cu_reject_connection(p_lcb, rcid, id, L2CAP_CONN_NO_PSM); break; } - else - { - if (!p_rcb->api.pL2CA_ConnectInd_Cb) - { - L2CAP_TRACE_WARNING1 ("L2CAP - rcvd conn req for outgoing-only connection PSM: %d", con_info.psm); - l2cu_reject_connection (p_lcb, rcid, id, L2CAP_CONN_NO_PSM); - break; - } - } - if ((p_ccb = l2cu_allocate_ccb (p_lcb, 0)) == NULL) + + if ((p_ccb = l2cu_allocate_ccb(p_lcb)) == NULL) { - L2CAP_TRACE_ERROR0 ("L2CAP - unable to allocate CCB"); - l2cu_reject_connection (p_lcb, rcid, id, L2CAP_CONN_NO_RESOURCES); + L2CAP_TRACE(ERROR, "L2CAP - unable to allocate CCB"); + l2cu_reject_connection(p_lcb, rcid, id, + L2CAP_CONN_NO_RESOURCES); break; } + p_ccb->remote_id = id; p_ccb->p_rcb = p_rcb; p_ccb->remote_cid = rcid; @@ -432,21 +295,23 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len) break; case L2CAP_CMD_CONN_RSP: - STREAM_TO_UINT16 (con_info.remote_cid, p); - STREAM_TO_UINT16 (lcid, p); - STREAM_TO_UINT16 (con_info.l2cap_result, p); - STREAM_TO_UINT16 (con_info.l2cap_status, p); + STREAM_TO_UINT16(con_info.remote_cid, p); + STREAM_TO_UINT16(lcid, p); + STREAM_TO_UINT16(con_info.l2cap_result, p); + STREAM_TO_UINT16(con_info.l2cap_status, p); - if ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, lcid)) == NULL) + if ((p_ccb = l2cu_find_ccb_by_cid(p_lcb, lcid)) == NULL) { - L2CAP_TRACE_WARNING2 ("L2CAP - no CCB for conn rsp, LCID: %d RCID: %d", - lcid, con_info.remote_cid); + L2CAP_TRACE(WARNING, + "L2CAP - no CCB for conn rsp, LCID: %d RCID: %d", + lcid, con_info.remote_cid); break; } if (p_ccb->local_id != id) { - L2CAP_TRACE_WARNING2 ("L2CAP - con rsp - bad ID. Exp: %d Got: %d", - p_ccb->local_id, id); + L2CAP_TRACE(WARNING, + "L2CAP - con rsp - bad ID. Exp: %d Got: %d", + p_ccb->local_id, id); break; } @@ -464,528 +329,302 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len) cfg_rej = FALSE; cfg_rej_len = 0; - STREAM_TO_UINT16 (lcid, p); - STREAM_TO_UINT16 (cfg_info.flags, p); + STREAM_TO_UINT16(lcid, p); + STREAM_TO_UINT16(cfg_info.flags, p); p_cfg_start = p; - cfg_info.flush_to_present = cfg_info.mtu_present = cfg_info.qos_present = - cfg_info.fcr_present = cfg_info.fcs_present = FALSE; + cfg_info.flush_to_present = + cfg_info.mtu_present = + cfg_info.qos_present = + cfg_info.fcr_present = FALSE; while (p < p_cfg_end) { - STREAM_TO_UINT8 (cfg_code, p); - STREAM_TO_UINT8 (cfg_len, p); + STREAM_TO_UINT8(cfg_code, p); + STREAM_TO_UINT8(cfg_len, p); - switch (cfg_code & 0x7F) + switch (cfg_code & 0x7f) { case L2CAP_CFG_TYPE_MTU: cfg_info.mtu_present = TRUE; - STREAM_TO_UINT16 (cfg_info.mtu, p); + STREAM_TO_UINT16(cfg_info.mtu, p); break; case L2CAP_CFG_TYPE_FLUSH_TOUT: cfg_info.flush_to_present = TRUE; - STREAM_TO_UINT16 (cfg_info.flush_to, p); + STREAM_TO_UINT16(cfg_info.flush_to, p); break; case L2CAP_CFG_TYPE_QOS: cfg_info.qos_present = TRUE; - STREAM_TO_UINT8 (cfg_info.qos.qos_flags, p); - STREAM_TO_UINT8 (cfg_info.qos.service_type, p); - STREAM_TO_UINT32 (cfg_info.qos.token_rate, p); - STREAM_TO_UINT32 (cfg_info.qos.token_bucket_size, p); - STREAM_TO_UINT32 (cfg_info.qos.peak_bandwidth, p); - STREAM_TO_UINT32 (cfg_info.qos.latency, p); - STREAM_TO_UINT32 (cfg_info.qos.delay_variation, p); + STREAM_TO_UINT8(cfg_info.qos.qos_flags, p); + STREAM_TO_UINT8(cfg_info.qos.service_type, p); + STREAM_TO_UINT32(cfg_info.qos.token_rate, p); + STREAM_TO_UINT32(cfg_info.qos.token_bucket_size, p); + STREAM_TO_UINT32(cfg_info.qos.peak_bandwidth, p); + STREAM_TO_UINT32(cfg_info.qos.latency, p); + STREAM_TO_UINT32(cfg_info.qos.delay_variation, p); break; case L2CAP_CFG_TYPE_FCR: cfg_info.fcr_present = TRUE; - STREAM_TO_UINT8 (cfg_info.fcr.mode, p); - STREAM_TO_UINT8 (cfg_info.fcr.tx_win_sz, p); - STREAM_TO_UINT8 (cfg_info.fcr.max_transmit, p); - STREAM_TO_UINT16 (cfg_info.fcr.rtrans_tout, p); - STREAM_TO_UINT16 (cfg_info.fcr.mon_tout, p); - STREAM_TO_UINT16 (cfg_info.fcr.mps, p); - break; - - case L2CAP_CFG_TYPE_FCS: - cfg_info.fcs_present = TRUE; - STREAM_TO_UINT8 (cfg_info.fcs, p); - break; - - case L2CAP_CFG_TYPE_EXT_FLOW: - cfg_info.ext_flow_spec_present = TRUE; - STREAM_TO_UINT8 (cfg_info.ext_flow_spec.id, p); - STREAM_TO_UINT8 (cfg_info.ext_flow_spec.stype, p); - STREAM_TO_UINT16 (cfg_info.ext_flow_spec.max_sdu_size, p); - STREAM_TO_UINT32 (cfg_info.ext_flow_spec.sdu_inter_time, p); - STREAM_TO_UINT32 (cfg_info.ext_flow_spec.access_latency, p); - STREAM_TO_UINT32 (cfg_info.ext_flow_spec.flush_timeout, p); + STREAM_TO_UINT8(cfg_info.fcr.mode, p); + STREAM_TO_UINT8(cfg_info.fcr.tx_win_sz, p); + STREAM_TO_UINT8(cfg_info.fcr.max_transmit, p); + STREAM_TO_UINT16(cfg_info.fcr.rtrans_tout, p); + STREAM_TO_UINT16(cfg_info.fcr.mon_tout, p); + STREAM_TO_UINT16(cfg_info.fcr.mps, p); break; default: - /* sanity check option length */ - if ((cfg_len + L2CAP_CFG_OPTION_OVERHEAD) <= cmd_len) + if (cfg_len + L2CAP_CFG_OPTION_OVERHEAD <= cmd_len) { p += cfg_len; - if ((cfg_code & 0x80) == 0) + + if (!(cfg_code & 0x80)) { cfg_rej_len += cfg_len + L2CAP_CFG_OPTION_OVERHEAD; cfg_rej = TRUE; } } - /* bad length; force loop exit */ else { p = p_cfg_end; - cfg_rej = TRUE; } + break; } } - if ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, lcid)) != NULL) + if ((p_ccb = l2cu_find_ccb_by_cid(p_lcb, lcid)) != NULL) { p_ccb->remote_id = id; + if (cfg_rej) { - l2cu_send_peer_config_rej (p_ccb, p_cfg_start, (UINT16) (cmd_len - L2CAP_CONFIG_REQ_LEN), cfg_rej_len); + l2cu_send_peer_config_rej( + p_ccb, p_cfg_start, + (UINT16)(cmd_len - L2CAP_CONFIG_REQ_LEN), cfg_rej_len); } else { - l2c_csm_execute (p_ccb, L2CEVT_L2CAP_CONFIG_REQ, &cfg_info); + l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONFIG_REQ, &cfg_info); } } else { - /* updated spec says send command reject on invalid cid */ - l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_INVALID_CID, id, 0, 0); + l2cu_send_peer_cmd_reject(p_lcb, L2CAP_CMD_REJ_INVALID_CID, id, + 0, 0); } break; case L2CAP_CMD_CONFIG_RSP: p_cfg_end = p + cmd_len; - STREAM_TO_UINT16 (lcid, p); - STREAM_TO_UINT16 (cfg_info.flags, p); - STREAM_TO_UINT16 (cfg_info.result, p); + STREAM_TO_UINT16(lcid, p); + STREAM_TO_UINT16(cfg_info.flags, p); + STREAM_TO_UINT16(cfg_info.result, p); - cfg_info.flush_to_present = cfg_info.mtu_present = cfg_info.qos_present = - cfg_info.fcr_present = cfg_info.fcs_present = FALSE; + cfg_info.flush_to_present = + cfg_info.mtu_present = + cfg_info.qos_present = FALSE; + cfg_info.fcr_present = FALSE; while (p < p_cfg_end) { - STREAM_TO_UINT8 (cfg_code, p); - STREAM_TO_UINT8 (cfg_len, p); + STREAM_TO_UINT8(cfg_code, p); + STREAM_TO_UINT8(cfg_len, p); - switch (cfg_code & 0x7F) + switch (cfg_code & 0x7f) { case L2CAP_CFG_TYPE_MTU: cfg_info.mtu_present = TRUE; - STREAM_TO_UINT16 (cfg_info.mtu, p); + STREAM_TO_UINT16(cfg_info.mtu, p); break; case L2CAP_CFG_TYPE_FLUSH_TOUT: cfg_info.flush_to_present = TRUE; - STREAM_TO_UINT16 (cfg_info.flush_to, p); + STREAM_TO_UINT16(cfg_info.flush_to, p); break; case L2CAP_CFG_TYPE_QOS: cfg_info.qos_present = TRUE; - STREAM_TO_UINT8 (cfg_info.qos.qos_flags, p); - STREAM_TO_UINT8 (cfg_info.qos.service_type, p); - STREAM_TO_UINT32 (cfg_info.qos.token_rate, p); - STREAM_TO_UINT32 (cfg_info.qos.token_bucket_size, p); - STREAM_TO_UINT32 (cfg_info.qos.peak_bandwidth, p); - STREAM_TO_UINT32 (cfg_info.qos.latency, p); - STREAM_TO_UINT32 (cfg_info.qos.delay_variation, p); + STREAM_TO_UINT8(cfg_info.qos.qos_flags, p); + STREAM_TO_UINT8(cfg_info.qos.service_type, p); + STREAM_TO_UINT32(cfg_info.qos.token_rate, p); + STREAM_TO_UINT32(cfg_info.qos.token_bucket_size, p); + STREAM_TO_UINT32(cfg_info.qos.peak_bandwidth, p); + STREAM_TO_UINT32(cfg_info.qos.latency, p); + STREAM_TO_UINT32(cfg_info.qos.delay_variation, p); break; case L2CAP_CFG_TYPE_FCR: cfg_info.fcr_present = TRUE; - STREAM_TO_UINT8 (cfg_info.fcr.mode, p); - STREAM_TO_UINT8 (cfg_info.fcr.tx_win_sz, p); - STREAM_TO_UINT8 (cfg_info.fcr.max_transmit, p); - STREAM_TO_UINT16 (cfg_info.fcr.rtrans_tout, p); - STREAM_TO_UINT16 (cfg_info.fcr.mon_tout, p); - STREAM_TO_UINT16 (cfg_info.fcr.mps, p); - break; - - case L2CAP_CFG_TYPE_FCS: - cfg_info.fcs_present = TRUE; - STREAM_TO_UINT8 (cfg_info.fcs, p); - break; - - case L2CAP_CFG_TYPE_EXT_FLOW: - cfg_info.ext_flow_spec_present = TRUE; - STREAM_TO_UINT8 (cfg_info.ext_flow_spec.id, p); - STREAM_TO_UINT8 (cfg_info.ext_flow_spec.stype, p); - STREAM_TO_UINT16 (cfg_info.ext_flow_spec.max_sdu_size, p); - STREAM_TO_UINT32 (cfg_info.ext_flow_spec.sdu_inter_time, p); - STREAM_TO_UINT32 (cfg_info.ext_flow_spec.access_latency, p); - STREAM_TO_UINT32 (cfg_info.ext_flow_spec.flush_timeout, p); + STREAM_TO_UINT8(cfg_info.fcr.mode, p); + STREAM_TO_UINT8(cfg_info.fcr.tx_win_sz, p); + STREAM_TO_UINT8(cfg_info.fcr.max_transmit, p); + STREAM_TO_UINT16(cfg_info.fcr.rtrans_tout, p); + STREAM_TO_UINT16(cfg_info.fcr.mon_tout, p); + STREAM_TO_UINT16(cfg_info.fcr.mps, p); break; } } - if ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, lcid)) != NULL) + if ((p_ccb = l2cu_find_ccb_by_cid(p_lcb, lcid)) != NULL) { if (p_ccb->local_id != id) { - L2CAP_TRACE_WARNING2 ("L2CAP - cfg rsp - bad ID. Exp: %d Got: %d", - p_ccb->local_id, id); + L2CAP_TRACE(WARNING, + "L2CAP - cfg rsp - bad ID. Exp: %d Got: %d", + p_ccb->local_id, id); break; } - if ( (cfg_info.result == L2CAP_CFG_OK) || (cfg_info.result == L2CAP_CFG_PENDING) ) - l2c_csm_execute (p_ccb, L2CEVT_L2CAP_CONFIG_RSP, &cfg_info); + + if (cfg_info.result == L2CAP_CFG_OK) + { + l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONFIG_RSP, &cfg_info); + } else - l2c_csm_execute (p_ccb, L2CEVT_L2CAP_CONFIG_RSP_NEG, &cfg_info); + { + l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONFIG_RSP_NEG, + &cfg_info); + } } else { - L2CAP_TRACE_WARNING1 ("L2CAP - rcvd cfg rsp for unknown CID: 0x%04x", lcid); + L2CAP_TRACE(WARNING, + "L2CAP - rcvd cfg rsp for unknown CID: %d", + lcid); } break; - case L2CAP_CMD_DISC_REQ: - STREAM_TO_UINT16 (lcid, p); - STREAM_TO_UINT16 (rcid, p); + STREAM_TO_UINT16(lcid, p); + STREAM_TO_UINT16(rcid, p); - if ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, lcid)) != NULL) + if ((p_ccb = l2cu_find_ccb_by_cid(p_lcb, lcid)) != NULL) { if (p_ccb->remote_cid == rcid) { p_ccb->remote_id = id; - l2c_csm_execute (p_ccb, L2CEVT_L2CAP_DISCONNECT_REQ, &con_info); + l2c_csm_execute(p_ccb, L2CEVT_L2CAP_DISCONNECT_REQ, + &con_info); } } else - l2cu_send_peer_disc_rsp (p_lcb, id, lcid, rcid); + { + l2cu_send_peer_disc_rsp(p_lcb, id, lcid, rcid); + } break; case L2CAP_CMD_DISC_RSP: - STREAM_TO_UINT16 (rcid, p); - STREAM_TO_UINT16 (lcid, p); + STREAM_TO_UINT16(rcid, p); + STREAM_TO_UINT16(lcid, p); - if ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, lcid)) != NULL) + if ((p_ccb = l2cu_find_ccb_by_cid(p_lcb, lcid)) != NULL) { if ((p_ccb->remote_cid == rcid) && (p_ccb->local_id == id)) { - l2c_csm_execute (p_ccb, L2CEVT_L2CAP_DISCONNECT_RSP, &con_info); + l2c_csm_execute(p_ccb, L2CEVT_L2CAP_DISCONNECT_RSP, + &con_info); } } + break; case L2CAP_CMD_ECHO_REQ: + if (cmd_len < btu_cb.hcit_acl_pkt_size - 12) + l2cu_send_peer_echo_rsp(p_lcb, id, p, cmd_len); + else + l2cu_send_peer_echo_rsp(p_lcb, id, NULL, 0); -#if (L2CAP_ENHANCED_FEATURES != 0) - if (!l2cu_check_feature_req (p_lcb, id, p, cmd_len)) - { - if (cmd_len < (btu_cb.hcit_acl_pkt_size - L2CAP_PKT_OVERHEAD - - L2CAP_CMD_OVERHEAD - - L2CAP_ECHO_RSP_LEN - - HCI_DATA_PREAMBLE_SIZE)) - { - l2cu_send_peer_echo_rsp (p_lcb, id, p, cmd_len); - } - else - { - l2cu_send_peer_echo_rsp (p_lcb, id, NULL, 0); - } - } -#else - l2cu_send_peer_echo_rsp (p_lcb, id, NULL, 0); -#endif break; case L2CAP_CMD_ECHO_RSP: -#if (L2CAP_ENHANCED_FEATURES != 0) - l2cu_check_feature_rsp (p_lcb, id, p, cmd_len); -#endif if (p_lcb->p_echo_rsp_cb) { tL2CA_ECHO_RSP_CB *p_cb = p_lcb->p_echo_rsp_cb; - /* Zero out the callback in case app immediately calls us again */ p_lcb->p_echo_rsp_cb = NULL; - (*p_cb) (L2CAP_PING_RESULT_OK); + (*p_cb)(L2CAP_PING_RESULT_OK); } break; case L2CAP_CMD_INFO_REQ: - STREAM_TO_UINT16 (info_type, p); - l2cu_send_peer_info_rsp (p_lcb, id, info_type); + STREAM_TO_UINT16(info_type, p); + l2cu_send_peer_info_rsp(p_lcb, id, info_type); break; - case L2CAP_CMD_INFO_RSP: - /* Stop the link connect timer if sent before L2CAP connection is up */ - if (p_lcb->w4_info_rsp) - { - btu_stop_timer (&p_lcb->info_timer_entry); - p_lcb->w4_info_rsp = FALSE; - } - - STREAM_TO_UINT16 (info_type, p); - STREAM_TO_UINT16 (result, p); - - p_lcb->info_rx_bits |= (1 << info_type); - - if ( (info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE) - && (result == L2CAP_INFO_RESP_RESULT_SUCCESS) ) - { - STREAM_TO_UINT32( p_lcb->peer_ext_fea, p ); - -#if (L2CAP_NUM_FIXED_CHNLS > 0) - if (p_lcb->peer_ext_fea & L2CAP_EXTFEA_FIXED_CHNLS) - { - l2cu_send_peer_info_req (p_lcb, L2CAP_FIXED_CHANNELS_INFO_TYPE); - break; - } - else - { - l2cu_process_fixed_chnl_resp (p_lcb); - } -#endif - } - - -#if (L2CAP_NUM_FIXED_CHNLS > 0) - if (info_type == L2CAP_FIXED_CHANNELS_INFO_TYPE) - { - if (result == L2CAP_INFO_RESP_RESULT_SUCCESS) - { - memcpy (p_lcb->peer_chnl_mask, p, L2CAP_FIXED_CHNL_ARRAY_SIZE); - } - - l2cu_process_fixed_chnl_resp (p_lcb); - } -#endif -#if (L2CAP_UCD_INCLUDED == TRUE) - else if (info_type == L2CAP_CONNLESS_MTU_INFO_TYPE) - { - if (result == L2CAP_INFO_RESP_RESULT_SUCCESS) - { - STREAM_TO_UINT16 (p_lcb->ucd_mtu, p); - } - } -#endif - - ci.status = HCI_SUCCESS; - memcpy (ci.bd_addr, p_lcb->remote_bd_addr, sizeof(BD_ADDR)); - for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) - { - l2c_csm_execute (p_ccb, L2CEVT_L2CAP_INFO_RSP, &ci); - } + case 11: break; default: - L2CAP_TRACE_WARNING1 ("L2CAP - bad cmd code: %d", cmd_code); - l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0); + L2CAP_TRACE(WARNING, "L2CAP - bad cmd code: %d", cmd_code); + l2cu_send_peer_cmd_reject(p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, + 0, 0); return; } } } -/******************************************************************************* -** -** Function l2c_process_held_packets -** -** Description This function processes any L2CAP packets that arrived before -** the HCI connection complete arrived. It is a work around for -** badly behaved controllers. -** -** Returns void -** -*******************************************************************************/ -void l2c_process_held_packets (BOOLEAN timed_out) -{ - BT_HDR *p_buf, *p_buf1; - BUFFER_Q *p_rcv_hold_q = &l2cb.rcv_hold_q; - - if (!p_rcv_hold_q->count) - return; - - if (!timed_out) - { - btu_stop_timer(&l2cb.rcv_hold_tle); - L2CAP_TRACE_WARNING0("L2CAP HOLD CONTINUE"); - } - else - { - L2CAP_TRACE_WARNING0("L2CAP HOLD TIMEOUT"); - } - - /* Update the timeouts in the hold queue */ - for (p_buf = (BT_HDR *)GKI_getfirst (p_rcv_hold_q); p_buf; p_buf = p_buf1) - { - p_buf1 = (BT_HDR *)GKI_getnext (p_buf); - if (!timed_out || (!p_buf->layer_specific) || (--p_buf->layer_specific == 0)) - { - GKI_remove_from_queue (p_rcv_hold_q, p_buf); - p_buf->layer_specific = 0xFFFF; - l2c_rcv_acl_data (p_buf); - } - } - - /* If anyone still in the queue, restart the timeout */ - if (p_rcv_hold_q->count) - btu_start_timer (&l2cb.rcv_hold_tle, BTU_TTYPE_L2CAP_HOLD, BT_1SEC_TIMEOUT); -} - -/******************************************************************************* -** -** Function l2c_init -** -** Description This function is called once at startup to initialize -** all the L2CAP structures -** -** Returns void -** -*******************************************************************************/ -void l2c_init (void) +void l2c_process_timeout(TIMER_LIST_ENT *p_tle) { - INT16 xx; - - memset (&l2cb, 0, sizeof (tL2C_CB)); - /* the psm is increased by 2 before being used */ - l2cb.dyn_psm = 0xFFF; - - /* Put all the channel control blocks on the free queue */ - for (xx = 0; xx < MAX_L2CAP_CHANNELS - 1; xx++) - { - l2cb.ccb_pool[xx].p_next_ccb = &l2cb.ccb_pool[xx + 1]; - } - -#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE) - /* it will be set to L2CAP_PKT_START_NON_FLUSHABLE if controller supports */ - l2cb.non_flushable_pbf = L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT; -#endif - - - l2cb.p_free_ccb_first = &l2cb.ccb_pool[0]; - l2cb.p_free_ccb_last = &l2cb.ccb_pool[MAX_L2CAP_CHANNELS - 1]; - -#ifdef L2CAP_DESIRED_LINK_ROLE - l2cb.desire_role = L2CAP_DESIRED_LINK_ROLE; -#else - l2cb.desire_role = HCI_ROLE_SLAVE; -#endif - - /* Set the default idle timeout */ - l2cb.idle_timeout = L2CAP_LINK_INACTIVITY_TOUT; - -#if defined(L2CAP_INITIAL_TRACE_LEVEL) - l2cb.l2cap_trace_level = L2CAP_INITIAL_TRACE_LEVEL; -#else - l2cb.l2cap_trace_level = BT_TRACE_LEVEL_NONE; /* No traces */ -#endif - -#if L2CAP_CONFORMANCE_TESTING == TRUE - /* Conformance testing needs a dynamic response */ - l2cb.test_info_resp = L2CAP_EXTFEA_SUPPORTED_MASK; -#endif - - /* Number of ACL buffers to use for high priority channel */ -#if (defined(L2CAP_HIGH_PRI_CHAN_QUOTA_IS_CONFIGURABLE) && (L2CAP_HIGH_PRI_CHAN_QUOTA_IS_CONFIGURABLE == TRUE)) - l2cb.high_pri_min_xmit_quota = L2CAP_HIGH_PRI_MIN_XMIT_QUOTA; -#endif - -} - -/******************************************************************************* -** -** Function l2c_process_timeout -** -** Description This function is called when an L2CAP-related timeout occurs -** -** Returns void -** -*******************************************************************************/ -void l2c_process_timeout (TIMER_LIST_ENT *p_tle) -{ - /* What type of timeout ? */ switch (p_tle->event) { case BTU_TTYPE_L2CAP_LINK: - l2c_link_timeout ((tL2C_LCB *)p_tle->param); + l2c_link_timeout((tL2C_LCB *)p_tle->param); break; case BTU_TTYPE_L2CAP_CHNL: - l2c_csm_execute (((tL2C_CCB *)p_tle->param), L2CEVT_TIMEOUT, NULL); - break; - - case BTU_TTYPE_L2CAP_FCR_ACK: - l2c_csm_execute (((tL2C_CCB *)p_tle->param), L2CEVT_ACK_TIMEOUT, NULL); + l2c_csm_execute(((tL2C_CCB *)p_tle->param), L2CEVT_TIMEOUT, NULL); break; case BTU_TTYPE_L2CAP_HOLD: - /* Update the timeouts in the hold queue */ l2c_process_held_packets(TRUE); break; - case BTU_TTYPE_L2CAP_INFO: - l2c_info_timeout((tL2C_LCB *)p_tle->param); - break; - + case BTU_TTYPE_73: + return; } } -/******************************************************************************* -** -** Function l2c_data_write -** -** Description API functions call this function to write data. -** -** Returns L2CAP_DW_SUCCESS, if data accepted, else FALSE -** L2CAP_DW_CONGESTED, if data accepted and the channel is congested -** L2CAP_DW_FAILED, if error -** -*******************************************************************************/ -UINT8 l2c_data_write (UINT16 cid, BT_HDR *p_data, UINT16 flags) +void l2c_process_held_packets(BOOLEAN timed_out) { - tL2C_CCB *p_ccb; + BT_HDR *p_buf; + BT_HDR *p_buf1; + BUFFER_Q *p_rcv_hold_q = &l2cb.rcv_hold_q; + + if (!p_rcv_hold_q->count) + return; - /* Find the channel control block. We don't know the link it is on. */ - if ((p_ccb = l2cu_find_ccb_by_cid (NULL, cid)) == NULL) + if (!timed_out) { - L2CAP_TRACE_WARNING1 ("L2CAP - no CCB for L2CA_DataWrite, CID: %d", cid); - GKI_freebuf (p_data); - return (L2CAP_DW_FAILED); + btu_stop_timer(&l2cb.rcv_hold_tle); + L2CAP_TRACE(WARNING, "L2CAP HOLD CONTINUE"); } - -#ifndef TESTER /* Tester may send any amount of data. otherwise sending message - bigger than mtu size of peer is a violation of protocol */ - if (p_data->len > p_ccb->peer_cfg.mtu) + else { - L2CAP_TRACE_WARNING1 ("L2CAP - CID: 0x%04x cannot send message bigger than peer's mtu size", cid); - GKI_freebuf (p_data); - return (L2CAP_DW_FAILED); + L2CAP_TRACE(WARNING, "L2CAP HOLD TIMEOUT\0\0\0\0\0"); } -#endif - /* channel based, packet based flushable or non-flushable */ - p_data->layer_specific = flags; - - /* If already congested, do not accept any more packets */ - if (p_ccb->cong_sent) + for (p_buf = GKI_getfirst(p_rcv_hold_q); p_buf; p_buf = p_buf1) { - L2CAP_TRACE_ERROR3 ("L2CAP - CID: 0x%04x cannot send, already congested xmit_hold_q.count: %u buff_quota: %u", - p_ccb->local_cid, p_ccb->xmit_hold_q.count, p_ccb->buff_quota); + p_buf1 = GKI_getnext(p_buf); - GKI_freebuf (p_data); - return (L2CAP_DW_FAILED); + if (!timed_out || !p_buf->layer_specific || !--p_buf->layer_specific) + { + GKI_remove_from_queue(p_rcv_hold_q, p_buf); + p_buf->layer_specific = 0xffff; + l2c_rcv_acl_data(p_buf); + } } - l2c_csm_execute (p_ccb, L2CEVT_L2CA_DATA_WRITE, p_data); - - if (p_ccb->cong_sent) - return (L2CAP_DW_CONGESTED); - - return (L2CAP_DW_SUCCESS); + if (p_rcv_hold_q->count) + { + btu_start_timer(&l2cb.rcv_hold_tle, BTU_TTYPE_L2CAP_HOLD, + 1); + } } - diff --git a/src/revolution/BTE/stack/l2cap/l2c_utils.c b/src/revolution/BTE/stack/l2cap/l2c_utils.c index a697d47..7ba9e2c 100644 --- a/src/revolution/BTE/stack/l2cap/l2c_utils.c +++ b/src/revolution/BTE/stack/l2cap/l2c_utils.c @@ -16,334 +16,187 @@ * ******************************************************************************/ +/* Original source: + * bluedroid + * stack/l2cap/l2c_utils.c + */ + +/* Includes changes by muff1n1634 and for this repository (KoopTheKoopa) */ + /****************************************************************************** * - * This file contains L2CAP utility functions + * This file contains L2CAP utility functions. * ******************************************************************************/ -#include +#include "l2c_int.h" + #include -#include -#include "gki.h" +#include "gki_target.h" +#include "bt_target.h" +#include "bt_trace.h" #include "bt_types.h" -#include "hcimsgs.h" -#include "l2cdefs.h" -#include "l2c_int.h" -#include "hcidefs.h" -#include "btu.h" +#include "data_types.h" + #include "btm_api.h" #include "btm_int.h" -#include "hcidefs.h" - -/******************************************************************************* -** -** Function l2cu_allocate_lcb -** -** Description Look for an unused LCB -** -** Returns LCB address or NULL if none found -** -*******************************************************************************/ -#ifdef REVOLUTION -tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr) -#else -tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding) -#endif +#include "btu.h" +#include "gki.h" +#include "hcimsgs.h" +#include "l2c_api.h" +#include "l2cdefs.h" + +tL2C_LCB *l2cu_allocate_lcb(BD_ADDR p_bd_addr) { - int xx; - tL2C_LCB *p_lcb = &l2cb.lcb_pool[0]; + int xx; + tL2C_LCB *p_lcb = l2cb.lcb_pool; + /* explicitly post-increment */ for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) { - if (!p_lcb->in_use) - { - memset (p_lcb, 0, sizeof (tL2C_LCB)); - - memcpy (p_lcb->remote_bd_addr, p_bd_addr, BD_ADDR_LEN); - - p_lcb->in_use = TRUE; - p_lcb->link_state = LST_DISCONNECTED; - p_lcb->handle = HCI_INVALID_HANDLE; - p_lcb->link_flush_tout = 0xFFFF; - p_lcb->timer_entry.param = (TIMER_PARAM_TYPE)p_lcb; - p_lcb->info_timer_entry.param = (TIMER_PARAM_TYPE)p_lcb; - p_lcb->idle_timeout = l2cb.idle_timeout; - p_lcb->id = 1; /* spec does not allow '0' */ -#ifndef REVOLUTION - p_lcb->is_bonding = is_bonding; -#endif - - l2cb.num_links_active++; - - l2c_link_adjust_allocation(); - return (p_lcb); - } - } + if (p_lcb->in_use) + continue; - /* If here, no free LCB found */ - return (NULL); -} + memset(p_lcb, 0, sizeof *p_lcb); -/******************************************************************************* -** -** Function l2cu_update_lcb_4_bonding -** -** Description Mark the lcb for bonding. Used when bonding takes place on -** an existing ACL connection. (Pre-Lisbon devices) -** -** Returns Nothing -** -*******************************************************************************/ -void l2cu_update_lcb_4_bonding (BD_ADDR p_bd_addr, BOOLEAN is_bonding) -{ - tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr); + p_lcb->in_use = TRUE; + memcpy(p_lcb->remote_bd_addr, p_bd_addr, BD_ADDR_LEN); + p_lcb->link_state = LST_DISCONNECTED; + p_lcb->handle = HCI_INVALID_HANDLE; + p_lcb->p_hcit_rcv_acl = NULL; + p_lcb->link_flush_tout = 0xffff; + p_lcb->timer_entry.param = (TIMER_PARAM_TYPE)p_lcb; + p_lcb->sent_not_acked = 0; + p_lcb->idle_timeout = l2cb.idle_timeout; + p_lcb->id = 0; - if (p_lcb) - { - L2CAP_TRACE_DEBUG3 ("l2cu_update_lcb_4_bonding BDA: %08x%04x is_bonding: %d", - (p_bd_addr[0]<<24)+(p_bd_addr[1]<<16)+(p_bd_addr[2]<<8)+p_bd_addr[3], - (p_bd_addr[4]<<8)+p_bd_addr[5], is_bonding); - p_lcb->is_bonding = is_bonding; + ++l2cb.num_links_active; + + l2c_link_adjust_allocation(); + return p_lcb; } + + return NULL; } -/******************************************************************************* -** -** Function l2cu_release_lcb -** -** Description Release an LCB. All timers will be stopped, channels -** dropped, buffers returned etc. -** -** Returns void -** -*******************************************************************************/ -void l2cu_release_lcb (tL2C_LCB *p_lcb) +void l2cu_release_lcb(tL2C_LCB *p_lcb) { - tL2C_CCB *p_ccb; + tL2C_CCB *p_ccb; - p_lcb->in_use = FALSE; - p_lcb->is_bonding = FALSE; + p_lcb->in_use = FALSE; - /* Stop timers */ - btu_stop_timer (&p_lcb->timer_entry); - btu_stop_timer (&p_lcb->info_timer_entry); + btu_stop_timer(&p_lcb->timer_entry); - /* Release any unfinished L2CAP packet on this link */ if (p_lcb->p_hcit_rcv_acl) { GKI_freebuf(p_lcb->p_hcit_rcv_acl); p_lcb->p_hcit_rcv_acl = NULL; } -#if BTM_SCO_INCLUDED == TRUE - /* Release all SCO links */ btm_remove_sco_links(p_lcb->remote_bd_addr); -#endif -#if (BLE_INCLUDED == TRUE) - p_lcb->is_ble_link = FALSE; - l2cb.is_ble_connecting = FALSE; -#endif - -#if (L2CAP_NUM_FIXED_CHNLS > 0) - { - int xx; - - for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) - { - if (p_lcb->p_fixed_ccbs[xx]) - { - l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]); - p_lcb->p_fixed_ccbs[xx] = NULL; - (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason); - } - else if ( (p_lcb->peer_chnl_mask[0] & (1 << (xx + L2CAP_FIRST_FIXED_CHNL))) - && (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL) ) - (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason); - } - } -#endif + for (p_ccb = p_lcb->p_first_ccb; p_ccb; p_ccb = p_lcb->p_first_ccb) + l2cu_release_ccb(p_ccb); - /* Ensure no CCBs left on this LCB */ - for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_lcb->ccb_queue.p_first_ccb) + if (p_lcb->link_state == LST_CONNECTED + || p_lcb->link_state == LST_DISCONNECTING) { - l2cu_release_ccb (p_ccb); + btm_acl_removed(p_lcb->remote_bd_addr); } - /* Tell BTM Acl management the link was removed */ - if ((p_lcb->link_state == LST_CONNECTED) || (p_lcb->link_state == LST_DISCONNECTING)) - btm_acl_removed (p_lcb->remote_bd_addr); - - /* Release any held buffers */ while (p_lcb->link_xmit_data_q.p_first) - GKI_freebuf (GKI_dequeue (&p_lcb->link_xmit_data_q)); - -#if (L2CAP_UCD_INCLUDED == TRUE) - /* clean up any security pending UCD */ - l2c_ucd_delete_sec_pending_q(p_lcb); -#endif + GKI_freebuf(GKI_dequeue(&p_lcb->link_xmit_data_q)); - /* Re-adjust flow control windows make sure it does not go negative */ if (l2cb.num_links_active >= 1) l2cb.num_links_active--; + l2cb.controller_xmit_window += p_lcb->sent_not_acked; + l2c_link_adjust_allocation(); - /* Check for ping outstanding */ if (p_lcb->p_echo_rsp_cb) { tL2CA_ECHO_RSP_CB *p_cb = p_lcb->p_echo_rsp_cb; - /* Zero out the callback in case app immediately calls us again */ p_lcb->p_echo_rsp_cb = NULL; - (*p_cb) (L2CAP_PING_RESULT_NO_LINK); + (*p_cb)(L2CAP_PING_RESULT_NO_LINK); } } - -/******************************************************************************* -** -** Function l2cu_find_lcb_by_bd_addr -** -** Description Look through all active LCBs for a match based on the -** remote BD address. -** -** Returns pointer to matched LCB, or NULL if no match -** -*******************************************************************************/ -tL2C_LCB *l2cu_find_lcb_by_bd_addr (BD_ADDR p_bd_addr) +tL2C_LCB *l2cu_find_lcb_by_bd_addr(BD_ADDR p_bd_addr) { - int xx; - tL2C_LCB *p_lcb = &l2cb.lcb_pool[0]; + int xx; + tL2C_LCB *p_lcb = l2cb.lcb_pool; + /* explicitly post-increment */ for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) { - if ((p_lcb->in_use) && (!memcmp (p_lcb->remote_bd_addr, p_bd_addr, BD_ADDR_LEN))) + if (p_lcb->in_use + && memcmp(p_lcb->remote_bd_addr, p_bd_addr, BD_ADDR_LEN) == 0) { - return (p_lcb); + return p_lcb; } } - /* If here, no match found */ - return (NULL); + return NULL; +} + +tL2C_LCB *l2cu_find_lcb_by_handle(UINT16 handle) +{ + int xx; + tL2C_LCB *p_lcb = l2cb.lcb_pool; + + /* explicitly post-increment */ + for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) + { + if (p_lcb->in_use && p_lcb->handle == handle) + return p_lcb; + } + + return NULL; } -/******************************************************************************* -** -** Function l2cu_get_conn_role -** -** Description Determine the desired role (master or slave) of a link. -** If already got a slave link, this one must be a master. If -** already got at least 1 link where we are the master, make this -** also a master. -** -** Returns HCI_ROLE_MASTER or HCI_ROLE_SLAVE -** -*******************************************************************************/ -UINT8 l2cu_get_conn_role (tL2C_LCB *p_this_lcb) +UINT8 l2cu_get_conn_role(tL2C_LCB *p_this_lcb) { return l2cb.desire_role; } -/******************************************************************************* -** -** Function l2cu_build_header -** -** Description Builds the L2CAP command packet header -** -** Returns Pointer to allocated packet or NULL if no resources -** -*******************************************************************************/ -BT_HDR *l2cu_build_header (tL2C_LCB *p_lcb, UINT16 len, UINT8 cmd, UINT8 id) +BT_HDR *l2cu_build_header(UINT16 hci_handle, UINT16 len, UINT8 cmd, UINT8 id) { - BT_HDR *p_buf = (BT_HDR *)GKI_getpoolbuf (L2CAP_CMD_POOL_ID); - UINT8 *p; + BT_HDR *p_buf; + UINT8 *p; - if (!p_buf) - { - L2CAP_TRACE_ERROR0 ("l2cu_build_header - no buffer"); - return (NULL); - } + if ((p_buf = GKI_getpoolbuf(L2CAP_CMD_POOL_ID)) == NULL) + return NULL; p_buf->offset = L2CAP_SEND_CMD_OFFSET; - p_buf->len = len + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; + p_buf->len = + len + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET; - /* Put in HCI header - handle + pkt boundary */ -#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE) - UINT16_TO_STREAM (p, p_lcb->handle | l2cb.non_flushable_pbf); -#else - UINT16_TO_STREAM (p, (p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT))); -#endif - - UINT16_TO_STREAM (p, len + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD); - UINT16_TO_STREAM (p, len + L2CAP_CMD_OVERHEAD); - -#if (BLE_INCLUDED == TRUE) - if (p_lcb->is_ble_link) - { - UINT16_TO_STREAM (p, L2CAP_BLE_SIGNALLING_CID); - } - else -#endif - { - UINT16_TO_STREAM (p, L2CAP_SIGNALLING_CID); - } + UINT16_TO_STREAM(p, L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT | hci_handle); - /* Put in L2CAP command header */ - UINT8_TO_STREAM (p, cmd); - UINT8_TO_STREAM (p, id); - UINT16_TO_STREAM (p, len); + UINT16_TO_STREAM(p, len + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD); + UINT16_TO_STREAM(p, len + L2CAP_CMD_OVERHEAD); - return (p_buf); -} + UINT16_TO_STREAM(p, L2CAP_SIGNALLING_CID); -/******************************************************************************* -** -** Function l2cu_adj_id -** -** Description Checks for valid ID based on specified mask -** and adjusts the id if invalid. -** -** Returns void -** -*******************************************************************************/ -void l2cu_adj_id (tL2C_LCB *p_lcb, UINT8 adj_mask) -{ -#if (L2CAP_ENHANCED_FEATURES != 0) - if ((adj_mask & L2CAP_ADJ_BRCM_ID) && p_lcb->id == L2CAP_FEATURE_REQ_ID) - { - p_lcb->id++; - } -#endif + UINT8_TO_STREAM(p, cmd); + UINT8_TO_STREAM(p, id); + UINT16_TO_STREAM(p, len); - if ((adj_mask & L2CAP_ADJ_ZERO_ID) && !p_lcb->id) - { - p_lcb->id++; - } + return p_buf; } -/******************************************************************************* -** -** Function l2cu_send_peer_cmd_reject -** -** Description Build and send an L2CAP "command reject" message -** to the peer. -** -** Returns void -** -*******************************************************************************/ -void l2cu_send_peer_cmd_reject (tL2C_LCB *p_lcb, UINT16 reason, UINT8 rem_id, - UINT16 p1, UINT16 p2) +void l2cu_send_peer_cmd_reject(tL2C_LCB *p_lcb, UINT16 reason, UINT8 rem_id, + UINT16 p1, UINT16 p2) { - UINT16 param_len; - BT_HDR *p_buf; - UINT8 *p; + UINT16 param_len; + BT_HDR *p_buf; + UINT8 *p; - /* Put in L2CAP packet header */ if (reason == L2CAP_CMD_REJ_MTU_EXCEEDED) param_len = 2; else if (reason == L2CAP_CMD_REJ_INVALID_CID) @@ -351,3058 +204,955 @@ void l2cu_send_peer_cmd_reject (tL2C_LCB *p_lcb, UINT16 reason, UINT8 rem_id, else param_len = 0; - if ((p_buf = l2cu_build_header (p_lcb, (UINT16) (L2CAP_CMD_REJECT_LEN + param_len), L2CAP_CMD_REJECT, rem_id)) == NULL ) + if ((p_buf = l2cu_build_header(p_lcb->handle, + (UINT16)(L2CAP_CMD_REJECT_LEN + param_len), + L2CAP_CMD_REJECT, rem_id)) + == NULL) { - L2CAP_TRACE_WARNING0 ("L2CAP - no buffer cmd_rej"); + L2CAP_TRACE(WARNING, "L2CAP - no buffer cmd_rej"); return; } - p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + - L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; + p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; - UINT16_TO_STREAM (p, reason); + UINT16_TO_STREAM(p, reason); if (param_len >= 2) - UINT16_TO_STREAM (p, p1); + UINT16_TO_STREAM(p, p1); if (param_len >= 4) - UINT16_TO_STREAM (p, p2); + UINT16_TO_STREAM(p, p2); - l2c_link_check_send_pkts (p_lcb, NULL, p_buf); + l2c_link_check_send_pkts(p_lcb, NULL, p_buf); } - -/******************************************************************************* -** -** Function l2cu_send_peer_connect_req -** -** Description Build and send an L2CAP "connection request" message -** to the peer. -** -** Returns void -** -*******************************************************************************/ -void l2cu_send_peer_connect_req (tL2C_CCB *p_ccb) +void l2cu_send_peer_connect_req(tL2C_CCB *p_ccb) { - BT_HDR *p_buf; - UINT8 *p; + BT_HDR *p_buf; + UINT8 *p; - /* Create an identifier for this packet */ - p_ccb->p_lcb->id++; - l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID); + p_ccb->local_id = ++p_ccb->p_lcb->id; - p_ccb->local_id = p_ccb->p_lcb->id; - - if ((p_buf = l2cu_build_header (p_ccb->p_lcb, L2CAP_CONN_REQ_LEN, L2CAP_CMD_CONN_REQ, - p_ccb->local_id)) == NULL) + if ((p_buf = l2cu_build_header(p_ccb->p_lcb->handle, L2CAP_CONN_REQ_LEN, + L2CAP_CMD_CONN_REQ, p_ccb->local_id)) + == NULL) { - L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for conn_req"); + L2CAP_TRACE(WARNING, "L2CAP - no buffer for conn_req"); return; } - p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET+HCI_DATA_PREAMBLE_SIZE + - L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; + p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; - UINT16_TO_STREAM (p, p_ccb->p_rcb->real_psm); - UINT16_TO_STREAM (p, p_ccb->local_cid); + UINT16_TO_STREAM(p, p_ccb->p_rcb->psm); + UINT16_TO_STREAM(p, p_ccb->local_cid); - l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf); + l2c_link_check_send_pkts(p_ccb->p_lcb, NULL, p_buf); } - -/******************************************************************************* -** -** Function l2cu_send_peer_connect_rsp -** -** Description Build and send an L2CAP "connection response" message -** to the peer. -** -** Returns void -** -*******************************************************************************/ -void l2cu_send_peer_connect_rsp (tL2C_CCB *p_ccb, UINT16 result, UINT16 status) +void l2cu_send_peer_connect_rsp(tL2C_CCB *p_ccb, UINT16 result, UINT16 status) { - BT_HDR *p_buf; - UINT8 *p; - - if (result == L2CAP_CONN_PENDING) - { - /* if we already sent pending response */ - if (p_ccb->flags & CCB_FLAG_SENT_PENDING) - return; - else - p_ccb->flags |= CCB_FLAG_SENT_PENDING; - } + BT_HDR *p_buf; + UINT8 *p; - if ((p_buf=l2cu_build_header(p_ccb->p_lcb, L2CAP_CONN_RSP_LEN, L2CAP_CMD_CONN_RSP, p_ccb->remote_id)) == NULL) + if ((p_buf = l2cu_build_header(p_ccb->p_lcb->handle, L2CAP_CONN_RSP_LEN, + L2CAP_CMD_CONN_RSP, p_ccb->remote_id)) + == NULL) { - L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for conn_rsp"); + L2CAP_TRACE(WARNING, "L2CAP - no buffer for conn_req"); return; } - p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET+HCI_DATA_PREAMBLE_SIZE + - L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; + p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; - UINT16_TO_STREAM (p, p_ccb->local_cid); - UINT16_TO_STREAM (p, p_ccb->remote_cid); - UINT16_TO_STREAM (p, result); - UINT16_TO_STREAM (p, status); + UINT16_TO_STREAM(p, p_ccb->local_cid); + UINT16_TO_STREAM(p, p_ccb->remote_cid); + UINT16_TO_STREAM(p, result); + UINT16_TO_STREAM(p, status); - l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf); + l2c_link_check_send_pkts(p_ccb->p_lcb, NULL, p_buf); } - -/******************************************************************************* -** -** Function l2cu_reject_connection -** -** Description Build and send an L2CAP "connection response neg" message -** to the peer. This function is called when there is no peer -** CCB (non-existant PSM or no resources). -** -** Returns void -** -*******************************************************************************/ -void l2cu_reject_connection (tL2C_LCB *p_lcb, UINT16 remote_cid, UINT8 rem_id, UINT16 result) +void l2cu_reject_connection(tL2C_LCB *p_lcb, UINT16 remote_cid, UINT8 rem_id, + UINT16 result) { - BT_HDR *p_buf; - UINT8 *p; + BT_HDR *p_buf; + UINT8 *p; - if ((p_buf = l2cu_build_header(p_lcb, L2CAP_CONN_RSP_LEN, L2CAP_CMD_CONN_RSP, rem_id)) == NULL ) + if ((p_buf = l2cu_build_header(p_lcb->handle, L2CAP_CONN_RSP_LEN, + L2CAP_CMD_CONN_RSP, rem_id)) + == NULL) { - L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for conn_req"); + L2CAP_TRACE(WARNING, "L2CAP - no buffer for conn_req"); return; } - p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET+HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; + p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; - UINT16_TO_STREAM (p, 0); /* Local CID of 0 */ - UINT16_TO_STREAM (p, remote_cid); - UINT16_TO_STREAM (p, result); - UINT16_TO_STREAM (p, 0); /* Status of 0 */ + UINT16_TO_STREAM(p, 0); + UINT16_TO_STREAM(p, remote_cid); + UINT16_TO_STREAM(p, result); + UINT16_TO_STREAM(p, 0); - l2c_link_check_send_pkts (p_lcb, NULL, p_buf); + l2c_link_check_send_pkts(p_lcb, NULL, p_buf); } -/******************************************************************************* -** -** Function l2cu_send_peer_config_req -** -** Description Build and send an L2CAP "configuration request" message -** to the peer. -** -** Returns void -** -*******************************************************************************/ -void l2cu_send_peer_config_req (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg) +void l2cu_send_peer_config_req(tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg) { - BT_HDR *p_buf; - UINT16 cfg_len=0; - UINT8 *p; + BT_HDR *p_buf; + UINT16 cfg_len = 0; + UINT8 *p; - /* Create an identifier for this packet */ - p_ccb->p_lcb->id++; - l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID); - - p_ccb->local_id = p_ccb->p_lcb->id; + p_ccb->local_id = ++p_ccb->p_lcb->id; if (p_cfg->mtu_present) cfg_len += L2CAP_CFG_MTU_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD; + if (p_cfg->flush_to_present) cfg_len += L2CAP_CFG_FLUSH_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD; + if (p_cfg->qos_present) cfg_len += L2CAP_CFG_QOS_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD; + if (p_cfg->fcr_present) cfg_len += L2CAP_CFG_FCR_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD; - if (p_cfg->fcs_present) - cfg_len += L2CAP_CFG_FCS_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD; - if (p_cfg->ext_flow_spec_present) - cfg_len += L2CAP_CFG_EXT_FLOW_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD; - if ((p_buf = l2cu_build_header (p_ccb->p_lcb, (UINT16) (L2CAP_CONFIG_REQ_LEN + cfg_len), - L2CAP_CMD_CONFIG_REQ, p_ccb->local_id)) == NULL ) + if ((p_buf = l2cu_build_header(p_ccb->p_lcb->handle, + L2CAP_CONFIG_REQ_LEN + cfg_len, + L2CAP_CMD_CONFIG_REQ, p_ccb->local_id)) + == NULL) { - L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for conn_req"); + L2CAP_TRACE(WARNING, "L2CAP - no buffer for conn_req"); return; } - p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + - L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; + p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; - UINT16_TO_STREAM (p, p_ccb->remote_cid); - UINT16_TO_STREAM (p, p_cfg->flags); /* Flags (continuation) */ + UINT16_TO_STREAM(p, p_ccb->remote_cid); + UINT16_TO_STREAM(p, 0); - /* Now, put the options */ if (p_cfg->mtu_present) { - UINT8_TO_STREAM (p, L2CAP_CFG_TYPE_MTU); - UINT8_TO_STREAM (p, L2CAP_CFG_MTU_OPTION_LEN); - UINT16_TO_STREAM (p, p_cfg->mtu); + UINT8_TO_STREAM(p, L2CAP_CFG_TYPE_MTU); + UINT8_TO_STREAM(p, L2CAP_CFG_MTU_OPTION_LEN); + UINT16_TO_STREAM(p, p_cfg->mtu); } + if (p_cfg->flush_to_present) { - UINT8_TO_STREAM (p, L2CAP_CFG_TYPE_FLUSH_TOUT); - UINT8_TO_STREAM (p, L2CAP_CFG_FLUSH_OPTION_LEN); - UINT16_TO_STREAM (p, p_cfg->flush_to); - } - if (p_cfg->qos_present) - { - UINT8_TO_STREAM (p, L2CAP_CFG_TYPE_QOS); - UINT8_TO_STREAM (p, L2CAP_CFG_QOS_OPTION_LEN); - UINT8_TO_STREAM (p, p_cfg->qos.qos_flags); - UINT8_TO_STREAM (p, p_cfg->qos.service_type); - UINT32_TO_STREAM (p, p_cfg->qos.token_rate); - UINT32_TO_STREAM (p, p_cfg->qos.token_bucket_size); - UINT32_TO_STREAM (p, p_cfg->qos.peak_bandwidth); - UINT32_TO_STREAM (p, p_cfg->qos.latency); - UINT32_TO_STREAM (p, p_cfg->qos.delay_variation); - } - if (p_cfg->fcr_present) - { - UINT8_TO_STREAM (p, L2CAP_CFG_TYPE_FCR); - UINT8_TO_STREAM (p, L2CAP_CFG_FCR_OPTION_LEN); - UINT8_TO_STREAM (p, p_cfg->fcr.mode); - UINT8_TO_STREAM (p, p_cfg->fcr.tx_win_sz); - UINT8_TO_STREAM (p, p_cfg->fcr.max_transmit); - UINT16_TO_STREAM (p, p_cfg->fcr.rtrans_tout); - UINT16_TO_STREAM (p, p_cfg->fcr.mon_tout); - UINT16_TO_STREAM (p, p_cfg->fcr.mps); + UINT8_TO_STREAM(p, L2CAP_CFG_TYPE_FLUSH_TOUT); + UINT8_TO_STREAM(p, L2CAP_CFG_FLUSH_OPTION_LEN); + UINT16_TO_STREAM(p, p_cfg->flush_to); } - if (p_cfg->fcs_present) + if (p_cfg->qos_present) { - UINT8_TO_STREAM (p, L2CAP_CFG_TYPE_FCS); - UINT8_TO_STREAM (p, L2CAP_CFG_FCS_OPTION_LEN); - UINT8_TO_STREAM (p, p_cfg->fcs); + UINT8_TO_STREAM(p, L2CAP_CFG_TYPE_QOS); + UINT8_TO_STREAM(p, L2CAP_CFG_QOS_OPTION_LEN); + UINT8_TO_STREAM(p, p_cfg->qos.qos_flags); + UINT8_TO_STREAM(p, p_cfg->qos.service_type); + UINT32_TO_STREAM(p, p_cfg->qos.token_rate); + UINT32_TO_STREAM(p, p_cfg->qos.token_bucket_size); + UINT32_TO_STREAM(p, p_cfg->qos.peak_bandwidth); + UINT32_TO_STREAM(p, p_cfg->qos.latency); + UINT32_TO_STREAM(p, p_cfg->qos.delay_variation); } - if (p_cfg->ext_flow_spec_present) + if (p_cfg->fcr_present) { - UINT8_TO_STREAM (p, L2CAP_CFG_TYPE_EXT_FLOW); - UINT8_TO_STREAM (p, L2CAP_CFG_EXT_FLOW_OPTION_LEN); - UINT8_TO_STREAM (p, p_cfg->ext_flow_spec.id); - UINT8_TO_STREAM (p, p_cfg->ext_flow_spec.stype); - UINT16_TO_STREAM (p, p_cfg->ext_flow_spec.max_sdu_size); - UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.sdu_inter_time); - UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.access_latency); - UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.flush_timeout); + UINT8_TO_STREAM(p, L2CAP_CFG_TYPE_FCR); + UINT8_TO_STREAM(p, L2CAP_CFG_FCR_OPTION_LEN); + UINT8_TO_STREAM(p, p_cfg->fcr.mode); + UINT8_TO_STREAM(p, p_cfg->fcr.tx_win_sz); + UINT8_TO_STREAM(p, p_cfg->fcr.max_transmit); + UINT16_TO_STREAM(p, p_cfg->fcr.rtrans_tout); + UINT16_TO_STREAM(p, p_cfg->fcr.mon_tout); + UINT16_TO_STREAM(p, p_cfg->fcr.mps); } - l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf); + l2c_link_check_send_pkts(p_ccb->p_lcb, NULL, p_buf); } -/******************************************************************************* -** -** Function l2cu_send_peer_config_rsp -** -** Description Build and send an L2CAP "configuration response" message -** to the peer. -** -** Returns void -** -*******************************************************************************/ -void l2cu_send_peer_config_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg) +void l2cu_send_peer_config_rsp(tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg) { - BT_HDR *p_buf; - UINT16 cfg_len = 0; - UINT8 *p; + BT_HDR *p_buf; + UINT16 cfg_len = 0; + UINT8 *p; - /* Create an identifier for this packet */ if (p_cfg->mtu_present) cfg_len += L2CAP_CFG_MTU_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD; + if (p_cfg->flush_to_present) cfg_len += L2CAP_CFG_FLUSH_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD; + if (p_cfg->qos_present) cfg_len += L2CAP_CFG_QOS_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD; + if (p_cfg->fcr_present) cfg_len += L2CAP_CFG_FCR_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD; - if (p_cfg->ext_flow_spec_present) - cfg_len += L2CAP_CFG_EXT_FLOW_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD; - if ((p_buf = l2cu_build_header (p_ccb->p_lcb, (UINT16)(L2CAP_CONFIG_RSP_LEN + cfg_len), - L2CAP_CMD_CONFIG_RSP, p_ccb->remote_id)) == NULL ) + if ((p_buf = l2cu_build_header(p_ccb->p_lcb->handle, + L2CAP_CONFIG_RSP_LEN + cfg_len, + L2CAP_CMD_CONFIG_RSP, p_ccb->remote_id)) + == NULL) { - L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for conn_req"); + L2CAP_TRACE(WARNING, "L2CAP - no buffer for conn_req"); return; } - p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET+HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; + p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; - UINT16_TO_STREAM (p, p_ccb->remote_cid); - UINT16_TO_STREAM (p, p_cfg->flags); /* Flags (continuation) Must match request */ - UINT16_TO_STREAM (p, p_cfg->result); + UINT16_TO_STREAM(p, p_ccb->remote_cid); + UINT16_TO_STREAM(p, 0); + UINT16_TO_STREAM(p, p_cfg->result); - /* Now, put the options */ if (p_cfg->mtu_present) { - UINT8_TO_STREAM (p, L2CAP_CFG_TYPE_MTU); - UINT8_TO_STREAM (p, L2CAP_CFG_MTU_OPTION_LEN); - UINT16_TO_STREAM (p, p_cfg->mtu); + UINT8_TO_STREAM(p, L2CAP_CFG_TYPE_MTU); + UINT8_TO_STREAM(p, L2CAP_CFG_MTU_OPTION_LEN); + UINT16_TO_STREAM(p, p_cfg->mtu); } + if (p_cfg->flush_to_present) { - UINT8_TO_STREAM (p, L2CAP_CFG_TYPE_FLUSH_TOUT); - UINT8_TO_STREAM (p, L2CAP_CFG_FLUSH_OPTION_LEN); - UINT16_TO_STREAM (p, p_cfg->flush_to); + UINT8_TO_STREAM(p, L2CAP_CFG_TYPE_FLUSH_TOUT); + UINT8_TO_STREAM(p, L2CAP_CFG_FLUSH_OPTION_LEN); + UINT16_TO_STREAM(p, p_cfg->flush_to); } + if (p_cfg->qos_present) { - UINT8_TO_STREAM (p, L2CAP_CFG_TYPE_QOS); - UINT8_TO_STREAM (p, L2CAP_CFG_QOS_OPTION_LEN); - UINT8_TO_STREAM (p, p_cfg->qos.qos_flags); - UINT8_TO_STREAM (p, p_cfg->qos.service_type); - UINT32_TO_STREAM (p, p_cfg->qos.token_rate); - UINT32_TO_STREAM (p, p_cfg->qos.token_bucket_size); - UINT32_TO_STREAM (p, p_cfg->qos.peak_bandwidth); - UINT32_TO_STREAM (p, p_cfg->qos.latency); - UINT32_TO_STREAM (p, p_cfg->qos.delay_variation); - } - if (p_cfg->fcr_present) - { - UINT8_TO_STREAM (p, L2CAP_CFG_TYPE_FCR); - UINT8_TO_STREAM (p, L2CAP_CFG_FCR_OPTION_LEN); - UINT8_TO_STREAM (p, p_cfg->fcr.mode); - UINT8_TO_STREAM (p, p_cfg->fcr.tx_win_sz); - UINT8_TO_STREAM (p, p_cfg->fcr.max_transmit); - UINT16_TO_STREAM (p, p_ccb->our_cfg.fcr.rtrans_tout); - UINT16_TO_STREAM (p, p_ccb->our_cfg.fcr.mon_tout); - UINT16_TO_STREAM (p, p_cfg->fcr.mps); + UINT8_TO_STREAM(p, L2CAP_CFG_TYPE_QOS); + UINT8_TO_STREAM(p, L2CAP_CFG_QOS_OPTION_LEN); + UINT8_TO_STREAM(p, p_cfg->qos.qos_flags); + UINT8_TO_STREAM(p, p_cfg->qos.service_type); + UINT32_TO_STREAM(p, p_cfg->qos.token_rate); + UINT32_TO_STREAM(p, p_cfg->qos.token_bucket_size); + UINT32_TO_STREAM(p, p_cfg->qos.peak_bandwidth); + UINT32_TO_STREAM(p, p_cfg->qos.latency); + UINT32_TO_STREAM(p, p_cfg->qos.delay_variation); } - if (p_cfg->ext_flow_spec_present) + if (p_cfg->fcr_present) { - UINT8_TO_STREAM (p, L2CAP_CFG_TYPE_EXT_FLOW); - UINT8_TO_STREAM (p, L2CAP_CFG_EXT_FLOW_OPTION_LEN); - UINT8_TO_STREAM (p, p_cfg->ext_flow_spec.id); - UINT8_TO_STREAM (p, p_cfg->ext_flow_spec.stype); - UINT16_TO_STREAM (p, p_cfg->ext_flow_spec.max_sdu_size); - UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.sdu_inter_time); - UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.access_latency); - UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.flush_timeout); + UINT8_TO_STREAM(p, L2CAP_CFG_TYPE_FCR); + UINT8_TO_STREAM(p, L2CAP_CFG_FCR_OPTION_LEN); + UINT8_TO_STREAM(p, p_cfg->fcr.mode); + UINT8_TO_STREAM(p, p_cfg->fcr.tx_win_sz); + UINT8_TO_STREAM(p, p_cfg->fcr.max_transmit); + UINT16_TO_STREAM(p, p_cfg->fcr.rtrans_tout); + UINT16_TO_STREAM(p, p_cfg->fcr.mon_tout); + UINT16_TO_STREAM(p, p_cfg->fcr.mps); } - l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf); + l2c_link_check_send_pkts(p_ccb->p_lcb, NULL, p_buf); } -/******************************************************************************* -** -** Function l2cu_send_peer_config_rej -** -** Description Build and send an L2CAP "configuration reject" message -** to the peer. -** -** Returns void -** -*******************************************************************************/ -void l2cu_send_peer_config_rej (tL2C_CCB *p_ccb, UINT8 *p_data, UINT16 data_len, UINT16 rej_len) +void l2cu_send_peer_config_rej(tL2C_CCB *p_ccb, UINT8 *p_data, UINT16 data_len, + UINT16 rej_len) { - BT_HDR *p_buf = (BT_HDR *)GKI_getpoolbuf (L2CAP_CMD_POOL_ID); - UINT16 len, cfg_len; - UINT8 *p, *p_hci_len, *p_data_end; - UINT8 cfg_code; + BT_HDR *p_buf = GKI_getpoolbuf(L2CAP_CMD_POOL_ID); + UINT16 len; + UINT16 cfg_len; + UINT8 *p; + UINT8 *p_hci_len; + UINT8 *p_data_end; + UINT8 cfg_code; if (!p_buf) { - L2CAP_TRACE_ERROR0 ("L2CAP - no buffer for cfg_rej"); + L2CAP_TRACE(WARNING, "L2CAP - no buffer for cfg_rej"); return; } p_buf->offset = L2CAP_SEND_CMD_OFFSET; p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET; - /* Put in HCI header - handle + pkt boundary */ -#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE) - if (HCI_NON_FLUSHABLE_PB_SUPPORTED(BTM_ReadLocalFeatures ())) - { - UINT16_TO_STREAM (p, (p_ccb->p_lcb->handle | (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT))); - } - else -#endif - { - UINT16_TO_STREAM (p, (p_ccb->p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT))); - } + UINT16_TO_STREAM(p, L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT + | p_ccb->p_lcb->handle); - /* Remember the HCI header length position, and save space for it */ p_hci_len = p; p += 2; - /* Put in L2CAP packet header */ - UINT16_TO_STREAM (p, L2CAP_CMD_OVERHEAD + L2CAP_CONFIG_RSP_LEN + rej_len); - UINT16_TO_STREAM (p, L2CAP_SIGNALLING_CID); + UINT16_TO_STREAM(p, L2CAP_CMD_OVERHEAD + L2CAP_CONFIG_RSP_LEN + rej_len); + UINT16_TO_STREAM(p, L2CAP_SIGNALLING_CID); - /* Put in L2CAP command header */ - UINT8_TO_STREAM (p, L2CAP_CMD_CONFIG_RSP); - UINT8_TO_STREAM (p, p_ccb->remote_id); + UINT8_TO_STREAM(p, L2CAP_CMD_CONFIG_RSP); + UINT8_TO_STREAM(p, p_ccb->remote_id); - UINT16_TO_STREAM (p, L2CAP_CONFIG_RSP_LEN + rej_len); + UINT16_TO_STREAM(p, L2CAP_CONFIG_RSP_LEN + rej_len); - UINT16_TO_STREAM (p, p_ccb->remote_cid); - UINT16_TO_STREAM (p, 0); /* Flags = 0 (no continuation) */ - UINT16_TO_STREAM (p, L2CAP_CFG_UNKNOWN_OPTIONS); + UINT16_TO_STREAM(p, p_ccb->remote_cid); + UINT16_TO_STREAM(p, 0); + UINT16_TO_STREAM(p, L2CAP_CFG_UNKNOWN_OPTIONS); - /* Now, put the rejected options */ p_data_end = p_data + data_len; while (p_data < p_data_end) { - cfg_code = *p_data; - cfg_len = *(p_data + 1); + cfg_code = p_data[0]; + cfg_len = p_data[1]; - switch (cfg_code & 0x7F) + switch (cfg_code & 0x7f) { - /* skip known options */ - case L2CAP_CFG_TYPE_MTU: - case L2CAP_CFG_TYPE_FLUSH_TOUT: - case L2CAP_CFG_TYPE_QOS: - p_data += cfg_len + L2CAP_CFG_OPTION_OVERHEAD; - break; + case L2CAP_CFG_TYPE_MTU: + case L2CAP_CFG_TYPE_FLUSH_TOUT: + case L2CAP_CFG_TYPE_QOS: + p_data += cfg_len + L2CAP_CFG_OPTION_OVERHEAD; + break; - /* unknown options; copy into rsp if not hints */ - default: - /* sanity check option length */ - if ((cfg_len + L2CAP_CFG_OPTION_OVERHEAD) <= data_len) - { - if ((cfg_code & 0x80) == 0) - { - memcpy(p, p_data, cfg_len + L2CAP_CFG_OPTION_OVERHEAD); - p += cfg_len + L2CAP_CFG_OPTION_OVERHEAD; - } - p_data += cfg_len + L2CAP_CFG_OPTION_OVERHEAD; - } - /* bad length; force loop exit */ - else + default: + if (cfg_len + L2CAP_CFG_OPTION_OVERHEAD <= data_len) + { + if (!(cfg_code & 0x80)) { - p_data = p_data_end; + memcpy(p, p_data, cfg_len + L2CAP_CFG_OPTION_OVERHEAD); + p += cfg_len + L2CAP_CFG_OPTION_OVERHEAD; } - break; + + p_data += cfg_len + L2CAP_CFG_OPTION_OVERHEAD; + } + else + { + p_data = p_data_end; + } + + break; } } - len = (UINT16) (p - p_hci_len - 2); - UINT16_TO_STREAM (p_hci_len, len); + len = p - p_hci_len - 2; + UINT16_TO_STREAM(p_hci_len, len); p_buf->len = len + 4; - l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf); + l2c_link_check_send_pkts(p_ccb->p_lcb, p_ccb, p_buf); } -/******************************************************************************* -** -** Function l2cu_send_peer_disc_req -** -** Description Build and send an L2CAP "disconnect request" message -** to the peer. -** -** Returns void -** -*******************************************************************************/ -void l2cu_send_peer_disc_req (tL2C_CCB *p_ccb) +void l2cu_send_peer_disc_req(tL2C_CCB *p_ccb) { - BT_HDR *p_buf, *p_buf2; - UINT8 *p; - - /* Create an identifier for this packet */ - p_ccb->p_lcb->id++; - l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID); + BT_HDR *p_buf; + UINT8 *p; - p_ccb->local_id = p_ccb->p_lcb->id; + p_ccb->local_id = ++p_ccb->p_lcb->id; - if ((p_buf = l2cu_build_header(p_ccb->p_lcb, L2CAP_DISC_REQ_LEN, L2CAP_CMD_DISC_REQ, p_ccb->local_id)) == NULL) + if ((p_buf = l2cu_build_header(p_ccb->p_lcb->handle, L2CAP_DISC_REQ_LEN, + L2CAP_CMD_DISC_REQ, p_ccb->local_id)) + == NULL) { - L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for disc_req"); + L2CAP_TRACE(WARNING, "L2CAP - no buffer for conn_req"); return; } - p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; + p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; - UINT16_TO_STREAM (p, p_ccb->remote_cid); - UINT16_TO_STREAM (p, p_ccb->local_cid); + UINT16_TO_STREAM(p, p_ccb->remote_cid); + UINT16_TO_STREAM(p, p_ccb->local_cid); - /* Move all queued data packets to the LCB. In FCR mode, assume the higher - layer checks that all buffers are sent before disconnecting. - */ - if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_BASIC_MODE) - { - while (p_ccb->xmit_hold_q.p_first) - { - p_buf2 = (BT_HDR *)GKI_dequeue (&p_ccb->xmit_hold_q); - l2cu_set_acl_hci_header (p_buf2, p_ccb); - l2c_link_check_send_pkts (p_ccb->p_lcb, p_ccb, p_buf2); - } - } + p_buf->layer_specific = 0; + GKI_enqueue(&p_ccb->p_lcb->link_xmit_data_q, p_buf); - l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf); + l2c_link_check_send_pkts(p_ccb->p_lcb, NULL, NULL); } - -/******************************************************************************* -** -** Function l2cu_send_peer_disc_rsp -** -** Description Build and send an L2CAP "disconnect response" message -** to the peer. -** -** This function is passed the parameters for the disconnect -** response instead of the CCB address, as it may be called -** to send a disconnect response when there is no CCB. -** -** Returns void -** -*******************************************************************************/ -void l2cu_send_peer_disc_rsp (tL2C_LCB *p_lcb, UINT8 remote_id, UINT16 local_cid, - UINT16 remote_cid) +void l2cu_send_peer_disc_rsp(tL2C_LCB *p_lcb, UINT8 remote_id, UINT16 local_cid, + UINT16 remote_cid) { - BT_HDR *p_buf; - UINT8 *p; + BT_HDR *p_buf; + UINT8 *p; - if ((p_buf=l2cu_build_header(p_lcb, L2CAP_DISC_RSP_LEN, L2CAP_CMD_DISC_RSP, remote_id)) == NULL) + if ((p_buf = l2cu_build_header(p_lcb->handle, L2CAP_DISC_RSP_LEN, + L2CAP_CMD_DISC_RSP, remote_id)) + == NULL) { - L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for disc_rsp"); + L2CAP_TRACE(WARNING, "L2CAP - no buffer for conn_req"); return; } - p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; + p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; - UINT16_TO_STREAM (p, local_cid); - UINT16_TO_STREAM (p, remote_cid); + UINT16_TO_STREAM(p, local_cid); + UINT16_TO_STREAM(p, remote_cid); - l2c_link_check_send_pkts (p_lcb, NULL, p_buf); -} + p_buf->layer_specific = 0; + GKI_enqueue(&p_lcb->link_xmit_data_q, p_buf); + l2c_link_check_send_pkts(p_lcb, NULL, NULL); +} -/******************************************************************************* -** -** Function l2cu_send_peer_echo_req -** -** Description Build and send an L2CAP "echo request" message -** to the peer. Note that we do not currently allow -** data in the echo request. -** -** Returns void -** -*******************************************************************************/ -void l2cu_send_peer_echo_req (tL2C_LCB *p_lcb, UINT8 *p_data, UINT16 data_len) +void l2cu_send_peer_echo_req(tL2C_LCB *p_lcb, UINT8 *p_data, UINT16 data_len) { - BT_HDR *p_buf; - UINT8 *p; - - p_lcb->id++; - l2cu_adj_id(p_lcb, L2CAP_ADJ_ZERO_ID); /* check for wrap to '0' */ + BT_HDR *p_buf; + UINT8 *p; - if ((p_buf = l2cu_build_header(p_lcb, (UINT16) (L2CAP_ECHO_REQ_LEN + data_len), L2CAP_CMD_ECHO_REQ, p_lcb->id)) == NULL) + if ((p_buf = l2cu_build_header(p_lcb->handle, L2CAP_ECHO_REQ_LEN + data_len, + L2CAP_CMD_ECHO_REQ, ++p_lcb->id)) + == NULL) { - L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for echo_req"); + L2CAP_TRACE(WARNING, "L2CAP - no buffer for echo_req"); return; } - p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; + p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; if (data_len) - { - ARRAY_TO_STREAM (p, p_data, data_len); - } + ARRAY_TO_STREAM(p, p_data, data_len); - l2c_link_check_send_pkts (p_lcb, NULL, p_buf); + l2c_link_check_send_pkts(p_lcb, NULL, p_buf); } - -/******************************************************************************* -** -** Function l2cu_send_peer_echo_rsp -** -** Description Build and send an L2CAP "echo response" message -** to the peer. -** -** Returns void -** -*******************************************************************************/ -void l2cu_send_peer_echo_rsp (tL2C_LCB *p_lcb, UINT8 id, UINT8 *p_data, UINT16 data_len) +void l2cu_send_peer_echo_rsp(tL2C_LCB *p_lcb, UINT8 id, UINT8 *p_data, + UINT16 data_len) { - BT_HDR *p_buf; - UINT8 *p; - UINT16 maxlen; + BT_HDR *p_buf; + UINT8 *p; + UINT16 maxlen; - /* Don't return data if it does not fit in ACL and L2CAP MTU */ - maxlen = (GKI_get_pool_bufsize(L2CAP_CMD_POOL_ID) > btu_cb.hcit_acl_pkt_size) ? - btu_cb.hcit_acl_data_size : (UINT16)GKI_get_pool_bufsize(L2CAP_CMD_POOL_ID); - maxlen -= (UINT16)(BT_HDR_SIZE + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + - L2CAP_CMD_OVERHEAD + L2CAP_ECHO_RSP_LEN); + maxlen = GKI_BUF2_SIZE > btu_cb.hcit_acl_pkt_size + ? btu_cb.hcit_acl_data_size + : GKI_BUF2_SIZE; + maxlen -= (UINT16)(HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + + L2CAP_CMD_OVERHEAD + L2CAP_ECHO_RSP_LEN); if (data_len > maxlen) data_len = 0; - if ((p_buf = l2cu_build_header (p_lcb, (UINT16)(L2CAP_ECHO_RSP_LEN + data_len), L2CAP_CMD_ECHO_RSP, id)) == NULL) + if ((p_buf = l2cu_build_header(p_lcb->handle, L2CAP_ECHO_RSP_LEN + data_len, + L2CAP_CMD_ECHO_RSP, id)) + == NULL) { - L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for echo_rsp"); + L2CAP_TRACE(WARNING, "L2CAP - no buffer for conn_req"); return; } - p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + - L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; + p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; if (data_len) - { - ARRAY_TO_STREAM (p, p_data, data_len); - } + ARRAY_TO_STREAM(p, p_data, data_len); - l2c_link_check_send_pkts (p_lcb, NULL, p_buf); + l2c_link_check_send_pkts(p_lcb, NULL, p_buf); } -/******************************************************************************* -** -** Function l2cu_send_peer_info_req -** -** Description Build and send an L2CAP "info request" message -** to the peer. -** Returns void -** -*******************************************************************************/ -void l2cu_send_peer_info_req (tL2C_LCB *p_lcb, UINT16 info_type) -{ - BT_HDR *p_buf; - UINT8 *p; - /* check for wrap and/or BRCM ID */ - p_lcb->id++; - l2cu_adj_id(p_lcb, L2CAP_ADJ_ID); +void l2cu_send_peer_info_rsp(tL2C_LCB *p_lcb, UINT8 remote_id, UINT16 info_type) +{ + BT_HDR *p_buf; + UINT8 *p; + UINT16 len = L2CAP_INFO_RSP_LEN; - if ((p_buf = l2cu_build_header(p_lcb, 2, L2CAP_CMD_INFO_REQ, p_lcb->id)) == NULL) + if ((p_buf = l2cu_build_header(p_lcb->handle, len, L2CAP_CMD_INFO_RSP, + remote_id)) + == NULL) { - L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for info_req"); + L2CAP_TRACE(WARNING, "L2CAP - no buffer for conn_req"); return; } - L2CAP_TRACE_EVENT1 ("l2cu_send_peer_info_req: type 0x%04x", info_type); - - p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET+HCI_DATA_PREAMBLE_SIZE + - L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; + p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; - UINT16_TO_STREAM (p, info_type); + UINT16_TO_STREAM(p, info_type); - p_lcb->w4_info_rsp = TRUE; - btu_start_timer (&p_lcb->info_timer_entry, BTU_TTYPE_L2CAP_INFO, L2CAP_WAIT_INFO_RSP_TOUT); + UINT16_TO_STREAM(p, L2CAP_INFO_RESP_RESULT_NOT_SUPPORTED); - l2c_link_check_send_pkts (p_lcb, NULL, p_buf); + l2c_link_check_send_pkts(p_lcb, NULL, p_buf); } - -/******************************************************************************* -** -** Function l2cu_send_peer_info_rsp -** -** Description Build and send an L2CAP "info response" message -** to the peer. -** -** Returns void -** -*******************************************************************************/ -void l2cu_send_peer_info_rsp (tL2C_LCB *p_lcb, UINT8 remote_id, UINT16 info_type) +tL2C_CCB *l2cu_allocate_ccb(tL2C_LCB *p_lcb) { - BT_HDR *p_buf; - UINT8 *p; - UINT16 len = L2CAP_INFO_RSP_LEN; - -#if (L2CAP_CONFORMANCE_TESTING == TRUE) - if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE) - && (l2cb.test_info_resp & (L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE | - L2CAP_EXTFEA_NO_CRC | L2CAP_EXTFEA_EXT_FLOW_SPEC | - L2CAP_EXTFEA_FIXED_CHNLS | L2CAP_EXTFEA_EXT_WINDOW | - L2CAP_EXTFEA_UCD_RECEPTION )) ) -#else - if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE) - && (L2CAP_EXTFEA_SUPPORTED_MASK & (L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE | - L2CAP_EXTFEA_NO_CRC |L2CAP_EXTFEA_FIXED_CHNLS | - L2CAP_EXTFEA_UCD_RECEPTION )) ) -#endif - { - len += L2CAP_EXTENDED_FEATURES_ARRAY_SIZE; - } - else if (info_type == L2CAP_FIXED_CHANNELS_INFO_TYPE) - { - len += L2CAP_FIXED_CHNL_ARRAY_SIZE; - } - else if (info_type == L2CAP_CONNLESS_MTU_INFO_TYPE) - { - len += L2CAP_CONNLESS_MTU_INFO_SIZE; - } - - if ((p_buf = l2cu_build_header(p_lcb, len, L2CAP_CMD_INFO_RSP, remote_id)) == NULL) - { - L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for info_rsp"); - return; - } + tL2C_CCB *p_ccb; - p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + - L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; + if (!l2cb.p_free_ccb_first) + return NULL; - UINT16_TO_STREAM (p, info_type); + p_ccb = l2cb.p_free_ccb_first; -#if (L2CAP_CONFORMANCE_TESTING == TRUE) - if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE) - && (l2cb.test_info_resp & ( L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE - | L2CAP_EXTFEA_UCD_RECEPTION )) ) -#else - if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE) - && (L2CAP_EXTFEA_SUPPORTED_MASK & ( L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE - | L2CAP_EXTFEA_UCD_RECEPTION )) ) -#endif - { - UINT16_TO_STREAM (p, L2CAP_INFO_RESP_RESULT_SUCCESS); -#if (BLE_INCLUDED == TRUE) - if (p_lcb->is_ble_link) - { - /* optional data are not added for now */ - UINT32_TO_STREAM (p, L2CAP_BLE_EXTFEA_MASK); - } - else -#endif - { -#if L2CAP_CONFORMANCE_TESTING == TRUE - UINT32_TO_STREAM (p, l2cb.test_info_resp); -#else -#if (L2CAP_NUM_FIXED_CHNLS > 0) - UINT32_TO_STREAM (p, L2CAP_EXTFEA_SUPPORTED_MASK | L2CAP_EXTFEA_FIXED_CHNLS); -#else - UINT32_TO_STREAM (p, L2CAP_EXTFEA_SUPPORTED_MASK); -#endif -#endif - } - } - else if (info_type == L2CAP_FIXED_CHANNELS_INFO_TYPE) - { - UINT16_TO_STREAM (p, L2CAP_INFO_RESP_RESULT_SUCCESS); - memset (p, 0, L2CAP_FIXED_CHNL_ARRAY_SIZE); + l2cb.p_free_ccb_first = p_ccb->p_next_ccb; - p[0] = L2CAP_FIXED_CHNL_SIG_BIT; + p_ccb->in_use = TRUE; - if ( L2CAP_EXTFEA_SUPPORTED_MASK & L2CAP_EXTFEA_UCD_RECEPTION ) - p[0] |= L2CAP_FIXED_CHNL_CNCTLESS_BIT; + p_ccb->local_cid = L2CAP_BASE_APPL_CID + (UINT16)(p_ccb - l2cb.ccb_pool); -#if (L2CAP_NUM_FIXED_CHNLS > 0) - { - int xx; + p_ccb->p_lcb = p_lcb; - for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) - if (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL) - p[0] |= 1 << (xx + L2CAP_FIRST_FIXED_CHNL); - } -#endif - } - else if (info_type == L2CAP_CONNLESS_MTU_INFO_TYPE) + if (!p_lcb->p_first_ccb) { - UINT16_TO_STREAM (p, L2CAP_INFO_RESP_RESULT_SUCCESS); - UINT16_TO_STREAM (p, L2CAP_UCD_MTU); + p_lcb->p_first_ccb = p_lcb->p_last_ccb = p_ccb; + p_ccb->p_next_ccb = NULL; + p_ccb->p_prev_ccb = NULL; } else { - UINT16_TO_STREAM (p, L2CAP_INFO_RESP_RESULT_NOT_SUPPORTED); /* 'not supported' */ - } + p_ccb->p_next_ccb = NULL; + p_ccb->p_prev_ccb = p_lcb->p_last_ccb; + p_lcb->p_last_ccb->p_next_ccb = p_ccb; + p_lcb->p_last_ccb = p_ccb; + } + + p_ccb->our_flush_to = 0xffff; + p_ccb->in_mtu = p_ccb->out_mtu = 672; + p_ccb->in_flow.service_type = p_ccb->out_flow.service_type = 1; + p_ccb->in_flow.token_rate = p_ccb->out_flow.token_rate = 0; + p_ccb->in_flow.token_bucket_size = p_ccb->out_flow.token_bucket_size = 0; + p_ccb->in_flow.peak_bandwidth = p_ccb->out_flow.peak_bandwidth = 0; + p_ccb->in_flow.latency = p_ccb->out_flow.latency = 0xffffffff; + p_ccb->in_flow.delay_variation = p_ccb->out_flow.delay_variation = + 0xffffffff; + + p_ccb->config_done = 0; + p_ccb->chnl_state = CST_CLOSED; + p_ccb->rtry_flag = 1; + p_ccb->timer_entry.param = (TIMER_PARAM_TYPE)p_ccb; - l2c_link_check_send_pkts (p_lcb, NULL, p_buf); + return p_ccb; } -/****************************************************************************** -** -** Function l2cu_enqueue_ccb -** -** Description queue CCB by priority. The first CCB is highest priority and -** is served at first. The CCB is queued to an LLCB or an LCB. -** -** Returns None -** -*******************************************************************************/ -void l2cu_enqueue_ccb (tL2C_CCB *p_ccb) +void l2cu_release_ccb(tL2C_CCB *p_ccb) { - tL2C_CCB *p_ccb1; - tL2C_CCB_Q *p_q = NULL; + tL2C_LCB *p_lcb = p_ccb->p_lcb; + UINT16 timeout; + tBTM_STATUS rc; + BT_HDR *p_buf; + + if (!p_ccb->in_use) + return; + + p_ccb->in_use = FALSE; - /* Find out which queue the channel is on - */ - if (p_ccb->p_lcb != NULL) - p_q = &p_ccb->p_lcb->ccb_queue; + btu_stop_timer(&p_ccb->timer_entry); - if ( (!p_ccb->in_use) || (p_q == NULL) ) + while (p_ccb->xmit_hold_q.p_first) { - L2CAP_TRACE_ERROR3 ("l2cu_enqueue_ccb CID: 0x%04x ERROR in_use: %u p_lcb: 0x%08x", - p_ccb->local_cid, p_ccb->in_use, p_ccb->p_lcb); - return; + p_buf = GKI_dequeue(&p_ccb->xmit_hold_q); + GKI_freebuf(p_buf); } - L2CAP_TRACE_DEBUG2 ("l2cu_enqueue_ccb CID: 0x%04x priority: %d", - p_ccb->local_cid, p_ccb->ccb_priority); + p_ccb->p_lcb = NULL; - /* If the queue is empty, we go at the front */ - if (!p_q->p_first_ccb) + if (p_lcb->p_first_ccb == p_ccb) + { + p_lcb->p_first_ccb = p_ccb->p_next_ccb; + if (p_lcb->p_first_ccb) + p_lcb->p_first_ccb->p_prev_ccb = NULL; + } + else if (p_lcb->p_last_ccb == p_ccb) { - p_q->p_first_ccb = p_q->p_last_ccb = p_ccb; - p_ccb->p_next_ccb = p_ccb->p_prev_ccb = NULL; + p_lcb->p_last_ccb = p_ccb->p_prev_ccb; + p_lcb->p_last_ccb->p_next_ccb = NULL; } else { - p_ccb1 = p_q->p_first_ccb; - - while (p_ccb1 != NULL) - { - /* Insert new ccb at the end of the same priority. Lower number, higher priority */ - if (p_ccb->ccb_priority < p_ccb1->ccb_priority) - { - /* Are we at the head of the queue ? */ - if (p_ccb1 == p_q->p_first_ccb) - p_q->p_first_ccb = p_ccb; - else - p_ccb1->p_prev_ccb->p_next_ccb = p_ccb; - - p_ccb->p_next_ccb = p_ccb1; - p_ccb->p_prev_ccb = p_ccb1->p_prev_ccb; - p_ccb1->p_prev_ccb = p_ccb; - break; - } - - p_ccb1 = p_ccb1->p_next_ccb; - } - - /* If we are lower then anyone in the list, we go at the end */ - if (!p_ccb1) - { - /* add new ccb at the end of the list */ - p_q->p_last_ccb->p_next_ccb = p_ccb; - - p_ccb->p_next_ccb = NULL; - p_ccb->p_prev_ccb = p_q->p_last_ccb; - p_q->p_last_ccb = p_ccb; - } + p_ccb->p_prev_ccb->p_next_ccb = p_ccb->p_next_ccb; + p_ccb->p_next_ccb->p_prev_ccb = p_ccb->p_prev_ccb; } -#if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) - /* Adding CCB into round robin service table of its LCB */ - if (p_ccb->p_lcb != NULL) + if (!l2cb.p_free_ccb_first) { - /* if this is the first channel in this priority group */ - if (p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb == 0 ) - { - /* Set the first channel to this CCB */ - p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = p_ccb; - /* Set the next serving channel in this group to this CCB */ - p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = p_ccb; - /* Initialize quota of this priority group based on its priority */ - p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].quota = L2CAP_GET_PRIORITY_QUOTA(p_ccb->ccb_priority); - } - /* increase number of channels in this group */ - p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb++; + l2cb.p_free_ccb_first = p_ccb; + l2cb.p_free_ccb_last = p_ccb; + p_ccb->p_next_ccb = NULL; + p_ccb->p_prev_ccb = NULL; + } + else + { + p_ccb->p_next_ccb = NULL; + p_ccb->p_prev_ccb = l2cb.p_free_ccb_last; + l2cb.p_free_ccb_last->p_next_ccb = p_ccb; + l2cb.p_free_ccb_last = p_ccb; } -#endif - -} - -/****************************************************************************** -** -** Function l2cu_dequeue_ccb -** -** Description dequeue CCB from a queue -** -** Returns - -** -*******************************************************************************/ -void l2cu_dequeue_ccb (tL2C_CCB *p_ccb) -{ - tL2C_CCB_Q *p_q = NULL; - L2CAP_TRACE_DEBUG1 ("l2cu_dequeue_ccb CID: 0x%04x", p_ccb->local_cid); + if (!p_lcb->in_use) + return; - /* Find out which queue the channel is on - */ - if (p_ccb->p_lcb != NULL) - p_q = &p_ccb->p_lcb->ccb_queue; + if (p_lcb->link_state != LST_CONNECTED) + return; - if ( (!p_ccb->in_use) || (p_q == NULL) || (p_q->p_first_ccb == NULL) ) - { - L2CAP_TRACE_ERROR5 ("l2cu_dequeue_ccb CID: 0x%04x ERROR in_use: %u p_lcb: 0x%08x p_q: 0x%08x p_q->p_first_ccb: 0x%08x", - p_ccb->local_cid, p_ccb->in_use, p_ccb->p_lcb, p_q, p_q ? p_q->p_first_ccb : 0); + if (p_lcb->p_first_ccb) return; - } -#if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) - /* Removing CCB from round robin service table of its LCB */ - if (p_ccb->p_lcb != NULL) + if (!p_lcb->idle_timeout) { - /* decrease number of channels in this priority group */ - p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb--; + rc = btm_sec_disconnect(p_lcb->handle, HCI_ERR_PEER_USER); - /* if it was the last channel in the priority group */ - if (p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb == 0 ) + if (rc == BTM_CMD_STARTED) { - p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = NULL; - p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = NULL; + p_lcb->link_state = LST_DISCONNECTING; + timeout = 30; } - else + else if (rc == BTM_SUCCESS) { - /* if it is the first channel of this group */ - if ( p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb == p_ccb ) - { - p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = p_ccb->p_next_ccb; - } - /* if it is the next serving channel of this group */ - if ( p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb == p_ccb ) - { - /* simply, start serving from the first channel */ - p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb - = p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb; - } + p_lcb->link_state = LST_DISCONNECTING; + timeout = 0xffff; } - } -#endif - - if (p_ccb == p_q->p_first_ccb) - { - /* We are removing the first in a queue */ - p_q->p_first_ccb = p_ccb->p_next_ccb; - - if (p_q->p_first_ccb) - p_q->p_first_ccb->p_prev_ccb = NULL; else - p_q->p_last_ccb = NULL; - } - else if (p_ccb == p_q->p_last_ccb) - { - /* We are removing the last in a queue */ - p_q->p_last_ccb = p_ccb->p_prev_ccb; - p_q->p_last_ccb->p_next_ccb = NULL; + { + timeout = 1; + } } else { - /* In the middle of a chain. */ - p_ccb->p_prev_ccb->p_next_ccb = p_ccb->p_next_ccb; - p_ccb->p_next_ccb->p_prev_ccb = p_ccb->p_prev_ccb; + timeout = p_lcb->idle_timeout; } - p_ccb->p_next_ccb = p_ccb->p_prev_ccb = NULL; + if (timeout != 0xffff) + btu_start_timer(&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, timeout); } -/****************************************************************************** -** -** Function l2cu_change_pri_ccb -** -** Description -** -** Returns - -** -*******************************************************************************/ -void l2cu_change_pri_ccb (tL2C_CCB *p_ccb, tL2CAP_CHNL_PRIORITY priority) +tL2C_CCB *l2cu_find_ccb_by_cid(tL2C_LCB *p_lcb, UINT16 local_cid) { - if (p_ccb->ccb_priority != priority) + tL2C_CCB *p_ccb = NULL; + + if (local_cid >= L2CAP_BASE_APPL_CID) { - /* If CCB is not the only guy on the queue */ - if ( (p_ccb->p_next_ccb != NULL) || (p_ccb->p_prev_ccb != NULL) ) - { - L2CAP_TRACE_DEBUG0 ("Update CCB list in logical link"); + local_cid -= L2CAP_BASE_APPL_CID; - /* Remove CCB from queue and re-queue it at new priority */ - l2cu_dequeue_ccb (p_ccb); + p_ccb = l2cb.ccb_pool + local_cid; - p_ccb->ccb_priority = priority; - l2cu_enqueue_ccb (p_ccb); - } -#if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) - else + if (!p_ccb->in_use) + p_ccb = NULL; + else if (p_lcb && p_lcb != p_ccb->p_lcb) + p_ccb = NULL; + } + + return p_ccb; +} + + +tL2C_RCB *l2cu_allocate_rcb(UINT16 psm) +{ + tL2C_RCB *p_rcb = l2cb.rcb_pool; + UINT16 xx; + + /* explicitly post-increment */ + for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++) + { + if (!p_rcb->in_use) { - /* If CCB is the only guy on the queue, no need to re-enqueue */ - /* update only round robin service data */ - p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb = 0; - p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = NULL; - p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = NULL; - - p_ccb->ccb_priority = priority; - - p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = p_ccb; - p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = p_ccb; - p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].quota = L2CAP_GET_PRIORITY_QUOTA(p_ccb->ccb_priority); - p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb = 1; + p_rcb->in_use = TRUE; + p_rcb->psm = psm; + + return p_rcb; } -#endif } + + return NULL; } -/******************************************************************************* -** -** Function l2cu_allocate_ccb -** -** Description This function allocates a Channel Control Block and -** attaches it to a link control block. The local CID -** is also assigned. -** -** Returns pointer to CCB, or NULL if none -** -*******************************************************************************/ -tL2C_CCB *l2cu_allocate_ccb (tL2C_LCB *p_lcb, UINT16 cid) +void l2cu_release_rcb(tL2C_RCB *p_rcb) { - tL2C_CCB *p_ccb; - tL2C_CCB *p_prev; - - L2CAP_TRACE_DEBUG1 ("l2cu_allocate_ccb: cid 0x%04x", cid); + p_rcb->in_use = FALSE; + p_rcb->psm = 0; +} - if (!l2cb.p_free_ccb_first) - return (NULL); +tL2C_RCB *l2cu_find_rcb_by_psm(UINT16 psm) +{ + tL2C_RCB *p_rcb = l2cb.rcb_pool; + UINT16 xx; - /* If a CID was passed in, use that, else take the first free one */ - if (cid == 0) + /* explicitly post-increment */ + for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++) { - p_ccb = l2cb.p_free_ccb_first; - l2cb.p_free_ccb_first = p_ccb->p_next_ccb; - } - else - { - p_prev = NULL; - - p_ccb = &l2cb.ccb_pool[cid - L2CAP_BASE_APPL_CID]; - - if (p_ccb == l2cb.p_free_ccb_first) - l2cb.p_free_ccb_first = p_ccb->p_next_ccb; - else - { - for (p_prev = l2cb.p_free_ccb_first; p_prev != NULL; p_prev = p_prev->p_next_ccb) - { - if (p_prev->p_next_ccb == p_ccb) - { - p_prev->p_next_ccb = p_ccb->p_next_ccb; - - if (p_ccb == l2cb.p_free_ccb_last) - l2cb.p_free_ccb_last = p_prev; - - break; - } - } - if (p_prev == NULL) - { - L2CAP_TRACE_ERROR1 ("l2cu_allocate_ccb: could not find CCB for CID 0x%04x in the free list", cid); - return NULL; - } - } - } - - p_ccb->p_next_ccb = p_ccb->p_prev_ccb = NULL; - - p_ccb->in_use = TRUE; - - /* Get a CID for the connection */ - p_ccb->local_cid = L2CAP_BASE_APPL_CID + (UINT16)(p_ccb - l2cb.ccb_pool); - - p_ccb->p_lcb = p_lcb; - p_ccb->p_rcb = NULL; - - /* Set priority then insert ccb into LCB queue (if we have an LCB) */ - p_ccb->ccb_priority = L2CAP_CHNL_PRIORITY_LOW; - - if (p_lcb) - l2cu_enqueue_ccb (p_ccb); - - /* clear what peer wants to configure */ - p_ccb->peer_cfg_bits = 0; - - /* Put in default values for configuration */ - memset (&p_ccb->our_cfg, 0, sizeof(tL2CAP_CFG_INFO)); - memset (&p_ccb->peer_cfg, 0, sizeof(tL2CAP_CFG_INFO)); - - /* Put in default values for local/peer configurations */ - p_ccb->our_cfg.flush_to = p_ccb->peer_cfg.flush_to = L2CAP_DEFAULT_FLUSH_TO; - p_ccb->our_cfg.mtu = p_ccb->peer_cfg.mtu = L2CAP_DEFAULT_MTU; - p_ccb->our_cfg.qos.service_type = p_ccb->peer_cfg.qos.service_type = L2CAP_DEFAULT_SERV_TYPE; - p_ccb->our_cfg.qos.token_rate = p_ccb->peer_cfg.qos.token_rate = L2CAP_DEFAULT_TOKEN_RATE; - p_ccb->our_cfg.qos.token_bucket_size = p_ccb->peer_cfg.qos.token_bucket_size = L2CAP_DEFAULT_BUCKET_SIZE; - p_ccb->our_cfg.qos.peak_bandwidth = p_ccb->peer_cfg.qos.peak_bandwidth = L2CAP_DEFAULT_PEAK_BANDWIDTH; - p_ccb->our_cfg.qos.latency = p_ccb->peer_cfg.qos.latency = L2CAP_DEFAULT_LATENCY; - p_ccb->our_cfg.qos.delay_variation = p_ccb->peer_cfg.qos.delay_variation = L2CAP_DEFAULT_DELAY; - - p_ccb->bypass_fcs = 0; - memset (&p_ccb->ertm_info, 0, sizeof(tL2CAP_ERTM_INFO)); - p_ccb->peer_cfg_already_rejected = FALSE; - p_ccb->fcr_cfg_tries = L2CAP_MAX_FCR_CFG_TRIES; - p_ccb->fcrb.ack_timer.param = (TIMER_PARAM_TYPE)p_ccb; - - /* if timer is running, remove it from timer list */ - if (p_ccb->fcrb.ack_timer.in_use) - btu_stop_quick_timer (&p_ccb->fcrb.ack_timer); - - p_ccb->fcrb.mon_retrans_timer.param = (TIMER_PARAM_TYPE)p_ccb; - -// btla-specific ++ - /* CSP408639 Fix: When L2CAP send amp move channel request or receive - * L2CEVT_AMP_MOVE_REQ do following sequence. Send channel move - * request -> Stop retrans/monitor timer -> Change channel state to CST_AMP_MOVING. */ - if (p_ccb->fcrb.mon_retrans_timer.in_use) - btu_stop_quick_timer (&p_ccb->fcrb.mon_retrans_timer); -// btla-specific -- - - l2c_fcr_stop_timer (p_ccb); - - p_ccb->ertm_info.preferred_mode = L2CAP_FCR_BASIC_MODE; /* Default mode for channel is basic mode */ - p_ccb->ertm_info.allowed_modes = L2CAP_FCR_CHAN_OPT_BASIC; /* Default mode for channel is basic mode */ - p_ccb->ertm_info.fcr_rx_pool_id = L2CAP_FCR_RX_POOL_ID; - p_ccb->ertm_info.fcr_tx_pool_id = L2CAP_FCR_TX_POOL_ID; - p_ccb->ertm_info.user_rx_pool_id = HCI_ACL_POOL_ID; - p_ccb->ertm_info.user_tx_pool_id = HCI_ACL_POOL_ID; - p_ccb->max_rx_mtu = L2CAP_MTU_SIZE; - p_ccb->tx_mps = GKI_get_pool_bufsize(HCI_ACL_POOL_ID) - 32; - - GKI_init_q (&p_ccb->xmit_hold_q); - - p_ccb->cong_sent = FALSE; - p_ccb->buff_quota = 2; /* This gets set after config */ - - /* If CCB was reserved Config_Done can already have some value */ - if (cid == 0) - p_ccb->config_done = 0; - else - { - L2CAP_TRACE_DEBUG2 ("l2cu_allocate_ccb: cid 0x%04x config_done:0x%x", cid, p_ccb->config_done); - } - - p_ccb->chnl_state = CST_CLOSED; - p_ccb->flags = 0; - p_ccb->tx_data_rate = L2CAP_CHNL_DATA_RATE_LOW; - p_ccb->rx_data_rate = L2CAP_CHNL_DATA_RATE_LOW; - -#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE) - p_ccb->is_flushable = FALSE; -#endif - - p_ccb->timer_entry.param = (TIMER_PARAM_TYPE)p_ccb; - p_ccb->timer_entry.in_use = 0; - - l2c_link_adjust_chnl_allocation (); - - return (p_ccb); -} - -/******************************************************************************* -** -** Function l2cu_start_post_bond_timer -** -** Description This function starts the ACL Link inactivity timer after -** dedicated bonding -** This timer can be longer than the normal link inactivity -** timer for some platforms. -** -** Returns BOOLEAN - TRUE if idle timer started or disconnect initiated -** FALSE if there's one or more pending CCB's exist -** -*******************************************************************************/ -BOOLEAN l2cu_start_post_bond_timer (UINT16 handle) -{ - UINT16 timeout; - tL2C_LCB *p_lcb = l2cu_find_lcb_by_handle(handle); - - if (!p_lcb) - return (TRUE); - - p_lcb->is_bonding = FALSE; - - /* Only start timer if no control blocks allocated */ - if (p_lcb->ccb_queue.p_first_ccb != NULL) - return (FALSE); - - /* If no channels on the connection, start idle timeout */ - if ( (p_lcb->link_state == LST_CONNECTED) || (p_lcb->link_state == LST_CONNECTING) || (p_lcb->link_state == LST_DISCONNECTING) ) - { - if (p_lcb->idle_timeout == 0) - { - if (btsnd_hcic_disconnect (p_lcb->handle, HCI_ERR_PEER_USER)) - { - p_lcb->link_state = LST_DISCONNECTING; - timeout = L2CAP_LINK_DISCONNECT_TOUT; - } - else - timeout = BT_1SEC_TIMEOUT; - } - else - { - timeout = L2CAP_BONDING_TIMEOUT; - } - - if (timeout != 0xFFFF) - btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, timeout); - - return (TRUE); - } - - return (FALSE); -} - -/******************************************************************************* -** -** Function l2cu_release_ccb -** -** Description This function releases a Channel Control Block. The timer -** is stopped, any attached buffers freed, and the CCB is removed -** from the link control block. -** -** Returns void -** -*******************************************************************************/ -void l2cu_release_ccb (tL2C_CCB *p_ccb) -{ - tL2C_LCB *p_lcb = p_ccb->p_lcb; - tL2C_RCB *p_rcb = p_ccb->p_rcb; - - L2CAP_TRACE_DEBUG2 ("l2cu_release_ccb: cid 0x%04x in_use: %u", p_ccb->local_cid, p_ccb->in_use); - - /* If already released, could be race condition */ - if (!p_ccb->in_use) - return; - - if (p_rcb && (p_rcb->psm != p_rcb->real_psm)) - { - btm_sec_clr_service_by_psm(p_rcb->psm); - } - /* Stop the timer */ - btu_stop_timer (&p_ccb->timer_entry); - - while (p_ccb->xmit_hold_q.p_first) - GKI_freebuf (GKI_dequeue (&p_ccb->xmit_hold_q)); - - l2c_fcr_cleanup (p_ccb); - - /* Channel may not be assigned to any LCB if it was just pre-reserved */ - if ( (p_lcb) && - ( (p_ccb->local_cid >= L2CAP_BASE_APPL_CID) -#if (L2CAP_UCD_INCLUDED == TRUE) - ||(p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID) -#endif - ) - ) - { - l2cu_dequeue_ccb (p_ccb); - - /* Delink the CCB from the LCB */ - p_ccb->p_lcb = NULL; - } - - /* Put the CCB back on the free pool */ - if (!l2cb.p_free_ccb_first) - { - l2cb.p_free_ccb_first = p_ccb; - l2cb.p_free_ccb_last = p_ccb; - p_ccb->p_next_ccb = NULL; - p_ccb->p_prev_ccb = NULL; - } - else - { - p_ccb->p_next_ccb = NULL; - p_ccb->p_prev_ccb = l2cb.p_free_ccb_last; - l2cb.p_free_ccb_last->p_next_ccb = p_ccb; - l2cb.p_free_ccb_last = p_ccb; - } - - /* Flag as not in use */ - p_ccb->in_use = FALSE; - - /* If no channels on the connection, start idle timeout */ - if ((p_lcb) && p_lcb->in_use && (p_lcb->link_state == LST_CONNECTED)) - { - if (!p_lcb->ccb_queue.p_first_ccb) - { - l2cu_no_dynamic_ccbs (p_lcb); - } - else - { - /* Link is still active, adjust channel quotas. */ - l2c_link_adjust_chnl_allocation (); - } - } -} - -/******************************************************************************* -** -** Function l2cu_find_ccb_by_remote_cid -** -** Description Look through all active CCBs on a link for a match based -** on the remote CID. -** -** Returns pointer to matched CCB, or NULL if no match -** -*******************************************************************************/ -tL2C_CCB *l2cu_find_ccb_by_remote_cid (tL2C_LCB *p_lcb, UINT16 remote_cid) -{ - tL2C_CCB *p_ccb; - - /* If LCB is NULL, look through all active links */ - if (!p_lcb) - { - return NULL; - } - else - { - for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) - if ((p_ccb->in_use) && (p_ccb->remote_cid == remote_cid)) - return (p_ccb); - } - - /* If here, no match found */ - return (NULL); -} - -/******************************************************************************* -** -** Function l2cu_allocate_rcb -** -** Description Look through the Registration Control Blocks for a free -** one. -** -** Returns Pointer to the RCB or NULL if not found -** -*******************************************************************************/ -tL2C_RCB *l2cu_allocate_rcb (UINT16 psm) -{ - tL2C_RCB *p_rcb = &l2cb.rcb_pool[0]; - UINT16 xx; - - for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++) - { - if (!p_rcb->in_use) - { - p_rcb->in_use = TRUE; - p_rcb->psm = psm; -#if (L2CAP_UCD_INCLUDED == TRUE) - p_rcb->ucd.state = L2C_UCD_STATE_UNUSED; -#endif - return (p_rcb); - } - } - - /* If here, no free RCB found */ - return (NULL); -} - - -/******************************************************************************* -** -** Function l2cu_release_rcb -** -** Description Mark an RCB as no longet in use -** -** Returns void -** -*******************************************************************************/ -void l2cu_release_rcb (tL2C_RCB *p_rcb) -{ - p_rcb->in_use = FALSE; - p_rcb->psm = 0; -} - - -/******************************************************************************* -** -** Function l2cu_disconnect_chnl -** -** Description Disconnect a channel. Typically, this is due to either -** receiving a bad configuration, bad packet or max_retries expiring. -** -*******************************************************************************/ -void l2cu_disconnect_chnl (tL2C_CCB *p_ccb) -{ - UINT16 local_cid = p_ccb->local_cid; - - if (local_cid >= L2CAP_BASE_APPL_CID) - { - tL2CA_DISCONNECT_IND_CB *p_disc_cb = p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb; - - L2CAP_TRACE_WARNING1 ("L2CAP - disconnect_chnl CID: 0x%04x", local_cid); - - l2cu_send_peer_disc_req (p_ccb); - - l2cu_release_ccb (p_ccb); - - (*p_disc_cb)(local_cid, FALSE); - } - else - { - /* failure on the AMP channel, probably need to disconnect ACL */ - L2CAP_TRACE_ERROR1 ("L2CAP - disconnect_chnl CID: 0x%04x Ignored", local_cid); - } -} - - -/******************************************************************************* -** -** Function l2cu_find_rcb_by_psm -** -** Description Look through the Registration Control Blocks to see if -** anyone registered to handle the PSM in question -** -** Returns Pointer to the RCB or NULL if not found -** -*******************************************************************************/ -tL2C_RCB *l2cu_find_rcb_by_psm (UINT16 psm) -{ - tL2C_RCB *p_rcb = &l2cb.rcb_pool[0]; - UINT16 xx; - - for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++) - { - if ((p_rcb->in_use) && (p_rcb->psm == psm)) - return (p_rcb); + if (p_rcb->in_use && p_rcb->psm == psm) + return p_rcb; } - /* If here, no match found */ - return (NULL); + return NULL; } - -/******************************************************************************* -** -** Function l2cu_process_peer_cfg_req -** -** Description This function is called when the peer sends us a "config request" -** message. It extracts the configuration of interest and saves -** it in the CCB. -** -** Note: Negotiation of the FCR channel type is handled internally, -** all others are passed to the upper layer. -** -** Returns UINT8 - L2CAP_PEER_CFG_OK if passed to upper layer, -** L2CAP_PEER_CFG_UNACCEPTABLE if automatically responded to -** because parameters are unnacceptable from a specification -** point of view. -** L2CAP_PEER_CFG_DISCONNECT if no compatible channel modes -** between the two devices, and shall be closed. -** -*******************************************************************************/ -UINT8 l2cu_process_peer_cfg_req (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg) +BOOLEAN l2cu_process_peer_cfg_req(tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg) { - BOOLEAN mtu_ok = TRUE; - BOOLEAN qos_type_ok = TRUE; - BOOLEAN flush_to_ok = TRUE; - BOOLEAN fcr_ok = TRUE; - UINT8 fcr_status; - - /* Ignore FCR parameters for basic mode */ - if (!p_cfg->fcr_present) - p_cfg->fcr.mode = L2CAP_FCR_BASIC_MODE; + BOOLEAN mtu_ok = TRUE; + BOOLEAN qos_type_ok = TRUE; + BOOLEAN flush_to_ok = TRUE; + BOOLEAN fcr_ok = TRUE; + BOOLEAN retval; - /* Save the MTU that our peer can receive */ if (p_cfg->mtu_present) { - /* Make sure MTU is at least the minimum */ if (p_cfg->mtu >= L2CAP_MIN_MTU) { - /* In basic mode, limit the MTU to our buffer size */ - if ( (p_cfg->fcr_present == FALSE) && (p_cfg->mtu > L2CAP_MTU_SIZE) ) - p_cfg->mtu = L2CAP_MTU_SIZE; - - /* Save the accepted value in case of renegotiation */ - p_ccb->peer_cfg.mtu = p_cfg->mtu; - p_ccb->peer_cfg.mtu_present = TRUE; - p_ccb->peer_cfg_bits |= L2CAP_CH_CFG_MASK_MTU; + p_ccb->out_mtu = p_cfg->mtu; + + if (p_ccb->out_mtu > L2CAP_MTU_SIZE) + p_ccb->out_mtu = p_cfg->mtu = L2CAP_MTU_SIZE; } - else /* Illegal MTU value */ + else { p_cfg->mtu = L2CAP_MIN_MTU; - mtu_ok = FALSE; + mtu_ok = FALSE; } } - /* Reload mtu from a previously accepted config request */ - else if (p_ccb->peer_cfg.mtu_present) - { - p_cfg->mtu_present = TRUE; - p_cfg->mtu = p_ccb->peer_cfg.mtu; - } - /* Verify that the flush timeout is a valid value (0 is illegal) */ if (p_cfg->flush_to_present) { if (!p_cfg->flush_to) { - p_cfg->flush_to = 0xFFFF; /* Infinite retransmissions (spec default) */ - flush_to_ok = FALSE; + p_cfg->flush_to = 0xffff; + flush_to_ok = FALSE; } - else /* Save the accepted value in case of renegotiation */ - { - p_ccb->peer_cfg.flush_to_present = TRUE; - p_ccb->peer_cfg.flush_to = p_cfg->flush_to; - p_ccb->peer_cfg_bits |= L2CAP_CH_CFG_MASK_FLUSH_TO; - } - } - /* Reload flush_to from a previously accepted config request */ - else if (p_ccb->peer_cfg.flush_to_present) - { - p_cfg->flush_to_present = TRUE; - p_cfg->flush_to = p_ccb->peer_cfg.flush_to; } - /* Save the QOS settings the the peer is using */ if (p_cfg->qos_present) { - /* Make sure service type is not a reserved value; otherwise let upper - layer decide if acceptable - */ if (p_cfg->qos.service_type <= GUARANTEED) { - p_ccb->peer_cfg.qos = p_cfg->qos; - p_ccb->peer_cfg.qos_present = TRUE; - p_ccb->peer_cfg_bits |= L2CAP_CH_CFG_MASK_QOS; + p_ccb->in_flow = p_cfg->qos; } - else /* Illegal service type value */ + else { p_cfg->qos.service_type = BEST_EFFORT; - qos_type_ok = FALSE; + qos_type_ok = FALSE; } } - /* Reload QOS from a previously accepted config request */ - else if (p_ccb->peer_cfg.qos_present) - { - p_cfg->qos_present = TRUE; - p_cfg->qos = p_ccb->peer_cfg.qos; - } - - if ((fcr_status = l2c_fcr_process_peer_cfg_req (p_ccb, p_cfg)) == L2CAP_PEER_CFG_DISCONNECT) - { - /* Notify caller to disconnect the channel (incompatible modes) */ - p_cfg->result = L2CAP_CFG_FAILED_NO_REASON; - p_cfg->mtu_present = p_cfg->qos_present = p_cfg->flush_to_present = 0; - - return (L2CAP_PEER_CFG_DISCONNECT); - } - fcr_ok = (fcr_status == L2CAP_PEER_CFG_OK); + retval = mtu_ok && flush_to_ok && qos_type_ok && fcr_ok; - /* Return any unacceptable parameters */ - if (mtu_ok && flush_to_ok && qos_type_ok && fcr_ok) - { - l2cu_adjust_out_mps (p_ccb); - return (L2CAP_PEER_CFG_OK); - } - else + if (!retval) { p_cfg->result = L2CAP_CFG_UNACCEPTABLE_PARAMS; if (mtu_ok) p_cfg->mtu_present = FALSE; + if (flush_to_ok) p_cfg->flush_to_present = FALSE; + if (qos_type_ok) p_cfg->qos_present = FALSE; + if (fcr_ok) p_cfg->fcr_present = FALSE; - - return (L2CAP_PEER_CFG_UNACCEPTABLE); } + + return retval; } +void l2cu_process_peer_cfg_rsp(tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg) +{ + if (p_cfg->qos_present) + p_ccb->out_flow = p_cfg->qos; +} -/******************************************************************************* -** -** Function l2cu_process_peer_cfg_rsp -** -** Description This function is called when the peer sends us a "config response" -** message. It extracts the configuration of interest and saves -** it in the CCB. -** -** Returns void -** -*******************************************************************************/ -void l2cu_process_peer_cfg_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg) +void l2cu_process_our_cfg_req(tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg) { - /* If we wanted QoS and the peer sends us a positive response with QoS, use his values */ - if ( (p_cfg->qos_present) && (p_ccb->our_cfg.qos_present) ) - p_ccb->our_cfg.qos = p_cfg->qos; + tL2C_LCB *p_lcb; + UINT16 hci_flush_to; + void *p_buf; - if (p_cfg->fcr_present) + if (p_cfg->mtu_present) { - /* Save the retransmission and monitor timeout values */ - if (p_cfg->fcr.mode == L2CAP_FCR_ERTM_MODE) - { - p_ccb->peer_cfg.fcr.rtrans_tout = p_cfg->fcr.rtrans_tout; - p_ccb->peer_cfg.fcr.mon_tout = p_cfg->fcr.mon_tout; - } - - /* Calculate the max number of packets for which we can delay sending an ack */ - if (p_cfg->fcr.tx_win_sz < p_ccb->our_cfg.fcr.tx_win_sz) - p_ccb->fcrb.max_held_acks = p_cfg->fcr.tx_win_sz / 3; - else - p_ccb->fcrb.max_held_acks = p_ccb->our_cfg.fcr.tx_win_sz / 3; + p_ccb->in_mtu = p_cfg->mtu; - L2CAP_TRACE_DEBUG3 ("l2cu_process_peer_cfg_rsp(): peer tx_win_sz: %d, our tx_win_sz: %d, max_held_acks: %d", - p_cfg->fcr.tx_win_sz, p_ccb->our_cfg.fcr.tx_win_sz, p_ccb->fcrb.max_held_acks); + if (p_ccb->in_mtu > L2CAP_MTU_SIZE) + p_ccb->in_mtu = p_cfg->mtu = L2CAP_MTU_SIZE; } -} - -/******************************************************************************* -** -** Function l2cu_process_our_cfg_req -** -** Description This function is called when we send a "config request" -** message. It extracts the configuration of interest and saves -** it in the CCB. -** -** Returns void -** -*******************************************************************************/ -void l2cu_process_our_cfg_req (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg) -{ - tL2C_LCB *p_lcb; - UINT16 hci_flush_to; - /* Save the QOS settings we are using for transmit */ if (p_cfg->qos_present) - { - p_ccb->our_cfg.qos_present = TRUE; - p_ccb->our_cfg.qos = p_cfg->qos; - } + p_ccb->out_flow = p_cfg->qos; - if (p_cfg->fcr_present) + if (p_cfg->flush_to_present) { - /* Override FCR options if attempting streaming or basic */ - if (p_cfg->fcr.mode == L2CAP_FCR_BASIC_MODE) - memset(&p_cfg->fcr, 0, sizeof(tL2CAP_FCR_OPTS)); - else - { - /* On BR/EDR, timer values are zero in config request */ - /* On class 2 AMP, timer value in config request shall be non-0 processing time */ - /* timer value in config response shall be greater than received processing time */ - p_cfg->fcr.mon_tout = p_cfg->fcr.rtrans_tout = 0; - - if (p_cfg->fcr.mode == L2CAP_FCR_STREAM_MODE) - p_cfg->fcr.max_transmit = p_cfg->fcr.tx_win_sz = 0; - } - - /* Set the threshold to send acks (may be updated in the cfg response) */ - p_ccb->fcrb.max_held_acks = p_cfg->fcr.tx_win_sz / 3; + if (!p_cfg->flush_to) + return; - /* Include FCS option only if peer can handle it */ - if (p_ccb->p_lcb->peer_ext_fea & L2CAP_EXTFEA_NO_CRC) - { - /* FCS check can be bypassed if peer also desires to bypass */ - if (p_cfg->fcs_present && p_cfg->fcs == L2CAP_CFG_FCS_BYPASS) - p_ccb->bypass_fcs |= L2CAP_CFG_FCS_OUR; - } - else - p_cfg->fcs_present = FALSE; - } - else - { - p_cfg->fcr.mode = L2CAP_FCR_BASIC_MODE; - } + p_ccb->our_flush_to = p_cfg->flush_to; - p_ccb->our_cfg.fcr.mode = p_cfg->fcr.mode; - p_ccb->our_cfg.fcr_present = p_cfg->fcr_present; + p_lcb = p_ccb->p_lcb; - /* Check the flush timeout. If it is lower than the current one used */ - /* then we need to adjust the flush timeout sent to the controller */ - if (p_cfg->flush_to_present) - { - if ((p_cfg->flush_to == 0)||(p_cfg->flush_to == L2CAP_NO_AUTOMATIC_FLUSH)) - { - /* don't send invalid flush timeout */ - /* SPEC: The sender of the Request shall specify its flush timeout value */ - /* if it differs from the default value of 0xFFFF */ - p_cfg->flush_to_present = FALSE; - } - else + if (p_cfg->flush_to < p_lcb->link_flush_tout) { - p_ccb->our_cfg.flush_to = p_cfg->flush_to; - p_lcb = p_ccb->p_lcb; + p_lcb->link_flush_tout = p_cfg->flush_to; - if (p_cfg->flush_to < p_lcb->link_flush_tout) + if (p_cfg->flush_to <= 0x4ff) { - p_lcb->link_flush_tout = p_cfg->flush_to; + hci_flush_to = (p_cfg->flush_to * 8 + 3) / 5; - /* If the timeout is within range of HCI, set the flush timeout */ - if (p_cfg->flush_to <= ((HCI_MAX_AUTO_FLUSH_TOUT * 5) / 8)) + p_buf = GKI_getpoolbuf(L2CAP_CMD_POOL_ID); + if (p_buf) { - /* Convert flush timeout to 0.625 ms units, with round */ - hci_flush_to = ((p_cfg->flush_to * 8) + 3) / 5; - btsnd_hcic_write_auto_flush_tout (p_lcb->handle, hci_flush_to); + btsnd_hcic_write_auto_flush_tout(p_buf, p_lcb->handle, + hci_flush_to); } } } } } - -/******************************************************************************* -** -** Function l2cu_process_our_cfg_rsp -** -** Description This function is called when we send the peer a "config response" -** message. It extracts the configuration of interest and saves -** it in the CCB. -** -** Returns void -** -*******************************************************************************/ -void l2cu_process_our_cfg_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg) +void l2cu_process_our_cfg_rsp(tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg) { - /* If peer wants QoS, we are allowed to change the values in a positive response */ - if ( (p_cfg->qos_present) && (p_ccb->peer_cfg.qos_present) ) - p_ccb->peer_cfg.qos = p_cfg->qos; - else - p_cfg->qos_present = FALSE; - - l2c_fcr_adj_our_rsp_options (p_ccb, p_cfg); + if (p_cfg->qos_present) + p_ccb->in_flow = p_cfg->qos; } - -/******************************************************************************* -** -** Function l2cu_device_reset -** -** Description This function is called when reset of the device is -** completed. For all active connection simulate HCI_DISC -** -** Returns void -** -*******************************************************************************/ -void l2cu_device_reset (void) +void l2cu_device_reset(void) { - int xx; - tL2C_LCB *p_lcb = &l2cb.lcb_pool[0]; + int xx; + tL2C_LCB *p_lcb = l2cb.lcb_pool; + /* explicitly post-increment */ for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) { - if ((p_lcb->in_use) && (p_lcb->handle != HCI_INVALID_HANDLE)) - { - l2c_link_hci_disc_comp (p_lcb->handle, (UINT8) -1); - } + if (p_lcb->in_use && p_lcb->handle != HCI_INVALID_HANDLE) + l2c_link_hci_disc_comp(p_lcb->handle, -1); } } -#if (TCS_WUG_MEMBER_INCLUDED == TRUE && TCS_INCLUDED == TRUE) -extern UINT16 tcs_wug_get_clk_offset( BD_ADDR addr ) ; -#endif - -/******************************************************************************* -** -** Function l2cu_create_conn -** -** Description This function initiates an acl connection via HCI -** -** Returns TRUE if successful, FALSE if gki get buffer fails. -** -*******************************************************************************/ -BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb) +BOOLEAN l2cu_create_conn(tL2C_LCB *p_lcb) { - int xx; - tL2C_LCB *p_lcb_cur = &l2cb.lcb_pool[0]; -#if BTM_SCO_INCLUDED == TRUE - BOOLEAN is_sco_active; -#endif - -#if (BLE_INCLUDED == TRUE) - tBT_DEVICE_TYPE dev_type; - tBLE_ADDR_TYPE addr_type; - - BTM_ReadDevInfo(p_lcb->remote_bd_addr, &dev_type, &addr_type); + int xx; + tL2C_LCB *p_lcb_cur = l2cb.lcb_pool; + BOOLEAN is_sco_active; - if (dev_type == BT_DEVICE_TYPE_BLE) - { - p_lcb->ble_addr_type = addr_type; - p_lcb->is_ble_link = TRUE; - - return (l2cble_create_conn(p_lcb)); - } -#endif + p_lcb->link_state = LST_CONNECTING; - /* If there is a connection where we perform as a slave, try to switch roles - for this connection */ - for (xx = 0, p_lcb_cur = &l2cb.lcb_pool[0]; xx < MAX_L2CAP_LINKS; xx++, p_lcb_cur++) + /* explicitly post-increment */ + for (xx = 0, p_lcb_cur = l2cb.lcb_pool; xx < MAX_L2CAP_LINKS; + xx++, p_lcb_cur++) { if (p_lcb_cur == p_lcb) continue; - if ((p_lcb_cur->in_use) && (p_lcb_cur->link_role == HCI_ROLE_SLAVE)) + if (p_lcb_cur->in_use && p_lcb_cur->link_role == HCI_ROLE_SLAVE) { + is_sco_active = + btm_is_sco_active_by_bdaddr(p_lcb_cur->remote_bd_addr); -#if BTM_SCO_INCLUDED == TRUE - /* The LMP_switch_req shall be sent only if the ACL logical transport - is in active mode, when encryption is disabled, and all synchronous - logical transports on the same physical link are disabled." */ - - /* Check if there is any SCO Active on this BD Address */ - is_sco_active = btm_is_sco_active_by_bdaddr(p_lcb_cur->remote_bd_addr); - - L2CAP_TRACE_API1 ("l2cu_create_conn - btm_is_sco_active_by_bdaddr() is_sco_active = %s", \ - (is_sco_active == TRUE) ? "TRUE":"FALSE"); + L2CAP_TRACE(API, + "l2cu_create_conn - btm_is_sco_active_by_bdaddr() " + "is_sco_active = %s", + is_sco_active == TRUE ? "TRUE" : "FALSE\0\0"); if (is_sco_active == TRUE) - continue; /* No Master Slave switch not allowed when SCO Active */ -#endif + continue; if (HCI_SWITCH_SUPPORTED(btm_cb.devcb.local_features)) { - /* mark this lcb waiting for switch to be completed and - start switch on the other one */ p_lcb->link_state = LST_CONNECTING_WAIT_SWITCH; - p_lcb->link_role = HCI_ROLE_MASTER; - - if (BTM_SwitchRole (p_lcb_cur->remote_bd_addr, HCI_ROLE_MASTER, NULL) == BTM_CMD_STARTED) - { - btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, L2CAP_LINK_ROLE_SWITCH_TOUT); - return (TRUE); - } - } - } - } - - p_lcb->link_state = LST_CONNECTING; + p_lcb->link_role = HCI_ROLE_MASTER; - return (l2cu_create_conn_after_switch (p_lcb)); -} + BTM_SwitchRole(p_lcb_cur->remote_bd_addr, HCI_ROLE_MASTER, + NULL); -/******************************************************************************* -** -** Function l2cu_get_num_hi_priority -** -** Description Gets the number of high priority channels. -** -** Returns -** -*******************************************************************************/ -UINT8 l2cu_get_num_hi_priority (void) -{ - UINT8 no_hi = 0; - int xx; - tL2C_LCB *p_lcb = &l2cb.lcb_pool[0]; + btu_start_timer(&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, + L2CAP_LINK_ROLE_SWITCH_TOUT); - for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) - { - if ((p_lcb->in_use) && (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH)) - { - no_hi++; + return TRUE; + } } } - return no_hi; -} + return l2cu_create_conn_after_switch(p_lcb); +} -/******************************************************************************* -** -** Function l2cu_create_conn_after_switch -** -** Description This function initiates an acl connection via HCI -** If switch required to create connection it is already done. -** -** Returns TRUE if successful, FALSE if gki get buffer fails. -** -*******************************************************************************/ - -BOOLEAN l2cu_create_conn_after_switch (tL2C_LCB *p_lcb) +BOOLEAN l2cu_create_conn_after_switch(tL2C_LCB *p_lcb) { - UINT8 allow_switch = HCI_CR_CONN_ALLOW_SWITCH; - tBTM_INQ_INFO *p_inq_info; - UINT8 page_scan_rep_mode; - UINT8 page_scan_mode; - UINT16 clock_offset; - UINT8 *p_features; - UINT16 num_acl = BTM_GetNumAclLinks(); - tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (p_lcb->remote_bd_addr); - UINT8 no_hi_prio_chs = l2cu_get_num_hi_priority(); - - p_features = BTM_ReadLocalFeatures(); - - L2CAP_TRACE_DEBUG4 ("l2cu_create_conn_after_switch :%d num_acl:%d no_hi: %d is_bonding:%d", - l2cb.disallow_switch, num_acl, no_hi_prio_chs, p_lcb->is_bonding); - /* FW team says that we can participant in 4 piconets - * typically 3 piconet + 1 for scanning. - * We can enhance the code to count the number of piconets later. */ - if ( ((!l2cb.disallow_switch && (num_acl < 3)) || (p_lcb->is_bonding && (no_hi_prio_chs==0))) - && HCI_SWITCH_SUPPORTED(p_features)) + UINT8 allow_switch = HCI_CR_CONN_ALLOW_SWITCH; + tBTM_INQ_INFO *p_inq_info; + UINT8 page_scan_rep_mode; + UINT8 page_scan_mode; + UINT16 clock_offset; + UINT8 *p_features = BTM_ReadLocalFeatures(); + + if (HCI_SWITCH_SUPPORTED(p_features)) allow_switch = HCI_CR_CONN_ALLOW_SWITCH; else allow_switch = HCI_CR_CONN_NOT_ALLOW_SWITCH; p_lcb->link_state = LST_CONNECTING; - -#if (TCS_WUG_MEMBER_INCLUDED == TRUE && TCS_INCLUDED == TRUE) - if ( (clock_offset = tcs_wug_get_clk_offset( p_lcb->remote_bd_addr )) != 0 ) + if ((p_inq_info = BTM_InqDbRead(p_lcb->remote_bd_addr)) != NULL) { - page_scan_rep_mode = HCI_PAGE_SCAN_REP_MODE_R0; - page_scan_mode = HCI_MANDATARY_PAGE_SCAN_MODE; + page_scan_rep_mode = p_inq_info->results.page_scan_rep_mode; + page_scan_mode = p_inq_info->results.page_scan_mode; + clock_offset = 0x8000 | p_inq_info->results.clock_offset; } else { -#endif - - /* Check with the BT manager if details about remote device are known */ - if ((p_inq_info = BTM_InqDbRead(p_lcb->remote_bd_addr)) != NULL) - { - page_scan_rep_mode = p_inq_info->results.page_scan_rep_mode; - page_scan_mode = p_inq_info->results.page_scan_mode; - clock_offset = (UINT16)(p_inq_info->results.clock_offset); - } - else - { - /* No info known. Use default settings */ - page_scan_rep_mode = HCI_PAGE_SCAN_REP_MODE_R1; - page_scan_mode = HCI_MANDATARY_PAGE_SCAN_MODE; - - clock_offset = (p_dev_rec) ? p_dev_rec->clock_offset : 0; - } -#if (TCS_WUG_MEMBER_INCLUDED == TRUE && TCS_INCLUDED == TRUE) + page_scan_rep_mode = HCI_PAGE_SCAN_REP_MODE_R1; + page_scan_mode = HCI_MANDATARY_PAGE_SCAN_MODE; + clock_offset = 0; } -#endif - if (!btsnd_hcic_create_conn (p_lcb->remote_bd_addr, - HCI_PKT_TYPES_MASK_DM1 + HCI_PKT_TYPES_MASK_DH1, - page_scan_rep_mode, - page_scan_mode, - clock_offset, - allow_switch)) + if (!btsnd_hcic_create_conn(p_lcb->remote_bd_addr, + HCI_PKT_TYPES_MASK_DM1 + HCI_PKT_TYPES_MASK_DH1, + page_scan_rep_mode, page_scan_mode, + clock_offset, allow_switch)) { - L2CAP_TRACE_ERROR0 ("L2CAP - no buffer for l2cu_create_conn"); - l2cu_release_lcb (p_lcb); - return (FALSE); + L2CAP_TRACE(ERROR, "L2CAP - no buffer for l2cu_create_conn\0"); + l2cu_release_lcb(p_lcb); + return FALSE; } -#if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE) - btm_acl_update_busy_level (BTM_BLI_PAGE_EVT); -#endif + btu_start_timer(&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, + L2CAP_LINK_CONNECT_TOUT); - btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, - L2CAP_LINK_CONNECT_TOUT); - - return (TRUE); + return TRUE; } - -/******************************************************************************* -** -** Function l2cu_find_lcb_by_state -** -** Description Look through all active LCBs for a match based on the -** LCB state. -** -** Returns pointer to first matched LCB, or NULL if no match -** -*******************************************************************************/ -tL2C_LCB *l2cu_find_lcb_by_state (tL2C_LINK_STATE state) +tL2C_LCB *l2cu_find_lcb_by_state(tL2C_LINK_STATE state) { - UINT16 i; - tL2C_LCB *p_lcb = &l2cb.lcb_pool[0]; + UINT16 i; + tL2C_LCB *p_lcb = l2cb.lcb_pool; + /* explicitly post-increment */ for (i = 0; i < MAX_L2CAP_LINKS; i++, p_lcb++) { - if ((p_lcb->in_use) && (p_lcb->link_state == state)) - { - return (p_lcb); - } + if (p_lcb->in_use && p_lcb->link_state == state) + return p_lcb; } - /* If here, no match found */ - return (NULL); + return NULL; } - -/******************************************************************************* -** -** Function l2cu_lcb_disconnecting -** -** Description On each active lcb, check if the lcb is in disconnecting -** state, or if there are no ccb's on the lcb (implying - idle timeout is running), or if last ccb on the link - is in disconnecting state. -** -** Returns TRUE if any of above conditions met, FALSE otherwise -** -*******************************************************************************/ -BOOLEAN l2cu_lcb_disconnecting (void) +BOOLEAN l2cu_lcb_disconnecting(void) { - tL2C_LCB *p_lcb; - tL2C_CCB *p_ccb; - UINT16 i; - BOOLEAN status = FALSE; + tL2C_LCB *p_lcb; + tL2C_CCB *p_ccb; + UINT16 i; + BOOLEAN status = FALSE; - p_lcb = &l2cb.lcb_pool[0]; + p_lcb = l2cb.lcb_pool; for (i = 0; i < MAX_L2CAP_LINKS; i++, p_lcb++) { - if (p_lcb->in_use) + if (!p_lcb->in_use) + continue; + + if (!p_lcb->p_first_ccb || p_lcb->link_state == LST_DISCONNECTING) { - /* no ccbs on lcb, or lcb is in disconnecting state */ - if ((!p_lcb->ccb_queue.p_first_ccb) || (p_lcb->link_state == LST_DISCONNECTING)) - { - status = TRUE; - break; - } - /* only one ccb left on lcb */ - else if (p_lcb->ccb_queue.p_first_ccb == p_lcb->ccb_queue.p_last_ccb) - { - p_ccb = p_lcb->ccb_queue.p_first_ccb; - - if ((p_ccb->in_use) && - ((p_ccb->chnl_state == CST_W4_L2CAP_DISCONNECT_RSP) || - (p_ccb->chnl_state == CST_W4_L2CA_DISCONNECT_RSP))) - { - status = TRUE; - break; - } - } - } - } - return status; -} - - -/******************************************************************************* -** -** Function l2cu_set_acl_priority -** -** Description Sets the transmission priority for a channel. -** (For initial implementation only two values are valid. -** L2CAP_PRIORITY_NORMAL and L2CAP_PRIORITY_HIGH). -** -** Returns TRUE if a valid channel, else FALSE -** -*******************************************************************************/ - -BOOLEAN l2cu_set_acl_priority (BD_ADDR bd_addr, UINT8 priority, BOOLEAN reset_after_rs) -{ - tL2C_LCB *p_lcb; - UINT8 *pp; - UINT8 command[HCI_BRCM_ACL_PRIORITY_PARAM_SIZE]; - UINT8 vs_param; - - APPL_TRACE_EVENT1("SET ACL PRIORITY %d", priority); - - /* Find the link control block for the acl channel */ - if ((p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr)) == NULL) - { - L2CAP_TRACE_WARNING0 ("L2CAP - no LCB for L2CA_SetAclPriority"); - return (FALSE); - } - - if (BTM_IS_BRCM_CONTROLLER()) - { - /* Called from above L2CAP through API; send VSC if changed */ - if ((!reset_after_rs && (priority != p_lcb->acl_priority)) || - /* Called because of a master/slave role switch; if high resend VSC */ - ( reset_after_rs && p_lcb->acl_priority == L2CAP_PRIORITY_HIGH)) - { - pp = command; - - vs_param = (priority == L2CAP_PRIORITY_HIGH) ? HCI_BRCM_ACL_PRIORITY_HIGH : HCI_BRCM_ACL_PRIORITY_LOW; - - UINT16_TO_STREAM (pp, p_lcb->handle); - UINT8_TO_STREAM (pp, vs_param); - - BTM_VendorSpecificCommand (HCI_BRCM_SET_ACL_PRIORITY, HCI_BRCM_ACL_PRIORITY_PARAM_SIZE, command, NULL); - - /* Adjust lmp buffer allocation for this channel if priority changed */ - if (p_lcb->acl_priority != priority) - { - p_lcb->acl_priority = priority; - l2c_link_adjust_allocation(); - } - } - } - return(TRUE); -} - -#if (L2CAP_ENHANCED_FEATURES != 0) -/******************************************************************************* -** -** Function l2cu_send_feature_req -** -** Description Called at connection establishment by the originator -** of the connection to send an L2CAP Echo request message -** to the peer to determine if he supports Widcomm proprietary -** features. -** -** Returns void -** -*******************************************************************************/ -void l2cu_send_feature_req (tL2C_CCB *p_ccb) -{ - UINT8 saved_id; - UINT8 buff[100], *p = buff; - - UINT8_TO_STREAM (p, 'R'); - UINT8_TO_STREAM (p, 'Q'); - - UINT8_TO_STREAM (p, 'r'); - UINT8_TO_STREAM (p, 'q'); - - /* save current ID to be restored after feature request */ - saved_id = p_ccb->p_lcb->id; - - /* Set appropriate ID */ - p_ccb->p_lcb->id = L2CAP_FEATURE_REQ_ID - 1; - - l2cu_send_peer_echo_req (p_ccb->p_lcb, buff, (UINT16)(p - buff)); - - /* packet has been built so we can restore the control block id */ - p_ccb->p_lcb->id = saved_id; -} - - - -/******************************************************************************* -** -** Function l2cu_check_feature_req -** -** Description Called when an echo request is received to check if the -** other side is doing a proprietary feature request. If so, -** extract the values and reply with a features response. -** -** Returns void -** -*******************************************************************************/ -BOOLEAN l2cu_check_feature_req (tL2C_LCB *p_lcb, UINT8 id, UINT8 *p_data, UINT16 data_len) -{ - UINT8 buff[100]; - UINT8 *p_out = buff; - UINT8 *p_end = p_data + data_len - 2; - UINT8 pe_type, pe_len; - - if ((data_len <= 4) - || (p_data[0] != 'R') - || (p_data[1] != 'Q') - || (p_data[data_len - 2] != 'r') - || (p_data[data_len - 1] != 'q') - || (id != L2CAP_FEATURE_REQ_ID)) - return (FALSE); - - /* Skip leading frame characters */ - p_data += 2; - - UINT8_TO_STREAM (p_out, 'R'); - UINT8_TO_STREAM (p_out, 'S'); - - while (p_data < p_end) - { - pe_type = *p_data++; - pe_len = *p_data++; - - switch (pe_type) - { - default: - p_data += pe_len; + status = TRUE; break; } - } - - /* Sanity check - we should not overrun the input */ - if (p_data != p_end) - { - L2CAP_TRACE_ERROR0 ("L2CAP - badly formatted feature req"); - return (FALSE); - } - - UINT8_TO_STREAM (p_out, 'r'); - UINT8_TO_STREAM (p_out, 's'); - - l2cu_send_peer_echo_rsp (p_lcb, L2CAP_FEATURE_RSP_ID, buff, (UINT16)(p_out - buff)); - - return (TRUE); -} - -/******************************************************************************* -** -** Function l2cu_check_feature_rsp -** -** Description Called when an echo response is received to check if the -** other side is suports proprietary feature(s). If so, -** extract the values. -** -** Returns void -** -*******************************************************************************/ -void l2cu_check_feature_rsp (tL2C_LCB *p_lcb, UINT8 id, UINT8 *p_data, UINT16 data_len) -{ - UINT8 *p_end = p_data + data_len - 2; - - if ((data_len <= 4) - || (p_data[0] != 'R') - || (p_data[1] != 'S') - || (p_data[data_len - 2] != 'r') - || (p_data[data_len - 1] != 's') - || (id != L2CAP_FEATURE_RSP_ID)) - { - return; - } - - /* Skip leading frame characters */ - p_data += 2; - while (p_data < p_end) - { - UINT8 pe_id = *p_data++; - UINT8 pe_len = *p_data++; - - switch (pe_id) + if (p_lcb->p_first_ccb == p_lcb->p_last_ccb) { - default: - p_data += pe_len; - break; - } - } - - /* Sanity check - we should not overrun the input */ - if (p_data != p_end) - { - L2CAP_TRACE_ERROR0 ("L2CAP - badly formatted feature rsp"); - } -} -#endif /* L2CAP_ENHANCED_FEATURES != 0 */ - -#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE) -/****************************************************************************** -** -** Function l2cu_set_non_flushable_pbf -** -** Description set L2CAP_PKT_START_NON_FLUSHABLE if controller supoorts -** -** Returns void -** -*******************************************************************************/ -void l2cu_set_non_flushable_pbf (BOOLEAN is_supported) -{ - if (is_supported) - l2cb.non_flushable_pbf = (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT); - else - l2cb.non_flushable_pbf = (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT); -} -#endif - -/******************************************************************************* -** -** Function l2cu_resubmit_pending_sec_req -** -** Description This function is called when required security procedures -** are completed and any pending requests can be re-submitted. -** -** Returns void -** -*******************************************************************************/ -void l2cu_resubmit_pending_sec_req (BD_ADDR p_bda) -{ - tL2C_LCB *p_lcb; - tL2C_CCB *p_ccb; - tL2C_CCB *p_next_ccb; - int xx; - - L2CAP_TRACE_DEBUG1 ("l2cu_resubmit_pending_sec_req p_bda: 0x%08x", p_bda); - - /* If we are called with a BDA, only resubmit for that BDA */ - if (p_bda) - { - p_lcb = l2cu_find_lcb_by_bd_addr (p_bda); + p_ccb = p_lcb->p_first_ccb; - /* If we don't have one, this is an error */ - if (p_lcb) - { - /* For all channels, send the event through their FSMs */ - for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_next_ccb) - { - p_next_ccb = p_ccb->p_next_ccb; - l2c_csm_execute (p_ccb, L2CEVT_SEC_RE_SEND_CMD, NULL); - } - } - else - { - L2CAP_TRACE_WARNING0 ("l2cu_resubmit_pending_sec_req - unknown BD_ADDR"); - } - } - else - { - /* No BDA pasesed in, so check all links */ - for (xx = 0, p_lcb = &l2cb.lcb_pool[0]; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) - { - if (p_lcb->in_use) + if (p_ccb->in_use + && (p_ccb->chnl_state == CST_W4_L2CAP_DISCONNECT_RSP + || p_ccb->chnl_state == CST_W4_L2CA_DISCONNECT_RSP)) { - /* For all channels, send the event through their FSMs */ - for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_next_ccb) - { - p_next_ccb = p_ccb->p_next_ccb; - l2c_csm_execute (p_ccb, L2CEVT_SEC_RE_SEND_CMD, NULL); - } - } - } - } -} - -#if L2CAP_CONFORMANCE_TESTING == TRUE -/******************************************************************************* -** -** Function l2cu_set_info_rsp_mask -** -** Description This function allows the script wrapper to change the -** info resp mask for conformance testing. -** -** Returns pointer to CCB, or NULL if none -** -*******************************************************************************/ -void l2cu_set_info_rsp_mask (UINT32 mask) -{ - l2cb.test_info_resp = mask; -} -#endif /* L2CAP_CONFORMANCE_TESTING */ - -/******************************************************************************* -** -** Function l2cu_adjust_out_mps -** -** Description Sets our MPS based on current controller capabilities -** -** Returns void -** -*******************************************************************************/ -void l2cu_adjust_out_mps (tL2C_CCB *p_ccb) -{ - UINT16 packet_size; - - /* on the tx side MTU is selected based on packet size of the controller */ - packet_size = btm_get_max_packet_size (p_ccb->p_lcb->remote_bd_addr); - - if (packet_size <= (L2CAP_PKT_OVERHEAD + L2CAP_FCR_OVERHEAD + L2CAP_SDU_LEN_OVERHEAD + L2CAP_FCS_LEN)) - { - /* something is very wrong */ - L2CAP_TRACE_ERROR2 ("l2cu_adjust_out_mps bad packet size: %u will use MPS: %u", packet_size, p_ccb->peer_cfg.fcr.mps); - p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps; - } - else - { - packet_size -= (L2CAP_PKT_OVERHEAD + L2CAP_FCR_OVERHEAD + L2CAP_SDU_LEN_OVERHEAD + L2CAP_FCS_LEN); - - /* We try to negotiate MTU that each packet can be split into whole - number of max packets. For example if link is 1.2 max packet size is 339 bytes. - At first calculate how many whole packets it is. MAX L2CAP is 1691 + 4 overhead. - 1695, that will be 5 Dh5 packets. Now maximum L2CAP packet is - 5 * 339 = 1695. Minus 4 bytes L2CAP header 1691. - - For EDR 2.0 packet size is 1027. So we better send RFCOMM packet as 1 3DH5 packet - 1 * 1027 = 1027. Minus 4 bytes L2CAP header 1023. */ - if (p_ccb->peer_cfg.fcr.mps >= packet_size) - p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps / packet_size * packet_size; - else - p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps; - - L2CAP_TRACE_DEBUG3 ("l2cu_adjust_out_mps use %d Based on peer_cfg.fcr.mps: %u packet_size: %u", - p_ccb->tx_mps, p_ccb->peer_cfg.fcr.mps, packet_size); - } -} - - -/******************************************************************************* -** -** Function l2cu_initialize_fixed_ccb -** -** Description Initialize a fixed channel's CCB -** -** Returns TRUE or FALSE -** -*******************************************************************************/ -BOOLEAN l2cu_initialize_fixed_ccb (tL2C_LCB *p_lcb, UINT16 fixed_cid, tL2CAP_FCR_OPTS *p_fcr) -{ -#if (L2CAP_NUM_FIXED_CHNLS > 0) - tL2C_CCB *p_ccb; - - /* If we already have a CCB, then simply return */ - if (p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL] != NULL) - return (TRUE); - - if ((p_ccb = l2cu_allocate_ccb (NULL, 0)) == NULL) - return (FALSE); - - /* Set CID for the connection */ - p_ccb->local_cid = fixed_cid; - p_ccb->remote_cid = fixed_cid; - - GKI_init_q (&p_ccb->xmit_hold_q); - - p_ccb->is_flushable = FALSE; - - p_ccb->timer_entry.param = (TIMER_PARAM_TYPE)p_ccb; - - - if (p_fcr) - { - /* Set the FCR parameters. For now, we will use default pools */ - p_ccb->our_cfg.fcr = p_ccb->peer_cfg.fcr = *p_fcr; - - p_ccb->ertm_info.fcr_rx_pool_id = HCI_ACL_POOL_ID; - p_ccb->ertm_info.fcr_tx_pool_id = HCI_ACL_POOL_ID; - p_ccb->ertm_info.user_rx_pool_id = HCI_ACL_POOL_ID; - p_ccb->ertm_info.user_tx_pool_id = HCI_ACL_POOL_ID; - - p_ccb->fcrb.max_held_acks = p_fcr->tx_win_sz / 3; - } - - /* Link ccb to lcb and lcb to ccb */ - p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL] = p_ccb; - p_ccb->p_lcb = p_lcb; - - /* There is no configuration, so if the link is up, the channel is up */ - if (p_lcb->link_state == LST_CONNECTED) - p_ccb->chnl_state = CST_OPEN; - - /* Set the default idle timeout value to use */ - p_ccb->fixed_chnl_idle_tout = l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].default_idle_tout; -#endif - return (TRUE); -} - -/******************************************************************************* -** -** Function l2cu_no_dynamic_ccbs -** -** Description Handles the case when there are no more dynamic CCBs. If there -** are any fixed CCBs, start the longest of the fixed CCB timeouts, -** otherwise start the default link idle timeout or disconnect. -** -** Returns void -** -*******************************************************************************/ -void l2cu_no_dynamic_ccbs (tL2C_LCB *p_lcb) -{ - tBTM_STATUS rc; - UINT16 timeout = p_lcb->idle_timeout; - -#if (L2CAP_NUM_FIXED_CHNLS > 0) - int xx; - - for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) - { - if ( (p_lcb->p_fixed_ccbs[xx] != NULL) && (p_lcb->p_fixed_ccbs[xx]->fixed_chnl_idle_tout > timeout) ) - timeout = p_lcb->p_fixed_ccbs[xx]->fixed_chnl_idle_tout; - } -#endif - - /* If the link is pairing, do not mess with the timeouts */ - if (p_lcb->is_bonding) - return; - - if (timeout == 0) - { - L2CAP_TRACE_DEBUG0 ("l2cu_no_dynamic_ccbs() IDLE timer 0, disconnecting link"); - - rc = btm_sec_disconnect (p_lcb->handle, HCI_ERR_PEER_USER); - if (rc == BTM_CMD_STARTED) - { - p_lcb->link_state = LST_DISCONNECTING; - timeout = L2CAP_LINK_DISCONNECT_TOUT; - } - else if (rc == BTM_SUCCESS) - { - /* BTM SEC will make sure that link is release (probably after pairing is done) */ - p_lcb->link_state = LST_DISCONNECTING; - timeout = 0xFFFF; - } - else if ( (p_lcb->is_bonding) - && (btsnd_hcic_disconnect (p_lcb->handle, HCI_ERR_PEER_USER)) ) - { - p_lcb->link_state = LST_DISCONNECTING; - timeout = L2CAP_LINK_DISCONNECT_TOUT; - } - else - { - /* probably no buffer to send disconnect */ - timeout = BT_1SEC_TIMEOUT; - } - } - - if (timeout != 0xFFFF) - { - L2CAP_TRACE_DEBUG1 ("l2cu_no_dynamic_ccbs() starting IDLE timeout: %d", timeout); - btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, timeout); - } - else - { - btu_stop_timer(&p_lcb->timer_entry); - } -} - -#if (L2CAP_NUM_FIXED_CHNLS > 0) -/******************************************************************************* -** -** Function l2cu_process_fixed_chnl_resp -** -** Description handle a fixed channel response (or lack thereof) -** if the link failed, or a fixed channel response was -** not received, the bitfield is all zeros. -** -*******************************************************************************/ -void l2cu_process_fixed_chnl_resp (tL2C_LCB *p_lcb) -{ - int xx; -#if BLE_INCLUDED == TRUE - UINT16 reason = (p_lcb->is_ble_link ) ? 1 : 0; -#else - UINT16 reason =0; -#endif - - /* Tell all registered fixed channels about the connection */ - for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) - { - if (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL) - { - if (p_lcb->peer_chnl_mask[0] & (1 << (xx + L2CAP_FIRST_FIXED_CHNL))) - { - if (p_lcb->p_fixed_ccbs[xx]) - p_lcb->p_fixed_ccbs[xx]->chnl_state = CST_OPEN; - - (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, TRUE, reason); - } - else if (p_lcb->p_fixed_ccbs[xx]) - { - (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason); - l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]); - p_lcb->p_fixed_ccbs[xx] = NULL; - } - } - } -} -#endif - -#if (BLE_INCLUDED == TRUE) -/******************************************************************************* -** -** Function l2cu_send_peer_ble_par_req -** -** Description Build and send a BLE parameter update request message -** to the peer. -** -** Returns void -** -*******************************************************************************/ -void l2cu_send_peer_ble_par_req (tL2C_LCB *p_lcb, UINT16 min_int, UINT16 max_int, UINT16 latency, UINT16 timeout) -{ - BT_HDR *p_buf; - UINT8 *p; - - /* Create an identifier for this packet */ - p_lcb->id++; - l2cu_adj_id (p_lcb, L2CAP_ADJ_ID); - - if ((p_buf = l2cu_build_header (p_lcb, L2CAP_CMD_BLE_UPD_REQ_LEN, L2CAP_CMD_BLE_UPDATE_REQ, p_lcb->id)) == NULL ) - { - L2CAP_TRACE_WARNING0 ("l2cu_send_peer_ble_par_req - no buffer"); - return; - } - - p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + - L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; - - UINT16_TO_STREAM (p, min_int); - UINT16_TO_STREAM (p, max_int); - UINT16_TO_STREAM (p, latency); - UINT16_TO_STREAM (p, timeout); - - l2c_link_check_send_pkts (p_lcb, NULL, p_buf); -} - -/******************************************************************************* -** -** Function l2cu_send_peer_ble_par_rsp -** -** Description Build and send a BLE parameter update response message -** to the peer. -** -** Returns void -** -*******************************************************************************/ -void l2cu_send_peer_ble_par_rsp (tL2C_LCB *p_lcb, UINT16 reason, UINT8 rem_id) -{ - BT_HDR *p_buf; - UINT8 *p; - - if ((p_buf = l2cu_build_header (p_lcb, L2CAP_CMD_BLE_UPD_RSP_LEN, L2CAP_CMD_BLE_UPDATE_RSP, rem_id)) == NULL ) - { - L2CAP_TRACE_WARNING0 ("l2cu_send_peer_ble_par_rsp - no buffer"); - return; - } - - p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + - L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; - - UINT16_TO_STREAM (p, reason); - - l2c_link_check_send_pkts (p_lcb, NULL, p_buf); -} - -#endif /* BLE_INCLUDED == TRUE */ - - -/******************************************************************************* -** Functions used by both Full and Light Stack -********************************************************************************/ - -/******************************************************************************* -** -** Function l2cu_find_lcb_by_handle -** -** Description Look through all active LCBs for a match based on the -** HCI handle. -** -** Returns pointer to matched LCB, or NULL if no match -** -*******************************************************************************/ -tL2C_LCB *l2cu_find_lcb_by_handle (UINT16 handle) -{ - int xx; - tL2C_LCB *p_lcb = &l2cb.lcb_pool[0]; - - for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) - { - if ((p_lcb->in_use) && (p_lcb->handle == handle)) - { - return (p_lcb); - } - } - - /* If here, no match found */ - return (NULL); -} - -/******************************************************************************* -** -** Function l2cu_find_ccb_by_cid -** -** Description Look through all active CCBs on a link for a match based -** on the local CID. If passed the link pointer is NULL, all -** active links are searched. -** -** Returns pointer to matched CCB, or NULL if no match -** -*******************************************************************************/ -tL2C_CCB *l2cu_find_ccb_by_cid (tL2C_LCB *p_lcb, UINT16 local_cid) -{ - tL2C_CCB *p_ccb = NULL; -#if (L2CAP_UCD_INCLUDED == TRUE) - UINT8 xx; -#endif - - if (local_cid >= L2CAP_BASE_APPL_CID) - { - /* find the associated CCB by "index" */ - local_cid -= L2CAP_BASE_APPL_CID; - - if (local_cid >= MAX_L2CAP_CHANNELS) - return NULL; - - p_ccb = l2cb.ccb_pool + local_cid; - - /* make sure the CCB is in use */ - if (!p_ccb->in_use) - { - p_ccb = NULL; - } - /* make sure it's for the same LCB */ - else if (p_lcb && p_lcb != p_ccb->p_lcb) - { - p_ccb = NULL; - } - } -#if (L2CAP_UCD_INCLUDED == TRUE) - else - { - /* searching fixed channel */ - p_ccb = l2cb.ccb_pool; - for ( xx = 0; xx < MAX_L2CAP_CHANNELS; xx++ ) - { - if ((p_ccb->local_cid == local_cid) - &&(p_ccb->in_use) - &&(p_lcb == p_ccb->p_lcb)) + status = TRUE; break; - else - p_ccb++; - } - if ( xx >= MAX_L2CAP_CHANNELS ) - return NULL; - } -#endif - - return (p_ccb); -} - -#if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) - -/****************************************************************************** -** -** Function l2cu_get_next_channel_in_rr -** -** Description get the next channel to send on a link. It also adjusts the -** CCB queue to do a basic priority and round-robin scheduling. -** -** Returns pointer to CCB or NULL -** -*******************************************************************************/ -static tL2C_CCB *l2cu_get_next_channel_in_rr(tL2C_LCB *p_lcb) -{ - tL2C_CCB *p_serve_ccb = NULL; - tL2C_CCB *p_ccb; - - int i, j; - - /* scan all of priority until finding a channel to serve */ - for ( i = 0; (i < L2CAP_NUM_CHNL_PRIORITY)&&(!p_serve_ccb); i++ ) - { - /* scan all channel within serving priority group until finding a channel to serve */ - for ( j = 0; (j < p_lcb->rr_serv[p_lcb->rr_pri].num_ccb)&&(!p_serve_ccb); j++) - { - /* scaning from next serving channel */ - p_ccb = p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb; - - if (!p_ccb) - { - L2CAP_TRACE_ERROR1("p_serve_ccb is NULL, rr_pri=%d", p_lcb->rr_pri); - return NULL; - } - - L2CAP_TRACE_DEBUG3("RR scan pri=%d, lcid=0x%04x, q_cout=%d", - p_ccb->ccb_priority, p_ccb->local_cid, p_ccb->xmit_hold_q.count ); - - /* store the next serving channel */ - /* this channel is the last channel of its priority group */ - if (( p_ccb->p_next_ccb == NULL ) - ||( p_ccb->p_next_ccb->ccb_priority != p_ccb->ccb_priority )) - { - /* next serving channel is set to the first channel in the group */ - p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb = p_lcb->rr_serv[p_lcb->rr_pri].p_first_ccb; - } - else - { - /* next serving channel is set to the next channel in the group */ - p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb = p_ccb->p_next_ccb; - } - - if (p_ccb->chnl_state != CST_OPEN) - continue; - - /* eL2CAP option in use */ - if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE) - { - if (p_ccb->fcrb.wait_ack || p_ccb->fcrb.remote_busy) - continue; - - if ( p_ccb->fcrb.retrans_q.count == 0 ) - { - if ( p_ccb->xmit_hold_q.count == 0 ) - continue; - - /* If using the common pool, should be at least 10% free. */ - if ( (p_ccb->ertm_info.fcr_tx_pool_id == HCI_ACL_POOL_ID) && (GKI_poolutilization (HCI_ACL_POOL_ID) > 90) ) - continue; - - /* If in eRTM mode, check for window closure */ - if ( (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) && (l2c_fcr_is_flow_controlled (p_ccb)) ) - continue; - } } - else - { - if (p_ccb->xmit_hold_q.count == 0) - continue; - } - - /* found a channel to serve */ - p_serve_ccb = p_ccb; - /* decrease quota of its priority group */ - p_lcb->rr_serv[p_lcb->rr_pri].quota--; - } - - /* if there is no more quota of the priority group or no channel to have data to send */ - if ((p_lcb->rr_serv[p_lcb->rr_pri].quota == 0)||(!p_serve_ccb)) - { - /* serve next priority group */ - p_lcb->rr_pri = (p_lcb->rr_pri + 1) % L2CAP_NUM_CHNL_PRIORITY; - /* initialize its quota */ - p_lcb->rr_serv[p_lcb->rr_pri].quota = L2CAP_GET_PRIORITY_QUOTA(p_lcb->rr_pri); } } - if (p_serve_ccb) - { - L2CAP_TRACE_DEBUG3("RR service pri=%d, quota=%d, lcid=0x%04x", - p_serve_ccb->ccb_priority, - p_lcb->rr_serv[p_serve_ccb->ccb_priority].quota, - p_serve_ccb->local_cid ); - } - - return p_serve_ccb; -} - -#else /* (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) */ - -/****************************************************************************** -** -** Function l2cu_get_next_channel -** -** Description get the next channel to send on a link bassed on priority -** scheduling. -** -** Returns pointer to CCB or NULL -** -*******************************************************************************/ -static tL2C_CCB *l2cu_get_next_channel(tL2C_LCB *p_lcb) -{ - tL2C_CCB *p_ccb; - - /* Get the first CCB with data to send. - */ - for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) - { - if (p_ccb->chnl_state != CST_OPEN) - continue; - - if (p_ccb->fcrb.wait_ack || p_ccb->fcrb.remote_busy) - continue; - - if (p_ccb->fcrb.retrans_q.count != 0) - return p_ccb; - - if (p_ccb->xmit_hold_q.count == 0) - continue; - - /* If using the common pool, should be at least 10% free. */ - if ( (p_ccb->ertm_info.fcr_tx_pool_id == HCI_ACL_POOL_ID) && (GKI_poolutilization (HCI_ACL_POOL_ID) > 90) ) - continue; - - /* If in eRTM mode, check for window closure */ - if ( (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) && (l2c_fcr_is_flow_controlled (p_ccb)) ) - continue; - - /* If here, we found someone */ - return p_ccb; - } - - return NULL; -} -#endif /* (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) */ - -/****************************************************************************** -** -** Function l2cu_get_next_buffer_to_send -** -** Description get the next buffer to send on a link. It also adjusts the -** CCB queue to do a basic priority and round-robin scheduling. -** -** Returns pointer to buffer or NULL -** -*******************************************************************************/ -BT_HDR *l2cu_get_next_buffer_to_send (tL2C_LCB *p_lcb) -{ - tL2C_CCB *p_ccb; - BT_HDR *p_buf; - - /* Highest priority are fixed channels */ -#if (L2CAP_NUM_FIXED_CHNLS > 0) - int xx; - - for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) - { - if ((p_ccb = p_lcb->p_fixed_ccbs[xx]) == NULL) - continue; - - /* eL2CAP option in use */ - if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE) - { - if (p_ccb->fcrb.wait_ack || p_ccb->fcrb.remote_busy) - continue; - - /* No more checks needed if sending from the reatransmit queue */ - if (p_ccb->fcrb.retrans_q.count == 0) - { - if (p_ccb->xmit_hold_q.count == 0) - continue; - - /* If using the common pool, should be at least 10% free. */ - if ( (p_ccb->ertm_info.fcr_tx_pool_id == HCI_ACL_POOL_ID) && (GKI_poolutilization (HCI_ACL_POOL_ID) > 90) ) - continue; - - /* If in eRTM mode, check for window closure */ - if ( (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) && (l2c_fcr_is_flow_controlled (p_ccb)) ) - continue; - } - - if ((p_buf = l2c_fcr_get_next_xmit_sdu_seg(p_ccb, 0)) != NULL) - { - l2cu_set_acl_hci_header (p_buf, p_ccb); - return (p_buf); - } - } - else - { - if (p_ccb->xmit_hold_q.count != 0) - { - p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->xmit_hold_q); - l2cu_set_acl_hci_header (p_buf, p_ccb); - return (p_buf); - } - } - } -#endif - -#if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) - /* get next serving channel in round-robin */ - p_ccb = l2cu_get_next_channel_in_rr( p_lcb ); -#else - p_ccb = l2cu_get_next_channel( p_lcb ); -#endif - - /* Return if no buffer */ - if (p_ccb == NULL) - return (NULL); - - if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE) - { - if ((p_buf = l2c_fcr_get_next_xmit_sdu_seg(p_ccb, 0)) == NULL) - return (NULL); - } - else - { - p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->xmit_hold_q); - } - - l2cu_check_channel_congestion (p_ccb); - - l2cu_set_acl_hci_header (p_buf, p_ccb); - - return (p_buf); -} - -/****************************************************************************** -** -** Function l2cu_set_acl_hci_header -** -** Description Set HCI handle for ACL packet -** -** Returns None -** -*******************************************************************************/ -void l2cu_set_acl_hci_header (BT_HDR *p_buf, tL2C_CCB *p_ccb) -{ - UINT8 *p; - - /* Set the pointer to the beginning of the data minus 4 bytes for the packet header */ - p = (UINT8 *)(p_buf + 1) + p_buf->offset - HCI_DATA_PREAMBLE_SIZE; - -#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE) - if ( (((p_buf->layer_specific & L2CAP_FLUSHABLE_MASK) == L2CAP_FLUSHABLE_CH_BASED) && (p_ccb->is_flushable)) - || ((p_buf->layer_specific & L2CAP_FLUSHABLE_MASK) == L2CAP_FLUSHABLE_PKT) ) - { - UINT16_TO_STREAM (p, p_ccb->p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT)); - } - else - { - UINT16_TO_STREAM (p, p_ccb->p_lcb->handle | l2cb.non_flushable_pbf); - } -#else - UINT16_TO_STREAM (p, p_ccb->p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT)); -#endif -#if (BLE_INCLUDED == TRUE) - if (p_ccb->p_lcb->is_ble_link) - { - /* The HCI transport will segment the buffers. */ - if (p_buf->len > btu_cb.hcit_ble_acl_data_size) - { - UINT16_TO_STREAM (p, btu_cb.hcit_ble_acl_data_size); - } - else - { - UINT16_TO_STREAM (p, p_buf->len); - } - } /* (BLE_INCLUDED == TRUE) */ - else -#endif - { - - /* The HCI transport will segment the buffers. */ - if (p_buf->len > btu_cb.hcit_acl_data_size) - { - UINT16_TO_STREAM (p, btu_cb.hcit_acl_data_size); - } - else - { - UINT16_TO_STREAM (p, p_buf->len); - } - } - p_buf->offset -= HCI_DATA_PREAMBLE_SIZE; - p_buf->len += HCI_DATA_PREAMBLE_SIZE; + return status; } -/****************************************************************************** -** -** Function l2cu_check_channel_congestion -** -** Description check if any change in congestion status -** -** Returns None -** -*******************************************************************************/ -void l2cu_check_channel_congestion (tL2C_CCB *p_ccb) -{ - UINT16 q_count = p_ccb->xmit_hold_q.count; -#if (L2CAP_UCD_INCLUDED == TRUE) - if ( p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID ) - { - q_count += p_ccb->p_lcb->ucd_out_sec_pending_q.count; - } -#endif - /* If the CCB queue limit is subject to a quota, check for congestion */ - /* if this channel has outgoing traffic */ - if ((p_ccb->p_rcb)&&(p_ccb->buff_quota != 0)) - { - /* If this channel was congested */ - if ( p_ccb->cong_sent ) - { - /* If the channel is not congested now, tell the app */ - if (q_count <= (p_ccb->buff_quota / 2)) - { - p_ccb->cong_sent = FALSE; - if (p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb) - { - L2CAP_TRACE_DEBUG3 ("L2CAP - Calling CongestionStatus_Cb (FALSE), CID: 0x%04x xmit_hold_q.count: %u buff_quota: %u", - p_ccb->local_cid, q_count, p_ccb->buff_quota); - /* Prevent recursive calling */ - l2cb.is_cong_cback_context = TRUE; - (*p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)(p_ccb->local_cid, FALSE); - l2cb.is_cong_cback_context = FALSE; - } -#if (L2CAP_UCD_INCLUDED == TRUE) - else if ( p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID ) - { - if ( p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb ) - { - L2CAP_TRACE_DEBUG3 ("L2CAP - Calling UCD CongestionStatus_Cb (FALSE), SecPendingQ:%u,XmitQ:%u,Quota:%u", - p_ccb->p_lcb->ucd_out_sec_pending_q.count, - p_ccb->xmit_hold_q.count, p_ccb->buff_quota); - p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb( p_ccb->p_lcb->remote_bd_addr, FALSE ); - } - } -#endif - } - } - else - { - /* If this channel was not congested but it is congested now, tell the app */ - if (q_count > p_ccb->buff_quota) - { - p_ccb->cong_sent = TRUE; - if (p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb) - { - L2CAP_TRACE_DEBUG3 ("L2CAP - Calling CongestionStatus_Cb (TRUE),CID:0x%04x,XmitQ:%u,Quota:%u", - p_ccb->local_cid, q_count, p_ccb->buff_quota); - (*p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)(p_ccb->local_cid, TRUE); - } -#if (L2CAP_UCD_INCLUDED == TRUE) - else if ( p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID ) - { - if ( p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb ) - { - L2CAP_TRACE_DEBUG3 ("L2CAP - Calling UCD CongestionStatus_Cb (TRUE), SecPendingQ:%u,XmitQ:%u,Quota:%u", - p_ccb->p_lcb->ucd_out_sec_pending_q.count, - p_ccb->xmit_hold_q.count, p_ccb->buff_quota); - p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb( p_ccb->p_lcb->remote_bd_addr, TRUE ); - } - } -#endif - } - } - } -} diff --git a/src/revolution/BTE/wbt_ext.c b/src/revolution/BTE/wbt_ext.c new file mode 100644 index 0000000..0e3cc57 --- /dev/null +++ b/src/revolution/BTE/wbt_ext.c @@ -0,0 +1,43 @@ +#include +#include + +#include "wbt_api.h" +#include "data_types.h" +#include "hcidefs.h" +#include "sdpdefs.h" +#include "sdp_api.h" + +/* Creates the Broadcom extension SDP record used by the Wii. */ +BOOLEAN WBT_ExtCreateRecord(void) +{ + tSDP_DI_GET_RECORD get_device_info; + UINT32 sdp_record_handle = 0; + tSDP_DI_RECORD *p_set_info; + UINT8 temp_u16[2]; + UINT16 list = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP; + + if (SDP_GetLocalDiRecord(&get_device_info, &sdp_record_handle) != SDP_SUCCESS) + { + p_set_info = &get_device_info.rec; + + memset(p_set_info, 0, sizeof(*p_set_info)); + p_set_info->vendor = LMP_COMPID_BROADCOM; + p_set_info->vendor_id_source = DI_VENDOR_ID_SOURCE_BTSIG; + p_set_info->primary_record = TRUE; + + if (SDP_SetLocalDiRecord(p_set_info, &sdp_record_handle) != SDP_SUCCESS) + { + sdp_record_handle = 0; + return FALSE; + } + } + + SDP_AddUuidSequence(sdp_record_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &list); + + temp_u16[0] = 0; + temp_u16[1] = 1; + SDP_AddAttribute(sdp_record_handle, ATTR_ID_EXT_BRCM_VERSION, UINT_DESC_TYPE, + sizeof(temp_u16) / sizeof(temp_u16[0]), temp_u16); + + return TRUE; +}