summaryrefslogtreecommitdiff
path: root/simulation.scm
diff options
context:
space:
mode:
authorEkaitz Zarraga <ekaitz@elenq.tech>2024-12-23 21:33:41 +0100
committerEkaitz Zarraga <ekaitz@elenq.tech>2024-12-23 23:25:49 +0100
commit237b826969b0f0be0d682649d36ad5d118ccb40b (patch)
treebde22848622caae8d4c31190728209e7d73cccb8 /simulation.scm
parent4db83c056a34aaa7adc3de215b9e6068155ce6f4 (diff)
simulation: start with downlink control
Diffstat (limited to 'simulation.scm')
-rw-r--r--simulation.scm112
1 files changed, 90 insertions, 22 deletions
diff --git a/simulation.scm b/simulation.scm
index dd78fa1..d3f2c96 100644
--- a/simulation.scm
+++ b/simulation.scm
@@ -7,8 +7,21 @@
#:use-module (ice-9 match)
#:use-module (fibers)
#:use-module (fibers channels)
+ #:use-module (fibers operations)
#:use-module (fibers timers))
+(define (put-message/timeout chan msg to)
+ (perform-operation (choice-operation
+ (sleep-operation to)
+ (put-operation chan msg))))
+
+(define (get-message/timeout chan to default)
+ (perform-operation (choice-operation
+ (wrap-operation (sleep-operation to)
+ (lambda _ default))
+ (get-operation chan))))
+
+
(define RX1 1) ; s (has to be between 1-15s)
(define RX2 (1+ RX1)) ; s
(define RECEIVE_DELAY1 1) ; s
@@ -87,6 +100,7 @@
(random 2.))
(define (make-class-a id initial-channel upstream-chn downstream-chn)
+ (define window (make-channel))
;; Make all atomic
(define channel initial-channel)
@@ -101,16 +115,23 @@
;; Handle the receive windows
(define listening? (make-atomic-box #f))
- (define (start-listening!)
+ (define (start-waiting-for! chn frame-counter)
(ll "Device ~a started listening" id)
- (atomic-box-set! listening? #t))
- (define (stop-listening!)
+ (atomic-box-set! listening? (list chn frame-counter)))
+ (define (stop-waiting!)
(ll "Device ~a stopped listening" id)
(atomic-box-set! listening? #f))
- (define (im-listening?)
- (atomic-box-ref listening?))
+ (define (waiting-for? chn frame)
+ (let ((listen (atomic-box-ref listening?)))
+ (and listen
+ (= chn (car listen))
+ (= (frame-FCnt frame) (cadr listen)))))
- (define (confirm frame-FCnt)
+ (define (process-downlink! frame)
+ ;; TODO
+ (ll "Device ~a got downlink frame ~a" id frame))
+
+ #;(define (confirm frame-FCnt)
(when (eq? frame-FCnt (atomic-box-compare-and-swap! to-confirm frame-FCnt #f))
(spawn-fiber
(lambda () "confirm confirmation frame"))))
@@ -134,12 +155,28 @@
(ll "Device ~a waiting for data" id)
(sleep (rand-time))) ;; wait for more data
(send-uplink-frame current-frame id #t)
- (set! current-frame (1+ current-frame)) ;; TODO: fix
- (sleep RECEIVE_DELAY1)
- (start-listening!)
- (sleep RX1)
- (stop-listening!)
- (when (atomic-box-ref to-confirm)
+ (set! current-frame (1+ current-frame)) ;; TODO: improve
+ (sleep RECEIVE_DELAY1) ;; TODO: make sure this is ok
+
+ (start-waiting-for! channel (1- current-frame))
+ (let ((maybe-downstream-event (get-message/timeout window RX1 #f)))
+ (match maybe-downstream-event
+ (($ <radio-event> 'downlink-start chn frame)
+ (let ((event (get-message window)))
+ (stop-waiting!)
+ (match event
+ (($ <radio-event> 'downlink-end chn frame)
+ (process-downlink! frame))
+ (_ #f))))
+ (_ (stop-waiting!)))
+
+ #;(when (in-time?)
+ (wait-until-rx2)
+ (start-waiting-for! answer-to-x)
+ (open-RX2)
+ (stop-waiting! answer-to-x)))
+
+ #;(when (atomic-box-ref to-confirm)
(sleep (- RECEIVE_DELAY2 RECEIVE_DELAY1 RX1))
(start-listening!)
(sleep RX2)
@@ -147,10 +184,17 @@
(define (downstream)
(forever
- (let ((msg (get-message downstream-chn)))
- (when (im-listening?)
- (match (frame-body msg)
- ('ack (confirm (frame-FCnt msg))))))))
+ (let ((ev (get-message downstream-chn)))
+ ;; TODO:
+ ;; If the same message is sent by several gateways how to identify
+ ;; which start corresponds to each end??
+ (match ev
+ (($ <radio-event> type chn frame)
+ (when (waiting-for? chn frame)
+ ;; do not add timeout if it's waiting for an end???
+ (spawn-fiber (lambda ()
+ (put-message window ev)))
+ ))))))
(lambda ()
(spawn-fiber upstream)
@@ -160,7 +204,17 @@
(define time-on-air 0.01) ;s (TODO)
(define pending-interferences '())
- (define (forward-frame x)
+ (define (send-to-device frame)
+ (ll "Trying to downlink")
+ (spawn-fiber
+ (lambda ()
+ ;; TODO: choose channel properly
+ (ll "Gateway ~a sending downlink ~a" id frame)
+ (put-message radio (make-radio-event 'downlink-start 0 frame))
+ (sleep time-on-air)
+ (put-message radio (make-radio-event 'downlink-end 0 frame)))))
+
+ (define (send-to-network-server x)
(ll "Gateway ~a forwarding ~a" id x)
(put-message network (make-network-event id x)))
@@ -169,6 +223,8 @@
(forever
(let* ((ev (get-message in)))
(match ev
+ (($ <network-event> id frame)
+ (send-to-device frame))
(($ <radio-event> 'uplink-start channel-n frame) #f)
(($ <radio-event> 'interference channel-n frame)
(set! pending-interferences (cons ev pending-interferences)))
@@ -179,7 +235,7 @@
pending-interferences)))
(set! pending-interferences not-mine)
(when (null? mine) ;; TODO
- (forward-frame frame)))))))))
+ (send-to-network-server frame)))))))))
(define (make-radio in end-devices gateways)
@@ -238,8 +294,8 @@
(frame-FCnt frame)
channel-n)
(use-lorawan-channel! channel-n ev)
- (let ((chan (hash-table-ref end-devices
- (frame-DeviceAddr frame)))
+ (let ((chan (device-channel (hash-table-ref end-devices
+ (frame-DeviceAddr frame))))
(ints (interferences ev channel-n)))
(put-message chan ev)
(for-each
@@ -261,7 +317,7 @@
(put-message (device-channel gateway) ev))))))
(($ <radio-event> 'downlink-end channel-n frame)
- (ll "Device ~a ended uplink-frame #~a on channel ~a"
+ (ll "Device ~a ended downlink-frame #~a on channel ~a"
(frame-DeviceAddr frame)
(frame-FCnt frame)
channel-n)
@@ -278,7 +334,19 @@
(forever
(match (get-message upstream)
(($ <network-event> gateway-id frame)
- (ll "Network event happend!"))))))
+ (ll "Network event happend!")
+ ;; TODO answer properly
+ (spawn-fiber
+ (lambda ()
+ (sleep RECEIVE_DELAY1)
+ (put-message
+ (device-channel (hash-table-ref gateways gateway-id))
+ (make-network-event
+ gateway-id
+ (make-frame (frame-FCnt frame)
+ (frame-DeviceAddr frame)
+ #f
+ 'hello))))))))))