Compare commits
No commits in common. "e014cb2656387a3e9e5055682ccba6d2d068f3c6" and "8e34d4d144f76b79ea51f6218e472e96a1945f54" have entirely different histories.
e014cb2656
...
8e34d4d144
102
mqtt.lua
102
mqtt.lua
|
@ -10,52 +10,32 @@ local safeRead = function (conn, n)
|
||||||
end
|
end
|
||||||
|
|
||||||
local readVarint = function (conn, first_byte)
|
local readVarint = function (conn, first_byte)
|
||||||
local b, data, err
|
local b, err
|
||||||
if first_byte == nil then
|
if first_byte == nil then
|
||||||
data, err = safeRead(conn, 1)
|
b, err = safeRead(conn, 1)
|
||||||
if err ~= nil then
|
|
||||||
return nil, err
|
|
||||||
end
|
|
||||||
|
|
||||||
b = string.byte(data)
|
|
||||||
else
|
else
|
||||||
b = first_byte
|
b = first_byte
|
||||||
end
|
end
|
||||||
|
|
||||||
local n, s = 0, 0
|
local n, s = 0, 0
|
||||||
while b & 0x80 == 0x80 do
|
while err == nil and b & 0x80 == 0x80 do
|
||||||
if s > 21 then
|
if s > 21 then
|
||||||
return nil, "number too large"
|
return 0, "number too large"
|
||||||
end
|
end
|
||||||
|
|
||||||
n = n + ((b & 0x7F) << s)
|
n = n + ((b & 0x7F) << s)
|
||||||
s = s + 7
|
s = s + 7
|
||||||
|
|
||||||
data, err = safeRead(conn, 1)
|
b, err = safeRead(conn, 1)
|
||||||
if err ~= nil then
|
end
|
||||||
return nil, err
|
|
||||||
end
|
|
||||||
|
|
||||||
b = string.byte(data)
|
if err ~= nil then
|
||||||
|
return n, err
|
||||||
end
|
end
|
||||||
|
|
||||||
return n + (b << s), nil
|
return n + (b << s), nil
|
||||||
end
|
end
|
||||||
|
|
||||||
local encodeVarint = function (n)
|
|
||||||
if n > 268435455 then
|
|
||||||
return nil, "number too large"
|
|
||||||
end
|
|
||||||
|
|
||||||
local data = ""
|
|
||||||
while n > 127 do
|
|
||||||
data = data .. string.char(0x80 | n & 0x7F)
|
|
||||||
n = n >> 7
|
|
||||||
end
|
|
||||||
|
|
||||||
return data .. string.char(n), nil
|
|
||||||
end
|
|
||||||
|
|
||||||
local MqttClient = {}
|
local MqttClient = {}
|
||||||
|
|
||||||
function mqtt.open (address, port)
|
function mqtt.open (address, port)
|
||||||
|
@ -84,10 +64,6 @@ function MqttClient:new (conn)
|
||||||
end
|
end
|
||||||
|
|
||||||
function MqttClient:handle ()
|
function MqttClient:handle ()
|
||||||
if not (self.is_connecting or self.is_connected) then
|
|
||||||
return "no connection"
|
|
||||||
end
|
|
||||||
|
|
||||||
local data, err = self.conn:safeRead(2)
|
local data, err = self.conn:safeRead(2)
|
||||||
if err ~= nil then
|
if err ~= nil then
|
||||||
return err
|
return err
|
||||||
|
@ -135,27 +111,12 @@ function MqttClient:handle ()
|
||||||
|
|
||||||
self.is_connecting = false
|
self.is_connecting = false
|
||||||
self.is_connected = true
|
self.is_connected = true
|
||||||
elseif ptype & 0xF0 == 0x40 then -- PUBACK
|
elseif ptype == 0x40 then -- PUBACK
|
||||||
-- TODO
|
-- TODO
|
||||||
elseif ptype & 0xF0 == 0xD0 then -- PINGRESP
|
elseif ptype == 0xD0 then -- PINGRESP
|
||||||
|
-- TODO
|
||||||
|
elseif ptype == 0xE0 then -- DISCONNECT
|
||||||
-- TODO
|
-- TODO
|
||||||
elseif ptype & 0xF0 == 0xE0 then -- DISCONNECT
|
|
||||||
if ptype ~= 0xE0 then
|
|
||||||
self:disconnect(0x81)
|
|
||||||
return "malformed packet"
|
|
||||||
end
|
|
||||||
|
|
||||||
self.is_connecting = false
|
|
||||||
self.is_connected = false
|
|
||||||
|
|
||||||
if length > 0 then
|
|
||||||
reason, _ = string.unpack("B", data)
|
|
||||||
if reason ~= 0 then
|
|
||||||
return "disconnect with error"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return "disconnect"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -163,7 +124,7 @@ end
|
||||||
|
|
||||||
function MqttClient:connect (username, password)
|
function MqttClient:connect (username, password)
|
||||||
if self.is_connecting or self.is_connected then
|
if self.is_connecting or self.is_connected then
|
||||||
return "already connected"
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
local length = 13
|
local length = 13
|
||||||
|
@ -177,7 +138,11 @@ function MqttClient:connect (username, password)
|
||||||
flags = flags | 0x40
|
flags = flags | 0x40
|
||||||
end
|
end
|
||||||
|
|
||||||
local data = string.char(0x10) .. encodeVarint(length) .. string.pack("> s2 B B I2 B s2", "MQTT", 5, flags, 0, 0, "")
|
if length > 127 then
|
||||||
|
return "packet size exceeds current implementation capabilities"
|
||||||
|
end
|
||||||
|
|
||||||
|
local data = string.pack("> B B s2 B B I2 B s2", 0x10, length, "MQTT", 5, flags, 0, 0, "")
|
||||||
if username ~= nil then
|
if username ~= nil then
|
||||||
data = data .. string.pack("> s2", username)
|
data = data .. string.pack("> s2", username)
|
||||||
end
|
end
|
||||||
|
@ -200,38 +165,9 @@ function MqttClient:connect (username, password)
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
function MqttClient:publish (topic, payload)
|
|
||||||
if not (self.is_connecting or self.is_connected) then
|
|
||||||
return "no connection"
|
|
||||||
end
|
|
||||||
|
|
||||||
if not topic or #topic == 0 then
|
|
||||||
return "topic is required"
|
|
||||||
end
|
|
||||||
if not payload then
|
|
||||||
payload = ""
|
|
||||||
end
|
|
||||||
|
|
||||||
local flags = 0
|
|
||||||
local length = 3 + #topic + #payload
|
|
||||||
local data = string.char(0x30 | flags) .. encodeVarint(length) .. string.pack("> s2 B", topic, 0) .. payload
|
|
||||||
|
|
||||||
local _, err = self.conn:write(data)
|
|
||||||
if err ~= nil then
|
|
||||||
return err
|
|
||||||
end
|
|
||||||
|
|
||||||
local _, err = self.conn:flush()
|
|
||||||
if err ~= nil then
|
|
||||||
return err
|
|
||||||
end
|
|
||||||
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
function MqttClient:disconnect (reason)
|
function MqttClient:disconnect (reason)
|
||||||
if not (self.is_connecting or self.is_connected) then
|
if not (self.is_connecting or self.is_connected) then
|
||||||
return "no connection"
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
if reason == nil then
|
if reason == nil then
|
||||||
|
|
Loading…
Reference in New Issue