TeamsACS 对于 PERIODIC Event 的处理逻辑

文章目录

    Event 类型的判别

    tr069/handlers.go

    func (s *Tr069Server) processInformEvent(c echo.Context, lastInform *cwmp.Inform) {
    	...
    
    	cpe := app.GApp().CwmpTable().GetCwmpCpe(lastInform.Sn)
    	cpe.CheckRegister(c.RealIP(), lastInform)
    	cpe.UpdateStatus(lastInform)
    	// 通知系统更新数据
    	cpe.NotifyDataUpdate(false)
    
    	log.Info2(fmt.Sprintf("debug: Events: %+v\n", lastInform.Events))
    
    	switch {
    	// 首次接入下发认证配置
    	case lastInform.IsEvent(cwmp.EventBootStrap) && lastInform.RetryCount == 0:
    		...
    	case lastInform.IsEvent(cwmp.EventBoot) && lastInform.RetryCount == 0:
    		...
    	case lastInform.IsEvent(cwmp.EventPeriodic) && lastInform.RetryCount == 0:
    		// here !!
    		err := cpe.CreateCwmpPresetEventTask(app.PeriodicEvent, "")
    		if err != nil {
    			log.Error2("CreateCwmpPresetEventTask error ", zap.String("namespace", "tr069"), zap.Error(err))
    		}
    	case lastInform.IsEvent(cwmp.EventScheduled) && lastInform.RetryCount == 0:
    		...
    	case lastInform.IsEvent(cwmp.EventValueChange) && lastInform.RetryCount == 0:
    		...
    	}
    }
    

    基于 Event 类型创建任务队列

    app/cwmp_preset.go

    顾名思义,CreateCwmpPresetEventTask 根据传过来的 Event 类型,创建对应的计划任务/任务队列。

    从上面的 tr069/handlers.go 中判断 Event 类型的逻辑看,只处理三种类型的 Event:

    • BootStrap
    • Boot
    • Periodic

    且都没有指定 CreateCwmpPresetEventTask 中的 pid 参数。

    确实没有多大意义,因为 pid 不可能预先知道,毕竟是后续人工在 web 管理后台录入的。

    // CreateCwmpPresetEventTask Create scheduled event tasks
    func (c *CwmpCpe) CreateCwmpPresetEventTask(event string, pid string) (err error) {
    	if event == "" {
    		return fmt.Errorf("event is empty")
    	}
    	var presets []models.CwmpPreset
    	query := app.gormDB.Where("event = ?", event)
    	if pid != "" {
    		query = query.Where("id = ?", pid)
    	}
    	err = query.Order("priority asc").Find(&presets).Error
    	if err != nil {
    		return err
    	}
    
    	batch := common.UUID()
    
    	for _, preset := range presets {
    		if !c.MatchTaskTags(preset.TaskTags) {
    			continue
    		}
    		var content models.CwmpPresetContent
    		err = yaml.Unmarshal([]byte(preset.Content), &content)
    		if err != nil {
    			return err
    		}
    
    		// Create a factory settings delivery task
    		if content.FactoryResetConfig != nil && content.FactoryResetConfig.Enabled {
    			err = c.creatFactoryResetConfigDownloadTask(preset.ID, content.FactoryResetConfig, batch, event)
    			if err != nil {
    				log.Errorf("creatFactoryResetConfigDownloadTask: %s", err)
    			}
    		}
    
    		// Create a firmware configuration delivery task
    		if content.FirmwareConfig != nil && content.FirmwareConfig.Enabled {
    			err = c.creatFirmwareConfigDownloadTask(preset.ID, content.FirmwareConfig, batch, event)
    			if err != nil {
    				log.Errorf("creatFirmwareConfigDownloadTask: %s", err)
    			}
    		}
    
    		// Create a script to configure the download task
    		if content.Downloads != nil {
    			for _, download := range content.Downloads {
    				err = c.creatDownloadTask(preset.ID, download, batch, event)
    				if err != nil {
    					log.Errorf("creatDownloadTask: %s", err)
    				}
    			}
    		}
    
    		// Create an upload task
    		if content.Uploads != nil {
    			for _, upload := range content.Uploads {
    				err = c.creatUploadTask(preset.ID, upload, batch, event)
    				if err != nil {
    					log.Errorf("creatUploadTask: %s", err)
    				}
    			}
    		}
    
    		go func() {
    			// Create parameter task
    			if content.SetParameterValues != nil {
    				err = c.creatSetParameterValuesTask(preset.ID, content.SetParameterValues, batch, event)
    				if err != nil {
    					log.Errorf("creatGetParameterValuesTask: %s", err)
    				}
    			}
    			// Create a parameter acquisition task
    			if content.GetParameterValues != nil {
    				err = c.creatGetParameterValuesTask(content.GetParameterValues)
    				if err != nil {
    					log.Errorf("creatGetParameterValuesTask: %s", err)
    				}
    			}
    
    		}()
    	}
    
    	return nil
    }
    

    CreateCwmpPresetEventTask 归属于指定的 cpe

    cpe.CreateCwmpPresetEventTask(app.PeriodicEvent, "")
    

    cpe 由 inform 消息中的 Sn,即设备序列号,查询得到。(但是这里可能有问题,我的 CPE 模拟器 sn 不是 000000,数据库里是!)

    cpe := app.GApp().CwmpTable().GetCwmpCpe(lastInform.Sn)
    

    cwmp_preset 表

    默认是空表,没有任何数据。

    我感觉这个是用于新 CPE 设备连上 ACS 之后,自动获取配置的功能。

    例如,在 web 管理后台,新增一堆规则,然后新设备连上之后,自动执行。

    CREATE TABLE "cwmp_preset" (
    	"id" BIGINT NOT NULL DEFAULT 'nextval(''cwmp_preset_id_seq''::regclass)',
    	"name" TEXT NULL DEFAULT NULL,
    	"priority" BIGINT NULL DEFAULT NULL,
    	"event" TEXT NULL DEFAULT NULL,
    	"sched_policy" TEXT NULL DEFAULT NULL,
    	"sched_key" TEXT NULL DEFAULT NULL,
    	"interval" BIGINT NULL DEFAULT NULL,
    	"content" TEXT NULL DEFAULT NULL,
    	"task_tags" TEXT NULL DEFAULT NULL,
    	"created_at" TIMESTAMPTZ NULL DEFAULT NULL,
    	"updated_at" TIMESTAMPTZ NULL DEFAULT NULL,
    	PRIMARY KEY ("id"),
    	INDEX "idx_cwmp_preset_task_tags" ("task_tags")
    )
    

    对应 model

    models/cwmp.go

    CREATE TABLE "cwmp_preset" (
    	"id" BIGINT NOT NULL DEFAULT 'nextval(''cwmp_preset_id_seq''::regclass)',
    	"name" TEXT NULL DEFAULT NULL,
    	"priority" BIGINT NULL DEFAULT NULL,
    	"event" TEXT NULL DEFAULT NULL,
    	"sched_policy" TEXT NULL DEFAULT NULL,
    	"sched_key" TEXT NULL DEFAULT NULL,
    	"interval" BIGINT NULL DEFAULT NULL,
    	"content" TEXT NULL DEFAULT NULL,
    	"task_tags" TEXT NULL DEFAULT NULL,
    	"created_at" TIMESTAMPTZ NULL DEFAULT NULL,
    	"updated_at" TIMESTAMPTZ NULL DEFAULT NULL,
    	PRIMARY KEY ("id"),
    	INDEX "idx_cwmp_preset_task_tags" ("task_tags")
    )
    

    对应的还有记录历史的表:

    type CwmpPresetTask struct {
    	ID        int64     `json:"id,string"` // 主键 ID
    	PresetId  int64     `json:"preset_id,string" gorm:"index"`
    	Sn        string    `json:"sn" gorm:"index"`
    	Name      string    `json:"name" `
    	Oid       string    `json:"oid" gorm:"index"`
    	Event     string    `json:"event" `
    	Batch     string    `json:"batch" `
    	Onfail    string    `json:"onfail" `
    	Session   string    `json:"session" gorm:"index"`
    	Request   string    `json:"request" `
    	Response  string    `json:"response"`
    	Content   string    `json:"content"`
    	Status    string    `json:"status" gorm:"index"`
    	ExecTime  time.Time `json:"exec_time"` // 执行时间
    	RespTime  time.Time `json:"resp_time"` // 响应时间
    	CreatedAt time.Time `json:"created_at" gorm:"index"`
    	UpdatedAt time.Time `json:"updated_at"`
    }
    

    关于作者 🌱

    我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式