blob: c3152e9d06bd555208ff6cb8214c8bb2f97e8fee [file] [log] [blame]
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() {
}