This is an automated email from the ASF dual-hosted git repository.

ccollins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-newtmgr.git

commit a8acde79a688239bfed847d1154fb9c6d7068d9e
Author: Christopher Collins <ccoll...@apache.org>
AuthorDate: Mon Aug 7 17:28:02 2017 -0700

    nmxact - Allow BLE security
---
 nmxact/bledefs/bledefs.go |  2 +-
 nmxact/nmble/ble_act.go   |  4 ++-
 nmxact/nmble/ble_sesn.go  | 17 +++++++----
 nmxact/nmble/ble_xport.go |  6 +---
 nmxact/nmble/conn.go      | 76 +++++++++++++++++++++++++++++++++++++++--------
 nmxact/nmxutil/block.go   | 21 ++++++++++---
 nmxact/nmxutil/nmxutil.go |  6 ++++
 nmxact/oic/resmgr.go      | 53 ++++++++++++++++++++++++++++-----
 nmxact/scan/scan.go       |  2 +-
 9 files changed, 149 insertions(+), 38 deletions(-)

diff --git a/nmxact/bledefs/bledefs.go b/nmxact/bledefs/bledefs.go
index 8a243ef..fe0322a 100644
--- a/nmxact/bledefs/bledefs.go
+++ b/nmxact/bledefs/bledefs.go
@@ -653,7 +653,7 @@ type BleEncryptWhen int
 
 const (
        BLE_ENCRYPT_NEVER BleEncryptWhen = iota
-       BLE_ENCRYPT_PRIV_ONLY
+       BLE_ENCRYPT_AS_REQD
        BLE_ENCRYPT_ALWAYS
 )
 
diff --git a/nmxact/nmble/ble_act.go b/nmxact/nmble/ble_act.go
index bd97133..679be3c 100644
--- a/nmxact/nmble/ble_act.go
+++ b/nmxact/nmble/ble_act.go
@@ -716,7 +716,7 @@ func reset(x *BleXport, bl *Listener,
 }
 
 // Blocking
-func encInitiate(x *BleXport, bl *Listener,
+func securityInitiate(x *BleXport, bl *Listener,
        r *BleSecurityInitiateReq) error {
 
        const rspType = MSG_TYPE_SECURITY_INITIATE
@@ -741,6 +741,8 @@ func encInitiate(x *BleXport, bl *Listener,
                                bl.Acked = true
                                if msg.Status != 0 {
                                        return StatusError(MSG_OP_RSP, rspType, 
msg.Status)
+                               } else {
+                                       return nil
                                }
 
                        default:
diff --git a/nmxact/nmble/ble_sesn.go b/nmxact/nmble/ble_sesn.go
index edbcbb6..00aef91 100644
--- a/nmxact/nmble/ble_sesn.go
+++ b/nmxact/nmble/ble_sesn.go
@@ -89,7 +89,7 @@ func (s *BleSesn) disconnectListen() {
        s.wg.Add(1)
        go func() {
                // If the session is being closed, unblock the close() call.
-               defer s.closeBlocker.Unblock()
+               defer s.closeBlocker.Unblock(nil)
 
                // Block until disconnect.
                err := <-s.conn.DisconnectChan()
@@ -151,9 +151,10 @@ func (s *BleSesn) notifyListen() {
                                return
 
                        case n, ok := <-nmpRspNl.NotifyChan:
-                               if ok {
-                                       s.txvr.DispatchNmpRsp(n.Data)
+                               if !ok {
+                                       return
                                }
+                               s.txvr.DispatchNmpRsp(n.Data)
 
                        case <-s.stopChan:
                                return
@@ -205,6 +206,12 @@ func (s *BleSesn) openOnce() (bool, error) {
                }
        }
 
+       if s.cfg.Ble.EncryptWhen == BLE_ENCRYPT_ALWAYS {
+               if err := s.conn.InitiateSecurity(); err != nil {
+                       return false, err
+               }
+       }
+
        // Listen for incoming notifications in the background.
        s.notifyListen()
 
@@ -234,7 +241,7 @@ func (s *BleSesn) OpenConnected(
 
        if err := s.conn.Inherit(connHandle, eventListener); err != nil {
                if !nmxutil.IsSesnAlreadyOpen(err) {
-                       s.closeBlocker.Unblock()
+                       s.closeBlocker.Unblock(nil)
                }
                return err
        }
@@ -257,7 +264,7 @@ func (s *BleSesn) Close() error {
        }
 
        // Block until close completes.
-       s.closeBlocker.Wait()
+       s.closeBlocker.Wait(nmxutil.DURATION_FOREVER)
        return nil
 }
 
diff --git a/nmxact/nmble/ble_xport.go b/nmxact/nmble/ble_xport.go
index da7cf30..79a1f2c 100644
--- a/nmxact/nmble/ble_xport.go
+++ b/nmxact/nmble/ble_xport.go
@@ -254,11 +254,7 @@ func (bx *BleXport) initialSyncCheck() (bool, *Listener, 
error) {
 }
 
 func (bx *BleXport) shutdown(restart bool, err error) {
-       if !nmxutil.IsXport(err) {
-               panic(fmt.Sprintf(
-                       "BleXport.shutdown() received error that isn't an 
XportError: %+v",
-                       err))
-       }
+       nmxutil.Assert(nmxutil.IsXport(err))
 
        log.Debugf("Shutting down BLE transport")
 
diff --git a/nmxact/nmble/conn.go b/nmxact/nmble/conn.go
index 28321ef..c2e8bcd 100644
--- a/nmxact/nmble/conn.go
+++ b/nmxact/nmble/conn.go
@@ -30,17 +30,18 @@ func NewNotifyListener() *NotifyListener {
 }
 
 type Conn struct {
-       bx      *BleXport
-       rxvr    *Receiver
-       attMtu  uint16
-       profile Profile
-       desc    BleConnDesc
+       bx         *BleXport
+       rxvr       *Receiver
+       attMtu     uint16
+       profile    Profile
+       desc       BleConnDesc
+       connHandle uint16
 
-       connHandle     uint16
        connecting     bool
        stopped        bool
        disconnectChan chan error
        wg             sync.WaitGroup
+       encBlocker     nmxutil.Blocker
 
        // Terminates all go routines.  Gets set to null after disconnect.
        stopChan chan struct{}
@@ -139,11 +140,18 @@ func (c *Conn) eventListen(bl *Listener) error {
                        case <-c.stopChan:
                                return
 
-                       case err := <-bl.ErrChan:
+                       case err, ok := <-bl.ErrChan:
+                               if !ok {
+                                       return
+                               }
+
                                go c.shutdown(err)
-                               return
 
-                       case bm := <-bl.MsgChan:
+                       case bm, ok := <-bl.MsgChan:
+                               if !ok {
+                                       return
+                               }
+
                                switch msg := bm.(type) {
                                case *BleMtuChangeEvt:
                                        if msg.Status != 0 {
@@ -167,8 +175,12 @@ func (c *Conn) eventListen(bl *Listener) error {
                                        } else {
                                                log.Debugf("Connection 
encrypted; conn_handle=%d",
                                                        msg.ConnHandle)
+                                               c.updateDescriptor()
                                        }
 
+                                       // Unblock any initiate-security 
procedures.
+                                       c.encBlocker.Unblock(err)
+
                                case *BleDisconnectEvt:
                                        go 
c.shutdown(c.newDisconnectError(msg.Reason))
                                        return
@@ -226,7 +238,11 @@ func (c *Conn) notifyListen() error {
                        case <-bl.ErrChan:
                                return
 
-                       case bm := <-bl.MsgChan:
+                       case bm, ok := <-bl.MsgChan:
+                               if !ok {
+                                       return
+                               }
+
                                switch msg := bm.(type) {
                                case *BleNotifyRxEvt:
                                        c.rxNotify(msg)
@@ -266,6 +282,16 @@ func (c *Conn) stopConnecting() {
        c.connecting = false
 }
 
+func (c *Conn) updateDescriptor() error {
+       d, err := ConnFindXact(c.bx, c.connHandle)
+       if err != nil {
+               return err
+       }
+
+       c.desc = d
+       return nil
+}
+
 func (c *Conn) finalizeConnection(connHandle uint16,
        eventListener *Listener) error {
 
@@ -284,11 +310,9 @@ func (c *Conn) finalizeConnection(connHandle uint16,
                return err
        }
 
-       d, err := ConnFindXact(c.bx, c.connHandle)
-       if err != nil {
+       if err := c.updateDescriptor(); err != nil {
                return err
        }
-       c.desc = d
 
        return nil
 }
@@ -652,6 +676,32 @@ func (c *Conn) ListenForNotifications(chr *Characteristic) 
*NotifyListener {
        return nl
 }
 
+func (c *Conn) InitiateSecurity() error {
+       r := NewBleSecurityInitiateReq()
+       r.ConnHandle = c.connHandle
+
+       bl, err := c.rxvr.AddListener("security-initiate", SeqKey(r.Seq))
+       if err != nil {
+               return err
+       }
+       defer c.rxvr.RemoveListener("security-initiate", bl)
+
+       c.encBlocker.Block()
+       if err := securityInitiate(c.bx, bl, r); err != nil {
+               return err
+       }
+
+       encErr, tmoErr := c.encBlocker.Wait(time.Second * 15)
+       if encErr != nil {
+               return encErr.(error)
+       }
+       if tmoErr != nil {
+               return fmt.Errorf("Timeout waiting for security to be 
established")
+       }
+
+       return nil
+}
+
 func (c *Conn) terminate() error {
        r := NewBleTerminateReq()
        r.ConnHandle = c.connHandle
diff --git a/nmxact/nmxutil/block.go b/nmxact/nmxutil/block.go
index f1f7c17..45b2e99 100644
--- a/nmxact/nmxutil/block.go
+++ b/nmxact/nmxutil/block.go
@@ -20,7 +20,9 @@
 package nmxutil
 
 import (
+       "fmt"
        "sync"
+       "time"
 )
 
 // Blocks a variable number of waiters until Unblock() is called.  Subsequent
@@ -28,15 +30,25 @@ import (
 type Blocker struct {
        ch  chan struct{}
        mtx sync.Mutex
+       val interface{}
 }
 
-func (b *Blocker) Wait() {
+func (b *Blocker) Wait(timeout time.Duration) (interface{}, error) {
        b.mtx.Lock()
        ch := b.ch
        b.mtx.Unlock()
 
-       if ch != nil {
-               <-ch
+       if ch == nil {
+               return b.val, nil
+       }
+
+       timer := time.NewTimer(timeout)
+       select {
+       case <-ch:
+               StopAndDrainTimer(timer)
+               return b.val, nil
+       case <-timer.C:
+               return nil, fmt.Errorf("timeout after %s", timeout.String())
        }
 }
 
@@ -49,11 +61,12 @@ func (b *Blocker) Block() {
        }
 }
 
-func (b *Blocker) Unblock() {
+func (b *Blocker) Unblock(val interface{}) {
        b.mtx.Lock()
        defer b.mtx.Unlock()
 
        if b.ch != nil {
+               b.val = val
                close(b.ch)
                b.ch = nil
        }
diff --git a/nmxact/nmxutil/nmxutil.go b/nmxact/nmxutil/nmxutil.go
index ff1e5f8..f49e3f8 100644
--- a/nmxact/nmxutil/nmxutil.go
+++ b/nmxact/nmxutil/nmxutil.go
@@ -126,6 +126,12 @@ func EncodeCborMap(value map[string]interface{}) ([]byte, 
error) {
        return b, nil
 }
 
+func StopAndDrainTimer(timer *time.Timer) {
+       if !timer.Stop() {
+               <-timer.C
+       }
+}
+
 var nextId uint32
 
 func GetNextId() uint32 {
diff --git a/nmxact/oic/resmgr.go b/nmxact/oic/resmgr.go
index f715f13..53e84a9 100644
--- a/nmxact/oic/resmgr.go
+++ b/nmxact/oic/resmgr.go
@@ -68,34 +68,71 @@ func (rm *ResMgr) Access(m coap.Message) (coap.COAPCode, 
[]byte) {
        }
 }
 
-type FixedResourceWriteFn func(uri string,
+type CborResourceGetFn func(uri string) (coap.COAPCode, map[string]interface{})
+
+type CborResourcePutFn func(uri string,
        val map[string]interface{}) coap.COAPCode
 
-func NewFixedResource(uri string, val map[string]interface{},
-       writeCb FixedResourceWriteFn) Resource {
+func NewCborResource(uri string,
+       getCb CborResourceGetFn, putCb CborResourcePutFn) Resource {
 
        return Resource{
                Uri: uri,
 
                GetCb: func(uri string) (coap.COAPCode, []byte) {
-                       b, err := nmxutil.EncodeCborMap(val)
+                       if getCb == nil {
+                               return coap.MethodNotAllowed, nil
+                       }
+
+                       code, m := getCb(uri)
+                       if code >= coap.BadRequest {
+                               return code, nil
+                       }
+                       b, err := nmxutil.EncodeCborMap(m)
                        if err != nil {
                                return coap.InternalServerError, nil
                        }
-                       return coap.Content, b
+                       return code, b
                },
 
                PutCb: func(uri string, data []byte) coap.COAPCode {
+                       if putCb == nil {
+                               return coap.MethodNotAllowed
+                       }
+
                        m, err := nmxutil.DecodeCborMap(data)
                        if err != nil {
                                return coap.BadRequest
                        }
 
-                       code := writeCb(uri, m)
+                       return putCb(uri, m)
+               },
+       }
+}
+
+func NewFixedResource(uri string, val map[string]interface{},
+       putCb CborResourcePutFn) Resource {
+
+       return NewCborResource(
+               // URI.
+               uri,
+
+               // Get.
+               func(uri string) (coap.COAPCode, map[string]interface{}) {
+                       return coap.Content, val
+               },
+
+               // Put.
+               func(uri string, newVal map[string]interface{}) coap.COAPCode {
+                       if putCb == nil {
+                               return coap.MethodNotAllowed
+                       }
+
+                       code := putCb(uri, newVal)
                        if code == coap.Created || code == coap.Changed {
-                               val = m
+                               val = newVal
                        }
                        return code
                },
-       }
+       )
 }
diff --git a/nmxact/scan/scan.go b/nmxact/scan/scan.go
index db1ade2..3a00595 100644
--- a/nmxact/scan/scan.go
+++ b/nmxact/scan/scan.go
@@ -61,7 +61,7 @@ type Scanner interface {
 func BleOmpScanCfg(ScanCb ScanFn) Cfg {
        sc := sesn.NewSesnCfg()
        sc.MgmtProto = sesn.MGMT_PROTO_OMP
-       sc.Ble.EncryptWhen = bledefs.BLE_ENCRYPT_PRIV_ONLY
+       sc.Ble.EncryptWhen = bledefs.BLE_ENCRYPT_AS_REQD
        sc.Ble.OwnAddrType = bledefs.BLE_ADDR_TYPE_RANDOM
 
        cfg := Cfg{

-- 
To stop receiving notification emails like this one, please contact
"commits@mynewt.apache.org" <commits@mynewt.apache.org>.

Reply via email to