Telnet server
NMarkRoberts
Junior Member
I was frustrated with trying to use the unreliable G3 browser control for remote admin / testing / config so I decided to build a command line server.
This code is a "telnet server" in the form of an include. It won't compile as is because it uses my code infrastructure, you'll have to modify it to yours.
It just listens for an incoming IP connection on a given port and replies to or acts upon text received. Note that you need to use a telnet client in which you can specify the port.
I'm not sure how robust this is yet, comments welcome.
This may be old hat to some but I was pleased with how easy it was to do!
This code is a "telnet server" in the form of an include. It won't compile as is because it uses my code infrastructure, you'll have to modify it to yours.
It just listens for an incoming IP connection on a given port and replies to or acts upon text received. Note that you need to use a telnet client in which you can specify the port.
I'm not sure how robust this is yet, comments welcome.
(*** iTelnetServer.axi ***)
(******************************************************************************)
define_device
(******************************************************************************)
dTelnetServer = 0:3:0
(******************************************************************************)
define_variable
(******************************************************************************)
volatile char sTelnetServerBuffer[1000] = ''
volatile integer bTelnetServerOpen = False
volatile integer bTelnetServerOnline = False
volatile integer nTelnetServerPort = 8001
(******************************************************************************)
define_function TelnetSend (
char sArgString[] )
(******************************************************************************)
{
send_string dTelnetServer,"sArgString,cCR,cLF"
} (* TelnetSendMessage *)
(******************************************************************************)
define_function integer TelnetServerOpen(
dev dArgDevice ,
integer nArgPort )
(******************************************************************************)
{
stack_var integer nMyResult
stack_var integer bMyServerOpen
nMyResult = type_cast(ip_server_open(dTelnetServer.Port,nArgPort,ip_tcp) * -1)
switch (nMyResult)
{
case 0:
{
Debug('OpenTelnetServer successful')
bMyServerOpen = True
}
case 1:
{
Error('OpenTelnetServer invalid server port')
bMyServerOpen = False
}
case 2:
{
Error('OpenTelnetServer invalid value for Protocol')
bMyServerOpen = False
}
case 3:
{
Error('OpenTelnetServer unable to open communication port')
bMyServerOpen = False
}
default:
{
ErrorNumber('OpenTelnetServer unknown result',nMyResult)
bMyServerOpen = False
}
}
return bMyServerOpen;
} (* TelnetServerOpen *)
(******************************************************************************)
(*
Handle string on incoming telnet session
*)
define_function HandleTelnetServerBuffer()
(******************************************************************************)
{
stack_var char sMyString[1000]
stack_var char sMyTerminator[10]
stack_var char sMyTokens[100][100]
stack_var integer nMyTokenCount
DebugHex('HandleTelnetServerBuffer',sTelnetServerBuffer)
sMyTerminator = "cLF"
while (find_string(sTelnetServerBuffer,sMyTerminator,1))
{
DebugHex('Terminator',sTelnetServerBuffer)
sMyString = remove_string(sTelnetServerBuffer,sMyTerminator,1)
sMyString = TruncateString(sMyString) (* Ditch trailing whitespace, CR, LF *)
while (length_string(sMyString) > 0)
{
nMyTokenCount++
sMyTokens[nMyTokenCount] = RemoveString(sMyString,' ')
}
sMyTokens[1] = upper_string(sMyTokens[1])
DebugHex('Token',sMyTokens[1])
(* First token is the keyword *)
switch (sMyTokens[1])
{
case 'HELLO':
{
TelnetSend('How the heck are you?')
}
case 'REBOOT':
{
TelnetSend('Rebooting')
RebootController()
}
default:
{
DebugHex('Unknown keyword',sMyTokens[1])
TelnetSend("'Unknown keyword [',sMyTokens[1],']'")
}
}
}
} (* HandleTelnetServerBuffer *)
(******************************************************************************)
define_event
(******************************************************************************)
data_event[dTelnetServer]
{
onerror:
{
ErrorNumber('dTelnetServer onerror',type_cast(data.number))
}
online:
{
Debug('dTelnetServer online')
bTelnetServerOnline = True
}
offline:
{
Debug('dTelnetServer offline')
bTelnetServerOnline = False
}
string:
{
DebugHex('dTelnetServer string',data.text)
sTelnetServerBuffer = "sTelnetServerBuffer,data.text"
HandleTelnetServerBuffer()
}
}
(******************************************************************************)
define_program
(******************************************************************************)
if (bModuleReady)
{
wait nOneMinuteTenths
{
if (not bTelnetServerOpen)
{
bTelnetServerOpen = TelnetServerOpen(dTelnetServer,nTelnetServerPort)
}
}
}
(*** End of iTelnetServer.axi ***)
This may be old hat to some but I was pleased with how easy it was to do!
Comments
-
Unless I?m missing your point, one virtual device is all you need to get the job done. The rest is already built into Netlinx. Consider the following:NMarkRoberts wrote:I decided to build a command line server?.I'm not sure how robust this is yet, comments welcome.DEFINE_DEVICE vdvCLI = 33001:1:0 //Virtual Command Line Interpreter DEFINE_EVENT DATA_EVENT[vdvCLI] { COMMAND: { SEND_STRING 0, "'Got your command to ',DATA.TEXT" } STRING: { SEND_STRING 0, "'Got your string: ',DATA.TEXT" IF (FIND_STRING(UPPER_STRING(DATA.TEXT),'HELLO',1)) { SEND_STRING 0, 'Hello to you too' } } }
Now you just telnet into the NI master, turn on messages with ?msg on?, and SEND_COMMANDs or SEND_STRINGs to your virtual CLI.
And make sure you say ?hello? to the NI master.Telnet session wrote:>msg on
Extended diagnostic information messages turned on.
>send_command vdvcli, 'Jump in the lake.'
>(0000245303) Got your command to Jump in the lake.
send_string vdvcli, 'hello'
>(0000259360) Got your string: hello
(0000259360) Hello to you too
-
I guess I was looking for something that could do anything, not just what could be reached via send_commands (etc), plus I wouldn't have to type "send_command etc" all the time.
So far I have experimentally implemented push, pulse, release, and also get and set for a bunch of regular variables and config variables that I already have in a diagnostics structure which allows me to refer to them by their name in a string.
I should note that I have more or less given up using NS2 debug cos it's unreliable when you have multiple modules. -
hi mark, richard here, we met in the Gold Coast.
i described then what i was doing with my application for all installations.
basically, every device is described in a text file database.
i've prepared a masssive arrary of commands for my command line interface.
also, the system runs scripts similiar to DOS batch files. all script commands are compatible with the command line interface.
my scripts also store their own local status variables and can use them for compares when the script runs. all devices report to a 'central' variable stack, so the scripts can also get the status of just about every device.
i've made the commands and variables to be fast indexed/lookup.
my objective is to do all processing thru scripts. this is close to being achieved after nearly three years of working on the one application.
the benefits include installing a known and thoroughly tested application, that hopefully only needs to be altered in it's text database and script files, ensuring a robust installation.
another benefit is to be able to quickly and quietly change functionality, even remotely over the net, without rebooting a system or recompiling and uploading.
a feature of this system is it contains a full web interface to all devices in the installation. command lines can be executed thru the web interface. lights and audio etc can be controlled (and automatically labelled from the database) from a mobile phone with web access.
i'm fairly happy now with the end product and willing to brag about it
. if anyone wants to see the web interface i'll setup a demo link.
here is some sample text from one of my script files. the DO statement begins the command. DO can be replaced by IF x=y to create a conditional command line.
do toggle lights bed 2
do delayscript bed2button3:5
if light~bed 2 = 0 goto killEnsuite
do on lights bed 2 ensuite
do goto endScript
:killEnsuite
do off lights bed 2 ensuite
:endScript
note the GOTO commands. there is also a GOSUB command to call repeated functions within the script.
i haven't provided source code samples. the project has become quite massive. it takes a couple of minutes for the controller to fully reboot and reload the application and it's data. a bit longer than usual, but many benefits once the reboot is done. (the compiled source file is over 2MBs).
i guess some wont agree with me on the taking this path. but i didn't want to rewrite a new application for every customer, so i have tried to create one application that does all.
so now, i write all my functions to be command line ready. then when a script wants access to something, it's already there.
more raving then help here i know, but i hope it gives you some food for thought.
i've setup a link to a demo system webpage if you care to take a look.
try http://zentra.com.au:888 -
I've often thought about doing this exact thing - and never took it so far, because I found in most cases using a virtual interface and using "send command" was adequate. However, there is no reason you couldn't make an entire telnet interface to a master that anyone could use, with different access levels and the whole nine yards. I've always thought the approach had a lot of potential.
Leave a Comment
Categories
- All Categories
- 2.5K AMX General Discussion
- 922 AMX Technical Discussion
- 514 AMX Hardware
- 502 AMX Control Products
- 3 AMX Video Distribution Products
- 9 AMX Networked AV (SVSI) Products
- AMX Workspace & Collaboration Products
- 3.4K AMX Software
- 151 AMX Resource Management Suite Software
- 386 AMX Design Tools
- 2.4K NetLinx Studio
- 135 Duet/Cafe Duet
- 248 NetLinx Modules & Duet Modules
- 57 AMX RPM Forum
- 228 MODPEDIA - The Public Repository of Modules for Everyone
- 943 AMX Specialty Forums
- 2.6K AMXForums Archive
- 2.6K AMXForums Archive Threads
- 1.5K AMX Hardware
- 432 AMX Applications and Solutions
- 249 Residential Forum
- 182 Tips and Tricks
- 146 AMX Website/Forums