newtmgr/cli/common.go (264 lines of code) (raw):

/** * 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.TxMsgFilter var globalRxFilter nmcoap.RxMsgFilter 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.TxFilter = globalTxFilter sc.RxFilter = 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.TxFilter = globalTxFilter sc.RxFilter = 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.TxMsgFilter, rxFilter nmcoap.RxMsgFilter) { globalTxFilter = txFilter globalRxFilter = rxFilter }