Introduced the SmartPackage struct to simplify and centralize logic for handling various payloads, including JSON and alarms. Moved specific handlers into dedicated functions and utilized maps for dynamic process function assignment. Improved error handling and modularity for better scalability and maintainability.
125 lines
3.0 KiB
Go
125 lines
3.0 KiB
Go
package n9m
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
)
|
|
|
|
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 {
|
|
return fmt.Errorf("unhanled alarm")
|
|
}
|
|
|
|
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")
|
|
}
|
|
|
|
if err = pack.handleAlarm(); err == nil {
|
|
return
|
|
}
|
|
|
|
var processFunc ProcessFunc
|
|
var ok bool
|
|
if processFunc, ok = pack.jsonProcess[fmt.Sprintf("%s:%s", pack.pack.Payload.Module, pack.pack.Payload.Operation)]; !ok {
|
|
return fmt.Errorf("unhanled operation")
|
|
}
|
|
|
|
return processFunc(pack, pack.pack)
|
|
}
|
|
|
|
func (pack *SmartPackage) handle() (err error) {
|
|
if err = pack.handleJson(); err == nil {
|
|
return
|
|
}
|
|
|
|
var processFunc ProcessFunc
|
|
var ok bool
|
|
if processFunc, ok = pack.payloadProcess[pack.pack.PayloadType]; !ok {
|
|
return fmt.Errorf("unhanled payload type")
|
|
}
|
|
|
|
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)
|
|
}
|