You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2017/03/28 22:41:49 UTC

[52/67] [abbrv] incubator-mynewt-newtmgr git commit: nmxact - Generic adv predicate during scanning.

nmxact - Generic adv predicate during scanning.

If the client doesn't know the address of the peer it wants to connect
to, it can supply a predicate which gets called for each incoming
advertisement.  If the callback returns true, nmxact will connect to the
sender of the corresponding advertisement.


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/commit/06f33c03
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/tree/06f33c03
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/diff/06f33c03

Branch: refs/heads/master
Commit: 06f33c03ececeac75b39fabea922d657958a6118
Parents: 4bcaec2
Author: Christopher Collins <cc...@apache.org>
Authored: Tue Mar 28 11:11:51 2017 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Tue Mar 28 15:38:36 2017 -0700

----------------------------------------------------------------------
 nmxact/bledefs/bledefs.go      | 21 +++++++++----
 nmxact/nmble/ble_fsm.go        | 60 +++++++++++++++++++++++++++----------
 nmxact/nmble/ble_oic_sesn.go   |  2 +-
 nmxact/nmble/ble_plain_sesn.go |  2 +-
 nmxact/sesn/sesn_cfg.go        | 28 ++++++++++++++++-
 5 files changed, 90 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/06f33c03/nmxact/bledefs/bledefs.go
----------------------------------------------------------------------
diff --git a/nmxact/bledefs/bledefs.go b/nmxact/bledefs/bledefs.go
index 5b12d0a..3bb2772 100644
--- a/nmxact/bledefs/bledefs.go
+++ b/nmxact/bledefs/bledefs.go
@@ -147,11 +147,6 @@ func (bd *BleDev) String() string {
 		bd.Addr.String())
 }
 
-type BlePeerSpec struct {
-	Name string
-	Dev  BleDev // Only used if name not present.
-}
-
 type BleScanFilterPolicy int
 
 const (
@@ -257,3 +252,19 @@ func (a *BleAdvEventType) UnmarshalJSON(data []byte) error {
 	*a, err = BleAdvEventTypeFromString(s)
 	return err
 }
+
+type BleAdvReport struct {
+	// These fields are always present.
+	EventType BleAdvEventType
+	Sender    BleDev
+	Rssi      int8
+	Data      []byte
+
+	// These fields are only present if the sender included them in its
+	// advertisement.
+	Flags          uint8  // 0 if not present.
+	Name           string // "" if not present.
+	NameIsComplete bool   // false if not present.
+}
+
+type BleAdvPredicate func(adv BleAdvReport) bool

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/06f33c03/nmxact/nmble/ble_fsm.go
----------------------------------------------------------------------
diff --git a/nmxact/nmble/ble_fsm.go b/nmxact/nmble/ble_fsm.go
index 88ce90e..411ce59 100644
--- a/nmxact/nmble/ble_fsm.go
+++ b/nmxact/nmble/ble_fsm.go
@@ -11,6 +11,7 @@ import (
 	. "mynewt.apache.org/newt/nmxact/bledefs"
 	"mynewt.apache.org/newt/nmxact/nmp"
 	"mynewt.apache.org/newt/nmxact/nmxutil"
+	"mynewt.apache.org/newt/nmxact/sesn"
 )
 
 type BleSesnState int32
@@ -38,7 +39,7 @@ type BleDisconnectFn func(err error)
 type BleFsmParams struct {
 	Bx           *BleXport
 	OwnAddrType  BleAddrType
-	PeerSpec     BlePeerSpec
+	PeerSpec     sesn.BlePeerSpec
 	SvcUuid      BleUuid
 	ReqChrUuid   BleUuid
 	RspChrUuid   BleUuid
@@ -48,9 +49,9 @@ type BleFsmParams struct {
 
 type BleFsm struct {
 	bx           *BleXport
-	peerSpec     BlePeerSpec
 	ownAddrType  BleAddrType
-	peer         *BleDev
+	peerSpec     sesn.BlePeerSpec
+	peerDev      *BleDev
 	svcUuid      BleUuid
 	reqChrUuid   BleUuid
 	rspChrUuid   BleUuid
@@ -87,8 +88,14 @@ func NewBleFsm(p BleFsmParams) *BleFsm {
 		attMtu: DFLT_ATT_MTU,
 	}
 
-	if bf.peerSpec.Name == "" {
-		bf.peer = &bf.peerSpec.Dev
+	// The peer spec contains one of:
+	//     * Peer address;
+	//     * Predicate function to call during scanning.
+	// If a peer address is specified, fill in the peer field now so the
+	// scanning step can be skipped.  Otherwise, the peer field gets populated
+	// during scanning.
+	if bf.peerSpec.ScanPred == nil {
+		bf.peerDev = &bf.peerSpec.Dev
 	}
 
 	return bf
@@ -97,7 +104,7 @@ func NewBleFsm(p BleFsmParams) *BleFsm {
 func (bf *BleFsm) disconnectError(reason int) error {
 	str := fmt.Sprintf("BLE peer disconnected; "+
 		"reason=\"%s\" (%d) peer=%s handle=%d",
-		ErrCodeToString(reason), reason, bf.peer.String(), bf.connHandle)
+		ErrCodeToString(reason), reason, bf.peerDev.String(), bf.connHandle)
 	return nmxutil.NewBleSesnDisconnectError(reason, str)
 }
 
@@ -231,7 +238,7 @@ func (bf *BleFsm) connectListen(seq int) error {
 						str := fmt.Sprintf("BLE connection attempt failed; "+
 							"status=%s (%d) peer=%s",
 							ErrCodeToString(msg.Status), msg.Status,
-							bf.peer.String())
+							bf.peerDev.String())
 						log.Debugf(str)
 						bf.connChan <- nmxutil.NewBleHostError(msg.Status, str)
 						return
@@ -241,7 +248,7 @@ func (bf *BleFsm) connectListen(seq int) error {
 					if msg.Status == 0 {
 						bl.Acked = true
 						log.Debugf("BLE connection attempt succeeded; "+
-							"peer=%d handle=%d", bf.peer.String(),
+							"peer=%d handle=%d", bf.peerDev.String(),
 							msg.ConnHandle)
 						bf.connHandle = msg.ConnHandle
 						if err := bf.nmpRspListen(); err != nil {
@@ -253,7 +260,7 @@ func (bf *BleFsm) connectListen(seq int) error {
 						str := fmt.Sprintf("BLE connection attempt failed; "+
 							"status=%s (%d) peer=%s",
 							ErrCodeToString(msg.Status), msg.Status,
-							bf.peer.String())
+							bf.peerDev.String())
 						log.Debugf(str)
 						bf.connChan <- nmxutil.NewBleHostError(msg.Status, str)
 						return
@@ -341,8 +348,8 @@ func (bf *BleFsm) nmpRspListen() error {
 func (bf *BleFsm) connect() error {
 	r := NewBleConnectReq()
 	r.OwnAddrType = bf.ownAddrType
-	r.PeerAddrType = bf.peer.AddrType
-	r.PeerAddr = bf.peer.Addr
+	r.PeerAddrType = bf.peerDev.AddrType
+	r.PeerAddr = bf.peerDev.Addr
 
 	if err := bf.connectListen(r.Seq); err != nil {
 		return err
@@ -372,15 +379,29 @@ func (bf *BleFsm) scan() error {
 
 	abortChan := make(chan struct{}, 1)
 
+	// This function gets called for each incoming advertisement.
 	scanCb := func(evt *BleScanEvt) {
-		if evt.DataName == bf.peerSpec.Name {
-			bf.peer = &BleDev{
+		r := BleAdvReport{
+			EventType: evt.EventType,
+			Sender: BleDev{
 				AddrType: evt.AddrType,
 				Addr:     evt.Addr,
-			}
+			},
+			Rssi: evt.Rssi,
+			Data: evt.Data.Bytes,
+
+			Flags:          evt.DataFlags,
+			Name:           evt.DataName,
+			NameIsComplete: evt.DataNameIsComplete,
+		}
+
+		// Ask client if we should connect to this advertiser.
+		if bf.peerSpec.ScanPred(r) {
+			bf.peerDev = &r.Sender
 			abortChan <- struct{}{}
 		}
 	}
+
 	if err := scan(bf.bx, bl, r, abortChan, scanCb); err != nil {
 		return err
 	}
@@ -596,7 +617,14 @@ func (bf *BleFsm) Start() error {
 		switch state {
 		case SESN_STATE_UNCONNECTED:
 			var err error
-			if bf.peer == nil {
+
+			// Determine if we can immediately initiate a connection, or if we
+			// need to scan for a peer first.  If the client specified a peer
+			// address, or if we have already successfully scanned, we initiate
+			// a connection now.  Otherwise, we need to scan to determine which
+			// peer meets the specified scan criteria.
+			if bf.peerDev == nil {
+				// Peer not inferred yet.  Initiate scan.
 				cb := func() error { return bf.scan() }
 				err = bf.action(
 					SESN_STATE_UNCONNECTED,
@@ -604,6 +632,8 @@ func (bf *BleFsm) Start() error {
 					SESN_STATE_UNCONNECTED,
 					cb)
 			} else {
+				// We already know the address we want to connect to.  Initiate
+				// a connection.
 				cb := func() error { return bf.connect() }
 				err = bf.action(
 					SESN_STATE_UNCONNECTED,

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/06f33c03/nmxact/nmble/ble_oic_sesn.go
----------------------------------------------------------------------
diff --git a/nmxact/nmble/ble_oic_sesn.go b/nmxact/nmble/ble_oic_sesn.go
index f0dead2..98a30e9 100644
--- a/nmxact/nmble/ble_oic_sesn.go
+++ b/nmxact/nmble/ble_oic_sesn.go
@@ -49,7 +49,7 @@ func NewBleOicSesn(bx *BleXport, cfg sesn.SesnCfg) *BleOicSesn {
 	bos.bf = NewBleFsm(BleFsmParams{
 		Bx:           bx,
 		OwnAddrType:  cfg.Ble.OwnAddrType,
-		PeerSpec:     cfg.Ble.Peer,
+		PeerSpec:     cfg.Ble.PeerSpec,
 		SvcUuid:      svcUuid,
 		ReqChrUuid:   reqChrUuid,
 		RspChrUuid:   rspChrUuid,

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/06f33c03/nmxact/nmble/ble_plain_sesn.go
----------------------------------------------------------------------
diff --git a/nmxact/nmble/ble_plain_sesn.go b/nmxact/nmble/ble_plain_sesn.go
index c4b24c6..b4fda8e 100644
--- a/nmxact/nmble/ble_plain_sesn.go
+++ b/nmxact/nmble/ble_plain_sesn.go
@@ -43,7 +43,7 @@ func NewBlePlainSesn(bx *BleXport, cfg sesn.SesnCfg) *BlePlainSesn {
 	bps.bf = NewBleFsm(BleFsmParams{
 		Bx:           bx,
 		OwnAddrType:  cfg.Ble.OwnAddrType,
-		PeerSpec:     cfg.Ble.Peer,
+		PeerSpec:     cfg.Ble.PeerSpec,
 		SvcUuid:      svcUuid,
 		ReqChrUuid:   chrUuid,
 		RspChrUuid:   chrUuid,

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/06f33c03/nmxact/sesn/sesn_cfg.go
----------------------------------------------------------------------
diff --git a/nmxact/sesn/sesn_cfg.go b/nmxact/sesn/sesn_cfg.go
index cb6dce6..c511d10 100644
--- a/nmxact/sesn/sesn_cfg.go
+++ b/nmxact/sesn/sesn_cfg.go
@@ -15,9 +15,35 @@ const (
 
 type OnCloseFn func(s Sesn, err error)
 
+// Specifies the BLE peer to connect to.
+type BlePeerSpec struct {
+	// This is filled in if you know the address of the peer to connect to.
+	Dev bledefs.BleDev
+
+	// Otherwise, we must scan for a peer to connect to.  This points to a
+	// function that indicates whether we should connect to the sender of the
+	// specified advertisement.  This function gets called each time an
+	// incoming advertisement is received.  If it returns true, the session
+	// will connect to the sender of the corresponding advertisement.  Set this
+	// to nil if you populate the Dev field.
+	ScanPred bledefs.BleAdvPredicate
+}
+
+func BlePeerSpecDev(dev bledefs.BleDev) BlePeerSpec {
+	return BlePeerSpec{Dev: dev}
+}
+
+func BlePeerSpecName(name string) BlePeerSpec {
+	return BlePeerSpec{
+		ScanPred: func(r bledefs.BleAdvReport) bool {
+			return r.Name == name
+		},
+	}
+}
+
 type SesnCfgBle struct {
 	OwnAddrType  bledefs.BleAddrType
-	Peer         bledefs.BlePeerSpec
+	PeerSpec     BlePeerSpec
 	CloseTimeout time.Duration
 }