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