Skip to content
Snippets Groups Projects
Commit 31cae738 authored by Benjamin Wenger's avatar Benjamin Wenger
Browse files

implementing send

parent ed54a3ff
Branches
Tags
No related merge requests found
package api package api
import ( import (
"github.com/pkg/errors"
jww "github.com/spf13/jwalterweatherman" jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/client/interfaces/message" "gitlab.com/elixxir/client/interfaces/message"
"gitlab.com/elixxir/client/interfaces/params" "gitlab.com/elixxir/client/interfaces/params"
...@@ -47,10 +48,13 @@ func (c *Client) SendCMIX(msg format.Message, param params.CMIX) (id.Round, ...@@ -47,10 +48,13 @@ func (c *Client) SendCMIX(msg format.Message, param params.CMIX) (id.Round,
// for the current cMix network. // for the current cMix network.
// FIXME: this is weird and shouldn't be necessary, but it is. // FIXME: this is weird and shouldn't be necessary, but it is.
func (c *Client) NewCMIXMessage(recipient *id.ID, func (c *Client) NewCMIXMessage(recipient *id.ID,
contents []byte) format.Message { contents []byte) (format.Message, error) {
primeSize := len(c.storage.Cmix().GetGroup().GetPBytes()) primeSize := len(c.storage.Cmix().GetGroup().GetPBytes())
msg := format.NewMessage(primeSize) msg := format.NewMessage(primeSize)
if len(contents) > msg.ContentsSize() {
return format.Message{}, errors.New("Contents to long for cmix")
}
msg.SetContents(contents) msg.SetContents(contents)
msg.SetRecipientID(recipient) msg.SetRecipientID(recipient)
return msg return msg, nil
} }
package bindings
import (
"gitlab.com/elixxir/client/interfaces"
"gitlab.com/elixxir/client/switchboard"
"gitlab.com/elixxir/comms/network/dataStructures"
"gitlab.com/xx_network/primitives/id"
)
// Listener provides a callback to hear a message
// An object implementing this interface can be called back when the client
// gets a message of the type that the regi sterer specified at registration
// time.
type Listener interface {
// Hear is called to receive a message in the UI
Hear(message Message)
// Returns a name, used for debugging
Name() string
}
// RoundEventHandler handles round events happening on the cMix network.
type RoundEventCallback interface {
EventCallback(rid int, state byte, timedOut bool)
}
// Generic Unregister - a generic return used for all callbacks which can be
// unregistered
// Interface which allows the un-registration of a listener
type Unregister struct {
f func()
}
//Call unregisters a callback
func (u Unregister) Unregister() {
u.f()
}
//creates an unregister interface for listeners
func newListenerUnregister(lid switchboard.ListenerID, sw interfaces.Switchboard) Unregister {
f := func() {
sw.Unregister(lid)
}
return Unregister{f: f}
}
//creates an unregister interface for round events
func newRoundUnregister(rid id.Round, ec *dataStructures.EventCallback,
re interfaces.RoundEvents) Unregister {
f := func() {
re.Remove(rid, ec)
}
return Unregister{f: f}
}
...@@ -10,6 +10,8 @@ import ( ...@@ -10,6 +10,8 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"gitlab.com/elixxir/client/api" "gitlab.com/elixxir/client/api"
"gitlab.com/elixxir/client/interfaces/message" "gitlab.com/elixxir/client/interfaces/message"
"gitlab.com/elixxir/comms/mixmessages"
"gitlab.com/elixxir/primitives/states"
"gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id"
"time" "time"
) )
...@@ -127,13 +129,17 @@ func (c *Client) RegisterNetworkHealthCB(nhc NetworkHealthCallback) { ...@@ -127,13 +129,17 @@ func (c *Client) RegisterNetworkHealthCB(nhc NetworkHealthCallback) {
// RegisterListener records and installs a listener for messages // RegisterListener records and installs a listener for messages
// matching specific uid, msgType, and/or username // matching specific uid, msgType, and/or username
// Returns a ListenerUnregister interface which can be
//
// Message Types can be found in client/interfaces/message/type.go
// Make sure to not conflict with ANY default message types
func (c *Client) RegisterListener(uid []byte, msgType int, func (c *Client) RegisterListener(uid []byte, msgType int,
listener Listener) (ListenerID, error) { listener Listener) (Unregister, error) {
name := listener.Name() name := listener.Name()
u, err := id.Unmarshal(uid) u, err := id.Unmarshal(uid)
if err != nil { if err != nil {
return ListenerID{}, err return Unregister{}, err
} }
mt := message.Type(msgType) mt := message.Type(msgType)
...@@ -143,20 +149,53 @@ func (c *Client) RegisterListener(uid []byte, msgType int, ...@@ -143,20 +149,53 @@ func (c *Client) RegisterListener(uid []byte, msgType int,
lid := c.api.GetSwitchboard().RegisterFunc(name, u, mt, f) lid := c.api.GetSwitchboard().RegisterFunc(name, u, mt, f)
return ListenerID{id: lid}, nil return newListenerUnregister(lid, c.api.GetSwitchboard()), nil
}
// Unregister removes the listener with the specified ID so it will no
// longer get called
func (c *Client) UnregisterListener(lid ListenerID) {
c.api.GetSwitchboard().Unregister(lid.id)
} }
// RegisterRoundEventsHandler registers a callback interface for round // RegisterRoundEventsHandler registers a callback interface for round
// events. // events.
func (c *Client) RegisterRoundEventsHandler(hdlr RoundEventHandler) { // The rid is the round the event attaches to
// The timeoutMS is the number of milliseconds until the event fails, and the
// validStates are a list of states (one per byte) on which the event gets
// triggered
// States:
// 0x00 - PENDING (Never seen by client)
// 0x01 - PRECOMPUTING
// 0x02 - STANDBY
// 0x03 - QUEUED
// 0x04 - REALTIME
// 0x05 - COMPLETED
// 0x06 - FAILED
// These states are defined in elixxir/primitives/states/state.go
func (c *Client) RegisterRoundEventsHandler(rid int, cb RoundEventCallback,
timeoutMS int, validStates []byte) Unregister {
rcb := func(ri *mixmessages.RoundInfo, timedOut bool) {
cb.EventCallback(int(ri.ID), byte(ri.State), timedOut)
}
timeout := time.Duration(timeoutMS) * time.Millisecond
vStates := make([]states.Round, len(validStates))
for i, s := range validStates {
vStates[i] = states.Round(s)
}
roundID := id.Round(rid)
ec := c.api.GetRoundEvents().AddRoundEvent(roundID, rcb, timeout, vStates...)
return newRoundUnregister(roundID, ec, c.api.GetRoundEvents())
}
// Returns a user object from which all information about the current user
// can be gleaned
func (c *Client) GetUser() User {
return c.GetUser()
} }
/* /*
// SearchWithHandler is a non-blocking search that also registers // SearchWithHandler is a non-blocking search that also registers
// a callback interface for user disovery events. // a callback interface for user disovery events.
...@@ -204,4 +243,4 @@ func (b *BindingsClient) SendCMIX(payload, recipient []byte) (int, error) { ...@@ -204,4 +243,4 @@ func (b *BindingsClient) SendCMIX(payload, recipient []byte) (int, error) {
func (b *BindingsClient) Search(data, separator string, func (b *BindingsClient) Search(data, separator string,
searchTypes []byte) ContactList { searchTypes []byte) ContactList {
return nil return nil
} }*/
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
package bindings package bindings
import "gitlab.com/xx_network/primitives/id"
// Client is defined inside the api package. At minimum, it implements all of // Client is defined inside the api package. At minimum, it implements all of
// functionality defined here. A Client handles all network connectivity, key // functionality defined here. A Client handles all network connectivity, key
// generation, and storage for a given cryptographic identity on the cmix // generation, and storage for a given cryptographic identity on the cmix
...@@ -173,19 +175,6 @@ type AuthEventHandler interface { ...@@ -173,19 +175,6 @@ type AuthEventHandler interface {
HandleRequest(contact Contact, payload []byte) HandleRequest(contact Contact, payload []byte)
} }
// RoundList contains a list of contacts
type RoundList interface {
// GetLen returns the number of contacts in the list
GetLen() int
// GetRoundID returns the round ID at index i
GetRoundID(i int) int
}
// RoundEventHandler handles round events happening on the cMix network.
type RoundEventHandler interface {
HandleEvent(id int, state byte)
}
// UserDiscoveryHandler handles search results against the user discovery agent. // UserDiscoveryHandler handles search results against the user discovery agent.
type UserDiscoveryHandler interface { type UserDiscoveryHandler interface {
HandleSearchResults(results ContactList) HandleSearchResults(results ContactList)
......
package bindings
import "gitlab.com/elixxir/client/switchboard"
// Listener provides a callback to hear a message
// An object implementing this interface can be called back when the client
// gets a message of the type that the regi sterer specified at registration
// time.
type Listener interface {
// Hear is called to receive a message in the UI
Hear(message Message)
// Returns a name, used for debugging
Name() string
}
// id object returned when a listener is created and is used to delete it from
// the system. Beyond calling unregister it has no uses.
type ListenerID struct {
id switchboard.ListenerID
}
func (lid ListenerID) GetUserID() []byte {
return lid.id.GetUserID().Bytes()
}
func (lid ListenerID) GetMessageType() int {
return int(lid.id.GetMessageType())
}
func (lid ListenerID) GetName() string {
return lid.id.GetName()
}
package bindings
type Params interface {
GetString(key string) (string, error)
SetString(key, value string)
GetInt(key string) (int, error)
SetInt(key string, value int)
GetFloat(key string) (float64, error)
SetFloat(key, value string)
GetParams(key string) (Params, error)
SetParams(key string, p Params)
}
package bindings
import "gitlab.com/xx_network/primitives/id"
type roundList struct {
list []id.Round
}
// RoundList contains a list of contacts
type RoundList interface {
// Len returns the number of contacts in the list
Len() int
// Get returns the round ID at index i
Get(i int) int
}
package bindings
import (
"gitlab.com/elixxir/client/interfaces/params"
"gitlab.com/xx_network/primitives/id"
)
// SendCMIX sends a "raw" CMIX message payload to the provided
// recipient. Note that both SendE2E and SendUnsafe call SendCMIX.
// Returns the round ID of the round the payload was sent or an error
// if it fails.
// This will return an error if:
// - the recipient ID is invalid
// - the contents are too long for the message structure
// - the message cannot be sent
// This will return the round the message was sent on if it is successfully sent
// This can be used to register a round event to learn about message delivery.
// on failure a round id of -1 is returned
func (c *Client) SendCmix(recipient, contents []byte) (int, error) {
u, err := id.Unmarshal(recipient)
if err != nil {
return -1, err
}
msg, err := c.api.NewCMIXMessage(u, contents)
if err != nil {
return -1, err
}
rid, err := c.api.SendCMIX(msg, params.GetDefaultCMIX())
if err != nil {
return -1, err
}
return int(rid), err
}
// SendUnsafe sends an unencrypted payload to the provided recipient
// with the provided msgType. Returns the list of rounds in which parts
// of the message were sent or an error if it fails.
// NOTE: Do not use this function unless you know what you are doing.
// This function always produces an error message in client logging.
//
// Message Types can be found in client/interfaces/message/type.go
// Make sure to not conflict with ANY default message types
func (c *Client) SendUnsafe(recipient, payload []byte,
messageType int) (RoundList, error) {
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment