Tuesday, October 4, 2016

Sample UDP Server / Client Code for NodeMCU ESP8266

This is code that lets you start talking over UDP on the NodeMCU.

-- UDP Hello Announce v3
--local M = {}
M = {}

M.port = 8988
M.myip = nil
M.sock = nil

--M.announce = 

M.isInitted = false

function M.init()
  print("Initting...")
  M.sock = net.createConnection(net.UDP, 0)
  M.myip = wifi.sta.getip()
  if M.myip == nil then
    print("You need to connect to wifi. Unable to init.")
  else 
    print("My IP: " .. M.myip)
    M.isInitted = true
  end 
end

function M.createAnnounce(jsonTagTable)
  
  -- see if there is a jsontagtable passed in as extra meta
  local jsontag = ""
  if jsonTagTable ~= nil then
    ok, jsontag = pcall(cjson.encode, jsonTagTable)
    if ok then
      --print("Adding jsontagtable" .. jsontag)
    else
      print("failed to encode jsontag!")
    end
  end

  local a = {}
  a.Announce = "i-am-a-client"
  a.Widget = "com-chilipeppr-widget-ina219"
  a.MyDeviceId = "chip:" .. node.chipid() .. "-flash:" .. node.flashid() .. "-mac:" .. wifi.sta.getmac()
  a.JsonTag = jsontag
  
  local ok, json = pcall(cjson.encode, a)
  if ok then
    --print("Encoded json for announce: " .. json)
  else
    print("failed to encode json!")
  end
  return json
end

-- send announce to broadcast addr so spjs 
-- knows of our existence
function M.sendBroadcast()
  if M.isInitted == false then
    print("You must init first.")
    return 
  end
  
  local bip = wifi.sta.getbroadcast()
  --print("Broadcast addr:" .. bip)
  
  print("Sending announce to ip: " .. bip)
  M.sock:connect(M.port, bip)
  M.sock:send(M.createAnnounce())
  M.sock:close()
  
end

function M.setupWifi()
  -- setwifi
  wifi.setmode(wifi.STATION)
  -- longest range is b
  wifi.setphymode(wifi.PHYMODE_B)
  --Connect to access point automatically when in range
  wifi.sta.config("NETGEAR-main", "******")
  wifi.sta.connect()
  
  --register callback
  wifi.sta.eventMonReg(wifi.STA_IDLE, function() print("STATION_IDLE") end)
  --wifi.sta.eventMonReg(wifi.STA_CONNECTING, function() print("STATION_CONNECTING") end)
  wifi.sta.eventMonReg(wifi.STA_WRONGPWD, function() print("STATION_WRONG_PASSWORD") end)
  wifi.sta.eventMonReg(wifi.STA_APNOTFOUND, function() print("STATION_NO_AP_FOUND") end)
  wifi.sta.eventMonReg(wifi.STA_FAIL, function() print("STATION_CONNECT_FAIL") end)
  wifi.sta.eventMonReg(wifi.STA_GOTIP, M.gotip)
  
  --register callback: use previous state
  wifi.sta.eventMonReg(wifi.STA_CONNECTING, function(previous_State)
      if(previous_State==wifi.STA_GOTIP) then 
          print("Station lost connection with access point\n\tAttempting to reconnect...")
      else
          print("STATION_CONNECTING")
      end
  end)
  
  --start WiFi event monitor with default interval
  wifi.sta.eventMonStart(1000)
  
end

function M.gotip()
  print("STATION_GOT_IP")
  M.myip = wifi.sta.getip()
  print("My IP: " .. M.myip)
  M.init()
  M.initUdpServer()
  M.initTcpServer()
  M.sendBroadcast()
end

function M.sendinit()
  -- we need to send a UDP announce packet to every IP
  -- on the subnet to let any possible SPJS know we are
  -- available

  -- iterate thru entire subnet
  M.ipctr = 1
  tmr.alarm(6, 200, tmr.ALARM_SINGLE, M.sendNextHello)

end

function M.sendNextHello()
  
  local i, j = string.find(M.myip, "%.%d+$")
  local prefix = string.sub(M.myip, 0, i)
  local ip = prefix .. M.ipctr
  print("Sending announce to ip: " .. ip)
  M.sock:connect(M.port, ip)
  M.sock:send(M.announce)
  M.sock:close()
  M.ipctr = M.ipctr + 1

  if M.ipctr < 25 then
    tmr.alarm(6, 50, tmr.ALARM_SINGLE, M.sendNextHello)
  end

end

function M.initUdpServer()
  M.udpServer = net.createServer(net.UDP)
  --M.udpServer:on("connection", M.onUdpConnection)
  M.udpServer:on("receive", M.onUdpRecv) 
  M.udpServer:listen(8988)
  print("UDP Server started on port 8988")
end

function M.onUdpConnection(sck)
  print("UDP connection.")
  --ip, port = sck:getpeer()
  --print("UDP connection. from: " .. ip)
end

function M.onUdpRecv(sck, data)
  print("UDP Recvd. data: " .. data)
end

function M.initTcpServer()
  M.tcpServer = net.createServer(net.TCP)
  M.tcpServer:listen(8988, M.onTcpListen)
  
  print("TCP Server started on port 8988")
end

function M.onTcpListen(conn)
  conn:on("receive", M.onTcpRecv)
end

function M.onTcpConnection(sck)
  print("TCP connection.")
  --ip, port = sck:getpeer()
  --print("UDP connection. from: " .. ip)
end

function M.onTcpRecv(sck, data)
  local peer = sck:getpeer()
  print("TCP Recvd. data: " .. data .. ", Peer:" .. peer)
end

--return M

M.setupWifi()
M.init()
--M.initServer()
--M.sendBroadcast()

No comments:

Post a Comment