newtmgr - revendor

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/ff255cbf
Tree: 
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/tree/ff255cbf
Diff: 
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/diff/ff255cbf

Branch: refs/heads/master
Commit: ff255cbfab3a81c2e012e6a7390bfe10c339f634
Parents: 4a3a72a
Author: Christopher Collins <[email protected]>
Authored: Wed Mar 29 16:00:30 2017 -0700
Committer: Christopher Collins <[email protected]>
Committed: Wed Mar 29 18:51:17 2017 -0700

----------------------------------------------------------------------
 newtmgr/Godeps/Godeps.json                      |  36 ++---
 .../newtmgr/nmxact/nmble/ble_fsm.go             | 138 +++++++++++--------
 .../newtmgr/nmxact/nmble/ble_oic_sesn.go        |  85 ++++++++----
 .../newtmgr/nmxact/nmble/ble_plain_sesn.go      |  94 +++++++++----
 .../newtmgr/nmxact/sesn/sesn_cfg.go             |   2 +
 5 files changed, 230 insertions(+), 125 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/ff255cbf/newtmgr/Godeps/Godeps.json
----------------------------------------------------------------------
diff --git a/newtmgr/Godeps/Godeps.json b/newtmgr/Godeps/Godeps.json
index fbbd835..4461c33 100644
--- a/newtmgr/Godeps/Godeps.json
+++ b/newtmgr/Godeps/Godeps.json
@@ -96,48 +96,48 @@
                },
                {
                        "ImportPath": 
"mynewt.apache.org/newtmgr/nmxact/bledefs",
-                       "Comment": "mynewt_0_9_0_tag-446-gabaa035",
-                       "Rev": "abaa03594e726b6d2b749bc405f4006eb4820c1b"
+                       "Comment": "mynewt_0_9_0_tag-448-ga808bde",
+                       "Rev": "a808bde2b242416e3ad2e52d125fa26f098dc6e1"
                },
                {
                        "ImportPath": "mynewt.apache.org/newtmgr/nmxact/nmble",
-                       "Comment": "mynewt_0_9_0_tag-446-gabaa035",
-                       "Rev": "abaa03594e726b6d2b749bc405f4006eb4820c1b"
+                       "Comment": "mynewt_0_9_0_tag-448-ga808bde",
+                       "Rev": "a808bde2b242416e3ad2e52d125fa26f098dc6e1"
                },
                {
                        "ImportPath": "mynewt.apache.org/newtmgr/nmxact/nmp",
-                       "Comment": "mynewt_0_9_0_tag-446-gabaa035",
-                       "Rev": "abaa03594e726b6d2b749bc405f4006eb4820c1b"
+                       "Comment": "mynewt_0_9_0_tag-448-ga808bde",
+                       "Rev": "a808bde2b242416e3ad2e52d125fa26f098dc6e1"
                },
                {
                        "ImportPath": 
"mynewt.apache.org/newtmgr/nmxact/nmserial",
-                       "Comment": "mynewt_0_9_0_tag-446-gabaa035",
-                       "Rev": "abaa03594e726b6d2b749bc405f4006eb4820c1b"
+                       "Comment": "mynewt_0_9_0_tag-448-ga808bde",
+                       "Rev": "a808bde2b242416e3ad2e52d125fa26f098dc6e1"
                },
                {
                        "ImportPath": 
"mynewt.apache.org/newtmgr/nmxact/nmxutil",
-                       "Comment": "mynewt_0_9_0_tag-446-gabaa035",
-                       "Rev": "abaa03594e726b6d2b749bc405f4006eb4820c1b"
+                       "Comment": "mynewt_0_9_0_tag-448-ga808bde",
+                       "Rev": "a808bde2b242416e3ad2e52d125fa26f098dc6e1"
                },
                {
                        "ImportPath": "mynewt.apache.org/newtmgr/nmxact/omp",
-                       "Comment": "mynewt_0_9_0_tag-446-gabaa035",
-                       "Rev": "abaa03594e726b6d2b749bc405f4006eb4820c1b"
+                       "Comment": "mynewt_0_9_0_tag-448-ga808bde",
+                       "Rev": "a808bde2b242416e3ad2e52d125fa26f098dc6e1"
                },
                {
                        "ImportPath": "mynewt.apache.org/newtmgr/nmxact/sesn",
-                       "Comment": "mynewt_0_9_0_tag-446-gabaa035",
-                       "Rev": "abaa03594e726b6d2b749bc405f4006eb4820c1b"
+                       "Comment": "mynewt_0_9_0_tag-448-ga808bde",
+                       "Rev": "a808bde2b242416e3ad2e52d125fa26f098dc6e1"
                },
                {
                        "ImportPath": "mynewt.apache.org/newtmgr/nmxact/xact",
-                       "Comment": "mynewt_0_9_0_tag-446-gabaa035",
-                       "Rev": "abaa03594e726b6d2b749bc405f4006eb4820c1b"
+                       "Comment": "mynewt_0_9_0_tag-448-ga808bde",
+                       "Rev": "a808bde2b242416e3ad2e52d125fa26f098dc6e1"
                },
                {
                        "ImportPath": "mynewt.apache.org/newtmgr/nmxact/xport",
-                       "Comment": "mynewt_0_9_0_tag-446-gabaa035",
-                       "Rev": "abaa03594e726b6d2b749bc405f4006eb4820c1b"
+                       "Comment": "mynewt_0_9_0_tag-448-ga808bde",
+                       "Rev": "a808bde2b242416e3ad2e52d125fa26f098dc6e1"
                }
        ]
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/ff255cbf/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_fsm.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_fsm.go 
b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_fsm.go
index 9c96526..cf12bdc 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_fsm.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_fsm.go
@@ -14,10 +14,10 @@ import (
        "mynewt.apache.org/newtmgr/nmxact/sesn"
 )
 
-type BleSesnState int32
-
 const DFLT_ATT_MTU = 23
 
+type BleSesnState int32
+
 const (
        SESN_STATE_UNCONNECTED     BleSesnState = 0
        SESN_STATE_SCANNING                     = 1
@@ -33,8 +33,17 @@ const (
        SESN_STATE_CONN_CANCELLING              = 11
 )
 
+type BleFsmDisconnectType int
+
+const (
+       FSM_DISCONNECT_TYPE_UNOPENED BleFsmDisconnectType = iota
+       FSM_DISCONNECT_TYPE_IMMEDIATE_TIMEOUT
+       FSM_DISCONNECT_TYPE_OPENED
+       FSM_DISCONNECT_TYPE_REQUESTED
+)
+
 type BleRxNmpFn func(data []byte)
-type BleDisconnectFn func(peer BleDev, err error)
+type BleDisconnectFn func(dt BleFsmDisconnectType, peer BleDev, err error)
 
 type BleFsmParams struct {
        Bx           *BleXport
@@ -48,16 +57,9 @@ type BleFsmParams struct {
 }
 
 type BleFsm struct {
-       bx           *BleXport
-       ownAddrType  BleAddrType
-       peerSpec     sesn.BlePeerSpec
-       peerDev      *BleDev
-       svcUuid      BleUuid
-       reqChrUuid   BleUuid
-       rspChrUuid   BleUuid
-       rxNmpCb      BleRxNmpFn
-       disconnectCb BleDisconnectFn
+       params BleFsmParams
 
+       peerDev    *BleDev
        connHandle int
        nmpSvc     *BleSvc
        nmpReqChr  *BleChr
@@ -75,14 +77,7 @@ type BleFsm struct {
 
 func NewBleFsm(p BleFsmParams) *BleFsm {
        bf := &BleFsm{
-               bx:           p.Bx,
-               peerSpec:     p.PeerSpec,
-               ownAddrType:  p.OwnAddrType,
-               svcUuid:      p.SvcUuid,
-               reqChrUuid:   p.ReqChrUuid,
-               rspChrUuid:   p.RspChrUuid,
-               rxNmpCb:      p.RxNmpCb,
-               disconnectCb: p.DisconnectCb,
+               params: p,
 
                bls:    map[*BleListener]struct{}{},
                attMtu: DFLT_ATT_MTU,
@@ -143,7 +138,7 @@ func (bf *BleFsm) addBleListener(base BleMsgBase) 
(*BleListener, error) {
        bf.bls[bl] = struct{}{}
        bf.mtx.Unlock()
 
-       if err := bf.bx.Bd.AddListener(base, bl); err != nil {
+       if err := bf.params.Bx.Bd.AddListener(base, bl); err != nil {
                delete(bf.bls, bl)
                return nil, err
        }
@@ -167,7 +162,7 @@ func (bf *BleFsm) addBleSeqListener(seq int) (*BleListener, 
error) {
 }
 
 func (bf *BleFsm) removeBleListener(base BleMsgBase) {
-       bl := bf.bx.Bd.RemoveListener(base)
+       bl := bf.params.Bx.Bd.RemoveListener(base)
        if bl != nil {
                bf.mtx.Lock()
                delete(bf.bls, bl)
@@ -205,6 +200,22 @@ func (bf *BleFsm) action(
        return nil
 }
 
+func (bf *BleFsm) calcDisconnectType() BleFsmDisconnectType {
+       switch bf.getState() {
+       case SESN_STATE_EXCHANGING_MTU:
+               return FSM_DISCONNECT_TYPE_IMMEDIATE_TIMEOUT
+
+       case SESN_STATE_DISCOVERED_CHR:
+               return FSM_DISCONNECT_TYPE_OPENED
+
+       case SESN_STATE_TERMINATING, SESN_STATE_CONN_CANCELLING:
+               return FSM_DISCONNECT_TYPE_REQUESTED
+
+       default:
+               return FSM_DISCONNECT_TYPE_UNOPENED
+       }
+}
+
 func (bf *BleFsm) connectListen(seq int) error {
        bf.connChan = make(chan error, 1)
 
@@ -279,20 +290,24 @@ func (bf *BleFsm) connectListen(seq int) error {
                                        }
                                        bf.mtx.Unlock()
 
+                                       // Remember some fields before we clear 
them.
+                                       dt := bf.calcDisconnectType()
+                                       peer := *bf.peerDev
+
+                                       bf.setState(SESN_STATE_UNCONNECTED)
+                                       bf.peerDev = nil
+
                                        for _, bl := range bls {
                                                bl.ErrChan <- err
                                        }
 
-                                       bf.setState(SESN_STATE_UNCONNECTED)
-                                       peer := *bf.peerDev
-                                       bf.peerDev = nil
-                                       bf.disconnectCb(peer, err)
+                                       bf.params.DisconnectCb(dt, peer, err)
                                        return
 
                                default:
                                }
 
-                       case <-bl.AfterTimeout(bf.bx.rspTimeout):
+                       case <-bl.AfterTimeout(bf.params.Bx.rspTimeout):
                                bf.connChan <- BhdTimeoutError(MSG_TYPE_CONNECT)
                        }
                }
@@ -326,7 +341,7 @@ func (bf *BleFsm) nmpRspListen() error {
                                        if bf.nmpRspChr != nil &&
                                                msg.AttrHandle == 
bf.nmpRspChr.ValHandle {
 
-                                               bf.rxNmpCb(msg.Data.Bytes)
+                                               
bf.params.RxNmpCb(msg.Data.Bytes)
                                        }
 
                                default:
@@ -339,7 +354,7 @@ func (bf *BleFsm) nmpRspListen() error {
 
 func (bf *BleFsm) connect() error {
        r := NewBleConnectReq()
-       r.OwnAddrType = bf.ownAddrType
+       r.OwnAddrType = bf.params.OwnAddrType
        r.PeerAddrType = bf.peerDev.AddrType
        r.PeerAddr = bf.peerDev.Addr
 
@@ -347,7 +362,7 @@ func (bf *BleFsm) connect() error {
                return err
        }
 
-       if err := connect(bf.bx, bf.connChan, r); err != nil {
+       if err := connect(bf.params.Bx, bf.connChan, r); err != nil {
                return err
        }
 
@@ -356,7 +371,7 @@ func (bf *BleFsm) connect() error {
 
 func (bf *BleFsm) scan() error {
        r := NewBleScanReq()
-       r.OwnAddrType = bf.ownAddrType
+       r.OwnAddrType = bf.params.OwnAddrType
        r.DurationMs = 15000
        r.FilterPolicy = BLE_SCAN_FILT_NO_WL
        r.Limited = false
@@ -388,13 +403,13 @@ func (bf *BleFsm) scan() error {
                }
 
                // Ask client if we should connect to this advertiser.
-               if bf.peerSpec.ScanPred(r) {
+               if bf.params.PeerSpec.ScanPred(r) {
                        bf.peerDev = &r.Sender
                        abortChan <- struct{}{}
                }
        }
 
-       if err := scan(bf.bx, bl, r, abortChan, scanCb); err != nil {
+       if err := scan(bf.params.Bx, bl, r, abortChan, scanCb); err != nil {
                return err
        }
 
@@ -411,7 +426,7 @@ func (bf *BleFsm) scanCancel() error {
        }
        defer bf.removeBleSeqListener(r.Seq)
 
-       if err := scanCancel(bf.bx, bl, r); err != nil {
+       if err := scanCancel(bf.params.Bx, bl, r); err != nil {
                return err
        }
 
@@ -452,7 +467,7 @@ func (bf *BleFsm) terminate() error {
        }
        defer bf.removeBleSeqListener(r.Seq)
 
-       if err := terminate(bf.bx, bl, r); err != nil {
+       if err := terminate(bf.params.Bx, bl, r); err != nil {
                return err
        }
 
@@ -474,7 +489,7 @@ func (bf *BleFsm) connCancel() error {
        }
        defer bf.removeBleSeqListener(r.Seq)
 
-       if err := connCancel(bf.bx, bl, r); err != nil {
+       if err := connCancel(bf.params.Bx, bl, r); err != nil {
                return err
        }
 
@@ -484,7 +499,7 @@ func (bf *BleFsm) connCancel() error {
 func (bf *BleFsm) discSvcUuid() error {
        r := NewBleDiscSvcUuidReq()
        r.ConnHandle = bf.connHandle
-       r.Uuid = bf.svcUuid
+       r.Uuid = bf.params.SvcUuid
 
        bl, err := bf.addBleSeqListener(r.Seq)
        if err != nil {
@@ -492,7 +507,7 @@ func (bf *BleFsm) discSvcUuid() error {
        }
        defer bf.removeBleSeqListener(r.Seq)
 
-       bf.nmpSvc, err = discSvcUuid(bf.bx, bl, r)
+       bf.nmpSvc, err = discSvcUuid(bf.params.Bx, bl, r)
        if err != nil {
                return err
        }
@@ -512,16 +527,16 @@ func (bf *BleFsm) discAllChrs() error {
        }
        defer bf.removeBleSeqListener(r.Seq)
 
-       chrs, err := discAllChrs(bf.bx, bl, r)
+       chrs, err := discAllChrs(bf.params.Bx, bl, r)
        if err != nil {
                return err
        }
 
        for _, c := range chrs {
-               if CompareUuids(bf.reqChrUuid, c.Uuid) == 0 {
+               if CompareUuids(bf.params.ReqChrUuid, c.Uuid) == 0 {
                        bf.nmpReqChr = c
                }
-               if CompareUuids(bf.rspChrUuid, c.Uuid) == 0 {
+               if CompareUuids(bf.params.RspChrUuid, c.Uuid) == 0 {
                        bf.nmpRspChr = c
                }
        }
@@ -529,13 +544,13 @@ func (bf *BleFsm) discAllChrs() error {
        if bf.nmpReqChr == nil {
                return fmt.Errorf(
                        "Peer doesn't support required characteristic: %s",
-                       bf.reqChrUuid.String())
+                       bf.params.ReqChrUuid.String())
        }
 
        if bf.nmpRspChr == nil {
                return fmt.Errorf(
                        "Peer doesn't support required characteristic: %s",
-                       bf.rspChrUuid.String())
+                       bf.params.RspChrUuid.String())
        }
 
        return nil
@@ -551,7 +566,7 @@ func (bf *BleFsm) exchangeMtu() error {
        }
        defer bf.removeBleSeqListener(r.Seq)
 
-       mtu, err := exchangeMtu(bf.bx, bl, r)
+       mtu, err := exchangeMtu(bf.params.Bx, bl, r)
        if err != nil {
                return err
        }
@@ -572,7 +587,7 @@ func (bf *BleFsm) writeCmd(data []byte) error {
        }
        defer bf.removeBleSeqListener(r.Seq)
 
-       if err := writeCmd(bf.bx, bl, r); err != nil {
+       if err := writeCmd(bf.params.Bx, bl, r); err != nil {
                return err
        }
 
@@ -591,7 +606,7 @@ func (bf *BleFsm) subscribe() error {
        }
        defer bf.removeBleSeqListener(r.Seq)
 
-       if err := writeCmd(bf.bx, bl, r); err != nil {
+       if err := writeCmd(bf.params.Bx, bl, r); err != nil {
                return err
        }
 
@@ -607,17 +622,20 @@ func (bf *BleFsm) tryFillPeerDev() bool {
        // 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
+       if bf.params.PeerSpec.ScanPred == nil {
+               bf.peerDev = &bf.params.PeerSpec.Dev
                return true
        }
 
        return false
 }
 
-func (bf *BleFsm) Start() error {
+// @return bool                 Whether another start attempt should be made;
+//         error                The error that caused the start attempt to
+//                                  fail; nil on success.
+func (bf *BleFsm) Start() (bool, error) {
        if bf.getState() != SESN_STATE_UNCONNECTED {
-               return nmxutil.NewSesnAlreadyOpenError(
+               return false, nmxutil.NewSesnAlreadyOpenError(
                        "Attempt to open an already-open BLE session")
        }
 
@@ -653,7 +671,7 @@ func (bf *BleFsm) Start() error {
                        }
 
                        if err != nil {
-                               return err
+                               return false, err
                        }
 
                case SESN_STATE_CONNECTED:
@@ -664,7 +682,9 @@ func (bf *BleFsm) Start() error {
                                SESN_STATE_EXCHANGED_MTU,
                                cb)
                        if err != nil {
-                               return err
+                               bhe := nmxutil.ToBleHost(err)
+                               retry := bhe != nil && bhe.Status == 
ERR_CODE_ENOTCONN
+                               return retry, err
                        }
 
                case SESN_STATE_EXCHANGED_MTU:
@@ -675,7 +695,7 @@ func (bf *BleFsm) Start() error {
                                SESN_STATE_DISCOVERED_SVC,
                                cb)
                        if err != nil {
-                               return err
+                               return false, err
                        }
 
                case SESN_STATE_DISCOVERED_SVC:
@@ -689,22 +709,22 @@ func (bf *BleFsm) Start() error {
                                SESN_STATE_DISCOVERED_CHR,
                                cb)
                        if err != nil {
-                               return err
+                               return false, err
                        }
 
                        if err := bf.subscribe(); err != nil {
-                               return err
+                               return false, err
                        }
 
                case SESN_STATE_DISCOVERED_CHR:
                        /* Open complete. */
-                       return nil
+                       return false, nil
 
                case SESN_STATE_CONNECTING,
                        SESN_STATE_DISCOVERING_SVC,
                        SESN_STATE_DISCOVERING_CHR,
                        SESN_STATE_TERMINATING:
-                       return fmt.Errorf("BleFsm already being opened")
+                       return false, fmt.Errorf("BleFsm already being opened")
                }
        }
 }
@@ -740,6 +760,10 @@ func (bf *BleFsm) IsOpen() bool {
        return bf.getState() == SESN_STATE_DISCOVERED_CHR
 }
 
+func (bf *BleFsm) IsClosed() bool {
+       return bf.getState() == SESN_STATE_UNCONNECTED
+}
+
 func (bf *BleFsm) TxNmp(payload []byte, nl *nmp.NmpListener,
        timeout time.Duration) (nmp.NmpRsp, error) {
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/ff255cbf/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_oic_sesn.go
----------------------------------------------------------------------
diff --git 
a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_oic_sesn.go 
b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_oic_sesn.go
index 365efc6..4001960 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_oic_sesn.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_oic_sesn.go
@@ -5,17 +5,18 @@ import (
        "sync"
        "time"
 
+       "mynewt.apache.org/newt/util"
        . "mynewt.apache.org/newtmgr/nmxact/bledefs"
        "mynewt.apache.org/newtmgr/nmxact/nmp"
        "mynewt.apache.org/newtmgr/nmxact/omp"
        "mynewt.apache.org/newtmgr/nmxact/sesn"
-       "mynewt.apache.org/newt/util"
 )
 
 type BleOicSesn struct {
        bf           *BleFsm
        nls          map[*nmp.NmpListener]struct{}
        od           *omp.OmpDispatcher
+       connTries    int
        closeTimeout time.Duration
        onCloseCb    sesn.BleOnCloseFn
 
@@ -27,6 +28,7 @@ func NewBleOicSesn(bx *BleXport, cfg sesn.SesnCfg) 
*BleOicSesn {
        bos := &BleOicSesn{
                nls:          map[*nmp.NmpListener]struct{}{},
                od:           omp.NewOmpDispatcher(),
+               connTries:    cfg.Ble.ConnTries,
                closeTimeout: cfg.Ble.CloseTimeout,
                onCloseCb:    cfg.Ble.OnCloseCb,
        }
@@ -47,14 +49,16 @@ func NewBleOicSesn(bx *BleXport, cfg sesn.SesnCfg) 
*BleOicSesn {
        }
 
        bos.bf = NewBleFsm(BleFsmParams{
-               Bx:           bx,
-               OwnAddrType:  cfg.Ble.OwnAddrType,
-               PeerSpec:     cfg.Ble.PeerSpec,
-               SvcUuid:      svcUuid,
-               ReqChrUuid:   reqChrUuid,
-               RspChrUuid:   rspChrUuid,
-               RxNmpCb:      func(d []byte) { bos.onRxNmp(d) },
-               DisconnectCb: func(p BleDev, e error) { bos.onDisconnect(p, e) 
},
+               Bx:          bx,
+               OwnAddrType: cfg.Ble.OwnAddrType,
+               PeerSpec:    cfg.Ble.PeerSpec,
+               SvcUuid:     svcUuid,
+               ReqChrUuid:  reqChrUuid,
+               RspChrUuid:  rspChrUuid,
+               RxNmpCb:     func(d []byte) { bos.onRxNmp(d) },
+               DisconnectCb: func(dt BleFsmDisconnectType, p BleDev, e error) {
+                       bos.onDisconnect(dt, p, e)
+               },
        })
 
        return bos
@@ -80,16 +84,16 @@ func (bos *BleOicSesn) removeNmpListener(seq uint8) {
 }
 
 // Returns true if a new channel was assigned.
-func (bos *BleOicSesn) setCloseChan() bool {
+func (bos *BleOicSesn) setCloseChan() error {
        bos.mx.Lock()
        defer bos.mx.Unlock()
 
        if bos.closeChan != nil {
-               return false
+               return fmt.Errorf("Multiple listeners waiting for session to 
close")
        }
 
        bos.closeChan = make(chan error, 1)
-       return true
+       return nil
 }
 
 func (bos *BleOicSesn) clearCloseChan() {
@@ -99,18 +103,51 @@ func (bos *BleOicSesn) clearCloseChan() {
        bos.closeChan = nil
 }
 
+func (bos *BleOicSesn) listenForClose(timeout time.Duration) error {
+       select {
+       case <-bos.closeChan:
+               return nil
+       case <-time.After(timeout):
+               // Session never closed.
+               return fmt.Errorf("Timeout while waiting for session to close")
+       }
+}
+
+func (bos *BleOicSesn) blockUntilClosed(timeout time.Duration) error {
+       if err := bos.setCloseChan(); err != nil {
+               return err
+       }
+       defer bos.clearCloseChan()
+
+       // If the session is already closed, we're done.
+       if bos.bf.IsClosed() {
+               return nil
+       }
+
+       // Block until close completes or timeout.
+       return bos.listenForClose(timeout)
+}
+
 func (bos *BleOicSesn) AbortRx(seq uint8) error {
        return bos.od.FakeRxError(seq, fmt.Errorf("Rx aborted"))
 }
 
 func (bos *BleOicSesn) Open() error {
-       return bos.bf.Start()
+       var err error
+       for i := 0; i < bos.connTries; i++ {
+               var retry bool
+               retry, err = bos.bf.Start()
+               if !retry {
+                       break
+               }
+       }
+
+       return err
 }
 
 func (bos *BleOicSesn) Close() error {
-       if !bos.setCloseChan() {
-               return bos.bf.closedError(
-                       "Attempt to close an unopened BLE session")
+       if err := bos.setCloseChan(); err != nil {
+               return err
        }
        defer bos.clearCloseChan()
 
@@ -125,12 +162,7 @@ func (bos *BleOicSesn) Close() error {
        }
 
        // Block until close completes or timeout.
-       select {
-       case <-bos.closeChan:
-       case <-time.After(bos.closeTimeout):
-       }
-
-       return nil
+       return bos.listenForClose(bos.closeTimeout)
 }
 
 func (bos *BleOicSesn) IsOpen() bool {
@@ -141,7 +173,9 @@ func (bos *BleOicSesn) onRxNmp(data []byte) {
        bos.od.Dispatch(data)
 }
 
-func (bos *BleOicSesn) onDisconnect(peer BleDev, err error) {
+func (bos *BleOicSesn) onDisconnect(dt BleFsmDisconnectType, peer BleDev,
+       err error) {
+
        for nl, _ := range bos.nls {
                nl.ErrChan <- err
        }
@@ -150,7 +184,10 @@ func (bos *BleOicSesn) onDisconnect(peer BleDev, err 
error) {
        if bos.closeChan != nil {
                bos.closeChan <- err
        }
-       if bos.onCloseCb != nil {
+
+       // Only execute client's disconnect callback if the disconnect was
+       // unsolicited and the session was fully open.
+       if dt == FSM_DISCONNECT_TYPE_OPENED && bos.onCloseCb != nil {
                bos.onCloseCb(bos, peer, err)
        }
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/ff255cbf/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_plain_sesn.go
----------------------------------------------------------------------
diff --git 
a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_plain_sesn.go 
b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_plain_sesn.go
index a8a46d6..012a301 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_plain_sesn.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_plain_sesn.go
@@ -5,16 +5,17 @@ import (
        "sync"
        "time"
 
+       "mynewt.apache.org/newt/util"
        . "mynewt.apache.org/newtmgr/nmxact/bledefs"
        "mynewt.apache.org/newtmgr/nmxact/nmp"
        "mynewt.apache.org/newtmgr/nmxact/sesn"
-       "mynewt.apache.org/newt/util"
 )
 
 type BlePlainSesn struct {
        bf           *BleFsm
        nls          map[*nmp.NmpListener]struct{}
        nd           *nmp.NmpDispatcher
+       connTries    int
        closeTimeout time.Duration
        onCloseCb    sesn.BleOnCloseFn
 
@@ -26,6 +27,7 @@ func NewBlePlainSesn(bx *BleXport, cfg sesn.SesnCfg) 
*BlePlainSesn {
        bps := &BlePlainSesn{
                nls:          map[*nmp.NmpListener]struct{}{},
                nd:           nmp.NewNmpDispatcher(),
+               connTries:    cfg.Ble.ConnTries,
                closeTimeout: cfg.Ble.CloseTimeout,
                onCloseCb:    cfg.Ble.OnCloseCb,
        }
@@ -41,14 +43,16 @@ func NewBlePlainSesn(bx *BleXport, cfg sesn.SesnCfg) 
*BlePlainSesn {
        }
 
        bps.bf = NewBleFsm(BleFsmParams{
-               Bx:           bx,
-               OwnAddrType:  cfg.Ble.OwnAddrType,
-               PeerSpec:     cfg.Ble.PeerSpec,
-               SvcUuid:      svcUuid,
-               ReqChrUuid:   chrUuid,
-               RspChrUuid:   chrUuid,
-               RxNmpCb:      func(d []byte) { bps.onRxNmp(d) },
-               DisconnectCb: func(p BleDev, e error) { bps.onDisconnect(p, e) 
},
+               Bx:          bx,
+               OwnAddrType: cfg.Ble.OwnAddrType,
+               PeerSpec:    cfg.Ble.PeerSpec,
+               SvcUuid:     svcUuid,
+               ReqChrUuid:  chrUuid,
+               RspChrUuid:  chrUuid,
+               RxNmpCb:     func(d []byte) { bps.onRxNmp(d) },
+               DisconnectCb: func(dt BleFsmDisconnectType, p BleDev, e error) {
+                       bps.onDisconnect(dt, p, e)
+               },
        })
 
        return bps
@@ -73,17 +77,16 @@ func (bps *BlePlainSesn) removeNmpListener(seq uint8) {
        }
 }
 
-// Returns true if a new channel was assigned.
-func (bps *BlePlainSesn) setCloseChan() bool {
+func (bps *BlePlainSesn) setCloseChan() error {
        bps.mx.Lock()
        defer bps.mx.Unlock()
 
        if bps.closeChan != nil {
-               return false
+               return fmt.Errorf("Multiple listeners waiting for session to 
close")
        }
 
        bps.closeChan = make(chan error, 1)
-       return true
+       return nil
 }
 
 func (bps *BlePlainSesn) clearCloseChan() {
@@ -93,18 +96,57 @@ func (bps *BlePlainSesn) clearCloseChan() {
        bps.closeChan = nil
 }
 
+func (bps *BlePlainSesn) listenForClose(timeout time.Duration) error {
+       select {
+       case <-bps.closeChan:
+               return nil
+       case <-time.After(timeout):
+               // Session never closed.
+               return fmt.Errorf("Timeout while waiting for session to close")
+       }
+}
+
+func (bps *BlePlainSesn) blockUntilClosed(timeout time.Duration) error {
+       if err := bps.setCloseChan(); err != nil {
+               return err
+       }
+       defer bps.clearCloseChan()
+
+       // If the session is already closed, we're done.
+       if bps.bf.IsClosed() {
+               return nil
+       }
+
+       // Block until close completes or timeout.
+       return bps.listenForClose(timeout)
+}
+
 func (bps *BlePlainSesn) AbortRx(seq uint8) error {
        return bps.nd.FakeRxError(seq, fmt.Errorf("Rx aborted"))
 }
 
 func (bps *BlePlainSesn) Open() error {
-       return bps.bf.Start()
+       var err error
+       for i := 0; i < bps.connTries; i++ {
+               var retry bool
+               retry, err = bps.bf.Start()
+               if !retry {
+                       break
+               }
+
+               if bps.blockUntilClosed(1*time.Second) != nil {
+                       // Just close the session manually and report the 
original error.
+                       bps.Close()
+                       return err
+               }
+       }
+
+       return err
 }
 
 func (bps *BlePlainSesn) Close() error {
-       if !bps.setCloseChan() {
-               return bps.bf.closedError(
-                       "Attempt to close an unopened BLE session")
+       if err := bps.setCloseChan(); err != nil {
+               return err
        }
        defer bps.clearCloseChan()
 
@@ -119,12 +161,7 @@ func (bps *BlePlainSesn) Close() error {
        }
 
        // Block until close completes or timeout.
-       select {
-       case <-bps.closeChan:
-       case <-time.After(bps.closeTimeout):
-       }
-
-       return nil
+       return bps.listenForClose(bps.closeTimeout)
 }
 
 func (bps *BlePlainSesn) IsOpen() bool {
@@ -135,16 +172,21 @@ func (bps *BlePlainSesn) onRxNmp(data []byte) {
        bps.nd.Dispatch(data)
 }
 
-func (bps *BlePlainSesn) onDisconnect(peer BleDev, err error) {
+func (bps *BlePlainSesn) onDisconnect(dt BleFsmDisconnectType, peer BleDev,
+       err error) {
+
        for nl, _ := range bps.nls {
                nl.ErrChan <- err
        }
 
-       // If the session is being closed, unblock the close() call.
+       // If someone is waiting for the session to close, unblock them.
        if bps.closeChan != nil {
                bps.closeChan <- err
        }
-       if bps.onCloseCb != nil {
+
+       // Only execute client's disconnect callback if the disconnect was
+       // unsolicited and the session was fully open.
+       if dt == FSM_DISCONNECT_TYPE_OPENED && bps.onCloseCb != nil {
                bps.onCloseCb(bps, peer, err)
        }
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/ff255cbf/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/sesn/sesn_cfg.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/sesn/sesn_cfg.go 
b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/sesn/sesn_cfg.go
index e18711d..9c84db1 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/sesn/sesn_cfg.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/sesn/sesn_cfg.go
@@ -44,6 +44,7 @@ func BlePeerSpecName(name string) BlePeerSpec {
 type SesnCfgBle struct {
        OwnAddrType  bledefs.BleAddrType
        PeerSpec     BlePeerSpec
+       ConnTries    int
        CloseTimeout time.Duration
        OnCloseCb    BleOnCloseFn
 }
@@ -59,6 +60,7 @@ type SesnCfg struct {
 func NewSesnCfg() SesnCfg {
        return SesnCfg{
                Ble: SesnCfgBle{
+                       ConnTries:    3,
                        CloseTimeout: 5 * time.Second,
                },
        }

Reply via email to