Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update everything to conform the 0.3.0 DBus spec #9

Merged
merged 13 commits into from
Jan 11, 2024
Merged
9 changes: 6 additions & 3 deletions _examples/basic_c_example/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
#include <unistd.h>
#include <string.h>

static void newMessage(char *instance, char *msg, char *id)
static void newMessage(char *instance, uint8_t *msg, size_t len, char *id)
{
//this message can be deserialized here from something like json or whatever encoding you like

// also note that the arguments to each of these input strings is freed after the function call
// so if you need the data you should copy it somewhere
printf("new message: %s\n", msg);

puts("new message: ");
fwrite(msg, len, 1, stdout);
puts("\n");
}

static void newEndpoint(char *instance, char *endpoint)
Expand Down Expand Up @@ -94,7 +97,7 @@ void pickDistributors()
int main(int argc, char **argv)
{

bool ok = UPInitializeAndCheck("cc.malhotra.karmanyaah.testapp.cgo", *newMessage, *newEndpoint, *unregistered);
bool ok = UPInitializeAndCheck("cc.malhotra.karmanyaah.testapp.cgo", "C example app", *newMessage, *newEndpoint, *unregistered);
if (ok) printf("successfully initialized notifications\n");

if (strnlen(UPGetDistributor(), 1) == 0)
Expand Down
6 changes: 3 additions & 3 deletions _examples/basic_example/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ var Endpoint string

type NotificationHandler struct{}

func (n NotificationHandler) Message(instance, message, id string) {
func (n NotificationHandler) Message(instance string, message []byte, id string) {
fmt.Println("new message received")
// this message can be in whatever format you like, in this case the title and message body are two strings seperated by a '-'
parts := strings.Split(message, "-")
parts := strings.Split(string(message), "-")

title := "No Title Provided"
if len(parts) > 1 {
Expand All @@ -42,7 +42,7 @@ func (n NotificationHandler) Unregistered(instance string) {

func main() {
connector := NotificationHandler{}
up.InitializeAndCheck("cc.malhotra.karmanyaah.testapp.golibrary", connector)
up.InitializeAndCheck("cc.malhotra.karmanyaah.testapp.golibrary", "Golang Example App", connector)

if len(up.GetDistributor()) == 0 { // not picked distributor yet
pickDist()
Expand Down
67 changes: 46 additions & 21 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
var ErrInstanceNotUnregistered = errors.New("Instance isn't unregistered yet")

var client *dbus.Client
var friendlyAppName string

// maybe mutex the globals?
var dataStore *store.Storage
Expand All @@ -24,7 +25,7 @@ type connector struct {
t chan time.Time
}

func (ch connector) Message(token, msg, id string) {
func (ch connector) Message(token string, msg []byte, id string) {
if ch.t != nil {
ch.t <- time.Now()
}
Expand Down Expand Up @@ -52,15 +53,15 @@ func (ch connector) Unregistered(token string) {
ch.c.Unregistered(instance)
}

// Initializes the bus and object
func Initialize(name string, handler dbus.ConnectorHandler) error {
if len(name) == 0 {
// Initialize the bus and object
func Initialize(fullName, friendlyName string, handler dbus.ConnectorHandler) error {
if len(fullName) == 0 {
return errors.New("invalid name")
}
if client != nil {
client.Close()
}
client = dbus.NewClient(name)
client = dbus.NewClient(fullName)
err := client.InitializeDefaultConnection()
if err != nil {
return errors.New("DBus Error")
Expand All @@ -77,24 +78,26 @@ func Initialize(name string, handler dbus.ConnectorHandler) error {
if err != nil {
return errors.New("DBus Error")
}
dataStore = store.NewStorage(name)
dataStore = store.NewStorage(fullName)
if dataStore == nil {
return errors.New("Storage Err")
}

friendlyAppName = friendlyName
return nil
}

// InitializeAndCheck is a convienience method that handles initialization and checking whether app started in the background.
// The background check checks whether the argument UNIFIEDPUSH_DBUS_BACKGROUND_ACTIVATION is input.
// Listens for 3 seconds after the last message and then exits.
// if running in the background this panics on error
func InitializeAndCheck(name string, handler dbus.ConnectorHandler) error {
func InitializeAndCheck(fullName, friendlyName string, handler dbus.ConnectorHandler) error {
if !containsString(os.Args, definitions.ConnectorBackgroundArgument) {
return Initialize(name, handler)
return Initialize(fullName, friendlyName, handler)
}
lastCallTime := make(chan time.Time)

err := Initialize(name, connector{c: handler, t: lastCallTime})
err := Initialize(fullName, friendlyName, connector{c: handler, t: lastCallTime})
if err != nil {
panic(err)
// panic bc in bg listener
Expand All @@ -118,22 +121,30 @@ func InitializeAndCheck(name string, handler dbus.ConnectorHandler) error {

// Actual UP methods

// TryRegister registers a new instance.
// Register registers a new instance.
// value of instance can be empty string for the default instance
// registration endpoint is returned through the callback if method is successful
func Register(instance string) (registerStatus definitions.RegisterStatus, registrationFailReason string, err error) {
return RegisterWithDescription(instance, "")
}

// RegisterWithDescription registers a new instance with a specific description.
// value of instance can be empty string for the default instance
// registration endpoint is returned through the callback if method is successful
func RegisterWithDescription(instance, description string) (registerStatus definitions.RegisterStatus, registrationFailReason string, err error) {
if len(GetDistributor()) == 0 {
err = errors.New("No distributor selected")
return
}

if len(getToken(instance)) == 0 {
err = saveNewToken(instance)
in, ok := getToken(instance)
if !ok {
in, err = generateNewToken(instance, description)
if err != nil {
return
}
}
status, reason := client.PickDistributor(GetDistributor()).Register(dataStore.AppName, getToken(instance))
status, reason := client.PickDistributor(GetDistributor()).Register(dataStore.AppName, in.Token, in.Description)
if status == definitions.RegisterStatusFailed || status == definitions.RegisterStatusRefused {
err = removeToken(instance)
}
Expand All @@ -143,7 +154,11 @@ func Register(instance string) (registerStatus definitions.RegisterStatus, regis
// TryUnregister attempts unregister, results are returned through callback
// any error returned is before unregister requested from dbus
func TryUnregister(instance string) error {
return client.PickDistributor(GetDistributor()).Unregister(getToken(instance))
in, ok := getToken(instance)
if !ok {
return errors.New("Instance not found")
}
return client.PickDistributor(GetDistributor()).Unregister(in.Token)
}

// Distributor things
Expand Down Expand Up @@ -191,21 +206,31 @@ func RemoveDistributor() error {
// Token things

// getToken returns token for instance or empty string if instance doesn't exist
func getToken(instance string) string {
func getToken(instance string) (store.Instance, bool) {
a, ok := dataStore.Instances[instance]
if !ok {
return ""
return store.Instance{}, false
}
return a.Token
return a, true
}

func saveNewToken(instance string) error {
func generateNewToken(instance, description string) (store.Instance, error) {
token, err := uuid.NewRandom()
if err != nil {
return err
return store.Instance{}, err
}
dataStore.Instances[instance] = store.Instance{Token: token.String()}
return dataStore.Commit()

// generate description if none is given
if len(description) == 0 {
description = friendlyAppName + " - " + instance
// just use the friendly name if there is only 1 instance
if len(instance) == 0 {
description = friendlyAppName
}
}

dataStore.Instances[instance] = store.Instance{Token: token.String(), Description: description}
return dataStore.Instances[instance], dataStore.Commit()
}

func removeToken(instance string) error {
Expand Down
28 changes: 18 additions & 10 deletions api_c/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ package main
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>

typedef void messageCallback(char* instance, char* message, char* id);
static void MessageCallback(messageCallback* f, char *a, char *b, char* c) {
(*f)(a,b,c);
typedef void messageCallback(char* instance, uint8_t* message, size_t msglen, char* id);
static void MessageCallback(messageCallback* f, char *a, uint8_t* b, size_t len, char* c) {
(*f)(a,b,len,c);
free(a);
free(b);
free(c);
Expand Down Expand Up @@ -49,8 +50,8 @@ type Connector struct {
unregistered *C.unregisteredCallback
}

func (c Connector) Message(a, b, d string) {
go C.MessageCallback(c.message, C.CString(a), C.CString(b), C.CString(d))
func (c Connector) Message(a string, b []byte, d string) {
go C.MessageCallback(c.message, C.CString(a), (*C.uint8_t)(C.CBytes(b)), C.size_t(len(b)), C.CString(d))
}

func (c Connector) NewEndpoint(a, b string) {
Expand All @@ -66,7 +67,8 @@ func (c Connector) Unregistered(a string) {
*/
//export UPInitializeAndCheck
func UPInitializeAndCheck(
name *C.char,
fullName *C.char,
friendlyName *C.char,
msg *C.messageCallback,
endpoint *C.endpointCallback,
unregistered *C.unregisteredCallback,
Expand All @@ -76,7 +78,7 @@ func UPInitializeAndCheck(
newEndpoint: endpoint,
unregistered: unregistered,
}
err := api.InitializeAndCheck(C.GoString(name), connector)
err := api.InitializeAndCheck(C.GoString(fullName), C.GoString(friendlyName), connector)
return err == nil
}

Expand All @@ -85,7 +87,8 @@ func UPInitializeAndCheck(
*/
//export UPInitialize
func UPInitialize(
name *C.char,
fullName *C.char,
friendlyName *C.char,
msg *C.messageCallback,
endpoint *C.endpointCallback,
unregistered *C.unregisteredCallback,
Expand All @@ -95,7 +98,7 @@ func UPInitialize(
newEndpoint: endpoint,
unregistered: unregistered,
}
err := api.Initialize(C.GoString(name), connector)
err := api.Initialize(C.GoString(fullName), C.GoString(friendlyName), connector)
return err == nil
}

Expand Down Expand Up @@ -154,7 +157,12 @@ func UPGetDistributor() *C.char {

//export UPRegister
func UPRegister(instance *C.char) (status C.UP_REGISTER_STATUS, reason *C.char) {
statusret, reasonret, errret := api.Register(C.GoString(instance))
return UPRegisterWithDescription(instance, C.CString(""))
}

//export UPRegisterWithDescription
func UPRegisterWithDescription(instance *C.char, description *C.char) (status C.UP_REGISTER_STATUS, reason *C.char) {
statusret, reasonret, errret := api.RegisterWithDescription(C.GoString(instance), C.GoString(description))
status = (C.UP_REGISTER_STATUS)(statusret)
reason = C.CString(reasonret)
if errret != nil {
Expand Down
4 changes: 2 additions & 2 deletions dbus/distributor.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ type Distributor struct {
object dbus.BusObject
}

func (d *Distributor) Register(name, token string) (definitions.RegisterStatus, string) {
func (d *Distributor) Register(name, token, description string) (definitions.RegisterStatus, string) {
var status, reason string
err := d.object.Call(definitions.DistributorInterface+".Register", dbus.Flags(0), name, token).Store(&status, &reason)
err := d.object.Call(definitions.DistributorInterface+".Register", dbus.Flags(0), name, token, description).Store(&status, &reason)
if err != nil {
return definitions.RegisterStatusFailedRequest, ""
}
Expand Down
4 changes: 2 additions & 2 deletions dbus/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func NewConnector(handler ConnectorHandler) Connector {
}

type ConnectorHandler interface {
Message(token, message, msgID string)
Message(token string, message []byte, msgID string)
NewEndpoint(token, endpoint string)
Unregistered(token string)
}
Expand All @@ -90,7 +90,7 @@ type Connector struct {
h ConnectorHandler
}

func (c Connector) Message(token, message, msgID string) *dbus.Error {
func (c Connector) Message(token string, message []byte, msgID string) *dbus.Error {
c.h.Message(token, message, msgID)
return nil
}
Expand Down
6 changes: 3 additions & 3 deletions definitions/dbus.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const (
)

var RegisterStatusMap = map[string]RegisterStatus{
"NEW_ENDPOINT": RegisterStatusNewEndpoint,
"REGISTRATION_REFUSED": RegisterStatusRefused,
"REGISTRATION_FAILED": RegisterStatusFailed,
"REGISTRATION_SUCCEEDED": RegisterStatusNewEndpoint,
"REGISTRATION_REFUSED": RegisterStatusRefused,
"REGISTRATION_FAILED": RegisterStatusFailed,
}
3 changes: 2 additions & 1 deletion store/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import (
)

type Instance struct {
Token string
Token string
Description string
}

func NewStorage(appName string) *Storage {
Expand Down
Loading