first cut.
Change-Id: I71970188e1ee7d3c519bfe46528704d2f506302c
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..81feab8
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,7 @@
+
+include ../shared/mojo.mk
+
+
+go/src/mojom/vanadium/discovery/discovery.mojom.go: mojom/vanadium/discovery.mojom | mojo-env-check
+ $(call MOJOM_GEN,$<,.,go)
+ gofmt -w $@
\ No newline at end of file
diff --git a/go/src/vanadium/discovery/discovery.go b/go/src/vanadium/discovery/discovery.go
new file mode 100644
index 0000000..0446f22
--- /dev/null
+++ b/go/src/vanadium/discovery/discovery.go
@@ -0,0 +1,88 @@
+package discovery
+
+import (
+ mojom "mojom/vanadium/discovery"
+ "v.io/v23/discovery"
+ "sync"
+ "v.io/v23/context"
+ "v.io/v23/security/access"
+ "v.io/v23/verror"
+ "mojo/public/go/bindings"
+)
+
+type discoveryService struct {
+ mu sync.Mutex
+ ctx *context.T
+ s discovery.T
+ nextAdv int32
+ pendingAdvs map[int32]chan struct{}
+ nextScan int32;
+ pendingScans map[int32]chan struct{}
+
+}
+
+
+func converToErrorStruct(err error) *mojom.Error {
+ outErr := &mojom.Error{
+ Id: "v.io/verror/Unknown",
+ Msg: err.Error(),
+ }
+ if e, ok := err.(verror.E); ok {
+ outErr.Id = string(e.ID)
+ outErr.Action = int32(e.Action)
+ }
+ return outErr
+}
+
+func (d *discoveryService) Advertisement(s mojom.Service, patterns []string) (int32, *mojom.Error) {
+ vService := discovery.Service{
+ InstanceUuid: s.InstanceUuid,
+ InterfaceName: s.InterfaceName,
+ Attrs: discovery.Attributes(s.Attrs),
+ Addrs: s.Addrs,
+ }
+
+ ctx, c := context.WithCancel(d.ctx)
+
+ err := d.s.Advertise(ctx, vService, access.Permissions{})
+ if err != nil {
+ return 0, converToErrorStruct(err)
+ }
+ ch := make(chan struct{})
+ d.mu.Lock()
+ id := d.nextAdv
+ d.pendingAdvs[id] = ch
+ d.nextAdv++
+ d.mu.Unlock()
+ go func() {
+ <-ch
+ c()
+ }()
+ return id, nil
+}
+
+func (d *discoveryService) StopAdvertising(handle int32) {
+ d.mu.Lock()
+ ch := d.pendingAdvs[handle]
+ d.mu.Unlock()
+ if ch != nil {
+ close(ch)
+ }
+}
+
+func (d *discoveryService) Scan(query string, scanHandler mojom.ScanHandler_Pointer) (int32, *mojom.Error) {
+ ctx, c := context.WithCancel(d.ctx)
+ proxy := mojom.NewScanHandlerProxy(scanHandler, bindings.GetAsyncWaiter())
+ scanCh, err := d.s.Scan(ctx, query)
+ go func() {
+ for v := range scanCh {
+ switch v.Interface().(type) {
+ case discovery.UpdateFound
+ }
+ if v.Index() == 0 {
+ v.
+ proxy.Found()
+ }
+ }
+ }()
+}
diff --git a/mojom/vanadium/discovery.mojom b/mojom/vanadium/discovery.mojom
new file mode 100644
index 0000000..996c3a6
--- /dev/null
+++ b/mojom/vanadium/discovery.mojom
@@ -0,0 +1,39 @@
+module discovery;
+
+// Copied from v.io/v23/discovery/types.vdl
+struct Service {
+ // The 128 bit (16 byte) universal unique identifier of a service instance.
+ // If this is not specified, a random UUID will be used.
+ array<uint8> InstanceUuid;
+ // The interface that the service implements.
+ // E.g., 'v.io/v23/services/vtrace.Store'.
+ string InterfaceName;
+ // The service attributes.
+ // E.g., {'resolution': '1024x768'}.
+ map<string, string> Attrs;
+ // The addresses that the service is served on.
+ // E.g., '/host:port/a/b/c'.
+ array<string> Addrs;
+};
+
+struct Error {
+ string id;
+ int32 action;
+ string msg;
+};
+
+interface Discoverer {
+ Advertise(Service s, array<string> pattern) => (int32 Handle, Error? Err);
+
+ StopAdvertising(int32 h);
+
+ Scan(string query, ScanHandler scanHandler) => (int32 Handle, Error? Err);
+
+ StopScan(int32 h);
+};
+
+interface ScanHandler {
+ Found(Service s);
+
+ Lost(Service s);
+};
\ No newline at end of file