@@ -1145,6 +1145,43 @@ local function parse_packet_subscribe(ptype, flags, input)
1145
1145
return packet
1146
1146
end
1147
1147
1148
+ -- SUBACK return codes/reason code strings
1149
+ -- DOC: Table 3‑8 - Subscribe Reason Codes
1150
+ local suback_rc = {
1151
+ [0x00 ] = " Granted QoS 0" ,
1152
+ [0x01 ] = " Granted QoS 1" ,
1153
+ [0x02 ] = " Granted QoS 2" ,
1154
+ [0x80 ] = " Unspecified error" ,
1155
+ [0x83 ] = " Implementation specific error" ,
1156
+ [0x87 ] = " Not authorized" ,
1157
+ [0x8F ] = " Topic Filter invalid" ,
1158
+ [0x91 ] = " Packet Identifier in use" ,
1159
+ [0x97 ] = " Quota exceeded" ,
1160
+ [0x9E ] = " Shared Subscriptions not supported" ,
1161
+ [0xA1 ] = " Subscription Identifiers not supported" ,
1162
+ [0xA2 ] = " Wildcard Subscriptions not supported" ,
1163
+ }
1164
+ protocol5 .suback_rc = suback_rc
1165
+
1166
+ --- Parsed SUBACK packet metatable
1167
+ local suback_packet_mt = {
1168
+ __tostring = protocol .packet_tostring , -- packet-to-human-readable-string conversion metamethod using protocol.packet_tostring()
1169
+ reason_strings = function (self ) -- Returns reason strings for the SUBACK packet according to its rc field
1170
+ local human_readable = {}
1171
+ for i , rc in ipairs (self .rc ) do
1172
+ local reason_string = suback_rc [rc ]
1173
+ if reason_string then
1174
+ human_readable [i ] = reason_string
1175
+ else
1176
+ human_readable [i ] = " Unknown: " .. tostring (rc )
1177
+ end
1178
+ end
1179
+ return human_readable
1180
+ end ,
1181
+ }
1182
+ suback_packet_mt .__index = suback_packet_mt
1183
+ protocol5 .suback_packet_mt = suback_packet_mt
1184
+
1148
1185
-- Parse SUBACK packet, DOC: 3.9 SUBACK – Subscribe acknowledgement
1149
1186
local function parse_packet_suback (ptype , flags , input )
1150
1187
-- DOC: 3.9.1 SUBACK Fixed Header
@@ -1158,7 +1195,7 @@ local function parse_packet_suback(ptype, flags, input)
1158
1195
return false , packet_type [ptype ].. " : failed to parse packet_id: " .. err
1159
1196
end
1160
1197
-- DOC: 3.9.2.1 SUBACK Properties
1161
- local packet = setmetatable ({type = ptype , packet_id = packet_id }, packet_mt )
1198
+ local packet = setmetatable ({type = ptype , packet_id = packet_id }, suback_packet_mt )
1162
1199
local ok
1163
1200
ok , err = parse_properties (ptype , read_data , input , packet )
1164
1201
if not ok then
@@ -1177,7 +1214,7 @@ local function parse_packet_suback(ptype, flags, input)
1177
1214
if not next (rcs ) then
1178
1215
return false , packet_type [ptype ].. " : expecting at least one reason code"
1179
1216
end
1180
- packet .rc = rcs -- TODO: reason codes table somewhere should be placed?
1217
+ packet .rc = rcs
1181
1218
return packet
1182
1219
end
1183
1220
@@ -1218,6 +1255,38 @@ local function parse_packet_unsubscribe(ptype, flags, input)
1218
1255
return packet
1219
1256
end
1220
1257
1258
+ -- UNSUBACK Reason Codes
1259
+ -- DOC[2]: Table 3‑9 - Unsubscribe Reason Codes
1260
+ local unsuback_rc = {
1261
+ [0x00 ] = " Success" ,
1262
+ [0x11 ] = " No subscription existed" ,
1263
+ [0x80 ] = " Unspecified error" ,
1264
+ [0x83 ] = " Implementation specific error" ,
1265
+ [0x87 ] = " Not authorized" ,
1266
+ [0x8F ] = " Topic Filter invalid" ,
1267
+ [0x91 ] = " Packet Identifier in use" ,
1268
+ }
1269
+ protocol5 .unsuback_rc = unsuback_rc
1270
+
1271
+ --- Parsed UNSUBACK packet metatable
1272
+ local unsuback_packet_mt = {
1273
+ __tostring = protocol .packet_tostring , -- packet-to-human-readable-string conversion metamethod using protocol.packet_tostring()
1274
+ reason_strings = function (self ) -- Returns reason strings for the UNSUBACK packet according to its rc field
1275
+ local human_readable = {}
1276
+ for i , rc in ipairs (self .rc ) do
1277
+ local reason_string = unsuback_rc [rc ]
1278
+ if reason_string then
1279
+ human_readable [i ] = reason_string
1280
+ else
1281
+ human_readable [i ] = " Unknown: " .. tostring (rc )
1282
+ end
1283
+ end
1284
+ return human_readable
1285
+ end ,
1286
+ }
1287
+ unsuback_packet_mt .__index = unsuback_packet_mt
1288
+ protocol5 .unsuback_packet_mt = unsuback_packet_mt
1289
+
1221
1290
-- Parse UNSUBACK packet, DOC: 3.11 UNSUBACK – Unsubscribe acknowledgement
1222
1291
local function parse_packet_unsuback (ptype , flags , input )
1223
1292
-- DOC: 3.11.1 UNSUBACK Fixed Header
@@ -1231,7 +1300,7 @@ local function parse_packet_unsuback(ptype, flags, input)
1231
1300
return false , packet_type [ptype ].. " : failed to parse packet_id: " .. err
1232
1301
end
1233
1302
-- 3.11.2.1 UNSUBACK Properties
1234
- local packet = setmetatable ({type = ptype , packet_id = packet_id }, packet_mt )
1303
+ local packet = setmetatable ({type = ptype , packet_id = packet_id }, unsuback_packet_mt )
1235
1304
local ok
1236
1305
ok , err = parse_properties (ptype , read_data , input , packet )
1237
1306
if not ok then
@@ -1272,18 +1341,67 @@ local function parse_packet_pingresp(ptype, flags, input_)
1272
1341
return setmetatable ({type = ptype , properties = {}, user_properties = {}}, packet_mt )
1273
1342
end
1274
1343
1344
+ -- DISCONNECT reason codes
1345
+ -- DOC: Table 3‑10 – Disconnect Reason Code values
1346
+ local disconnect_rc = {
1347
+ [0x00 ] = " Normal disconnection" ,
1348
+ [0x04 ] = " Disconnect with Will Message" ,
1349
+ [0x80 ] = " Unspecified error" ,
1350
+ [0x81 ] = " Malformed Packet" ,
1351
+ [0x82 ] = " Protocol Error" ,
1352
+ [0x83 ] = " Implementation specific error" ,
1353
+ [0x87 ] = " Not authorized" ,
1354
+ [0x89 ] = " Server busy" ,
1355
+ [0x8B ] = " Server shutting down" ,
1356
+ [0x8D ] = " Keep Alive timeout" ,
1357
+ [0x8E ] = " Session taken over" ,
1358
+ [0x8F ] = " Topic Filter invalid" ,
1359
+ [0x90 ] = " Topic Name invalid" ,
1360
+ [0x93 ] = " Receive Maximum exceeded" ,
1361
+ [0x94 ] = " Topic Alias invalid" ,
1362
+ [0x95 ] = " Packet too large" ,
1363
+ [0x96 ] = " Message rate too high" ,
1364
+ [0x97 ] = " Quota exceeded" ,
1365
+ [0x98 ] = " Administrative action" ,
1366
+ [0x99 ] = " Payload format invalid" ,
1367
+ [0x9A ] = " Retain not supported" ,
1368
+ [0x9B ] = " QoS not supported" ,
1369
+ [0x9C ] = " Use another server" ,
1370
+ [0x9D ] = " Server moved" ,
1371
+ [0x9E ] = " Shared Subscriptions not supported" ,
1372
+ [0x9F ] = " Connection rate exceeded" ,
1373
+ [0xA0 ] = " Maximum connect time" ,
1374
+ [0xA1 ] = " Subscription Identifiers not supported" ,
1375
+ [0xA2 ] = " Wildcard Subscriptions not supported" ,
1376
+ }
1377
+ protocol5 .disconnect_rc = disconnect_rc
1378
+
1379
+ --- Parsed DISCONNECT packet metatable
1380
+ local disconnect_packet_mt = {
1381
+ __tostring = protocol .packet_tostring , -- packet-to-human-readable-string conversion metamethod using protocol.packet_tostring()
1382
+ reason_string = function (self ) -- Returns reason string for the DISCONNECT packet according to its rc field
1383
+ local reason_string = disconnect_rc [self .rc ]
1384
+ if not reason_string then
1385
+ reason_string = " Unknown: " .. self .rc
1386
+ end
1387
+ return reason_string
1388
+ end ,
1389
+ }
1390
+ disconnect_packet_mt .__index = disconnect_packet_mt
1391
+ protocol5 .disconnect_packet_mt = disconnect_packet_mt
1392
+
1275
1393
-- Parse DISCONNECT packet, DOC: 3.14 DISCONNECT – Disconnect notification
1276
1394
local function parse_packet_disconnect (ptype , flags , input )
1277
1395
-- DOC: 3.14.1 DISCONNECT Fixed Header
1278
1396
if flags ~= 0 then -- Reserved
1279
1397
return false , packet_type [ptype ].. " : unexpected flags value: " .. flags
1280
1398
end
1281
1399
local read_data = input .read_func
1282
- local packet = setmetatable ({type = ptype , rc = 0 , properties = {}, user_properties = {}}, packet_mt )
1400
+ local packet = setmetatable ({type = ptype , rc = 0 , properties = {}, user_properties = {}}, disconnect_packet_mt )
1283
1401
if input .available > 0 then
1284
1402
-- DOC: 3.14.2 DISCONNECT Variable Header
1285
1403
-- DOC: 3.14.2.1 Disconnect Reason Code
1286
- local rc , err = parse_uint8 (read_data ) -- TODO: reason codes table?
1404
+ local rc , err = parse_uint8 (read_data )
1287
1405
if not rc then
1288
1406
return false , packet_type [ptype ].. " : failed to parse rc: " .. err
1289
1407
end
0 commit comments