some errors still causing crashes, error handling work needed
This commit is contained in:
223
ledd.go
223
ledd.go
@@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"gopkg.in/mgo.v2"
|
"gopkg.in/mgo.v2"
|
||||||
|
"gopkg.in/mgo.v2/bson"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
@@ -132,7 +133,13 @@ func (manager *LEDManager) start() {
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case led := <-manager.add:
|
case led := <-manager.add:
|
||||||
log.Debugf("[%s] Request to add led: %s", led.backend, led.name)
|
log.Debugf("[%s] Request to add LED: %s (%s)", led.backend, led.name, led.channel)
|
||||||
|
|
||||||
|
if led.name == "" || len(led.channel) == 0 || led.backend == "" {
|
||||||
|
log.Warningf("[%s] Can't add LED without required information! (%s)", LOG_CLIENTS, led)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
manager.leds[led.name] = led
|
manager.leds[led.name] = led
|
||||||
go manager.color(led)
|
go manager.color(led)
|
||||||
err := LEDCollection.Insert(led)
|
err := LEDCollection.Insert(led)
|
||||||
@@ -141,7 +148,8 @@ func (manager *LEDManager) start() {
|
|||||||
}
|
}
|
||||||
case led := <-manager.remove:
|
case led := <-manager.remove:
|
||||||
if _, ok := manager.leds[led.name]; ok {
|
if _, ok := manager.leds[led.name]; ok {
|
||||||
log.Debugf("[%s] Request to remove led %s", led.backend, led.name)
|
log.Debugf("[%s] Request to remove %s", led.backend, led.name)
|
||||||
|
LEDCollection.RemoveAll(bson.M{"name": led.name})
|
||||||
delete(manager.leds, led.name)
|
delete(manager.leds, led.name)
|
||||||
}
|
}
|
||||||
case color := <-manager.broadcast:
|
case color := <-manager.broadcast:
|
||||||
@@ -158,7 +166,33 @@ func (manager *LEDManager) color(led *LED) {
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case color := <-led.color:
|
case color := <-led.color:
|
||||||
led.setColor(color)
|
if backend, ok := backManager.backends[led.backend]; ok {
|
||||||
|
if len(led.channel) != 3 {
|
||||||
|
log.Warningf("[%s] Currently only RGB LEDs are supported", led.name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cMap := make(map[int32]int32)
|
||||||
|
r, g, b := color.Clamped().RGB255()
|
||||||
|
|
||||||
|
cMap[led.channel[0]] = int32((float64(r) / 255) * float64(backend.resolution))
|
||||||
|
cMap[led.channel[1]] = int32((float64(g) / 255) * float64(backend.resolution))
|
||||||
|
cMap[led.channel[2]] = int32((float64(b) / 255) * float64(backend.resolution))
|
||||||
|
|
||||||
|
wrapperMsg := &ledd.BackendWrapperMessage{
|
||||||
|
Msg: &ledd.BackendWrapperMessage_MSetChannel{
|
||||||
|
MSetChannel: &ledd.BackendSetChannel{
|
||||||
|
NewChannelValues: cMap}}}
|
||||||
|
|
||||||
|
data, err := proto.Marshal(wrapperMsg)
|
||||||
|
if err != nil {
|
||||||
|
log.Warningf("[%s] Failed to encode protobuf msg to %s: %s", led.name, backend.name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
backend.data <- prepareProtobuf(data)
|
||||||
|
} else {
|
||||||
|
log.Warningf("[LM] Failed to set color for %s: backend %s not found", led.name, led.backend)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -170,7 +204,7 @@ func (manager *BackendManager) start() {
|
|||||||
select {
|
select {
|
||||||
case backend := <-manager.register:
|
case backend := <-manager.register:
|
||||||
manager.backends[backend.name] = backend
|
manager.backends[backend.name] = backend
|
||||||
log.Debugf("[%s] New backend: %s", LOG_BACKEND, backend.niceName())
|
log.Debugf("[%s] %s registered", LOG_BACKEND, backend.niceName())
|
||||||
wrapperMsg := &ledd.BackendWrapperMessage{
|
wrapperMsg := &ledd.BackendWrapperMessage{
|
||||||
Msg: &ledd.BackendWrapperMessage_MLedd{
|
Msg: &ledd.BackendWrapperMessage_MLedd{
|
||||||
MLedd: &ledd.LedD{
|
MLedd: &ledd.LedD{
|
||||||
@@ -187,7 +221,7 @@ func (manager *BackendManager) start() {
|
|||||||
backend.data <- prepareProtobuf(data)
|
backend.data <- prepareProtobuf(data)
|
||||||
case backend := <-manager.unregister:
|
case backend := <-manager.unregister:
|
||||||
if _, ok := manager.backends[backend.name]; ok {
|
if _, ok := manager.backends[backend.name]; ok {
|
||||||
log.Debugf("[%s] Backend %s removed: connection terminated", LOG_BACKEND, backend.socket.RemoteAddr())
|
log.Debugf("[%s] %s removed: connection terminated", LOG_BACKEND, backend.socket.RemoteAddr())
|
||||||
close(backend.data)
|
close(backend.data)
|
||||||
delete(manager.backends, backend.name)
|
delete(manager.backends, backend.name)
|
||||||
}
|
}
|
||||||
@@ -238,10 +272,10 @@ func (manager *BackendManager) receive(backend *Backend) {
|
|||||||
if length > 0 {
|
if length > 0 {
|
||||||
msgLen := binary.BigEndian.Uint32(message[0:4])
|
msgLen := binary.BigEndian.Uint32(message[0:4])
|
||||||
|
|
||||||
log.Debugf("[%s] Read %d bytes, first protobuf is %d long", backend.niceName(), length, msgLen)
|
// log.Debugf("[%s] Read %d bytes, first protobuf is %d long", backend.niceName(), length, msgLen)
|
||||||
|
|
||||||
backendMsg := &ledd.BackendWrapperMessage{}
|
backendMsg := &ledd.BackendWrapperMessage{}
|
||||||
err = proto.Unmarshal(message[4:msgLen+1], backendMsg)
|
err = proto.Unmarshal(message[4:msgLen+4], backendMsg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warningf("[%s] Couldn't decode protobuf msg!", backend.niceName())
|
log.Warningf("[%s] Couldn't decode protobuf msg!", backend.niceName())
|
||||||
continue
|
continue
|
||||||
@@ -269,10 +303,46 @@ func (manager *ClientManager) start() {
|
|||||||
select {
|
select {
|
||||||
case client := <-manager.register:
|
case client := <-manager.register:
|
||||||
manager.clients[client] = true
|
manager.clients[client] = true
|
||||||
log.Debugf("[%s] New frontend (%s)", LOG_CLIENTS, client.socket.RemoteAddr(), client.platform)
|
log.Debugf("[%s] Client %s (%s) registered", LOG_CLIENTS, client.socket.RemoteAddr(), client.platform)
|
||||||
|
|
||||||
|
backends := make([]*ledd.Backend, 0, len(backManager.backends))
|
||||||
|
leds := make([]*ledd.LED, 0, len(ledManager.leds))
|
||||||
|
|
||||||
|
for _, led := range ledManager.leds {
|
||||||
|
leds = append(leds, &ledd.LED{
|
||||||
|
Name: led.name,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, backend := range backManager.backends {
|
||||||
|
backends = append(backends, &ledd.Backend{
|
||||||
|
Name: backend.name,
|
||||||
|
Channel: backend.channel,
|
||||||
|
Resolution: backend.resolution,
|
||||||
|
Type: backend.platformType,
|
||||||
|
Version: backend.version,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
wrapperMsg := &ledd.ClientWrapperMessage{
|
||||||
|
Leds: leds,
|
||||||
|
Backends: backends,
|
||||||
|
Msg: &ledd.ClientWrapperMessage_MLedd{
|
||||||
|
MLedd: &ledd.LedD{
|
||||||
|
Name: config.Name,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := proto.Marshal(wrapperMsg)
|
||||||
|
if err != nil {
|
||||||
|
log.Warningf("[%s] Failed to encode protobuf msg: %s", client.socket.RemoteAddr(), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client.data <- prepareProtobuf(data)
|
||||||
case client := <-manager.unregister:
|
case client := <-manager.unregister:
|
||||||
if _, ok := manager.clients[client]; ok {
|
if _, ok := manager.clients[client]; ok {
|
||||||
log.Debugf("[%s] Removed client (%s)", LOG_CLIENTS, client.socket.RemoteAddr(), client.platform)
|
log.Debugf("[%s] %s (%s) removed", LOG_CLIENTS, client.socket.RemoteAddr(), client.platform)
|
||||||
close(client.data)
|
close(client.data)
|
||||||
delete(manager.clients, client)
|
delete(manager.clients, client)
|
||||||
}
|
}
|
||||||
@@ -313,55 +383,95 @@ func (manager *ClientManager) receive(client *Client) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
if length > 0 {
|
if length > 0 {
|
||||||
msgLen := binary.BigEndian.Uint32(message[0:4])
|
//log.Debugf("[%s] Read %d bytes", client.socket.RemoteAddr(), length)
|
||||||
|
|
||||||
log.Debugf("[%s] Read %d bytes, first protobuf is %d long", client.socket.RemoteAddr(), length, msgLen)
|
for i := 0; i < length; {
|
||||||
|
msgLen := int(binary.BigEndian.Uint32(message[i:i+4]))
|
||||||
|
|
||||||
clientMsg := &ledd.ClientWrapperMessage{}
|
// log.Debugf("[%s] Reading protobuf after %d (len=%d)", client.socket.RemoteAddr(), i+4, msgLen)
|
||||||
err = proto.Unmarshal(message[4:msgLen+1], clientMsg)
|
|
||||||
if err != nil {
|
|
||||||
log.Warningf("[%s] Couldn't decode protobuf msg!", client.socket.RemoteAddr())
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
switch msg := clientMsg.Msg.(type) {
|
clientMsg := &ledd.ClientWrapperMessage{}
|
||||||
case *ledd.ClientWrapperMessage_MClient:
|
err = proto.Unmarshal(message[i+4:i+msgLen+4], clientMsg)
|
||||||
client.platform = msg.MClient.Type
|
i += msgLen + 4
|
||||||
log.Infof("[%s] %s is now identified as client (%s)", LOG_CLIENTS, client.socket.RemoteAddr(), client.platform)
|
|
||||||
clientManager.register <- client
|
|
||||||
case *ledd.ClientWrapperMessage_MGetLed:
|
|
||||||
allLED := make([]*ledd.LED, 0)
|
|
||||||
|
|
||||||
for _, led := range ledManager.leds {
|
|
||||||
allLED = append(allLED, &ledd.LED{Name: led.name})
|
|
||||||
}
|
|
||||||
|
|
||||||
data, err := proto.Marshal(&ledd.ClientWrapperMessage{Leds: allLED})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("[%s] Error encoding protobuf: %s", client.socket.RemoteAddr(), err)
|
log.Warningf("[%s] Couldn't decode protobuf msg!", client.socket.RemoteAddr())
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
client.data <- prepareProtobuf(data)
|
switch msg := clientMsg.Msg.(type) {
|
||||||
case *ledd.ClientWrapperMessage_MAddLed:
|
case *ledd.ClientWrapperMessage_MClient:
|
||||||
backend, ok := backManager.backends[msg.MAddLed.Backend]
|
client.platform = msg.MClient.Type
|
||||||
if !ok {
|
log.Infof("[%s] %s is now identified as client (%s)", LOG_CLIENTS, client.socket.RemoteAddr(), client.platform)
|
||||||
log.Warningf("[%s] Can't add LED for non-existing backend %s", client.socket.RemoteAddr(), msg.MAddLed.Backend)
|
clientManager.register <- client
|
||||||
}
|
case *ledd.ClientWrapperMessage_MGetLed:
|
||||||
|
allLED := make([]*ledd.LED, 0)
|
||||||
|
|
||||||
nLED := &LED{
|
for _, led := range ledManager.leds {
|
||||||
name: msg.MAddLed.Name,
|
allLED = append(allLED, &ledd.LED{Name: led.name})
|
||||||
channel: msg.MAddLed.Channel,
|
}
|
||||||
backend: backend.name,
|
|
||||||
}
|
|
||||||
|
|
||||||
ledManager.add <- nLED
|
data, err := proto.Marshal(&ledd.ClientWrapperMessage{Leds: allLED})
|
||||||
case *ledd.ClientWrapperMessage_MSetLed:
|
if err != nil {
|
||||||
led, ok := ledManager.leds[msg.MSetLed.Name]
|
log.Errorf("[%s] Error encoding protobuf: %s", client.socket.RemoteAddr(), err)
|
||||||
if !ok {
|
break
|
||||||
log.Warningf("[%s] Failed to set LED %s: LED not found", client.socket.RemoteAddr(), msg.MSetLed.Name)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
led.color <- colorful.Hcl(msg.MSetLed.Colour.Hue, msg.MSetLed.Colour.Chroma, msg.MSetLed.Colour.Light)
|
client.data <- prepareProtobuf(data)
|
||||||
|
case *ledd.ClientWrapperMessage_MAddLed:
|
||||||
|
backend, ok := backManager.backends[msg.MAddLed.Backend]
|
||||||
|
if !ok {
|
||||||
|
log.Warningf("[%s] Can't add LED for non-existing backend %s", client.socket.RemoteAddr(), msg.MAddLed.Backend)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := ledManager.leds[msg.MAddLed.Name]; ok {
|
||||||
|
log.Warningf("[%s] Can't add LED with exisiting name %s", client.socket.RemoteAddr(), msg.MAddLed.Name)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
nLED := &LED{
|
||||||
|
name: msg.MAddLed.Name,
|
||||||
|
channel: msg.MAddLed.Channel,
|
||||||
|
backend: backend.name,
|
||||||
|
color: make(chan colorful.Color),
|
||||||
|
}
|
||||||
|
|
||||||
|
ledManager.add <- nLED
|
||||||
|
case *ledd.ClientWrapperMessage_MSetLed:
|
||||||
|
leds := clientMsg.Leds
|
||||||
|
|
||||||
|
if len(leds) == 0 {
|
||||||
|
log.Warningf("[%s] Got setLED with no LEDs attached!", client.socket.RemoteAddr())
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, pLED := range leds {
|
||||||
|
led, ok := ledManager.leds[pLED.Name]
|
||||||
|
if !ok {
|
||||||
|
log.Warningf("[%s] Failed to set %s: not found", client.socket.RemoteAddr(), pLED.Name)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// log.Debugf("[%s] Set %s to %s", client.socket.RemoteAddr(), led.name, colorful.Hcl(msg.MSetLed.Colour.Hue, msg.MSetLed.Colour.Chroma, msg.MSetLed.Colour.Light))
|
||||||
|
|
||||||
|
led.color <- colorful.Hcl(msg.MSetLed.Colour.Hue, msg.MSetLed.Colour.Chroma, msg.MSetLed.Colour.Light)
|
||||||
|
}
|
||||||
|
case *ledd.ClientWrapperMessage_MSetDirect:
|
||||||
|
backend, ok := backManager.backends[msg.MSetDirect.Backend]
|
||||||
|
if !ok {
|
||||||
|
log.Warningf("[%s] Can't set channel for non-existing backend %s", client.socket.RemoteAddr(), msg.MSetDirect.Backend)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
backend.setChannel(msg.MSetDirect.Channel, msg.MSetDirect.Value)
|
||||||
|
case *ledd.ClientWrapperMessage_MRemoveLed:
|
||||||
|
led, ok := ledManager.leds[msg.MRemoveLed.Name]
|
||||||
|
if !ok {
|
||||||
|
log.Warningf("[%s] Failed to remove %s: not found", client.socket.RemoteAddr(), msg.MRemoveLed.Name)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
ledManager.remove <- led
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -383,19 +493,10 @@ func (backend *Backend) niceName() string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (led *LED) setColor(color colorful.Color) {
|
func (backend Backend) setChannel(channel int32, val int32) {
|
||||||
backend := backManager.backends[led.backend]
|
|
||||||
|
|
||||||
if len(led.channel) != 3 {
|
|
||||||
log.Warningf("[%s] Currently only RGB LEDs are supported", led.name)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
cMap := make(map[int32]int32)
|
cMap := make(map[int32]int32)
|
||||||
|
|
||||||
cMap[led.channel[0]] = int32(color.R * float64(backend.resolution))
|
cMap[channel] = val
|
||||||
cMap[led.channel[1]] = int32(color.G * float64(backend.resolution))
|
|
||||||
cMap[led.channel[2]] = int32(color.B * float64(backend.resolution))
|
|
||||||
|
|
||||||
wrapperMsg := &ledd.BackendWrapperMessage{
|
wrapperMsg := &ledd.BackendWrapperMessage{
|
||||||
Msg: &ledd.BackendWrapperMessage_MSetChannel{
|
Msg: &ledd.BackendWrapperMessage_MSetChannel{
|
||||||
@@ -404,7 +505,7 @@ func (led *LED) setColor(color colorful.Color) {
|
|||||||
|
|
||||||
data, err := proto.Marshal(wrapperMsg)
|
data, err := proto.Marshal(wrapperMsg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warningf("[%s] Failed to encode protobuf msg to %s: %s", led.name, backend.name, err)
|
log.Warningf("[%s] Failed to encode protobuf msg: %s", backend.niceName(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
backend.data <- prepareProtobuf(data)
|
backend.data <- prepareProtobuf(data)
|
||||||
|
2
proto
2
proto
Submodule proto updated: c0b46db0cf...b0f65bb09a
Reference in New Issue
Block a user