Logic Xử Lý TeamsACS cho Sự Kiện BootStrap - chơi bắn cá

/imgposts/b68w33sb.jpg

Logic xử lý sự kiện BootStrap của TeamsACS thực tế tương tự như logic xử lý sự kiện PERIODIC, chỉ khác biệt ở chỗ có thêm quy trình xử lý UpdateManagementAuthInfo.

1err = cpe.UpdateManagementAuthInfo("bootstrap-session-"+common.UUID(), 1000, false)

Logic chính chơi bắn cá là ACS gửi username và password dùng để xác thực tới CPE.

  • Username sử dụng trực tiếp mã số sê-ri (sn), không tuân theo định dạng quy định trong giao thức TR069.
  • Password được tạo ra dựa trên một logic cụ thể cần tìm hiểu thêm.
 1func (c *CwmpCpe) UpdateManagementAuthInfo(session string, timeout int, hp bool) error {
 2    return c.SendCwmpEventData(models.CwmpEventData{
 3        Session: session,
 4        Sn:      c.Sn,
 5        Message: &cwmp.SetParameterValues{
 6            ID:     session,
 7            Name:   "",
 8            NoMore: 0,
 9            Params: map[string]cwmp.ValueStruct{
10                "Device.ManagementServer.ConnectionRequestUsername": {
11                    Type:  "xsd:string",
12                    Value: c.Sn,
13                },
14                "Device.ManagementServer.ConnectionRequestPassword": {
15                    Type:  "xsd:string",
16                    Value: app.GetTr069SettingsStringValue("CpeConnectionRequestPassword"),
17                },
18            },
19        },
20    }, timeout, hp)
21}
 1// SendCwmpEventData gửi một sự kiện Cwmp
 2func (c *CwmpCpe) SendCwmpEventData(data models.CwmpEventData, timeoutMsec int, hp bool) error {
 3    select {
 4    case c.getQueue(hp) <- data:
 5        return nil
 6    case <-time.After(time.Millisecond * time.Duration(timeoutMsec)):
 7        return errors.New("kênh sự kiện cwmp đầy, thời gian chờ đã hết")
 8    }
 9}
10
11func (c *CwmpCpe) getQueue(hp bool) chan models.CwmpEventData {
12    var que = c.cwmpQueueMap
13    if hp {
14        que = c.cwmpHPQueueMap
15    }
16    return que
17}
18
19type CwmpCpe struct {
20    Sn               string                 `json:"sn"`
21    OUI              string                 `json:"oui"`
22    taskTags         []string
23    SoftwareVersion  string                `json:"software_version"`
24    Manufacturer     string                `json:"manufacturer"`
25    ProductClass     string                `json:"product_class"`
26    cwmpQueueMap     chan models.CwmpEventData
27    cwmpHPQueueMap   chan models.CwmpEventData
28    LastInform       *cwmp.Inform         `json:"latest_message"`
29    LastUpdate       time.Time            `json:"last_update"`
30    LastDataNotify   time.Time            `json:"last_data_notify"`
31    IsRegister       bool                 `json:"is_register"`
32}
33
34// RecvCwmpEventData nhận một sự kiện Cwmp
35func (c *CwmpCpe) RecvCwmpEventData(timeoutMsec int, hp bool) (data *models.CwmpEventData, err error) {
36    select {
37    case _data := <-c.getQueue(hp):
38        return &_data, nil
39    case <-time.After(time.Millisecond * time.Duration(timeoutMsec)):
40        return nil, errors.New("thời gian chờ đọc kênh sự kiện cwmp đã hết")
41    }
42}

Việc gọi RecvCwmpEventData diễn ra trong tệp tr069/handlers.go:

 1// Khi CPE gửi tin nhắn rỗng, kiểm tra hàng đợi tác vụ CPE
 2lastestSn := s.GetLatestCookieSn(c)
 3if lastestSn == "" {
 4    return noContentResp(c)
 5}
 6cpe := app.GApp().CwmpTable().GetCwmpCpe(lastestSn)
 7
 8// Trước tiên xử lý các tác vụ đã đặt trước
 9ptask, err := cpe.GetLatestCwmpPresetTask()
10if err == nil && ptask != nil && len(ptask.Request) > 0 {
11    return xmlCwmpMessage(c, []byte(ptask.Request))
12}
13
14// Lấy tác vụ từ hàng đợi
15msg, err := cpe.RecvCwmpEventData(1000, true)
16if err != nil {
17    msg, _ = cpe.RecvCwmpEventData(1000, false)
18}
19if msg != nil {
20    if msg.Session != "" {
21        events.PubEventCwmpSuperviseStatus(lastestSn, msg.Session, "info",
22            fmt.Sprintf("Gửi Cwmp %s Tin nhắn %s", msg.Message.GetName(), common.ToJson(msg.Message)))
23    }
24    return xmlCwmpMessage(c, msg.Message.CreateXML())
25}
1// GetTr069SettingsStringValue Lấy giá trị chuỗi thiết lập TR069
2func (a *Application) GetTr069SettingsStringValue(name string) string {
3    return a.GetSettingsStringValue("tr069", name)
4}
 1> grep CpeConnectionRequestPassword -r ./
 2./app/constant.go:   ConfigCpeConnectionRequestPassword = "CpeConnectionRequestPassword"
 3./app/constant.go:   ConfigCpeConnectionRequestPassword,
 4./app/cwmp.go:                 Value: app.GetTr069SettingsStringValue("CpeConnectionRequestPassword"),
 5./app/cwmp.go:     ConfigCpeConnectionRequestPassword: a.GetTr069SettingsStringValue(ConfigCpeConnectionRequestPassword),
 6./app/initdb.go:        case ConfigCpeConnectionRequestPassword:
 7./app/initdb.go:            checkConfig(sortid, "tr069", ConfigCpeConnectionRequestPassword, "teamsacscpepassword", "Mật khẩu xác thực kết nối CPE, được cung cấp cho TeamsACS để truy cập CPE")
 8./assets/static/views/settings.js:            name: "CpeConnectionRequestPassword",
 9./assets/static/views/settings.min.js:name:"TR069AccessPassword",labelPosition:"top",label:tr("settings","TR069 access password"),bottomLabel:tr("settings","Teamsacs TR069 access password, It is provided to CPE to access TeamsACS")},{view:"text",name:"CpeConnectionRequestPassword",labelPosition:"top",label:tr("settings","CPE Connection authentication password"),bottomLabel:tr("settings","tr069 The authentication password used when the server connects to cpe")},{view:"template",css:"form-desc",height:200,borderless:!0,src:"/admin/settings/tr069/quickset"}]}]}};
10./controllers/supervise/cwmp.go:    isok, err := cwmp.ConnectionRequestAuth(dev.Sn, app.GApp().GetTr069SettingsStringValue("CpeConnectionRequestPassword"), dev.CwmpUrl)

Tuy nhiên, tại đây có một vài câu hỏi cần làm rõ:

  • Tại sao chỉ khi ACS nhận được tin nhắn rỗng thì mới kiểm tra hàng đợi tin nhắn? Tại sao không xử lý ngay hoặc xử lý bất đồng bộ?
  • Lợi ích của việc sử dụng channel trong Go so với dịch vụ hàng đợi thông thường là gì?
  • Cơ chế tạo mật khẩu hoạt động như thế nào?