guile-netlink/netlink/message.scm

message.scm

1
;;;; This file is part of Guile Netlink
2
;;;;
3
;;;; Copyright (C) 2020 Julien Lepiller <julien@lepiller.eu>
4
;;;; 
5
;;;; This library is free software: you can redistribute it and/or modify
6
;;;; it under the terms of the GNU General Public License as published by
7
;;;; the Free Software Foundation, either version 3 of the License, or
8
;;;; (at your option) any later version.
9
;;;;
10
;;;; This library is distributed in the hope that it will be useful,
11
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
;;;; GNU General Public License for more details.
14
;;;;
15
;;;; You should have received a copy of the GNU General Public License
16
;;;; along with this library.  If not, see <https://www.gnu.org/licenses/>.
17
18
(define-module (netlink message)
19
  #:use-module (ice-9 match)
20
  #:use-module (netlink data)
21
  #:use-module (netlink standard)
22
  #:use-module (rnrs bytevectors)
23
  #:use-module (srfi srfi-9)
24
  #:export (make-message
25
            message?
26
            message-kind
27
            message-flags
28
            message-seq
29
            message-pid
30
            message-data
31
            deserialize-message
32
            deserialize-message-header))
33
34
(define-data-type message
35
  message-type-len
36
  (lambda (msg pos bv)
37
    (match msg
38
      (($ message-type type flags seq pid data)
39
       (bytevector-u32-set! bv pos (message-type-len msg) (native-endianness))
40
       (bytevector-u16-set! bv (+ pos 4) type (native-endianness))
41
       (bytevector-u16-set! bv (+ pos 6) flags (native-endianness))
42
       (bytevector-u32-set! bv (+ pos 8) seq (native-endianness))
43
       (bytevector-u32-set! bv (+ pos 12) pid (native-endianness))
44
       (serialize data (+ 16 pos) bv))))
45
  (type  message-kind  message-type-type)
46
  (flags message-flags message-type-flags)
47
  (seq   message-seq   message-type-seq)
48
  (pid   message-pid   message-type-pid)
49
  (data  message-data  message-type-data))
50
51
(define (message-type-len msg)
52
  (+ 16 (data-size (message-type-data msg))))
53
54
(define (deserialize-message decoder bv pos)
55
  (let* ((len (bytevector-u32-ref bv pos (native-endianness)))
56
         (type (bytevector-u16-ref bv (+ pos 4) (native-endianness)))
57
         (data (make-bytevector len))
58
         (deserialize (get-next-deserialize decoder 'message type)))
59
    (bytevector-copy! bv pos data 0 len)
60
    (let ((data (deserialize decoder data 16)))
61
      (make-message
62
        type
63
        (bytevector-u16-ref bv (+ pos 6) (native-endianness))
64
        (bytevector-u32-ref bv (+ pos 8) (native-endianness))
65
        (bytevector-u32-ref bv (+ pos 12) (native-endianness))
66
        (if (< (data-size data) (- len 16))
67
            (ensure-data-size data (- len 16))
68
            data)))))
69
70
(define (deserialize-message-header decoder bv pos)
71
  (make-message
72
    (bytevector-u16-ref bv (+ pos 4) (native-endianness))
73
    (bytevector-u16-ref bv (+ pos 6) (native-endianness))
74
    (bytevector-u32-ref bv (+ pos 8) (native-endianness))
75
    (bytevector-u32-ref bv (+ pos 12) (native-endianness))
76
    no-data))
77