Linux bluetooth development
 help / color / mirror / Atom feed
* Re: [PATCH v2 01/20] cyclingspeed: Add CSC profile plugin skeleton
From: Andrzej Kaczmarek @ 2012-12-03  9:09 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Johan Hedberg
In-Reply-To: <20121115093126.GA4414@x220>

Hi Johan,

On 11/15/2012 10:31 AM, Johan Hedberg wrote:
> Hi Andrzej,
>
> On Mon, Nov 05, 2012, Andrzej Kaczmarek wrote:
>> This patch adds stub profile driver plugin for CSC profile.
>> ---
>>   Makefile.am                          |   9 +-
>>   lib/uuid.h                           |   2 +
>>   profiles/cyclingspeed/cyclingspeed.c | 163 +++++++++++++++++++++++++++++++++++
>>   profiles/cyclingspeed/cyclingspeed.h |  26 ++++++
>>   profiles/cyclingspeed/main.c         |  53 ++++++++++++
>>   profiles/cyclingspeed/manager.c      |  79 +++++++++++++++++
>>   profiles/cyclingspeed/manager.h      |  24 ++++++
>>   7 files changed, 354 insertions(+), 2 deletions(-)
>>   create mode 100644 profiles/cyclingspeed/cyclingspeed.c
>>   create mode 100644 profiles/cyclingspeed/cyclingspeed.h
>>   create mode 100644 profiles/cyclingspeed/main.c
>>   create mode 100644 profiles/cyclingspeed/manager.c
>>   create mode 100644 profiles/cyclingspeed/manager.h
>
> You'll need to rebase these against latest git since this one doesn't
> apply cleanly (due to Makefile.am) and doesn't compile either (due to
> main_opts.gatt_enabled having been removed).

Sure, will do.

>> +struct csc_adapter {
>> +	struct btd_adapter	*adapter;
>> +	GSList			*devices;	/* list of registered devices */
>> +};
>> +
>> +struct csc {
>> +	struct btd_device	*dev;
>> +	struct csc_adapter	*cadapter;
>> +};
>
> I'm a bit worried that we've failed to create proper internal GATT APIs
> if they require this kind of per-profile tracking of devices and
> adapters. You can already get a list of btd_device from btd_adapter and
> the btd_adapter from a btd_device. Profiles should only need to track a
> very minimal amount of context.

Probably would be good to have some kind of API to attach profile 
specific data for particular device and/or adapter so we can get rid of 
duplicated code across plugins and just use one already existing list. 
Not sure how this could look like at the moment though.

>> +++ b/profiles/cyclingspeed/main.c
>> @@ -0,0 +1,53 @@

<snip>

>> +static int cyclingspeed_init(void)
>> +{
>> +	if (!main_opts.gatt_enabled) {
>> +		DBG("GATT is disabled");
>> +		return -ENOTSUP;
>> +	}
>> +
>> +	return cyclingspeed_manager_init();
>> +}
>> +
>> +static void cyclingspeed_exit(void)
>> +{
>> +	cyclingspeed_manager_exit();
>> +}
>> +
>> +BLUETOOTH_PLUGIN_DEFINE(cyclingspeed, VERSION,
>> +					BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
>> +					cyclingspeed_init, cyclingspeed_exit)
>
> If this is all the main.c file does seems like it should be merged into
> manager.c or even cyclingspeed.c.
>
>> +++ b/profiles/cyclingspeed/manager.c
>> @@ -0,0 +1,79 @@

<snip>

>> +
>> +static struct btd_profile cscp_profile = {
>> +	.name		= "Cycling Speed and Cadence GATT Driver",
>> +	.remote_uuids	= BTD_UUIDS(CYCLING_SC_UUID),
>> +
>> +	.adapter_probe	= csc_adapter_probe,
>> +	.adapter_remove	= csc_adapter_remove,
>> +
>> +	.device_probe	= csc_device_probe,
>> +	.device_remove	= csc_device_remove,
>> +};
>> +
>> +int cyclingspeed_manager_init(void)
>> +{
>> +	return btd_profile_register(&cscp_profile);
>> +}
>> +
>> +void cyclingspeed_manager_exit(void)
>> +{
>> +	btd_profile_unregister(&cscp_profile);
>> +}
>
> Are these functions ever going to do anything else than make single
> Vcalls into cyclingspeed.c? If not it seems to me like all this should
> be merged into that file.
>
> Btw, I do realize that other profiles might have similar brain dead
> design but that's not a good enough excuse to keep replicating the bad
> design. Instead the other profiles should be fixed.

Probably I'll just merge all this code into single cyclingspeed.c since 
all code in main.c and manager.c are just dumb calls and I don't see any 
need to extend them in future.

I'll try to send new patchset later today.

BR,
Andrzej

^ permalink raw reply

* Oops: sysfs duplicate filename on device reconnect
From: Matthew Gabeler-Lee @ 2012-12-03  6:33 UTC (permalink / raw)
  To: linux-bluetooth

[-- Attachment #1: Type: text/plain, Size: 685 bytes --]

I'm having what appears to be the same error as reported by Jebb
Stewart ("Problem pairing wiimote device via bluetooth", 2012-10-10),
but with a Logitech DiNovo Mini keyboard/mouse device, and the dongle
that comes with it.

In my case, the problem is possibly more severe than Jebb's, as the
Logitech device goes into a power saving mode after only a few seconds
of not typing, producing a bluetooth disconnect, and then reconnects
as soon as you touch it again.  Therefore, in normal usage, it is
disconnects and reconnects a lot.

The sysfs error I see is, AFAICT, identical to Jebb's.  I'm running a
vanilla 3.6.8 kernel.

An example of the error as it occurs for me is attached.

[-- Attachment #2: bthiderror.log --]
[-- Type: application/octet-stream, Size: 17452 bytes --]

Dec  3 00:37:01 cheetah kernel: Bluetooth: HIDP (Human Interface Emulation) ver 1.2
Dec  3 00:38:41 cheetah kernel: hid-generic 0005:046D:B30C.0005: unknown main item tag 0x0
Dec  3 00:38:41 cheetah kernel: input: Logitech diNovo Mini as /devices/pci0000:00/0000:00:1d.0/usb8/8-2/8-2.1/8-2.1:1.0/bluetooth/hci0/hci0:11/input14
Dec  3 00:38:41 cheetah kernel: hid-generic 0005:046D:B30C.0005: input,hidraw1: BLUETOOTH HID v0.44 Mouse [Logitech diNovo Mini] on 00:1F:20:08:FD:0F
Dec  3 00:39:11 cheetah kernel: ------------[ cut here ]------------
Dec  3 00:39:11 cheetah kernel: WARNING: at fs/sysfs/dir.c:536 sysfs_add_one+0xc3/0xf0()
Dec  3 00:39:11 cheetah kernel: Hardware name: MS-7666
Dec  3 00:39:11 cheetah kernel: sysfs: cannot create duplicate filename '/devices/pci0000:00/0000:00:1d.0/usb8/8-2/8-2.1/8-2.1:1.0/bluetooth/hci0/hci0:11'
Dec  3 00:39:11 cheetah kernel: Modules linked in: hidp tcp_diag cpufreq_ondemand cpufreq_userspace cpufreq_stats cpufreq_conservative cpufreq_powersave rfcomm bnep ppdev autofs4 tun binfmt_misc nfsd auth_rpcgss nfs_acl nfs lockd fscache sunrpc xt_NOTRACK iptable_raw xt_set ip_set_hash_net ip_set ip6table_mangle xt_hl nf_conntrack_ipv6 nf_defrag_ipv6 xt_hashlimit xt_multiport xt_LOG xt_tcpudp iptable_mangle xt_mark xt_state ip6table_filter ip6_tables iptable_filter nf_nat_h323 nf_nat_pptp nf_nat_ftp nf_nat_sip nf_nat_irc iptable_nat ip_tables nf_nat_proto_dccp nf_nat_proto_gre nf_nat_proto_udplite nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_conntrack_sip nf_conntrack_h323 nf_conntrack_proto_dccp nf_conntrack_netlink nfnetlink xt_conntrack x_tables nf_conntrack_proto_udplite nf_conntrack_irc nf_conntrack_pptp nf_conntrack_proto_gre nf_conntrack_ftp nf_conntrack ipv6 btusb bluetooth rfkill dm_crypt hid_generic quota_v2 quota_tree fuse inet_diag pl2303 usbserial usb_storage uas nvidia(PO) coretemp kvm_intel kvm crc3
Dec  3 00:39:11 cheetah kernel: c_intel ghash_clmulni_intel aesni_intel aes_x86_64 snd_hda_codec_realtek aes_generic ablk_helper cryptd acpi_cpufreq uhci_hcd mperf snd_hda_intel snd_hda_codec iTCO_wdt iTCO_vendor_support gpio_ich freq_table snd_pcm snd_page_alloc snd_timer firewire_ohci i2c_i801 microcode lpc_ich processor sg r8169 firewire_core snd serio_raw button ehci_hcd wmi soundcore xhci_hcd crc_itu_t mfd_core mii
Dec  3 00:39:11 cheetah kernel: Pid: 7, comm: kworker/u:0H Tainted: P           O 3.6.8 #1
Dec  3 00:39:11 cheetah kernel: Call Trace:
Dec  3 00:39:11 cheetah kernel:  [<ffffffff81035419>] ? warn_slowpath_common+0x79/0xc0
Dec  3 00:39:11 cheetah kernel:  [<ffffffff81035515>] ? warn_slowpath_fmt+0x45/0x50
Dec  3 00:39:11 cheetah kernel:  [<ffffffff81151a73>] ? sysfs_add_one+0xc3/0xf0
Dec  3 00:39:11 cheetah kernel:  [<ffffffff81151c82>] ? create_dir+0x72/0xd0
Dec  3 00:39:11 cheetah kernel:  [<ffffffff81151fe3>] ? sysfs_create_dir+0x83/0xe0
Dec  3 00:39:11 cheetah kernel:  [<ffffffff81229f10>] ? kobject_add_internal+0x90/0x210
Dec  3 00:39:11 cheetah kernel:  [<ffffffff8122a65e>] ? kobject_add+0x6e/0xc0
Dec  3 00:39:11 cheetah kernel:  [<ffffffff810e2ac8>] ? kmem_cache_alloc+0xd8/0xe0
Dec  3 00:39:11 cheetah kernel:  [<ffffffff812d5bd1>] ? device_add+0x101/0x690
Dec  3 00:39:11 cheetah kernel:  [<ffffffff812d45f2>] ? dev_set_name+0x42/0x50
Dec  3 00:39:11 cheetah kernel:  [<ffffffffa01c408d>] ? hci_conn_add_sysfs+0x3d/0x80 [bluetooth]
Dec  3 00:39:11 cheetah kernel:  [<ffffffffa01b9102>] ? hci_event_packet+0x102/0x27b0 [bluetooth]
Dec  3 00:39:11 cheetah kernel:  [<ffffffffa01b05bb>] ? hci_rx_work+0x27b/0x330 [bluetooth]
Dec  3 00:39:11 cheetah kernel:  [<ffffffff81042213>] ? lock_timer_base.isra.33+0x33/0x70
Dec  3 00:39:11 cheetah kernel:  [<ffffffff81041e68>] ? internal_add_timer+0x18/0x50
Dec  3 00:39:11 cheetah kernel:  [<ffffffff81042453>] ? mod_timer+0x103/0x1c0
Dec  3 00:39:11 cheetah kernel:  [<ffffffff8104ce86>] ? process_one_work+0x126/0x450
Dec  3 00:39:11 cheetah kernel:  [<ffffffff8104aede>] ? cwq_activate_delayed_work+0x2e/0x50
Dec  3 00:39:11 cheetah kernel:  [<ffffffffa01b0340>] ? hci_send_frame+0x90/0x90 [bluetooth]
Dec  3 00:39:11 cheetah kernel:  [<ffffffff8104d57d>] ? worker_thread+0x15d/0x440
Dec  3 00:39:11 cheetah kernel:  [<ffffffff8104d420>] ? rescuer_thread+0x230/0x230
Dec  3 00:39:11 cheetah kernel:  [<ffffffff81052245>] ? kthread+0x85/0x90
Dec  3 00:39:11 cheetah kernel:  [<ffffffff814642f4>] ? kernel_thread_helper+0x4/0x10
Dec  3 00:39:11 cheetah kernel:  [<ffffffff810521c0>] ? kthread_freezable_should_stop+0x60/0x60
Dec  3 00:39:11 cheetah kernel:  [<ffffffff814642f0>] ? gs_change+0xb/0xb
Dec  3 00:39:11 cheetah kernel: ---[ end trace 0dcb8b510e7dd429 ]---
Dec  3 00:39:11 cheetah kernel: ------------[ cut here ]------------
Dec  3 00:39:11 cheetah kernel: WARNING: at lib/kobject.c:196 kobject_add_internal+0x1f4/0x210()
Dec  3 00:39:11 cheetah kernel: Hardware name: MS-7666
Dec  3 00:39:11 cheetah kernel: kobject_add_internal failed for hci0:11 with -EEXIST, don't try to register things with the same name in the same directory.
Dec  3 00:39:11 cheetah kernel: Modules linked in: hidp tcp_diag cpufreq_ondemand cpufreq_userspace cpufreq_stats cpufreq_conservative cpufreq_powersave rfcomm bnep ppdev autofs4 tun binfmt_misc nfsd auth_rpcgss nfs_acl nfs lockd fscache sunrpc xt_NOTRACK iptable_raw xt_set ip_set_hash_net ip_set ip6table_mangle xt_hl nf_conntrack_ipv6 nf_defrag_ipv6 xt_hashlimit xt_multiport xt_LOG xt_tcpudp iptable_mangle xt_mark xt_state ip6table_filter ip6_tables iptable_filter nf_nat_h323 nf_nat_pptp nf_nat_ftp nf_nat_sip nf_nat_irc iptable_nat ip_tables nf_nat_proto_dccp nf_nat_proto_gre nf_nat_proto_udplite nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_conntrack_sip nf_conntrack_h323 nf_conntrack_proto_dccp nf_conntrack_netlink nfnetlink xt_conntrack x_tables nf_conntrack_proto_udplite nf_conntrack_irc nf_conntrack_pptp nf_conntrack_proto_gre nf_conntrack_ftp nf_conntrack ipv6 btusb bluetooth rfkill dm_crypt hid_generic quota_v2 quota_tree fuse inet_diag pl2303 usbserial usb_storage uas nvidia(PO) coretemp kvm_intel kvm crc3
Dec  3 00:39:11 cheetah kernel: c_intel ghash_clmulni_intel aesni_intel aes_x86_64 snd_hda_codec_realtek aes_generic ablk_helper cryptd acpi_cpufreq uhci_hcd mperf snd_hda_intel snd_hda_codec iTCO_wdt iTCO_vendor_support gpio_ich freq_table snd_pcm snd_page_alloc snd_timer firewire_ohci i2c_i801 microcode lpc_ich processor sg r8169 firewire_core snd serio_raw button ehci_hcd wmi soundcore xhci_hcd crc_itu_t mfd_core mii
Dec  3 00:39:11 cheetah kernel: Pid: 7, comm: kworker/u:0H Tainted: P        W  O 3.6.8 #1
Dec  3 00:39:11 cheetah kernel: Call Trace:
Dec  3 00:39:11 cheetah kernel:  [<ffffffff81035419>] ? warn_slowpath_common+0x79/0xc0
Dec  3 00:39:11 cheetah kernel:  [<ffffffff81035515>] ? warn_slowpath_fmt+0x45/0x50
Dec  3 00:39:11 cheetah kernel:  [<ffffffff81151fe3>] ? sysfs_create_dir+0x83/0xe0
Dec  3 00:39:11 cheetah kernel:  [<ffffffff8122a074>] ? kobject_add_internal+0x1f4/0x210
Dec  3 00:39:11 cheetah kernel:  [<ffffffff8122a65e>] ? kobject_add+0x6e/0xc0
Dec  3 00:39:11 cheetah kernel:  [<ffffffff810e2ac8>] ? kmem_cache_alloc+0xd8/0xe0
Dec  3 00:39:11 cheetah kernel:  [<ffffffff812d5bd1>] ? device_add+0x101/0x690
Dec  3 00:39:11 cheetah kernel:  [<ffffffff812d45f2>] ? dev_set_name+0x42/0x50
Dec  3 00:39:11 cheetah kernel:  [<ffffffffa01c408d>] ? hci_conn_add_sysfs+0x3d/0x80 [bluetooth]
Dec  3 00:39:11 cheetah kernel:  [<ffffffffa01b9102>] ? hci_event_packet+0x102/0x27b0 [bluetooth]
Dec  3 00:39:11 cheetah kernel:  [<ffffffffa01b05bb>] ? hci_rx_work+0x27b/0x330 [bluetooth]
Dec  3 00:39:11 cheetah kernel:  [<ffffffff81042213>] ? lock_timer_base.isra.33+0x33/0x70
Dec  3 00:39:11 cheetah kernel:  [<ffffffff81041e68>] ? internal_add_timer+0x18/0x50
Dec  3 00:39:11 cheetah kernel:  [<ffffffff81042453>] ? mod_timer+0x103/0x1c0
Dec  3 00:39:11 cheetah kernel:  [<ffffffff8104ce86>] ? process_one_work+0x126/0x450
Dec  3 00:39:11 cheetah kernel:  [<ffffffff8104aede>] ? cwq_activate_delayed_work+0x2e/0x50
Dec  3 00:39:11 cheetah kernel:  [<ffffffffa01b0340>] ? hci_send_frame+0x90/0x90 [bluetooth]
Dec  3 00:39:11 cheetah kernel:  [<ffffffff8104d57d>] ? worker_thread+0x15d/0x440
Dec  3 00:39:11 cheetah kernel:  [<ffffffff8104d420>] ? rescuer_thread+0x230/0x230
Dec  3 00:39:11 cheetah kernel:  [<ffffffff81052245>] ? kthread+0x85/0x90
Dec  3 00:39:11 cheetah kernel:  [<ffffffff814642f4>] ? kernel_thread_helper+0x4/0x10
Dec  3 00:39:11 cheetah kernel:  [<ffffffff810521c0>] ? kthread_freezable_should_stop+0x60/0x60
Dec  3 00:39:11 cheetah kernel:  [<ffffffff814642f0>] ? gs_change+0xb/0xb
Dec  3 00:39:11 cheetah kernel: ---[ end trace 0dcb8b510e7dd42a ]---
Dec  3 00:39:11 cheetah kernel: Bluetooth: Failed to register connection device
Dec  3 00:39:14 cheetah kernel: power_supply hid-00:1F:20:05:16:2D-battery: driver failed to report `capacity' property: -5
Dec  3 00:39:19 cheetah kernel: power_supply hid-00:1F:20:05:16:2D-battery: driver failed to report `capacity' property: -5
Dec  3 00:39:20 cheetah kernel: ------------[ cut here ]------------
Dec  3 00:39:20 cheetah kernel: WARNING: at lib/kobject.c:200 kobject_add_internal+0xf3/0x210()
Dec  3 00:39:20 cheetah kernel: Hardware name: MS-7666
Dec  3 00:39:20 cheetah kernel: kobject_add_internal failed for 0005:046D:B30C.0006 (error: -2 parent: hci0:11)
Dec  3 00:39:20 cheetah kernel: Modules linked in: hidp tcp_diag cpufreq_ondemand cpufreq_userspace cpufreq_stats cpufreq_conservative cpufreq_powersave rfcomm bnep ppdev autofs4 tun binfmt_misc nfsd auth_rpcgss nfs_acl nfs lockd fscache sunrpc xt_NOTRACK iptable_raw xt_set ip_set_hash_net ip_set ip6table_mangle xt_hl nf_conntrack_ipv6 nf_defrag_ipv6 xt_hashlimit xt_multiport xt_LOG xt_tcpudp iptable_mangle xt_mark xt_state ip6table_filter ip6_tables iptable_filter nf_nat_h323 nf_nat_pptp nf_nat_ftp nf_nat_sip nf_nat_irc iptable_nat ip_tables nf_nat_proto_dccp nf_nat_proto_gre nf_nat_proto_udplite nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_conntrack_sip nf_conntrack_h323 nf_conntrack_proto_dccp nf_conntrack_netlink nfnetlink xt_conntrack x_tables nf_conntrack_proto_udplite nf_conntrack_irc nf_conntrack_pptp nf_conntrack_proto_gre nf_conntrack_ftp nf_conntrack ipv6 btusb bluetooth rfkill dm_crypt hid_generic quota_v2 quota_tree fuse inet_diag pl2303 usbserial usb_storage uas nvidia(PO) coretemp kvm_intel kvm crc3
Dec  3 00:39:20 cheetah kernel: c_intel ghash_clmulni_intel aesni_intel aes_x86_64 snd_hda_codec_realtek aes_generic ablk_helper cryptd acpi_cpufreq uhci_hcd mperf snd_hda_intel snd_hda_codec iTCO_wdt iTCO_vendor_support gpio_ich freq_table snd_pcm snd_page_alloc snd_timer firewire_ohci i2c_i801 microcode lpc_ich processor sg r8169 firewire_core snd serio_raw button ehci_hcd wmi soundcore xhci_hcd crc_itu_t mfd_core mii
Dec  3 00:39:20 cheetah kernel: Pid: 12986, comm: bluetoothd Tainted: P        W  O 3.6.8 #1
Dec  3 00:39:20 cheetah kernel: Call Trace:
Dec  3 00:39:20 cheetah kernel:  [<ffffffff81035419>] ? warn_slowpath_common+0x79/0xc0
Dec  3 00:39:20 cheetah kernel:  [<ffffffff81035515>] ? warn_slowpath_fmt+0x45/0x50
Dec  3 00:39:20 cheetah kernel:  [<ffffffff81229f73>] ? kobject_add_internal+0xf3/0x210
Dec  3 00:39:20 cheetah kernel:  [<ffffffff8122a65e>] ? kobject_add+0x6e/0xc0
Dec  3 00:39:20 cheetah kernel:  [<ffffffff810e2ac8>] ? kmem_cache_alloc+0xd8/0xe0
Dec  3 00:39:20 cheetah kernel:  [<ffffffff812d5bd1>] ? device_add+0x101/0x690
Dec  3 00:39:20 cheetah kernel:  [<ffffffff812d45f2>] ? dev_set_name+0x42/0x50
Dec  3 00:39:20 cheetah kernel:  [<ffffffff81392bcc>] ? hid_add_device+0x1bc/0x410
Dec  3 00:39:20 cheetah kernel:  [<ffffffffa010cbbb>] ? hidp_add_connection+0x3fb/0x880 [hidp]
Dec  3 00:39:20 cheetah kernel:  [<ffffffff81052b80>] ? abort_exclusive_wait+0xb0/0xb0
Dec  3 00:39:20 cheetah kernel:  [<ffffffffa010d47f>] ? hidp_sock_ioctl+0x20f/0x2c0 [hidp]
Dec  3 00:39:20 cheetah kernel:  [<ffffffff813ad48a>] ? sock_do_ioctl.constprop.45+0x1a/0x50
Dec  3 00:39:20 cheetah kernel:  [<ffffffff813ad73f>] ? sock_ioctl+0x5f/0x260
Dec  3 00:39:20 cheetah kernel:  [<ffffffff810fd0d7>] ? do_vfs_ioctl+0x97/0x590
Dec  3 00:39:20 cheetah kernel:  [<ffffffff813ac756>] ? sock_alloc_file+0xa6/0x120
Dec  3 00:39:20 cheetah kernel:  [<ffffffff810ea443>] ? fd_install+0x33/0x70
Dec  3 00:39:20 cheetah kernel:  [<ffffffff810fd619>] ? sys_ioctl+0x49/0x80
Dec  3 00:39:20 cheetah kernel:  [<ffffffff814631a6>] ? system_call_fastpath+0x1a/0x1f
Dec  3 00:39:20 cheetah kernel: ---[ end trace 0dcb8b510e7dd42b ]---
Dec  3 00:39:20 cheetah kernel: VFS: Close: file count is 0
Dec  3 00:39:20 cheetah kernel: BUG: unable to handle kernel NULL pointer dereference at           (null)
Dec  3 00:39:20 cheetah kernel: IP: [<ffffffff81462748>] _raw_spin_lock_irqsave+0x8/0x30
Dec  3 00:39:20 cheetah kernel: PGD 0 
Dec  3 00:39:20 cheetah kernel: Oops: 0002 [#1] SMP 
Dec  3 00:39:20 cheetah kernel: Modules linked in: hidp tcp_diag cpufreq_ondemand cpufreq_userspace cpufreq_stats cpufreq_conservative cpufreq_powersave rfcomm bnep ppdev autofs4 tun binfmt_misc nfsd auth_rpcgss nfs_acl nfs lockd fscache sunrpc xt_NOTRACK iptable_raw xt_set ip_set_hash_net ip_set ip6table_mangle xt_hl nf_conntrack_ipv6 nf_defrag_ipv6 xt_hashlimit xt_multiport xt_LOG xt_tcpudp iptable_mangle xt_mark xt_state ip6table_filter ip6_tables iptable_filter nf_nat_h323 nf_nat_pptp nf_nat_ftp nf_nat_sip nf_nat_irc iptable_nat ip_tables nf_nat_proto_dccp nf_nat_proto_gre nf_nat_proto_udplite nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_conntrack_sip nf_conntrack_h323 nf_conntrack_proto_dccp nf_conntrack_netlink nfnetlink xt_conntrack x_tables nf_conntrack_proto_udplite nf_conntrack_irc nf_conntrack_pptp nf_conntrack_proto_gre nf_conntrack_ftp nf_conntrack ipv6 btusb bluetooth rfkill dm_crypt hid_generic quota_v2 quota_tree fuse inet_diag pl2303 usbserial usb_storage uas nvidia(PO) coretemp kvm_intel kvm crc3
Dec  3 00:39:20 cheetah kernel: c_intel ghash_clmulni_intel aesni_intel aes_x86_64 snd_hda_codec_realtek aes_generic ablk_helper cryptd acpi_cpufreq uhci_hcd mperf snd_hda_intel snd_hda_codec iTCO_wdt iTCO_vendor_support gpio_ich freq_table snd_pcm snd_page_alloc snd_timer firewire_ohci i2c_i801 microcode lpc_ich processor sg r8169 firewire_core snd serio_raw button ehci_hcd wmi soundcore xhci_hcd crc_itu_t mfd_core mii
Dec  3 00:39:20 cheetah kernel: CPU 2 
Dec  3 00:39:20 cheetah kernel: Pid: 14607, comm: khidpd_046db30c Tainted: P        W  O 3.6.8 #1 MSI MS-7666/Big Bang-XPower (MS-7666)
Dec  3 00:39:20 cheetah kernel: RIP: 0010:[<ffffffff81462748>]  [<ffffffff81462748>] _raw_spin_lock_irqsave+0x8/0x30
Dec  3 00:39:20 cheetah kernel: RSP: 0018:ffff880194f47dc8  EFLAGS: 00010093
Dec  3 00:39:20 cheetah kernel: RAX: 0000000000000293 RBX: ffff880194f47e98 RCX: 0000000000000001
Dec  3 00:39:20 cheetah kernel: RDX: 0000000000000100 RSI: ffff880194f47e98 RDI: 0000000000000000
Dec  3 00:39:20 cheetah kernel: RBP: ffff880194f47eb0 R08: ffff880194f46000 R09: 0000000000000000
Dec  3 00:39:20 cheetah kernel: R10: 0000000000000001 R11: 0000000000000001 R12: 0000000000000000
Dec  3 00:39:20 cheetah kernel: R13: ffff8801a3a944b8 R14: ffff88019ab74468 R15: 0000000000000000
Dec  3 00:39:20 cheetah kernel: FS:  0000000000000000(0000) GS:ffff8801bfc40000(0000) knlGS:0000000000000000
Dec  3 00:39:20 cheetah kernel: CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
Dec  3 00:39:20 cheetah kernel: CR2: 0000000000000000 CR3: 00000000015d6000 CR4: 00000000000007e0
Dec  3 00:39:20 cheetah kernel: DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
Dec  3 00:39:20 cheetah kernel: DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Dec  3 00:39:20 cheetah kernel: Process khidpd_046db30c (pid: 14607, threadinfo ffff880194f46000, task ffff8801b712f2c0)
Dec  3 00:39:20 cheetah kernel: Stack:
Dec  3 00:39:20 cheetah kernel:  ffffffff8105284a ffff8801a3a94400 0000000000000000 ffff88019ab74400
Dec  3 00:39:20 cheetah kernel:  ffffffffa010c46d ffff8801b80b5940 ffff88019ab76068 ffff8801b712f2c0
Dec  3 00:39:20 cheetah kernel:  ffff88019ab74400 ffff88019ab76000 ffff88019ab74468 ffff8801a3a94518
Dec  3 00:39:20 cheetah kernel: Call Trace:
Dec  3 00:39:20 cheetah kernel:  [<ffffffff8105284a>] ? finish_wait+0x3a/0x90
Dec  3 00:39:20 cheetah kernel:  [<ffffffffa010c46d>] ? hidp_session+0x52d/0x880 [hidp]
Dec  3 00:39:20 cheetah kernel:  [<ffffffff8105e760>] ? try_to_wake_up+0x280/0x280
Dec  3 00:39:20 cheetah kernel:  [<ffffffff8105e760>] ? try_to_wake_up+0x280/0x280
Dec  3 00:39:20 cheetah kernel:  [<ffffffff81052b80>] ? abort_exclusive_wait+0xb0/0xb0
Dec  3 00:39:20 cheetah kernel:  [<ffffffffa010bf40>] ? hidp_input_report.isra.8+0x2c0/0x2c0 [hidp]
Dec  3 00:39:20 cheetah kernel:  [<ffffffff81052245>] ? kthread+0x85/0x90
Dec  3 00:39:20 cheetah kernel:  [<ffffffff814642f4>] ? kernel_thread_helper+0x4/0x10
Dec  3 00:39:20 cheetah kernel:  [<ffffffff810521c0>] ? kthread_freezable_should_stop+0x60/0x60
Dec  3 00:39:20 cheetah kernel:  [<ffffffff814642f0>] ? gs_change+0xb/0xb
Dec  3 00:39:20 cheetah kernel: Code: 38 c2 74 10 0f 1f 80 00 00 00 00 f3 90 0f b6 07 38 d0 75 f7 c3 66 66 66 66 66 2e 0f 1f 84 00 00 00 00 00 9c 58 fa ba 00 01 00 00 <f0> 66 0f c1 17 0f b6 ce 38 d1 74 0d 0f 1f 40 00 f3 90 0f b6 17 
Dec  3 00:39:20 cheetah kernel: RIP  [<ffffffff81462748>] _raw_spin_lock_irqsave+0x8/0x30
Dec  3 00:39:20 cheetah kernel:  RSP <ffff880194f47dc8>
Dec  3 00:39:20 cheetah kernel: CR2: 0000000000000000
Dec  3 00:39:20 cheetah kernel: ---[ end trace 0dcb8b510e7dd42c ]---

^ permalink raw reply

* [RFC v3 obexd 10/10] fuse: Add rename operation
From: Michał Poczwardowski @ 2012-12-01 23:14 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Michał Poczwardowski
In-Reply-To: <1354403695-18985-1-git-send-email-dmp0x7c5@gmail.com>

---
 fuse/helpers.c  |   46 ++++++++++++++++++++++++++++++++++++++++++++++
 fuse/helpers.h  |    3 +++
 fuse/obexfuse.c |   16 ++++++++++++++++
 3 files changed, 65 insertions(+), 0 deletions(-)

diff --git a/fuse/helpers.c b/fuse/helpers.c
index a523cc3..e45591d 100644
--- a/fuse/helpers.c
+++ b/fuse/helpers.c
@@ -736,3 +736,49 @@ void obexhlp_delete(struct obexhlp_session* session, const char *path)
 	free_location(l);
 	request_wait_free(session);
 }
+
+void obexhlp_mkdir(struct obexhlp_session* session, const char *path)
+{
+	struct obexhlp_location *l;
+	struct stat *stbuf;
+
+	g_print("obexhlp_mkdir(%s)\n", path);
+
+	l = get_location(path);
+	obexhlp_setpath(session, l->dir);
+
+	request_new(session, g_strdup_printf("mkdir %s", path));
+	/* g_obex_mkdir also sets path, to new folder */
+	g_obex_mkdir(session->obex, l->file, response_func, session,
+							&session->err);
+	g_free(session->setpath);
+	session->setpath = g_strdup(path);
+
+	stbuf = g_malloc0(sizeof(struct stat));
+	stbuf->st_mode = S_IFDIR;
+	stbuf->st_mtime = time(NULL);
+	g_hash_table_replace(session->file_stat, g_strdup(path), stbuf);
+
+	free_location(l);
+	request_wait_free(session);
+}
+
+void obexhlp_move(struct obexhlp_session* session, const char *oldpath,
+						const char* newpath)
+{
+	struct obexhlp_location *l_from, *l_to;
+
+	l_to = get_location(newpath);
+	l_from = get_location(oldpath);
+	obexhlp_setpath(session, l_from->dir);
+
+	g_print("obexhlp_move(%s to %s)\n", l_from->file, l_to->file);
+
+	request_new(session, g_strdup_printf("move %s:%s",
+					oldpath, newpath));
+	g_obex_move(session->obex, l_from->file, l_to->file, response_func,
+						session, &session->err);
+	free_location(l_to);
+	free_location(l_from);
+	request_wait_free(session);
+}
diff --git a/fuse/helpers.h b/fuse/helpers.h
index 362e322..5ace3ea 100644
--- a/fuse/helpers.h
+++ b/fuse/helpers.h
@@ -62,3 +62,6 @@ void obexhlp_put(struct obexhlp_session* session,
 					const char *path);
 void obexhlp_touch(struct obexhlp_session* session, const char *path);
 void obexhlp_delete(struct obexhlp_session* session, const char *path);
+void obexhlp_mkdir(struct obexhlp_session* session, const char *path);
+void obexhlp_move(struct obexhlp_session* session, const char *oldpath,
+					const char* newpath);
diff --git a/fuse/obexfuse.c b/fuse/obexfuse.c
index 065b6a6..a08f720 100644
--- a/fuse/obexfuse.c
+++ b/fuse/obexfuse.c
@@ -237,6 +237,20 @@ static int obexfuse_unlink(const char *path)
 	return session->status;
 }
 
+static int obexfuse_mkdir(const char *path, mode_t mode)
+{
+	obexhlp_mkdir(session, path);
+
+	return session->status;
+}
+
+static int obexfuse_rename(const char *from, const char *to)
+{
+	obexhlp_move(session, from, to);
+
+	return session->status;
+}
+
 static struct fuse_operations obexfuse_oper = {
 	.readdir = obexfuse_readdir,
 	.getattr = obexfuse_getattr,
@@ -249,6 +263,8 @@ static struct fuse_operations obexfuse_oper = {
 	.mknod = obexfuse_mknod,
 	.unlink = obexfuse_unlink,
 	.rmdir = obexfuse_unlink,
+	.mkdir = obexfuse_mkdir,
+	.rename = obexfuse_rename,
 	.init = obexfuse_init,
 	.destroy = obexfuse_destroy,
 };
-- 
1.7.8.6


^ permalink raw reply related

* [RFC v3 obexd 09/10] fuse: Add unlink/rmdir operation
From: Michał Poczwardowski @ 2012-12-01 23:14 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Michał Poczwardowski
In-Reply-To: <1354403695-18985-1-git-send-email-dmp0x7c5@gmail.com>

---
 fuse/helpers.c  |   28 ++++++++++++++++++++++++++++
 fuse/helpers.h  |    1 +
 fuse/obexfuse.c |    9 +++++++++
 3 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/fuse/helpers.c b/fuse/helpers.c
index b4bd7e5..a523cc3 100644
--- a/fuse/helpers.c
+++ b/fuse/helpers.c
@@ -665,6 +665,16 @@ void obexhlp_put(struct obexhlp_session* session,
 
 	g_print("obexhlp_put(%s%s)\n", l->dir, l->file);
 
+	if (g_strcmp0(path, session->vtouch_path) == 0 &&
+				session->vtouch == TRUE) {
+		session->vtouch = FALSE;
+		g_free(session->vtouch_path);
+	} else {
+		/* delete existing file */
+		if (session->rtouch == FALSE)
+			obexhlp_delete(session, path);
+	}
+
 	obexhlp_setpath(session, l->dir);
 	buffer->tmpsize = 0;
 	session->buffer = buffer;
@@ -708,3 +718,21 @@ void obexhlp_touch_real(struct obexhlp_session* session, gchar *path)
 
 	session->buffer = tmpbuf;
 }
+
+void obexhlp_delete(struct obexhlp_session* session, const char *path)
+{
+	struct obexhlp_location *l;
+	l = get_location(path);
+
+	g_print("obexhlp_delete(%s)\n", l->file);
+
+	obexhlp_setpath(session, l->dir);
+	request_new(session, g_strdup_printf("delete %s", path));
+	g_obex_delete(session->obex, l->file, response_func, session,
+							&session->err);
+
+	g_hash_table_remove(session->file_stat, path);
+
+	free_location(l);
+	request_wait_free(session);
+}
diff --git a/fuse/helpers.h b/fuse/helpers.h
index 4372fdf..362e322 100644
--- a/fuse/helpers.h
+++ b/fuse/helpers.h
@@ -61,3 +61,4 @@ void obexhlp_put(struct obexhlp_session* session,
 					struct obexhlp_buffer *buffer,
 					const char *path);
 void obexhlp_touch(struct obexhlp_session* session, const char *path);
+void obexhlp_delete(struct obexhlp_session* session, const char *path);
diff --git a/fuse/obexfuse.c b/fuse/obexfuse.c
index 4a9f297..065b6a6 100644
--- a/fuse/obexfuse.c
+++ b/fuse/obexfuse.c
@@ -230,6 +230,13 @@ static int obexfuse_mknod(const char *path, mode_t mode, dev_t dev)
 	return 0;
 }
 
+static int obexfuse_unlink(const char *path)
+{
+	obexhlp_delete(session, path);
+
+	return session->status;
+}
+
 static struct fuse_operations obexfuse_oper = {
 	.readdir = obexfuse_readdir,
 	.getattr = obexfuse_getattr,
@@ -240,6 +247,8 @@ static struct fuse_operations obexfuse_oper = {
 	.release = obexfuse_release,
 	.utimens = obexfuse_utimens,
 	.mknod = obexfuse_mknod,
+	.unlink = obexfuse_unlink,
+	.rmdir = obexfuse_unlink,
 	.init = obexfuse_init,
 	.destroy = obexfuse_destroy,
 };
-- 
1.7.8.6


^ permalink raw reply related

* [RFC v3 obexd 08/10] fuse: Add write and touch operations
From: Michał Poczwardowski @ 2012-12-01 23:14 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Michał Poczwardowski
In-Reply-To: <1354403695-18985-1-git-send-email-dmp0x7c5@gmail.com>

---
 fuse/helpers.c  |   84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 fuse/helpers.h  |    4 ++
 fuse/obexfuse.c |   61 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 149 insertions(+), 0 deletions(-)

diff --git a/fuse/helpers.c b/fuse/helpers.c
index 72b0b3e..b4bd7e5 100644
--- a/fuse/helpers.c
+++ b/fuse/helpers.c
@@ -56,6 +56,8 @@ struct obexhlp_location {
 	gchar *file;
 };
 
+void obexhlp_touch_real(struct obexhlp_session* session, gchar *path);
+
 static volatile sig_atomic_t __sdp_io_finished = 0;
 
 /* adopted from client/bluetooth.c - search_callback() */
@@ -326,6 +328,12 @@ void request_new(struct obexhlp_session *session,
 {
 	g_print("REQUEST %s\n", name);
 
+	if (session->vtouch == TRUE) {
+		session->vtouch = FALSE;
+		obexhlp_touch_real(session, session->vtouch_path);
+		g_free(session->vtouch_path);
+	}
+
 	if (session->request != NULL)
 		g_error("Another request (%s) active!\n",
 					session->request->name);
@@ -624,3 +632,79 @@ struct obexhlp_buffer *obexhlp_get(struct obexhlp_session* session,
 
 	return buffer;
 }
+
+static gssize async_put_producer(void *buf, gsize len, gpointer user_data)
+{
+	gssize size;
+	struct obexhlp_session *session = user_data;
+	struct obexhlp_buffer *buffer = session->buffer;
+
+	size = buffer->size - buffer->tmpsize;
+
+	if (size > len)
+		size = len;
+
+	g_obex_suspend(session->obex);
+	g_obex_resume(session->obex);
+
+	if (size == 0)
+		return 0;
+
+	memcpy(buf, buffer->data + buffer->tmpsize, size);
+	buffer->tmpsize += size;
+
+	return size;
+}
+
+void obexhlp_put(struct obexhlp_session* session,
+				struct obexhlp_buffer *buffer,
+				const char *path)
+{
+	struct obexhlp_location *l;
+	l = get_location(path);
+
+	g_print("obexhlp_put(%s%s)\n", l->dir, l->file);
+
+	obexhlp_setpath(session, l->dir);
+	buffer->tmpsize = 0;
+	session->buffer = buffer;
+	request_new(session, g_strdup_printf("put %s", path));
+	g_obex_put_req(session->obex, async_put_producer,
+					complete_func, session, &session->err,
+					G_OBEX_HDR_NAME, l->file,
+					G_OBEX_HDR_INVALID);
+	free_location(l);
+	request_wait_free(session);
+}
+
+/* virtual file creation */
+void obexhlp_touch(struct obexhlp_session* session, const char *path)
+{
+	struct stat *stbuf;
+
+	g_print("obexhlp_touch(%s)\n", path);
+
+	stbuf = g_malloc0(sizeof(struct stat));
+	stbuf->st_mode = S_IFREG;
+	g_hash_table_replace(session->file_stat, g_strdup(path), stbuf);
+
+	session->vtouch = TRUE;
+	session->vtouch_path = g_strdup(path);
+}
+
+void obexhlp_touch_real(struct obexhlp_session* session, gchar *path)
+{
+	struct obexhlp_buffer *buffer, *tmpbuf;
+
+	g_print("obexhlp_touch_real(%s)\n", path);
+
+	tmpbuf = session->buffer; /* save buffer state */
+
+	buffer = g_malloc0(sizeof(struct obexhlp_buffer));
+	session->rtouch = TRUE;
+	obexhlp_put(session, buffer, path);
+	session->rtouch = FALSE;
+	g_free(buffer);
+
+	session->buffer = tmpbuf;
+}
diff --git a/fuse/helpers.h b/fuse/helpers.h
index 9080590..4372fdf 100644
--- a/fuse/helpers.h
+++ b/fuse/helpers.h
@@ -57,3 +57,7 @@ struct stat *obexhlp_getattr(struct obexhlp_session* session,
 					const char *path);
 struct obexhlp_buffer *obexhlp_get(struct obexhlp_session* session,
 					const char *path);
+void obexhlp_put(struct obexhlp_session* session,
+					struct obexhlp_buffer *buffer,
+					const char *path);
+void obexhlp_touch(struct obexhlp_session* session, const char *path);
diff --git a/fuse/obexfuse.c b/fuse/obexfuse.c
index e185250..4a9f297 100644
--- a/fuse/obexfuse.c
+++ b/fuse/obexfuse.c
@@ -174,11 +174,72 @@ static int obexfuse_read(const char *path, char *buf, size_t size,
 	return asize;
 }
 
+static int obexfuse_write(const char *path, const char *buf, size_t size,
+				off_t offset, struct fuse_file_info *fi)
+{
+	gsize nsize;
+	struct obexhlp_buffer *file_buffer = (struct obexhlp_buffer*)fi->fh;
+
+	if (file_buffer->size < offset + size) {
+		nsize = offset + size;
+		file_buffer->data = g_realloc(file_buffer->data, nsize);
+		file_buffer->size = nsize;
+	} else {
+		nsize = file_buffer->size;
+	}
+
+	file_buffer->edited = TRUE;
+	memcpy(file_buffer->data + offset, buf, size);
+
+	return size;
+}
+
+static int obexfuse_truncate(const char *path, off_t offset)
+{
+	/*
+	 *  Allow to change the size of a file.
+	 */
+	return 0;
+}
+
+static int obexfuse_release(const char *path, struct fuse_file_info *fi)
+{
+	struct obexhlp_buffer *file_buffer = (struct obexhlp_buffer*)fi->fh;
+
+	if (file_buffer->edited == TRUE)
+		obexhlp_put(session, file_buffer, path); /* send to device */
+
+	g_free(file_buffer->data);
+	g_free(file_buffer);
+
+	return session->status;
+}
+
+static int obexfuse_utimens(const char *path, const struct timespec tv[2])
+{
+	/*
+	 * Important for mknod (touch) operation
+	 */
+	return 0;
+}
+
+static int obexfuse_mknod(const char *path, mode_t mode, dev_t dev)
+{
+	obexhlp_touch(session, path);
+
+	return 0;
+}
+
 static struct fuse_operations obexfuse_oper = {
 	.readdir = obexfuse_readdir,
 	.getattr = obexfuse_getattr,
 	.open = obexfuse_open,
 	.read = obexfuse_read,
+	.write = obexfuse_write,
+	.truncate = obexfuse_truncate,
+	.release = obexfuse_release,
+	.utimens = obexfuse_utimens,
+	.mknod = obexfuse_mknod,
 	.init = obexfuse_init,
 	.destroy = obexfuse_destroy,
 };
-- 
1.7.8.6


^ permalink raw reply related

* [RFC v3 obexd 07/10] fuse: Add open and read operations plus location helpers
From: Michał Poczwardowski @ 2012-12-01 23:14 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Michał Poczwardowski
In-Reply-To: <1354403695-18985-1-git-send-email-dmp0x7c5@gmail.com>

---
 fuse/helpers.c  |   62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 fuse/helpers.h  |    2 +
 fuse/obexfuse.c |   32 ++++++++++++++++++++++++++++
 3 files changed, 96 insertions(+), 0 deletions(-)

diff --git a/fuse/helpers.c b/fuse/helpers.c
index 4e4747d..72b0b3e 100644
--- a/fuse/helpers.c
+++ b/fuse/helpers.c
@@ -562,3 +562,65 @@ struct stat *obexhlp_getattr(struct obexhlp_session* session,
 {
 	return g_hash_table_lookup(session->file_stat, path);
 }
+
+static struct obexhlp_location *get_location(const char *path)
+{
+	struct obexhlp_location *location;
+	gchar **directories;
+	guint i, len, fid = 0;
+
+	location = g_malloc0(sizeof(*location));
+	directories = g_strsplit(path, "/", -1);
+	len = g_strv_length(directories);
+
+	for (i = 0; i < len; i++)
+		if (directories[i][0] != '\0') /* protect multi slashes */
+			fid = i; /* last nonempty is a file */
+
+	location->file = g_strdup(directories[fid]);
+	directories[fid][0] = '\0'; /* remove file */
+	location->dir = g_strjoinv("/", directories);
+
+	g_strfreev(directories);
+
+	return location;
+}
+
+void free_location(struct obexhlp_location *location)
+{
+	g_free(location->file);
+	g_free(location->dir);
+	g_free(location);
+}
+
+struct obexhlp_buffer *obexhlp_get(struct obexhlp_session* session,
+						const char *path)
+{
+	struct obexhlp_location *l;
+	struct obexhlp_buffer *buffer;
+	struct stat *stfile;
+	l = get_location(path);
+
+	g_print("obexhlp_get(%s%s)\n", l->dir, l->file);
+
+	stfile = obexhlp_getattr(session, path);
+	if (stfile == NULL)
+		return NULL;
+
+	buffer = g_malloc0(sizeof(*buffer));
+
+	if (stfile->st_size == 0)
+		return buffer;
+
+	obexhlp_setpath(session, l->dir);
+	request_new(session, g_strdup_printf("get %s", path));
+	session->buffer = buffer;
+	g_obex_get_req(session->obex, async_get_consumer,
+					complete_func, session, &session->err,
+					G_OBEX_HDR_NAME, l->file,
+					G_OBEX_HDR_INVALID);
+	free_location(l);
+	request_wait_free(session);
+
+	return buffer;
+}
diff --git a/fuse/helpers.h b/fuse/helpers.h
index 0435317..9080590 100644
--- a/fuse/helpers.h
+++ b/fuse/helpers.h
@@ -55,3 +55,5 @@ void obexhlp_disconnect(struct obexhlp_session* session);
 GList *obexhlp_listfolder(struct obexhlp_session* session, const char *path);
 struct stat *obexhlp_getattr(struct obexhlp_session* session,
 					const char *path);
+struct obexhlp_buffer *obexhlp_get(struct obexhlp_session* session,
+					const char *path);
diff --git a/fuse/obexfuse.c b/fuse/obexfuse.c
index 5270293..e185250 100644
--- a/fuse/obexfuse.c
+++ b/fuse/obexfuse.c
@@ -144,9 +144,41 @@ static int obexfuse_getattr(const char *path, struct stat *stbuf)
 	return res;
 }
 
+static int obexfuse_open(const char *path, struct fuse_file_info *fi)
+{
+	struct obexhlp_buffer *file_buffer;
+
+	file_buffer = obexhlp_get(session, path);
+
+	if (file_buffer == NULL)
+		return -ENOENT;
+
+	fi->fh = (uint64_t)file_buffer;
+
+	return session->status;
+}
+
+static int obexfuse_read(const char *path, char *buf, size_t size,
+			off_t offset, struct fuse_file_info *fi)
+{
+	gsize asize;
+	struct obexhlp_buffer *file_buffer = (struct obexhlp_buffer*)fi->fh;
+
+	asize = file_buffer->size - offset;
+
+	if (asize > size)
+		asize = size;
+
+	memcpy(buf, file_buffer->data + offset, asize);
+
+	return asize;
+}
+
 static struct fuse_operations obexfuse_oper = {
 	.readdir = obexfuse_readdir,
 	.getattr = obexfuse_getattr,
+	.open = obexfuse_open,
+	.read = obexfuse_read,
 	.init = obexfuse_init,
 	.destroy = obexfuse_destroy,
 };
-- 
1.7.8.6


^ permalink raw reply related

* [RFC v3 obexd 06/10] fuse: Add getattr operation
From: Michał Poczwardowski @ 2012-12-01 23:14 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Michał Poczwardowski
In-Reply-To: <1354403695-18985-1-git-send-email-dmp0x7c5@gmail.com>

---
 fuse/helpers.c  |    6 ++++++
 fuse/helpers.h  |    2 ++
 fuse/obexfuse.c |   34 ++++++++++++++++++++++++++++++++++
 3 files changed, 42 insertions(+), 0 deletions(-)

diff --git a/fuse/helpers.c b/fuse/helpers.c
index 42a0e21..4e4747d 100644
--- a/fuse/helpers.c
+++ b/fuse/helpers.c
@@ -556,3 +556,9 @@ GList *obexhlp_listfolder(struct obexhlp_session* session,
 
 	return session->lsfiles;
 }
+
+struct stat *obexhlp_getattr(struct obexhlp_session* session,
+					const char *path)
+{
+	return g_hash_table_lookup(session->file_stat, path);
+}
diff --git a/fuse/helpers.h b/fuse/helpers.h
index 832f856..0435317 100644
--- a/fuse/helpers.h
+++ b/fuse/helpers.h
@@ -53,3 +53,5 @@ struct obexhlp_session* obexhlp_connect(const char *srcstr,
 void obexhlp_disconnect(struct obexhlp_session* session);
 
 GList *obexhlp_listfolder(struct obexhlp_session* session, const char *path);
+struct stat *obexhlp_getattr(struct obexhlp_session* session,
+					const char *path);
diff --git a/fuse/obexfuse.c b/fuse/obexfuse.c
index 0560031..5270293 100644
--- a/fuse/obexfuse.c
+++ b/fuse/obexfuse.c
@@ -111,8 +111,42 @@ static int obexfuse_readdir(const char *path, void *buf,
 	return session->status;
 }
 
+static int obexfuse_getattr(const char *path, struct stat *stbuf)
+{
+	int res = 0;
+	struct stat *stfile;
+
+	memset(stbuf, 0, sizeof(struct stat));
+
+	if (strcmp(path, "/") == 0) {
+		stbuf->st_mode = S_IFDIR | 0755;
+		stbuf->st_nlink = 2;
+	} else {
+		stfile = obexhlp_getattr(session, path);
+
+		if (stfile == NULL)
+			return -ENOENT;
+
+		if (stfile->st_mode == S_IFREG)
+			stbuf->st_mode = stfile->st_mode | 0666;
+		else /* S_IFDIR */
+			stbuf->st_mode = stfile->st_mode | 0755;
+
+		stbuf->st_nlink = 1;
+		stbuf->st_size = stfile->st_size;
+		stbuf->st_mtime = stbuf->st_atime = stbuf->st_ctime =
+						stfile->st_mtime;
+		stbuf->st_blksize = 512;
+		stbuf->st_blocks = (stbuf->st_size + stbuf->st_blksize)
+						/ stbuf->st_blksize;
+	}
+
+	return res;
+}
+
 static struct fuse_operations obexfuse_oper = {
 	.readdir = obexfuse_readdir,
+	.getattr = obexfuse_getattr,
 	.init = obexfuse_init,
 	.destroy = obexfuse_destroy,
 };
-- 
1.7.8.6


^ permalink raw reply related

* [RFC v3 obexd 05/10] fuse: Add readdir operation
From: Michał Poczwardowski @ 2012-12-01 23:14 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Michał Poczwardowski
In-Reply-To: <1354403695-18985-1-git-send-email-dmp0x7c5@gmail.com>

---
 fuse/helpers.c  |  128 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 fuse/helpers.h  |    2 +
 fuse/obexfuse.c |   23 ++++++++++
 3 files changed, 153 insertions(+), 0 deletions(-)

diff --git a/fuse/helpers.c b/fuse/helpers.c
index d3e70ff..42a0e21 100644
--- a/fuse/helpers.c
+++ b/fuse/helpers.c
@@ -428,3 +428,131 @@ void obexhlp_setpath(struct obexhlp_session *session, const char *path)
 
 	g_strfreev(path_v);
 }
+
+static void listfolder_xml_element(GMarkupParseContext *ctxt,
+			const gchar *element, const gchar **names,
+			const gchar **values, gpointer user_data,
+			GError **gerr)
+{
+	gchar *key, *pathname, *name = NULL;
+	struct obexhlp_session *session = user_data;
+	struct stat *stbuf;
+	gint i = 0;
+
+	stbuf = g_malloc0(sizeof(struct stat));
+
+	if ((strcasecmp("file", element) == 0)) {
+		stbuf->st_mode = S_IFREG;
+	} else if ((strcasecmp("folder", element)) == 0) {
+		stbuf->st_mode = S_IFDIR;
+		stbuf->st_mtime = time(NULL);
+	} else {
+		g_free(stbuf);
+		return;
+	}
+
+	for (key = (gchar *) names[i]; key; key = (gchar *) names[++i]) {
+		if (g_str_equal("name", key) == TRUE) {
+			session->lsfiles = g_list_append(session->lsfiles,
+						g_strdup(values[i]));
+			name = g_strdup(values[i]);
+
+		} else if (g_str_equal("size", key) == TRUE) {
+			guint64 size;
+			size = g_ascii_strtoll(values[i], NULL, 10);
+			stbuf->st_size = size;
+
+		} else if (g_str_equal("created", key) == TRUE) {
+			GTimeVal time;
+			GDateTime *datetime;
+			g_time_val_from_iso8601(values[i], &time);
+			datetime = g_date_time_new_from_timeval_utc(&time);
+			stbuf->st_mtime = g_date_time_to_unix(datetime);
+		}
+	}
+
+	if (g_str_equal("/", session->setpath) == TRUE)
+		pathname = g_strdup_printf("/%s", name);
+	else
+		pathname = g_strdup_printf("%s/%s", session->setpath, name);
+
+	g_hash_table_replace(session->file_stat, pathname, stbuf);
+	g_free(name);
+}
+
+static const GMarkupParser parser = {
+	listfolder_xml_element,
+	NULL, NULL, NULL, NULL
+};
+
+static void complete_listfolder_func(GObex *obex, GError *err,
+				gpointer user_data)
+{
+	GMarkupParseContext *ctxt;
+	struct obexhlp_session *session = user_data;
+	struct obexhlp_buffer *buffer = session->buffer;
+
+	if (err == NULL) {
+		ctxt = g_markup_parse_context_new(&parser, 0, session, NULL);
+		g_markup_parse_context_parse(ctxt, buffer->data, buffer->size,
+							NULL);
+		g_markup_parse_context_free(ctxt);
+	}
+
+	complete_func(obex, err, user_data);
+}
+
+static gboolean async_get_consumer(const void *buf, gsize len,
+							gpointer user_data)
+{
+	struct obexhlp_session *session = user_data;
+	struct obexhlp_buffer *buffer = session->buffer;
+
+	if (buffer->size == 0)
+		buffer->data = g_malloc0(sizeof(char) * len);
+	else
+		buffer->data = g_realloc(buffer->data, buffer->size + len);
+
+	memcpy(buffer->data + buffer->size, buf, len);
+	buffer->size += len;
+
+	g_obex_suspend(session->obex);
+	g_obex_resume(session->obex);
+
+	return TRUE;
+}
+
+GList *obexhlp_listfolder(struct obexhlp_session* session,
+					const char *path)
+{
+	struct obexhlp_buffer *buffer;
+	GObexPacket *req;
+	guint reqpkt;
+
+	obexhlp_setpath(session, path);
+
+	g_print("obexhlp_listfolder(%s)\n", path);
+
+	if (session->lsfiles != NULL) {
+		g_list_free_full(session->lsfiles, g_free);
+		session->lsfiles = NULL;
+	}
+
+	session->lsfiles = g_list_alloc();
+	buffer = g_malloc0(sizeof(struct obexhlp_buffer));
+	session->buffer = buffer;
+
+	request_new(session, g_strdup_printf("listfolder %s", path));
+	req = g_obex_packet_new(G_OBEX_OP_GET, TRUE, G_OBEX_HDR_INVALID);
+	g_obex_packet_add_bytes(req, G_OBEX_HDR_TYPE, OBEX_FTP_LS,
+						strlen(OBEX_FTP_LS) + 1);
+	reqpkt = g_obex_get_req_pkt(session->obex, req,
+				async_get_consumer,
+				complete_listfolder_func,
+				session, &session->err);
+	request_wait_free(session);
+	g_free(buffer->data);
+	g_free(buffer);
+
+	return session->lsfiles;
+}
diff --git a/fuse/helpers.h b/fuse/helpers.h
index 3ef924e..832f856 100644
--- a/fuse/helpers.h
+++ b/fuse/helpers.h
@@ -51,3 +51,5 @@ struct obexhlp_session {
 struct obexhlp_session* obexhlp_connect(const char *srcstr,
 						const char *dstsrc);
 void obexhlp_disconnect(struct obexhlp_session* session);
+
+GList *obexhlp_listfolder(struct obexhlp_session* session, const char *path);
diff --git a/fuse/obexfuse.c b/fuse/obexfuse.c
index d6a87f3..0560031 100644
--- a/fuse/obexfuse.c
+++ b/fuse/obexfuse.c
@@ -89,7 +89,30 @@ void obexfuse_destroy()
 	g_thread_join(main_gthread);
 }
 
+static int obexfuse_readdir(const char *path, void *buf,
+			fuse_fill_dir_t filler, off_t offset,
+				struct fuse_file_info *fi)
+{
+	int len, i;
+	gchar *string;
+	GList *files;
+
+	filler(buf, ".", NULL, 0);
+	filler(buf, "..", NULL, 0);
+
+	files = obexhlp_listfolder(session, path);
+	len = g_list_length(files);
+
+	for (i = 1; i < len; i++) { /* element for i==0 is NULL */
+		string = g_list_nth_data(files, i);
+		filler(buf, string, NULL, 0);
+	}
+
+	return session->status;
+}
+
 static struct fuse_operations obexfuse_oper = {
+	.readdir = obexfuse_readdir,
 	.init = obexfuse_init,
 	.destroy = obexfuse_destroy,
 };
-- 
1.7.8.6


^ permalink raw reply related

* [RFC v3 obexd 04/10] fuse: Add request helpers and setpath operation
From: Michał Poczwardowski @ 2012-12-01 23:14 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Michał Poczwardowski
In-Reply-To: <1354403695-18985-1-git-send-email-dmp0x7c5@gmail.com>

---
 fuse/helpers.c |  108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 108 insertions(+), 0 deletions(-)

diff --git a/fuse/helpers.c b/fuse/helpers.c
index 82797d9..d3e70ff 100644
--- a/fuse/helpers.c
+++ b/fuse/helpers.c
@@ -320,3 +320,111 @@ void obexhlp_disconnect(struct obexhlp_session* session)
 
 	g_free(session);
 }
+
+void request_new(struct obexhlp_session *session,
+					gchar *name)
+{
+	g_print("REQUEST %s\n", name);
+
+	if (session->request != NULL)
+		g_error("Another request (%s) active!\n",
+					session->request->name);
+
+	session->status = 0;
+	session->request = g_malloc0(sizeof(struct obexhlp_request));
+	session->request->name = name;
+
+	/*
+	 * suspend/resume operations recreates g_io_add_watch(),
+	 * it fixes obex->io freeze during transfer
+	 */
+	g_obex_suspend(session->obex);
+	g_obex_resume(session->obex);
+}
+
+void request_wait_free(struct obexhlp_session *session)
+{
+	g_print("WAIT for %s\n", session->request->name);
+
+	g_obex_suspend(session->obex);
+	g_obex_resume(session->obex);
+
+	if (session->err != NULL) {
+		g_print("ERROR: %s (%d)\n", session->err->message,
+						session->err->code);
+		g_error_free(session->err);
+		raise(SIGTERM);
+		return;
+	}
+
+	g_mutex_lock(obexhlp_mutex);
+
+	while (session->request->complete != TRUE)
+		g_cond_wait(obexhlp_cond, obexhlp_mutex);
+
+	g_mutex_unlock(obexhlp_mutex);
+
+	g_free(session->request->name);
+	g_free(session->request);
+	session->request = NULL;
+}
+
+static void complete_func(GObex *obex, GError *err,
+				gpointer user_data)
+{
+	struct obexhlp_session *session = user_data;
+
+	if (err != NULL) {
+		g_print("ERROR: %s\n", err->message);
+		session->status = -ECANCELED;
+		g_error_free(err);
+	} else {
+		g_print("COMPLETE %s\n", session->request->name);
+	}
+
+	g_mutex_lock(obexhlp_mutex);
+	session->request->complete = TRUE;
+	g_cond_signal(obexhlp_cond);
+	g_mutex_unlock(obexhlp_mutex);
+}
+
+static void response_func(GObex *obex, GError *err, GObexPacket *rsp,
+							gpointer user_data)
+{
+	complete_func(obex, err, user_data);
+}
+
+void obexhlp_setpath(struct obexhlp_session *session, const char *path)
+{
+	guint i = 0, split = 0;
+	gchar **path_v;
+	gsize len;
+
+	g_print("obexhlp_setpath(%s)\n", path);
+
+	if (g_str_has_prefix(path, session->setpath)) {
+		split = strlen(session->setpath);
+	} else {
+		request_new(session, g_strdup_printf("setpath root"));
+		g_obex_setpath(session->obex, "", response_func,
+						session, &session->err);
+		request_wait_free(session);
+	}
+
+	path_v = g_strsplit(path+split, "/", -1);
+	len = g_strv_length(path_v);
+
+	for (i = 0; i < len; i++)
+		if (path_v[i][0] != '\0') {
+			request_new(session,
+				g_strdup_printf("setpath %s", path_v[i]));
+			g_obex_setpath(session->obex, path_v[i],
+					response_func, session, &session->err);
+			request_wait_free(session);
+		}
+
+	g_free(session->setpath);
+	session->setpath = g_strdup(path);
+
+	g_strfreev(path_v);
+}
-- 
1.7.8.6


^ permalink raw reply related

* [RFC v3 obexd 03/10] fuse: Add obexhlp_connect/disconnect functions with helpers
From: Michał Poczwardowski @ 2012-12-01 23:14 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Michał Poczwardowski
In-Reply-To: <1354403695-18985-1-git-send-email-dmp0x7c5@gmail.com>

---
 fuse/helpers.c  |  268 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 fuse/helpers.h  |    4 +
 fuse/obexfuse.c |   40 ++++++++
 3 files changed, 312 insertions(+), 0 deletions(-)

diff --git a/fuse/helpers.c b/fuse/helpers.c
index 2dc309a..82797d9 100644
--- a/fuse/helpers.c
+++ b/fuse/helpers.c
@@ -43,6 +43,9 @@
 
 #define OBEX_FTP_LS "x-obex/folder-listing"
 
+static GCond *obexhlp_cond;
+static GMutex *obexhlp_mutex;
+
 struct obexhlp_request {
 	gchar *name;
 	gboolean complete;
@@ -52,3 +55,268 @@ struct obexhlp_location {
 	gchar *dir;
 	gchar *file;
 };
+
+static volatile sig_atomic_t __sdp_io_finished = 0;
+
+/* adopted from client/bluetooth.c - search_callback() */
+static void search_callback(uint8_t type, uint16_t status,
+			uint8_t *rsp, size_t size, void *user_data)
+{
+	struct obexhlp_session *session = user_data;
+	unsigned int scanned, bytesleft = size;
+	int seqlen = 0;
+	uint8_t dataType;
+	uint16_t port = 0;
+
+	if (status || type != SDP_SVC_SEARCH_ATTR_RSP)
+		goto done;
+
+	scanned = sdp_extract_seqtype(rsp, bytesleft, &dataType, &seqlen);
+	if (!scanned || !seqlen)
+		goto done;
+
+	rsp += scanned;
+	bytesleft -= scanned;
+	do {
+		sdp_record_t *rec;
+		sdp_list_t *protos;
+		sdp_data_t *data;
+		int recsize, ch = -1;
+
+		recsize = 0;
+		rec = sdp_extract_pdu(rsp, bytesleft, &recsize);
+		if (!rec)
+			break;
+
+		if (!recsize) {
+			sdp_record_free(rec);
+			break;
+		}
+
+		if (!sdp_get_access_protos(rec, &protos)) {
+			port = sdp_get_proto_port(protos, RFCOMM_UUID);
+			sdp_list_foreach(protos,
+					(sdp_list_func_t) sdp_list_free, NULL);
+			sdp_list_free(protos, NULL);
+			protos = NULL;
+			goto done;
+		}
+
+		data = sdp_data_get(rec, 0x0200);
+		/* PSM must be odd and lsb of upper byte must be 0 */
+		if (data != NULL && (data->val.uint16 & 0x0101) == 0x0001)
+			ch = data->val.uint16;
+
+		sdp_record_free(rec);
+
+		if (ch > 0) {
+			port = ch;
+			break;
+		}
+
+		scanned += recsize;
+		rsp += recsize;
+		bytesleft -= recsize;
+	} while (scanned < size && bytesleft > 0);
+
+done:
+	session->channel = port;
+	__sdp_io_finished = 1;
+}
+
+static uint16_t get_ftp_channel(struct obexhlp_session* session,
+					bdaddr_t *src, bdaddr_t *dst)
+{
+	sdp_list_t *search, *attrid;
+	uint32_t range = 0x0000ffff;
+	sdp_session_t *sdp;
+	uuid_t uuid;
+
+	sdp = sdp_connect(src, dst, SDP_RETRY_IF_BUSY);
+	if (sdp == NULL)
+		return 0;
+
+	/* FTP_SDP_UUID "00001106-0000-1000-8000-00805f9b34fb" */
+	uint8_t uuid_int[] = {0, 0, 0x11, 0x06, 0, 0, 0x10, 0, 0x80,
+					0, 0, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
+	sdp_uuid128_create(&uuid, uuid_int);
+
+	if (sdp_set_notify(sdp, search_callback, session) < 0)
+		goto done;
+
+	search = sdp_list_append(NULL, &uuid);
+	attrid = sdp_list_append(NULL, &range);
+
+	if (sdp_service_search_attr_async(sdp,
+				search, SDP_ATTR_REQ_RANGE, attrid) < 0) {
+		sdp_list_free(attrid, NULL);
+		sdp_list_free(search, NULL);
+		goto done;
+	}
+
+	sdp_list_free(attrid, NULL);
+	sdp_list_free(search, NULL);
+
+	while (!__sdp_io_finished)
+		sdp_process(sdp);
+
+done:
+	return session->channel;
+}
+
+/* taken from client/bluetooth.c - bluetooth_getpacketopt */
+static int get_packet_opt(GIOChannel *io, int *tx_mtu, int *rx_mtu)
+{
+	int sk = g_io_channel_unix_get_fd(io);
+	int type;
+	int omtu = -1;
+	int imtu = -1;
+	socklen_t len = sizeof(int);
+
+	if (getsockopt(sk, SOL_SOCKET, SO_TYPE, &type, &len) < 0)
+		return -errno;
+
+	if (type != SOCK_SEQPACKET)
+		return -EINVAL;
+
+	if (!bt_io_get(io, NULL, BT_IO_OPT_OMTU, &omtu,
+						BT_IO_OPT_IMTU, &imtu,
+						BT_IO_OPT_INVALID))
+		return -EINVAL;
+
+	if (tx_mtu)
+		*tx_mtu = omtu;
+
+	if (rx_mtu)
+		*rx_mtu = imtu;
+
+	return 0;
+}
+
+static void obex_callback(GObex *obex, GError *err, GObexPacket *rsp,
+							gpointer user_data)
+{
+	if (err != NULL) {
+		g_print("OBEX Connect failed: %s\n", err->message);
+		g_error_free(err);
+	} else {
+		g_print("OBEX Connect succeeded\n");
+	}
+}
+
+static void bt_io_callback(GIOChannel *io, GError *err, gpointer user_data)
+{
+	struct obexhlp_session *session = user_data;
+	GObexTransportType type;
+	int tx_mtu = -1;
+	int rx_mtu = -1;
+
+	if (err != NULL) {
+		g_printerr("%s\n", err->message);
+		g_error_free(err);
+		return;
+	}
+
+	g_print("Bluetooth socket connected\n");
+
+	g_io_channel_set_close_on_unref(io, FALSE);
+
+	if (get_packet_opt(io, &tx_mtu, &rx_mtu) == 0) {
+		type = G_OBEX_TRANSPORT_PACKET;
+		g_print("PACKET transport tx:%d rx:%d\n", tx_mtu, rx_mtu);
+	} else {
+		type = G_OBEX_TRANSPORT_STREAM;
+		g_print("STREAM transport\n");
+	}
+
+	session->obex = g_obex_new(io, type, tx_mtu, rx_mtu);
+	if (session->obex == NULL) {
+		g_print("ERROR: obex is NULL");
+		raise(SIGTERM);
+	}
+
+	g_io_channel_set_close_on_unref(io, TRUE);
+
+	g_obex_connect(session->obex, obex_callback, session, &err,
+				G_OBEX_HDR_TARGET, OBEX_FTP_UUID,
+				OBEX_FTP_UUID_LEN, G_OBEX_HDR_INVALID);
+
+	if (err != NULL) {
+		g_print("ERROR: %s\n", err->message);
+		g_obex_unref(session->obex);
+		raise(SIGTERM);
+	}
+}
+
+struct obexhlp_session* obexhlp_connect(const char *srcstr,
+						const char *dststr)
+{
+	struct obexhlp_session *session;
+	uint16_t channel;
+	bdaddr_t src, dst;
+
+	session = g_try_malloc0(sizeof(struct obexhlp_session));
+	if (session == NULL)
+		return NULL;
+
+	if (srcstr == NULL)
+		bacpy(&src, BDADDR_ANY);
+	else
+		str2ba(srcstr, &src);
+
+	str2ba(dststr, &dst);
+	channel = get_ftp_channel(session, &src, &dst);
+
+	if (channel == 0)
+		return NULL;
+
+	if (channel > 31)
+		session->io = bt_io_connect(bt_io_callback, session,
+				NULL, &session->err,
+				BT_IO_OPT_SOURCE_BDADDR, &src,
+				BT_IO_OPT_DEST_BDADDR, &dst,
+				BT_IO_OPT_PSM, channel,
+				BT_IO_OPT_MODE, BT_IO_MODE_ERTM,
+				BT_IO_OPT_OMTU, BT_TX_MTU,
+				BT_IO_OPT_IMTU, BT_RX_MTU,
+				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+				BT_IO_OPT_INVALID);
+	else
+		session->io = bt_io_connect(bt_io_callback, session,
+				NULL, &session->err,
+				BT_IO_OPT_SOURCE_BDADDR, &src,
+				BT_IO_OPT_DEST_BDADDR, &dst,
+				BT_IO_OPT_CHANNEL, channel,
+				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+				BT_IO_OPT_INVALID);
+
+	if (session->err != NULL)
+		return NULL;
+
+	session->file_stat = g_hash_table_new_full( g_str_hash, g_str_equal,
+					g_free, g_free);
+	session->setpath = g_strdup("/");
+
+	obexhlp_mutex = g_mutex_new();
+	obexhlp_cond = g_cond_new();
+
+	return session;
+}
+
+void obexhlp_disconnect(struct obexhlp_session* session)
+{
+	if (session == NULL)
+		return;
+
+	g_obex_unref(session->obex);
+	g_free(session->io);
+
+	g_hash_table_remove_all(session->file_stat);
+	g_list_free_full(session->lsfiles, g_free);
+	g_free(session->setpath);
+
+	g_mutex_free(obexhlp_mutex);
+	g_cond_free(obexhlp_cond);
+
+	g_free(session);
+}
diff --git a/fuse/helpers.h b/fuse/helpers.h
index abbdd70..3ef924e 100644
--- a/fuse/helpers.h
+++ b/fuse/helpers.h
@@ -47,3 +47,7 @@ struct obexhlp_session {
 	int status;
 	GError *err;
 };
+
+struct obexhlp_session* obexhlp_connect(const char *srcstr,
+						const char *dstsrc);
+void obexhlp_disconnect(struct obexhlp_session* session);
diff --git a/fuse/obexfuse.c b/fuse/obexfuse.c
index fe4f4da..d6a87f3 100644
--- a/fuse/obexfuse.c
+++ b/fuse/obexfuse.c
@@ -33,6 +33,10 @@
 
 #include "helpers.h"
 
+struct obexhlp_session* session = NULL;
+static GMainLoop *main_loop;
+static GThread *main_gthread;
+
 struct options {
 	char* dststr;
 	char* srcstr;
@@ -60,7 +64,34 @@ static struct fuse_opt obexfuse_opts[] =
 	FUSE_OPT_END
 };
 
+gpointer main_loop_func(gpointer user_data)
+{
+	main_loop = g_main_loop_new(NULL, FALSE);
+	g_main_loop_run(main_loop);
+
+	return 0;
+}
+
+void* obexfuse_init(struct fuse_conn_info *conn)
+{
+	main_gthread = g_thread_create(main_loop_func, NULL, TRUE, NULL);
+
+	conn->async_read = 0;
+	conn->want &= ~FUSE_CAP_ASYNC_READ;
+
+	return 0;
+}
+
+void obexfuse_destroy()
+{
+	obexhlp_disconnect(session);
+	g_main_loop_quit(main_loop);
+	g_thread_join(main_gthread);
+}
+
 static struct fuse_operations obexfuse_oper = {
+	.init = obexfuse_init,
+	.destroy = obexfuse_destroy,
 };
 
 static int obexfuse_opt_proc(void *data, const char *arg, int key,
@@ -111,6 +142,15 @@ int main(int argc, char *argv[])
 
 	g_thread_init(NULL);
 
+	session = obexhlp_connect(options.srcstr, options.dststr);
+	if (session == NULL || session->io == NULL) {
+		g_printerr("Connection to %s failed\n", options.dststr);
+		obexhlp_disconnect(session);
+		return -EHOSTUNREACH;
+	} else {
+		g_print("Connected\nMounting %s\n", options.dststr);
+	}
+
 	fuse_opt_add_arg(&args, "-s"); /* force single threaded mode */
 	retfuse = fuse_main(args.argc, args.argv, &obexfuse_oper, NULL);
 
-- 
1.7.8.6


^ permalink raw reply related

* [RFC v3 obexd 02/10] build: Add --enable-fuse for obexfuse
From: Michał Poczwardowski @ 2012-12-01 23:14 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Michał Poczwardowski
In-Reply-To: <1354403695-18985-1-git-send-email-dmp0x7c5@gmail.com>

---
 Makefile.am  |    9 +++++++++
 configure.ac |   15 +++++++++++++++
 2 files changed, 24 insertions(+), 0 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 724dd5d..01441dc 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -132,6 +132,15 @@ client_obex_client_SOURCES = $(gdbus_sources) $(gobex_sources) \
 client_obex_client_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ @BLUEZ_LIBS@
 endif
 
+if FUSE
+bin_PROGRAMS = fuse/obexfuse
+
+fuse_obexfuse_SOURCES = $(gobex_sources) $(btio_sources) \
+		fuse/helpers.c fuse/obexfuse.c
+
+fuse_obexfuse_LDADD = @GLIB_LIBS@ @GTHREAD_LIBS@ @BLUEZ_LIBS@ @FUSE_LIBS@
+endif
+
 service_DATA = $(service_in_files:.service.in=.service)
 
 AM_CFLAGS = @BLUEZ_CFLAGS@ @EBOOK_CFLAGS@ @GTHREAD_CFLAGS@ @GLIB_CFLAGS@ \
diff --git a/configure.ac b/configure.ac
index 69d636f..7d0a904 100644
--- a/configure.ac
+++ b/configure.ac
@@ -180,4 +180,19 @@ AM_CONDITIONAL(CLIENT, test "${enable_client}" != "no")
 
 AM_CONDITIONAL(READLINE, test "${readline_found}" = "yes")
 
+AC_ARG_ENABLE(fuse, AC_HELP_STRING([--enable-fuse],
+			[Build obexfuse]), [
+	PKG_CHECK_MODULES(FUSE, fuse, dummy=yes,
+				      AC_MSG_ERROR(FUSE is required))
+	AC_SUBST(FUSE_CFLAGS)
+	AC_SUBST(FUSE_LIBS)
+	enable_fuse=${enableval}
+
+	PKG_CHECK_MODULES(GTHREAD, gthread-2.0, dummy=yes,
+					AC_MSG_ERROR(libgthread is required))
+	AC_SUBST(GTHREAD_CFLAGS)
+	AC_SUBST(GTHREAD_LIBS)
+])
+AM_CONDITIONAL(FUSE, test "${enable_fuse}" != "no")
+
 AC_OUTPUT(Makefile)
-- 
1.7.8.6


^ permalink raw reply related

* [RFC v3 obexd 01/10] fuse: Add initial obexfuse files, fuse main and options parse
From: Michał Poczwardowski @ 2012-12-01 23:14 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Michał Poczwardowski

---
 fuse/helpers.c  |   54 +++++++++++++++++++++++++
 fuse/helpers.h  |   49 ++++++++++++++++++++++
 fuse/obexfuse.c |  119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 222 insertions(+), 0 deletions(-)
 create mode 100644 fuse/helpers.c
 create mode 100644 fuse/helpers.h
 create mode 100644 fuse/obexfuse.c

diff --git a/fuse/helpers.c b/fuse/helpers.c
new file mode 100644
index 0000000..2dc309a
--- /dev/null
+++ b/fuse/helpers.c
@@ -0,0 +1,54 @@
+/*
+ *  OBEX Filesystem in Userspace
+ *
+ *  Copyright (C) 2012  Michał Poczwardowski <dmp0x7c5@gmail.com>
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#include <gobex/gobex.h>
+#include <btio/btio.h>
+
+#include <glib.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/rfcomm.h>
+#include <bluetooth/sdp.h>
+#include <bluetooth/sdp_lib.h>
+
+#define BT_RX_MTU 32767
+#define BT_TX_MTU 32767
+
+#include "helpers.h"
+
+#define OBEX_FTP_UUID \
+	"\xF9\xEC\x7B\xC4\x95\x3C\x11\xD2\x98\x4E\x52\x54\x00\xDC\x9E\x09"
+#define OBEX_FTP_UUID_LEN 16
+
+#define OBEX_FTP_LS "x-obex/folder-listing"
+
+struct obexhlp_request {
+	gchar *name;
+	gboolean complete;
+};
+
+struct obexhlp_location {
+	gchar *dir;
+	gchar *file;
+};
diff --git a/fuse/helpers.h b/fuse/helpers.h
new file mode 100644
index 0000000..abbdd70
--- /dev/null
+++ b/fuse/helpers.h
@@ -0,0 +1,49 @@
+/*
+ *  OBEX Filesystem in Userspace
+ *
+ *  Copyright (C) 2012  Michał Poczwardowski <dmp0x7c5@gmail.com>
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#include <gobex/gobex.h>
+#include <glib.h>
+
+struct obexhlp_request;
+
+struct obexhlp_buffer {
+	void *data;
+	gsize tmpsize;
+	gsize size;
+	gboolean edited;
+};
+
+struct obexhlp_session {
+	GObex *obex;
+	uint16_t channel;
+	GList *lsfiles;
+	GIOChannel *io;
+	GHashTable *file_stat;
+	gchar *setpath;
+	struct obexhlp_request *request;
+	struct obexhlp_buffer *buffer;
+	gboolean vtouch;
+	gchar *vtouch_path;
+	gboolean rtouch;
+	int status;
+	GError *err;
+};
diff --git a/fuse/obexfuse.c b/fuse/obexfuse.c
new file mode 100644
index 0000000..fe4f4da
--- /dev/null
+++ b/fuse/obexfuse.c
@@ -0,0 +1,119 @@
+/*
+ *  OBEX Filesystem in Userspace
+ *
+ *  Copyright (C) 2012  Michał Poczwardowski <dmp0x7c5@gmail.com>
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#define FUSE_USE_VERSION 26
+
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <fuse.h>
+#include <fuse/fuse_opt.h>
+
+#include "helpers.h"
+
+struct options {
+	char* dststr;
+	char* srcstr;
+} options;
+
+#define GOBEXFUSE_OPT_KEY(t, p, v) { t, offsetof(struct options, p), v }
+
+enum
+{
+   KEY_VERSION,
+   KEY_HELP,
+};
+
+static struct fuse_opt obexfuse_opts[] =
+{
+	GOBEXFUSE_OPT_KEY("--target=%s",dststr, 0),
+	GOBEXFUSE_OPT_KEY("-t %s",	dststr, 0),
+	GOBEXFUSE_OPT_KEY("--source=%s",srcstr, 0),
+	GOBEXFUSE_OPT_KEY("-s %s",	srcstr, 0),
+
+	FUSE_OPT_KEY("-V",             KEY_VERSION),
+	FUSE_OPT_KEY("--version",      KEY_VERSION),
+	FUSE_OPT_KEY("-h",             KEY_HELP),
+	FUSE_OPT_KEY("--help",         KEY_HELP),
+	FUSE_OPT_END
+};
+
+static struct fuse_operations obexfuse_oper = {
+};
+
+static int obexfuse_opt_proc(void *data, const char *arg, int key,
+					struct fuse_args *outargs)
+{
+	switch (key) {
+	case KEY_HELP:
+		g_printerr("Usage: %s mountpoint [options]\n"
+				"\n"
+				"general options:\n"
+				"    -o opt,[opt...]  mount options\n"
+				"    -h   --help      print help\n"
+				"    -V   --version   print version\n"
+				"\n"
+				"obexfuse options:\n"
+				"    -t   --target    target btaddr "
+				"(mandatory)\n"
+				"    -s   --source    source btaddr\n"
+				"\n"
+				, outargs->argv[0]);
+		fuse_opt_add_arg(outargs, "-ho");
+		fuse_main(outargs->argc, outargs->argv, &obexfuse_oper, NULL);
+		exit(1);
+	case KEY_VERSION:
+		g_print("obexfuse upon:\n");
+		fuse_opt_add_arg(outargs, "--version");
+		fuse_main(outargs->argc, outargs->argv, &obexfuse_oper, NULL);
+		exit(0);
+	}
+	return 1;
+}
+
+int main(int argc, char *argv[])
+{
+	int retfuse;
+	struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
+
+	memset(&options, 0, sizeof(struct options));
+
+	if (fuse_opt_parse(&args, &options, obexfuse_opts,
+				obexfuse_opt_proc) == -1)
+		return -EINVAL;
+
+	if (options.dststr == NULL) {
+		g_printerr("Target not specified\n");
+		return -EINVAL;
+	}
+
+	g_thread_init(NULL);
+
+	fuse_opt_add_arg(&args, "-s"); /* force single threaded mode */
+	retfuse = fuse_main(args.argc, args.argv, &obexfuse_oper, NULL);
+
+	fuse_opt_free_args(&args);
+	return retfuse;
+}
-- 
1.7.8.6


^ permalink raw reply related

* Re: [PATCH BlueZ] control: Add methods FastForward and Rewind
From: Johan Hedberg @ 2012-12-01  9:25 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1354279699-1245-1-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On Fri, Nov 30, 2012, Luiz Augusto von Dentz wrote:
> These method can be used to fast-forward and rewind the playback, their
> action will keep active until another method is called.
> 
> The commands are reapeated every 2 seconds to conform with AVC spec.
> ---
>  doc/control-api.txt      |  10 ++++
>  profiles/audio/avctp.c   | 148 ++++++++++++++++++++++++++++++++++++++++++-----
>  profiles/audio/control.c |  14 +++++
>  3 files changed, 157 insertions(+), 15 deletions(-)


Applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH BlueZ v2 1/2] input: Fix emitting a signal for a non-existant interface
From: Johan Hedberg @ 2012-12-01  9:13 UTC (permalink / raw)
  To: Vinicius Costa Gomes; +Cc: linux-bluetooth
In-Reply-To: <1354322217-11219-1-git-send-email-vinicius.gomes@openbossa.org>

Hi Vinicius,

On Fri, Nov 30, 2012, Vinicius Costa Gomes wrote:
> When the 'org.bluez.Input' interface was removed, this should have been
> removed as well, now it is causing a segmentation fault.
> ---
>  profiles/input/device.c | 6 ------
>  1 file changed, 6 deletions(-)

Both patches have been applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH 1/4] gas: Fix memory leak at gas struct removal
From: Johan Hedberg @ 2012-12-01  9:11 UTC (permalink / raw)
  To: Paulo Borges; +Cc: linux-bluetooth
In-Reply-To: <1354300294-9105-1-git-send-email-paulo.borges@openbossa.org>

Hi Paulo,

On Fri, Nov 30, 2012, Paulo Borges wrote:
> ---
>  profiles/gatt/gas.c |    1 +
>  1 file changed, 1 insertion(+)

All four patches have been applied. Thanks.

Johan

^ permalink raw reply

* [PATCH BlueZ v2 2/2] input: Remove leftovers from the Input iface removal
From: Vinicius Costa Gomes @ 2012-12-01  0:36 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes
In-Reply-To: <1354322217-11219-1-git-send-email-vinicius.gomes@openbossa.org>

Now that the Input interface is removed, the only way to connect is
via the Profile interface, so no need to separate the way that
connection is made.
---
 profiles/input/device.c | 37 ++++++-------------------------------
 1 file changed, 6 insertions(+), 31 deletions(-)

diff --git a/profiles/input/device.c b/profiles/input/device.c
index 7538297..8464062 100644
--- a/profiles/input/device.c
+++ b/profiles/input/device.c
@@ -64,14 +64,8 @@
 #define FI_FLAG_CONNECTED	1
 
 struct pending_connect {
-	bool local;
-	union {
-		struct {
-			struct btd_profile *profile;
-			btd_profile_cb cb;
-		} p;
-		DBusMessage *msg;
-	};
+	struct btd_profile *profile;
+	btd_profile_cb cb;
 };
 
 struct input_device {
@@ -119,11 +113,8 @@ static void input_device_free(struct input_device *idev)
 	g_free(idev->name);
 	g_free(idev->path);
 
-	if (idev->pending) {
-		if (idev->pending->local)
-			dbus_message_unref(idev->pending->msg);
+	if (idev->pending)
 		g_free(idev->pending);
-	}
 
 	if (idev->ctrl_watch > 0)
 		g_source_remove(idev->ctrl_watch);
@@ -510,8 +501,6 @@ static void connect_reply(struct input_device *idev, int err,
 							const char *err_msg)
 {
 	struct pending_connect *pending = idev->pending;
-	DBusConnection *conn = btd_get_dbus_connection();
-	DBusMessage *reply;
 
 	if (!pending)
 		return;
@@ -521,20 +510,7 @@ static void connect_reply(struct input_device *idev, int err,
 	if (err_msg)
 		error("%s", err_msg);
 
-	if (!pending->local) {
-		pending->p.cb(pending->p.profile, idev->device, err);
-		g_free(pending);
-		return;
-	}
-
-	if (err_msg) {
-		reply = btd_error_failed(idev->pending->msg, err_msg);
-		g_dbus_send_message(conn, reply);
-	} else {
-		g_dbus_send_reply(conn, pending->msg, DBUS_TYPE_INVALID);
-	}
-
-	dbus_message_unref(pending->msg);
+	pending->cb(pending->profile, idev->device, err);
 	g_free(pending);
 }
 
@@ -667,9 +643,8 @@ int input_device_connect(struct btd_device *dev, struct btd_profile *profile,
 		return -EALREADY;
 
 	idev->pending = g_new0(struct pending_connect, 1);
-	idev->pending->local = false;
-	idev->pending->p.profile = profile;
-	idev->pending->p.cb = cb;
+	idev->pending->profile = profile;
+	idev->pending->cb = cb;
 
 	return dev_connect(idev);
 }
-- 
1.8.0


^ permalink raw reply related

* [PATCH BlueZ v2 1/2] input: Fix emitting a signal for a non-existant interface
From: Vinicius Costa Gomes @ 2012-12-01  0:36 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes

When the 'org.bluez.Input' interface was removed, this should have been
removed as well, now it is causing a segmentation fault.
---
 profiles/input/device.c | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/profiles/input/device.c b/profiles/input/device.c
index 2871cc3..7538297 100644
--- a/profiles/input/device.c
+++ b/profiles/input/device.c
@@ -160,9 +160,6 @@ static gboolean intr_watch_cb(GIOChannel *chan, GIOCondition cond, gpointer data
 	if ((cond & (G_IO_HUP | G_IO_ERR)) && idev->ctrl_watch)
 		g_io_channel_shutdown(chan, TRUE, NULL);
 
-	g_dbus_emit_property_changed(idev->conn, idev->path,
-					INPUT_DEVICE_INTERFACE, "Connected");
-
 	device_remove_disconnect_watch(idev->device, idev->dc_id);
 	idev->dc_id = 0;
 
@@ -503,9 +500,6 @@ static int input_device_connected(struct input_device *idev)
 	if (err < 0)
 		return err;
 
-	g_dbus_emit_property_changed(idev->conn, idev->path,
-					INPUT_DEVICE_INTERFACE, "Connected");
-
 	idev->dc_id = device_add_disconnect_watch(idev->device, disconnect_cb,
 							idev, NULL);
 
-- 
1.8.0


^ permalink raw reply related

* Re: [PATCH BlueZ] input: Fix emitting a signal for a non-existant interface
From: Vinicius Gomes @ 2012-11-30 23:45 UTC (permalink / raw)
  To: BlueZ development; +Cc: Vinicius Costa Gomes
In-Reply-To: <1354318625-15066-1-git-send-email-vinicius.gomes@openbossa.org>

Hi,

On Fri, Nov 30, 2012 at 8:37 PM, Vinicius Costa Gomes
<vinicius.gomes@openbossa.org> wrote:
> When the 'org.bluez.Input' interface was removed, this should have been
> removed as well, now it is causing a segmentation fault.
> ---

Please ignore this patch. I didn't notice that the signal is emitted
in another place too. Updated version coming soon.


Cheers,
--
Vinicius

^ permalink raw reply

* [PATCH BlueZ] input: Fix emitting a signal for a non-existant interface
From: Vinicius Costa Gomes @ 2012-11-30 23:37 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes

When the 'org.bluez.Input' interface was removed, this should have been
removed as well, now it is causing a segmentation fault.
---
 profiles/input/device.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/profiles/input/device.c b/profiles/input/device.c
index 2871cc3..421af64 100644
--- a/profiles/input/device.c
+++ b/profiles/input/device.c
@@ -503,9 +503,6 @@ static int input_device_connected(struct input_device *idev)
 	if (err < 0)
 		return err;
 
-	g_dbus_emit_property_changed(idev->conn, idev->path,
-					INPUT_DEVICE_INTERFACE, "Connected");
-
 	idev->dc_id = device_add_disconnect_watch(idev->device, disconnect_cb,
 							idev, NULL);
 
-- 
1.8.0


^ permalink raw reply related

* [PATCH 4/4] gatt: Improve characteristics discovery
From: Paulo Borges @ 2012-11-30 18:31 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Paulo Borges
In-Reply-To: <1354300294-9105-1-git-send-email-paulo.borges@openbossa.org>

In the Discover Characteristics by UUID sub-procedure, if a fetched
characteristic doesn't matches with the target UUID, all others
characteristics in that response were discarded.

Because of this, the procedure will make a new request to possibly
rediscover the characteristics in the range beyond this last
characteristic.

At present, this procedure works because the gatt library will send a
Read by Type Request starting at the first attribute after the non
matching characteristic.

This commit makes the rest of the characteristics to be checked for a
matching type, which should reduce the number of requests sent during
the discovery of characteristics.
---
 attrib/gatt.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/attrib/gatt.c b/attrib/gatt.c
index b834b13..38c050e 100644
--- a/attrib/gatt.c
+++ b/attrib/gatt.c
@@ -476,7 +476,7 @@ static void char_discovered_cb(guint8 status, const guint8 *ipdu, guint16 iplen,
 			uuid = att_get_uuid128(&value[5]);
 
 		if (dc->uuid && bt_uuid_cmp(dc->uuid, &uuid))
-			break;
+			continue;
 
 		chars = g_try_new0(struct gatt_char, 1);
 		if (!chars) {
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 3/4] gatt: Fix memory leak in characteristic discovery
From: Paulo Borges @ 2012-11-30 18:31 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Paulo Borges
In-Reply-To: <1354300294-9105-1-git-send-email-paulo.borges@openbossa.org>

If the Discover Characteristics by UUID sub-procedure has been
executed and the first characteristic is not the target, a memory
leak occurs.

This commit fixes this leak by postponing the allocation to after
the UUID verification.
---
 attrib/gatt.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/attrib/gatt.c b/attrib/gatt.c
index 963fa20..b834b13 100644
--- a/attrib/gatt.c
+++ b/attrib/gatt.c
@@ -475,15 +475,15 @@ static void char_discovered_cb(guint8 status, const guint8 *ipdu, guint16 iplen,
 		} else
 			uuid = att_get_uuid128(&value[5]);
 
+		if (dc->uuid && bt_uuid_cmp(dc->uuid, &uuid))
+			break;
+
 		chars = g_try_new0(struct gatt_char, 1);
 		if (!chars) {
 			err = ATT_ECODE_INSUFF_RESOURCES;
 			goto done;
 		}
 
-		if (dc->uuid && bt_uuid_cmp(dc->uuid, &uuid))
-			break;
-
 		chars->handle = last;
 		chars->properties = value[2];
 		chars->value_handle = att_get_u16(&value[3]);
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 2/4] input: Fix memory leak at hogdev struct removal
From: Paulo Borges @ 2012-11-30 18:31 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Paulo Borges
In-Reply-To: <1354300294-9105-1-git-send-email-paulo.borges@openbossa.org>

---
 profiles/input/hog_device.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/profiles/input/hog_device.c b/profiles/input/hog_device.c
index 0a5fb58..a873eac 100644
--- a/profiles/input/hog_device.c
+++ b/profiles/input/hog_device.c
@@ -705,6 +705,7 @@ static void hog_device_free(struct hog_device *hogdev)
 {
 	btd_device_unref(hogdev->device);
 	g_slist_free_full(hogdev->reports, report_free);
+	g_attrib_unref(hogdev->attrib);
 	g_free(hogdev->hog_primary);
 	g_free(hogdev);
 }
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 1/4] gas: Fix memory leak at gas struct removal
From: Paulo Borges @ 2012-11-30 18:31 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Paulo Borges

---
 profiles/gatt/gas.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/profiles/gatt/gas.c b/profiles/gatt/gas.c
index 0e82097..e6cddad 100644
--- a/profiles/gatt/gas.c
+++ b/profiles/gatt/gas.c
@@ -64,6 +64,7 @@ static void gas_free(struct gas *gas)
 	if (gas->attioid)
 		btd_device_remove_attio_callback(gas->device, gas->attioid);
 
+	g_attrib_unref(gas->attrib);
 	btd_device_unref(gas->device);
 	g_free(gas);
 }
-- 
1.7.9.5


^ permalink raw reply related

* Re: [PATCHv2 4/4] Bluetooth: trivial: Change NO_FCS_RECV to RECV_NO_FCS
From: Gustavo Padovan @ 2012-11-30 17:50 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1354203968-1335-4-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

* Andrei Emeltchenko <Andrei.Emeltchenko.news@gmail.com> [2012-11-29 17:46:08 +0200]:

> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> 
> Make code more readable by changing CONF_NO_FCS_RECV which is read
> as "No L2CAP FCS option received" to CONF_RECV_NO_FCS which means
> "Received L2CAP option NO_FCS". This flag really means that we have
> received L2CAP FRAME CHECK SEQUENCE (FCS) OPTION with value "No FCS".
> 
> Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> ---
>  include/net/bluetooth/l2cap.h |    2 +-
>  net/bluetooth/l2cap_core.c    |   10 +++++-----
>  2 files changed, 6 insertions(+), 6 deletions(-)

All patches have been applied to bluetooth-next. Thanks.

	Gustavo

^ permalink raw reply

* [PATCH] Bluetooth: Fix using locked state_change for A2MP chan
From: Andrei Emeltchenko @ 2012-11-30 14:51 UTC (permalink / raw)
  To: linux-bluetooth

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

A2MP channel do not have sk associated so use unlocked version
of state_change. chan is already locked.

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
 net/bluetooth/l2cap_core.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 2414cff..6de4287 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1276,7 +1276,7 @@ static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
 	}
 
 	if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
-		l2cap_state_change(chan, BT_DISCONN);
+		__l2cap_state_change(chan, BT_DISCONN);
 		return;
 	}
 
-- 
1.7.10.4


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox