summaryrefslogtreecommitdiff
path: root/ebus-racket/ebus/layer2.rkt
blob: f9bc31a883cb039643a3ef16727e4143a93405f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#lang racket/base
(require (only-in racket/bool false?)
         "../3rdparty/bzlib/parseq/main.ss")

(define-logger ebus2)

(define ebus-const-syn #xaa) ;; SYN
(define ebus-const-escape #xa9) ;; Escape-Sequence Start
(define ebus-const-ackok #x00) ;; ACK
(define ebus-const-broadcastaddr #xfe) ;; Broadcast Address

(struct ebus-body-broadcast (crc) #:transparent)

(struct ebus-body-mastermaster (crc) #:transparent)

(struct ebus-body-masterslave
  (crc payloadSlaveLength payloadSlave crcSlave)
  #:transparent)

(struct ebus-paket
  (source destination primaryCommand secondaryCommand payloadLength payload body)
  #:transparent)

;; single, maybe escaped, payload data byte 
(define ebus-payload
  (choice (seq escape-seq <- ebus-const-escape
               escape-code <- (byte-in (list 0 1))
               (return (cond
                         ((= escape-code 0) ebus-const-escape)
                         ((= escape-code 1) bytes ebus-const-syn))))
          any-byte
          ))

(define parse-ebus-broadcast
  (token (seq crc <- any-byte
              syn <- ebus-const-syn
              (return (ebus-body-broadcast crc)))))

(define parse-ebus-mastermaster
  (token (seq  crc <- any-byte
               ack <- ebus-const-ackok ;; ACK des Empfängers
               syn <- ebus-const-syn   ;; SYN des Senders
               (return (ebus-body-mastermaster crc)))))

(define parse-ebus-masterslave 
  (token (seq crc <- any-byte
              ack <- ebus-const-ackok ;; ACK des Empfängers
              payloadSlaveLength <- any-byte
              payloadSlave <- (repeat ebus-payload payloadSlaveLength payloadSlaveLength)
              crcSlave <- any-byte
              ackSlave <- ebus-const-ackok ;; ACK des Senders
              synSlave <- ebus-const-syn   ;; SYN des Senders
              (return (ebus-body-masterslave crc payloadSlaveLength payloadSlave crcSlave)))))

(define parse-ebus-paket
  (token (seq source <- any-byte
              destination <- any-byte
              primaryCommand <- any-byte
              secondaryCommand <- any-byte
              payloadLength <- any-byte
              payload <- (repeat ebus-payload payloadLength payloadLength)
              body <- (cond ((= destination ebus-const-broadcastaddr) parse-ebus-broadcast)
                            (else (choice parse-ebus-mastermaster 
                                          parse-ebus-masterslave)))
              (return (ebus-paket source 
                                  destination
                                  primaryCommand
                                  secondaryCommand
                                  payloadLength
                                  payload 
                                  body)))))

(define ebus-sync (tokens syncs <- (seq (repeat (string->bytes/latin-1 "\xaa")))
                          (return (length syncs))))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(define (read-ebus input-port)
  (define syn   ((make-reader ebus-sync #:sof? #f #:eof? #f)  input-port))
  (define paket   ((make-reader parse-ebus-paket #:sof? #f #:eof? #f) input-port))
  (cond ((not (false? syn)) (log-ebus2-debug "dropped ~a x SYN (~a)" syn ebus-const-syn)))
  (cond ((not (false? paket)) paket)
        ((eof-object? (peek-byte input-port)) eof)
        (else
         ;; skip one byte
         (let ([byte (read-byte input-port)])
           (log-ebus2-debug "drop ~s 0x~x" byte byte))
         (read-ebus input-port))))

(provide 
 ;; Read Layer Ebus-Paket `ebus-paket`
 read-ebus
 ;; Expose datastructures
 (struct-out ebus-paket)
 (struct-out ebus-body-broadcast)
 (struct-out ebus-body-mastermaster)
 (struct-out ebus-body-masterslave))