Skip to content

Commit

Permalink
Merge pull request #9 from topjor/spec-update
Browse files Browse the repository at this point in the history
Update everything to conform the 0.3.0 DBus spec
  • Loading branch information
karmanyaahm authored Jan 11, 2024
2 parents 5b0d99a + 7ab23a6 commit bc0df18
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 45 deletions.
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

0 comments on commit bc0df18

Please sign in to comment.