From b4a1ad8ac5a0a0d164ceefcc639d82a0de21a6fd Mon Sep 17 00:00:00 2001
From: Ekaitz Zarraga <ekaitz@elenq.tech>
Date: Wed, 1 Jan 2025 12:03:16 +0100
Subject: simulation: forward vchannel:

Now we can answer in the proper channel and SF in both windows.
---
 simulation.scm | 100 +++++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 69 insertions(+), 31 deletions(-)

diff --git a/simulation.scm b/simulation.scm
index 92db446..262140c 100644
--- a/simulation.scm
+++ b/simulation.scm
@@ -25,6 +25,7 @@
   #:use-module (fibers operations)
   #:use-module (fibers timers))
 
+;; TODO: review these
 (define RX1 1) ; s (has to be between 1-15s)
 (define RX2 (+ 2 RX1)) ; s
 (define RECEIVE_DELAY1 3) ; s
@@ -97,6 +98,10 @@
 (define RX2-vchannel-US902-928 (make-vchannel 923300 8))
 (define RX1DROffset 0)
 
+;; TODO Parameterize the EU/US selection so we can just call:
+;; `upstream-vchannel->RX1-vchannel` so the thing just works with the proper
+;; legislation
+
 (define (upstream-vchannel->RX1-vchannel-EU863-870 vchan RX1DROffset)
   (define (upstream-dr->downstream-dr dr)
     (match dr
@@ -148,10 +153,11 @@
 
 ;; For Gateway <--> Network Server
 (define-record-type <network-event>
-  (make-network-event gateway-id frame)
+  (make-network-event gateway-id frame in-vchannel)
   network-event?
   (gateway-id network-event-gateway-id)
-  (frame network-event-frame))
+  (frame network-event-frame)
+  (in-vchannel network-event-in-vchannel))
 
 ;; body can be:
 ;; 'unconfirmed-data (uplink)
@@ -265,12 +271,21 @@
       (let* ((now       (get-internal-real-time))
              (RX1-start (+ now (seconds->time-unit RECEIVE_DELAY1)))
              (RX2-start (+ now (seconds->time-unit RECEIVE_DELAY2)))
-             (downlink  (or (begin (wait-until RX1-start)
-                                   (receive-window vchannel RX1))
-                            (if (< (get-internal-real-time) RX2-start)
-                              (begin (wait-until RX2-start)
-                                     (receive-window vchannel RX2))
-                              #f))))
+             (downlink
+               (or (begin
+                     (wait-until RX1-start)
+                     (receive-window
+                       ;; TODO: US?
+                       (upstream-vchannel->RX1-vchannel-EU863-870
+                         vchannel
+                         RX1DROffset)
+                       RX1))
+                   (if (< (get-internal-real-time) RX2-start)
+                     (begin
+                       (wait-until RX2-start)
+                       ;; TODO: US
+                       (receive-window RX2-vchannel-EU863-870 RX2))
+                     #f))))
         (when downlink (process-downlink! downlink)))))
 
   (define (downstream-sink)
@@ -293,13 +308,12 @@
   (define time-on-air 0.01) ;s (TODO)
   (define pending-interferences '())
 
-  (define (send-to-device frame)
+  (define (send-to-device frame vchannel)
     (ll "Trying to downlink")
     (spawn-fiber
       (lambda ()
         ;; TODO: choose channel properly
-        (let ((event-id (new-id))
-              (vchannel (make-vchannel 50000000 0))) ;; TODO: hehe invented!
+        (let ((event-id (new-id)))
           (ll "Gateway ~a sending downlink ~a" id frame)
           (put-message radio
             (make-radio-event 'downlink-start event-id vchannel frame))
@@ -307,17 +321,17 @@
           (put-message radio
             (make-radio-event 'downlink-end   event-id vchannel frame))))))
 
-  (define (send-to-network-server x)
-    (ll "Gateway ~a forwarding ~a" id x)
-    (put-message network (make-network-event id x)))
+  (define (send-to-network-server frame vchannel)
+    (ll "Gateway ~a forwarding ~a" id frame)
+    (put-message network (make-network-event id frame vchannel)))
 
   ;; Upstream: listen, and answer in new fibers
   (lambda ()
     (forever
       (let* ((ev (get-message in)))
         (match ev
-          (($ <network-event> id frame)
-           (send-to-device frame))
+          (($ <network-event> id frame vchannel)
+           (send-to-device frame vchannel))
           (($ <radio-event> 'uplink-start event-id vchannel frame) #f)
           (($ <radio-event> 'interference event-id vchannel frame)
            (set! pending-interferences (cons ev pending-interferences)))
@@ -328,7 +342,7 @@
                                     pending-interferences)))
              (set! pending-interferences not-mine)
              (when (null? mine) ;; TODO
-               (send-to-network-server frame)))))))))
+               (send-to-network-server frame vchannel)))))))))
 
 
 (define (make-radio in end-devices gateways)
@@ -425,23 +439,47 @@
 
 (define (make-network-server upstream gateways end-devices)
 
+  (define (answer-in-RX1-async gateway-id vchannel frame)
+    (spawn-fiber
+      (lambda ()
+        (sleep RECEIVE_DELAY1)
+        (put-message
+          ;; TODO: should we answer to more gateways than the one that sent us
+          ;; the message?
+          (device-channel (hash-table-ref gateways gateway-id))
+          (make-network-event
+            gateway-id
+            (make-frame (frame-FCnt frame)
+                        (frame-DeviceAddr frame)
+                        #f
+                        'hello) ;; TODO answer properly
+            ;; TODO: US?
+            (upstream-vchannel->RX1-vchannel-EU863-870 vchannel RX1DROffset))))))
+
+  (define (answer-in-RX2-async gateway-id _ frame)
+    (spawn-fiber
+      (lambda ()
+        (sleep RECEIVE_DELAY2)
+        (put-message
+          ;; TODO: should we answer to more gateways than the one that sent us
+          ;; the message?
+          (device-channel (hash-table-ref gateways gateway-id))
+          (make-network-event
+            gateway-id
+            (make-frame (frame-FCnt frame)
+                        (frame-DeviceAddr frame)
+                        #f
+                        'hello) ;; TODO answer properly
+            ;; TODO: US?
+            RX2-vchannel-EU863-870)))))
+
   (lambda ()
     (forever
       (match (get-message upstream)
-        (($ <network-event> gateway-id frame)
-         (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))))))))))
+         (($ <network-event> gateway-id frame vchannel)
+           (ll "Network event happened!")
+           ;; TODO: Maybe answer in RX2 under certain conditions?
+           (answer-in-RX1-async gateway-id vchannel frame))))))
 
 
 
-- 
cgit v1.2.3