2025-02-22 18:15:03 +00:00
|
|
|
package n9m
|
|
|
|
|
|
|
|
import (
|
2025-02-23 08:51:16 +00:00
|
|
|
"errors"
|
2025-02-22 18:15:03 +00:00
|
|
|
"fmt"
|
|
|
|
"net"
|
|
|
|
)
|
|
|
|
|
2025-02-23 08:51:16 +00:00
|
|
|
type notFoundError struct {
|
|
|
|
message string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *notFoundError) Error() string {
|
|
|
|
return fmt.Sprintf("not found %s", e.message)
|
|
|
|
}
|
|
|
|
|
2025-02-22 18:15:03 +00:00
|
|
|
func NewSmartPackage(conn net.Conn) *SmartPackage {
|
|
|
|
return &SmartPackage{
|
|
|
|
pack: Package{},
|
|
|
|
conn: conn,
|
|
|
|
buff: make([]byte, 1024),
|
|
|
|
payloadProcess: make(map[PayloadType]ProcessFunc),
|
|
|
|
jsonProcess: make(map[string]ProcessFunc),
|
|
|
|
alarmProcess: make(map[AlarmType]AlarmProcessFunc),
|
|
|
|
Storage: make(map[string]interface{}),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (pack *SmartPackage) AddPayloadHandler(payloadType PayloadType, processFunc ProcessFunc) {
|
|
|
|
pack.payloadProcess[payloadType] = processFunc
|
|
|
|
}
|
|
|
|
|
|
|
|
func (pack *SmartPackage) AddJSONHandler(module, operation string, processFunc ProcessFunc) {
|
|
|
|
pack.jsonProcess[fmt.Sprintf("%s:%s", module, operation)] = processFunc
|
|
|
|
}
|
|
|
|
|
|
|
|
func (pack *SmartPackage) AddAlarmHandler(alarmType AlarmType, processFunc AlarmProcessFunc) {
|
|
|
|
pack.alarmProcess[alarmType] = processFunc
|
|
|
|
}
|
|
|
|
|
|
|
|
func (pack *SmartPackage) handleAlarm() (err error) {
|
|
|
|
if !(pack.pack.PayloadType == PayloadTypeData && pack.pack.Payload.Module == "EVEM" && pack.pack.Payload.Operation == "SENDALARMINFO") {
|
|
|
|
return fmt.Errorf("invalid payload type or operation for alarm handling")
|
|
|
|
}
|
|
|
|
|
|
|
|
var params SendAlarmInfoParameters
|
|
|
|
if err = pack.pack.GetParametersAs(¶ms); err != nil {
|
|
|
|
return fmt.Errorf("invalid payload")
|
|
|
|
}
|
|
|
|
|
|
|
|
var processFunc AlarmProcessFunc
|
|
|
|
var ok bool
|
|
|
|
if processFunc, ok = pack.alarmProcess[params.AlarmType]; !ok {
|
2025-02-23 08:51:16 +00:00
|
|
|
return ¬FoundError{
|
|
|
|
message: fmt.Sprintf("alarm %d", params.AlarmType),
|
|
|
|
}
|
2025-02-22 18:15:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var response SendAlarmInfoResponse
|
|
|
|
|
|
|
|
response.ErrorCode = 0
|
|
|
|
response.AlarmType = params.AlarmType
|
|
|
|
response.CommandType = params.CommandType
|
|
|
|
response.AlarmUID = params.AlarmUID
|
|
|
|
response.NumberOfRestarts = params.NumberOfRestarts
|
|
|
|
response.InstructionSerial = params.InstructionSerial
|
|
|
|
|
|
|
|
return processFunc(pack, pack.pack, response)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (pack *SmartPackage) handleJson() (err error) {
|
|
|
|
if pack.pack.PayloadType != PayloadTypeData {
|
|
|
|
return fmt.Errorf("invalid json payload type")
|
|
|
|
}
|
|
|
|
|
2025-02-23 08:51:16 +00:00
|
|
|
var nfErr *notFoundError
|
|
|
|
if err = pack.handleAlarm(); err == nil || errors.As(err, &nfErr) {
|
2025-02-22 18:15:03 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
var processFunc ProcessFunc
|
|
|
|
var ok bool
|
2025-02-23 08:51:16 +00:00
|
|
|
var key = fmt.Sprintf("%s:%s", pack.pack.Payload.Module, pack.pack.Payload.Operation)
|
|
|
|
if processFunc, ok = pack.jsonProcess[key]; !ok {
|
|
|
|
return ¬FoundError{
|
|
|
|
message: fmt.Sprintf("json %s", key),
|
|
|
|
}
|
2025-02-22 18:15:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return processFunc(pack, pack.pack)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (pack *SmartPackage) handle() (err error) {
|
2025-02-23 08:51:16 +00:00
|
|
|
var nfErr *notFoundError
|
|
|
|
if err = pack.handleJson(); err == nil || errors.As(err, &nfErr) {
|
2025-02-22 18:15:03 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
var processFunc ProcessFunc
|
|
|
|
var ok bool
|
|
|
|
if processFunc, ok = pack.payloadProcess[pack.pack.PayloadType]; !ok {
|
2025-02-23 08:51:16 +00:00
|
|
|
return ¬FoundError{
|
|
|
|
message: fmt.Sprintf("payload type %d", pack.pack.PayloadType),
|
|
|
|
}
|
2025-02-22 18:15:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return processFunc(pack, pack.pack)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (pack *SmartPackage) handleLoop() (err error) {
|
|
|
|
for pack.pack.ReadPackage() {
|
|
|
|
if err = pack.handle(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (pack *SmartPackage) Handle() (err error) {
|
|
|
|
if err = pack.handleLoop(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
var rn int
|
|
|
|
|
|
|
|
if rn, err = pack.conn.Read(pack.buff); err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
pack.pack.AddToAccum(pack.buff[:rn])
|
|
|
|
|
|
|
|
return pack.handleLoop()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (pack *SmartPackage) GetPackage() Package {
|
|
|
|
return pack.pack
|
|
|
|
}
|
|
|
|
|
|
|
|
func (pack *SmartPackage) Write(data []byte) (int, error) {
|
|
|
|
return pack.conn.Write(data)
|
|
|
|
}
|