Merge pull request #172 from rmal30/hotfix/remove-loadint64

Change MaxRxOff to be a 32-bit integer
diff --git a/newtmgr/bll/bll_sesn.go b/newtmgr/bll/bll_sesn.go
index 234a8a0..d062140 100644
--- a/newtmgr/bll/bll_sesn.go
+++ b/newtmgr/bll/bll_sesn.go
@@ -276,7 +276,7 @@
 			"Attempt to open an already-open bll session")
 	}
 
-	txvr, err := mgmt.NewTransceiver(s.cfg.TxFilterCb, s.cfg.RxFilterCb, true,
+	txvr, err := mgmt.NewTransceiver(s.cfg.TxFilter, s.cfg.RxFilter, true,
 		s.cfg.MgmtProto, 3)
 	if err != nil {
 		return false, err
@@ -437,12 +437,12 @@
 	return true
 }
 
-func (s *BllSesn) Filters() (nmcoap.MsgFilter, nmcoap.MsgFilter) {
+func (s *BllSesn) Filters() (nmcoap.TxMsgFilter, nmcoap.RxMsgFilter) {
 	return s.txvr.Filters()
 }
 
-func (s *BllSesn) SetFilters(txFilter nmcoap.MsgFilter,
-	rxFilter nmcoap.MsgFilter) {
+func (s *BllSesn) SetFilters(txFilter nmcoap.TxMsgFilter,
+	rxFilter nmcoap.RxMsgFilter) {
 
 	s.txvr.SetFilters(txFilter, rxFilter)
 }
diff --git a/newtmgr/bll/bll_sesn_cfg.go b/newtmgr/bll/bll_sesn_cfg.go
index b56ce48..daa584f 100644
--- a/newtmgr/bll/bll_sesn_cfg.go
+++ b/newtmgr/bll/bll_sesn_cfg.go
@@ -37,8 +37,8 @@
 	ConnTimeout  time.Duration
 	ConnTries    int
 	WriteRsp     bool
-	TxFilterCb   nmcoap.MsgFilter
-	RxFilterCb   nmcoap.MsgFilter
+	TxFilter     nmcoap.TxMsgFilter
+	RxFilter     nmcoap.RxMsgFilter
 }
 
 func NewBllSesnCfg() BllSesnCfg {
diff --git a/newtmgr/cli/common.go b/newtmgr/cli/common.go
index 78033d0..e6d32a9 100644
--- a/newtmgr/cli/common.go
+++ b/newtmgr/cli/common.go
@@ -44,8 +44,8 @@
 // This keeps track of whether the global interface has been assigned.  This
 // is necessary to accommodate golang's nil-interface semantics.
 var globalXportSet bool
-var globalTxFilter nmcoap.MsgFilter
-var globalRxFilter nmcoap.MsgFilter
+var globalTxFilter nmcoap.TxMsgFilter
+var globalRxFilter nmcoap.RxMsgFilter
 
 func initConnProfile() error {
 	var p *config.ConnProfile
@@ -286,8 +286,8 @@
 		return nil, util.NewNewtError("ERROR")
 	}
 
-	sc.TxFilterCb = globalTxFilter
-	sc.RxFilterCb = globalRxFilter
+	sc.TxFilter = globalTxFilter
+	sc.RxFilter = globalRxFilter
 
 	s, err := bx.BuildBllSesn(sc)
 	if err != nil {
@@ -320,8 +320,8 @@
 		if err != nil {
 			return nil, err
 		}
-		sc.TxFilterCb = globalTxFilter
-		sc.RxFilterCb = globalRxFilter
+		sc.TxFilter = globalTxFilter
+		sc.RxFilter = globalRxFilter
 
 		x, err := GetXport()
 		if err != nil {
@@ -350,7 +350,7 @@
 	return globalSesn, nil
 }
 
-func SetFilters(txFilter nmcoap.MsgFilter, rxFilter nmcoap.MsgFilter) {
+func SetFilters(txFilter nmcoap.TxMsgFilter, rxFilter nmcoap.RxMsgFilter) {
 	globalTxFilter = txFilter
 	globalRxFilter = rxFilter
 }
diff --git a/nmxact/mgmt/transceiver.go b/nmxact/mgmt/transceiver.go
index 8bf41e6..6f432cc 100644
--- a/nmxact/mgmt/transceiver.go
+++ b/nmxact/mgmt/transceiver.go
@@ -45,27 +45,27 @@
 	// Used for OMP and CoAP resource requests.
 	od *omp.Dispatcher
 
-	txFilterCb nmcoap.MsgFilter
+	txFilter nmcoap.TxMsgFilter
 
 	isTcp bool
 	proto sesn.MgmtProto
 	wg    sync.WaitGroup
 }
 
-func NewTransceiver(txFilterCb, rxFilterCb nmcoap.MsgFilter, isTcp bool,
+func NewTransceiver(txFilter nmcoap.TxMsgFilter, rxFilter nmcoap.RxMsgFilter, isTcp bool,
 	mgmtProto sesn.MgmtProto, logDepth int) (*Transceiver, error) {
 
 	t := &Transceiver{
-		txFilterCb: txFilterCb,
-		isTcp:      isTcp,
-		proto:      mgmtProto,
+		txFilter: txFilter,
+		isTcp:    isTcp,
+		proto:    mgmtProto,
 	}
 
 	if mgmtProto == sesn.MGMT_PROTO_NMP {
 		t.nd = nmp.NewDispatcher(logDepth)
 	}
 
-	od, err := omp.NewDispatcher(rxFilterCb, isTcp, logDepth)
+	od, err := omp.NewDispatcher(rxFilter, isTcp, logDepth)
 	if err != nil {
 		return nil, err
 	}
@@ -173,9 +173,9 @@
 
 	var b []byte
 	if t.isTcp {
-		b, err = omp.EncodeOmpTcp(t.txFilterCb, req)
+		b, err = omp.EncodeOmpTcp(t.txFilter, req)
 	} else {
-		b, err = omp.EncodeOmpDgram(t.txFilterCb, req)
+		b, err = omp.EncodeOmpDgram(t.txFilter, req)
 	}
 	if err != nil {
 		return nil, err
@@ -219,9 +219,9 @@
 
 	var b []byte
 	if t.isTcp {
-		b, err = omp.EncodeOmpTcp(t.txFilterCb, req)
+		b, err = omp.EncodeOmpTcp(t.txFilter, req)
 	} else {
-		b, err = omp.EncodeOmpDgram(t.txFilterCb, req)
+		b, err = omp.EncodeOmpDgram(t.txFilter, req)
 	}
 	if err != nil {
 		return err
@@ -364,13 +364,13 @@
 	return t.proto
 }
 
-func (t *Transceiver) Filters() (nmcoap.MsgFilter, nmcoap.MsgFilter) {
-	return t.txFilterCb, t.od.RxFilter()
+func (t *Transceiver) Filters() (nmcoap.TxMsgFilter, nmcoap.RxMsgFilter) {
+	return t.txFilter, t.od.RxFilter()
 }
 
-func (t *Transceiver) SetFilters(txFilter nmcoap.MsgFilter,
-	rxFilter nmcoap.MsgFilter) {
+func (t *Transceiver) SetFilters(txFilter nmcoap.TxMsgFilter,
+	rxFilter nmcoap.RxMsgFilter) {
 
-	t.txFilterCb = txFilter
+	t.txFilter = txFilter
 	t.od.SetRxFilter(rxFilter)
 }
diff --git a/nmxact/mtech_lora/mtech_lora_sesn.go b/nmxact/mtech_lora/mtech_lora_sesn.go
index 62203fb..200207f 100644
--- a/nmxact/mtech_lora/mtech_lora_sesn.go
+++ b/nmxact/mtech_lora/mtech_lora_sesn.go
@@ -88,7 +88,7 @@
 			"Attempt to open an already-open Lora session")
 	}
 
-	txvr, err := mgmt.NewTransceiver(s.cfg.TxFilterCb, s.cfg.RxFilterCb, false,
+	txvr, err := mgmt.NewTransceiver(s.cfg.TxFilter, s.cfg.RxFilter, false,
 		s.cfg.MgmtProto, 3)
 	if err != nil {
 		return err
@@ -381,8 +381,8 @@
 			}
 			cl_s.cfg.Lora.ConfirmedTx = s.cfg.Lora.ConfirmedTx
 			cl_s.cfg.Lora.SegSz = s.cfg.Lora.SegSz
-			cl_s.cfg.TxFilterCb = s.cfg.TxFilterCb
-			cl_s.cfg.RxFilterCb = s.cfg.RxFilterCb
+			cl_s.cfg.TxFilter = s.cfg.TxFilter
+			cl_s.cfg.RxFilter = s.cfg.RxFilter
 			return cl_s, &cl_s.cfg, nil
 		case <-s.stopChan:
 			return nil, nil, fmt.Errorf("Session closed")
@@ -437,12 +437,12 @@
 	}
 }
 
-func (s *LoraSesn) Filters() (nmcoap.MsgFilter, nmcoap.MsgFilter) {
+func (s *LoraSesn) Filters() (nmcoap.TxMsgFilter, nmcoap.RxMsgFilter) {
 	return s.txvr.Filters()
 }
 
-func (s *LoraSesn) SetFilters(txFilter nmcoap.MsgFilter,
-	rxFilter nmcoap.MsgFilter) {
+func (s *LoraSesn) SetFilters(txFilter nmcoap.TxMsgFilter,
+	rxFilter nmcoap.RxMsgFilter) {
 
 	s.txvr.SetFilters(txFilter, rxFilter)
 }
diff --git a/nmxact/nmble/ble_sesn.go b/nmxact/nmble/ble_sesn.go
index 62d3f88..a9212ce 100644
--- a/nmxact/nmble/ble_sesn.go
+++ b/nmxact/nmble/ble_sesn.go
@@ -136,12 +136,12 @@
 	return s.Ns.RxCoap(opt)
 }
 
-func (s *BleSesn) Filters() (nmcoap.MsgFilter, nmcoap.MsgFilter) {
+func (s *BleSesn) Filters() (nmcoap.TxMsgFilter, nmcoap.RxMsgFilter) {
 	return s.Ns.Filters()
 }
 
-func (s *BleSesn) SetFilters(txFilter nmcoap.MsgFilter,
-	rxFilter nmcoap.MsgFilter) {
+func (s *BleSesn) SetFilters(txFilter nmcoap.TxMsgFilter,
+	rxFilter nmcoap.RxMsgFilter) {
 
 	s.Ns.SetFilters(txFilter, rxFilter)
 }
diff --git a/nmxact/nmble/naked_sesn.go b/nmxact/nmble/naked_sesn.go
index 83c33cc..ad6d4ba 100644
--- a/nmxact/nmble/naked_sesn.go
+++ b/nmxact/nmble/naked_sesn.go
@@ -85,7 +85,7 @@
 		s.txvr.Stop()
 	}
 
-	txvr, err := mgmt.NewTransceiver(s.cfg.TxFilterCb, s.cfg.RxFilterCb, true,
+	txvr, err := mgmt.NewTransceiver(s.cfg.TxFilter, s.cfg.RxFilter, true,
 		s.cfg.MgmtProto, 3)
 	if err != nil {
 		return err
@@ -648,12 +648,12 @@
 	return nil, fmt.Errorf("Op not implemented yet")
 }
 
-func (s *NakedSesn) Filters() (nmcoap.MsgFilter, nmcoap.MsgFilter) {
+func (s *NakedSesn) Filters() (nmcoap.TxMsgFilter, nmcoap.RxMsgFilter) {
 	return s.txvr.Filters()
 }
 
-func (s *NakedSesn) SetFilters(txFilter nmcoap.MsgFilter,
-	rxFilter nmcoap.MsgFilter) {
+func (s *NakedSesn) SetFilters(txFilter nmcoap.TxMsgFilter,
+	rxFilter nmcoap.RxMsgFilter) {
 
 	s.txvr.SetFilters(txFilter, rxFilter)
 }
diff --git a/nmxact/nmcoap/nmcoap.go b/nmxact/nmcoap/nmcoap.go
index 2951fae..f3d3369 100644
--- a/nmxact/nmcoap/nmcoap.go
+++ b/nmxact/nmcoap/nmcoap.go
@@ -38,7 +38,29 @@
 	OBSERVE_STOP
 )
 
-type MsgFilter func(msg coap.Message) (coap.Message, error)
+type TxMsgFilter interface {
+	// Filter applies the filter to an outgoing CoAP message.
+	Filter(msg coap.Message) (coap.Message, error)
+
+	// Freeze makes the filter use the same parameters for all transmits until
+	// unfrozen.  The parameters will be different from the previous message,
+	// but they will not change while the session is frozen.
+	Freeze()
+
+	// Unfreeze makes the filter use new parameters for all subsequent
+	// messages.
+	Unfreeze()
+}
+
+type RxMsgFilter interface {
+	Filter(msg coap.Message) (coap.Message, error)
+}
+
+type RxFilterFunc func(msg coap.Message) (coap.Message, error)
+
+func (f RxFilterFunc) Filter(msg coap.Message) (coap.Message, error) {
+	return f(msg)
+}
 
 type MsgParams struct {
 	Code    coap.COAPCode
diff --git a/nmxact/nmserial/serial_sesn.go b/nmxact/nmserial/serial_sesn.go
index 1ad0a0d..8bca77c 100644
--- a/nmxact/nmserial/serial_sesn.go
+++ b/nmxact/nmserial/serial_sesn.go
@@ -57,7 +57,7 @@
 		sx:  sx,
 	}
 
-	txvr, err := mgmt.NewTransceiver(cfg.TxFilterCb, cfg.RxFilterCb, false,
+	txvr, err := mgmt.NewTransceiver(cfg.TxFilter, cfg.RxFilter, false,
 		cfg.MgmtProto, 3)
 	if err != nil {
 		return nil, err
@@ -76,7 +76,7 @@
 			"Attempt to open an already-open serial session")
 	}
 
-	txvr, err := mgmt.NewTransceiver(s.cfg.TxFilterCb, s.cfg.RxFilterCb, false,
+	txvr, err := mgmt.NewTransceiver(s.cfg.TxFilter, s.cfg.RxFilter, false,
 		s.cfg.MgmtProto, 3)
 	if err != nil {
 		s.m.Unlock()
@@ -333,12 +333,12 @@
 	}
 }
 
-func (s *SerialSesn) Filters() (nmcoap.MsgFilter, nmcoap.MsgFilter) {
+func (s *SerialSesn) Filters() (nmcoap.TxMsgFilter, nmcoap.RxMsgFilter) {
 	return s.txvr.Filters()
 }
 
-func (s *SerialSesn) SetFilters(txFilter nmcoap.MsgFilter,
-	rxFilter nmcoap.MsgFilter) {
+func (s *SerialSesn) SetFilters(txFilter nmcoap.TxMsgFilter,
+	rxFilter nmcoap.RxMsgFilter) {
 
 	s.txvr.SetFilters(txFilter, rxFilter)
 }
diff --git a/nmxact/nmserial/serial_xport.go b/nmxact/nmserial/serial_xport.go
index f81028f..1c97fc0 100644
--- a/nmxact/nmserial/serial_xport.go
+++ b/nmxact/nmserial/serial_xport.go
@@ -83,8 +83,8 @@
 func (sx *SerialXport) acceptServerSesn(sl *SerialSesn) (*SerialSesn, error) {
 	sc := sesn.NewSesnCfg()
 	sc.MgmtProto = sesn.MGMT_PROTO_COAP_SERVER
-	sc.TxFilterCb = sl.cfg.TxFilterCb
-	sc.RxFilterCb = sl.cfg.RxFilterCb
+	sc.TxFilter = sl.cfg.TxFilter
+	sc.RxFilter = sl.cfg.RxFilter
 
 	s, err := NewSerialSesn(sx, sc)
 	if err != nil {
diff --git a/nmxact/omp/dispatch.go b/nmxact/omp/dispatch.go
index cab7a79..62d0be7 100644
--- a/nmxact/omp/dispatch.go
+++ b/nmxact/omp/dispatch.go
@@ -42,13 +42,13 @@
 	seqListenerMap map[uint8]*Listener
 	coapd          *nmcoap.Dispatcher
 	wg             sync.WaitGroup
-	rxFilter       nmcoap.MsgFilter
+	rxFilter       nmcoap.RxMsgFilter
 	stopped        bool
 	logDepth       int
 	mtx            sync.Mutex
 }
 
-func NewDispatcher(rxFilter nmcoap.MsgFilter, isTcp bool,
+func NewDispatcher(rxFilter nmcoap.RxMsgFilter, isTcp bool,
 	logDepth int) (*Dispatcher, error) {
 
 	d := &Dispatcher{
@@ -199,10 +199,10 @@
 	d.coapd.ErrorAll(err)
 }
 
-func (d *Dispatcher) SetRxFilter(rxFilter nmcoap.MsgFilter) {
+func (d *Dispatcher) SetRxFilter(rxFilter nmcoap.RxMsgFilter) {
 	d.rxFilter = rxFilter
 }
 
-func (d *Dispatcher) RxFilter() nmcoap.MsgFilter {
+func (d *Dispatcher) RxFilter() nmcoap.RxMsgFilter {
 	return d.rxFilter
 }
diff --git a/nmxact/omp/omp.go b/nmxact/omp/omp.go
index e36a8f1..a3f852d 100644
--- a/nmxact/omp/omp.go
+++ b/nmxact/omp/omp.go
@@ -44,16 +44,16 @@
  * codec.  So we need to decode the whole response, and then re-encode the
  * newtmgr response part.
  */
-func DecodeOmp(m coap.Message, rxFilterCb nmcoap.MsgFilter) (nmp.NmpRsp, error) {
+func DecodeOmp(m coap.Message, rxFilter nmcoap.RxMsgFilter) (nmp.NmpRsp, error) {
 	// Ignore non-responses.
 	if m.Code() == coap.GET || m.Code() == coap.PUT || m.Code() == coap.POST ||
 		m.Code() == coap.DELETE {
 		return nil, nil
 	}
 
-	if rxFilterCb != nil {
+	if rxFilter != nil {
 		var err error
-		m, err = rxFilterCb(m)
+		m, err = rxFilter.Filter(m)
 		if err != nil {
 			return nil, err
 		}
@@ -99,7 +99,7 @@
 	fieldMap map[string]interface{}
 }
 
-func encodeOmpBase(txFilterCb nmcoap.MsgFilter, isTcp bool, nmr *nmp.NmpMsg) (encodeRecord, error) {
+func encodeOmpBase(txFilter nmcoap.TxMsgFilter, isTcp bool, nmr *nmp.NmpMsg) (encodeRecord, error) {
 	er := encodeRecord{}
 
 	mp := coap.MessageParams{
@@ -133,9 +133,9 @@
 	}
 	er.m.SetPayload(payload)
 
-	if txFilterCb != nil {
+	if txFilter != nil {
 		var err error
-		er.m, err = txFilterCb(er.m)
+		er.m, err = txFilter.Filter(er.m)
 		if err != nil {
 			return er, err
 		}
@@ -144,8 +144,8 @@
 	return er, nil
 }
 
-func EncodeOmpTcp(txFilterCb nmcoap.MsgFilter, nmr *nmp.NmpMsg) ([]byte, error) {
-	er, err := encodeOmpBase(txFilterCb, true, nmr)
+func EncodeOmpTcp(txFilter nmcoap.TxMsgFilter, nmr *nmp.NmpMsg) ([]byte, error) {
+	er, err := encodeOmpBase(txFilter, true, nmr)
 	if err != nil {
 		return nil, err
 	}
@@ -158,8 +158,8 @@
 	return data, nil
 }
 
-func EncodeOmpDgram(txFilterCb nmcoap.MsgFilter, nmr *nmp.NmpMsg) ([]byte, error) {
-	er, err := encodeOmpBase(txFilterCb, false, nmr)
+func EncodeOmpDgram(txFilter nmcoap.TxMsgFilter, nmr *nmp.NmpMsg) ([]byte, error) {
+	er, err := encodeOmpBase(txFilter, false, nmr)
 	if err != nil {
 		return nil, err
 	}
diff --git a/nmxact/sesn/sesn.go b/nmxact/sesn/sesn.go
index 40b6171..f9a40d6 100644
--- a/nmxact/sesn/sesn.go
+++ b/nmxact/sesn/sesn.go
@@ -116,9 +116,9 @@
 
 	// Returns a transmit and a receive callback used to manipulate CoAP
 	// messages
-	Filters() (nmcoap.MsgFilter, nmcoap.MsgFilter)
+	Filters() (nmcoap.TxMsgFilter, nmcoap.RxMsgFilter)
 
 	// Sets the transmit and a receive callback used to manipulate CoAP
 	// messages
-	SetFilters(txFilter nmcoap.MsgFilter, rxFilter nmcoap.MsgFilter)
+	SetFilters(txFilter nmcoap.TxMsgFilter, rxFilter nmcoap.RxMsgFilter)
 }
diff --git a/nmxact/sesn/sesn_cfg.go b/nmxact/sesn/sesn_cfg.go
index 138dcb8..1304e15 100644
--- a/nmxact/sesn/sesn_cfg.go
+++ b/nmxact/sesn/sesn_cfg.go
@@ -86,9 +86,9 @@
 	Ble  SesnCfgBle
 	Lora SesnCfgLora
 
-	// Callbacks
-	TxFilterCb nmcoap.MsgFilter
-	RxFilterCb nmcoap.MsgFilter
+	// Filters
+	TxFilter nmcoap.TxMsgFilter
+	RxFilter nmcoap.RxMsgFilter
 }
 
 func NewSesnCfg() SesnCfg {
diff --git a/nmxact/udp/udp_sesn.go b/nmxact/udp/udp_sesn.go
index fdeff79..45873c6 100644
--- a/nmxact/udp/udp_sesn.go
+++ b/nmxact/udp/udp_sesn.go
@@ -45,7 +45,7 @@
 	s := &UdpSesn{
 		cfg: cfg,
 	}
-	txvr, err := mgmt.NewTransceiver(cfg.TxFilterCb, cfg.RxFilterCb, false,
+	txvr, err := mgmt.NewTransceiver(cfg.TxFilter, cfg.RxFilter, false,
 		cfg.MgmtProto, 3)
 	if err != nil {
 		return nil, err
@@ -161,12 +161,12 @@
 	return nil, fmt.Errorf("Op not implemented yet")
 }
 
-func (s *UdpSesn) Filters() (nmcoap.MsgFilter, nmcoap.MsgFilter) {
+func (s *UdpSesn) Filters() (nmcoap.TxMsgFilter, nmcoap.RxMsgFilter) {
 	return s.txvr.Filters()
 }
 
-func (s *UdpSesn) SetFilters(txFilter nmcoap.MsgFilter,
-	rxFilter nmcoap.MsgFilter) {
+func (s *UdpSesn) SetFilters(txFilter nmcoap.TxMsgFilter,
+	rxFilter nmcoap.RxMsgFilter) {
 
 	s.txvr.SetFilters(txFilter, rxFilter)
 }
diff --git a/nmxact/xact/image.go b/nmxact/xact/image.go
index a34688d..b3b332c 100644
--- a/nmxact/xact/image.go
+++ b/nmxact/xact/image.go
@@ -157,6 +157,14 @@
 	*nmp.ImageUploadReq, error) {
 	var hash []byte = nil
 
+	// Ensure we produce consistent requests while we calculate the chunk
+	// length.
+	txFilter, _ := s.Filters()
+	if txFilter != nil {
+		txFilter.Freeze()
+		defer txFilter.Unfreeze()
+	}
+
 	// For 1st chunk we'll need valid data hash
 	if off == 0 {
 		sha := sha256.Sum256(data)