You are on page 1of 11
CR inteRFACEWARE Help Center Post Home > Translator as ASTM TCP Glient (Sender) > Translator as ASTM TCP Client Sender) This post was originally written for Iguana 5 so it uses version 5 screenshots, and may contain out of date references. Sending ASTM messages using Translator is not much different fram sending HLT messages. For this purpose we will use well known lip module from the tools repo, and rename it and modify to match ASTM protocol particulars and exclude LLP specific elements, This Example Dependencies In order to test this project, it requires to run active ASTM TCP Server (Listener) and Iguana Webserver to do HTTP POST of ASTM messages to Iguana. Data presentation ‘Suggested example will read initial ASTM message data from file (... or from "Sample Data’ when working in Translator IDE.) Depending on type of fle system, the end-of-line can be or or combination of both, Our testdata can be seen below; and one can note that in this data the end-of- line is Ox0A character (AKA ‘\n' or ,) ]wse STH 1a a)aneneres) | |DOR-SeRK m) }20121292/m)| 1) °RORIaNE-ZH || 1) 1) 9)3) apeparearoe|| “-ama\**-x\-**c1\"+Ac02\"**mPop) a) | 12345066 sees)" rsm\ “PEAY R||20422231134500) | ||) || 12) 1 am 212) jaan ein ono Thus in module main we will examine and normalize input ASTM message frames; calculate and concatenate respective checksum digits; and pipe result to sending module. Because data itself includes numerous control characters, it could optionally be saved as binary file instead of text. If data had instead of this would make our example more simple, but let's see below how to handle non-standard terminator. Frames must be surrounded by leading STX and trailing ETX, or ETB. This sample ‘ASTM Sender’ has no way to know if frame has to be terminated with ETX or ETB unless it has boon promptly specified in data itself. Translator as ASTM TCP Client For impatient complete ASTM_sender_To_Translator zip project is available for download. Modules We call four modules. 1. The astm_send module handles ASTM specific protocol to send a message 2. The astn_top module handles TCP communications 3. The astmutil module contains functions to calculate checksum digits, write debug logs, and send HTTP POST request to Iguana Webserver 4. The stringutil module contains few string manipulation functions Module Dependencies Modules don't ‘require’ external to Iguana Lua modules. Configuration Three places which will require custom configuration: 1, Please remember to adjust TCP host and port values in function main() to match host and port of ASTM TCP Server that ASTM messages will be sent to, 2. The webserver access credential in function astmutil,postJson () in module astmutil may have to be adjusted as well, 3. The function calculating checksum digits may have to be adjusted to match specific interface design. In this example Checksum calculation is defined for not ‘i’ delimiters. Checksum is also defined to exclude , but to include either , or . In another environment it potentially can be different. Then algorithm in function astmutilchecksum() in module astmutil has to be adjusted Main module uw 2. B. ua. . 1. 20. a. 2. 23. 24 25. 26 ar 28 29 30 31. 32. 33. 34. 35. 36. 38. 39. 40. require( 'astn_send') require( ‘stringutit’) require( ‘astmutit') -- Data (frames) must be enclosed in leading STX and trailing ETX, or ETB. -- ‘ASTM Sender’ has no way to know if frame has to be terminated with ETX ++ or £T8 unless it has been promptly specified in data itself. function main(Data) Local data = bata:split('\992") table. renove(data, 1) for i= stata do data[i} :trimRNL() data[i}="\o02". .data{i) end data = addchecksun(data) Vocal Success, err = astm_send, send( data, "192.168.5.4", -- host 6559, => port 18, -- timeout true) ++ live if not Success then iguana. logError(err) end end function addchecksum(data) vidata do Vocal é = datalil: Local ckeastmutil .checksum(d) Gatalil=d..ck..'\r" end for return data end Modules code ‘The astm_send module. 1 require(‘asta_tcp') Local function astm_initiator(param) 4 5 Vocal detrl=(5,4} -- flow control ENQ and EOT values, respectively 6. Vocal gs 7 Local inconversation=false 8 Local tep = asta_tep.connect(host=param[2] ,port=param(3] ,timeout=paran[4},Livesparam(5]) 10 uw Local function sendit(d) 2. if type(d) == ‘string’ then B iguana. logdebug (‘sending *. .d) rT tep:send(d) be else 16. tep:send(string.char(d)..'\n') uw. end 1B. 1. if d == detrt(2] then 20. return au. end 2. 23. while true do 2a. Vocal s = tepzrecv() 25. gs=s 26. if gs then 2. return gs 28 end 28 30. end 31 end 2 3 gs = sendit(detrt{1]) 34 iguana. Logdebug (‘sent EN signal’) 35. 36. if not inconversation and string. byte(gs) iguana. Logdebug (‘received ASTM ACK") gsenit 38. inconversation=true 40. end al. 42. if not inconversation and string. byte(9s) 43, iguana. LogDebug (‘received ASTM NACK") 4a, gs-nit 45. end 46, a7 Local repeats 48. 49 Local function repeatsends(d) 50 repeats=repeats-1 su gsesendit(a) 82 if string.byte(gs) == 6 then 53. iguana. logdebug (‘received ASTM ACK") 5a. 55. 56. 57. 58 59 60. 61 62. 63 64 6. 66. 67. 68. 69. 70. n. rR. 2. ma. 3. 76. 7. 78 79. 89 a1 82, 83. 84 85. 89. 90. al. 92. return elseif repeats > 9 then iguana. logDebug (‘received ASTM NACK") repeatsends(d) else if repeats == 6 then iguana. logError(' failed to transmit frame "'..d.." end return end end Local function sendpayload() for k,v in ipairs(paran(1]) do repeats = 5 repeatsends(param(1}(k)..'\n') end end if inconversation then sendpayload() gs = sendit(dctrU(2]) iguana. logdebug (‘sent EOT signal") elseif not inconversation then iguana. logError('remote not accepting’) -- some repeat logic could be nice to have. return end tep:close() end ~ public astm_send = {) function asta_send. send (data, Host Port, Timeout ,Live) Success, err = pcall (astm_initiator, (data,Host Port, Timeout Live}) return Success, err end The asim_top module, Here we expose 2 single function, connect(), that opens -+ an astm_tcp connection to a remote host, and returns a -+ to interact with. + When debugging, it actually returns a fake connection, which can be sent ASTM messages, and ) => replies with ACKs (one ACK per message sent) If you want to test a real astmtcp connection in the e pass Livestrue along with your connection settings =- require('astm_tcp') local s = astm_tcp. connect {host=" frink', port=8086) sisend(Data) ~ local Ack + siclese() srecv() _astm_tep = ( send_astn_tep = function(s, msg) Vocal sent, text = 0, ms9 repeat sent = sent + s:send(text, sent+1) until sent >= text:Len() return sent recv_astn_tcp = function(s, buf) buf=s:reev() return buf end; real_meta = { index = { send = function(selt, msg) return _astm_tcp-send_astm_tcp(self.s, msg) end; recy = function(selt) local msg, skipped sg = _astn_tep.recv_astm_tep(selt.s, self.bu turn msg close = function(self) self end selose() -- Metatable for Simulation simulation_neta = ( index = ( send = function(self, msg) if not self-connected then error(*not connected’, 2) 58. 59. 69. 61. 62. 63 64 65. 66 67 68. 69. 70. n R. 2. m. 5. 76. 7. 78. 79. 80. Bi. 82 83 84 85, 86 87 88. 89. 90. gL. 92. 93. 94, 95. 96. 97. 98, 99. 108 11 102 103 104 105 106 107. end self.sent = msg return msg:ten() end; recy = function(self) if not self-connected then error(‘not connected’, 2) elseif not self.sent then error('timeout', 2) else Local got = '\906' -- ASTM flow control ACK self.sent = nil return got end close = function(self) self. connected = false end ++ Error Checking check_arg = function(args, k, t, optional) Vocal help = [[Connect to a remote astm_tcp host Takes a table with the following required entries: "host - the hostnane of the renote site "port! - the port on the renote site and optionally these entries ‘timeout’ - maximum wait time, in seconds (default 5s) ‘Live’ - create Live astm_tcp connections in the edit: 1086) e.g. local s = astm_tcp.connect{hos' fend(Data) Local Ack = s:recv() jostname' , por selose() if not args then error(help, 3) elseif type(args) error( ‘Parameter 1 is not a table.\n'..help, 3) elseif not optional and not args{k) then ‘table’ then error("Parameter '*..k.."! is required.\n"..help, elseif args[k] and type(args[k]) ~= t then error(*Parameter '*..k.."' should be a "..t..'.\n end end; 108, 109. nie un. 12 113 na 15 116 17 us 1s. 129. 1. 122. 123. 124, 125. 128. 127. 128. 129. 130. ai. 132 133 134 135 136 137 138 139. ~~ Public Interface astm_tep = function astm_tcp.connect (args) Local required, optional = false, true _astm_tep.check_arg(args, ‘host’, ‘string’, requirs __astm_tep.check_arg(args, ‘port’, ‘number’, requir __astm_tep.check_arg(args, ‘timeout’, ‘number’, option: __astm_tep.check_arg(args, ‘live’, ‘boolean’, option: if args. Live or not iguana.isTest() then = Normal behaviour (in running channel). args. live = nil Local Success, Socket = peal inet. tcp.connect, args) if not Success then -- raise error to caller level error(Socket, 2) end return setmetatable({ s = Socket, buf =", ~~ input buffer. >, _astm_tep. reat_meta) else = Simulate behaviour white editing return setmetatable({ connected = true, }, _astm_tep.simulation_neta) end end The astmutil module. astmutil function astmutil.checksum(s) Sone test data may have wrong delimiters, e.g. rn or Checksum calculation is defined for r not n delinite, -- Checksum below is defined to strip , but not

You might also like