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
+}