endpoint.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. // Copyright 2013 Google Inc. All rights reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package usb
  15. // #include "libusb.h"
  16. import "C"
  17. import (
  18. "fmt"
  19. "reflect"
  20. "time"
  21. "unsafe"
  22. )
  23. type Endpoint interface {
  24. Read(b []byte) (int, error)
  25. Write(b []byte) (int, error)
  26. Interface() InterfaceSetup
  27. Info() EndpointInfo
  28. }
  29. type endpoint struct {
  30. *Device
  31. InterfaceSetup
  32. EndpointInfo
  33. xfer func(*endpoint, []byte, time.Duration) (int, error)
  34. }
  35. func (e *endpoint) Read(buf []byte) (int, error) {
  36. if EndpointDirection(e.Address)&ENDPOINT_DIR_MASK != ENDPOINT_DIR_IN {
  37. return 0, fmt.Errorf("usb: read: not an IN endpoint")
  38. }
  39. return e.xfer(e, buf, e.ReadTimeout)
  40. }
  41. func (e *endpoint) Write(buf []byte) (int, error) {
  42. if EndpointDirection(e.Address)&ENDPOINT_DIR_MASK != ENDPOINT_DIR_OUT {
  43. return 0, fmt.Errorf("usb: write: not an OUT endpoint")
  44. }
  45. return e.xfer(e, buf, e.WriteTimeout)
  46. }
  47. func (e *endpoint) Interface() InterfaceSetup { return e.InterfaceSetup }
  48. func (e *endpoint) Info() EndpointInfo { return e.EndpointInfo }
  49. // TODO(kevlar): (*Endpoint).Close
  50. func bulk_xfer(e *endpoint, buf []byte, timeout time.Duration) (int, error) {
  51. if len(buf) == 0 {
  52. return 0, nil
  53. }
  54. data := (*reflect.SliceHeader)(unsafe.Pointer(&buf)).Data
  55. var cnt C.int
  56. if errno := C.libusb_bulk_transfer(
  57. e.handle,
  58. C.uchar(e.Address),
  59. (*C.uchar)(unsafe.Pointer(data)),
  60. C.int(len(buf)),
  61. &cnt,
  62. C.uint(timeout/time.Millisecond)); errno < 0 {
  63. return 0, usbError(errno)
  64. }
  65. return int(cnt), nil
  66. }
  67. func interrupt_xfer(e *endpoint, buf []byte, timeout time.Duration) (int, error) {
  68. if len(buf) == 0 {
  69. return 0, nil
  70. }
  71. data := (*reflect.SliceHeader)(unsafe.Pointer(&buf)).Data
  72. var cnt C.int
  73. if errno := C.libusb_interrupt_transfer(
  74. e.handle,
  75. C.uchar(e.Address),
  76. (*C.uchar)(unsafe.Pointer(data)),
  77. C.int(len(buf)),
  78. &cnt,
  79. C.uint(timeout/time.Millisecond)); errno < 0 {
  80. return 0, usbError(errno)
  81. }
  82. return int(cnt), nil
  83. }