Skip to content

Commit bdd547d

Browse files
committed
Feat: Refactor BLCU TFTP status handling
1 parent 4f7ec52 commit bdd547d

4 files changed

Lines changed: 88 additions & 15 deletions

File tree

backend/cmd/dev-config.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ boards = ["HVSCU", "HVSCU-cabinet", "PCU", "LCU", "BCU", "BMSL"]
1818

1919
# ADJ (Architecture Description JSON) Configuration
2020
[adj]
21-
branch = "software" # Leave blank when using ADJ as a submodule (like this: "")
21+
branch = "BLCU_fixed_packets" # Leave blank when using ADJ as a submodule (like this: "")
2222
test = true # Enable test mode
2323

2424
# Network Configuration
2525
[network]
26-
manual = false # Manual network device selection
27-
dev_mode = true # IMPORTANT: Dev mode enabled - uses UDP server instead of packet sniffer
26+
manual = true # Manual network device selection
27+
dev_mode = true # IMPORTANT: Dev mode enabled - uses UDP server instead of packet sniffer
2828

2929
# Transport Configuration
3030
[transport]

backend/pkg/boards/blcu.go

Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212
)
1313

1414
const (
15-
BlcuName = "BLCU"
15+
BlcuName = "target"
1616

1717
AckId = abstraction.BoardEvent("ACK")
1818
DownloadEventId = abstraction.BoardEvent("DOWNLOAD")
@@ -33,7 +33,7 @@ type TFTPConfig struct {
3333

3434
type BLCU struct {
3535
api abstraction.BoardAPI
36-
ackChan chan struct{}
36+
tftpStatusChan chan bool
3737
ip string
3838
tftpConfig TFTPConfig
3939
id abstraction.BoardId
@@ -55,7 +55,7 @@ func New(ip string) *BLCU {
5555
// Deprecated: Use NewWithConfig for proper order ID configuration
5656
func NewWithTFTPConfig(ip string, tftpConfig TFTPConfig, id abstraction.BoardId) *BLCU {
5757
return &BLCU{
58-
ackChan: make(chan struct{}),
58+
tftpStatusChan: make(chan bool, 1),
5959
ip: ip,
6060
tftpConfig: tftpConfig,
6161
id: id,
@@ -66,7 +66,7 @@ func NewWithTFTPConfig(ip string, tftpConfig TFTPConfig, id abstraction.BoardId)
6666

6767
func NewWithConfig(ip string, tftpConfig TFTPConfig, id abstraction.BoardId, downloadOrderId, uploadOrderId uint16) *BLCU {
6868
return &BLCU{
69-
ackChan: make(chan struct{}),
69+
tftpStatusChan: make(chan bool, 1),
7070
ip: ip,
7171
tftpConfig: tftpConfig,
7272
id: id,
@@ -80,8 +80,8 @@ func (board *BLCU) Id() abstraction.BoardId {
8080

8181
func (boards *BLCU) Notify(boardNotification abstraction.BoardNotification) {
8282
switch notification := boardNotification.(type) {
83-
case *AckNotification:
84-
boards.ackChan <- struct{}{}
83+
case *TFTPStatusNotification:
84+
boards.tftpStatusChan <- notification.IsTFTPEnabled
8585

8686
case *DownloadEvent:
8787
err := boards.download(*notification)
@@ -92,6 +92,7 @@ func (boards *BLCU) Notify(boardNotification abstraction.BoardNotification) {
9292
}.Error())
9393
}
9494
case *UploadEvent:
95+
fmt.Println("Received upload event for board:", notification.Board)
9596
err := boards.upload(*notification)
9697
if err != nil {
9798
fmt.Println(ErrUploadFailure{
@@ -124,17 +125,32 @@ func (boards *BLCU) download(notification DownloadEvent) error {
124125

125126
err := boards.api.SendMessage(transport.NewPacketMessage(ping))
126127
if err != nil {
128+
// Couldn't connect to the BLCU
127129
return ErrSendMessageFailed{
128130
Timestamp: time.Now(),
129131
Inner: err,
130132
}
131133
}
132134

133-
// Wait for the ACK
134-
<-boards.ackChan
135+
// Wait for TFTP enabled status
136+
select {
137+
case isTFTPEnabled := <-boards.tftpStatusChan:
138+
if !isTFTPEnabled {
139+
return ErrSendMessageFailed{
140+
Timestamp: time.Now(),
141+
Inner: fmt.Errorf("TFTP not enabled on BLCU device"),
142+
}
143+
}
144+
case <-time.After(10 * time.Second):
145+
return ErrSendMessageFailed{
146+
Timestamp: time.Now(),
147+
Inner: fmt.Errorf("timeout waiting for TFTP status"),
148+
}
149+
}
135150

136151
// TODO! Notify on progress
137152

153+
// Start TFTP client
138154
client, err := tftp.NewClient(boards.ip,
139155
tftp.WithBlockSize(boards.tftpConfig.BlockSize),
140156
tftp.WithRetries(boards.tftpConfig.Retries),
@@ -148,6 +164,7 @@ func (boards *BLCU) download(notification DownloadEvent) error {
148164
}
149165
}
150166

167+
// Download the file
151168
buffer := &bytes.Buffer{}
152169

153170
_, err = client.ReadFile(BlcuName, tftp.BinaryMode, buffer)
@@ -171,6 +188,7 @@ func (boards *BLCU) download(notification DownloadEvent) error {
171188
}
172189
}
173190

191+
// Notify success to front
174192
pushErr := boards.api.SendPush(abstraction.BrokerPush(
175193
&DownloadSuccess{
176194
Data: buffer.Bytes(),
@@ -187,42 +205,72 @@ func (boards *BLCU) download(notification DownloadEvent) error {
187205
}
188206

189207
func (boards *BLCU) upload(notification UploadEvent) error {
190-
ping := dataPacket.NewPacketWithValues(abstraction.PacketId(boards.uploadOrderId),
208+
fmt.Println("Uploading BLCU firmware...")
209+
210+
// Create new packet with board update command
211+
ping := dataPacket.NewPacketWithValues(abstraction.PacketId(boards.uploadOrderId), // 700
191212
map[dataPacket.ValueName]dataPacket.Value{
192-
BlcuName: dataPacket.NewEnumValue(dataPacket.EnumVariant(notification.Board)),
213+
BlcuName: dataPacket.NewEnumValue(dataPacket.EnumVariant(notification.Board)), // The board to be updated
193214
},
194-
map[dataPacket.ValueName]bool{
215+
map[dataPacket.ValueName]bool{ // True
195216
BlcuName: true,
196217
})
218+
fmt.Println("Notifying BLCU...", ping)
197219

220+
// Actually send the message
198221
err := boards.api.SendMessage(transport.NewPacketMessage(ping))
199222
if err != nil {
223+
// Couldn't connect to the BLCU
224+
fmt.Println("Failed to send upload ping:", err)
200225
return ErrSendMessageFailed{
201226
Timestamp: time.Now(),
202227
Inner: err,
203228
}
204229
}
205230

206-
<-boards.ackChan
231+
// Wait for TFTP enabled status
232+
fmt.Println("Waiting for TFTP status...")
233+
select {
234+
case isTFTPEnabled := <-boards.tftpStatusChan:
235+
if !isTFTPEnabled {
236+
fmt.Println("TFTP not enabled on BLCU device")
237+
return ErrSendMessageFailed{
238+
Timestamp: time.Now(),
239+
Inner: fmt.Errorf("TFTP not enabled on BLCU device"),
240+
}
241+
}
242+
fmt.Println("TFTP enabled, starting upload...")
243+
case <-time.After(10 * time.Second):
244+
fmt.Println("Timeout waiting for TFTP status")
245+
return ErrSendMessageFailed{
246+
Timestamp: time.Now(),
247+
Inner: fmt.Errorf("timeout waiting for TFTP status"),
248+
}
249+
}
207250

208251
// TODO! Notify on progress
209252

253+
// Start TFTP client
254+
// TODO: Check if it fails here
210255
client, err := tftp.NewClient(boards.ip,
211256
tftp.WithBlockSize(boards.tftpConfig.BlockSize),
212257
tftp.WithRetries(boards.tftpConfig.Retries),
213258
tftp.WithTimeout(time.Duration(boards.tftpConfig.TimeoutMs)*time.Millisecond),
214259
)
215260
if err != nil {
261+
fmt.Println("Failed to create TFTP client:", err)
216262
return ErrNewClientFailed{
217263
Addr: boards.ip,
218264
Timestamp: time.Now(),
219265
Inner: err,
220266
}
221267
}
222268

269+
// Get the update payload and prepare the buffer
223270
data := notification.Data
224271
buffer := bytes.NewBuffer(data)
225272

273+
// Write the file
226274
read, err := client.WriteFile(BlcuName, tftp.BinaryMode, buffer)
227275
if err != nil {
228276
pushErr := boards.api.SendPush(abstraction.BrokerPush(
@@ -263,6 +311,7 @@ func (boards *BLCU) upload(notification UploadEvent) error {
263311
return err
264312
}
265313

314+
// Notify success to front
266315
pushErr := boards.api.SendPush(abstraction.BrokerPush(
267316
&UploadSuccess{}))
268317
if pushErr != nil {

backend/pkg/boards/events.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@ func (ack AckNotification) Event() abstraction.BoardEvent {
1212
return ack.ID
1313
}
1414

15+
type TFTPStatusNotification struct {
16+
IsTFTPEnabled bool
17+
}
18+
19+
func (status TFTPStatusNotification) Event() abstraction.BoardEvent {
20+
return "TFTP_STATUS"
21+
}
22+
1523
type DownloadEvent struct {
1624
BoardEvent abstraction.BoardEvent // DownloadId
1725
BoardID abstraction.BoardId

backend/pkg/vehicle/notification.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,22 @@ func (vehicle *Vehicle) handlePacketNotification(notification transport.PacketNo
4747

4848
switch p := notification.Packet.(type) {
4949
case *data.Packet:
50+
// Check if this is a TFTP status packet from BLCU (packet ID 5)
51+
if p.Id() == 5 && notification.From != "" {
52+
// Extract isTFTPEnabled boolean value
53+
values := p.GetValues()
54+
if isTFTPEnabledValue, ok := values["isTFTPEnabled"]; ok {
55+
if boolVal, ok := isTFTPEnabledValue.(*data.BooleanValue); ok {
56+
vehicle.boards[vehicle.BlcuId].Notify(abstraction.BoardNotification(
57+
&boards.TFTPStatusNotification{
58+
IsTFTPEnabled: boolVal.Value(),
59+
},
60+
))
61+
return nil
62+
}
63+
}
64+
}
65+
5066
update := vehicle.updateFactory.NewUpdate(p)
5167
err := vehicle.broker.Push(data_topic.NewPush(&update))
5268
if err != nil {

0 commit comments

Comments
 (0)