Skip to content

Commit 4f6efde

Browse files
authored
Merge pull request #324 from HyperloopUPV-H8/backend/blcu-board-id
Get BLCU id from ADJ
2 parents af4cd10 + e32f14f commit 4f6efde

File tree

6 files changed

+143
-49
lines changed

6 files changed

+143
-49
lines changed

backend/cmd/main.go

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ import (
6767

6868
const (
6969
BACKEND = "backend"
70-
BLCU = "blcu"
70+
BLCU = "BLCU"
7171
TcpClient = "TCP_CLIENT"
7272
TcpServer = "TCP_SERVER"
7373
UDP = "UDP"
@@ -88,7 +88,7 @@ var currentVersion string
8888

8989
func main() {
9090
// update() // FIXME: Updater disabled due to cross-platform and reliability issues
91-
91+
9292
traceFile := initTrace(*traceLevel, *traceFile)
9393
defer traceFile.Close()
9494

@@ -223,16 +223,34 @@ func main() {
223223
// <--- BLCU Board --->
224224
// Register BLCU board for handling bootloader operations
225225
if blcuIP, exists := adj.Info.Addresses[BLCU]; exists {
226-
tftpConfig := boards.TFTPConfig{
227-
BlockSize: config.TFTP.BlockSize,
228-
Retries: config.TFTP.Retries,
229-
TimeoutMs: config.TFTP.TimeoutMs,
230-
BackoffFactor: config.TFTP.BackoffFactor,
231-
EnableProgress: config.TFTP.EnableProgress,
226+
blcuId, idExists := adj.Info.BoardIds["BLCU"]
227+
if !idExists {
228+
trace.Error().Msg("BLCU IP found in ADJ but board ID missing")
229+
} else {
230+
// Get configurable order IDs or use defaults
231+
downloadOrderId := config.Blcu.DownloadOrderId
232+
uploadOrderId := config.Blcu.UploadOrderId
233+
if downloadOrderId == 0 {
234+
downloadOrderId = boards.DefaultBlcuDownloadOrderId
235+
}
236+
if uploadOrderId == 0 {
237+
uploadOrderId = boards.DefaultBlcuUploadOrderId
238+
}
239+
240+
tftpConfig := boards.TFTPConfig{
241+
BlockSize: config.TFTP.BlockSize,
242+
Retries: config.TFTP.Retries,
243+
TimeoutMs: config.TFTP.TimeoutMs,
244+
BackoffFactor: config.TFTP.BackoffFactor,
245+
EnableProgress: config.TFTP.EnableProgress,
246+
}
247+
blcuBoard := boards.NewWithConfig(blcuIP, tftpConfig, abstraction.BoardId(blcuId), downloadOrderId, uploadOrderId)
248+
vehicle.AddBoard(blcuBoard)
249+
vehicle.SetBlcuId(abstraction.BoardId(blcuId))
250+
trace.Info().Str("ip", blcuIP).Int("id", int(blcuId)).Uint16("download_order_id", downloadOrderId).Uint16("upload_order_id", uploadOrderId).Msg("BLCU board registered")
232251
}
233-
blcuBoard := boards.NewWithTFTPConfig(blcuIP, tftpConfig)
234-
vehicle.AddBoard(blcuBoard)
235-
trace.Info().Str("ip", blcuIP).Msg("BLCU board registered")
252+
} else {
253+
trace.Warn().Msg("BLCU not found in ADJ configuration - bootloader operations unavailable")
236254
}
237255

238256
// <--- transport --->
@@ -254,15 +272,15 @@ func main() {
254272
downloadOrderId := config.Blcu.DownloadOrderId
255273
uploadOrderId := config.Blcu.UploadOrderId
256274
if downloadOrderId == 0 {
257-
downloadOrderId = boards.BlcuDownloadOrderId
275+
downloadOrderId = boards.DefaultBlcuDownloadOrderId
258276
}
259277
if uploadOrderId == 0 {
260-
uploadOrderId = boards.BlcuUploadOrderId
278+
uploadOrderId = boards.DefaultBlcuUploadOrderId
261279
}
262-
280+
263281
transp.SetIdTarget(abstraction.PacketId(downloadOrderId), abstraction.TransportTarget("BLCU"))
264282
transp.SetIdTarget(abstraction.PacketId(uploadOrderId), abstraction.TransportTarget("BLCU"))
265-
283+
266284
// Use BLCU address from config, ADJ, or default
267285
blcuIP := config.Blcu.IP
268286
if blcuIP == "" {
@@ -289,23 +307,23 @@ func main() {
289307
}
290308
// Create TCP client config with custom parameters from config
291309
clientConfig := tcp.NewClientConfig(backendTcpClientAddr)
292-
310+
293311
// Apply custom timeout if specified
294312
if config.TCP.ConnectionTimeout > 0 {
295313
clientConfig.Timeout = time.Duration(config.TCP.ConnectionTimeout) * time.Millisecond
296314
}
297-
315+
298316
// Apply custom keep-alive if specified
299317
if config.TCP.KeepAlive > 0 {
300318
clientConfig.KeepAlive = time.Duration(config.TCP.KeepAlive) * time.Millisecond
301319
}
302-
320+
303321
// Apply custom backoff parameters
304322
if config.TCP.BackoffMinMs > 0 || config.TCP.BackoffMaxMs > 0 || config.TCP.BackoffMultiplier > 0 {
305323
minBackoff := 100 * time.Millisecond // default
306-
maxBackoff := 5 * time.Second // default
307-
multiplier := 1.5 // default
308-
324+
maxBackoff := 5 * time.Second // default
325+
multiplier := 1.5 // default
326+
309327
if config.TCP.BackoffMinMs > 0 {
310328
minBackoff = time.Duration(config.TCP.BackoffMinMs) * time.Millisecond
311329
}
@@ -315,13 +333,13 @@ func main() {
315333
if config.TCP.BackoffMultiplier > 0 {
316334
multiplier = config.TCP.BackoffMultiplier
317335
}
318-
336+
319337
clientConfig.ConnectionBackoffFunction = tcp.NewExponentialBackoff(minBackoff, multiplier, maxBackoff)
320338
}
321-
339+
322340
// Apply max retries (0 or negative means infinite)
323341
clientConfig.MaxConnectionRetries = config.TCP.MaxRetries
324-
342+
325343
go transp.HandleClient(clientConfig, fmt.Sprintf("%s:%d", adj.Info.Addresses[board.Name], adj.Info.Ports[TcpServer]))
326344
i++
327345
}

backend/pkg/boards/blcu.go

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,16 @@ import (
1111
dataPacket "github.com/HyperloopUPV-H8/h9-backend/pkg/transport/packet/data"
1212
)
1313

14-
// TODO! Get from ADE
1514
const (
1615
BlcuName = "BLCU"
17-
BlcuId = abstraction.BoardId(1)
1816

1917
AckId = abstraction.BoardEvent("ACK")
2018
DownloadEventId = abstraction.BoardEvent("DOWNLOAD")
2119
UploadEventId = abstraction.BoardEvent("UPLOAD")
2220

23-
BlcuDownloadOrderId = 701
24-
BlcuUploadOrderId = 700
21+
// Default order IDs - can be overridden via config.toml
22+
DefaultBlcuDownloadOrderId = 701
23+
DefaultBlcuUploadOrderId = 700
2524
)
2625

2726
type TFTPConfig struct {
@@ -33,31 +32,50 @@ type TFTPConfig struct {
3332
}
3433

3534
type BLCU struct {
36-
api abstraction.BoardAPI
37-
ackChan chan struct{}
38-
ip string
39-
tftpConfig TFTPConfig
35+
api abstraction.BoardAPI
36+
ackChan chan struct{}
37+
ip string
38+
tftpConfig TFTPConfig
39+
id abstraction.BoardId
40+
downloadOrderId uint16
41+
uploadOrderId uint16
4042
}
4143

44+
// Deprecated: Use NewWithConfig with proper board ID and order IDs from configuration
4245
func New(ip string) *BLCU {
4346
return NewWithTFTPConfig(ip, TFTPConfig{
4447
BlockSize: 131072, // 128kB
4548
Retries: 3,
4649
TimeoutMs: 5000,
4750
BackoffFactor: 2,
4851
EnableProgress: true,
49-
})
52+
}, 0) // Board ID 0 indicates missing configuration
5053
}
5154

52-
func NewWithTFTPConfig(ip string, tftpConfig TFTPConfig) *BLCU {
55+
// Deprecated: Use NewWithConfig for proper order ID configuration
56+
func NewWithTFTPConfig(ip string, tftpConfig TFTPConfig, id abstraction.BoardId) *BLCU {
5357
return &BLCU{
54-
ackChan: make(chan struct{}),
55-
ip: ip,
56-
tftpConfig: tftpConfig,
58+
ackChan: make(chan struct{}),
59+
ip: ip,
60+
tftpConfig: tftpConfig,
61+
id: id,
62+
downloadOrderId: DefaultBlcuDownloadOrderId,
63+
uploadOrderId: DefaultBlcuUploadOrderId,
5764
}
5865
}
59-
func (boards *BLCU) Id() abstraction.BoardId {
60-
return BlcuId
66+
67+
func NewWithConfig(ip string, tftpConfig TFTPConfig, id abstraction.BoardId, downloadOrderId, uploadOrderId uint16) *BLCU {
68+
return &BLCU{
69+
ackChan: make(chan struct{}),
70+
ip: ip,
71+
tftpConfig: tftpConfig,
72+
id: id,
73+
downloadOrderId: downloadOrderId,
74+
uploadOrderId: uploadOrderId,
75+
}
76+
}
77+
func (board *BLCU) Id() abstraction.BoardId {
78+
return board.id
6179
}
6280

6381
func (boards *BLCU) Notify(boardNotification abstraction.BoardNotification) {
@@ -96,7 +114,7 @@ func (boards *BLCU) SetAPI(api abstraction.BoardAPI) {
96114
func (boards *BLCU) download(notification DownloadEvent) error {
97115
// Notify the BLCU
98116
ping := dataPacket.NewPacketWithValues(
99-
abstraction.PacketId(BlcuDownloadOrderId),
117+
abstraction.PacketId(boards.downloadOrderId),
100118
map[dataPacket.ValueName]dataPacket.Value{
101119
BlcuName: dataPacket.NewEnumValue(dataPacket.EnumVariant(notification.Board)),
102120
},
@@ -169,7 +187,7 @@ func (boards *BLCU) download(notification DownloadEvent) error {
169187
}
170188

171189
func (boards *BLCU) upload(notification UploadEvent) error {
172-
ping := dataPacket.NewPacketWithValues(abstraction.PacketId(BlcuUploadOrderId),
190+
ping := dataPacket.NewPacketWithValues(abstraction.PacketId(boards.uploadOrderId),
173191
map[dataPacket.ValueName]dataPacket.Value{
174192
BlcuName: dataPacket.NewEnumValue(dataPacket.EnumVariant(notification.Board)),
175193
},

backend/pkg/boards/blcu_simple_test.go

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,76 @@ package boards_test
33
import (
44
"testing"
55

6+
"github.com/HyperloopUPV-H8/h9-backend/pkg/abstraction"
67
"github.com/HyperloopUPV-H8/h9-backend/pkg/boards"
78
blcu_topic "github.com/HyperloopUPV-H8/h9-backend/pkg/broker/topics/blcu"
89
"github.com/HyperloopUPV-H8/h9-backend/pkg/vehicle"
910
"github.com/rs/zerolog"
1011
)
1112

12-
// TestBLCUBoardRegistration tests that BLCU board can be registered
13+
// TestBLCUBoardRegistration tests that BLCU board can be registered with different configurations
1314
func TestBLCUBoardRegistration(t *testing.T) {
1415
logger := zerolog.New(nil).Level(zerolog.Disabled)
1516
v := vehicle.New(logger)
1617

17-
// Create and register BLCU board
18+
// Test deprecated constructor (should use board ID 0)
1819
blcuBoard := boards.New("192.168.0.10")
1920
v.AddBoard(blcuBoard)
2021

22+
// Verify board is registered with ID 0 (missing configuration)
23+
if blcuBoard.Id() != 0 {
24+
t.Errorf("Expected board ID 0 for deprecated constructor, got %d", blcuBoard.Id())
25+
}
26+
}
27+
28+
// TestBLCUWithCustomConfiguration tests BLCU with custom board ID and order IDs
29+
func TestBLCUWithCustomConfiguration(t *testing.T) {
30+
logger := zerolog.New(nil).Level(zerolog.Disabled)
31+
v := vehicle.New(logger)
32+
33+
// Test new constructor with custom configuration
34+
tftpConfig := boards.TFTPConfig{
35+
BlockSize: 131072,
36+
Retries: 3,
37+
TimeoutMs: 5000,
38+
BackoffFactor: 2,
39+
EnableProgress: true,
40+
}
41+
42+
customBoardId := abstraction.BoardId(7)
43+
customDownloadOrderId := uint16(801)
44+
customUploadOrderId := uint16(802)
45+
46+
blcuBoard := boards.NewWithConfig("192.168.0.10", tftpConfig, customBoardId, customDownloadOrderId, customUploadOrderId)
47+
v.AddBoard(blcuBoard)
48+
49+
// Verify board is registered with custom ID
50+
if blcuBoard.Id() != customBoardId {
51+
t.Errorf("Expected board ID %d, got %d", customBoardId, blcuBoard.Id())
52+
}
53+
}
54+
55+
// TestBLCUWithDefaultConfiguration tests BLCU with default order IDs
56+
func TestBLCUWithDefaultConfiguration(t *testing.T) {
57+
logger := zerolog.New(nil).Level(zerolog.Disabled)
58+
v := vehicle.New(logger)
59+
60+
// Test deprecated constructor (should use default order IDs)
61+
tftpConfig := boards.TFTPConfig{
62+
BlockSize: 131072,
63+
Retries: 3,
64+
TimeoutMs: 5000,
65+
BackoffFactor: 2,
66+
EnableProgress: true,
67+
}
68+
69+
boardId := abstraction.BoardId(7)
70+
blcuBoard := boards.NewWithTFTPConfig("192.168.0.10", tftpConfig, boardId)
71+
v.AddBoard(blcuBoard)
72+
2173
// Verify board is registered
22-
if blcuBoard.Id() != boards.BlcuId {
23-
t.Errorf("Expected board ID %d, got %d", boards.BlcuId, blcuBoard.Id())
74+
if blcuBoard.Id() != boardId {
75+
t.Errorf("Expected board ID %d, got %d", boardId, blcuBoard.Id())
2476
}
2577
}
2678

backend/pkg/vehicle/constructor.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,8 @@ func (vehicle *Vehicle) SetIpToBoardId(ipToBoardId map[string]abstraction.BoardI
7575
vehicle.ipToBoardId = ipToBoardId
7676
vehicle.trace.Info().Msg("set ip to board id")
7777
}
78+
79+
func (vehicle *Vehicle) SetBlcuId(id abstraction.BoardId) {
80+
vehicle.BlcuId = id
81+
vehicle.trace.Info().Uint16("blcu_id", uint16(id)).Msg("set blcu id")
82+
}

backend/pkg/vehicle/notification.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ func (vehicle *Vehicle) handlePacketNotification(notification transport.PacketNo
131131
return errors.Join(fmt.Errorf("remove state orders (state orders from %s to %s)", notification.From, notification.To), err)
132132
}
133133
case *blcu_packet.Ack:
134-
vehicle.boards[boards.BlcuId].Notify(abstraction.BoardNotification(
134+
vehicle.boards[vehicle.BlcuId].Notify(abstraction.BoardNotification(
135135
&boards.AckNotification{
136136
ID: boards.AckId,
137137
},

backend/pkg/vehicle/vehicle.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ type Vehicle struct {
3333
updateFactory *update_factory.UpdateFactory
3434
idToBoardName map[uint16]string
3535
ipToBoardId map[string]abstraction.BoardId
36+
BlcuId abstraction.BoardId
3637

3738
trace zerolog.Logger
3839
}
@@ -92,11 +93,11 @@ func (vehicle *Vehicle) UserPush(push abstraction.BrokerPush) error {
9293
case "blcu/downloadRequest":
9394
download := push.(*blcu_topic.DownloadRequest)
9495

95-
if board, exists := vehicle.boards[boards.BlcuId]; exists {
96+
if board, exists := vehicle.boards[vehicle.BlcuId]; exists {
9697
board.Notify(abstraction.BoardNotification(
9798
&boards.DownloadEvent{
9899
BoardEvent: boards.DownloadEventId,
99-
BoardID: boards.BlcuId,
100+
BoardID: vehicle.BlcuId,
100101
Board: download.Board,
101102
},
102103
))
@@ -124,7 +125,7 @@ func (vehicle *Vehicle) UserPush(push abstraction.BrokerPush) error {
124125
return nil
125126
}
126127

127-
if board, exists := vehicle.boards[boards.BlcuId]; exists {
128+
if board, exists := vehicle.boards[vehicle.BlcuId]; exists {
128129
board.Notify(abstraction.BoardNotification(uploadEvent))
129130
} else {
130131
fmt.Fprintf(os.Stderr, "BLCU board not registered\n")

0 commit comments

Comments
 (0)