| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- // Author: NiuJiuRu
- // Email: niujiuru@qq.com
- package ec200u
- import (
- "os"
- "sync"
- "time"
- "hnyfkj.com.cn/rtu/linux/baseapp"
- )
- const MODULE_NAME = "EC200U"
- var (
- imei string // EC200U模块的IMEI号, 唯一标识
- rssi string // EC200U模块当前信号强度(RSSI)
- iccid string // EC200U模块插入SIM卡的ICCID号
- mu1, mu2, mu3 sync.Mutex
- isRunning1, isRunning2 bool
- exitCh1, exitCh2 chan struct{}
- wg1, wg2 sync.WaitGroup
- )
- // 初始化4G网络模块
- func ModuleInit(bForceRepower bool /*是否强制重启*/) bool {
- mu1.Lock()
- defer mu1.Unlock()
- if isRunning1 {
- return true
- }
- var err error
- var ret int
- var bExists, bReady bool
- _, statErr := os.Stat("/dev/ttyUSB0")
- bExists = (statErr == nil)
- if bExists && !bForceRepower {
- ret, err = ec200U_ComInit()
- if err == nil {
- goto openOK
- }
- switch ret {
- case -1, -3, -4, -5: // -1: 串口被占用或不存在(驱动有问题时)
- // -3, -4, -5: 设备无应答(初始化时会发送的三条关键配置指令)
- if ret == -1 {
- freeTTYUSB0()
- }
- ec200U_Repower() // 重新上电
- bExists = false // 等待复位, 标记设备已不存在
- }
- } else { ///// 设备不存在, 或调用该函数时明确要求强制重启 ////
- ec200U_Repower() //// 重新上电
- bExists = false //// 等待复位, 标记设备已不存在
- }
- for range 6 {
- if baseapp.IsExit1() {
- ec200U_ComExit()
- return false
- }
- if !bExists {
- time.Sleep(5 * time.Second) // 等待设备文件再次出现
- }
- ret, err = ec200U_ComInit()
- if err != nil && ret == -1 && !bExists { // 继续等待
- continue
- }
- break
- }
- if err != nil {
- ec200U_ComExit()
- baseapp.Logger.Errorf("[%s] 错误: %v!!", MODULE_NAME, err)
- return false
- }
- openOK:
- imei, err = ec200U_GetIMEI()
- if err != nil {
- ec200U_ComExit()
- baseapp.Logger.Errorf("[%s] 错误: %v!!", MODULE_NAME, err)
- return false
- }
- baseapp.Logger.Infof("[%s] 模块IMEI: %s", MODULE_NAME, imei)
- for range 30 { // 等待模块完成蜂窝网络注册, 否则RSSI读取不到, 网也不可能不去
- if baseapp.IsExit1() {
- ec200U_ComExit()
- return false
- }
- cs, err := ec200U_GetCregState()
- if err != nil || cs == 1 /*已注册本地网*/ || cs == 5 /*已注册漫游网*/ {
- break
- }
- time.Sleep(1 * time.Second)
- }
- rssi, err = ec200U_GetRSSIFromCSQ()
- if err != nil {
- ec200U_ComExit()
- baseapp.Logger.Errorf("[%s] 错误: %v!!", MODULE_NAME, err)
- return false
- }
- baseapp.Logger.Infof("[%s] 模块RSSI: %s", MODULE_NAME, rssi)
- bReady, err = ec200U_IsSimCardReady()
- if err != nil {
- ec200U_ComExit()
- baseapp.Logger.Errorf("[%s] 错误: %v!!", MODULE_NAME, err)
- return false
- }
- baseapp.Logger.Infof("[%s] SIM卡状态: %v", MODULE_NAME, bReady)
- if !bReady { // 未插入SIM卡, 也不影响初始化成功, 可等待之后的热插入
- goto initOK
- }
- iccid, err = ec200U_GetSimICCID()
- if err != nil {
- ec200U_ComExit()
- baseapp.Logger.Errorf("[%s] 错误: %v!!", MODULE_NAME, err)
- return false
- }
- baseapp.Logger.Infof("[%s] SIM卡ICCID: %s", MODULE_NAME, iccid)
- initOK:
- exitCh1 = make(chan struct{})
- wg1.Add(1)
- go func() { // 启动携程循环读取4G模块的信号强度和ICCID号等信息
- defer wg1.Done()
- monitorEC200UInfo(exitCh1)
- }()
- isRunning1 = true
- return isRunning1
- }
- // 4G调制解调器退出
- func ModuleExit() {
- mu1.Lock()
- defer mu1.Unlock()
- if !isRunning1 {
- return
- }
- close(exitCh1)
- wg1.Wait() // 等待循环读取4G模块的信号强度和ICCID号等信息的携程退出
- ec200U_ComExit()
- imei, rssi, iccid = "", "", ""
- isRunning1 = false
- }
- // 获取模块的标识号
- func GetIMEI() string {
- mu2.Lock()
- defer mu2.Unlock()
- return imei
- }
- // 获取当前信号强度
- func GetRSSI() string {
- mu2.Lock()
- defer mu2.Unlock()
- return rssi
- }
- // 获取电话卡标识号
- func GetSimICCID() string {
- mu2.Lock()
- defer mu2.Unlock()
- return iccid
- }
- // 循环读取刷新信息
- func monitorEC200UInfo(exitCh <-chan struct{}) {
- t := time.NewTicker(time.Duration(5) * time.Second)
- defer t.Stop()
- for {
- select {
- case <-t.C:
- mu2.Lock()
- rssi, _ = ec200U_GetRSSIFromCSQ()
- if bOK, _ := ec200U_IsSimCardReady(); bOK {
- iccid, _ = ec200U_GetSimICCID()
- } else {
- iccid = ""
- }
- mu2.Unlock()
- case <-exitCh:
- return
- } // select end
- } // for end
- }
- // 打开连接到4G网络
- func Start4GNetwork() bool {
- mu3.Lock()
- defer mu3.Unlock()
- if isRunning2 {
- return true
- }
- killAllUdhcpc()
- err := disableEthButUSB0()
- if err != nil {
- baseapp.Logger.Errorf("[%s] 错误: %v!!", MODULE_NAME, err)
- return false
- }
- bExists, _ := udhcpcUSB0Exists()
- if bExists {
- killUSB0Udhcpc()
- }
- err = dialupUSB0()
- if err != nil {
- baseapp.Logger.Errorf("[%s] 拨号连接\"eth2\"时发生错误: %v!!", MODULE_NAME, err)
- return false
- }
- ipv4, mask, err := getUSB0Addr()
- if err != nil {
- baseapp.Logger.Errorf("[%s] 读取\"eth2\"地址时发生错误: %v!!", MODULE_NAME, err)
- return false
- }
- baseapp.Logger.Infof("[%s] \"eth2\"分配的地址: %s/%s", MODULE_NAME, ipv4, mask)
- exitCh2 = make(chan struct{})
- wg2.Add(1)
- go func() { // 启动携程守护"eth2"网卡上的 "udhcpc"后台服务进程
- defer wg2.Done()
- monitorUSB0Udhcpc(exitCh2)
- }()
- isRunning2 = true
- return isRunning2
- }
- // 从4G网络断开连接
- func Stop4GNetwork() {
- mu3.Lock()
- defer mu3.Unlock()
- if !isRunning2 {
- return
- }
- close(exitCh2)
- wg2.Wait() // 等待守护"eth2"网卡上的 "udhcpc"后台服务进程的携程退出
- bExists, _ := udhcpcUSB0Exists()
- if bExists {
- killUSB0Udhcpc()
- }
- isRunning2 = false
- }
|