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) }