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 (
|
||||
"encoding/binary"
|
||||
"gopkg.in/mgo.v2"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"net"
|
||||
"os"
|
||||
"os/signal"
|
||||
@@ -132,7 +133,13 @@ func (manager *LEDManager) start() {
|
||||
for {
|
||||
select {
|
||||
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
|
||||
go manager.color(led)
|
||||
err := LEDCollection.Insert(led)
|
||||
@@ -141,7 +148,8 @@ func (manager *LEDManager) start() {
|
||||
}
|
||||
case led := <-manager.remove:
|
||||
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)
|
||||
}
|
||||
case color := <-manager.broadcast:
|
||||
@@ -158,7 +166,33 @@ func (manager *LEDManager) color(led *LED) {
|
||||
for {
|
||||
select {
|
||||
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 {
|
||||
case backend := <-manager.register:
|
||||
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{
|
||||
Msg: &ledd.BackendWrapperMessage_MLedd{
|
||||
MLedd: &ledd.LedD{
|
||||
@@ -187,7 +221,7 @@ func (manager *BackendManager) start() {
|
||||
backend.data <- prepareProtobuf(data)
|
||||
case backend := <-manager.unregister:
|
||||
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)
|
||||
delete(manager.backends, backend.name)
|
||||
}
|
||||
@@ -238,10 +272,10 @@ func (manager *BackendManager) receive(backend *Backend) {
|
||||
if length > 0 {
|
||||
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{}
|
||||
err = proto.Unmarshal(message[4:msgLen+1], backendMsg)
|
||||
err = proto.Unmarshal(message[4:msgLen+4], backendMsg)
|
||||
if err != nil {
|
||||
log.Warningf("[%s] Couldn't decode protobuf msg!", backend.niceName())
|
||||
continue
|
||||
@@ -269,10 +303,46 @@ func (manager *ClientManager) start() {
|
||||
select {
|
||||
case client := <-manager.register:
|
||||
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:
|
||||
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)
|
||||
delete(manager.clients, client)
|
||||
}
|
||||
@@ -313,55 +383,95 @@ func (manager *ClientManager) receive(client *Client) {
|
||||
break
|
||||
}
|
||||
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{}
|
||||
err = proto.Unmarshal(message[4:msgLen+1], clientMsg)
|
||||
if err != nil {
|
||||
log.Warningf("[%s] Couldn't decode protobuf msg!", client.socket.RemoteAddr())
|
||||
continue
|
||||
}
|
||||
// log.Debugf("[%s] Reading protobuf after %d (len=%d)", client.socket.RemoteAddr(), i+4, msgLen)
|
||||
|
||||
switch msg := clientMsg.Msg.(type) {
|
||||
case *ledd.ClientWrapperMessage_MClient:
|
||||
client.platform = msg.MClient.Type
|
||||
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})
|
||||
clientMsg := &ledd.ClientWrapperMessage{}
|
||||
err = proto.Unmarshal(message[i+4:i+msgLen+4], clientMsg)
|
||||
i += msgLen + 4
|
||||
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)
|
||||
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)
|
||||
}
|
||||
switch msg := clientMsg.Msg.(type) {
|
||||
case *ledd.ClientWrapperMessage_MClient:
|
||||
client.platform = msg.MClient.Type
|
||||
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)
|
||||
|
||||
nLED := &LED{
|
||||
name: msg.MAddLed.Name,
|
||||
channel: msg.MAddLed.Channel,
|
||||
backend: backend.name,
|
||||
}
|
||||
for _, led := range ledManager.leds {
|
||||
allLED = append(allLED, &ledd.LED{Name: led.name})
|
||||
}
|
||||
|
||||
ledManager.add <- nLED
|
||||
case *ledd.ClientWrapperMessage_MSetLed:
|
||||
led, ok := ledManager.leds[msg.MSetLed.Name]
|
||||
if !ok {
|
||||
log.Warningf("[%s] Failed to set LED %s: LED not found", client.socket.RemoteAddr(), msg.MSetLed.Name)
|
||||
}
|
||||
data, err := proto.Marshal(&ledd.ClientWrapperMessage{Leds: allLED})
|
||||
if err != nil {
|
||||
log.Errorf("[%s] Error encoding protobuf: %s", client.socket.RemoteAddr(), err)
|
||||
break
|
||||
}
|
||||
|
||||
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) {
|
||||
backend := backManager.backends[led.backend]
|
||||
|
||||
if len(led.channel) != 3 {
|
||||
log.Warningf("[%s] Currently only RGB LEDs are supported", led.name)
|
||||
return
|
||||
}
|
||||
|
||||
func (backend Backend) setChannel(channel int32, val int32) {
|
||||
cMap := make(map[int32]int32)
|
||||
|
||||
cMap[led.channel[0]] = int32(color.R * float64(backend.resolution))
|
||||
cMap[led.channel[1]] = int32(color.G * float64(backend.resolution))
|
||||
cMap[led.channel[2]] = int32(color.B * float64(backend.resolution))
|
||||
cMap[channel] = val
|
||||
|
||||
wrapperMsg := &ledd.BackendWrapperMessage{
|
||||
Msg: &ledd.BackendWrapperMessage_MSetChannel{
|
||||
@@ -404,7 +505,7 @@ func (led *LED) setColor(color colorful.Color) {
|
||||
|
||||
data, err := proto.Marshal(wrapperMsg)
|
||||
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)
|
||||
|
2
proto
2
proto
Submodule proto updated: c0b46db0cf...b0f65bb09a
Reference in New Issue
Block a user