| package main |
| |
| import ( |
| "v.io/v23" |
| idiscovery "v.io/x/ref/lib/discovery" |
| "v.io/x/ref/lib/discovery/plugins/ble" |
| "v.io/x/ref/lib/discovery/plugins/mdns" |
| |
| _ "v.io/x/ref/runtime/factories/generic" |
| |
| mojom "mojom/vanadium/discovery" |
| "vanadium/discovery/internal" |
| |
| "mojo/public/go/application" |
| "mojo/public/go/bindings" |
| "mojo/public/go/system" |
| "v.io/v23/context" |
| ) |
| |
| //#include "mojo/public/c/system/types.h" |
| import "C" |
| |
| type discoveryDelegate struct { |
| ctx *context.T |
| stubs []*bindings.Stub |
| impl *internal.DiscoveryService |
| shutdown v23.Shutdown |
| } |
| |
| func (d *discoveryDelegate) Initialize(c application.Context) { |
| // TODO(bjornick): Caling init multiple times in the same process |
| // will be bad. For now, this is ok because this is the only |
| // vanadium service that will be used in the demos and each go library |
| // will be in its own process. |
| ctx, shutdown := v23.Init() |
| host := c.Args()[1] |
| ctx.Info("Starting discovery with name", host) |
| mplugin, err := mdns.New(host) |
| pluginList := []idiscovery.Plugin{} |
| if err != nil { |
| ctx.Error("Failed to start MDNS plugin", err) |
| } else { |
| pluginList = append(pluginList, mplugin) |
| } |
| |
| bplugin, err := ble.NewPlugin(host) |
| if err != nil { |
| ctx.Error("Failed to start BLE plugin", err) |
| } else { |
| pluginList = append(pluginList, bplugin) |
| } |
| |
| if len(pluginList) == 0 { |
| c.Close() |
| return |
| } |
| d.impl = internal.NewDiscoveryService(ctx, idiscovery.New(pluginList)) |
| d.shutdown = shutdown |
| } |
| |
| func (d *discoveryDelegate) addAndServeStub(stub *bindings.Stub) { |
| d.stubs = append(d.stubs, stub) |
| go func() { |
| for { |
| if err := stub.ServeRequest(); err != nil { |
| connectionErr, ok := err.(*bindings.ConnectionError) |
| if !ok || !connectionErr.Closed() { |
| d.ctx.Error(err) |
| } |
| break |
| } |
| } |
| }() |
| } |
| |
| type advertiseFactory struct { |
| d *discoveryDelegate |
| } |
| |
| func (a *advertiseFactory) Create(request mojom.Advertiser_Request) { |
| stub := mojom.NewAdvertiserStub(request, a.d.impl, bindings.GetAsyncWaiter()) |
| a.d.addAndServeStub(stub) |
| } |
| |
| type scannerFactory struct { |
| d *discoveryDelegate |
| } |
| |
| func (s *scannerFactory) Create(request mojom.Scanner_Request) { |
| stub := mojom.NewScannerStub(request, s.d.impl, bindings.GetAsyncWaiter()) |
| s.d.addAndServeStub(stub) |
| } |
| |
| func (d *discoveryDelegate) AcceptConnection(connection *application.Connection) { |
| advFactory := &advertiseFactory{d: d} |
| scanFactory := &scannerFactory{d: d} |
| connection.ProvideServices(&mojom.Advertiser_ServiceFactory{advFactory}, &mojom.Scanner_ServiceFactory{scanFactory}) |
| } |
| |
| func (d *discoveryDelegate) Quit() { |
| d.impl.Stop() |
| d.shutdown() |
| for _, stub := range d.stubs { |
| stub.Close() |
| } |
| } |
| |
| //export MojoMain |
| func MojoMain(handle C.MojoHandle) C.MojoResult { |
| application.Run(&discoveryDelegate{}, system.MojoHandle(handle)) |
| return C.MOJO_RESULT_OK |
| } |
| |
| func main() { |
| } |