message.go 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. package dbus
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "errors"
  6. "io"
  7. "reflect"
  8. "strconv"
  9. )
  10. const protoVersion byte = 1
  11. // Flags represents the possible flags of a D-Bus message.
  12. type Flags byte
  13. const (
  14. // FlagNoReplyExpected signals that the message is not expected to generate
  15. // a reply. If this flag is set on outgoing messages, any possible reply
  16. // will be discarded.
  17. FlagNoReplyExpected Flags = 1 << iota
  18. // FlagNoAutoStart signals that the message bus should not automatically
  19. // start an application when handling this message.
  20. FlagNoAutoStart
  21. )
  22. // Type represents the possible types of a D-Bus message.
  23. type Type byte
  24. const (
  25. TypeMethodCall Type = 1 + iota
  26. TypeMethodReply
  27. TypeError
  28. TypeSignal
  29. typeMax
  30. )
  31. func (t Type) String() string {
  32. switch t {
  33. case TypeMethodCall:
  34. return "method call"
  35. case TypeMethodReply:
  36. return "reply"
  37. case TypeError:
  38. return "error"
  39. case TypeSignal:
  40. return "signal"
  41. }
  42. return "invalid"
  43. }
  44. // HeaderField represents the possible byte codes for the headers
  45. // of a D-Bus message.
  46. type HeaderField byte
  47. const (
  48. FieldPath HeaderField = 1 + iota
  49. FieldInterface
  50. FieldMember
  51. FieldErrorName
  52. FieldReplySerial
  53. FieldDestination
  54. FieldSender
  55. FieldSignature
  56. FieldUnixFDs
  57. fieldMax
  58. )
  59. // An InvalidMessageError describes the reason why a D-Bus message is regarded as
  60. // invalid.
  61. type InvalidMessageError string
  62. func (e InvalidMessageError) Error() string {
  63. return "dbus: invalid message: " + string(e)
  64. }
  65. // fieldType are the types of the various header fields.
  66. var fieldTypes = [fieldMax]reflect.Type{
  67. FieldPath: objectPathType,
  68. FieldInterface: stringType,
  69. FieldMember: stringType,
  70. FieldErrorName: stringType,
  71. FieldReplySerial: uint32Type,
  72. FieldDestination: stringType,
  73. FieldSender: stringType,
  74. FieldSignature: signatureType,
  75. FieldUnixFDs: uint32Type,
  76. }
  77. // requiredFields lists the header fields that are required by the different
  78. // message types.
  79. var requiredFields = [typeMax][]HeaderField{
  80. TypeMethodCall: {FieldPath, FieldMember},
  81. TypeMethodReply: {FieldReplySerial},
  82. TypeError: {FieldErrorName, FieldReplySerial},
  83. TypeSignal: {FieldPath, FieldInterface, FieldMember},
  84. }
  85. // Message represents a single D-Bus message.
  86. type Message struct {
  87. Type
  88. Flags
  89. Headers map[HeaderField]Variant
  90. Body []interface{}
  91. serial uint32
  92. }
  93. type header struct {
  94. Field byte
  95. Variant
  96. }
  97. // DecodeMessage tries to decode a single message in the D-Bus wire format
  98. // from the given reader. The byte order is figured out from the first byte.
  99. // The possibly returned error can be an error of the underlying reader, an
  100. // InvalidMessageError or a FormatError.
  101. func DecodeMessage(rd io.Reader) (msg *Message, err error) {
  102. var order binary.ByteOrder
  103. var hlength, length uint32
  104. var typ, flags, proto byte
  105. var headers []header
  106. b := make([]byte, 1)
  107. _, err = rd.Read(b)
  108. if err != nil {
  109. return
  110. }
  111. switch b[0] {
  112. case 'l':
  113. order = binary.LittleEndian
  114. case 'B':
  115. order = binary.BigEndian
  116. default:
  117. return nil, InvalidMessageError("invalid byte order")
  118. }
  119. dec := newDecoder(rd, order)
  120. dec.pos = 1
  121. msg = new(Message)
  122. vs, err := dec.Decode(Signature{"yyyuu"})
  123. if err != nil {
  124. return nil, err
  125. }
  126. if err = Store(vs, &typ, &flags, &proto, &length, &msg.serial); err != nil {
  127. return nil, err
  128. }
  129. msg.Type = Type(typ)
  130. msg.Flags = Flags(flags)
  131. // get the header length separately because we need it later
  132. b = make([]byte, 4)
  133. _, err = io.ReadFull(rd, b)
  134. if err != nil {
  135. return nil, err
  136. }
  137. binary.Read(bytes.NewBuffer(b), order, &hlength)
  138. if hlength+length+16 > 1<<27 {
  139. return nil, InvalidMessageError("message is too long")
  140. }
  141. dec = newDecoder(io.MultiReader(bytes.NewBuffer(b), rd), order)
  142. dec.pos = 12
  143. vs, err = dec.Decode(Signature{"a(yv)"})
  144. if err != nil {
  145. return nil, err
  146. }
  147. if err = Store(vs, &headers); err != nil {
  148. return nil, err
  149. }
  150. msg.Headers = make(map[HeaderField]Variant)
  151. for _, v := range headers {
  152. msg.Headers[HeaderField(v.Field)] = v.Variant
  153. }
  154. dec.align(8)
  155. body := make([]byte, int(length))
  156. if length != 0 {
  157. _, err := io.ReadFull(rd, body)
  158. if err != nil {
  159. return nil, err
  160. }
  161. }
  162. if err = msg.IsValid(); err != nil {
  163. return nil, err
  164. }
  165. sig, _ := msg.Headers[FieldSignature].value.(Signature)
  166. if sig.str != "" {
  167. buf := bytes.NewBuffer(body)
  168. dec = newDecoder(buf, order)
  169. vs, err := dec.Decode(sig)
  170. if err != nil {
  171. return nil, err
  172. }
  173. msg.Body = vs
  174. }
  175. return
  176. }
  177. // EncodeTo encodes and sends a message to the given writer. The byte order must
  178. // be either binary.LittleEndian or binary.BigEndian. If the message is not
  179. // valid or an error occurs when writing, an error is returned.
  180. func (msg *Message) EncodeTo(out io.Writer, order binary.ByteOrder) error {
  181. if err := msg.IsValid(); err != nil {
  182. return err
  183. }
  184. var vs [7]interface{}
  185. switch order {
  186. case binary.LittleEndian:
  187. vs[0] = byte('l')
  188. case binary.BigEndian:
  189. vs[0] = byte('B')
  190. default:
  191. return errors.New("dbus: invalid byte order")
  192. }
  193. body := new(bytes.Buffer)
  194. enc := newEncoder(body, order)
  195. if len(msg.Body) != 0 {
  196. enc.Encode(msg.Body...)
  197. }
  198. vs[1] = msg.Type
  199. vs[2] = msg.Flags
  200. vs[3] = protoVersion
  201. vs[4] = uint32(len(body.Bytes()))
  202. vs[5] = msg.serial
  203. headers := make([]header, 0, len(msg.Headers))
  204. for k, v := range msg.Headers {
  205. headers = append(headers, header{byte(k), v})
  206. }
  207. vs[6] = headers
  208. var buf bytes.Buffer
  209. enc = newEncoder(&buf, order)
  210. enc.Encode(vs[:]...)
  211. enc.align(8)
  212. body.WriteTo(&buf)
  213. if buf.Len() > 1<<27 {
  214. return InvalidMessageError("message is too long")
  215. }
  216. if _, err := buf.WriteTo(out); err != nil {
  217. return err
  218. }
  219. return nil
  220. }
  221. // IsValid checks whether msg is a valid message and returns an
  222. // InvalidMessageError if it is not.
  223. func (msg *Message) IsValid() error {
  224. if msg.Flags & ^(FlagNoAutoStart|FlagNoReplyExpected) != 0 {
  225. return InvalidMessageError("invalid flags")
  226. }
  227. if msg.Type == 0 || msg.Type >= typeMax {
  228. return InvalidMessageError("invalid message type")
  229. }
  230. for k, v := range msg.Headers {
  231. if k == 0 || k >= fieldMax {
  232. return InvalidMessageError("invalid header")
  233. }
  234. if reflect.TypeOf(v.value) != fieldTypes[k] {
  235. return InvalidMessageError("invalid type of header field")
  236. }
  237. }
  238. for _, v := range requiredFields[msg.Type] {
  239. if _, ok := msg.Headers[v]; !ok {
  240. return InvalidMessageError("missing required header")
  241. }
  242. }
  243. if path, ok := msg.Headers[FieldPath]; ok {
  244. if !path.value.(ObjectPath).IsValid() {
  245. return InvalidMessageError("invalid path name")
  246. }
  247. }
  248. if iface, ok := msg.Headers[FieldInterface]; ok {
  249. if !isValidInterface(iface.value.(string)) {
  250. return InvalidMessageError("invalid interface name")
  251. }
  252. }
  253. if member, ok := msg.Headers[FieldMember]; ok {
  254. if !isValidMember(member.value.(string)) {
  255. return InvalidMessageError("invalid member name")
  256. }
  257. }
  258. if errname, ok := msg.Headers[FieldErrorName]; ok {
  259. if !isValidInterface(errname.value.(string)) {
  260. return InvalidMessageError("invalid error name")
  261. }
  262. }
  263. if len(msg.Body) != 0 {
  264. if _, ok := msg.Headers[FieldSignature]; !ok {
  265. return InvalidMessageError("missing signature")
  266. }
  267. }
  268. return nil
  269. }
  270. // Serial returns the message's serial number. The returned value is only valid
  271. // for messages received by eavesdropping.
  272. func (msg *Message) Serial() uint32 {
  273. return msg.serial
  274. }
  275. // String returns a string representation of a message similar to the format of
  276. // dbus-monitor.
  277. func (msg *Message) String() string {
  278. if err := msg.IsValid(); err != nil {
  279. return "<invalid>"
  280. }
  281. s := msg.Type.String()
  282. if v, ok := msg.Headers[FieldSender]; ok {
  283. s += " from " + v.value.(string)
  284. }
  285. if v, ok := msg.Headers[FieldDestination]; ok {
  286. s += " to " + v.value.(string)
  287. }
  288. s += " serial " + strconv.FormatUint(uint64(msg.serial), 10)
  289. if v, ok := msg.Headers[FieldReplySerial]; ok {
  290. s += " reply_serial " + strconv.FormatUint(uint64(v.value.(uint32)), 10)
  291. }
  292. if v, ok := msg.Headers[FieldUnixFDs]; ok {
  293. s += " unixfds " + strconv.FormatUint(uint64(v.value.(uint32)), 10)
  294. }
  295. if v, ok := msg.Headers[FieldPath]; ok {
  296. s += " path " + string(v.value.(ObjectPath))
  297. }
  298. if v, ok := msg.Headers[FieldInterface]; ok {
  299. s += " interface " + v.value.(string)
  300. }
  301. if v, ok := msg.Headers[FieldErrorName]; ok {
  302. s += " error " + v.value.(string)
  303. }
  304. if v, ok := msg.Headers[FieldMember]; ok {
  305. s += " member " + v.value.(string)
  306. }
  307. if len(msg.Body) != 0 {
  308. s += "\n"
  309. }
  310. for i, v := range msg.Body {
  311. s += " " + MakeVariant(v).String()
  312. if i != len(msg.Body)-1 {
  313. s += "\n"
  314. }
  315. }
  316. return s
  317. }