blob: 727152b2465c76613e849af25be436d11b53c40f [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package vango
import (
"fmt"
"time"
"v.io/v23"
"v.io/v23/context"
"v.io/v23/discovery"
"v.io/v23/naming"
"v.io/v23/rpc"
"v.io/v23/security"
libdiscovery "v.io/x/ref/lib/discovery"
)
const (
rpcTimeout = 10 * time.Second
tcpServerName = "tmp/vango/tcp"
btServerName = "tmp/vango/bt"
)
var (
bleServerName = naming.Endpoint{Protocol: "ble"}.Name()
// vangoFuncs is a map containing go functions keys by unique strings
// intended to be run by java/android applications using Vango.run(key).
// Users must add function entries to this map and rebuild lib/android-lib in
// the vanadium java repository.
vangoFuncs = map[string]func(*context.T) error{
"tcp-client": tcpClientFunc,
"tcp-server": tcpServerFunc,
"bt-client": btClientFunc,
"bt-server": btServerFunc,
"ble-client": bleClientFunc,
"ble-server": bleServerFunc,
"all": AllFunc,
}
)
func tcpServerFunc(ctx *context.T) error {
ctx = v23.WithListenSpec(ctx, rpc.ListenSpec{Proxy: "proxy"})
return runServer(ctx, tcpServerName)
}
func tcpClientFunc(ctx *context.T) error {
return runClient(ctx, tcpServerName)
}
func btServerFunc(ctx *context.T) error {
ctx = v23.WithListenSpec(ctx, rpc.ListenSpec{Addrs: rpc.ListenAddrs{{Protocol: "bt", Address: "/0"}}})
return runServer(ctx, btServerName)
}
func btClientFunc(ctx *context.T) error {
return runClient(ctx, btServerName)
}
func bleServerFunc(ctx *context.T) error {
ctx = v23.WithListenSpec(ctx, rpc.ListenSpec{Addrs: rpc.ListenAddrs{{Protocol: "ble", Address: "na"}}})
return runServer(ctx, "")
}
func bleClientFunc(ctx *context.T) error {
return runClient(ctx, bleServerName)
}
// AllFunc runs a server, advertises it, scans for other servers and makes an
// Echo RPC to every advertised remote server.
func AllFunc(ctx *context.T) error {
ls := rpc.ListenSpec{Proxy: "proxy"}
addRegisteredProto(&ls, "tcp", ":0")
addRegisteredProto(&ls, "bt", "/0")
ctx.Infof("ListenSpec: %#v", ls)
ctx, server, err := v23.WithNewServer(
v23.WithListenSpec(ctx, ls),
mountName(ctx, "all"),
&echoServer{},
security.AllowEveryone())
if err != nil {
return err
}
const interfaceName = "v.io/x/jni/impl/google/services/vango.EchoServer"
ad := &discovery.Advertisement{
InterfaceName: interfaceName,
Attributes: discovery.Attributes{
"Hello": "There",
},
}
d, err := v23.NewDiscovery(ctx)
if err != nil {
return err
}
stoppedAd, err := libdiscovery.AdvertiseServer(ctx, d, server, "", ad, nil)
if err != nil {
return err
}
updates, err := d.Scan(ctx, "")
if err != nil {
return err
}
status := server.Status()
ctx.Infof("My AdID: %v", ad.Id)
ctx.Infof("Status: %+v", status)
counter := 0
onDiscovered := func(addr, message string) {
ctx, cancel := context.WithTimeout(ctx, rpcTimeout)
defer cancel()
summary, err := runTimedCall(ctx, addr, message)
if err != nil {
ctx.Infof("%s: ERROR: %v", summary, err)
return
}
ctx.Infof("%s: SUCCESS", summary)
}
for {
select {
case <-ctx.Done():
ctx.Infof("EXITING")
return nil
case <-status.Dirty:
status = server.Status()
ctx.Infof("Status Changed: %+v", status)
case u := <-updates:
if u.IsLost() {
ctx.Infof("LOST: %v", u.Id())
break
}
counter++
ctx.Infof("FOUND(%d): %+v", counter, u.Advertisement())
for _, addr := range u.Addresses() {
go onDiscovered(addr, fmt.Sprintf("CALL #%03d", counter))
}
case <-stoppedAd:
ctx.Infof("Stopped advertising")
return fmt.Errorf("stopped advertising")
}
}
}