#lang racket (require (planet bzlib/parseq:1:3)) ; Ebus SYN Byte-String (define ebus-const-syn (string->bytes/latin-1 "\xaa")) (define ebus-const-escape (string->bytes/latin-1 "\xa9")) (define ebus-const-ackok (string->bytes/latin-1 "\x00")) (define ebus-const-broadcastaddr 254) (struct ebus-header (source destination primaryCommand secondaryCommand payloadLength) #:transparent) (struct ebus-body-broadcast (crc) #:transparent) (struct ebus-body-mastermaster (crc) #:transparent) (struct ebus-body-masterslave (crc payloadSlaveLength payloadSlave crcSlave) #:transparent) (struct ebus-paket (header body) #:transparent) (define parse-ebus-header (token (seq source <- any-byte destination <- any-byte primaryCommand <- any-byte secondaryCommand <- any-byte payloadLength <- any-byte (return (ebus-header source destination primaryCommand secondaryCommand payloadLength)) ))) ;; 1 payload data byte (define ebus-payload (choice (seq ebus-const-escape escape-code <- (byte-in (list #"\0" #"\1")) (return (cond ((= escape-code #"\0") ebus-const-escape) ((= escape-code #"\0") ebus-const-syn)))) any-byte )) (define parse-ebus-broadcast (token (seq crc <- any-byte syn <- (bytes= ebus-const-syn) (return (ebus-body-broadcast crc))))) (define parse-ebus-mastermaster (token (seq crc <- any-byte ack <- (bytes= ebus-const-ackok) ; ACK des Empfängers syn <- (bytes= ebus-const-syn) ; SYN des Senders (return (ebus-body-mastermaster crc))))) (define parse-ebus-masterslave (token (seq crc <- any-byte ack <- (bytes= ebus-const-ackok) ;ACK des Empfängers payloadSlaveLength <- any-byte payloadSlave <- (repeat ebus-payload payloadSlaveLength payloadSlaveLength) crcSlave <- any-byte ackSlave <- (bytes= ebus-const-ackok) ;ACK des Senders synSlave <- (bytes= ebus-const-syn) ;SYN des Senders (return (ebus-body-masterslave crc payloadSlaveLength payloadSlave crcSlave))))) (define parse-ebus-master-or-slave (token (choice parse-ebus-mastermaster parse-ebus-masterslave))) (define parse-ebus-paket (token (seq header <- parse-ebus-header payload <- (repeat ebus-payload (ebus-header-payloadLength header) (ebus-header-payloadLength header)) body <- (cond ((= (ebus-header-destination header) ebus-const-broadcastaddr) parse-ebus-broadcast) (else parse-ebus-master-or-slave)) (return (ebus-paket header body))))) (define ebus-sync (tokens syncs <- (seq (repeat (string->bytes/latin-1 "\xaa"))) (return (length syncs)))) (define input-port (open-input-file "../doc/dumps/dump_2011-12-17_23-04-00.bin")) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define (read-ebus) (let ([syn ((make-reader ebus-sync #:sof? #f #:eof? #f) input-port)] [paket ((make-reader parse-ebus-paket #:sof? #f #:eof? #f) input-port)]) (cond ((not (false? paket)) (cond ((not (false? syn)) (display (format "drop ~s x SYN (~s) ~n" syn ebus-const-syn)))) (display (format "Paket ~s~n" paket))) (else (display (format "drop ~s ~n" (peek-byte input-port))) (file-position input-port (+ 1 (file-position input-port))) )) (cond ((not (eof-object? (peek-byte input-port))) (read-ebus))))) (read-ebus) ;(define-values (cin cout) ; (tcp-connect "localhost" 2222)) ; ;(define (work-on port) ; (pretty-print token)