package netmgrd import "C" import ( "sync/atomic" "time" modem "hnyfkj.com.cn/rtu/linux/air720u" "hnyfkj.com.cn/rtu/linux/baseapp" ) const MODULE_NAME = "NetworkManager" var ( isOnline atomic.Bool // 标记是否联网 offlineStartTs atomic.Int64 // 离线开始时间 isSyncNTPTimeOK atomic.Bool // 标记本地时间是否已同步成功 ) const ( interval1 = time.Duration(1) * time.Second interval2 = time.Duration(5) * time.Second ) func ModuleInit() { go serviceRun() } // 联网保持服务 func serviceRun() { t := time.NewTimer(interval1) defer t.Stop() for { select { case <-t.C: // 1, 联网检测-看结果 dnsOK, pingOK, tcpOK, httpOK := CheckNetwork() baseapp.Logger.Infof("[%s] 联网检测: DNS OK=%v, PING OK=%v, TCP OK=%v, HTTP OK=%v", MODULE_NAME, dnsOK, pingOK, tcpOK, httpOK) // 2, 检测成功-在线时 if dnsOK && pingOK && tcpOK { isOnline.Store(true) offlineStartTs.Store(0) if isSyncNTPTimeOK.Load() { t.Reset(interval2) continue } err := SyncNTPTime() if err == nil { isSyncNTPTimeOK.Store(true) baseapp.Logger.Infof("[%s] NTP时间已同步", MODULE_NAME) t.Reset(interval2) continue } else { baseapp.Logger.Errorf("[%s] 同步NTP时间时有错误发生: %v!!", MODULE_NAME, err) t.Reset(interval1) continue } } // 3, 检测失败-离线时 if isOnline.Load() { // 状态由"1"变为"0" isOnline.Store(false) offlineStartTs.Store(time.Now().UnixNano()) // 记录离线开始时间 } if OfflineDuration() >= (time.Duration(60) * time.Second) { baseapp.Logger.Warnf("[%s] 检测到网络长时间断开, 将重置4G模块!", MODULE_NAME) reset4gNetwork() offlineStartTs.Store(time.Now().UnixNano()) // 重置离线开始时间 } t.Reset(interval1) case <-baseapp.IsExit2(): return } // select end } // for end } // 返回联网状态 func IsInetAvailable() bool { return isOnline.Load() } // 时间是否同步 func IsSyncedNtpTime() bool { return isSyncNTPTimeOK.Load() } // 等待所有成功 func WaitAllOK(timeout time.Duration) bool { deadline := time.Now().Add(timeout) tick := 50 * time.Millisecond for { if IsInetAvailable() && IsSyncedNtpTime() { return true } remaining := time.Until(deadline) if remaining <= 0 { return false } sleep := min(tick, remaining) time.Sleep(sleep) } } // 返回断网时长 func OfflineDuration() time.Duration { if IsInetAvailable() { return 0 } ts := offlineStartTs.Load() if ts == 0 { return 0 } return time.Since(time.Unix(0, ts)) } // 重启模块联网 func reset4gNetwork() { modem.ModuleExit() modem.ModuleInit(true) } //export RTU_IsInetAvailable func RTU_IsInetAvailable() C.int { if IsInetAvailable() { return 1 } return 0 } //export RTU_IsSyncedNtpTime func RTU_IsSyncedNtpTime() C.int { if IsSyncedNtpTime() { return 1 } return 0 }