Introduce the notFoundError struct to provide more detailed error messages for missing handlers like alarms, JSON operations, and payload types. Update error handling to leverage the new custom type and use errors.As for better flexibility. Additionally, update module imports to version v2 in relevant files.
143 lines
3.4 KiB
Go
143 lines
3.4 KiB
Go
package n9m
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net"
|
|
)
|
|
|
|
type notFoundError struct {
|
|
message string
|
|
}
|
|
|
|
func (e *notFoundError) Error() string {
|
|
return fmt.Sprintf("not found %s", e.message)
|
|
}
|
|
|
|
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 ¬FoundError{
|
|
message: fmt.Sprintf("alarm %d", params.AlarmType),
|
|
}
|
|
}
|
|
|
|
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")
|
|
}
|
|
|
|
var nfErr *notFoundError
|
|
if err = pack.handleAlarm(); err == nil || errors.As(err, &nfErr) {
|
|
return
|
|
}
|
|
|
|
var processFunc ProcessFunc
|
|
var ok bool
|
|
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),
|
|
}
|
|
}
|
|
|
|
return processFunc(pack, pack.pack)
|
|
}
|
|
|
|
func (pack *SmartPackage) handle() (err error) {
|
|
var nfErr *notFoundError
|
|
if err = pack.handleJson(); err == nil || errors.As(err, &nfErr) {
|
|
return
|
|
}
|
|
|
|
var processFunc ProcessFunc
|
|
var ok bool
|
|
if processFunc, ok = pack.payloadProcess[pack.pack.PayloadType]; !ok {
|
|
return ¬FoundError{
|
|
message: fmt.Sprintf("payload type %d", pack.pack.PayloadType),
|
|
}
|
|
}
|
|
|
|
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)
|
|
}
|