|
@ -34,7 +34,8 @@ type MoteMainWindow struct { |
|
|
msg,data *walk.TextEdit |
|
|
msg,data *walk.TextEdit |
|
|
ssl,timeSend *walk.CheckBox |
|
|
ssl,timeSend *walk.CheckBox |
|
|
connConf ConnectConfig |
|
|
connConf ConnectConfig |
|
|
moteConf MoteConfig |
|
|
motesConf MotesConfig |
|
|
|
|
|
currentMoteConf MoteConfig |
|
|
connConfFileName string |
|
|
connConfFileName string |
|
|
moteConfFileName string |
|
|
moteConfFileName string |
|
|
icon *walk.Icon |
|
|
icon *walk.Icon |
|
@ -163,14 +164,16 @@ func main() { |
|
|
_ = mw.password.SetText(mw.connConf.Password) |
|
|
_ = mw.password.SetText(mw.connConf.Password) |
|
|
} |
|
|
} |
|
|
mw.moteConfFileName = dir + "/LoRaMoteConf.json" |
|
|
mw.moteConfFileName = dir + "/LoRaMoteConf.json" |
|
|
|
|
|
mw.motesConf.Configs = make(map[string]MoteConfig) |
|
|
data, err = ioutil.ReadFile(mw.moteConfFileName) |
|
|
data, err = ioutil.ReadFile(mw.moteConfFileName) |
|
|
if err == nil { |
|
|
if err == nil { |
|
|
err = json.Unmarshal(data, &mw.moteConf) |
|
|
err = json.Unmarshal(data, &mw.motesConf) |
|
|
if err != nil { |
|
|
if err != nil { |
|
|
msg := "配置文件格式错误:" + err.Error() |
|
|
msg := "配置文件格式错误:" + err.Error() |
|
|
walk.MsgBox(mw, "错误", msg, walk.MsgBoxIconError) |
|
|
walk.MsgBox(mw, "错误", msg, walk.MsgBoxIconError) |
|
|
return |
|
|
return |
|
|
} |
|
|
} |
|
|
|
|
|
mw.currentMoteConf = mw.motesConf.Configs[mw.motesConf.Current] |
|
|
} |
|
|
} |
|
|
mw.Run() |
|
|
mw.Run() |
|
|
} |
|
|
} |
|
@ -250,6 +253,7 @@ func (mw *MoteMainWindow) Disconnect() { |
|
|
|
|
|
|
|
|
func (mw *MoteMainWindow) MoteConfig() { |
|
|
func (mw *MoteMainWindow) MoteConfig() { |
|
|
var dlg *walk.Dialog |
|
|
var dlg *walk.Dialog |
|
|
|
|
|
var name *walk.ComboBox |
|
|
var otaa *walk.CheckBox |
|
|
var otaa *walk.CheckBox |
|
|
var gatewayId,devEUI,devAddr,appKey,appSKey,nwkSKey *walk.LineEdit |
|
|
var gatewayId,devEUI,devAddr,appKey,appSKey,nwkSKey *walk.LineEdit |
|
|
var fPort,fCnt,freq *walk.NumberEdit |
|
|
var fPort,fCnt,freq *walk.NumberEdit |
|
@ -266,6 +270,22 @@ func (mw *MoteMainWindow) MoteConfig() { |
|
|
Composite{ |
|
|
Composite{ |
|
|
Layout:Grid{Columns: 2}, |
|
|
Layout:Grid{Columns: 2}, |
|
|
Children:[]Widget{ |
|
|
Children:[]Widget{ |
|
|
|
|
|
Label{Text: "终端名称:"}, |
|
|
|
|
|
ComboBox{AssignTo: &name,Editable: true,OnCurrentIndexChanged: func() { |
|
|
|
|
|
mw.motesConf.Current = name.Text() |
|
|
|
|
|
mw.currentMoteConf = mw.motesConf.Configs[mw.motesConf.Current] |
|
|
|
|
|
otaa.SetChecked(mw.currentMoteConf.OTAA) |
|
|
|
|
|
_ = gatewayId.SetText(mw.currentMoteConf.GatewayId) |
|
|
|
|
|
_ = devEUI.SetText(mw.currentMoteConf.DevEui) |
|
|
|
|
|
_ = devAddr.SetText(mw.currentMoteConf.DevAddr) |
|
|
|
|
|
_ = appKey.SetText(mw.currentMoteConf.AppKey) |
|
|
|
|
|
_ = appSKey.SetText(mw.currentMoteConf.AppSKey) |
|
|
|
|
|
_ = nwkSKey.SetText(mw.currentMoteConf.NwkSKey) |
|
|
|
|
|
_ = fPort.SetValue(float64(mw.currentMoteConf.FPort)) |
|
|
|
|
|
_ = fCnt.SetValue(float64(mw.currentMoteConf.FCnt)) |
|
|
|
|
|
_ = freq.SetValue(mw.currentMoteConf.Freq) |
|
|
|
|
|
|
|
|
|
|
|
}}, |
|
|
Label{Text:"入网方式:"}, |
|
|
Label{Text:"入网方式:"}, |
|
|
CheckBox{AssignTo: &otaa,Text:"OTAA入网",OnClicked: func() { |
|
|
CheckBox{AssignTo: &otaa,Text:"OTAA入网",OnClicked: func() { |
|
|
if otaa.Checked() { |
|
|
if otaa.Checked() { |
|
@ -309,19 +329,21 @@ func (mw *MoteMainWindow) MoteConfig() { |
|
|
AssignTo: &acceptPB, |
|
|
AssignTo: &acceptPB, |
|
|
Text: "确定", |
|
|
Text: "确定", |
|
|
OnClicked: func() { |
|
|
OnClicked: func() { |
|
|
mw.moteConf.OTAA = otaa.Checked() |
|
|
mw.currentMoteConf.OTAA = otaa.Checked() |
|
|
mw.moteConf.GatewayId = gatewayId.Text() |
|
|
mw.currentMoteConf.GatewayId = gatewayId.Text() |
|
|
mw.moteConf.DevEui = devEUI.Text() |
|
|
mw.currentMoteConf.DevEui = devEUI.Text() |
|
|
mw.moteConf.DevAddr = devAddr.Text() |
|
|
mw.currentMoteConf.DevAddr = devAddr.Text() |
|
|
mw.moteConf.AppKey = appKey.Text() |
|
|
mw.currentMoteConf.AppKey = appKey.Text() |
|
|
mw.moteConf.AppSKey = appSKey.Text() |
|
|
mw.currentMoteConf.AppSKey = appSKey.Text() |
|
|
mw.moteConf.NwkSKey = nwkSKey.Text() |
|
|
mw.currentMoteConf.NwkSKey = nwkSKey.Text() |
|
|
mw.moteConf.FPort = uint8(fPort.Value()) |
|
|
mw.currentMoteConf.FPort = uint8(fPort.Value()) |
|
|
mw.moteConf.FCnt = uint32(fCnt.Value()) |
|
|
mw.currentMoteConf.FCnt = uint32(fCnt.Value()) |
|
|
mw.moteConf.Freq = freq.Value() |
|
|
mw.currentMoteConf.Freq = freq.Value() |
|
|
|
|
|
mw.motesConf.Current = name.Text() |
|
|
|
|
|
mw.motesConf.Configs[mw.motesConf.Current] = mw.currentMoteConf |
|
|
|
|
|
|
|
|
var confData bytes.Buffer |
|
|
var confData bytes.Buffer |
|
|
d,_ := json.Marshal(&mw.moteConf) |
|
|
d,_ := json.Marshal(&mw.motesConf) |
|
|
_ = json.Indent(&confData, d, "", "\t") |
|
|
_ = json.Indent(&confData, d, "", "\t") |
|
|
_ = ioutil.WriteFile(mw.moteConfFileName,confData.Bytes(),0644) |
|
|
_ = ioutil.WriteFile(mw.moteConfFileName,confData.Bytes(),0644) |
|
|
dlg.Accept() |
|
|
dlg.Accept() |
|
@ -336,17 +358,22 @@ func (mw *MoteMainWindow) MoteConfig() { |
|
|
}, |
|
|
}, |
|
|
}, |
|
|
}, |
|
|
}.Create(mw) |
|
|
}.Create(mw) |
|
|
|
|
|
var names []string |
|
|
otaa.SetChecked(mw.moteConf.OTAA) |
|
|
for k,_ := range mw.motesConf.Configs { |
|
|
_ = gatewayId.SetText(mw.moteConf.GatewayId) |
|
|
names = append(names,k) |
|
|
_ = devEUI.SetText(mw.moteConf.DevEui) |
|
|
} |
|
|
_ = devAddr.SetText(mw.moteConf.DevAddr) |
|
|
_ = name.SetModel(names) |
|
|
_ = appKey.SetText(mw.moteConf.AppKey) |
|
|
_ = name.SetText(mw.motesConf.Current) |
|
|
_ = appSKey.SetText(mw.moteConf.AppSKey) |
|
|
otaa.SetChecked(mw.currentMoteConf.OTAA) |
|
|
_ = nwkSKey.SetText(mw.moteConf.NwkSKey) |
|
|
_ = gatewayId.SetText(mw.currentMoteConf.GatewayId) |
|
|
_ = fPort.SetValue(float64(mw.moteConf.FPort)) |
|
|
_ = devEUI.SetText(mw.currentMoteConf.DevEui) |
|
|
_ = fCnt.SetValue(float64(mw.moteConf.FCnt)) |
|
|
_ = devAddr.SetText(mw.currentMoteConf.DevAddr) |
|
|
_ = freq.SetValue(mw.moteConf.Freq) |
|
|
_ = appKey.SetText(mw.currentMoteConf.AppKey) |
|
|
|
|
|
_ = appSKey.SetText(mw.currentMoteConf.AppSKey) |
|
|
|
|
|
_ = nwkSKey.SetText(mw.currentMoteConf.NwkSKey) |
|
|
|
|
|
_ = fPort.SetValue(float64(mw.currentMoteConf.FPort)) |
|
|
|
|
|
_ = fCnt.SetValue(float64(mw.currentMoteConf.FCnt)) |
|
|
|
|
|
_ = freq.SetValue(mw.currentMoteConf.Freq) |
|
|
|
|
|
|
|
|
dlg.Run() |
|
|
dlg.Run() |
|
|
} |
|
|
} |
|
@ -472,8 +499,8 @@ func (mw *MoteMainWindow) HandleData(client paho.Client, message paho.Message){ |
|
|
dd := &Mote{ |
|
|
dd := &Mote{ |
|
|
Index: mw.model.Len() + 1, |
|
|
Index: mw.model.Len() + 1, |
|
|
Direction:"downlink", |
|
|
Direction:"downlink", |
|
|
DevEUI: mw.moteConf.DevEui, |
|
|
DevEUI: mw.currentMoteConf.DevEui, |
|
|
DevAddr: mw.moteConf.DevAddr, |
|
|
DevAddr: mw.currentMoteConf.DevAddr, |
|
|
MType: phy.MHDR.MType.String(), |
|
|
MType: phy.MHDR.MType.String(), |
|
|
GatewayID: hex.EncodeToString(downlinkFrame.TxInfo.GatewayId), |
|
|
GatewayID: hex.EncodeToString(downlinkFrame.TxInfo.GatewayId), |
|
|
Time:time.Now().Format("2006-01-02 15:04:05"), |
|
|
Time:time.Now().Format("2006-01-02 15:04:05"), |
|
@ -500,7 +527,7 @@ func (mw *MoteMainWindow) HandleData(client paho.Client, message paho.Message){ |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (mw *MoteMainWindow) HandleJoinAccept(phy *lorawan.PHYPayload){ |
|
|
func (mw *MoteMainWindow) HandleJoinAccept(phy *lorawan.PHYPayload){ |
|
|
key := mw.moteConf.AppKey |
|
|
key := mw.currentMoteConf.AppKey |
|
|
var aseKey lorawan.AES128Key |
|
|
var aseKey lorawan.AES128Key |
|
|
_ = aseKey.UnmarshalText([]byte(key)) |
|
|
_ = aseKey.UnmarshalText([]byte(key)) |
|
|
err := phy.DecryptJoinAcceptPayload(aseKey) |
|
|
err := phy.DecryptJoinAcceptPayload(aseKey) |
|
@ -511,32 +538,32 @@ func (mw *MoteMainWindow) HandleJoinAccept(phy *lorawan.PHYPayload){ |
|
|
if !ok { |
|
|
if !ok { |
|
|
fmt.Println("lorawan: MACPayload must be of type *JoinAcceptPayload") |
|
|
fmt.Println("lorawan: MACPayload must be of type *JoinAcceptPayload") |
|
|
} |
|
|
} |
|
|
mw.moteConf.DevAddr = jap.DevAddr.String() |
|
|
mw.currentMoteConf.DevAddr = jap.DevAddr.String() |
|
|
dn := mw.moteConf.devNonce |
|
|
dn := mw.currentMoteConf.devNonce |
|
|
appSKey,err := getAppSKey(aseKey,jap.HomeNetID,jap.JoinNonce,dn) |
|
|
appSKey,err := getAppSKey(aseKey,jap.HomeNetID,jap.JoinNonce,dn) |
|
|
if err == nil { |
|
|
if err == nil { |
|
|
mw.moteConf.AppSKey = appSKey.String() |
|
|
mw.currentMoteConf.AppSKey = appSKey.String() |
|
|
fmt.Println(mw.moteConf.AppSKey) |
|
|
fmt.Println(mw.currentMoteConf.AppSKey) |
|
|
} |
|
|
} |
|
|
nwkSKey,err := getNwkSKey(aseKey,jap.HomeNetID,jap.JoinNonce,dn) |
|
|
nwkSKey,err := getNwkSKey(aseKey,jap.HomeNetID,jap.JoinNonce,dn) |
|
|
if err == nil { |
|
|
if err == nil { |
|
|
mw.moteConf.NwkSKey = nwkSKey.String() |
|
|
mw.currentMoteConf.NwkSKey = nwkSKey.String() |
|
|
fmt.Println(mw.moteConf.NwkSKey) |
|
|
fmt.Println(mw.currentMoteConf.NwkSKey) |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (mw *MoteMainWindow) HandleDataDown(phy *lorawan.PHYPayload){ |
|
|
func (mw *MoteMainWindow) HandleDataDown(phy *lorawan.PHYPayload){ |
|
|
mpl := phy.MACPayload.(*lorawan.MACPayload) |
|
|
mpl := phy.MACPayload.(*lorawan.MACPayload) |
|
|
key := mw.moteConf.AppSKey |
|
|
key := mw.currentMoteConf.AppSKey |
|
|
if mpl.FPort != nil && *mpl.FPort == 0 { |
|
|
if mpl.FPort != nil && *mpl.FPort == 0 { |
|
|
key = mw.moteConf.NwkSKey |
|
|
key = mw.currentMoteConf.NwkSKey |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
var aseKey lorawan.AES128Key |
|
|
var aseKey lorawan.AES128Key |
|
|
_ = aseKey.UnmarshalText([]byte(key)) |
|
|
_ = aseKey.UnmarshalText([]byte(key)) |
|
|
err := phy.DecryptFRMPayload(aseKey) |
|
|
err := phy.DecryptFRMPayload(aseKey) |
|
|
if err == nil { |
|
|
if err == nil { |
|
|
mw.moteConf.DevAddr = mpl.FHDR.DevAddr.String() |
|
|
mw.currentMoteConf.DevAddr = mpl.FHDR.DevAddr.String() |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -559,20 +586,20 @@ func (mw *MoteMainWindow) sendMsg() error{ |
|
|
walk.MsgBox(mw, "错误", msg, walk.MsgBoxIconError) |
|
|
walk.MsgBox(mw, "错误", msg, walk.MsgBoxIconError) |
|
|
return errors.New("请先连接服务器") |
|
|
return errors.New("请先连接服务器") |
|
|
} |
|
|
} |
|
|
if mw.moteConf.OTAA && mw.moteConf.DevAddr == ""{ |
|
|
if mw.currentMoteConf.OTAA && mw.currentMoteConf.DevAddr == ""{ |
|
|
mw.moteConf.devNonce = lorawan.DevNonce(rand.Uint32()) |
|
|
mw.currentMoteConf.devNonce = lorawan.DevNonce(rand.Uint32()) |
|
|
appEui := "0807060504030201" |
|
|
appEui := "0807060504030201" |
|
|
packet,phy,_ := BuildJoin(mw.moteConf.GatewayId,appEui,mw.moteConf.DevEui,mw.moteConf.AppKey, |
|
|
packet,phy,_ := BuildJoin(mw.currentMoteConf.GatewayId,appEui,mw.currentMoteConf.DevEui,mw.currentMoteConf.AppKey, |
|
|
5,2,mw.moteConf.Freq,7,-51, mw.moteConf.devNonce) |
|
|
5,2,mw.currentMoteConf.Freq,7,-51, mw.currentMoteConf.devNonce) |
|
|
var origData bytes.Buffer |
|
|
var origData bytes.Buffer |
|
|
jsonData,_ := phy.MarshalJSON() |
|
|
jsonData,_ := phy.MarshalJSON() |
|
|
_ = json.Indent(&origData, jsonData, "", " ") |
|
|
_ = json.Indent(&origData, jsonData, "", " ") |
|
|
du := &Mote{ |
|
|
du := &Mote{ |
|
|
Index:mw.model.Len() + 1, |
|
|
Index:mw.model.Len() + 1, |
|
|
Direction:"uplink", |
|
|
Direction:"uplink", |
|
|
DevEUI:mw.moteConf.DevEui, |
|
|
DevEUI:mw.currentMoteConf.DevEui, |
|
|
MType:phy.MHDR.MType.String(), |
|
|
MType:phy.MHDR.MType.String(), |
|
|
GatewayID:mw.moteConf.GatewayId, |
|
|
GatewayID:mw.currentMoteConf.GatewayId, |
|
|
Rssi:packet.Payload.RXPK[0].RSSI, |
|
|
Rssi:packet.Payload.RXPK[0].RSSI, |
|
|
LoRaSNR:packet.Payload.RXPK[0].LSNR, |
|
|
LoRaSNR:packet.Payload.RXPK[0].LSNR, |
|
|
Frequency:packet.Payload.RXPK[0].Freq, |
|
|
Frequency:packet.Payload.RXPK[0].Freq, |
|
@ -584,13 +611,13 @@ func (mw *MoteMainWindow) sendMsg() error{ |
|
|
_ = mw.tv.SetSelectedIndexes([]int{}) |
|
|
_ = mw.tv.SetSelectedIndexes([]int{}) |
|
|
frames,_:= packet.GetUplinkFrames(true,false) |
|
|
frames,_:= packet.GetUplinkFrames(true,false) |
|
|
for j := range frames { |
|
|
for j := range frames { |
|
|
mw.PushData(mw.moteConf.GatewayId,"up",&frames[j]) |
|
|
mw.PushData(mw.currentMoteConf.GatewayId,"up",&frames[j]) |
|
|
} |
|
|
} |
|
|
fmt.Println("push join ") |
|
|
fmt.Println("push join ") |
|
|
for cnt := 0;mw.moteConf.DevAddr == "" && cnt < 5;cnt ++ { |
|
|
for cnt := 0;mw.currentMoteConf.DevAddr == "" && cnt < 5;cnt ++ { |
|
|
time.Sleep(time.Second) |
|
|
time.Sleep(time.Second) |
|
|
} |
|
|
} |
|
|
if mw.moteConf.DevAddr != "" { |
|
|
if mw.currentMoteConf.DevAddr != "" { |
|
|
fmt.Println("join ok") |
|
|
fmt.Println("join ok") |
|
|
}else{ |
|
|
}else{ |
|
|
fmt.Println("join failed") |
|
|
fmt.Println("join failed") |
|
@ -611,12 +638,12 @@ func (mw *MoteMainWindow) sendMsg() error{ |
|
|
} |
|
|
} |
|
|
var fCtrl lorawan.FCtrl |
|
|
var fCtrl lorawan.FCtrl |
|
|
_ = fCtrl.UnmarshalBinary([]byte{128}) |
|
|
_ = fCtrl.UnmarshalBinary([]byte{128}) |
|
|
key := mw.moteConf.AppSKey |
|
|
key := mw.currentMoteConf.AppSKey |
|
|
if mw.moteConf.FPort == 0 { |
|
|
if mw.currentMoteConf.FPort == 0 { |
|
|
key = mw.moteConf.NwkSKey |
|
|
key = mw.currentMoteConf.NwkSKey |
|
|
} |
|
|
} |
|
|
packet,phy,_ := BuildUpData(mw.moteConf.GatewayId,mw.moteConf.DevAddr,key, |
|
|
packet,phy,_ := BuildUpData(mw.currentMoteConf.GatewayId,mw.currentMoteConf.DevAddr,key, |
|
|
mw.moteConf.NwkSKey,mw.moteConf.FCnt,mw.moteConf.FPort,5,2,mw.moteConf.Freq,7, |
|
|
mw.currentMoteConf.NwkSKey,mw.currentMoteConf.FCnt,mw.currentMoteConf.FPort,5,2,mw.currentMoteConf.Freq,7, |
|
|
lorawan.UnconfirmedDataUp,fCtrl,-51,bmsg) |
|
|
lorawan.UnconfirmedDataUp,fCtrl,-51,bmsg) |
|
|
|
|
|
|
|
|
var origData bytes.Buffer |
|
|
var origData bytes.Buffer |
|
@ -625,15 +652,15 @@ func (mw *MoteMainWindow) sendMsg() error{ |
|
|
du := &Mote{ |
|
|
du := &Mote{ |
|
|
Index:mw.model.Len() + 1, |
|
|
Index:mw.model.Len() + 1, |
|
|
Direction:"uplink", |
|
|
Direction:"uplink", |
|
|
DevEUI:mw.moteConf.DevEui, |
|
|
DevEUI:mw.currentMoteConf.DevEui, |
|
|
DevAddr:mw.moteConf.DevAddr, |
|
|
DevAddr:mw.currentMoteConf.DevAddr, |
|
|
MType:phy.MHDR.MType.String(), |
|
|
MType:phy.MHDR.MType.String(), |
|
|
GatewayID:mw.moteConf.GatewayId, |
|
|
GatewayID:mw.currentMoteConf.GatewayId, |
|
|
Rssi:packet.Payload.RXPK[0].RSSI, |
|
|
Rssi:packet.Payload.RXPK[0].RSSI, |
|
|
LoRaSNR:packet.Payload.RXPK[0].LSNR, |
|
|
LoRaSNR:packet.Payload.RXPK[0].LSNR, |
|
|
Frequency:packet.Payload.RXPK[0].Freq, |
|
|
Frequency:packet.Payload.RXPK[0].Freq, |
|
|
FCnt:mw.moteConf.FCnt, |
|
|
FCnt:mw.currentMoteConf.FCnt, |
|
|
FPort:mw.moteConf.FPort, |
|
|
FPort:mw.currentMoteConf.FPort, |
|
|
HexData:hex.EncodeToString(bmsg), |
|
|
HexData:hex.EncodeToString(bmsg), |
|
|
AsciiData:BytesToString(bmsg), |
|
|
AsciiData:BytesToString(bmsg), |
|
|
Time:time.Now().Format("2006-01-02 15:04:05"), |
|
|
Time:time.Now().Format("2006-01-02 15:04:05"), |
|
@ -644,11 +671,11 @@ func (mw *MoteMainWindow) sendMsg() error{ |
|
|
_ = mw.tv.SetSelectedIndexes([]int{}) |
|
|
_ = mw.tv.SetSelectedIndexes([]int{}) |
|
|
frames,_:= packet.GetUplinkFrames(true,false) |
|
|
frames,_:= packet.GetUplinkFrames(true,false) |
|
|
for j := range frames { |
|
|
for j := range frames { |
|
|
mw.PushData(mw.moteConf.GatewayId,"up",&frames[j]) |
|
|
mw.PushData(mw.currentMoteConf.GatewayId,"up",&frames[j]) |
|
|
} |
|
|
} |
|
|
mw.moteConf.FCnt ++ |
|
|
mw.currentMoteConf.FCnt ++ |
|
|
var confData bytes.Buffer |
|
|
var confData bytes.Buffer |
|
|
d,_ := json.Marshal(&mw.moteConf) |
|
|
d,_ := json.Marshal(&mw.currentMoteConf) |
|
|
_ = json.Indent(&confData, d, "", "\t") |
|
|
_ = json.Indent(&confData, d, "", "\t") |
|
|
_ = ioutil.WriteFile(mw.moteConfFileName,confData.Bytes(),0644) |
|
|
_ = ioutil.WriteFile(mw.moteConfFileName,confData.Bytes(),0644) |
|
|
return nil |
|
|
return nil |
|
|