Asterisk AGI script falls when caller hangup - asterisk

I'm having the simple AGI script, I need to dial 101 extension by calling 6666 number and calculate answered time after call. Everything works fine when callee hangup, but when caller hangup agi script falls with returning 4.
Sorry for my English)
agi.php
#!/usr/bin/php -q
<?php
require('include/phpagi.php');
$agi = new AGI();
$agi->answer();
$agi->exec("Dial", "SIP/101");
$result = $agi->get_variable("ANSWEREDTIME");
file_put_contents("/tmp/test.txt", json_encode($result));
$agi->hangup();
?>
**sip.conf**
[general]
externaddr=51.15.53.237:5060
localnet=10.18.222.53/255.255.255.0 ; локальная сеть
language=ru
context=default
allowoverlap=no
udpbindaddr=0.0.0.0
tcpenable=no
tcpbindaddr=0.0.0.0
transport=udp
srvlookup=yes
allowguest=no
limitonpeers=yes
[authentication]
[managers-phones](!)
type=friend
context=call-out
secret=qwerty
host=dynamic
nat=yes
qualify=yes
canreinvite=no
callgroup=1
pickupgroup=1
call-limit=5
dtmfmode=auto
disallow=all
allow=alaw
allow=ulaw
allow=g729
allow=g723
allow=g722
[100](managers-phones)
callerid="Number 100" <100>
[101](managers-phones)
callerid="Number 101" <101>
**extensions.conf**
[general]
static=yes
writeprotect=no
[globals]
[default]
[handup-sip]
exten => _X!,1,HangUp()
[call-out]
exten => 6666,1,AGI(agi.php)
exten => _XXX,1,Dial(SIP/${EXTEN})
include => handup-sip
Console output when callee hangup:
== Using SIP RTP CoS mark 5
> 0x7fabe000deb0 -- Strict RTP learning after remote address set to: 176.213.58.47:7078
-- Executing [6666#call-out:1] AGI("SIP/100-00000016", "agi.php") in new stack
-- Launched AGI Script /var/lib/asterisk/agi-bin/agi.php
<SIP/100-00000016>AGI Tx >> agi_request: agi.php
<SIP/100-00000016>AGI Tx >> agi_channel: SIP/100-00000016
<SIP/100-00000016>AGI Tx >> agi_language: ru
<SIP/100-00000016>AGI Tx >> agi_type: SIP
<SIP/100-00000016>AGI Tx >> agi_uniqueid: 1594145722.33
<SIP/100-00000016>AGI Tx >> agi_version: 16.11.1
<SIP/100-00000016>AGI Tx >> agi_callerid: 100
<SIP/100-00000016>AGI Tx >> agi_calleridname: Number 100
<SIP/100-00000016>AGI Tx >> agi_callingpres: 0
<SIP/100-00000016>AGI Tx >> agi_callingani2: 0
<SIP/100-00000016>AGI Tx >> agi_callington: 0
<SIP/100-00000016>AGI Tx >> agi_callingtns: 0
<SIP/100-00000016>AGI Tx >> agi_dnid: 6666
<SIP/100-00000016>AGI Tx >> agi_rdnis: unknown
<SIP/100-00000016>AGI Tx >> agi_context: call-out
<SIP/100-00000016>AGI Tx >> agi_extension: 6666
<SIP/100-00000016>AGI Tx >> agi_priority: 1
<SIP/100-00000016>AGI Tx >> agi_enhanced: 0.0
<SIP/100-00000016>AGI Tx >> agi_accountcode:
<SIP/100-00000016>AGI Tx >> agi_threadid: 140374906681088
<SIP/100-00000016>AGI Tx >>
<SIP/100-00000016>AGI Rx << ANSWER
> 0x7fabe000deb0 -- Strict RTP switching to RTP target address 176.213.58.47:7078 as source
<SIP/100-00000016>AGI Tx >> 200 result=0
<SIP/100-00000016>AGI Rx << EXEC Dial SIP/101
-- AGI Script Executing Application: (Dial) Options: (SIP/101)
== Using SIP RTP CoS mark 5
-- Called SIP/101
-- SIP/101-00000017 is ringing
> 0x7fabd000cb70 -- Strict RTP learning after remote address set to: 176.213.58.47:8000
-- SIP/101-00000017 answered SIP/100-00000016
-- Channel SIP/101-00000017 joined 'simple_bridge' basic-bridge <dafb98ba-3e18-4c2e-a51c-46f2f7cc7f5b>
-- Channel SIP/100-00000016 joined 'simple_bridge' basic-bridge <dafb98ba-3e18-4c2e-a51c-46f2f7cc7f5b>
> Bridge dafb98ba-3e18-4c2e-a51c-46f2f7cc7f5b: switching from simple_bridge technology to native_rtp
> Locally RTP bridged 'SIP/100-00000016' and 'SIP/101-00000017' in stack
> 0x7fabd000cb70 -- Strict RTP switching to RTP target address 176.213.58.47:8000 as source
> 0x7fabe000deb0 -- Strict RTP learning complete - Locking on source address 176.213.58.47:7078
-- Channel SIP/101-00000017 left 'native_rtp' basic-bridge <dafb98ba-3e18-4c2e-a51c-46f2f7cc7f5b>
-- Channel SIP/100-00000016 left 'native_rtp' basic-bridge <dafb98ba-3e18-4c2e-a51c-46f2f7cc7f5b>
<SIP/100-00000016>AGI Tx >> 200 result=-1
<SIP/100-00000016>AGI Rx << GET VARIABLE ANSWEREDTIME
<SIP/100-00000016>AGI Tx >> 200 result=1 (6)
<SIP/100-00000016>AGI Rx << HANGUP
<SIP/100-00000016>AGI Tx >> 200 result=1
-- <SIP/100-00000016>AGI Script agi.php completed, returning 4
== Spawn extension (call-out, 6666, 1) exited non-zero on 'SIP/100-00000016'
Console output when caller hangup:
== Using SIP RTP CoS mark 5
> 0x7fabe000deb0 -- Strict RTP learning after remote address set to: 176.213.58.47:7078
-- Executing [6666#call-out:1] AGI("SIP/100-0000001e", "agi.php") in new stack
-- Launched AGI Script /var/lib/asterisk/agi-bin/agi.php
<SIP/100-0000001e>AGI Tx >> agi_request: agi.php
<SIP/100-0000001e>AGI Tx >> agi_channel: SIP/100-0000001e
<SIP/100-0000001e>AGI Tx >> agi_language: ru
<SIP/100-0000001e>AGI Tx >> agi_type: SIP
<SIP/100-0000001e>AGI Tx >> agi_uniqueid: 1594145890.45
<SIP/100-0000001e>AGI Tx >> agi_version: 16.11.1
<SIP/100-0000001e>AGI Tx >> agi_callerid: 100
<SIP/100-0000001e>AGI Tx >> agi_calleridname: Number 100
<SIP/100-0000001e>AGI Tx >> agi_callingpres: 0
<SIP/100-0000001e>AGI Tx >> agi_callingani2: 0
<SIP/100-0000001e>AGI Tx >> agi_callington: 0
<SIP/100-0000001e>AGI Tx >> agi_callingtns: 0
<SIP/100-0000001e>AGI Tx >> agi_dnid: 6666
<SIP/100-0000001e>AGI Tx >> agi_rdnis: unknown
<SIP/100-0000001e>AGI Tx >> agi_context: call-out
<SIP/100-0000001e>AGI Tx >> agi_extension: 6666
<SIP/100-0000001e>AGI Tx >> agi_priority: 1
<SIP/100-0000001e>AGI Tx >> agi_enhanced: 0.0
<SIP/100-0000001e>AGI Tx >> agi_accountcode:
<SIP/100-0000001e>AGI Tx >> agi_threadid: 140374906681088
<SIP/100-0000001e>AGI Tx >>
<SIP/100-0000001e>AGI Rx << ANSWER
> 0x7fabe000deb0 -- Strict RTP switching to RTP target address 176.213.58.47:7078 as source
<SIP/100-0000001e>AGI Tx >> 200 result=0
<SIP/100-0000001e>AGI Rx << EXEC Dial SIP/101
-- AGI Script Executing Application: (Dial) Options: (SIP/101)
== Using SIP RTP CoS mark 5
-- Called SIP/101
-- SIP/101-0000001f is ringing
> 0x7fac0000c120 -- Strict RTP learning after remote address set to: 176.213.58.47:8000
-- SIP/101-0000001f answered SIP/100-0000001e
-- Channel SIP/101-0000001f joined 'simple_bridge' basic-bridge <e8f305f8-5d84-4ae7-8be5-babcdefdb5ef>
-- Channel SIP/100-0000001e joined 'simple_bridge' basic-bridge <e8f305f8-5d84-4ae7-8be5-babcdefdb5ef>
> Bridge e8f305f8-5d84-4ae7-8be5-babcdefdb5ef: switching from simple_bridge technology to native_rtp
> Locally RTP bridged 'SIP/100-0000001e' and 'SIP/101-0000001f' in stack
> 0x7fac0000c120 -- Strict RTP switching to RTP target address 176.213.58.47:8000 as source
-- Channel SIP/101-0000001f left 'native_rtp' basic-bridge <e8f305f8-5d84-4ae7-8be5-babcdefdb5ef>
-- Channel SIP/100-0000001e left 'native_rtp' basic-bridge <e8f305f8-5d84-4ae7-8be5-babcdefdb5ef>
<SIP/100-0000001e>AGI Tx >> 200 result=-1
<SIP/100-0000001e>AGI Rx << GET VARIABLE ANSWEREDTIME
<SIP/100-0000001e>AGI Tx >> 200 result=1 (4)
<SIP/100-0000001e>AGI Rx << HANGUP
<SIP/100-0000001e>AGI Tx >> 200 result=1
-- <SIP/100-0000001e>AGI Script agi.php completed, returning 4
== Spawn extension (call-out, 6666, 1) exited non-zero on 'SIP/100-0000001e'
As a result when caller hangup there is no file /tmp/test.txt, but when callee hangup there is. Where is problem?
Asterisk 16 LTS builded from source
PHP 7.2.24-0ubuntu0.18.04.6

I do not know what exactly you need to do, but if you want some data after call happened then, I think proper approach will be to run hangup script. Check out how hangup scripts works - h extension and hangup handlers:
https://wiki.asterisk.org/wiki/display/AST/Hangup+Handlers
In your case you are trying still do something on dead channel what is not correct approach.

Related

MAX14830 not flushing TX

So after a day of struggling I managed to get Debian 11 on a IMX7D, 5.4.129 kernel to recognize the MAX14830 and talk to it via the MAX310X driver. But when I try to send data with echo a > /dev/ttyMAX0 nothing happens. Well except the Tx count going up.
Looking at the SPI traffic this seems to be going correctly and the chip is sending the expected responses (Tx FIFO count returns three if three characters are being send) but nothing seems to happen to the buffer. The driver keeps interrogating the max but the FIFO stays at 3. Then the driver reaches a timeout I guess. Because it then sends 0x81,0x00 which clears the IRQen register, followed by 0x9B 0x40 which sets the baudrate register... which makes it all the more confusing.
So far I've gone through all the stty settings and used -ixon to disable XON/XOFF but that didn't make a difference.
Is there a way/place/file that holds the settings for the driver? Or am I forgetting something? RX doesn't seem to work either but not sure if the max isn't receiving it or just not informing the driver.
The relevant portion of the DTS
&ecspi3 {
max14830: max14830#3 {
compatible = "maxim,max14830";
spi-max-frequency = <15000000>;
reg = <0>; // SPI chip select number
clocks = <&clk16m0>;
clock-names = "osc";
interrupt-parent = <&gpio5>;
interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
gpio-controller; // Marks the device node as a GPIO controller
#gpio-cells = <2>;
clk16m0: clk16m0 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <3686400>; // freq of external xtal
clock-accuracy = <100>;
};
};
};
And the comms during startup
OUT IN MEANING
0x9F 0xCE -> Write globalCmd = Enable Extend register map acces
0x05 0x00 -> 0x0F 0xB4 -> Clear SpclChrIntEn= RevID is B4
0x9F 0xCD -> Write globalCmd = Disable Extend register map access
0x8A 0x01 -> Write UART0 Mode2 = Set RST
0x8A 0x00 -> Write UART0 Mode2 = Clear RST
0x1C 0x00 -> 0x0F 0x01 -> Read UART0 DivLSB = Div0 set
0x89 0x80 -> Set UART0 MODE1 = ~RTS0 is three state
0xAA 0x01 -> Write UART1 Mode2 = Set RST
0xAA 0x00 -> Write UART1 Mode2 = Clear RST
0x3C 0x00 -> 0x0F 0x01 -> Read UART1 DivLSB = Div0 set
0xA9 0x80 -> Set UART1 MODE1 = ~RTS1 is three state
0xCA 0x01 -> Write UART2 Mode2 = Set RST
0xCA 0x00 -> Write UART2 Mode2 = Clear RST
0x5C 0x00 -> 0xF 0x01 -> Read UART2 DivLSB = Div0 set
0xC9 0x80 -> Set UART2 MODE1 = ~RTS2 is three state
0xEA 0x01 -> Write UART3 Mode2 = Set RST
0xEA 0x00 -> Write UART3 Mode2 = Clear RST
0x7C 0x00 -> 0x0F 0x01 -> Read UART3 DivLSB = Div0 set
0xE9 0x80 -> Set UART3 MODE1 = ~RTS3 is three state
0x9A 0x44 -> Write PLLConfig = Set PreDiv5 and PreDiv2
0x9E 0x14 -> Write ClockSource = 0001 0100 -> first 1 at dont care, second PLLen
0x81 0x00 -> Clear IRQen UART0
0x02 0x00 -> 0x0F 0x60 -> Read ISR UART0 = both fifo empty
0x1B 0x00 -> 0x0F 0x00 -> Read BRConfig UART0 -> all clear
0x9B 0x40 -> Write BRConfig UART0 -> FRACT2 Set
0xA1 0x00 -> Clear IRQen UART1
0x22 0x00 -> 0x0F 0x60 -> Read ISR UART1 = both fifo empty
0x3B 0x00 -> 0x0F 0x00 -> Read BRConfig UART1 -> all clear
0xBB 0x40 -> Write BRConfig UART1 -> FRACT2 Set
0xC1 0x00 -> Clear IRQen UART2
0x42 0x00 -> 0x0F 0x60 -> Read ISR UART2 = both fifo empty
0x58 0x00 -> 0x0F 0x00 -> Read BRConfig UART2 -> all clear
0xDB 0x40 -> Write BRConfig UART2 -> FRACT2 Set
0xE1 0x00 -> Clear IRQen UART3
0x62 0x00 -> 0x0F 0x60 -> Read ISR UART3 = both fifo empty
0x7B 0x00 -> 0x0F 0x00 -> Read BRConfig UART3 -> all clear
0xFB 0x40 -> Write BRConfig UART3 -> FRACT2 Set
ttyMAX0 setup according to stty
Result of stty -F /dev/ttyMAX0
-parenb -> don't generate parity
-parodd -> Even parity?
-cmspar -> No stick parity
cs8 -> character size 8 bits
hupcl -> don't send hangup signal
-cstopb -> use one bit per character
cread -> allow input to be received
clocal -> disable modem control signals
-crtscts -> dont enable rts/cts handschaking
-ignbr -> don't ignore break characters
-brkint -> breaks don't cause an interrupt signal
-ignpar -> don't ignore characters with parity errors
-parmrk -> don't mark parity errors
-inpck -> don't enable parity checking
-istrip -> don't clear high (8th) bit of input characters
-inlcr -> dont translate newline to carriage return
-igncr -> don't ignore carriage return
icrnl -> don't translate carriage return to newline
-ixon -> disable XON/XOFF flow control
-ixoff -> disable sending of start/stop characters
-iuclc -> don't translate uppercase to lowercase
-ixany -> Don't let any character restart output
-imaxbel -> don't beep and flush
-iutf8 -> don't assume characters are utf8 encoded
OUTPUT SETTINGS
opost -> post process output
-olcuc -> don't translate lower to upper
-ocrnl -> don't translate carriage return to newline
onlcr -> translate newline to carriage return newline
-onocr -> print carriage return in the first column
-onlret -> newline doesn't perform a carriage return
-ofill -> don't use fill characters instead of timing for delays
-ofdel -> don't use delete character for fill instead of null
nl0
cr0
tab0 -> horizontal tab delay style 0
bs0
vt0
ff0 -> form feed delay style
isig -> enable interrpt,
icanon -> enable special characters: erase, kill, werase, rprnt
iexten -> enable non-POSIX special characters
echo -> echo input characters
echoe -> echo erase characters as backspace-space-backspace
echok -> echo a newline after a kill character
-echonl
-noflsh -> don't disable flushing after interrupt & quit special
chars
-xcase
-tostop
-echoprt
echoctl -> echo control characters in hat notation ('^c')
echoke -> kill all line by obeying the echoprt and echoe settings
-flusho
-extproc
TX wasn't working because clock-names should have been xtal
RX wasn't working because i never opened the port but checked /proc/tty/driver/max310x for received data and the driver disables rx if a port isn't open.
Working node.
&ecspi3 {
/delete-node/spidev#0;
max14830: max14830#3 {
compatible = "maxim,max14830";
spi-max-frequency = <15000000>;
reg = <0>; // SPI chip select number
clocks = <&clk16m0>;
clock-names = "xtal"; /* because using external xtal */
interrupt-parent = <&gpio5>;
interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
gpio-controller; /* Marks the device node as a GPIO controller */
#gpio-cells = <2>;
clk16m0: clk16m0 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <3686400>; /* external xtal frequency */
clock-accuracy = <100>;
};
};
};
```

Pymodbus TCP Slave Busy

I've been trying to update someone else' software to work on a new machine.
They built a Modbus controller using the Pymodbus library to work with the main software.
The only difference between the original working machine and this new one is that the DAQ is different.
I had assumed going in that this would just mean changing addresses but probably due to my lack of knowledge about Pymodbus this has been very far from the case.
The main issue I am having right now is that is that I am trying to simply communicate with holding registers and the only response I can get back is "(131, 3, Slave Device Busy)".
I am really not sure what to do with this information, It happens as soon as it is started and nothing is able to change it.
Has anyone else had any experience where a device always outputting this same error code?
the DAQ I am using is a Aspar IO Slim Module MOD-ETH
Any advice would be much appreciated.
Thank you
J
(I would attached the code here but it is quite long and I'm not sure a snippet would really help but do let me know if it would be helpful)
Short test code
from pymodbus.client.sync import ModbusTcpClient as ModbusClient
import logging
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)
log.debug("Connecting to controller (IP=169.254.54.23, Port 502)")
client = ModbusClient('192.168.1.135', port=502)
59 #client = ModbusClient(method='ascii', port='/dev/pts/2', timeout=1)
60 # client = ModbusClient(method='rtu', port='/dev/ttyp0', timeout=1)
client.connect()
log.debug("Connected to controller (IP=192.168.1.135, Port 502)")
log.debug("Reading Sump Oil Temperature")
rr = client.read_holding_registers(1021, 1, unit=1)
log.debug("Read Sump Oil Temperature")
if rr.function_code > 0x80:
print( "Error has occured!\n" + str( rr.function_code ) + "\n" + str( rr.exception_code ) )
else:
print( rr.getRegister(0) )
client.close()
Response:
DEBUG:root:Connecting to controller (IP=169.254.54.23, Port 502)
DEBUG:root:Connected to controller (IP=192.168.1.135, Port 502)
DEBUG:root:Reading Sump Oil Temperature
DEBUG:pymodbus.transaction:Current transaction state - IDLE
DEBUG:pymodbus.transaction:Running transaction 1
DEBUG:pymodbus.transaction:SEND: 0x0 0x1 0x0 0x0 0x0 0x6 0x1 0x3 0x3 0xfd 0x0 0x1
DEBUG:pymodbus.client.sync:New Transaction state 'SENDING'
DEBUG:pymodbus.transaction:Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
DEBUG:pymodbus.transaction:Changing transaction state from 'WAITING FOR REPLY' to 'PROCESSING REPLY'
DEBUG:pymodbus.transaction:RECV: 0x0 0x1 0x0 0x0 0x0 0x3 0x1 0x83 0x6
DEBUG:pymodbus.framer.socket_framer:Processing: 0x0 0x1 0x0 0x0 0x0 0x3 0x1 0x83 0x6
DEBUG:pymodbus.factory:Factory Response[131]
DEBUG:pymodbus.transaction:Adding transaction 1
DEBUG:pymodbus.transaction:Getting transaction 1
DEBUG:pymodbus.transaction:Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'
DEBUG:root:Read Sump Oil Temperature
Error has occured!
131
6

How to list network devices in NASM (custom OS)

I have a custom, DOS-like OS built in NASM completely (no C code). It is very modest (it does have a FAT file system, few apps, is in real mode, etc.) I want to write a command that will list all the network devices (network cards) that are currently connected.
My assumptions go like this: I will need to write a driver for the network card (I'd put it manually inside kernel for simplicity, so dynamic loading would NOT exist), but it would be enough for that driver to just provide the name of the card, the network card wouldn't actually need to work. How do I tell the OS to connect that function to precisely that one network card? This is what I'm in the blue about, I have no idea how the OS usually matches a piece of hardware to code (its driver(s)).
Since it appears from your comments that you have Dosbox supporting an NE2000 card then the code below should detect the presence of an NE2000 card (A port base of 0x300 is assumed). The code is a DOS COM program I wrote and should be compilable with a command like nasm ne2kchk.asm -fbin -o ne2kchk.com
NS_DATAPORT EQU 0x10 ; NatSemi-defined port window offset.
NE_DATAPORT EQU 0x10 ; NatSemi-defined port window offset.
NS_RESET EQU 0x1f ; Issue a read to reset, a write to clear.
NE1SM_START_PG EQU 0x20 ; First page of TX buffer
NE1SM_STOP_PG EQU 0x40 ; Last page +1 of RX ring
NESM_START_PG EQU 0x40 ; First page of TX buffer
NESM_STOP_PG EQU 0x80 ; Last page +1 of RX ring
E8390_CMD EQU 0x00 ; The command register (for all pages)
E8390_STOP EQU 0x01 ; Stop and reset the chip
E8390_START EQU 0x02 ; Start the chip, clear reset
E8390_RREAD EQU 0x08 ; Remote read
E8390_NODMA EQU 0x20 ; Remote DMA
E8390_PAGE0 EQU 0x00 ; Select page chip registers
E8390_PAGE1 EQU 0x40 ; using the two high-order bits
E8390_PAGE2 EQU 0x80
E8390_PAGE3 EQU 0xC0 ; Page 3 is invalid on the real 8390.
E8390_RXOFF EQU 0x20 ; EN0_RXCR: Accept no packets
E8390_TXOFF EQU 0x02 ; EN0_TXCR: Transmitter off
; Page 0 register offsets.
EN0_CLDALO EQU 0x01 ; Low byte of current local dma addr RD
EN0_STARTPG EQU 0x01 ; Starting page of ring bfr WR
EN0_CLDAHI EQU 0x02 ; High byte of current local dma addr RD
EN0_STOPPG EQU 0x02 ; Ending page +1 of ring bfr WR
EN0_BOUNDARY EQU 0x03 ; Boundary page of ring bfr RD WR
EN0_TSR EQU 0x04 ; Transmit status reg RD
EN0_TPSR EQU 0x04 ; Transmit starting page WR
EN0_NCR EQU 0x05 ; Number of collision reg RD
EN0_TCNTLO EQU 0x05 ; Low byte of tx byte count WR
EN0_FIFO EQU 0x06 ; FIFO RD
EN0_TCNTHI EQU 0x06 ; High byte of tx byte count WR
EN0_ISR EQU 0x07 ; Interrupt status reg RD WR
EN0_CRDALO EQU 0x08 ; low byte of current remote dma address RD
EN0_RSARLO EQU 0x08 ; Remote start address reg 0
EN0_CRDAHI EQU 0x09 ; high byte, current remote dma address RD
EN0_RSARHI EQU 0x09 ; Remote start address reg 1
EN0_RCNTLO EQU 0x0a ; Remote byte count reg WR
EN0_RCNTHI EQU 0x0b ; Remote byte count reg WR
EN0_RSR EQU 0x0c ; rx status reg RD
EN0_RXCR EQU 0x0c ; RX configuration reg WR
EN0_TXCR EQU 0x0d ; TX configuration reg WR
EN0_COUNTER0 EQU 0x0d ; Rcv alignment error counter RD
EN0_DCFG EQU 0x0e ; Data configuration reg WR
EN0_COUNTER1 EQU 0x0e ; Rcv CRC error counter RD
EN0_IMR EQU 0x0f ; Interrupt mask reg WR
EN0_COUNTER2 EQU 0x0f ; Rcv missed frame error counter RD
PORT_BASE EQU 0x300 ; Default base port
[BITS 16]
org 0x100
section .text
start:
push cs
pop ds
; Probe for NE2000 card
; Try non destructive test first
mov dx, PORT_BASE+E8390_CMD
in al, dx
cmp al, 0xff
jz .s_notfound
; Attempt potentially destuctive tests
mov al, E8390_NODMA | E8390_PAGE1 | E8390_STOP
mov dx, PORT_BASE+E8390_CMD
out dx, al ; Receive alignment error counter
mov dx, PORT_BASE+EN0_COUNTER0
in al, dx
mov cl, al ; Save to REGD (CL)
mov al, 0xff
out dx, al
mov al, E8390_NODMA | E8390_PAGE0
mov dx, PORT_BASE+E8390_CMD
out dx, al
mov dx, PORT_BASE+EN0_COUNTER0
in al, dx ; Clear the counter by reading.
test al, al
jz .s_found ; If al is clear then card was found
; Card not found
.s_notfound:
xchg al, cl ; Temporarily save al to avoid clobber
out dx, al
mov ah, 0x09
mov dx, notfound_str
int 0x21
xchg al, cl ; Restore al. al = error value to return
jmp .s_exit
; Card found
.s_found:
mov ah, 0x09
mov dx, found_str
int 0x21
xor al, al ; Clear the error code
; exit with al = errcode
.s_exit:
mov ah, 0x4C
int 0x21
notfound_str db "NE2000 not found", 0x0a, 0x0d, "$"
found_str db "NE2000 found", 0x0a, 0x0d, "$"
The code above is an adaptation of "C" code that I found in the Debian nictool code available here . It can be found in the file ne2k-diags.c. It seems more information (datasheets) are available for the rtl8019 which is a clone of the NE2000. The 8390NIC that is at the heart of these devices is documented here. The 8390 documentation discusses how to send and receive data. An excerpt of the "C" code that I based mine on was:
printf("Checking the ethercard at %#3x.\n", port_base);
{ int regd;
long ioaddr = port_base;
outb_p(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD);
regd = inb_p(ioaddr + 0x0d);
printk(" Receive alignment error counter (%#lx) is %2.2x\n",
ioaddr + 0x0d, regd);
outb_p(0xff, ioaddr + 0x0d);
outb_p(E8390_NODMA+E8390_PAGE0, ioaddr + E8390_CMD);
inb_p(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */
if (inb_p(ioaddr + EN0_COUNTER0) != 0) {
outb(regd, ioaddr + 0x0d); /* Restore the old values. */
printk(" Failed initial NE2000 probe, value %2.2x.\n",
inb(ioaddr + EN0_COUNTER0));
} else
printk(" Passed initial NE2000 probe, value %2.2x.\n",
inb(ioaddr + EN0_COUNTER0));
}
The code above is the initial probe but there is more "C" code in the same file that tries to detect some of the specific variants and query the card signature.

Scenario where HTTP Response is not fragmented but request is fragmented

In our application, we are using apache tomcat webserver running in 8081.
We observed one behavior where HTTP POST Requests from clients are getting fragmented whereas HTTP Response "200 OK" is not getting fragmented. This we observed by collecting iptraces.
Our ETH MTU value is 1500 Bytes.
Sample POST Request which is fragmented:
===( 331 bytes received on interface en0 )==== 13:50:01.040393849
ETHERNET packet : [ 00:26:cb:eb:df:7f -> 00:1a:64:47:3c:02 ] type 800 (IP)
IP header breakdown:
< SRC = 172.30.17.142 >
< DST = 10.16.0.72 > (un51sv01_if0)
ip_v=4, ip_hl=20, ip_tos=0, ip_len=317, ip_id=57225, ip_off=0 DF
ip_ttl=62, ip_sum=942d, ip_p = 6 (TCP)
TCP header breakdown:
<source port=43795, destination port=8081 >
th_seq=2849969884, th_ack=3790782429
th_off=5, flags<PUSH | ACK>
th_win=49680, th_sum=ba63, th_urp=0
00000000 504f5354 202f6973 61736f61 702f656e |POST /isasoap/en|
00000010 64706f69 6e742f49 6e766f6b 65417070 |dpoint/InvokeApp|
00000020 53657276 69636549 46204854 54502f31 |ServiceIF HTTP/1|
00000030 2e310d0a 436f6e74 656e742d 54797065 |.1..Content-Type|
00000040 3a207465 78742f78 6d6c3b20 63686172 |: text/xml; char|
00000050 7365743d 7574662d 380d0a41 63636570 |set=utf-8..Accep|
00000060 743a2074 6578742f 786d6c2c 20746578 |t: text/xml, tex|
00000070 742f6874 6d6c2c20 696d6167 652f6769 |t/html, image/gi|
00000080 662c2069 6d616765 2f6a7065 672c202a |f, image/jpeg, *|
00000090 3b20713d 2e322c20 2a2f2a3b 20713d2e |; q=.2, */*; q=.|
000000a0 320d0a53 4f415041 6374696f 6e3a2022 |2..SOAPAction: "|
000000b0 220d0a55 7365722d 4167656e 743a204a |"..User-Agent: J|
000000c0 6176612f 312e362e 305f3831 0d0a486f |ava/1.6.0_81..Ho|
000000d0 73743a20 31302e31 362e302e 37323a38 |st: 10.16.0.72:8|
000000e0 3038310d 0a436f6e 6e656374 696f6e3a |081..Connection:|
000000f0 206b6565 702d616c 6976650d 0a436f6e | keep-alive..Con|
00000100 74656e74 2d4c656e 6774683a 20333634 |tent-Length: 364|
00000110 390d0a0d 0a |9.... |
Now the fragmented second packet start:
====( 1434 bytes received on interface en0 )==== 13:50:01.040697474
ETHERNET packet : [ 00:26:cb:eb:df:7f -> 00:1a:64:47:3c:02 ] type 800 (IP)
IP header breakdown:
< SRC = 172.30.17.142 >
< DST = 10.16.0.72 > (un51sv01_if0)
ip_v=4, ip_hl=20, ip_tos=0, ip_len=1420, ip_id=57227, ip_off=0 DF
ip_ttl=62, ip_sum=8fdc, ip_p = 6 (TCP)
TCP header breakdown:
<source port=43795, destination port=8081 >
th_seq=2849970161, th_ack=3790782429
th_off=5, flags<ACK>
th_win=49680, th_sum=f8e9, th_urp=0
00000000 3c3f786d 6c207665 7273696f 6e3d2231 |<?xml version="1|
00000010 2e302220 656e636f 64696e67 3d225554 |.0" encoding="UT|
00000020 462d3822 3f3e0a3c 656e763a 456e7665 |F-8"?>.<env:Enve|
00000030 6c6f7065 20786d6c 6e733a65 6e763d22 |lope xmlns:env="|
00000040 68747470 3a2f2f73 6368656d 61732e78 |http://schemas.x|
00000050 6d6c736f 61702e6f 72672f73 6f61702f |mlsoap.org/soap/|
00000060 656e7665 6c6f7065 2f222078 6d6c6e73 |envelope/" xmlns|
00000070 3a787364 3d226874 74703a2f 2f777777 |:xsd="http://www|
00000080 2e77332e 6f72672f 32303031 2f584d4c |.w3.org/2001/XML|
00000090 53636865 6d612220 786d6c6e 733a7873 |Schema" xmlns:xs|
Similar to above, there is another packet.
Now the Final packet of ~950 Octets:
====( 943 bytes received on interface en0 )==== 13:50:01.040713619
ETHERNET packet : [ 00:26:cb:eb:df:7f -> 00:1a:64:47:3c:02 ] type 800 (IP)
IP header breakdown:
< SRC = 172.30.17.142 >
< DST = 10.16.0.72 > (un51sv01_if0)
ip_v=4, ip_hl=20, ip_tos=0, ip_len=929, ip_id=57229, ip_off=0 DF
ip_ttl=62, ip_sum=91c5, ip_p = 6 (TCP)
TCP header breakdown:
<source port=43795, destination port=8081 >
th_seq=2849972921, th_ack=3790782429
th_off=5, flags<PUSH | ACK>
th_win=49680, th_sum=32ac, th_urp=0
00000000 74612069 643d2249 44313122 20787369 |ta id="ID11" xsi|
00000010 3a747970 653d226e 73313a49 6e766f6b |:type="ns1:Invok|
00000020 65417070 44617461 223e3c64 61746154 |eAppData"><dataT|
.....
After some internal processing by our application, we send 200 OK and HTTP Response.
HTTP 200 OK Response
====( 3209 bytes transmitted on interface en0 )==== 13:50:01.041804849
ETHERNET packet : [ 00:1a:64:47:3c:02 -> 00:00:0c:07:ac:32 ] type 800 (IP)
IP header breakdown:
< SRC = 10.16.0.72 > (un51sv01_if0)
< DST = 172.30.17.142 >
ip_v=4, ip_hl=20, ip_tos=0, ip_len=3195, ip_id=60324, ip_off=0
ip_ttl=60, ip_sum=ffff, ip_p = 6 (TCP)
TCP header breakdown:
<source port=8081, destination port=43574 >
th_seq=3486085705, th_ack=3771812741
th_off=5, flags<PUSH | ACK>
th_win=65535, th_sum=564, th_urp=0
00000000 48545450 2f312e31 20323030 204f4b0d |HTTP/1.1 200 OK.|
00000010 0a416363 6570743a 20746578 742f786d |.Accept: text/xm|
00000020 6c2c2074 6578742f 68746d6c 2c20696d |l, text/html, im|
00000030 6167652f 6769662c 20696d61 67652f6a |age/gif, image/j|
00000040 7065672c 202a3b20 713d2e32 2c202a2f |peg, *; q=.2, */|
00000050 2a3b2071 3d2e320d 0a436f6e 74656e74 |*; q=.2..Content|
Please note from above that the length of packet received on en0 is "3209" for 200 OK HTTP Response which is actually the entire Response. But it is exceeding MTU of ethernet...
Our MTU value is default - 1500 bytes
un51sv01# lsattr -El en0 |grep mtu
mtu 1500 Maximum IP Packet Size for This Device True
Can somebody throw light into why it is happening this way?
Change / Show Characteristics of an Ethernet Adapter
Type or select values in entry fields.
Press Enter AFTER making all desired changes.
[Entry Fields]
Ethernet Adapter ent0
Description Logical Host Ethernet Port (lp-hea)
Status Available
Location
Request Transmit and Receive Jumbo Frames no +
Enable hardware Transmit TCP segmentation yes +
Enable receive TCP segment aggregation yes +
Enable hardware Transmit checksum yes +
Enable hardware Receive checksum yes +
Requested media speed Auto_Negotiation +
Enable ALTERNATE ETHERNET address no +
ALTERNATE ETHERNET address [0x000000000000] +
Apply change to DATABASE only no +
The above indicate Jumbo Frames are not enabled.
Thanks,
Sashi

ttyO ports do not have the good port address on QEMU 1.4.0 running image for beagleboard-xm

I'm running an Linux Image (kernel 3.2.8) for beagleboard-xm on QEMU's 1.4.0 emulator Ubuntu distribution for 13.04. My image is created using Buildroot beagle_defconfig. I added some pkgs to be able to debug a little.
QEMU call cmd:
`$ sudo qemu-system-arm -M beaglexm -m 1024 -sd ./test.img -clock unix -serial stdio -device usb-mouse -device usb-kbd -serial pty -serial pty`
[sudo] password for emperador:
char device redirected to /dev/pts/3 (label serial1)
char device redirected to /dev/pts/4 (label serial2)
What I want to do is to have a communication between guest and host across serial the 4 differents ttyO present on the guest. QEMU offer facilities to redirect the trafic to some device in the host side. My problem goes like this:
At the guest kernel boot Im able to see that my UART where enabled
[ 2.682040] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
[ 2.777947] omap_uart.0: ttyO0 at MMIO 0x4806a000 (irq = 72) is a OMAP UART0
[ 2.794967] omap_uart.1: ttyO1 at MMIO 0x4806c000 (irq = 73) is a OMAP UART1
[ 2.814942] omap_uart.2: ttyO2 at MMIO 0x49020000 (irq = 74) is a OMAP UART2
[ 2.966825] console [ttyO2] enabled
[ 2.984777] omap_uart.3: ttyO3 at MMIO 0x49042000 (irq = 80) is a OMAP UART3
In fact when I go see in to /proc/tty/driver and I do a cat on OMAP-SERIAL Im able to see this
serinfo:1.0 driver revision:
0: uart:OMAP UART0 mmio:0x4806A000 irq:72 tx:0 rx:0 CTS|DSR|CD
1: uart:OMAP UART1 mmio:0x4806C000 irq:73 tx:0 rx:0 CTS|DSR|CD
2: uart:OMAP UART2 mmio:0x49020000 irq:74 tx:268 rx:37 RTS|CTS|DTR|DSR|CD
3: uart:OMAP UART3 mmio:0x49042000 irq:80 tx:0 rx:0 CTS|DSR|CD
I know that ttyO2 is working because my console is been redirected to it. The thing is that doing a set serial on any of the ttyO I get the following message:
[root#enu driver]# setserial -a /dev/ttyO0
/dev/ttyO0, Line 0, UART: undefined, Port: 0x0000, IRQ: 72
Baud_base: 3000000, close_delay: 50, divisor: 0
closing_wait: 3000
Flags: spd_normal
The same goes with ttyO2.
I tried to set some settings to any of the ttyO with setserial but I always get the same message:
[root#enu ~]# setserial /dev/ttyO0 uart 8250
setserial: can't set serial info: Invalid argument
[root#enu ~]# setserial /dev/ttyO0 port 0x4806a000
setserial: can't set serial info: Invalid argument
While looking at guest /proc/tty/drives this is what we see
/dev/tty /dev/tty 5 0 system:/dev/tty
/dev/console /dev/console 5 1 system:console
/dev/ptmx /dev/ptmx 5 2 system
/dev/vc/0 /dev/vc/0 4 0 system:vtmaster
sdio_uart /dev/ttySDIO 249 0-7 serial
acm /dev/ttyACM 166 0-31 serial
ttyprintk /dev/ttyprintk 5 3 console
OMAP-SERIAL /dev/ttyO 253 0-3 serial
serial /dev/ttyS 4 64-95 serial
pty_slave /dev/pts 136 0-1048575 pty:slave
pty_master /dev/ptm 128 0-1048575 pty:master
unknown /dev/tty 4 1-63 console
Basically I want to establish a serial communication between a guest and a host, but the serial ports on the guest side aren't well configured.
/sys/class/tty show that tty drivers had been linked to a serial device.
has I showed up before, only omap uarts have been initialized and attached to ttyO*. notice that the console is been redirected ttyO2 by kernel configs. but because I added -serial stdio, console is been redirected to the terminal that invoked QEMU.
If I redirect the console using at first -serial pty instead of -serial stdio , I'm able to prompt the console in minicom by opening the pty created on the host side. Still nothing happen on the others pty created on the host side to communicate across other ports.
On host side I open /dev/pts/3 and /dev/pts/4 with minicom or by doing cat on them
On guest side:
Whent I do echo "test" > /dev/ttyO0 or 1 or 3 nothing. but when I do it on ttyO2, "test" prompt on the console terminal (which is normal).
now when using any of the ttyS:
echo "test" > /dev/ttyS0
I get
-bash: echo: write error: Input/output error
I made some research about this error and what I found is that is could be many things. But one thing that I noticed was that no device beside serial has been assigned to ttyS. and looking at /proc/tty/driver/serial we see this :
serinfo:1.0 driver revision:
0: uart:unknown port:00000000 irq:0
1: uart:unknown port:00000000 irq:0
2: uart:unknown port:00000000 irq:0
3: uart:unknown port:00000000 irq:0
also setserial -a /dev/ttyS0 confrim this:
/dev/ttyS0, Line 0, UART: unknown, Port: 0x0000, IRQ: 0
Baud_base: 0, close_delay: 50, divisor: 0
closing_wait: 3000
Flags: spd_normal
I managed to do serial communication with muliples ports usig grml image on a x86 architecture. So its seems my host side is fine.
If anyone have ever made something like this work before on QEMU -M beaglexm or any other ARM architecture, I would gladly take any details on the VM used, QEMU's version and distribution as well as the kernel details and image configs used.
I found what my problem was, QEMU ins't mapping the serial chardev of any extra -serial pty.
After doing the this Invoke command:
sudo qemu-system-arm -M beaglexm -m 1024 -sd ./test.img -clonix -serial stdio -device usb-mouse -device usb-kbd -serial pty -serial pty -monitor pty
char device redirected to /dev/pts/5 (label compat_monitor0)
char device redirected to /dev/pts/7 (label serial1)
char device redirected to /dev/pts/10 (label serial2)
We can see that 2 extra serials where created with the label serial 1 and 2.
But if I look at the tree info
(qemu) info qtree
dev: omap_uart, id "uart4"
revision = 82
mmio_size = 4096
baudrate = 812500
chardev = uart4
irq 3
mmio 0000000049042000/0000000000001000
dev: omap_uart, id "uart3"
revision = 82
mmio_size = 4096
baudrate = 812500
chardev = serial0
irq 3
mmio 0000000049020000/0000000000001000
dev: omap_uart, id "uart2"
revision = 82
mmio_size = 4096
baudrate = 812500
chardev = uart2
irq 3
mmio 000000004806c000/0000000000001000
dev: omap_uart, id "uart1"
revision = 82
mmio_size = 4096
baudrate = 812500
chardev = uart1
irq 3
mmio 000000004806a000/0000000000001000
We clearly see that just the label serial0 was attached to a uart (the one setted to be the console). The other labels (serial1 and serial2) are no where to be found.
With the working image of grml that jofel was realy nice to tell me we see this:
dev: i440FX-pcihost, id ""
irq 0
bus: pci.0
type PCI
dev: PIIX3, id ""
addr = 01.0
romfile = <null>
rombar = 1
multifunction = on
command_serr_enable = on
class ISA bridge, addr 00:01.0, pci id 8086:7000 (sub 1af4:1100)
bus: isa.0
type ISA
dev: isa-serial, id ""
index = 2
iobase = 0x3e8
irq = 4
chardev = serial2
wakeup = 0
isa irq 4
dev: isa-serial, id ""
index = 1
iobase = 0x2f8
irq = 3
chardev = serial1
wakeup = 0
isa irq 3
dev: isa-serial, id ""
index = 0
iobase = 0x3f8
irq = 4
chardev = serial0
wakeup = 0
isa irq 4
all 3 serial lebels were attached to a chardev.
Now I just have to ask a new question about how making QEMU to link those lables to my beagleboard uarts.
Also I would like to add I think that setserial did not outputed any info about ttyO's because it doesn't support omap uarts. setserial ? shows what devices are supported. In the case of the ttyS's, I think its because the tty drivers are installed but there is no other type of uarts bisede omap uarts emulated for bealgeboard in QEMU.
Thanks alot for everyone that took a look on this question and specialy jofel.

Resources