blob: 78033d033d9559ee4ea8ba9b41450e43f5997e45 [file] [log] [blame]
/**
* 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 cli
import (
"fmt"
log "github.com/sirupsen/logrus"
"mynewt.apache.org/newt/util"
"mynewt.apache.org/newtmgr/newtmgr/bll"
"mynewt.apache.org/newtmgr/newtmgr/config"
"mynewt.apache.org/newtmgr/newtmgr/nmutil"
"mynewt.apache.org/newtmgr/nmxact/mtech_lora"
"mynewt.apache.org/newtmgr/nmxact/nmble"
"mynewt.apache.org/newtmgr/nmxact/nmcoap"
"mynewt.apache.org/newtmgr/nmxact/nmserial"
"mynewt.apache.org/newtmgr/nmxact/sesn"
"mynewt.apache.org/newtmgr/nmxact/udp"
"mynewt.apache.org/newtmgr/nmxact/xport"
)
var globalSesn sesn.Sesn
var globalXport xport.Xport
var globalP *config.ConnProfile
// 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
func initConnProfile() error {
var p *config.ConnProfile
if nmutil.ConnProfile == "" {
p = config.NewConnProfile()
p.Name = "unnamed"
} else {
var err error
cpm := config.GlobalConnProfileMgr()
p, err = cpm.GetConnProfile(nmutil.ConnProfile)
if err != nil {
return err
}
}
if nmutil.ConnType != "" {
t, err := config.ConnTypeFromString(nmutil.ConnType)
if err != nil {
return util.FmtNewtError("invalid conntype: \"%s\"",
nmutil.ConnType)
}
p.Type = t
}
if nmutil.ConnString != "" {
p.ConnString = nmutil.ConnString
}
if nmutil.ConnExtra != "" {
if p.ConnString != "" {
p.ConnString += ","
}
p.ConnString += nmutil.ConnExtra
}
if p.Type == config.CONN_TYPE_NONE {
return util.FmtNewtError("No connection type specified")
}
log.Debugf("Using connection profile: %v", p)
globalP = p
return nil
}
func getConnProfile() (*config.ConnProfile, error) {
if globalP == nil {
if err := initConnProfile(); err != nil {
return nil, err
}
}
return globalP, nil
}
func GetXport() (xport.Xport, error) {
if globalXport != nil {
return globalXport, nil
}
cp, err := getConnProfile()
if err != nil {
return nil, err
}
switch cp.Type {
case config.CONN_TYPE_SERIAL_PLAIN, config.CONN_TYPE_SERIAL_OIC:
sc, err := config.ParseSerialConnString(cp.ConnString)
if err != nil {
return nil, err
}
globalXport = nmserial.NewSerialXport(sc)
case config.CONN_TYPE_BLL_PLAIN, config.CONN_TYPE_BLL_OIC:
bc, err := config.ParseBllConnString(cp.ConnString)
if err != nil {
return nil, err
}
cfg := bll.NewXportCfg()
if bc.CtlrName != "" {
cfg.CtlrName = bc.CtlrName
}
cfg.OwnAddrType = bc.OwnAddrType
globalXport = bll.NewBllXport(cfg, bc.HciIdx)
case config.CONN_TYPE_BLE_PLAIN, config.CONN_TYPE_BLE_OIC:
bc, err := config.ParseBleConnString(cp.ConnString)
if err != nil {
return nil, err
}
globalXport, err = config.BuildBleXport(bc)
if err != nil {
return nil, err
}
case config.CONN_TYPE_UDP_PLAIN, config.CONN_TYPE_UDP_OIC:
globalXport = udp.NewUdpXport()
case config.CONN_TYPE_MTECH_LORA_OIC:
cfg := mtech_lora.NewXportCfg()
globalXport = mtech_lora.NewLoraXport(cfg)
default:
return nil, util.FmtNewtError("Unknown connection type: %s (%d)",
config.ConnTypeToString(cp.Type), int(cp.Type))
}
globalXportSet = true
if err := globalXport.Start(); err != nil {
return nil, util.ChildNewtError(err)
}
return globalXport, nil
}
func GetXportIfOpen() (xport.Xport, error) {
if !globalXportSet {
return nil, fmt.Errorf("xport not initailized")
}
return globalXport, nil
}
func buildSesnCfg() (sesn.SesnCfg, error) {
sc := sesn.NewSesnCfg()
cp, err := getConnProfile()
if err != nil {
return sc, err
}
switch cp.Type {
case config.CONN_TYPE_SERIAL_PLAIN:
sc.MgmtProto = sesn.MGMT_PROTO_NMP
return sc, nil
case config.CONN_TYPE_SERIAL_OIC:
sc.MgmtProto = sesn.MGMT_PROTO_OMP
return sc, nil
case config.CONN_TYPE_BLE_PLAIN:
bc, err := config.ParseBleConnString(cp.ConnString)
if err != nil {
return sc, err
}
x, err := GetXport()
if err != nil {
return sc, err
}
bx := x.(*nmble.BleXport)
sc.MgmtProto = sesn.MGMT_PROTO_NMP
if err := config.FillSesnCfg(bx, bc, &sc); err != nil {
return sc, err
}
return sc, nil
case config.CONN_TYPE_BLE_OIC:
bc, err := config.ParseBleConnString(cp.ConnString)
if err != nil {
return sc, err
}
x, err := GetXport()
if err != nil {
return sc, err
}
bx := x.(*nmble.BleXport)
sc.MgmtProto = sesn.MGMT_PROTO_OMP
if err := config.FillSesnCfg(bx, bc, &sc); err != nil {
return sc, err
}
return sc, nil
case config.CONN_TYPE_UDP_PLAIN:
sc.MgmtProto = sesn.MGMT_PROTO_NMP
sc.PeerSpec.Udp = cp.ConnString
return sc, nil
case config.CONN_TYPE_UDP_OIC:
sc.MgmtProto = sesn.MGMT_PROTO_OMP
sc.PeerSpec.Udp = cp.ConnString
return sc, nil
case config.CONN_TYPE_MTECH_LORA_OIC:
mc, err := config.ParseMtechLoraConnString(cp.ConnString)
if err != nil {
return sc, err
}
sc.MgmtProto = sesn.MGMT_PROTO_OMP
err = config.FillMtechLoraSesnCfg(mc, &sc)
return sc, err
default:
return sc, util.FmtNewtError("Unknown connection type: %s (%d)",
config.ConnTypeToString(cp.Type), int(cp.Type))
}
}
func buildBllSesn(cp *config.ConnProfile) (sesn.Sesn, error) {
bc, err := config.ParseBllConnString(cp.ConnString)
if err != nil {
return nil, err
}
sc, err := config.BuildBllSesnCfg(bc)
if err != nil {
return nil, err
}
x, err := GetXport()
if err != nil {
return nil, err
}
bx := x.(*bll.BllXport)
switch cp.Type {
case config.CONN_TYPE_BLL_PLAIN:
sc.MgmtProto = sesn.MGMT_PROTO_NMP
case config.CONN_TYPE_BLL_OIC:
sc.MgmtProto = sesn.MGMT_PROTO_OMP
default:
return nil, util.NewNewtError("ERROR")
}
sc.TxFilterCb = globalTxFilter
sc.RxFilterCb = globalRxFilter
s, err := bx.BuildBllSesn(sc)
if err != nil {
return nil, util.ChildNewtError(err)
}
return s, nil
}
func GetSesn() (sesn.Sesn, error) {
if globalSesn != nil {
return globalSesn, nil
}
cp, err := getConnProfile()
if err != nil {
return nil, err
}
var s sesn.Sesn
if cp.Type == config.CONN_TYPE_BLL_PLAIN ||
cp.Type == config.CONN_TYPE_BLL_OIC {
s, err = buildBllSesn(cp)
if err != nil {
return nil, util.ChildNewtError(err)
}
} else {
sc, err := buildSesnCfg()
if err != nil {
return nil, err
}
sc.TxFilterCb = globalTxFilter
sc.RxFilterCb = globalRxFilter
x, err := GetXport()
if err != nil {
return nil, err
}
s, err = x.BuildSesn(sc)
if err != nil {
return nil, util.ChildNewtError(err)
}
}
globalSesn = s
if err := globalSesn.Open(); err != nil {
return nil, util.ChildNewtError(err)
}
return globalSesn, nil
}
func GetSesnIfOpen() (sesn.Sesn, error) {
if globalSesn == nil {
return nil, fmt.Errorf("sesn not initailized")
}
return globalSesn, nil
}
func SetFilters(txFilter nmcoap.MsgFilter, rxFilter nmcoap.MsgFilter) {
globalTxFilter = txFilter
globalRxFilter = rxFilter
}