Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions gap.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ type GAPDevice interface {
RequestConnectionParams(params ConnectionParams) error
Connected() (bool, error)
Disconnect() error
OpenL2CAPChannel(psm L2CAPPSM) (*L2CAPConn, error)
}

// ScanResult contains information from when an advertisement packet was
Expand Down
10 changes: 9 additions & 1 deletion gap_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ type deviceInternal struct {
servicesChan chan error
charsChan chan error

services map[UUID]DeviceService
services map[UUID]DeviceService
l2capChan chan l2capResult
}

// Connect starts a connection attempt to the given peripheral device address.
Expand Down Expand Up @@ -256,3 +257,10 @@ func (pd *peripheralDelegate) DidWriteValueForCharacteristic(_ cbgo.Peripheral,
}
}
}

// DidOpenL2CAPChannel is called when an L2CAP channel has been opened.
func (pd *peripheralDelegate) DidOpenL2CAPChannel(prph cbgo.Peripheral, channel cbgo.L2CAPChannel, err error) {
if pd.d.l2capChan != nil {
pd.d.l2capChan <- l2capResult{channel: channel, err: err}
}
}
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ require (
github.com/godbus/dbus/v5 v5.1.0
github.com/saltosystems/winrt-go v0.0.0-20240509164145-4f7860a3bd2b
github.com/soypat/cyw43439 v0.0.0-20250505012923-830110c8f4af
github.com/tinygo-org/cbgo v0.0.4
golang.org/x/crypto v0.12.0
github.com/tinygo-org/cbgo v0.0.5-0.20260404133704-78b73a9c8e7e
golang.org/x/crypto v0.26.0
tinygo.org/x/drivers v0.33.0
tinygo.org/x/tinyfont v0.6.0
tinygo.org/x/tinyterm v0.5.0
Expand All @@ -20,6 +20,6 @@ require (
github.com/soypat/seqs v0.0.0-20250124201400-0d65bc7c1710 // indirect
github.com/tinygo-org/pio v0.2.0 // indirect
golang.org/x/exp v0.0.0-20241204233417-43b7b7cde48d // indirect
golang.org/x/sys v0.11.0 // indirect
golang.org/x/term v0.11.0 // indirect
golang.org/x/sys v0.23.0 // indirect
golang.org/x/term v0.23.0 // indirect
)
77 changes: 69 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
Expand All @@ -24,21 +25,81 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.5 h1:s5PTfem8p8EbKQOctVV53k6jCJt3UX4IEJzwh+C324Q=
github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/tinygo-org/cbgo v0.0.4 h1:3D76CRYbH03Rudi8sEgs/YO0x3JIMdyq8jlQtk/44fU=
github.com/tinygo-org/cbgo v0.0.4/go.mod h1:7+HgWIHd4nbAz0ESjGlJ1/v9LDU1Ox8MGzP9mah/fLk=
github.com/tinygo-org/cbgo v0.0.5-0.20260404133704-78b73a9c8e7e h1:6rWS9GYjNL5fM9R57DO9sm0k29i0083HhSfJCzEmq2Q=
github.com/tinygo-org/cbgo v0.0.5-0.20260404133704-78b73a9c8e7e/go.mod h1:FruLOLNWPVyKyydTExa3RiPBjlAiorVsfRizhv4evoM=
github.com/tinygo-org/pio v0.2.0 h1:vo3xa6xDZ2rVtxrks/KcTZHF3qq4lyWOntvEvl2pOhU=
github.com/tinygo-org/pio v0.2.0/go.mod h1:LU7Dw00NJ+N86QkeTGjMLNkYcEYMor6wTDpTCu0EaH8=
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/exp v0.0.0-20241204233417-43b7b7cde48d h1:0olWaB5pg3+oychR51GUVCEsGkeCU/2JxjBgIo4f3M0=
golang.org/x/exp v0.0.0-20241204233417-43b7b7cde48d/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0=
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU=
golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Expand Down
13 changes: 13 additions & 0 deletions l2cap.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package bluetooth

import "io"

// L2CAPPSM represents an L2CAP Protocol/Service Multiplexer identifier.
type L2CAPPSM = uint16

// L2CAPChannel is the common interface implemented by L2CAPConn on all platforms.
type L2CAPChannel interface {
io.ReadWriteCloser
// PSM returns the Protocol/Service Multiplexer identifier for this channel.
PSM() L2CAPPSM
}
143 changes: 143 additions & 0 deletions l2cap_darwin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package bluetooth

import (
"errors"
"io"
"runtime"
"sync"
"time"

"github.com/tinygo-org/cbgo"
)

// l2capResult is used internally to communicate the result of an L2CAP channel
// open operation from the delegate callback to the calling goroutine.
type l2capResult struct {
channel cbgo.L2CAPChannel
err error
}

// L2CAPConn represents an L2CAP Connection-Oriented Channel connection.
// It implements io.ReadWriteCloser for bidirectional communication.
type L2CAPConn struct {
channel cbgo.L2CAPChannel
mu sync.Mutex
closed bool
}

var _ L2CAPChannel = (*L2CAPConn)(nil)

// OpenL2CAPChannel opens an L2CAP Connection-Oriented Channel to the
// connected peripheral. The PSM (Protocol/Service Multiplexer) identifies the
// L2CAP service to connect to on the remote device.
//
// The device must already be connected via Connect before calling this method.
func (d Device) OpenL2CAPChannel(psm L2CAPPSM) (*L2CAPConn, error) {
ch := make(chan l2capResult, 1)
d.l2capChan = ch
defer func() { d.l2capChan = nil }()

d.prph.OpenL2CAPChannel(psm)

select {
case result := <-ch:
if result.err != nil {
return nil, result.err
}
return &L2CAPConn{
channel: result.channel,
}, nil
case <-time.NewTimer(30 * time.Second).C:
return nil, errors.New("bluetooth: timeout on OpenL2CAPChannel")
}
}

// Read reads data from the L2CAP channel. It blocks until data is available,
// the channel is closed locally, or the remote end closes the stream (EOF).
func (c *L2CAPConn) Read(p []byte) (int, error) {
if len(p) == 0 {
return 0, nil
}

for {
c.mu.Lock()
if c.closed {
c.mu.Unlock()
return 0, io.ErrClosedPipe
}
c.mu.Unlock()

n := c.channel.Read(p)
if n < 0 {
return 0, errors.New("bluetooth: L2CAP read error")
}
if n > 0 {
return n, nil
}

// c.channel.Read returns 0 in two cases:
// - hasBytesAvailable was false → no data yet, retry.
// - hasBytesAvailable was true but NSInputStream read returned 0 → EOF.
// Distinguish them by checking HasBytesAvailable after a 0-byte read.
if !c.channel.HasBytesAvailable() {
// No data available yet, yield and retry.
runtime.Gosched()
continue
}
// The stream reported bytes available yet Read returned 0:
// the input stream has reached end-of-stream.
return 0, io.EOF
}
}

// Write writes data to the L2CAP channel. It blocks until all data has been
// written or the channel is closed.
func (c *L2CAPConn) Write(p []byte) (int, error) {
if len(p) == 0 {
return 0, nil
}

total := 0
for total < len(p) {
c.mu.Lock()
if c.closed {
c.mu.Unlock()
return total, io.ErrClosedPipe
}
c.mu.Unlock()

// Output stream not ready yet, yield and retry.
if !c.channel.HasSpaceAvailable() {
runtime.Gosched()
continue
}

n := c.channel.Write(p[total:])
if n < 0 {
return total, errors.New("bluetooth: L2CAP write error")
}
if n > 0 {
total += n
continue
}
}
return total, nil
}

// Close closes the L2CAP channel.
func (c *L2CAPConn) Close() error {
c.mu.Lock()
defer c.mu.Unlock()

if c.closed {
return nil
}
c.closed = true
c.channel.Close()
return nil
}

// PSM returns the Protocol/Service Multiplexer identifier for this channel.
func (c *L2CAPConn) PSM() L2CAPPSM {
return c.channel.PSM()
}
30 changes: 30 additions & 0 deletions l2cap_hci.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,33 @@ func (l *l2cap) sendReq(handle uint16, data []byte) error {

return l.hci.sendAclPkt(handle, signalingCID, data)
}

// L2CAPConn represents an L2CAP Connection-Oriented Channel connection.
type L2CAPConn struct{}

var _ L2CAPChannel = (*L2CAPConn)(nil)

// Read is not yet implemented on this platform.
func (c *L2CAPConn) Read(p []byte) (int, error) {
return 0, errNotYetImplmented
}

// Write is not yet implemented on this platform.
func (c *L2CAPConn) Write(p []byte) (int, error) {
return 0, errNotYetImplmented
}

// Close is not yet implemented on this platform.
func (c *L2CAPConn) Close() error {
return errNotYetImplmented
}

// PSM is not yet implemented on this platform.
func (c *L2CAPConn) PSM() L2CAPPSM {
return 0
}

// OpenL2CAPChannel is not yet implemented on this platform.
func (d Device) OpenL2CAPChannel(psm L2CAPPSM) (*L2CAPConn, error) {
return nil, errNotYetImplmented
}
33 changes: 33 additions & 0 deletions l2cap_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//go:build !baremetal

package bluetooth

// L2CAPConn represents an L2CAP Connection-Oriented Channel connection.
type L2CAPConn struct{}

var _ L2CAPChannel = (*L2CAPConn)(nil)

// Read is not yet implemented on this platform.
func (c *L2CAPConn) Read(p []byte) (int, error) {
return 0, errNotYetImplmented
}

// Write is not yet implemented on this platform.
func (c *L2CAPConn) Write(p []byte) (int, error) {
return 0, errNotYetImplmented
}

// Close is not yet implemented on this platform.
func (c *L2CAPConn) Close() error {
return errNotYetImplmented
}

// PSM is not yet implemented on this platform.
func (c *L2CAPConn) PSM() L2CAPPSM {
return 0
}

// OpenL2CAPChannel is not yet implemented on this platform.
func (d Device) OpenL2CAPChannel(psm L2CAPPSM) (*L2CAPConn, error) {
return nil, errNotYetImplmented
}
Loading
Loading