Sunday, 19 July 2020

Nodemcu esp8266 telnet client

The example net example in the nodemcu docs works ok talking to a busybox telnetd, but when trying to talk to an old Linux NetKit (0.17)  in.telnetd running on a bifferboard it chokes on the telnet option negotiation.
The man page for the sever does say
"Because of bugs in the original 4.2 BSD telnet(1), telnetd performs some dubious protocol exchanges" 

So, wading thru RFCs and wireshark captures to fake up the telnet options results in this :

-- tn.lua =====================================

-- TELNET OPTIONS
NUL = string.char(0)
ECHO = string.char(1)
SGA = string.char(3)
ESC = string.char(27)
FLOWCONTROL = string.char(33)
SUB = string.char(250)
WILL = string.char(251)   --fb
WONT = string.char(252)   --fc
DO = string.char(253)     --fd
DONT = string.char(254)   --fe
IAC = string.char(255)    --ff
AYT = string.char(246)  -- ARE YOU THERE
SE = string.char(240)  -- End of subnegotiation
GA = string.char(249) -- GO AHEAD
BRK = string.char(243)  -- BRK
IP = string.char(244) -- INTERUPT PROCESS
DM = string.char(244)  -- DATA MARK

optionsSent = nil 
buffer = ""
hexprint = function(s)
 for z=1,#s  do
    uart.write(0, string.format("/x%x - %d ",string.byte(s,z),string.byte(s,z)))
 end
end


function conff = function(s,...)  return s:format(...) end

telnetOptions =  IAC .. DO .. SGA ..
                 IAC .. WILL .. string.char(24)..
                 IAC .. WILL .. string.char(31) ..
                 IAC .. WILL .. string.char(32) ..
                 IAC .. WONT .. FLOWCONTROL ..
                 IAC .. WILL .. string.char(34) ..
                 IAC .. WILL .. string.char(39) ..
                 IAC .. DO .. string.char(05) ..
                 IAC .. WILL .. string.char(35)
   
--subptions
telnetSubOptions = IAC .. SUB .. string.char(31) .. NUL .. string.char(80) .. NUL .. string.char(24) .. IAC .. SE ..
IAC .. SUB .. string.char(32) .. NUL .. "115200,115200" .. IAC .. SE  ..
IAC .. SUB .. string.char(35) .. NUL .. "ESP8266" .. IAC .. SE .. 
IAC .. SUB .. string.char(39) .. NUL .. "ESP8266" .. IAC .. SE ..
IAC .. SUB .. string.char(24) .. NUL .. "ansi" .. IAC .. SE
      
if IP and LOGIN and PASSWORD then
conn=net.createConnection(net.TCP, false)

conn:on("connection", function(sck, c)
 if DEBUG then print ("*** Connection ***")  end
 optionsSent = 1
 conn:send(telnetOptions)
 if DEBUG then print "** Telnet options SENT ***"  end
end )

conn:on("sent",function(sck,c)
 -- print "**** SENT ***"
 if optionsSent == 1 then
   if DEBUG then print "** Telnet sub options SENT ***" end
   conn:send(telnetSubOptions)
   optionsSent = optionsSent + 1
   end
 end )

conn:on("receive", function(sck, c)
 if DEBUG then print ("*** Receiving ***") end
 

 if string.find(c, IAC .. DO .. string.char(24)) then
  print("DO TERMINAL")
-- conn:send(conff("%c%c%c",IAC,DO,24))
 end
 

 if string.find(c, IAC .. DO .. string.char(32)) then
  print("DO TSPEED")
-- conn:send(conff("%c%c%c",IAC,DO,32))
 end
 

 if string.find(c, IAC .. DO .. string.char(35)) then
   print("DO XDISPLOC")
-- conn:send(conff("%c%c%c",IAC,DO,32))
 end
 

 if string.find(c, IAC .. DO .. string.char(39)) then
  print("DO ENVIRON")
-- conn:send(conff("%c%c%c",IAC,DO,39))
-- conn:send(conff("%c%c%c",IAC,DO,03))
 end
 

  if string.find(c, IAC .. DO .. ECHO ) then 
   conn:send(IAC .. WONT .. ECHO) -- WONT DO ECHO
   print "rec do echo, send wont"
 end   
 

  if string.find(c, IAC .. WILL .. ECHO ) then
  conn:send(IAC .. DO .. ECHO) -- WONT DO ECHO
  print "rec will echo, sending do"
 end  
 

  if string.find(c, IAC .. SUB .. FLOWCONTROL .. NUL ) then 
    print ("REMOTE FLOW CONTROL OFF")
 end  
 

  if string.find(c, IAC .. SUB .. FLOWCONTROL .. string.char(01) ) then 
    print ("REMOTE FLOW CONTROL ON")
    tmr.delay(100)
 end  
 

 if  string.find(c, "gin:") then conn:send(LOGIN .. "\n") end

 if string.find(c, "word:") then conn:send(PASSWORD .. "\n") end

  uart.write(0,c)

end )

 uart.on("data", 0 ,
   function(data)
    if buffer == "" then
      buffer = data
    else
      buffer = buffer .. data
    end 


     if string.find(buffer,"+++q")  then
       uart.on("data") -- unregister callback function
       conn:close()
     end
    
     if string.find(buffer,"+++c") then
        buffer = ""
        conn:connect(23,HOSTIP)
     end
    
    if #buffer > 20 then buffer = "" end
    if string.find(buffer,"\r")  then buffer = "" end
 
      
   if string.find(buffer,ESC ) then
     if DEBUG then hexprint ( buffer  ) end
     if string.find(buffer,ESC .. ESC ) then
       conn:send( ESC )
       buffer = ""
     end          

    -- CURSOR KEYS
    CURSORKEY =  ESC .. "%[%u"
      if string.find(buffer,CURSORKEY ) then
        if DEBUG then hexprint ( buffer  ) end
        conn:send( string.match(buffer,CURSORKEY ))
        buffer = ""
      end          
  
    else
        conn:send( data )
    end
 end, 0)

 print "+++c to connect , +++q to disconnect"

 else
 print ("define HOSTIP, LOGIN and PASSWORD and try again")
 end

--=======================================================


this works for the old server, but doesn't work on a busybox telnetd or a newer telnetd (GNU inetutils) 1.9.2. it needs a proper state machine to do negotiation.
 
And you need to push escape twice to send escape, it is a work in progress.

Tuesday, 23 June 2020

M5Atom Binary Clock

Finally received M5's latest tiny ESP32 module (it was way delayed due to the virus). Tried some demos, the LedDisplay demo doesn't work unless you change as per this advice:

"change in LED_DisPlay.ccp line 103
// xSemaphoreTake(_xSemaphore, portMAX_DELAY);
xSemaphoreTake(_xSemaphore, 100);" 


from ririfonfon on the M5Stack/M5Atom forum.

And then, a binary clock based on SimpleTime from the ESP32 examples, gets the time from NTP and displays on the M5Atom's leds.

The M5Atom set up uses the FastLed library but for some reason the colours work strange if you use the defined colour constants eg, if you use "CRGB::Red" the led lights green and vice-versa .

The fifth column is the seconds/2 in binary. The hours and minutes are BCD.

It does need a daylight savings check added.

the code is here

Sunday, 12 April 2020

Anniversary of Human Spaceflight



Anniversary of Human Spaceflight 12 April 1961

First person in space Yuri Gagarin in Vostok 1

Saturday, 14 March 2020

Wednesday, 11 March 2020

A day out in Tasmania

Legerwood tree sculptures



Mt. Victoria Forest Reserve, Ringarooma


 St. Helens Point




Friday, 28 February 2020

"The World" visits kanamaluka/Tamar River



MS "The World" visits kanamaluka/Tamar River in Northern lutruwita / Tasmania.

Krita on Tiny Core Linux

Reminder: the Appimage version of Krita for Linux needs the fuse.tcz loaded to work on Tiny Core Linux. Best to have Xorg loaded as well.