Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Fake pod implementation

* This version also mimics a behavior we see in some DASH pods where the pod disconnects every 3 minutes; this can be used with iOS hooks to make a heartbeat to run Loop in situations where a BLE CGM is not available.

* It serves a control panel at http://<host>:8080/ (`-api` changes the address): the pod's reservoir, delivery, age, alerts and fault, with controls to set the reservoir and pod age, raise alerts, trigger or clear a fault, and crash on the next command to test unacknowledged commands. The panel drives a JSON API: `GET /status`, and `POST /command` with `{"command": "changeReservoir", "value": 45}` (also `setActiveTime` in minutes, `setAlerts` as a slot mask, `setFault` with a fault code, 0 to clear, and `crashNextCommand` with `"beforeProcessing": true|false`).
* It serves a control panel at http://<host>:8080/ (`-api` changes the address): the pod's reservoir, delivery, age, alerts and fault, with controls to set the reservoir and pod age, raise alerts, trigger or clear a fault, and crash on the next command to test unacknowledged commands. The panel drives a JSON API: `GET /status`, and `POST /command` with `{"command": "changeReservoir", "value": 45}` (also `setActiveTime` in minutes, `setAlerts` as a slot mask, `setFault` with a fault code, 0 to clear, `crashNextCommand` with `"beforeProcessing": true|false`, and `ignoreNextMessages` with a count, which keeps the link up but leaves that many messages unanswered, as a pod that didn't hear them would).

* The websocket API at `/ws`, used by the separate [NodeJS/React frontend](https://github.com/ps2/pod_simulator_frontend), is still there.

Expand Down
5 changes: 5 additions & 0 deletions pkg/api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,11 @@ func (s *Server) handleCommand(bytes []byte) error {
return err
}
s.pod.SetActiveTime(int(value))
case "ignoreNextMessages":
if err := needValue("message count", 0, 100); err != nil {
return err
}
s.pod.IgnoreNextMessages(int(value))
case "crashNextCommand":
beforeProcessing, ok := msg["beforeProcessing"].(bool)
if !ok {
Expand Down
20 changes: 20 additions & 0 deletions pkg/pod/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ type Pod struct {
// Once one of these are set, the next command will crash the executable.
var crashBeforeProcessingCommand bool
var crashAfterProcessingCommand bool
var ignoreMessages int

func New(ble *bluetooth.Ble, state *PODState) *Pod {
ret := &Pod{
Expand Down Expand Up @@ -338,6 +339,17 @@ func (p *Pod) CommandLoop(pMsg PodMsgBody) {
}
log.Tracef("pkg pod; got command message: %s", spew.Sdump(msg))

p.mtx.Lock()
ignore := ignoreMessages > 0
if ignore {
ignoreMessages--
}
p.mtx.Unlock()
if ignore {
log.Infof("pkg pod; ignoring message seq %d (ignoreNextMessages)", msg.SequenceNumber)
continue
}

if msg.SequenceNumber == lastMsgSeq {
// this is a retry because we did not answer yet
// ignore duplicate commands/mesages
Expand Down Expand Up @@ -835,6 +847,14 @@ func (p *Pod) SetActiveTime(newVal int) {
p.mtx.Unlock()
}

// IgnoreNextMessages makes the pod stay connected but not answer the next
// count messages, as a pod that didn't hear them would.
func (p *Pod) IgnoreNextMessages(count int) {
p.mtx.Lock()
ignoreMessages = count
p.mtx.Unlock()
}

func (p *Pod) CrashNextCommand(beforeProcessing bool) {
p.mtx.Lock()
if beforeProcessing {
Expand Down
Loading