Merge "[docs] Add overview and compilation info."
diff --git a/cmd/zedmon/zedmon.go b/cmd/zedmon/zedmon.go
new file mode 100644
index 0000000..cd20015
--- /dev/null
+++ b/cmd/zedmon/zedmon.go
@@ -0,0 +1,92 @@
+// Copyright 2017 The Fuchsia Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package main
+
+import (
+ "encoding/csv"
+ "fmt"
+ "os"
+ "os/signal"
+ "strconv"
+
+ "fuchsia.googlesource.com/zedmon"
+)
+
+func main() {
+ zedmon, err := zedmon.OpenZedmon()
+ if err != nil {
+ panic(fmt.Sprintf("Can't open zendmon: %v", err))
+ }
+ defer zedmon.Close()
+
+ f, err := os.OpenFile("zedmon.csv", os.O_CREATE|os.O_RDWR, 0666)
+ if err != nil {
+ panic(fmt.Sprintf("Can't open zedmon.csv: %v", err))
+ }
+ defer f.Close()
+
+ offset, delta, err := zedmon.GetTimeOffset()
+ if err != nil {
+ panic(fmt.Sprintf("Get time offset: %v", err))
+ }
+ fmt.Printf("Time offset: %v ± %v\n", offset, delta)
+
+ termChan := make(chan os.Signal, 1)
+ signal.Notify(termChan, os.Interrupt)
+
+ writer := csv.NewWriter(f)
+ defer writer.Flush()
+
+ fmt.Printf("Starting report recording. Send ^C to stop.\n")
+ zedmon.EnableReporting()
+
+RecordSampling:
+ for {
+ reports, err := zedmon.ReadReports()
+ if err != nil {
+ fmt.Printf("Error reading reports: %v\n", err)
+ continue
+ }
+ for _, report := range reports {
+ record := make([]string, 0, len(report.Values))
+ record = append(record, strconv.FormatUint(report.Timestamp, 10))
+ for _, value := range report.Values {
+ record = append(record, strconv.FormatFloat(value, 'g', -1, 64))
+ }
+ writer.Write(record)
+ }
+
+ select {
+ case <-termChan:
+ break RecordSampling
+ default:
+ }
+ }
+ fmt.Printf("Stopping report recording.\n")
+}
diff --git a/lib/data_type.go b/lib/data_type.go
new file mode 100644
index 0000000..c7b3e45
--- /dev/null
+++ b/lib/data_type.go
@@ -0,0 +1,89 @@
+package lib
+
+import (
+ "encoding/binary"
+ "fmt"
+ "io"
+)
+
+type DataType uint
+
+const (
+ DATA_TYPE_UINT8 DataType = 0x00
+ DATA_TYPE_UINT16 = 0x01
+ DATA_TYPE_UINT32 = 0x02
+ DATA_TYPE_UINT64 = 0x03
+ DATA_TYPE_INT8 = 0x10
+ DATA_TYPE_INT16 = 0x11
+ DATA_TYPE_INT32 = 0x12
+ DATA_TYPE_INT64 = 0x13
+ DATA_TYPE_FLOAT32 = 0x40
+)
+
+func (dt DataType) Size() int {
+ switch dt {
+ case DATA_TYPE_UINT8:
+ return 1
+ case DATA_TYPE_UINT16:
+ return 2
+ case DATA_TYPE_UINT32:
+ return 4
+ case DATA_TYPE_UINT64:
+ return 8
+ case DATA_TYPE_INT8:
+ return 1
+ case DATA_TYPE_INT16:
+ return 2
+ case DATA_TYPE_INT32:
+ return 4
+ case DATA_TYPE_INT64:
+ return 8
+ case DATA_TYPE_FLOAT32:
+ return 4
+ default:
+ return -1
+ }
+}
+
+func (dt DataType) Read(r io.Reader) (float64, error) {
+ switch dt {
+ case DATA_TYPE_UINT8:
+ var val uint8
+ err := binary.Read(r, binary.LittleEndian, &val)
+ return float64(val), err
+ case DATA_TYPE_UINT16:
+ var val uint16
+ err := binary.Read(r, binary.LittleEndian, &val)
+ return float64(val), err
+ case DATA_TYPE_UINT32:
+ var val uint32
+ err := binary.Read(r, binary.LittleEndian, &val)
+ return float64(val), err
+ case DATA_TYPE_UINT64:
+ var val uint64
+ err := binary.Read(r, binary.LittleEndian, &val)
+ return float64(val), err
+ case DATA_TYPE_INT8:
+ var val int8
+ err := binary.Read(r, binary.LittleEndian, &val)
+ return float64(val), err
+ case DATA_TYPE_INT16:
+ var val int16
+ err := binary.Read(r, binary.LittleEndian, &val)
+ return float64(val), err
+ case DATA_TYPE_INT32:
+ var val int32
+ err := binary.Read(r, binary.LittleEndian, &val)
+ return float64(val), err
+ case DATA_TYPE_INT64:
+ var val int64
+ err := binary.Read(r, binary.LittleEndian, &val)
+ return float64(val), err
+ case DATA_TYPE_FLOAT32:
+ var val float32
+ err := binary.Read(r, binary.LittleEndian, &val)
+ return float64(val), err
+ default:
+ return 0.0, fmt.Errorf("Can't decode type %d.", dt)
+ }
+}
diff --git a/lib/field.go b/lib/field.go
new file mode 100644
index 0000000..1c24880
--- /dev/null
+++ b/lib/field.go
@@ -0,0 +1,56 @@
+// Copyright 2017 The Fuchsia Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package lib
+
+import (
+ "io"
+)
+
+type Unit uint
+
+const (
+ UNIT_AMPHERE Unit = 0
+ UNIT_VOLT = 1
+)
+
+type Field struct {
+ Name string
+ Offset int
+ Type DataType
+ Unit Unit
+ Scale float32
+}
+
+func (f *Field) Decode(r io.Reader) (float64, error) {
+ val, err := f.Type.Read(r)
+ if err != nil {
+ return 0.0, err
+ }
+ return val * float64(f.Scale), nil
+}
diff --git a/lib/proto.go b/lib/proto.go
new file mode 100644
index 0000000..6094291
--- /dev/null
+++ b/lib/proto.go
@@ -0,0 +1,50 @@
+// Copyright 2017 The Fuchsia Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package lib
+
+type PacketType uint8
+
+const (
+ PACKET_TYPE_QUERY_REPORT_FORMAT PacketType = 0x00
+ PACKET_TYPE_QUERY_TIME = 0x01
+ PACKET_TYPE_ENABLE_REPORTING = 0x10
+ PACKET_TYPE_DISABLE_REPORTING = 0x11
+ PACKET_TYPE_REPORT_FORMAT = 0x80
+ PACKET_TYPE_REPORT = 0x81
+ PACKET_TYPE_TIMESTAMP = 0x82
+)
+
+type reportFormatPacket struct {
+ PacketType uint8
+ ValueIndex uint8
+ ValueType uint8
+ ValueUnit uint8
+ Scale float32
+ Name [56]byte
+}
diff --git a/lib/zedmon.go b/lib/zedmon.go
new file mode 100644
index 0000000..366dfda
--- /dev/null
+++ b/lib/zedmon.go
@@ -0,0 +1,378 @@
+// Copyright 2017 The Fuchsia Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package lib
+
+import (
+ "bytes"
+ "encoding/binary"
+ "fmt"
+ "log"
+ "math"
+ "time"
+
+ "github.com/google/gousb"
+)
+
+type Report struct {
+ Timestamp uint64
+ Values []float64
+}
+
+type Zedmon struct {
+ ctx *gousb.Context
+ dev *gousb.Device
+ config *gousb.Config
+ intf *gousb.Interface
+
+ inEpNum int
+ outEpNum int
+
+ inEp *gousb.InEndpoint
+ outEp *gousb.OutEndpoint
+
+ readStream *gousb.ReadStream
+ reportingEnabled bool
+
+ fields []*Field
+}
+
+func (z *Zedmon) Close() {
+ if z.reportingEnabled {
+ z.DisableReporting()
+ }
+
+ if z.readStream != nil {
+ z.readStream.Close()
+ }
+
+ if z.intf != nil {
+ z.intf.Close()
+ }
+
+ if z.config != nil {
+ z.config.Close()
+ }
+
+ if z.dev != nil {
+ z.dev.Close()
+ }
+
+ if z.ctx != nil {
+ z.ctx.Close()
+ }
+}
+
+func (z *Zedmon) read() []byte {
+ buf := make([]byte, z.inEp.Desc.MaxPacketSize)
+ len, err := z.readStream.Read(buf)
+ if err != nil {
+ log.Printf("Read stream error: %v", err)
+ return nil
+ }
+ return buf[:len]
+}
+
+// Synchronize with the device.
+//
+// It is possible for out endpoint data toggles to get out of phase on on
+// successive invocations. Repeating a get format report command until we
+// get a response synchronizes them.
+func (z *Zedmon) sync() {
+ z.inEp.Timeout = time.Millisecond * 100
+ for {
+ data := make([]byte, 2)
+ data[0] = 0x00
+ data[1] = 0x00
+ _, err := z.outEp.Write(data)
+ if err != nil {
+ log.Printf("Sync Send Error: %v\n", err)
+ continue
+ }
+ buf := make([]byte, z.inEp.Desc.MaxPacketSize)
+ _, err = z.inEp.Read(buf)
+ if err == nil {
+ break
+ }
+ if usbErr, ok := err.(gousb.TransferStatus); ok && usbErr == gousb.TransferTimedOut {
+ continue
+ }
+ log.Printf("Sync Read Error: %v\n", err)
+ }
+}
+
+func (z *Zedmon) GetTimeOffset() (time.Duration, time.Duration, error) {
+ bestRoundTripDuration := time.Duration(math.MaxInt64)
+ bestOffset := time.Duration(0)
+
+ for i := 0; i < 10; i++ {
+ data := make([]byte, 1)
+ data[0] = 0x01
+
+ start := time.Now()
+ _, err := z.outEp.Write(data)
+ if err != nil {
+ log.Printf("Sync Send Error: %v\n", err)
+ return 0, 0, err
+ }
+ buf := z.read()
+ if buf == nil {
+ return 0, 0, fmt.Errorf("Can't read packet\n")
+ }
+ end := time.Now()
+ reader := bytes.NewReader(buf[1:])
+ var rawTimestamp uint64
+ err = binary.Read(reader, binary.LittleEndian, &rawTimestamp)
+ timestamp := time.Unix(int64(rawTimestamp/1000000), int64((rawTimestamp%1000000)*1000))
+
+ delta := end.Sub(start)
+ median := start.Add(delta / 2)
+ offset := median.Sub(timestamp)
+
+ if delta < bestRoundTripDuration {
+ bestRoundTripDuration = delta
+ bestOffset = offset
+ }
+ }
+
+ return bestOffset, bestRoundTripDuration, nil
+}
+
+func (z *Zedmon) EnableReporting() error {
+ data := make([]byte, 1)
+ data[0] = PACKET_TYPE_ENABLE_REPORTING
+ _, err := z.outEp.Write(data)
+ if err != nil {
+ return err
+ }
+
+ z.reportingEnabled = true
+
+ return nil
+}
+
+func (z *Zedmon) DisableReporting() error {
+ data := make([]byte, 1)
+ data[0] = PACKET_TYPE_DISABLE_REPORTING
+ _, err := z.outEp.Write(data)
+ if err != nil {
+ return err
+ }
+
+ // Give time for the packet to be sent. This could be avoided by adding
+ // ACKs to the protocol.
+ time.Sleep(time.Millisecond * 100)
+
+ z.reportingEnabled = false
+ return nil
+}
+
+// TODO: Add mechanism for pre-allocating reports.
+func (z *Zedmon) ReadReports() ([]*Report, error) {
+ buf := z.read()
+
+ if buf[0] != PACKET_TYPE_REPORT {
+ return nil, fmt.Errorf("Unexpected packet type: %02x", buf[0])
+ }
+
+ var reports []*Report
+
+ reader := bytes.NewReader(buf[1:])
+ for reader.Len() > 0 {
+ var timestamp uint64
+ err := binary.Read(reader, binary.LittleEndian, ×tamp)
+ if err != nil {
+ return nil, err
+ }
+
+ report := &Report{
+ Timestamp: timestamp,
+ Values: make([]float64, 0, len(z.fields)),
+ }
+
+ for _, field := range z.fields {
+ val, err := field.Decode(reader)
+ if err != nil {
+ return nil, err
+ }
+ report.Values = append(report.Values, val)
+ }
+
+ reports = append(reports, report)
+ }
+
+ return reports, nil
+}
+
+// Returns: offset after this field, error
+func (z *Zedmon) getFormatReport(index uint, offset *int) (bool, error) {
+ if index >= 0xff {
+ return false, fmt.Errorf("Index %d out of range.", index)
+ }
+
+ data := make([]byte, 2)
+ data[0] = 0x00
+ data[1] = uint8(index)
+ numBytes, err := z.outEp.Write(data)
+ if err != nil {
+ return false, err
+ }
+ if numBytes != len(data) {
+ return false, fmt.Errorf("Incomplete write %d != %d", numBytes, len(data))
+ }
+
+ response := z.read() //<-z.readChan
+ var packet reportFormatPacket
+ binary.Read(bytes.NewReader(response), binary.LittleEndian, &packet)
+
+ if packet.ValueIndex == 0xff {
+ return true, nil
+ }
+
+ dataType := DataType(packet.ValueType)
+ if dataType.Size() < 0 {
+ return false, fmt.Errorf("Can't handle Value type %d.", dataType)
+ }
+
+ // TODO: validate Unit
+
+ var name string
+ n := bytes.IndexByte(packet.Name[:], 0x00)
+ if n != -1 {
+ name = string(packet.Name[:n])
+ } else {
+ name = string(packet.Name[:])
+ }
+
+ field := &Field{
+ Offset: *offset,
+ Name: name,
+ Type: dataType,
+ Unit: Unit(packet.ValueUnit),
+ Scale: packet.Scale,
+ }
+
+ z.fields = append(z.fields, field)
+ *offset += dataType.Size()
+
+ return false, nil
+}
+
+func findZedmonInterface(dev *gousb.Device) (config int, intf int, setting int, err error) {
+ for cfgNum, cfgDesc := range dev.Desc.Configs {
+ for intfNum, intfDesc := range cfgDesc.Interfaces {
+ for settingNum, settingDesc := range intfDesc.AltSettings {
+ if settingDesc.Class == gousb.ClassVendorSpec &&
+ settingDesc.SubClass == gousb.ClassVendorSpec &&
+ settingDesc.Protocol == 0x0 &&
+ len(settingDesc.Endpoints) == 2 {
+ return cfgNum, intfNum, settingNum, nil
+ }
+ }
+ }
+ }
+ return 0, 0, 0, fmt.Errorf("Can't find zedmon interface.")
+}
+
+func (z *Zedmon) enumerateFields() error {
+ offset := 0
+ for i := uint(0); ; i++ {
+ done, err := z.getFormatReport(i, &offset)
+ if err != nil {
+ return err
+ }
+ if done {
+ return nil
+ }
+ }
+}
+
+func OpenZedmon() (*Zedmon, error) {
+ zedmon := &Zedmon{
+ ctx: gousb.NewContext(),
+ }
+
+ dev, err := zedmon.ctx.OpenDeviceWithVIDPID(0x18d1, 0xaf00)
+ if err != nil {
+ zedmon.Close()
+ return nil, err
+ }
+
+ configNum, intfNum, settingNum, err := findZedmonInterface(dev)
+ if err != nil {
+ zedmon.Close()
+ return nil, err
+ }
+
+ zedmon.config, err = dev.Config(configNum)
+ if err != nil {
+ zedmon.Close()
+ return nil, err
+ }
+
+ zedmon.intf, err = zedmon.config.Interface(intfNum, settingNum)
+ if err != nil {
+ zedmon.Close()
+ return nil, err
+ }
+
+ // TODO: We should verify this will succeed in findZedmonInterface().
+ for _, epDesc := range zedmon.intf.Setting.Endpoints {
+ switch epDesc.Direction {
+ case gousb.EndpointDirectionIn:
+ zedmon.inEpNum = epDesc.Number
+ case gousb.EndpointDirectionOut:
+ zedmon.outEpNum = epDesc.Number
+ }
+ }
+
+ zedmon.inEp, err = zedmon.intf.InEndpoint(zedmon.inEpNum)
+ if err != nil {
+ zedmon.Close()
+ return nil, err
+ }
+
+ zedmon.outEp, err = zedmon.intf.OutEndpoint(zedmon.outEpNum)
+ if err != nil {
+ zedmon.Close()
+ return nil, err
+ }
+
+ zedmon.sync()
+
+ zedmon.inEp.Timeout = time.Second * 1
+ zedmon.readStream, err = zedmon.inEp.NewStream(zedmon.inEp.Desc.MaxPacketSize, 100)
+ if err != nil {
+ zedmon.Close()
+ return nil, err
+ }
+
+ zedmon.enumerateFields()
+
+ return zedmon, nil
+}
diff --git a/stub.go b/stub.go
new file mode 100644
index 0000000..2171b1f
--- /dev/null
+++ b/stub.go
@@ -0,0 +1,39 @@
+// Copyright 2017 The Fuchsia Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package zedmon
+
+import (
+ "fuchsia.googlesource.com/zedmon/lib"
+)
+
+type Zedmon = lib.Zedmon
+
+func OpenZedmon() (*Zedmon, error) {
+ return lib.OpenZedmon()
+}