Kotlin/native compiler can't functions inet_addr, htons, e.t.c - kotlin-native

I would like to write simple program with socket connection in kotlin/native:
There is simple function that open and bind socket.
actual fun openSocket(endpoint: IpPort): Socket {
// Initialize sockets in platform-dependent way.
init_sockets()
var socketDescriptor = 0
memScoped {
val serverAddr = alloc<sockaddr_in>()
socketDescriptor = socket(AF_INET, SOCK_STREAM, 0)
.ensureUnixCallResult("socket") { !it.isMinusOne() }
with(serverAddr) {
memset(this.ptr, 0, sockaddr_in.size.narrow())
sin_family = AF_INET.convert()
sin_addr.s_addr = inet_addr(endpoint.cstr.ptr); /
//sin_port = htons(endpoint.port.convert())
}
bind(socketDescriptor, serverAddr.ptr.reinterpret(), sockaddr_in.size.convert())
.ensureUnixCallResult("bind") { it == 0 }
}
return Socket(socketDescriptor)
}
Compiler (./gradlew compileKonan) can't resolve functions: inet_addr, htons.
Also compiler resolver import import platform.ios.*.
I think these function should be on iOS system (and any other OS) headers.
There is build.gradle of
apply plugin: 'konan'
konan.targets = ['iphone']
konanArtifacts {
framework('MezzoCore') {
enableMultiplatform true
}
}
dependencies {
expectedBy project(':common')
}
I can't understand what i do wrong. Can anyone help me?

Following may help:
import platform.posix.*
import platform.darwin.*
import kotlinx.cinterop.*
// Just to avoid import conflict.
typealias sockaddr_in = platform.posix.sockaddr_in
fun main() {
val endpoint ="127.0.0.1"
val port = 8080
var socketDescriptor = 0
memScoped {
val serverAddr = alloc<sockaddr_in>()
socketDescriptor = socket(AF_INET, SOCK_STREAM, 0)
with(serverAddr) {
memset(this.ptr, 0, sockaddr_in.size.convert())
sin_family = AF_INET.convert()
sin_addr.s_addr = inet_addr(endpoint)
sin_port = ((port shr 8) or ((port and 0xff) shl 8)).toUShort()
}
bind(socketDescriptor, serverAddr.ptr.reinterpret(),
sockaddr_in.size.convert())
}
println("sd=$socketDescriptor")
}

Related

How to write Modem Drivers for non-subnero modems?

How can i use the existing modems which is not subnero with UnetStack (basically is not support UnetStack natively) ? I was gone through the post in detailed, but unfortunately had bad compilation issues. Can anyone point me to right direction ?
Below is the detailed error i encountered:
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.
Here is my code:
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()
)
}
}
}
#manuignatius is right, Groovy complains about this when there is a syntax error in a dynamically loaded Groovy class.
To get a more detailed stack trace on the error, you can manually invoke the Groovy compiler. Set your CLASSPATH environment variable to include all the jars in the lib folder in your local UnetStack installation. Then simply run groovyc MyModemDriver.groovy, and it should show you compilation errors, if any. The compiled .class file that is produced on successful compilation can then be copied to the classes folder in UnetStack/modem instead of the source code.

Add multiple channel pipeline handlers in SwiftNIO similarly as Java Netty

I am exploring how to add multiple handlers in channel pipelines in SwiftNIO. In Java Netty, I have the following code:
#Component
public class NettyClientFilter extends ChannelInitializer<SocketChannel> {
#Autowired
private NettyClientHandler nettyClientHandler;
#Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline ph = ch.pipeline();
ph.addLast(new IdleStateHandler(20, 10, 0));
ph.addLast(new LengthFieldBasedFrameDecoder(1024, 0, 4, 0, 4));
ph.addLast(new ProtobufDecoder(IMessage.getDefaultInstance()));
ph.addLast(new LengthFieldPrepender(4));
ph.addLast(new ProtobufEncoder());
ph.addLast("nettyClientHandler",nettyClientHandler);
}
}
In the SwiftNIO, seems there are no similar classes as "LengthFieldBasedFrameDecoder", "ProtobufDecoder", "LengthFieldPrepender", "ProtobufEncoder". How can I get those ones in SwiftNIO?
Right, let me go through all the handlers you add to your pipeline in Netty:
IdleStateHandler: available with import NIO from the swift-nio package
LengthFieldBasedFrameDecoder: right now in a PR but will be available shortly through import NIOExtras from the swift-nio-extras package
ProtobufDecoder, LengthFieldPrepender, ProtobufEncoder: all currently unavailable but straightforward to implement:
LengthFieldPrepender:
final class LengthFieldPrepender<IntType: FixedWidthInteger>: ChannelOutboundHandler {
// we send send and receive ByteBuffers
typealias OutboundIn = ByteBuffer
typealias OutboundOut = ByteBuffer
private let endianness: Endianness
private var buf: ByteBuffer?
init(type: IntType.Type = IntType.self, endianness: Endianness = .big) {
self.endianness = endianness
}
func handlerAdded(ctx: ChannelHandlerContext) {
self.buf = ctx.channel.allocator.buffer(capacity: 8)
}
func write(ctx: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise<Void>?) {
let incomingData = self.unwrapOutboundIn(data)
// we cache `self.buf` so we might get lucky and save an allocation here if the previous buffer has been fully written already
self.buf!.clear()
// write the length as the right type
self.buf!.write(integer: IntType(incomingData.readableBytes), endianness: self.endianness)
ctx.write(self.wrapOutboundOut(self.buf!), promise: nil)
// write the actual data
ctx.write(data, promise: promise)
}
}
ProtobufDecoder:
import SwiftProtobuf
import NIOFoundationCompat // for ByteBuffer.readData
final class ProtobufDecoder<Msg: SwiftProtobuf.Message>: ChannelInboundHandler {
typealias InboundIn = ByteBuffer
typealias InboundOut = Msg
func channelRead(ctx: ChannelHandlerContext, data: NIOAny) {
var buffer = self.unwrapInboundIn(data)
let data = buffer.readData(length: buffer.readableBytes)!
do {
// pretty straightforward here, just call the message type's initialiser
let req = try Msg(serializedData: data)
ctx.fireChannelRead(self.wrapInboundOut(req))
} catch {
ctx.fireErrorCaught(error)
}
}
}
ProtobufEncoder:
import NIOFoundationCompat
import SwiftProtobuf
final class ProtobufEncoder<Msg: SwiftProtobuf.Message>: ChannelOutboundHandler {
typealias OutboundIn = Msg
typealias OutboundOut = ByteBuffer
private var buf: ByteBuffer?
func handlerAdded(ctx: ChannelHandlerContext) {
self.buf = ctx.channel.allocator.buffer(capacity: 4096)
}
func write(ctx: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise<Void>?) {
let msg = self.unwrapOutboundIn(data)
self.buf!.clear()
do {
// just use SwiftProtobuf's nice encoder
self.buf!.write(bytes: try msg.serializedData())
ctx.write(self.wrapOutboundOut(self.buf!), promise: promise)
} catch {
ctx.fireErrorCaught(error)
}
}
}

Handling streaming iterator as normal iterator by using PhantomData and unsafe

I know the code below is hacky, but could it be called safe and idiomatic Rust? Is there better way for this?
// needs to do 'rustup default nightly' to run under valgrind
// #![feature(alloc_system, global_allocator, allocator_api)]
// extern crate alloc_system;
// use alloc_system::System;
// #[global_allocator]
// static A: System = System;
struct Foo<'a> {
v: Vec<u8>,
pos: usize,
phantom: std::marker::PhantomData<&'a u8>,
}
impl<'a> Iterator for Foo<'a> {
type Item = &'a mut u8;
fn next(&mut self) -> Option<&'a mut u8> {
let r = self.v.get_mut(self.pos);
if r.is_some() {
self.pos += 1;
unsafe { Some(&mut *(r.unwrap() as *mut u8)) }
} else {
None
}
}
}
impl<'a> Foo<'a> {
fn reset(&mut self) {
self.pos = 0;
}
}
fn main() {
let mut x = Foo {
v: (1..10).collect(),
pos: 0,
phantom: std::marker::PhantomData,
};
let vp = x.v.as_ptr();
{
for i in &mut x {
println!("{}", i);
}
}
{
x.reset();
}
{
for i in &mut x {
*i *= *i;
}
}
{
x.reset();
}
{
for i in &mut x {
println!("{}", i);
}
}
assert!(vp == x.v.as_ptr());
}
Write a little bit in the comment, Valgrind told me no leak and the result is as expected under Rust 1.26.0-nightly and 1.25.0.
Related:
How do I write an iterator that returns references to itself?
Iterator returning items by reference, lifetime issue
This code is not safe. The user of the type may choose any lifetime, including 'static:
fn constructor() -> Foo<'static> {
Foo {
v: vec![42; 10],
pos: 0,
phantom: std::marker::PhantomData,
}
}
fn example() -> &'static u8 {
let mut f = constructor();
f.next().unwrap()
}
fn main() {
println!("example: {}", example());
}
Here, example returns a reference to a variable that is no longer in scope, accessing invalid memory and subverting the restrictions you must uphold.
There's an example of how you could write this code with no unsafe whatsoever in another Q&A.

Does rust 0.10 have a rl package?

I'm starting to use rust to create a little toy command prompt applicationusing the gnu readline library. I started using the c foreign function interface but then came across this in rust 0.8.
The crate extra has a module extra::rl which appears to be a readline with all the tools that are needed. My question is, is this present in rust 0.10 and if so where is it? if not, is it packaged as an external module, and if so where can I find it?
Thanks in advance.
use std::c_str;
#[link(name = "readline")]
extern {
fn readline (p: *std::libc::c_char) -> * std::libc::c_char;
}
fn rust_readline (prompt: &str) -> Option<~str> {
let cprmt = prompt.to_c_str();
cprmt.with_ref(|c_buf| {
unsafe {
let ret = c_str::CString::new (readline (c_buf), true);
ret.as_str().map(|ret| ret.to_owned())
}
})
}
fn eval(input: &str)
{
println! ("{}", input);
}
fn main()
{
loop {
let val = rust_readline (">>> ");
match val {
None => { break }
_ => {
let input = val.unwrap ();
eval(input);
}
}
}
}
This is a sample REPL style interpreter that just prints instead of eval'ing. Based on code from http://redbrain.co.uk/2013/11/09/rust-and-readline-c-ffi/. His example no longer compiles.
This code is now on github here.
Sorry I really should have said, I came up with an answer to my own question, it includes a history for readline. I have put it here in case anyone else wants some of this functionality.
//! Readline FFI
//extern crate libc;
use std::libc;
use libc::c_char;
use std::c_str;
#[link(name = "readline")]
extern {
fn readline(p: *c_char) -> * c_char;
fn add_history(l: *c_char);
}
pub fn rust_readline(prompt: &str) -> Option<~str> {
let c_prompt = prompt.to_c_str();
c_prompt.with_ref(|c_buf| {
unsafe {
let ret = c_str::CString::new(readline(c_buf), true);
ret.as_str().map(|ret| ret.to_owned())
}
})
}
pub fn rust_add_history(line: &str) -> int {
// if line.len() == 0 { return Err("Empty string!") }
let c_line = line.to_c_str();
c_line.with_ref(|my_c_line| {
unsafe {
// println!("{}", my_c_line)
add_history(my_c_line);
}
});
0
}
fn main() {
loop {
let val = rust_readline("mikes_lisp> ");
match val {
None => { break }
_ => {
let input = val.unwrap();
rust_add_history(input);
println!("you said: '{}'", input);
}
}
}
}

How to catch SIGINT for the current in Dart?

How can Ctrl+C or SIGINT be caught in a Dart program for the current process?
Something similar to this for Node:
process.on('SIGINT', function() {
// do stuff
});
It looks like the SIGUSR1 and SIGUSR2 fields used in the old answer are now deprecated. I got the following example working using the sigint field:
import "dart:io";
void main() {
var n = 0;
ProcessSignal.sigint.watch().listen((signal) {
print(" caught ${++n} of 3");
if (n == 3) {
exit(0);
}
});
}
I found the following test code at Unified Diff: tests/standalone/io/signals_test_script.dart
import "dart:io";
void main(args) {
int usr1Count = int.parse(args[0]);
int usr2Count = int.parse(args[1]);
var sub1;
var sub2;
void check() {
if (usr1Count < 0 || usr2Count < 0) exit(1);
if (usr1Count == 0 && usr2Count == 0) {
sub1.cancel();
sub2.cancel();
}
print("ready");
}
sub1 = ProcessSignal.SIGUSR1.watch().listen((signal) {
if (signal != ProcessSignal.SIGUSR1) exit(1);
usr1Count--;
check();
});
sub2 = ProcessSignal.SIGUSR2.watch().listen((signal) {
if (signal != ProcessSignal.SIGUSR2) exit(1);
usr2Count--;
check();
});
check();
}

Resources