我如何使用现有的非 subnero 与 UnetStack 的调制解调器(基本上不支持 UnetStack)?我详细阅读了这篇文章,但不幸的是编译问题很糟糕。谁能指出我正确的方向?
以下是我遇到的详细错误:
BUG! exception in phase 'semantic analysis' in source unit 'Script66.groovy' The lookup for MyModemDriver caused a failed compilation. There should not have been any compilation from this call.
这是我的代码:
import org.arl.fjage.*
import org.arl.unet.*
import com.fazecast.jSerialComm.*
import org.arl.unet.api.UnetSocket
import org.arl.unet.phy.RxFrameNtf
import org.arl.unet.phy.TxFrameNtf
class PopotoModemDriver extends UnetAgent {
// Using UnetSocket to connect to network modem ('ip',port)
def sock = UnetSocket('192.168.0.42', 1100)
AgentID notify // notification topic
int plvl = 170 // default power level setting
@Override
void setup() {
notify = topic()
register Services.PHYSICAL
register Services.DATAGRAM
}
@Override
void shutdown() {
sock.close()
}
@Override
Message processRequest(Message req) {
if (req instanceof DatagramReq) {
String s = "AT+TX:" + req.to + "," + req.data.encodeHex() + "\n"
byte[] b = s.getBytes()
sock.writeBytes(b, b.length)
add new OneShotBehavior({
send new TxFrameNtf(req)
})
return new Message(req, Performative.AGREE)
}
return null
}
int getMTU() {
return 32 // frame size
}
boolean getRxEnable() {
return true
}
float getPropagationSpeed() {
return 1500 // assume sound speed is 1500 m/s
}
int getTimestampedTxDelay() {
return 0 // our modem doesn't support timestamped transmissions
}
long getTime() {
return 1000*System.currentTimeMillis() // use system clock for timing in µs
}
boolean getBusy() {
return false
}
float getRefPowerLevel() {
return 0 // our modem uses absolute power levels in dB re uPa @ 1m
}
float getMaxPowerLevel() {
return 180 // our modem can transmit at max power level of 180 dB
}
float getMinPowerLevel() {
return 120 // ... and a min power level of 120 dB
}
int getMTU(int ch) {
return 32 // frame size
}
float getFrameDuration(int ch) {
return getMTU(ch)/getDataRate(ch)
}
float getPowerLevel(int ch) {
return plvl
}
int getErrorDetection(int ch) {
return 0
}
int getFrameLength(int ch) {
return getMTU(ch) // fixed frame size
}
int getMaxFrameLength(int ch) {
return getMTU(ch) // fixed frame size
}
int getFec(int ch) {
return 0
}
List getFecList(int ch) {
return null
}
float getDataRate(int ch) {
return 320.0 // data rate of 320 bps
}
float setPowerLevel(int ch, float x) {
plvl = x
if (plvl < getMinPowerLevel()) plvl = getMinPowerLevel()
if (plvl > getMaxPowerLevel()) plvl = getMaxPowerLevel()
String s = "AT+TPL:" + plvl + "\n"
byte[] b = s.getBytes()
sock.writeBytes(b, b.length)
return plvl
}
@Override
void startup() {
sock.openPort()
add new CyclicBehavior({
int n = sock.bytesAvailable()
if (n == 0) Thread.sleep(20)
else {
// data available
byte[] buf = new byte[n]
sock.readBytes(buf, n)
parseRxData(new String(buf))
}
})
}
String data = ''
void parseRxData(String s) {
data += s
int n = data.indexOf('\n')
if (n < 0) return
s = data.substring(0, n)
data = data.substring(n)
if (s.startsWith("AT+RX:")) {
int addr = s.substring(6,9) as int
byte[] bytes = s.substring(10).decodeHex()
send new RxFrameNtf(
recipient: notify,
from: addr,
data: bytes,
bits: 8*bytes.length,
rxTime: 1000*System.currentTimeMillis()
)
}
}
}