'0208
'---------------------------------------------------------------------------------------------
' STL, general gateway for audio
' 
' 02.00  Apr 08 2010  AD  started from Andrew RTP_STL V1.24
'                         + added new web UI
'                         + added standard BRTP
'                         + added appstatus page
'                         c chged usb failover fixed, just ON/OFF available
'                         + added keep alive "disabled", no send, no reply
'                         ! fixed no pld update without USB pen on decoder side
'                         ! fixed USB audio holes sometime
' 02.01  Jun 12 2010  AD  c chged buffer to msecs, song module C8.05 introduced
'                         c added external ADC option
' 02.02  Jul 23 2010  AD  c chged loopback as default mixer (0x4000) always
'                         + added RTP statistics
'                         + added Exstreamer 500 support
'                         + added Reflector-based reboot
' 02.03  Jul 27 2010  PK  ! fixed #61.14: long string expressions causing audio dropouts
'        Jul 30 2010  PK  ! fixed input selection on Ex500 (WEB UI)
' 02.04  Aug 10 2010  AD  + added SNMP alarm system
'                         + added SNMP Walk parameters as per BNA request spec.
'                         + added relay ON while OUT On/Off options
'                         ! fixed input states must not be displayed for device with no inputs
'                         ! fixed activation of relays in "send on level" and "send on inputX"
'                                 done immediate (no timeout)
'                         + added minor alarm for no incoming stream
' 02.05  Aug 13 2010  AD  ! fixed ON while OUT audio ON/OFF behaviour
'                         ! fixed bug #061.15
' 02.06  Sep 07 2010  AD  ! fixed bug #061.18, relay 1 set to On while OUT audio OFF,
'                                 _MSG_1.mp3 was locking app. in a loop.
' 02.07  Sep 28 2010  AD  ! fixed bug #061.20, stream 2 (com2) reused in init
' 02.08  Oct 28 2010  AD  ! fixed bug #061.01, UDP/TCP port - no check for value range
'                         c chged stream numbers changed to 8 and 9 for usb playlist / mesgs
'                         ! fixed bug #061.22, _MSG_x.MP3 feature works not properly
'                         c chged status page update method
'---------------------------------------------------------------------------------------------
dim ver$(24)

ver$="V2.08 (Oct 28 2010)"

#define WMODE_SE   0
#define WMODE_TD   1
#define WMODE_SED  2
#define WMODE_TED  3

syslog "STL, general tunnel for audio "+ver$

dim l,j,i,j1,x
dim dst(7,1),sdst(7,1),tdst(7),mdst(1,1),idst(7),rdst
dim _Ms$(1500)
dim set$,vol,scks$,lport,rport,port,rhost$(16)
dim msg$(500),sts$,audio$(30),dir$(15),snd$(15),rcv$(15),nd$(25)
dim RL$(15),RL_o$(15),file$(128),brtps,brtpc
dim ad_gn,mc_gn,inp,af,bit5
dim sr,srt,ql,qlty,msdel,confl,ocnfl,smode,kaprd,kadis,rmode(8),levth,stout,bcip$(16)
dim dmode,talk,buffl,tm0,relay,rf(8),tm,buf,atime,btime
dim levl,levr,levlo,levro,ldbl,ldbr,ldblo,ldbro
dim IR$(9),IR_o$(9),IL$(9),IL_o$(9),mp3fl,mp3mn,plo,pln,volfd,fact,atimI,btimI,ramp,msgfl,mf(8)
dim com$(50),_Mb$(1024),lb,com1p,com2p,ofs,comb,rh1$(16),rh2$(16),rp1,rp2 'for SG'S
dim snmp$,snmpd(3)                               'for SNMP
dim tmout,mserv$,mfrom$,mto$,msubj$,mbody$,tmp$  'for SMTP (e-mail)
dim wmode ' working mode
dim rtpdr,rtpdu,rtplo,rtpla ' statistics
dim outth,otout
dim atomI, btomI
dim pllst, mdlay
dim badpf, bufhi


' new 2.04, SNMP parameters

dim _S01$(16) ' "RST "	' Relay state
dim _S02$(64) ' "CST " ' Connection state
dim _S03$(16) ' "IAL " ' Input audio level left
dim _S04$(16) ' "IAR " ' Input audio level right
dim _S05$(16) ' "OAL " ' Output audio level left
dim _S06$(16) ' "OAR " ' Output audio level right
dim _S07$(16) ' "LOF " ' RTP lost frames
dim _S08$(16) ' "DUF " ' RTP duplicated frames
dim _S09$(16) ' "DRF " ' RTP dropped frames
dim _S10$(16) ' "LAT " ' RTP latency
dim _S40$	  ' last alarm text

_S02$="CST No keep-alive info" ' startup status

' AD 05-08-2010
' new 2.04, alarm service introduced.
'
' how it works:
'
' There is a 32-bit bitmask (amask) keeping alarm states for a maximumn of 32 alarms.
' Alarms are set(/unset) through the function <alarm> as below:
'
' alarm(ALARM_CONN_LOST,1)
'
' Every time a new alarm change is dectected checking amask with old mask (omask)
' the correspondent alarm/s trap is/are sent.

dim amask,omask   ' 32 alarms to be used, (on/off)
dim atmp
dim algen$        ' general text for alarm event

' stream map
'
' 0 SMTP / setup init readings
' 1 com 1
' 2 com 2
' 3
' 4 UDP audio tunnel
' 5 TCP/UDP SG
' 6 TCP/UDP SG
' 7 audio

' alarms

#define ALARM_CONN_LOST		0
#define ALARM_NO_IN_STREAM	1

' alarms severities, max 16, and correspondent human readable strings

#define SEV_NONE				0
#define SEV_INFO     		1
#define SEV_MINOR     		2
#define SEV_MAJOR     		3
#define SEV_CRITICAL 		4

dim sev$(16)
sev$="NONINFMINMAJCRI"

' alarm specific parameters, as bitmask per every alarm (severities, etc)
' XXXXXXXXXXXXXXXXXXXXXXXXSSSSUUUU
' X = reservered for future uses
' S = alarm set(on) severity
' U = alarm unset(off) severity

dim apara(32)

apara(ALARM_CONN_LOST)=or(shl(SEV_CRITICAL,4),SEV_INFO)
apara(ALARM_NO_IN_STREAM)=or(shl(SEV_MINOR,4),SEV_INFO)


dim sread <gosub 10000>
dim ssave <gosub 10100>
dim alarm <gosub 550>		' set / unset (1/0) alarm state
dim alsnd <gosub 650>		' send alarm, parames are alarm n. and state (on/off)
dim calcd <gosub 10400>		' calculate low buffer limit

bcip$ = sprintf$("%1A",5)           'broadcast IP for auto start-up config
for i = 1 to 8
	ioctl i,0 'all possible relays off
next i

' *** READING SETUP VARIABLES ***

' detecting hw type
i = iostate(60000)
if and(i,i<26) then
	j=-1
	' decoder only ?
	if or(i=1,i=9,i=14,i=20) then j=WMODE_TD
	' or encoder only ?
	if i=8 then j=WMODE_SE
	if j<>-1 then
		lock 1
		sread(500)
		midset set$,37,1,j
		ssave(500)
		lock 0
	endif
endif

sread(500)
' WMODE
wmode=midget(set$,37,1)

outth=midget(set$,28,2)
otout=midget(set$,39,2)

' AUDIO
vol=midget(set$,1,1)				' AD, volume in dB
if vol>127 then vol=vol-256	' convert to signed
if vol>12 then vol=12			' safe limit

ad_gn = midget(set$,2,1) : if ad_gn>15 then ad_gn=15
mc_gn = midget(set$,3,1) : if mc_gn>15 then mc_gn=15
ramp = midget(set$,8,1) ' fading option

' SG'S
com1p = midget(set$,4,2) 'UDP/TCP port for COM1 gateway (0 - disable, >0 - UDP, <0 - TCP)
if com1p > 32768 then com1p = com1p-65536
com2p = midget(set$,6,2) 'UDP/TCP port for COM2 gateway (0 - disable, >0 - UDP, <0 - TCP)
if com2p > 32768 then com2p = com2p-65536

inp = midget(set$,11,1)					'input (1=line,2=mic,4/5=SPDIF opt/coax,9=AES/EBU)
if inp = 9 then inp = 5             'really use 5 for AES/EBU in BCL

' AUDIO FORMAT
af = midget(set$,12,1)					'audio format
if or(af=3, af=5) then bit5 = 1		'correction for PCM LSB mono / stereo
if af>5 then
	if af=6 then mp3mn = 1				'it is mono MPEG 1/2 format
	mp3fl = 1								'it is MPEG 1/2 format (to BCL table)
endif

' AUDIO BCL Quality SETUP
' transforming sample rate from a common drop down value
sr = midget(set$,13,1)              'sampling rate, common
if or(sr<0,sr>7) then af=1:sr=0		'protection against bad eeprom
if mp3fl=0 then
	i=0 ' stereo bit
	if or(af=4,af=5) then i=4096
	if af>=2 then af=2
	if sr=0 then srt=8
	if sr=1 then srt=12
	if sr=4 then srt=24
	if sr=5 then srt=32
	if sr=6 then srt=44
	if sr=7 then srt=48
	qlty=i+256*af+srt						'analog quality w/o coder bits
else
	ql = midget(set$,14,1)           'mpeg qlty, AD, DOM asked to add a separate drop down
	if sr=2 then srt=4  ' 16
	if sr=3 then srt=0						
	if sr=4 then srt=2
	if sr=5 then srt=5
	if sr=6 then srt=1
	if sr=7 then srt=3
	qlty=1024+16*ql+srt ' 1024 bit reservoir
endif

msdel = midget(set$,26,2)           'max playback buffer level
if and(mp3fl=0,msdel>1000) then msdel = 1000 ' auto limitation from the FW, to 32K


smode = midget(set$,21,1)           'sending mode
if wmode=WMODE_TD then smode=5		'set to never if transmitter only
kaprd = midget(set$,30,1)        	'keep-alive sending period (0 - disable)
if kaprd=255 then 
	kaprd=0 : kadis=1 'disable send and receive
else
	kaprd=kaprd*10
endif

rmode(1) = midget(set$,31,1)        'Relay1 mode
rmode(2) = midget(set$,32,1)        'Relay2 mode
rmode(3) = midget(set$,33,1)        'Relay3 mode
rmode(4) = midget(set$,34,1)        'Relay4 mode

levth = midget(set$,22,2)           'trigger level for "send on level"
stout = midget(set$,24,2)           'stop "send on level" after this number of ms
lport = midget(set$,35,2)           'local port (0 for encoder)
snmp$ = mid$(set$,41,60)            'destination SNMP IPs (string)

if snmp$ then syslog "SNMP destination : "+snmp$

sread(1000)
mserv$ = mid$(set$,  1, 50)         'IP/DNS of open SMTP server
mfrom$ = mid$(set$, 51, 50)         'e-mail address of this device
mto$   = mid$(set$,101,100)         'comma delimited destination e-mail addresses
syslog "SMTP: "+mserv$+", from: "+mfrom$+", to: "+mto$

if mserv$ then syslog "SMTP destination : "+mserv$

on timer1 gosub 2500 'waiting for SMTP
timer 1,0 : _TMR_(1) = 0 'initial state

'check message files on USB (trick: mf(0) is quasi file to block output mixer)
for i = 0 to 8
	open "C_R:usb:///_MSG_"+str$(i)+".MP3" as 6 'try to open message file on USB
	if mediatype(6) then mf(i) = 1 : close 6    'set flags for existing messafe files
next i

3   'possible restart after autoplay
syslog "Start/restart for streaming..."

' playing from playlist reset, playing message reset
msgfl=0 : pllst=0

for i = 0 to 7
	if mediatype(i) then close i
	rf(i+1) = 0 'drop remote inputs
next i
plo = 127 : file$ = ""

' serial gateway
sread(0)
if com1p then
	i = 1 : gosub 30050
	if com1p > 0 then open "UDP:0.0.0.0:"+str$( com1p) as 5 'open COM1-UDP5
	if com1p < 0 then open "TCP:0.0.0.0:"+str$(-com1p) as 5 'open COM1-TCP5
endif
if com2p then
	i = 2 : gosub 30050
	if com2p > 0 then open "UDP:0.0.0.0:"+str$( com2p) as 6 'open COM2-UDP6
	if com2p < 0 then open "TCP:0.0.0.0:"+str$(-com2p) as 6 'open COM2-TCP6
endif

' start of init
j = 1                               'parse SNMP IPs string
for i = 0 to 3
	if j > len(snmp$) then goto 15   'rest of string is empty
	j1 = instr(j,snmp$,",") : if j1=0 then j1 = len(snmp$)+1 'limit of IP/DNS
	snmpd(i) = RESOLVE(mid$(snmp$,j,j1-j)) : j = j1+1        'value of IP
next i

15 'continue...

' OUTGOING STREAM (DESTINATIONS)
sread(600)
' parse URL strings
for i = 0 to 7
	scks$ = mid$(set$,1+32*i,32)
	dst(i,0)=resolve(scks$) : sdst(i,0) = dst(i,0)
next i
open "STP:856" as 0 : read 0,set$ : close 0

for i = 0 to 7
	' parse Destination Type
	idst(i) = midget(set$,1+i,1)
	' parse Remote Port values
	dst(i,1) = midget(set$,9+i*2,2) : sdst(i,1) = dst(i,1)
	' trace out sockets
	syslog "d "+str$(i+1)+" : type "+str$(idst(i))+" : "+&
			  sprintf$("%lA",dst(i,0))+" : "+str$(dst(i,1))
next i

if idst(0)=2  then
	if wmode=WMODE_SE then
		' BRTP must listen in the 1 Destination port
		syslog "Studio Encoder, BRTP selected, listening on Outgoing Stream BRTP port."
		open "UDP:0.0.0.0:"+str$(dst(0,1)) as 4 'usual passive UDP socket
		goto 14
	else
		syslog "BRTP service will listen on the same incoming stream port."
	endif
endif

10 ' continue...

' INCOMING STREAM
if lport then port = lport else port = dst(0,1) 'conventional local port for encoder
if port=0 then msg$ = "'red'> wrong settings: all ports are zero" ': goto 999 'end
' receiving mode
scks$=mid$(set$,35,32)
rdst=midget(set$,67,1)	' listening type
j=resolve(scks$)			' listening resolved ip	
syslog "in  : type "+str$(rdst)+" : "+sprintf$("%lA",j)+" : "+str$(port)
if rdst=1 then 'type=1, then multicast
	open "UDP:"+sprintf$("%lA",j)+":"+str$(port) as 4 'multicast UDP socket
	mdst(0,0) = j : mdst(0,1) = port 'socket for possible keep-alive
	dst(0,0) = 0 : sdst(0,0) = 0 'to set passive half-duplex decoder in future
	if mdst(0,0) = resolve(bcip$) then close 4 : goto 13 'if BRTP with broadcast IP
endif
if or(rdst=0,rdst=2) then
	if rdst=2 then mdst(0,0)=j : mdst(0,1)=port
13	open "UDP:0.0.0.0:"+str$(port) as 4 'usual passive UDP socket
endif

14

' Std BRTP, check enabled ?
if and(wmode <> WMODE_TD, idst(0)=2) then brtpc=1
' Std BRTP, send  enabled
if and(wmode <> WMODE_SE, rdst=2) then brtps=_TMR_(0) : gosub 500 ' first BRTP request

' active half-duplex encoder
if and(wmode = WMODE_SE, idst(0)<2) then dmode=2 : goto 11
'passive (learned) half-duplex encoder
if and(wmode = WMODE_SE, idst(0)=2) then
	dmode = -2 : dst(0,1) = 0 : sdst(0,1) = 0 : goto 11
endif
'active full-duplex encoder/decoder
if and(or(wmode = WMODE_SED, wmode = WMODE_TED), idst(0)<2) then dmode=1 : goto 11
'passive (learned) full-duplex encoder/decoder
if and(or(wmode = WMODE_SED, wmode = WMODE_TED), idst(0)=2) then
	dmode=-1 : dst(0,1) = 0 : sdst(0,1) = 0 : goto 11
endif
'passive half-duplex decoder
if and(wmode = WMODE_TD, rdst=2) then dmode = 0 : goto 11
'passive multicast half-duplex decoder
if and(wmode = WMODE_TD, rdst=0) then dmode = 0 : goto 11

11
' audio
if or(dmode=2,dmode=-2) then
	if mp3fl = 0 then
		'encoder analog
		audio$ = "AUD:11,"+str$(or(1,shl(bit5,5)))+","+str$(or(qlty,shl(1,10)))+","+str$(msdel)
		goto 12
	endif
	if mp3fl = 1 then 
		'encoder mpeg
		audio$ = "AUD:2,7,"+str$(or(qlty,shl(mp3mn,11)))+","+str$(msdel) : goto 12
	endif
endif
if dmode = 0 then
	if mp3fl = 0 then
		'decoder analog
      ' here only msdel is used, frame_duration left as automatic calculated from the FW
		audio$ = "AUD:11,"+str$(or(1,shl(bit5,5)))+","+str$(or(qlty,shl(1,11)))+","+str$(msdel)
		goto 12
	endif
	'decoder mpeg and all other formats (auto from RTP)
	if mp3fl=1 then audio$ = "AUD:1,7,0,"+str$(msdel) : goto 12
endif
'encoder/decoder (dmode -1 or +1)
if mp3fl then
	' a site type change, with still an MPEG format can result in bad audio open
	' let's default to uLaw mono 8Khz
	syslog "Unsupported full-duplex audio format, default to uLaw 8Khz mono"
	bit5=0 : qlty=256*0+8
	lock 1
	sread(500) : midset set$,12,1,0 : midset set$,13,1,0 : ssave(500)
	lock 0
endif
audio$ = "AUD:11,"+str$(or(1,shl(bit5,5)))+","+str$(or(qlty,shl(3,10)))+","+str$(msdel) 

12
' bufhi limit calculation from bitrate
bufhi=calcd() 
' give the chance to cactch the first keep alive
tm=_TMR_(0)

if smode then gosub 370 'initially to block sending for all modes excepting "send always"
gosub 350 'open audio tunnel

IR_o$ = "????????" : IL_o$ = "????????" : RL_o$ = "????????" 'init for status

'start of main loop
100
	' connection state changed ?
	if confl<>ocnfl then gosub 600 : ocnfl=confl
	' alarm for stream missing
	if confl then
		if buffl then alarm(ALARM_NO_IN_STREAM,0) else alarm(ALARM_NO_IN_STREAM,1)
	endif
	' some alarm to process ?
	if amask<>omask then gosub 700 ' process alarms if any
	' message programmed for a relay ? Playlist can't be interrupted !
	if and(msgfl,pllst=0) then
		if file$ then
			gosub 400 'try to play message file from USB
			if msgfl=0 then mdlay=_TMR_(0) : goto 3
		else
			if ramp then
				gosub 10200 ' ramp down actual music if any
			else
				write 7,str$(-127),-12 : gosub 460
			endif
		endif
		goto 100 ' AD continue until the message is played
	endif
	' serial gateway, bgn 
	if com1p then
		if and(com1p < 0, kaprd, _TMR_(0)-tm0 > kaprd) then
			if mediatype(5)   then if connected(5)=0 then close 5 : syslog "close COM1-TCP/handle 5"
			if mediatype(5)=0 then open "TCN:"+rhost$+":"+str$(-com1p) as 5 : syslog "open COM1-TCP" 'open active COM1-TCP5
		endif
		if filesize(1) then gosub 30001 'send COM1 -> UDP/TCP5
		if com1p > 0 then lb = lastlen(5) : if lb<0 then gosub 30005 ' receive UDP5 -> COM1
		if com1p < 0 then if mediatype(5) then if and(connected(5),filesize(5)) then gosub 30007 ' receive TCP5 -> COM1
	endif

	if com2p then
		if and(com2p < 0, kaprd, _TMR_(0)-tm0 > kaprd) then
			if mediatype(6)   then if connected(6)=0 then close 6 : syslog "close COM2-TCP/handle 6"
			if mediatype(6)=0 then open "TCN:"+rhost$+":"+str$(-com2p) as 6 : syslog "open COM2-TCP" 'open active COM2-TCP6
		endif
		if filesize(2) then gosub 30002 'send COM2 -> UDP/TCP6
		if com2p > 0 then lb = lastlen(6) : if lb<0 then gosub 30006 ' receive UDP6 -> COM2
		if com2p < 0 then if mediatype(6) then if and(connected(6),filesize(6)) then gosub 30008 ' receive TCP6 -> COM2
	endif
	' serial gateway, end
	IL$ = "" 'drop input values
	for i = 1 to 8
		if or(iostate(200+i)=0,iostate(200+i)=2) then IL$=IL$+"1" else IL$=IL$+"0"
	next i

	read 7,_Ms$,-1 : levl=lastlen(7) : _S03$="IAL "+str$(levl) 'left  audio in level
	read 7,_Ms$,-2 : levr=lastlen(7) : _S04$="IAR "+str$(levr) 'right audio in level
	read 7,_Ms$,-3 : levlo=lastlen(7) : _S05$="OAL "+str$(levlo) 'left  audio out level
	read 7,_Ms$,-4 : levro=lastlen(7) : _S06$="OAR "+str$(levro) 'right audio out level

	read 7,_Ms$,-13 : ldbl=lastlen(7) 'left  audio in level
	read 7,_Ms$,-14 : ldbr=lastlen(7) 'right audio in level
	read 7,_Ms$,-15 : ldblo=lastlen(7) 'left  audio out level
	read 7,_Ms$,-16 : ldbro=lastlen(7) 'right audio out level
	
	read 7,_Ms$,-10 : rtplo=lastlen(7) : _S07$ = "LOF "+str$(rtplo)
	read 7,_Ms$,-11 : rtpdu=lastlen(7) : _S08$ = "DUF "+str$(rtpdu) 
	read 7,_Ms$,-12 : rtpdr=lastlen(7) : _S09$ = "DRF "+str$(rtpdr)
	read 7,_Ms$,-20 : rtpla=lastlen(7) : _S10$ = "LAT "+str$(rtpla)

	if talk  then snd$ = "OUT stream ON" else snd$ = "OUT stream OFF"
	if buffl then rcv$ =  "IN stream ON" else rcv$ =  "IN stream OFF"

	if IL_o$ <> IL$ then if kaprd then write 4,tmp$,10,rhost$,rport 'to send urgent changes inputs
	
	if dmode then                  'if active side
		if smode = 1 then gosub 320 '"send on input1" mode
		if smode = 2 then gosub 320 '"send on input2" mode
		if smode = 3 then gosub 330 '"send on level" mode
		if and(kaprd, _TMR_(0)-tm0 > kaprd) then    'send keepalive/heart-beat messages
			tm0 = _TMR_(0) : write 4,"?"+IL$,10,sdst 'send request each keepalive period
		endif
	else
		if and(kaprd, _TMR_(0)-tm0 > kaprd) then    'send keepalive/heart-beat messages
			tm0 = _TMR_(0) : write 4,"?"+IL$,10,mdst 'send request each keepalive period
		endif
	endif
	if dmode = -2 then gosub 390 'check timers to free BRTP table on streaming end
	if and(brtps, _TMR_(0)>brtps+4000) then
		brtps=_TMR_(0)
		gosub 500
	endif
	' See LINK cmd, l<0 ONLY for non correct PAYLOAD TYPES or Outbands
	l=lastlen(4)
	if l<0 then
		if plo=-1 then goto 3 'possible restart after autoplay
		rhost$ = rmthost$(4) 'IP of active remote side
		rport  = rmtport(4)  'port of active remote side
		if and(dmode=0,kaprd,mdst(0,0)=0) then mdst(0,0)=RESOLVE(rhost$) : mdst(0,1)=rport 'socket for possible keep-alive
		read 4,_Ms$
		tm = _TMR_(0) ' keep alive reset
		' check for a payload
		if and(dmode=0,midget(_Ms$,1,1)=&H80) then   'if new RTP stream
			pln = and(midget(_Ms$,2,1),127)           'get RTP payload
			if plo <> pln then gosub 200 : goto 11    'start new passive RTP
		endif
		if mid$(_Ms$,1,1) = "!" then   'gotten reply from passive side (keep-alive)
			dir$ = "OUT Con to" : nd$ = "Net Delay: "+str$((tm-tm0)/2)+" ms" 'drop relay message
			IR$ = mid$(_Ms$,2) : confl=1
			for i=1 to 8
				rf(i)=val(mid$(IR$,i,1))    'gotten remote input i value
			next i
			if dmode=2 then write 7,str$(vol),-12 'set volume to vol for sender
		endif
		if mid$(_Ms$,1,1) = "?" then   'if heart-beat request (keep-alive)
			dir$ = "IN Con ON from" : nd$ = "RTP Payload: "+str$(plo) 'drop relay message
			IR$ = mid$(_Ms$,2) : confl = 2
			for i = 1 to 8
				rf(i) = val(mid$(IR$,i,1))    'gotten remote input i value
			next i
			'if dmode < 0 then gosub 380 'get new destination IP:port for passive (learned)
			if and(talk = 0, buffl = 1, smode = 4) then gosub 360 'start sending for "respond" mode
			if kadis=0 then write 4,"!"+IL$,10,rhost$,rport  'send heart-beat reply message
			if dmode = -2 then write 7,str$(vol),-12 'set volume to vol for sender
		endif
		' STANDARD RTP, AD
		if brtpc then
			'get new destination IP:port for passive (learned)
			if mid$(_Ms$,1,3)="BRX" then gosub 380
		endif
		
		' long expression split into several subexpressions to allow task switch (see bug #61.14)
		msg$ = "'lime'><table><tr><td>" + dir$ + "</td><td>" + rhost$ + "</td><td>: "+ str$(rport)
		msg$ = msg$ + "</td><td>INput AUD L:</td><td>" + str$(levl) + "</td></tr><tr><td>" + nd$ 
		msg$ = msg$ + "&nbsp;&nbsp;&nbsp;</td><td>Remote DIs:</td><td>" + IR$ + "</td><td>INput AUD R:</td><td>" + str$(levr)
		msg$ = msg$ + "</td></tr><tr><td>" + rcv$ + "</td><td>Local DIs:</td><td>" + IL$ + "&nbsp;&nbsp;&nbsp;</td><td>OUTput AUD L:</td><td>"
		msg$ = msg$ + str$(levlo) + "</td></tr><tr><td>" + snd$ + "</td><td>Local Relays:</td><td>" + RL$
		msg$ = msg$ + "</td><td>OUTput AUD R:</td><td>" + str$(levro) + "</td></tr></table>"
	endif
	
101 
	read 7,_Ms$,-6 : buf = lastlen(7) 'check rest of audio buffer
	'syslog "plo="+str$(plo)  '  why plo = -1 ?
	if plo=-1 then gosub 400 : goto 100 'try to autoplay from USB
	if buf>bufhi/10 then
      if _TMR_(0)-tm > 3000 then
			msg$ = "'lime'> IN Con ON, "+rcv$ : tm = _TMR_(0) 'to avoid interrupt by timer
			'to correct rhost$ and rport
			if confl <> 3 then confl = 3 : syslog "Restart for no Keep-alive" : goto 3
		endif
		buffl=1 'set buffer flag
		if ramp then
			if msgfl=0 then gosub 10300 ' fading, rumping up after a message
		else
			if msgfl=0 then write 7,str$(vol),-12 'set volume to vol
		endif
	else
		buffl = 0 : if and(talk=1,smode=4) then gosub 370 'block sending for "respond" mode
		if _TMR_(0)-tm>3500 then
			confl = 0 : msg$ = "'red'> NB! Connection is broken or closed!"
			'drop buffer flag and set volume to 0 (except keepalive OFF mode)
			volfd = 0 : if kaprd then write 7,str$(0),-12  
			if dmode = 0 then
				syslog "prepare possible autoplay"
				plo = -1 'prepare possible autoplay
				' SG can stay open actually, stream 8,9 are used for playlist and msg files
				'if mediatype(5) then close 5 'finish gateway for using by autoplay playlist
				'if mediatype(6) then close 6 'finish gateway for using by current autoplay file
			endif
		endif
	endif
102
	RL$ = "" 'drop output values
	for i = 1 to 8
		'actions for Relay i for gotten request/reply
		gosub 300 : ioctl i,relay : RL$=RL$+str$(relay) 
		if and(relay, mf(i)) then
			' studio encoder only ? no message must be played
			if or(dmode=2,dmode=-2) then next i
			' message must have priority on playlists since message is linked to relay action
			' and can happen also with stream on.
			if or(rmode(i)=1,rmode(i)=5,rmode(i)=6,rmode(i)=8,rmode(i)=9,rmode(i)=10) then
				' a certain delay is required to detect some level is back
				if _TMR_(0)-mdlay>5000 then msgfl=i
			else
				msgfl=i ' start process for playing message file, later 460 set file$
			endif
		endif
	next i
	if IR_o$ <> IR$ then IR_o$ = IR$
	if IL_o$ <> IL$ then IL_o$ = IL$
	if RL_o$ <> RL$ then
		RL_o$ = RL$
		_S01$ = "RST "+RL$
		for i = 0 to 3
			if snmpd(i) then trap sprintf$("%lA",snmpd(i)),6,1,"P1.3.0","E1.5.1.1.1.2.1"
		next i
		if mserv$ then msubj$ = RL$ : gosub 2300 'send by e-mail
	endif
	' long expression split into several subexpressions to allow task switch (see bug #61.14)
	sts$ = str$(smode)+":"+str$(PLO)+":"
	sts$ = sts$+str$(TALK)+":"+str$(BUFFL)+":"+str$(CONFL)+":"
	sts$ = sts$+str$(LEVL)+":"+str$(LEVR)+":"+str$(LEVLO)+":"
	sts$ = sts$+str$(LEVRO)+":"+str$(LDBL)+":"+str$(LDBR)+":"
	sts$ = sts$+str$(LDBLO)+":"+str$(LDBRO)+":"+IR_O$+":"
	sts$ = sts$+IL_O$+":"+RL_O$+":"+RHOST$+":"+str$(RPORT)+":"

	goto 100 'end of main loop

999 delay 10000
    end
' get new values for audio (see BCL manual, 3.10.3.5 RTP payload types)
200
	plo=pln : mp3fl=0 : syslog "new RTP payload type "+str$(plo)'set a new payload as old value
	if plo = 0   then qlty = &H0008 : bit5 = 0 : return 'u-Law, 8bit, mono, 8kHz
	if plo = 8   then qlty = &H0108 : bit5 = 0 : return 'A-Law, 8bit, mono, 8kHz
	if plo = 10  then qlty = &H122C : bit5 = 0 : return 'PCM,  16bit, MSB first, signed, 44.1kHz stereo, left channel first
	if plo = 11  then qlty = &H022C : bit5 = 0 : return 'PCM,  16bit, MSB first, signed, 44.1kHz mono
	if plo = 14  then mp3fl = 1                : return 'MPEG audio
	if plo = 96  then qlty = &H0208 : bit5 = 0 : return 'PCM,  16bit, MSB first, signed,  8kHz mono
	if plo = 97  then qlty = &H0018 : bit5 = 0 : return 'u-Law, 8bit, mono, 24kHz
	if plo = 98  then qlty = &H0118 : bit5 = 0 : return 'A-Law, 8bit, mono, 24kHz
	if plo = 99  then qlty = &H0218 : bit5 = 0 : return 'PCM,  16bit, MSB first, signed, 24kHz mono
	if plo = 100 then qlty = &H0020 : bit5 = 0 : return 'u-Law, 8bit, mono, 32kHz
	if plo = 101 then qlty = &H0120 : bit5 = 0 : return 'A-Law, 8bit, mono, 32kHz
	if plo = 102 then qlty = &H0220 : bit5 = 0 : return 'PCM,  16bit, MSB first, signed, 32kHz mono
	if plo = 103 then qlty = &H1230 : bit5 = 0 : return 'PCM,  16bit, MSB first, signed, 48kHz stereo, left channel first
	if plo = 104 then qlty = &H0208 : bit5 = 1 : return 'PCM,  16bit, LSB first, signed,  8kHz mono
	if plo = 105 then qlty = &H0218 : bit5 = 1 : return 'PCM,  16bit, LSB first, signed, 24kHz mono
	if plo = 106 then qlty = &H0220 : bit5 = 1 : return 'PCM,  16bit, LSB first, signed, 32kHz mono
	if plo = 107 then qlty = &H122C : bit5 = 1 : return 'PCM,  16bit, LSB first, signed, 44.1kHz stereo, left channel first
	if plo = 108 then qlty = &H1230 : bit5 = 1 : return 'PCM,  16bit, LSB first, signed, 48kHz stereo, left channel first
	if plo = 109 then qlty = &H000C : bit5 = 0 : return 'u-Law, 8bit, mono, 12kHz
	if plo = 110 then qlty = &H010C : bit5 = 0 : return 'A-Law, 8bit, mono, 12kHz
	if plo = 111 then qlty = &H020C : bit5 = 0 : return 'PCM,  16bit, MSB first, signed, 12kHz mono
	if plo = 112 then qlty = &H020C : bit5 = 1 : return 'PCM,  16bit, LSB first, signed, 12kHz mono
	syslog "wrong or generic RTP payload type "+str$(plo) : plo = 127
	return

'------------------------------------------------------------------------------
300 'actions for gotten request/reply
'------------------------------------------------------------------------------
    relay = 0
	 'syslog "rmode(i):"+str$(rmode(i))
    on 1+rmode(i) goto 301,302,303,304,305,306,307,308,309,310,311
301 if rf(i)   then relay = 1 : return else return 'set relay by remote input
302 if confl   then relay = 1 : return else return 'set relay by connection ON
303                                         return 'set relay by always OFF
304 if buffl   then relay = 1 : return else return 'set relay by incomming stream ON
305 if buffl=0 then relay = 1 : return else return 'set relay by incomming stream OFF
306 if confl=0 then relay = 1 : return else return 'set relay by connection OFF
307                             gosub 340 : return 'set relay by IN audio OFF
308                             gosub 340 : return 'set relay by IN audio change (pulsed)
309                             gosub 340 : return 'set relay by IN audio ON
310                             gosub 345 : return 'set relay by OUT audio ON
311									  gosub 345 : return 'set relay by OUT audio OFF
    syslog "wrong mode setting for Relay "+str$(i)
    return
'------------------------------------------------------------------------------
320 'actions for smode = 1 or 2
'------------------------------------------------------------------------------
    if val(mid$(IL$,smode,1)) then 'check input1/2
       if talk=0 then ',_TMR_(0)-btime>stout) then
          gosub 360          'set destination sockets and start sending
          syslog "start talk with active input1/2 "+str$(smode)+" immediate send"
       endif
       atime = _TMR_(0)      'remember latest time "send on input1/2"
    else
       if and(talk=1,_TMR_(0)-atime>stout) then
          gosub 370       'block sending
          syslog "stop talk with passive input "+str$(smode)+" after "+str$(stout)+" ms"
       endif
       btime = _TMR_(0)      'remember latest block time "send on input1/2"
    endif
    return
'------------------------------------------------------------------------------
330 'actions for smode = 3 (ON while incoming stream ON)
'------------------------------------------------------------------------------
    if or(levl>levth,levr>levth) then 'check levels
       if talk=0 then ',_TMR_(0)-btime>stout) then
          gosub 360        'set destination sockets and start sending
          syslog "start talk with levels "+str$(levl)+"/"+str$(levr)+" >= "+str$(levth)+" immediate"
       endif
       atime=_TMR_(0)      'remember latest activate time "send on level"
    else
       if and(talk=1,_TMR_(0)-atime>stout) then
          gosub 370        'block sending
          syslog "stop talk with levels "+str$(levl)+"/"+str$(levr)+" after "+str$(stout)+" ms"
       endif
       btime=_TMR_(0)      'remember latest block time "send on level"
    endif
    return
'------------------------------------------------------------------------------
340 'actions for rmode = 6,7,8 (ON while IN audio ON/OFF + pulse on change)
'------------------------------------------------------------------------------
    if or(levl > levth, levr > levth) then 'check levels
       if and(btimI-atimI > 0, btimI-atimI < stout) then btimI = _TMR_(0)-stout-5000 'block short switching
       if _TMR_(0)-btimI > stout then
          if rmode(i) = 8 then relay = 1 'ON for audio ON
          if rmode(i) = 7 then if _TMR_(0)-btimI < stout+3000 then relay = 1 'ON for 3 sec
       else
          if rmode(i) = 6 then relay = 1 'ON for audio still ON
       endif
       atimI = _TMR_(0)      'remember latest activate time "send on level"
    else
       if and(atimI-btimI > 0, atimI-btimI < stout) then atimI = _TMR_(0)-stout-5000 'block short switching
       if _TMR_(0)-atimI > stout then
          if rmode(i) = 6 then relay = 1 'ON for audio OFF
          if rmode(i) = 7 then if _TMR_(0)-atimI < stout+3000 then relay = 1 'ON for 3 sec
       else
          if rmode(i) = 8 then relay = 1 'ON for audio still OFF
       endif
       btimI = _TMR_(0)      'remember latest block time "send on level"
    endif
    return

' actions for rmode = 9 10 (ON while OUT audio ON/OFF )
345
	if or(levlo>outth,levro>outth) then ' se sopra soglia
		if and(btomI-atomI>0,btomI-atomI<otout) then btomI=_TMR_(0)-otout-5000 'no short switch
		if _TMR_(0)-btomI>otout then
			if rmode(i)=9 then relay = 1 ' ON for audio ON
		else
			if rmode(i)=10 then relay = 1 ' ON for audio still ON
		endif
		atomI=_TMR_(0) ' remember latest activate time "send on level"
   else
		if and(atomI-btomI>0,atomI-btomI<otout) then atomI=_TMR_(0)-otout-5000 'no short switch
		if _TMR_(0)-atomI>otout then
			if rmode(i)=10 then relay = 1 ' ON for audio OFF
		else
			if rmode(i)=9 then relay = 1 ' ON for audio still OFF
		endif
		btomI=_TMR_(0) 'remember latest block time "send on level"
   endif
	return
	 
'------------------------------------------------------------------------------
350 'open audio tunnel
'------------------------------------------------------------------------------
	if mediatype(7) then close 7

	syslog "Opening audio : "+audio$
	syslog "Actual dmode  : "+str$(dmode)
	
	open audio$ as 7                 'open audio
	if dmode then
		write 7,str$(ad_gn),   -2     'set A/D Gain
		write 7,str$(mc_gn),   -1     'set Mic Gain
		write 7,str$(inp),     -3     'set input source to mic/line
	endif
	'set mixer for 100% input and 100% output
	'if mf(0)=0 then if or(dmode=2,dmode=-2) then write 7,"16448",-13
	' default, 0x4000, new loopback feature
	write 7,str$(1),-11 		'volume in dB
	write 7,str$(-127),-12	'set volume to 0 firstly
	
	' reset fixed ramp rate, volume id db
	volfd =- 127 : fact = 96

	link 4,7,dst                     	'new Petr audio tunnel
	if wmode<>WMODE_TD then 
		gosub 360   							'try start anyway if some sockets exist, 2009/12/01
		write 4,"*",1,sdst					'wake up remote Connection Status
	endif
	return

360 'set source destination sockets in order to start sending
	talk=0
	LOCK 1
	for i=0 to 7
		dst(i,0)=sdst(i,0) : dst(i,1)=sdst(i,1) : if dst(i,0) then talk=1
	next i
	LOCK 0
	return
	
370 'reset source destination sockets to 0 in order to block sending
	LOCK 1
	for i=0 to 7
		dst(i,0)=0 : dst(i,1)=0
	next i
	LOCK 0
	talk=0
	return

380 'get new destination IP:port for passive (learned)
	for i=0 to 7 ' up to maximum of 8 channels
		if and(sprintf$("%lA",sdst(i,0))=rhost$, sdst(i,1)=rport) then ' already exists ?
			'syslog "channel already exist, updating timer"
			tdst(i) = _TMR_(0) : return 'update timer for this channel
		endif
	next i
	for i=0 to 7 ' get the first free slot
		if and(sdst(i,0)=0,sdst(i,1)=0) then
			syslog "Added BRTP channel: ["+str$(i)+"] -> "+rhost$+":"+str$(rport)
			sdst(i,0)=resolve(rhost$) : sdst(i,1)=rport : tdst(i)=_TMR_(0)
			gosub 360
			' wake up the "Connection Status" after usb playing if ka=passive
			write 4,"!"+IL$,10,rhost$,rport
			return
		endif
	next i
	syslog "BRTP table is full, no possibility to add: "+rhost$+":"+str$(rport)
	return
	
390 'check timers for BRTP table
	for i = 0 to 7
		if and(tdst(i), _TMR_(0)-tdst(i) > 30000) then 'channel timer is exhausted
			syslog "Deleted by timer BRTP channel: ["+str$(i)+"] -> "+&
				sprintf$("%lA",dst(i,0))+":"+str$(dst(i,1))
			sdst(i,0) = 0 : sdst(i,1) = 0 : tdst(i) = 0
			gosub 360 : return
		endif
	next i
	return
'------------------------------------------------------------------------------
'--- serial gateway, bgn ------------------------------------------------------
'------------------------------------------------------------------------------
30001
'------------------------------------------------------------------------------
    read 1,_Mb$ : lb = lastlen(1)
    if lb > 0 then
       if com1p > 0 then if rh1$ then write 5,_Mb$,lb,rh1$,rp1 else write 5,_Mb$,lb,rhost$,com1p
       if com1p < 0 then if mediatype(5) then if connected(5) then write 5,_Mb$,lb
    endif
    return
'------------------------------------------------------------------------------
30002
'------------------------------------------------------------------------------
    read 2,_Mb$ : lb = lastlen(2)
    if lb > 0 then
       if com2p > 0 then if rh2$ then write 6,_Mb$,lb,rh2$,rp2 else write 6,_Mb$,lb,rhost$,com2p
       if com2p < 0 then if mediatype(6) then if connected(6) then write 6,_Mb$,lb
    endif
    return
'------------------------------------------------------------------------------
30005 rh1$=rmthost$(5) : rp1=rmtport(5) : read 5,_Mb$ : write 1,_Mb$,-lb : return
'------------------------------------------------------------------------------
30006 rh2$=rmthost$(6) : rp2=rmtport(6) : read 6,_Mb$ : write 2,_Mb$,-lb : return
'------------------------------------------------------------------------------
30007 read 5,_Mb$ : lb = lastlen(5) : write 1,_Mb$,lb : return
'------------------------------------------------------------------------------
30008 read 6,_Mb$ : lb = lastlen(6) : write 2,_Mb$,lb : return
'------------------------------------------------------------------------------
30050 'open com port
'------------------------------------------------------------------------------
    if i = 1 then ofs = 81 'setup offset for COM1
    if i = 2 then ofs = 84 'setup offset for COM2

    com$="COM:"
    comb=midget(set$,ofs+1,1)
    if comb=0 then com$=com$+"38400,"
    if comb=1 then com$=com$+"19200,"
    if comb=2 then com$=com$+"9600,"
    if comb=3 then com$=com$+"4800,"
    if comb=4 then com$=com$+"2400,"
    if comb=5 then com$=com$+"1200,"
    if comb=6 then com$=com$+"600,"
    if comb=7 then com$=com$+"300,"
    if comb=8 then com$=com$+"115200,"
    if comb=9 then com$=com$+"57600,"
    if comb=10 then com$=com$+"230400,"
    if comb=11 then com$=com$+"76800,"

    comb=midget(set$,ofs,1)
    if and(comb,&H30)=0 then com$=com$+"N,"
    if and(comb,&H30)=&H30 then com$=com$+"E,"
    if and(comb,&H30)=&H10 then com$=com$+"O,"

    if and(comb,4) then com$=com$+"8," else com$=com$+"7,"

    if and(comb,128) then com$=com$+"2," else com$=com$+"1,"

    comb=midget(set$,ofs+2,1)
    if comb=0 then com$=com$+"NON:"
    if comb=1 then com$=com$+"SFW:"
    if comb=2 then com$=com$+"HDW:"
    if comb=8 then com$=com$+"485:"

    com$=com$+str$(i)   'number of serial port
    syslog "serial> "+com$
    open com$ as i 'open serial port for the gateway

    return
'------------------------------------------------------------------------------
'--- serial gateway, end ------------------------------------------------------
'------------------------------------------------------------------------------
' SMTP Subroutine - Used to send an email message
'
' The following variables must be defined before calling:
'
'       mserv$ : The address of the SMTP server
'       mfrom$ : The from email address (from@host.com)
'       mto$   : The to email addresses (to1@host1.com,to2@host2.com,...)
'       msubj$ : The email message subject
'       mbody$ : The body text of the email
'
' Uses File Handle 0 for TCP I/O
'------------------------------------------------------------------------------

2300 if mfrom$ = "" then syslog "Empty e-mail address FROM. SUBJ: "+ msubj$ goto 2302
     if mto$   = "" then syslog "Empty e-mail address TO. SUBJ: "  + msubj$ goto 2302

     open "TCP:"+sprintf$("%lA",RESOLVE(mserv$))+":25" as 0
     if mediatype(0) = 0 then syslog "SMTP server ("+mserv$+") is wrong!"   goto 2301

     tmout = 3000 'max time for e-mail sending in order not to break audio connection
     timer 1,tmout 'set waiting timer

2010 if connected(0) = 0 then               if _TMR_(1) then goto 2010 else goto 2301

     syslog mserv$
     write 0,"HELO STL\r\n",0
2011 read  0,tmp$,0 : if len(tmp$) = 0 then if _TMR_(1) then goto 2011 else goto 2301


     syslog mfrom$
     write 0,"MAIL FROM: <" + mfrom$ + ">\r\n",0
2012 read  0,tmp$,0 : if len(tmp$) = 0 then if _TMR_(1) then goto 2012 else goto 2301

     j = 0
2303 i = j + 1 : j = instr(i,mto$,",")
     if j then tmp$ = mid$(mto$,i,j-i) else tmp$ = mid$(mto$,i)
     syslog tmp$ 'part of mto$
     write 0,"RCPT TO: <" + tmp$ + ">\r\n",0
2013 read  0,tmp$,0 : if len(tmp$) = 0 then if _TMR_(1) then goto 2013 else goto 2301
     if j then goto 2303 'repeat for some addresses

     write 0,"DATA\r\n",0
2014 read  0,tmp$,0 : if len(tmp$) = 0 then if _TMR_(1) then goto 2014 else goto 2301

     syslog msubj$
     write 0,"From: "    + mfrom$ + "\r\n",0
     write 0,"Subject: " + msubj$ + "\r\n",0
     write 0,"To: "      + mto$   + "\r\n",0
     write 0,"Content-Type: text/html\r\n",0
     write 0,                       "\r\n",0
    'write 0,              mbody$ + "\r\n",0
     write 0,        "<html><head></head>",0
     write 0,             "<body bgcolor=",0
     write 0,                         MSG$,0
     write 0,             "</body></html>",0
     write 0,                  "\r\n.\r\n",0 'EOM
2015 read  0,tmp$,0 : if len(tmp$) = 0 then if _TMR_(1) then goto 2015 else goto 2301
     syslog mbody$

     write 0,"QUIT\r\n",0
2016 read  0,tmp$,0 : if len(tmp$) = 0 then if _TMR_(1) then goto 2016 else goto 2301

2301 if mediatype(0) then close 0
     if _TMR_(1) = 0 then syslog "ERROR : incomplete SMTP sending."
     gosub 2501
2302 '''mto$ = "" 'to prevent sending to nobody
     return
'------------------------------------------------------------------------------
2500 syslog "end of waiting SMTP sending for "+str$(tmout)
'------------------------------------------------------------------------------
2501 timer 1,0
     _TMR_(1) = 0 'drop flag _TMR_(1)
     return

399 ' open mp3
	open "AUD:1,0,0,0" as 7
	write 7,str$(vol),-12
	delay 450 ' workaround to avoid first part lost on MICRONAS volume rump-up devices
	return

' try to autoplay from USB (open if not, and play a chunk)
400
	if file$="" then
		' opening/getting next file from "playlist.m3u"
		badpf=0 : gosub 450
		if file$="" then return
		' new file has been found, close and re-opening audio here
		if mediatype(7) then close 7
		gosub 399
	endif
	if mediatype(9)=0 then open "C_R:usb:///"+file$ as 9
	if mediatype(9)=0 then
		' bad file
		if badpf=0 then syslog "ERROR : can't find playlist file "+file$
		badpf=1
		return		
	endif

	msg$ = "'yellow'> Autoplay: "+file$    'playback...
401
	if filesize(7)<4096 then return        'is there free buffer enough ?
	l=0 : if mediatype(9) then read 9,_Ms$ : l=lastlen(9)
	if l>0 then write 7,_Ms$,l : goto 401  ' add to play buffer until it's near to be full
	' l<=0 = EOF
   if mediatype(9) then close 9           ' end of the current file
	if msgfl then msgfl=0						' end of message, re-check the application status

	close 7, 1 : file$=""
	if pllst then gosub 400 ' restart needed imediately to avoid stream error readin 7
	return

' play by USB playlist file "playlist.m3u"
450
	syslog "getting next playlist file"
	if mediatype(8)=0 then open "C_R:usb:///playlist.m3u" as 8 'check playlist
	if mediatype(8)=0 then syslog "ERROR : playlist not found." : return
	pllst=1
451
	read 8,tmp$,0
	if len(tmp$)>0 then
		if instr(1,UCASE$(tmp$),".MP3") = 0 then goto 451 'miss all other files (except MP3)
		file$ = tmp$ : syslog "Start autoplay: "+file$
		return
	endif
	close 8 : goto 450 'start playlist again
	return

' get message file
460
	if mediatype(7) then close 7 ' finish audio tunnel for using by message play
	if mediatype(9) then close 9 ' if playlist is playing, just reset
	file$="_MSG_"+str$(msgfl)+".MP3"
	gosub 399

	return
'------------------------------------------------------------------------------

500 ' initiate a standard BRTP stream request
	
	if rdst=2 then
		'syslog "sending BRTP announcment"
		'syslog "dest : " + sprintf$("%lA",mdst(0,0)) + ":" + str$(mdst(0,1))
		write 4,"BRX ",4,sprintf$("%lA",mdst(0,0)),mdst(0,1)
	endif
	return

550 ' alarm, set/unset the alarm
	LOCAL alrm,state
	if state then
		amask=or(amask,shl(1,alrm))
	else
		amask=and(amask,not(shl(1,alrm)))
	endif
	return
	
600 ' get status string
	'syslog "connection state changed: confl="+str$(confl)+" ocnfl="+str$(ocnfl)
	_S02$="CST "
	on confl+1 goto 601,602,603,604
601 _S02$=_S02$+"No keep-alive info" : goto 610
602 _S02$=_S02$+"Established TO "+rhost$+":"+str$(rport) : goto 610
603 _S02$=_S02$+"Established FROM "+rhost$+":"+str$(rport) : goto 610
604 _S02$=_S02$+"Only Stream FROM "+rhost$+":"+str$(rport) : goto 610

610 if and(ocnfl>0,confl=0) then alarm(ALARM_CONN_LOST,1)
	 if and(confl>0,ocnfl=0) then alarm(ALARM_CONN_LOST,0)

	return

650 ' alsnd alarm, preparing texts
	LOCAL als,set

	if set<>0 then set=1
	x=1000+(shl(als,1))+set

	_S40$="ALARM "
	if set then ' apply string for severity
		_S40$=_S40$+mid$(sev$,1+(shr(apara(als),4)*3),3)
	else
		_S40$=_S40$+mid$(sev$,1+(and(apara(als),&H0f)*3),3)
	endif
	on als+1 goto 651,652,653,654 ' .. etc, apply alarm descriptions
651	_S40$=_S40$+" CONNECTION_LOST"
		algen$="Connection lost for keep alive missing" : goto 690
652	_S40$=_S40$+" NO_INCOMING_STREAM"
		algen$="Incoming stream missing" : goto 690
653
654
690 if set=0 then _S40$=_S40$+"_CLEARED " else _S40$=_S40$+" "
	_S40$=_S40$+algen$ ' append general text
	syslog "SENDING ALARM: "+_S40$
	for i=0 to 3 ' ready, fire
		if snmpd(i) then trap sprintf$("%lA",snmpd(i)),6,x,"P1.3.0","E3.1.1.0","E1.5.1.1.1.2.40"
	next i
	alsnd=0
	return

700 ' alarm, sending, once for all
	for atmp=0 to 31
		if and(amask,shl(1,atmp)) then ' alarm is set
			if and(omask,shl(1,atmp))=0 then alsnd(atmp,1) ' sending SET  if it was not set only
		else
			if and(omask,shl(1,atmp)) then alsnd(atmp,0) ' sending CLEAR if it was set only
		endif
	next atmp
	omask=amask
	alarm=0
	return

10000 'sread
	LOCAL val1
	open "STP:"+str$(val1) as 0 : read 0,set$ : close 0
	sread=1
	return
	
10100 'ssave
	LOCAL val2
	open "STP:"+str$(val2) as 0 : write 0,set$,256 : close 0
	ssave=1
	return

10200
	'fade volume to 0 before message
	if volfd>-32 then
		' syslog "ramping down, volfd="+str$(volfd)
		volfd=volfd-1 : write 7,str$(volfd),-12
		if volfd<=-32 then volfd=-127
	else
		' undefined
		volfd=-127
	endif
	'close gateway/tunnel and get message file
	if volfd=-127 then syslog "Playing message" : gosub 460
	return

10300
	'restore ramp volume to vol
	if volfd<vol+1 then
		if fact>1 then fact=shr(fact,1)
		volfd=volfd+fact : write 7,str$(volfd),-12
	endif
	return

' calcd
' AD 22.10.2010
' initial implementation of this application was detecting the stream using
' the buf=bufhi/10 algorithm.
' This detection was tested and well working. So with the introduction of
' the msec delay, bufhi in bytes is reconstructed starting from msec delay.

10400
	LOCAL Bps

	if mp3fl then
		' bitrate depend on quality
		' using minimal bitrate
		Bps=4625
	else
		x=and(shr(qlty,8),2)		' format
		j=and(qlty,&Hff)			' Khz
		i=and(shr(qlty,12),1)	' stereo
		if or(x=0,x=1) then
			' uLaw, aLaw
			Bps=j*1000 ' 8 bit samples
		else ' PCM
			Bps=j*1000*2 ' 16 bit samples
		endif
		if i then Bps=shl(Bps,1)
	endif
	' Bps : 1 = x : mdelay
	calcd=msdel*Bps/1000

	return

end

