add mc transport subsystem, replace js protobuf to protokot

This commit is contained in:
MaximZaitsev
2016-08-16 14:22:27 +03:00
parent 9671d19535
commit 4c8f83a281
12 changed files with 159 additions and 164 deletions
+8 -28
View File
@@ -19,27 +19,19 @@ val serverIp: String = "127.0.0.1"
val mainServerAddress = "127.0.0.1" val mainServerAddress = "127.0.0.1"
val mainServerPort = 7925 val mainServerPort = 7925
val protoBuf = require("protobufjs") val fs = require("fs")
fun main(args: Array<String>) { fun main(args: Array<String>) {
val controlConstructor = protoBuf.loadProtoFile(getRelativePathToProto("direction.proto")).build("carkot")
val rcSessionConstructor = protoBuf.loadProtoFile(getRelativePathToProto("rc_session.proto")).build("carkot")
val carkotConstructor = protoBuf.loadProtoFile(getRelativePathToProto("carkot.proto")).build("carkot")
val routeConstructor = protoBuf.loadProtoFile(getRelativePathToProto("route.proto")).build("carkot")
val locationConstructor = protoBuf.loadProtoFile(getRelativePathToProto("location.proto")).build("carkot")
val handlers: MutableMap<String, AbstractHandler> = mutableMapOf() val handlers: MutableMap<String, AbstractHandler> = mutableMapOf()
handlers.put("/rc/control", Control(controlConstructor.DirectionRequest, controlConstructor.DirectionResponse)) handlers.put("/rc/control", Control(DirectionRequest.BuilderDirectionRequest(DirectionRequest.Command.fromIntToCommand(0), 0), DirectionResponse.BuilderDirectionResponse(0)))
handlers.put("/rc/connect", Connect(null, rcSessionConstructor.SessionUpResponse)) handlers.put("/rc/connect", Connect(SessionUpResponse.BuilderSessionUpResponse(0, 0)))
handlers.put("/rc/disconnect", Disconnect(rcSessionConstructor.SessionDownRequest, rcSessionConstructor.SessionDownResponse)) handlers.put("/rc/disconnect", Disconnect(SessionDownRequest.BuilderSessionDownRequest(0), SessionDownResponse.BuilderSessionDownResponse(0)))
handlers.put("/rc/heartbeat", Heartbeat(rcSessionConstructor.HeartBeatRequest, rcSessionConstructor.HeartBeatResponse)) handlers.put("/rc/heartbeat", Heartbeat(HeartBeatRequest.BuilderHeartBeatRequest(0), HeartBeatResponse.BuilderHeartBeatResponse(0)))
handlers.put("/loadBin", LoadBin(carkotConstructor.Upload, carkotConstructor.UploadResult)) handlers.put("/loadBin", LoadBin(Upload.BuilderUpload(ByteArray(0)), UploadResult.BuilderUploadResult(0)))
handlers.put("/route", SetRoute(routeConstructor.RouteRequest, routeConstructor.RouteResponse)) handlers.put("/route", SetRoute(RouteRequest.BuilderRouteRequest(IntArray(0), IntArray(0)), RouteResponse.BuilderRouteResponse(0)))
handlers.put("/getLocation", GetLocation(null, locationConstructor.LocationResponse)) handlers.put("/getLocation", GetLocation(LocationResponse.BuilderLocationResponse(LocationResponse.LocationData.BuilderLocationData(0, 0, 0).build(), 0)))
net.server.start(handlers, serverPort) net.server.start(handlers, serverPort)
val udev = Udev() val udev = Udev()
@@ -49,18 +41,6 @@ fun main(args: Array<String>) {
} }
fun getRelativePathToProto(fileName: String): String {
return "./proto/" + fileName
}
fun trimBuffer(buffer: dynamic, length: Int): dynamic {
val byteArray = ByteArray(length);
for (i in 0..length - 1) {
byteArray[i] = buffer[i]
}
return js("new Buffer(byteArray)")
}
@native @native
fun require(name: String): dynamic { fun require(name: String): dynamic {
return null return null
+7 -6
View File
@@ -95,16 +95,17 @@ class MicroController private constructor() {
} }
fun connectToServer(thisIp: String, thisPort: Int) { fun connectToServer(thisIp: String, thisPort: Int) {
val connectProtobuf = protoBuf.loadProtoFile(getRelativePathToProto("connect.proto")).build("carkot") val requestObject = ConnectionRequest.BuilderConnectionRequest(serverIp.split(".").map { str -> parseInt(str, 10) }.toIntArray(), serverPort).build()
val requestObject = js("new connectProtobuf.ConnectionRequest({ip:thisIp, port:thisPort})").encode() val bytes = ByteArray(requestObject.getSizeNoTag())
net.sendRequest(trimBuffer(requestObject.buffer, requestObject.limit), "/connect", { resultData -> requestObject.writeTo(CodedOutputStream(bytes))
val responseObject = connectProtobuf.ConnectionResponse.decode(resultData) net.sendRequest(js("new Buffer(bytes)"), "/connect", { resultData ->
val responseObject = ConnectionResponse.BuilderConnectionResponse(0, 0).build()
responseObject.mergeFrom(CodedInputStream(resultData))
if (responseObject.code == 0) { if (responseObject.code == 0) {
this.uid = responseObject.uid this.uid = responseObject.uid
} else { } else {
println("server login error\n" + println("server login error\n" +
"code: ${responseObject.code}\n" + "code: ${responseObject.code}")
"error message: ${responseObject.errorMsg}")
} }
}, { error -> }, { error ->
println("connection error (to main server). error message:\n" + error) println("connection error (to main server). error message:\n" + error)
+2 -1
View File
@@ -17,6 +17,7 @@ class Udev {
//mc connected //mc connected
println("mc connected. transport file is " + device.DEVNAME) println("mc connected. transport file is " + device.DEVNAME)
microController.transportFilePath = device.DEVNAME; microController.transportFilePath = device.DEVNAME;
mcTransport.initStreams(device.DEVNAME)
} }
}) })
@@ -25,8 +26,8 @@ class Udev {
//mc disconnected //mc disconnected
println("mc disconnected") println("mc disconnected")
microController.transportFilePath = "" microController.transportFilePath = ""
mcTransport.closeStreams()
} }
}) })
} }
} }
@@ -1,7 +1,8 @@
package carControl package carControl
import MicroController import MicroController
import require import mcTransport
import fs
import setTimeout import setTimeout
@@ -10,47 +11,33 @@ import setTimeout
*/ */
class ControlImpl : Control { class ControlImpl : Control {
val fs: dynamic;
init {
this.fs = require("fs")
}
override fun moveCarLeft() { override fun moveCarLeft() {
println("move left") println("move left")
writeToFile(4) mcTransport.writeToFile(4)
} }
override fun moveCarRight() { override fun moveCarRight() {
println("move rigth") println("move rigth")
writeToFile(3) mcTransport.writeToFile(3)
} }
override fun moveCarForward() { override fun moveCarForward() {
println("move forward") println("move forward")
writeToFile(1) mcTransport.writeToFile(1)
} }
override fun moveCarBackward() { override fun moveCarBackward() {
println("move backward") println("move backward")
writeToFile(2) mcTransport.writeToFile(2)
} }
override fun stopCar() { override fun stopCar() {
println("stopped") println("stopped")
writeToFile(0) mcTransport.writeToFile(0)
} }
override fun delay(ms: Int, callBack: () -> Unit) { override fun delay(ms: Int, callBack: () -> Unit) {
setTimeout(callBack, ms) setTimeout(callBack, ms)
} }
fun writeToFile(byte: Byte) {
fs.appendFile(MicroController.instance.transportFilePath, byte.toString(), "binary", { err ->
if (err) {
println("error\n" + err.toString())
}
})
}
} }
@@ -5,35 +5,16 @@ import trimBuffer
/** /**
* Created by user on 7/27/16. * Created by user on 7/27/16.
*/ */
abstract class AbstractHandler(protoDecoder: dynamic, protoEncoder: dynamic) { abstract class AbstractHandler {
val protoDecoder: dynamic
val protoEncoder: dynamic
init {
this.protoDecoder = protoDecoder
this.protoEncoder = protoEncoder
}
fun execute(data: List<Byte>, response: dynamic) { fun execute(data: List<Byte>, response: dynamic) {
getBytesResponse(data.toByteArray(), { resultBytes ->
val message = if (protoDecoder != null) protoDecoder.decode(data.toByteArray()) else null val resultBuffer = js("new Buffer(resultBytes)")
val resultMessage: dynamic = {} response.write(resultBuffer)
js("resultMessage = {}")
val afterExecute: () -> Unit = {
if (this.protoEncoder != null) {
val protoEn = this.protoEncoder//temporarily:)
val resultMsg = resultMessage
val resultBuffer = js("new protoEn(resultMsg)").encode()
val trimBuffer = trimBuffer(resultBuffer.buffer, resultBuffer.limit)
response.write(trimBuffer)
}
response.end() response.end()
} })
makeResponse(message, resultMessage, afterExecute)
} }
abstract fun makeResponse(message: dynamic, responseMessage: dynamic, finalCallback: () -> Unit) abstract fun getBytesResponse(data: ByteArray, callback: (b: ByteArray) -> Unit)
} }
@@ -2,50 +2,51 @@ package net.server.handlers.flash
import net.server.handlers.AbstractHandler import net.server.handlers.AbstractHandler
import require import require
import CodedInputStream
import CodedOutputStream
import mcTransport
/** /**
* Created by user on 7/27/16. * Created by user on 7/27/16.
*/ */
class LoadBin : AbstractHandler { class LoadBin : AbstractHandler {
val fs: dynamic
val exec: dynamic val exec: dynamic
constructor(protoDecoder: dynamic, protoEncoder: dynamic) : super(protoDecoder, protoEncoder) { val fromServerObjectBuilder: Upload.BuilderUpload
this.fs = require("fs") val toServerObjectBuilder: UploadResult.BuilderUploadResult
constructor(fromSrv: Upload.BuilderUpload, toSrv: UploadResult.BuilderUploadResult) : super() {
this.fromServerObjectBuilder = fromSrv
this.toServerObjectBuilder = toSrv
this.exec = require("child_process").exec this.exec = require("child_process").exec
} }
override fun makeResponse(message: dynamic, responseMessage: dynamic, finalCallback: () -> Unit) { override fun getBytesResponse(data: ByteArray, callback: (b: ByteArray) -> Unit) {
var stdOut: String = "" val message = fromServerObjectBuilder.build()
var strErr: String = "" message.mergeFrom(CodedInputStream(data))
var resultCode = 0 var resultCode = 0
fs.writeFile("./flash.bin", message.data.buffer, "binary", { error -> val responseMessage = toServerObjectBuilder.build()
if (error != null) { mcTransport.writeToFile(message.data)
resultCode = 14 // if (error != null) {
strErr = error.toString() // resultCode = 14
responseMessage.stdOut = stdOut // responseMessage.resultCode = resultCode
responseMessage.strErr = strErr // val resultByteArray = ByteArray(responseMessage.getSizeNoTag())
responseMessage.resultCode = resultCode // responseMessage.writeTo(CodedOutputStream(resultByteArray))
finalCallback.invoke() // callback.invoke(resultByteArray)
// } else {
val stFlashCommand = "./st-flash write ./flash.bin " + "0x08000000"
exec(stFlashCommand, { err, stdOutRes, stdErrRes ->
if (err != null) {
resultCode = 15
} else { } else {
val stFlashCommand = "./st-flash write ./flash.bin " + message.base resultCode = 0
exec(stFlashCommand, { err, stdOutRes, stdErrRes ->
if (err != null) {
resultCode = 15
strErr = stdErrRes.toString() + "\n" + err.toString()
stdOut = stdOutRes.toString()
} else {
resultCode = 0
strErr = stdErrRes.toString()
stdOut = stdOutRes.toString()
}
responseMessage.stdOut = stdOut
responseMessage.strErr = strErr
responseMessage.resultCode = resultCode
finalCallback.invoke()
})
} }
responseMessage.resultCode = resultCode
val resultByteArray = ByteArray(responseMessage.getSizeNoTag())
responseMessage.writeTo(CodedOutputStream(resultByteArray))
callback.invoke(resultByteArray)
}) })
// }
} }
} }
@@ -1,19 +1,25 @@
package net.server.handlers.main package net.server.handlers.main
import net.server.handlers.AbstractHandler import net.server.handlers.AbstractHandler
import CodedOutputStream
/** /**
* Created by user on 7/28/16. * Created by user on 7/28/16.
*/ */
class GetLocation : AbstractHandler { class GetLocation : AbstractHandler {
constructor(protoDecoder: dynamic, protoEncoder: dynamic) : super(protoDecoder, protoEncoder) val toServerObjectBuilder: LocationResponse.BuilderLocationResponse
override fun makeResponse(message: dynamic, responseMessage: dynamic, finalCallback: () -> Unit) { constructor(toSrv: LocationResponse.BuilderLocationResponse) : super() {
this.toServerObjectBuilder = toSrv
}
override fun getBytesResponse(data: ByteArray, callback: (ByteArray) -> Unit) {
val car = MicroController.instance.car val car = MicroController.instance.car
val locationResponseData = {} val locationData = LocationResponse.LocationData.BuilderLocationData(car.x.toInt(), car.y.toInt(), car.angle.toInt()).build()
js("locationResponseData = {x:car.x, y:car.y, angle:car.angle}") val resultMessage = toServerObjectBuilder.setLocationResponseData(locationData).build()
responseMessage.locationResponseData = locationResponseData val resultByteArray = ByteArray(resultMessage.getSizeNoTag())
finalCallback.invoke() resultMessage.writeTo(CodedOutputStream(resultByteArray))
callback.invoke(resultByteArray)
} }
} }
@@ -1,22 +1,34 @@
package net.server.handlers.main package net.server.handlers.main
import net.server.handlers.AbstractHandler import net.server.handlers.AbstractHandler
import CodedInputStream
import CodedOutputStream
/** /**
* Created by user on 7/28/16. * Created by user on 7/28/16.
*/ */
class SetRoute : AbstractHandler { class SetRoute : AbstractHandler {
constructor(protoDecoder: dynamic, protoEncoder: dynamic) : super(protoDecoder, protoEncoder) val fromServerObjectBuilder: RouteRequest.BuilderRouteRequest
val toServerObjectBuilder: RouteResponse.BuilderRouteResponse
override fun makeResponse(message: dynamic, responseMessage: dynamic, finalCallback: () -> Unit) { constructor(fromSrv: RouteRequest.BuilderRouteRequest, toSrv: RouteResponse.BuilderRouteResponse) : super() {
this.fromServerObjectBuilder = fromSrv
this.toServerObjectBuilder = toSrv
}
override fun getBytesResponse(data: ByteArray, callback: (ByteArray) -> Unit) {
val car = MicroController.instance.car val car = MicroController.instance.car
val message = fromServerObjectBuilder.build()
message.mergeFrom(CodedInputStream(data))
car.routeExecutor.executeRoute(message) car.routeExecutor.executeRoute(message)
responseMessage.code = 0 val responseMessage = toServerObjectBuilder.setCode(0).build()
responseMessage.errorMsg = "" val resultByteArray = ByteArray(responseMessage.getSizeNoTag())
responseMessage.writeTo(CodedOutputStream(resultByteArray))
finalCallback.invoke() callback.invoke(resultByteArray)
} }
} }
@@ -2,32 +2,34 @@ package net.server.handlers.rc
import exceptions.RcControlException import exceptions.RcControlException
import net.server.handlers.AbstractHandler import net.server.handlers.AbstractHandler
import CodedOutputStream
/** /**
* Created by user on 7/27/16. * Created by user on 7/27/16.
*/ */
class Connect : AbstractHandler { class Connect : AbstractHandler {
constructor(protoDecoder: dynamic, protoEncoder: dynamic) : super(protoDecoder, protoEncoder) val toServerObjectBuilder: SessionUpResponse.BuilderSessionUpResponse
override fun makeResponse(message: dynamic, responseMessage: dynamic, finalCallback: () -> Unit) { constructor(toSrv: SessionUpResponse.BuilderSessionUpResponse) : super() {
this.toServerObjectBuilder = toSrv
}
override fun getBytesResponse(data: ByteArray, callback: (ByteArray) -> Unit) {
val resultCode: Int val resultCode: Int
val resultMsg: String
val sid: Int; val sid: Int;
try { try {
sid = MicroController.instance.connectRC() sid = MicroController.instance.connectRC()
resultCode = 0 resultCode = 0
resultMsg = ""
} catch (e: RcControlException) { } catch (e: RcControlException) {
resultCode = 13 resultCode = 13
resultMsg = "car already controlled by RC"
sid = 0 sid = 0
} }
responseMessage.sid = sid val responseMessage = toServerObjectBuilder.setCode(resultCode).setSid(sid).build()
responseMessage.code = resultCode val resultByteArray = ByteArray(responseMessage.getSizeNoTag())
responseMessage.errorMsg = resultMsg responseMessage.writeTo(CodedOutputStream(resultByteArray))
callback.invoke(resultByteArray)
finalCallback.invoke()
} }
} }
@@ -4,47 +4,56 @@ import MicroController
import carControl.RouteExecutorImpl.MoveDirection import carControl.RouteExecutorImpl.MoveDirection
import exceptions.RcControlException import exceptions.RcControlException
import net.server.handlers.AbstractHandler import net.server.handlers.AbstractHandler
import DirectionRequest
import CodedInputStream
import CodedOutputStream
/** /**
* Created by user on 7/27/16. * Created by user on 7/27/16.
*/ */
class Control : AbstractHandler { class Control : AbstractHandler {
constructor(protoDecoder: dynamic, protoEncoder: dynamic) : super(protoDecoder, protoEncoder) val fromServerObjectBuilder: DirectionRequest.BuilderDirectionRequest
val toServerObjectBuilder: DirectionResponse.BuilderDirectionResponse
override fun makeResponse(message: dynamic, responseMessage: dynamic, finalCallback: () -> Unit) { constructor(fromSrv: DirectionRequest.BuilderDirectionRequest, toSrv: DirectionResponse.BuilderDirectionResponse) : super() {
this.fromServerObjectBuilder = fromSrv
this.toServerObjectBuilder = toSrv
}
override fun getBytesResponse(data: ByteArray, callback: (b: ByteArray) -> Unit) {
val message = fromServerObjectBuilder.build()
message.mergeFrom(CodedInputStream(data))
val commandNumber = message.command val commandNumber = message.command
val sid = message.sid val sid = message.sid
val command = when (commandNumber) { val command = when (commandNumber) {
protoDecoder.Command.stop -> { DirectionRequest.Command.stop -> {
MoveDirection.STOP MoveDirection.STOP
} }
protoDecoder.Command.forward -> { DirectionRequest.Command.forward -> {
MoveDirection.FORWARD MoveDirection.FORWARD
} }
protoDecoder.Command.backward -> { DirectionRequest.Command.backward -> {
MoveDirection.BACKWARD MoveDirection.BACKWARD
} }
protoDecoder.Command.right -> { DirectionRequest.Command.right -> {
MoveDirection.RIGHT MoveDirection.RIGHT
} }
protoDecoder.Command.left -> { DirectionRequest.Command.left -> {
MoveDirection.LEFT MoveDirection.LEFT
} }
else -> MoveDirection.STOP else -> MoveDirection.STOP
} }
val resultCode:Int val resultCode: Int
val resultMsg:String
try { try {
MicroController.instance.RcMove(command, sid) MicroController.instance.RcMove(command, sid)
resultCode = 0 resultCode = 0
resultMsg = ""
} catch (e: RcControlException) { } catch (e: RcControlException) {
resultCode = 12 resultCode = 12
resultMsg = "incorrect remote control sid"
} }
responseMessage.code = resultCode val resultMessage = toServerObjectBuilder.setCode(resultCode).build()
responseMessage.errorMsg = resultMsg val resultByteArray = ByteArray(resultMessage.getSizeNoTag())
finalCallback.invoke() resultMessage.writeTo(CodedOutputStream(resultByteArray))
callback.invoke(resultByteArray)
} }
} }
@@ -2,29 +2,36 @@ package net.server.handlers.rc
import exceptions.RcControlException import exceptions.RcControlException
import net.server.handlers.AbstractHandler import net.server.handlers.AbstractHandler
import CodedInputStream
import CodedOutputStream
/** /**
* Created by user on 7/27/16. * Created by user on 7/27/16.
*/ */
class Disconnect : AbstractHandler{ class Disconnect : AbstractHandler {
constructor(protoDecoder: dynamic, protoEncoder: dynamic) : super(protoDecoder, protoEncoder) val fromServerObjectBuilder: SessionDownRequest.BuilderSessionDownRequest
val toServerObjectBuilder: SessionDownResponse.BuilderSessionDownResponse
override fun makeResponse(message: dynamic, responseMessage: dynamic, finalCallback: () -> Unit) { constructor(fromSrv: SessionDownRequest.BuilderSessionDownRequest, toSrv: SessionDownResponse.BuilderSessionDownResponse) : super() {
this.fromServerObjectBuilder = fromSrv
this.toServerObjectBuilder = toSrv
}
override fun getBytesResponse(data: ByteArray, callback: (ByteArray) -> Unit) {
val message = fromServerObjectBuilder.build()
message.mergeFrom(CodedInputStream(data))
val resultCode: Int val resultCode: Int
val resultMsg: String
try { try {
MicroController.instance.disconnectRC(message.sid) MicroController.instance.disconnectRC(message.sid)
resultCode = 0 resultCode = 0
resultMsg = ""
} catch (e: RcControlException) { } catch (e: RcControlException) {
resultCode = 12 resultCode = 12
resultMsg = "incorrect remote control sid"
} }
responseMessage.code = resultCode val responseMessage = toServerObjectBuilder.setCode(resultCode).build()
responseMessage.errorMsg = resultMsg val resultByteArray = ByteArray(responseMessage.getSizeNoTag())
responseMessage.writeTo(CodedOutputStream(resultByteArray))
finalCallback.invoke() callback.invoke(resultByteArray)
} }
} }
@@ -2,27 +2,35 @@ package net.server.handlers.rc
import exceptions.RcControlException import exceptions.RcControlException
import net.server.handlers.AbstractHandler import net.server.handlers.AbstractHandler
import CodedInputStream
import CodedOutputStream
/** /**
* Created by user on 7/27/16. * Created by user on 7/27/16.
*/ */
class Heartbeat : AbstractHandler { class Heartbeat : AbstractHandler {
constructor(protoDecoder: dynamic, protoEncoder: dynamic) : super(protoDecoder, protoEncoder) val fromServerObjectBuilder: HeartBeatRequest.BuilderHeartBeatRequest
val toServerObjectBuilder: HeartBeatResponse.BuilderHeartBeatResponse
override fun makeResponse(message: dynamic, responseMessage: dynamic, finalCallback: () -> Unit) { constructor(fromSrv: HeartBeatRequest.BuilderHeartBeatRequest, toSrv: HeartBeatResponse.BuilderHeartBeatResponse) : super() {
this.fromServerObjectBuilder = fromSrv
this.toServerObjectBuilder = toSrv
}
override fun getBytesResponse(data: ByteArray, callback: (ByteArray) -> Unit) {
val message = fromServerObjectBuilder.build()
message.mergeFrom(CodedInputStream(data))
val resultCode: Int val resultCode: Int
val resultMsg: String
try { try {
MicroController.instance.rcHeartBeat(message.sid) MicroController.instance.rcHeartBeat(message.sid)
resultCode = 0 resultCode = 0
resultMsg = ""
} catch (e: RcControlException) { } catch (e: RcControlException) {
resultCode = 12 resultCode = 12
resultMsg = "incorrect remote control sid"
} }
responseMessage.code = resultCode val responseMessage = toServerObjectBuilder.setCode(resultCode).build()
responseMessage.errorMsg = resultMsg val resultByteArray = ByteArray(responseMessage.getSizeNoTag())
finalCallback.invoke() responseMessage.writeTo(CodedOutputStream(resultByteArray))
callback.invoke(resultByteArray)
} }
} }