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/04/07 23:02:39 UTC
[1/2] incubator-mynewt-newtmgr git commit: nmxact - ble_dual example.
Repository: incubator-mynewt-newtmgr
Updated Branches:
refs/heads/master a5c9d0b3f -> 14d4b457c
nmxact - ble_dual example.
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/aa00340e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/tree/aa00340e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/diff/aa00340e
Branch: refs/heads/master
Commit: aa00340e0736e63d0ed8b0b9ed5e1d07e163f54c
Parents: a5c9d0b
Author: Christopher Collins <cc...@apache.org>
Authored: Fri Apr 7 16:01:44 2017 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Fri Apr 7 16:01:44 2017 -0700
----------------------------------------------------------------------
nmxact/example/ble_dual/ble_dual.go | 171 +++++++++++++++++++++++++++++++
1 file changed, 171 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/aa00340e/nmxact/example/ble_dual/ble_dual.go
----------------------------------------------------------------------
diff --git a/nmxact/example/ble_dual/ble_dual.go b/nmxact/example/ble_dual/ble_dual.go
new file mode 100644
index 0000000..a0167c3
--- /dev/null
+++ b/nmxact/example/ble_dual/ble_dual.go
@@ -0,0 +1,171 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package main
+
+import (
+ "fmt"
+ "math/rand"
+ "os"
+ "os/signal"
+ "sync"
+ "syscall"
+ "time"
+
+ "mynewt.apache.org/newt/util"
+ "mynewt.apache.org/newtmgr/nmxact/bledefs"
+ "mynewt.apache.org/newtmgr/nmxact/nmble"
+ "mynewt.apache.org/newtmgr/nmxact/sesn"
+ "mynewt.apache.org/newtmgr/nmxact/xact"
+ "mynewt.apache.org/newtmgr/nmxact/xport"
+)
+
+func configExitHandler(x xport.Xport, s sesn.Sesn) {
+ onExit := func() {
+ if s.IsOpen() {
+ s.Close()
+ }
+
+ x.Stop()
+ }
+
+ sigChan := make(chan os.Signal, 1)
+ signal.Notify(sigChan)
+
+ go func() {
+ for {
+ s := <-sigChan
+ switch s {
+ case os.Interrupt, syscall.SIGTERM:
+ onExit()
+ os.Exit(0)
+ case syscall.SIGQUIT:
+ util.PrintStacks()
+ }
+ }
+ }()
+}
+
+func sendOne(s sesn.Sesn) {
+ // Repeatedly:
+ // * Connect to peer if unconnected.
+ // * Send an echo command to peer.
+ //
+ // If blehostd crashes or the controller is unplugged, nmxact should
+ // recover on the next connect attempt.
+ if !s.IsOpen() {
+ // Connect to the peer (open the session).
+ if err := s.Open(); err != nil {
+ fmt.Fprintf(os.Stderr, "error starting BLE session: %s\n",
+ err.Error())
+ return
+ }
+ }
+
+ // Send an echo command to the peer.
+ c := xact.NewEchoCmd()
+ c.Payload = fmt.Sprintf("hello %p", s)
+
+ res, err := c.Run(s)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "error executing echo command: %s\n",
+ err.Error())
+ return
+ }
+
+ if res.Status() != 0 {
+ fmt.Printf("Peer responded negatively to echo command; status=%d\n",
+ res.Status())
+ }
+
+ eres := res.(*xact.EchoResult)
+ fmt.Printf("Peer echoed back: %s\n", eres.Rsp.Payload)
+}
+
+func main() {
+ // Initialize the BLE transport.
+ params := nmble.NewXportCfg()
+ params.SockPath = "/tmp/blehostd-uds"
+ params.BlehostdPath = "blehostd.elf"
+ params.DevPath = "/dev/cu.usbmodem142111"
+
+ x, err := nmble.NewBleXport(params)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "error creating BLE transport: %s1\n",
+ err.Error())
+ os.Exit(1)
+ }
+
+ // Start the BLE transport.
+ if err := x.Start(); err != nil {
+ fmt.Fprintf(os.Stderr, "error starting BLE transport: %s1\n",
+ err.Error())
+ os.Exit(1)
+ }
+ defer x.Stop()
+
+ // Prepare a BLE session:
+ // * Plain NMP (not tunnelled over OIC).
+ // * We use a random address.
+ // * Peer has name "nimble-bleprph".
+ sc1 := sesn.NewSesnCfg()
+ sc1.MgmtProto = sesn.MGMT_PROTO_NMP
+ sc1.Ble.OwnAddrType = bledefs.BLE_ADDR_TYPE_RANDOM
+ sc1.Ble.PeerSpec = sesn.BlePeerSpecName("ccollins")
+
+ s1, err := x.BuildSesn(sc1)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "error creating BLE session: %s1\n", err.Error())
+ os.Exit(1)
+ }
+
+ sc2 := sesn.NewSesnCfg()
+ sc2.MgmtProto = sesn.MGMT_PROTO_NMP
+ sc2.Ble.OwnAddrType = bledefs.BLE_ADDR_TYPE_RANDOM
+ sc2.Ble.PeerSpec = sesn.BlePeerSpecName("ccollins2")
+
+ s2, err := x.BuildSesn(sc2)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "error creating BLE session: %s2\n", err.Error())
+ os.Exit(1)
+ }
+
+ configExitHandler(x, s1)
+
+ var wg sync.WaitGroup
+ wg.Add(1)
+ go func() {
+ for {
+ sendOne(s1)
+ time.Sleep(time.Duration(rand.Uint32()%100) * time.Millisecond)
+ }
+ }()
+ wg.Add(1)
+
+ //time.Sleep(2 * time.Second)
+
+ go func() {
+ for {
+ sendOne(s2)
+ time.Sleep(time.Duration(rand.Uint32()%100) * time.Millisecond)
+ }
+ }()
+
+ wg.Wait()
+}
[2/2] incubator-mynewt-newtmgr git commit: nxmact - Protect access to
master op state
Posted by cc...@apache.org.
nxmact - Protect access to master op state
I.e., prevent two sessions from connecting at the same time.
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/14d4b457
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/tree/14d4b457
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/diff/14d4b457
Branch: refs/heads/master
Commit: 14d4b457c0384fe7cdd6050b8fe551d55c465b85
Parents: aa00340
Author: Christopher Collins <cc...@apache.org>
Authored: Fri Apr 7 16:02:10 2017 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Fri Apr 7 16:02:10 2017 -0700
----------------------------------------------------------------------
nmxact/nmble/ble_fsm.go | 62 ++++++++++++++++++++++++++++++++----------
nmxact/nmble/ble_xport.go | 47 ++++++++++++++++++++++++++++++++
2 files changed, 94 insertions(+), 15 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/14d4b457/nmxact/nmble/ble_fsm.go
----------------------------------------------------------------------
diff --git a/nmxact/nmble/ble_fsm.go b/nmxact/nmble/ble_fsm.go
index 7bf429e..8dacc4e 100644
--- a/nmxact/nmble/ble_fsm.go
+++ b/nmxact/nmble/ble_fsm.go
@@ -105,16 +105,30 @@ func (bf *BleFsm) getState() BleSesnState {
return bf.state
}
-func (bf *BleFsm) setStateNoLock(toState BleSesnState) {
+func stateRequiresMaster(s BleSesnState) bool {
+ return s == SESN_STATE_SCANNING || s == SESN_STATE_CONNECTING
+}
+
+func (bf *BleFsm) setStateNoLock(toState BleSesnState) error {
+ if !stateRequiresMaster(bf.state) && stateRequiresMaster(toState) {
+ if err := bf.params.Bx.AcquireMaster(); err != nil {
+ return err
+ }
+ } else if stateRequiresMaster(bf.state) && !stateRequiresMaster(toState) {
+ bf.params.Bx.ReleaseMaster()
+ }
+
bf.state = toState
bf.lastStateChange = time.Now()
+
+ return nil
}
-func (bf *BleFsm) setState(toState BleSesnState) {
+func (bf *BleFsm) setState(toState BleSesnState) error {
bf.mtx.Lock()
defer bf.mtx.Unlock()
- bf.setStateNoLock(toState)
+ return bf.setStateNoLock(toState)
}
func (bf *BleFsm) transitionState(fromState BleSesnState,
@@ -130,10 +144,20 @@ func (bf *BleFsm) transitionState(fromState BleSesnState,
toState, fromState)
}
- bf.setStateNoLock(toState)
+ if err := bf.setStateNoLock(toState); err != nil {
+ return err
+ }
+
return nil
}
+func (bf *BleFsm) resetState() {
+ if err := bf.setState(SESN_STATE_UNCONNECTED); err != nil {
+ log.Debugf("BleFsm state change resulted in unexpected error: %s",
+ err)
+ }
+}
+
func (bf *BleFsm) addBleListener(base BleMsgBase) (*BleListener, error) {
bl := NewBleListener()
@@ -195,11 +219,15 @@ func (bf *BleFsm) action(
}
if err := cb(); err != nil {
- bf.setState(preState)
+ if err := bf.setState(preState); err != nil {
+ return err
+ }
return err
}
- bf.setState(postState)
+ if err := bf.setState(postState); err != nil {
+ return err
+ }
return nil
}
@@ -229,15 +257,16 @@ func calcDisconnectType(state BleSesnState) BleFsmDisconnectType {
}
func (bf *BleFsm) onDisconnect(err error) {
- log.Debugf(err.Error())
-
bf.mtx.Lock()
// Remember some fields before we clear them.
dt := calcDisconnectType(bf.state)
peer := *bf.peerDev
- bf.setStateNoLock(SESN_STATE_UNCONNECTED)
+ if err := bf.setStateNoLock(SESN_STATE_UNCONNECTED); err != nil {
+ log.Debugf("BleFsm state change resulted in unexpected error: %s",
+ err)
+ }
bf.peerDev = nil
// Make a copy of all the listeners so we don't have to keep the mutex
@@ -453,7 +482,10 @@ func (bf *BleFsm) terminateSetState() error {
return fmt.Errorf(
"BLE terminate failed; session already being closed")
default:
- bf.setStateNoLock(SESN_STATE_TERMINATING)
+ if err := bf.setStateNoLock(SESN_STATE_TERMINATING); err != nil {
+ log.Debugf("BleFsm state change resulted in unexpected error: %s",
+ err)
+ }
}
return nil
@@ -678,7 +710,7 @@ func (bf *BleFsm) Start() (bool, error) {
}
if err != nil {
- bf.setState(SESN_STATE_UNCONNECTED)
+ bf.resetState()
return false, err
}
@@ -692,7 +724,7 @@ func (bf *BleFsm) Start() (bool, error) {
if err != nil {
bhe := nmxutil.ToBleHost(err)
retry := bhe != nil && bhe.Status == ERR_CODE_ENOTCONN
- bf.setState(SESN_STATE_UNCONNECTED)
+ bf.resetState()
return retry, err
}
@@ -704,7 +736,7 @@ func (bf *BleFsm) Start() (bool, error) {
SESN_STATE_DISCOVERED_SVC,
cb)
if err != nil {
- bf.setState(SESN_STATE_UNCONNECTED)
+ bf.resetState()
return false, err
}
@@ -719,12 +751,12 @@ func (bf *BleFsm) Start() (bool, error) {
SESN_STATE_DISCOVERED_CHR,
cb)
if err != nil {
- bf.setState(SESN_STATE_UNCONNECTED)
+ bf.resetState()
return false, err
}
if err := bf.subscribe(); err != nil {
- bf.setState(SESN_STATE_UNCONNECTED)
+ bf.resetState()
return false, err
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/14d4b457/nmxact/nmble/ble_xport.go
----------------------------------------------------------------------
diff --git a/nmxact/nmble/ble_xport.go b/nmxact/nmble/ble_xport.go
index 93fece1..f5a9272 100644
--- a/nmxact/nmble/ble_xport.go
+++ b/nmxact/nmble/ble_xport.go
@@ -91,6 +91,8 @@ type BleXport struct {
shutdownChan chan bool
readyChan chan error
numReadyListeners int
+ masterQueue [](chan error)
+ masterActive bool
randAddr *BleAddr
mtx sync.Mutex
@@ -102,6 +104,7 @@ func NewBleXport(cfg XportCfg) (*BleXport, error) {
Bd: NewBleDispatcher(),
shutdownChan: make(chan bool),
readyChan: make(chan error),
+ masterQueue: [](chan error){},
cfg: cfg,
}
@@ -247,6 +250,11 @@ func (bx *BleXport) shutdown(restart bool, err error) {
// them from blocking endlessly while awaiting a BLE message.
bx.Bd.ErrorAll(err)
+ for _, listener := range bx.masterQueue {
+ listener <- err
+ }
+ bx.masterQueue = [](chan error){}
+
// Stop all of this transport's go routines.
for i := 0; i < bx.numStopListeners; i++ {
bx.stopChan <- struct{}{}
@@ -514,3 +522,42 @@ func (bx *BleXport) Tx(data []byte) error {
func (bx *BleXport) RspTimeout() time.Duration {
return bx.cfg.BlehostdRspTimeout
}
+
+func (bx *BleXport) AcquireMaster() error {
+ bx.mtx.Lock()
+
+ if !bx.masterActive {
+ bx.masterActive = true
+ bx.mtx.Unlock()
+ return nil
+ }
+
+ listener := make(chan error)
+ bx.masterQueue = append(bx.masterQueue, listener)
+
+ bx.mtx.Unlock()
+
+ return <-listener
+}
+
+func (bx *BleXport) ReleaseMaster() {
+ bx.mtx.Lock()
+
+ if !bx.masterActive {
+ bx.mtx.Unlock()
+ return
+ }
+
+ if len(bx.masterQueue) == 0 {
+ bx.masterActive = false
+ bx.mtx.Unlock()
+ return
+ }
+
+ listener := bx.masterQueue[0]
+ bx.masterQueue = bx.masterQueue[1:]
+
+ bx.mtx.Unlock()
+
+ listener <- nil
+}