1 /// 2 module modbus.exception; 3 4 import std.string : format; 5 6 enum MINIMUM_MODBUS_MSG_LENGTH = 5; 7 8 /// 9 class ModbusException : Exception 10 { 11 /// 12 this(string msg, string file=__FILE__, size_t line=__LINE__) 13 @nogc @safe pure nothrow 14 { super(msg, file, line); } 15 } 16 17 /// 18 class ModbusDevException : ModbusException 19 { 20 /// 21 ulong dev; 22 /// 23 ubyte fnc; 24 /// 25 this(ulong dev, ubyte fnc, string msg, string file=__FILE__, size_t line=__LINE__) 26 { 27 this.dev = dev; 28 this.fnc = fnc; 29 super(msg, file, line); 30 } 31 } 32 33 /// 34 class CheckCRCException : ModbusDevException 35 { 36 /// 37 this(ulong dev, ubyte fnc, string file=__FILE__, size_t line=__LINE__) 38 { 39 super(dev, fnc, format("dev %d fnc %d(0x%x) recive msg CRC check fails", 40 dev, fnc, fnc), file, line); 41 } 42 } 43 44 /// 45 class FunctionErrorException : ModbusDevException 46 { 47 /// 48 ubyte res; 49 /// 50 FunctionErrorCode code; 51 52 /// 53 this(ulong dev, ubyte fnc, ubyte res, ubyte code, 54 string file=__FILE__, size_t line=__LINE__) 55 { 56 this.res = res; 57 this.code = cast(FunctionErrorCode)code; 58 59 super(dev, fnc, format("dev %d fnc %d(0x%x) recive fnc %d(0x%x) with exception code %s (%d)", 60 dev, fnc, fnc, res, res, code, code), file, line); 61 } 62 } 63 64 /// 65 class ReadDataLengthException : ModbusDevException 66 { 67 size_t expected, responseLength; 68 /// 69 this(ulong dev, ubyte fnc, size_t exp, size_t res, 70 string file=__FILE__, size_t line=__LINE__) 71 { 72 expected = exp; 73 responseLength = res; 74 super(dev, fnc, format("dev %d fnc to %d(0x%x) recieves wrong"~ 75 " count of bytes (%d != expected %d or more what %d)", 76 dev, fnc, fnc, res, exp, MINIMUM_MODBUS_MSG_LENGTH), file, line); 77 } 78 } 79 80 /// 81 enum FunctionErrorCode : ubyte 82 { 83 ILLEGAL_FUNCTION = 1, /// 1 84 ILLEGAL_DATA_ADDRESS = 2, /// 2 85 ILLEGAL_DATA_VALUE = 3, /// 3 86 SLAVE_DEVICE_FAILURE = 4, /// 4 87 ACKNOWLEDGE = 5, /// 5 88 SLAVE_DEVICE_BUSY = 6, /// 6 89 MEMORY_PARITY_ERROR = 8, /// 8 90 GATEWAY_PATH_UNAVAILABLE = 0xA, /// 0xA 91 GATEWAY_TARGET_DEVICE_FAILED_TO_RESPOND = 0xB, /// 0xB 92 } 93 94 private version (modbus_use_prealloc_exceptions) 95 { 96 __gshared 97 { 98 auto preallocModbusException = new ModbusException("many args"); 99 auto preallocCheckCRCException = new CheckCRCException(0, 0); 100 auto preallocReadDataLengthException = new ReadDataLengthException(0,0,0,0); 101 auto preallocFunctionErrorException = new FunctionErrorException(0,0,0,0); 102 } 103 } 104 105 /// Returns: preallocated exception with new values of fields 106 ModbusException modbusException()(string msg, string file=__FILE__, size_t line=__LINE__) 107 { 108 version (modbus_use_prealloc_exceptions) 109 { 110 preallocModbusException.msg = msg; 111 preallocModbusException.file = file; 112 preallocModbusException.line = line; 113 return preallocModbusException; 114 } 115 else return new ModbusException(msg, file, line); 116 } 117 118 /// Returns: preallocated exception with new values of fields 119 CheckCRCException checkCRCException()(ulong dev, ubyte fnc, 120 string file=__FILE__, size_t line=__LINE__) 121 { 122 version (modbus_use_prealloc_exceptions) 123 { 124 preallocCheckCRCException.msg = "check CRC fails"; 125 preallocCheckCRCException.dev = dev; 126 preallocCheckCRCException.fnc = fnc; 127 preallocCheckCRCException.file = file; 128 preallocCheckCRCException.line = line; 129 return preallocCheckCRCException; 130 } 131 else return new CheckCRCException(dev, fnc, file, line); 132 } 133 134 /// Returns: preallocated exception with new values of fields 135 FunctionErrorException functionErrorException()(ulong dev, ubyte fnc, ubyte res, ubyte code, 136 string file=__FILE__, size_t line=__LINE__) 137 { 138 version (modbus_use_prealloc_exceptions) 139 { 140 preallocFunctionErrorException.msg = "error while read function response"; 141 preallocFunctionErrorException.dev = dev; 142 preallocFunctionErrorException.fnc = fnc; 143 preallocFunctionErrorException.res = res; 144 preallocFunctionErrorException.code = cast(FunctionErrorCode)code; 145 preallocFunctionErrorException.file = file; 146 preallocFunctionErrorException.line = line; 147 return preallocFunctionErrorException; 148 } 149 else return new FunctionErrorException(dev, fnc, res, code, file, line); 150 } 151 152 /// Returns: preallocated exception with new values of fields 153 ReadDataLengthException readDataLengthException()(ulong dev, ubyte fnc, size_t exp, size_t res, 154 string file=__FILE__, size_t line=__LINE__) 155 { 156 version (modbus_use_prealloc_exceptions) 157 { 158 preallocReadDataLengthException.msg = "error while read function response: wrong length"; 159 preallocReadDataLengthException.dev = dev; 160 preallocReadDataLengthException.fnc = fnc; 161 preallocReadDataLengthException.expected = exp; 162 preallocReadDataLengthException.responseLength = res; 163 preallocReadDataLengthException.file = file; 164 preallocReadDataLengthException.line = line; 165 return preallocReadDataLengthException; 166 } 167 else return new ReadDataLengthException(dev, fnc, exp, res, file, line); 168 }