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 聊聊, 查看更多联系方式