full gomobile and ffi support + new GetMessages #3
|
@ -0,0 +1,5 @@
|
|||
.idea
|
||||
cwtch-sources.jar
|
||||
cwtch.aar
|
||||
libCwtch.h
|
||||
libCwtch.so
|
12
README.md
12
README.md
|
@ -1,6 +1,14 @@
|
|||
# Build Instructions...
|
||||
go build -buildmode c-shared -o libCwtch.so
|
||||
make linux
|
||||
make android
|
||||
|
||||
# Using
|
||||
|
||||
LD_LIBRARY_PATH set to point to libCwtch.so
|
||||
## Linux Desktop:
|
||||
|
||||
- `LD_LIBRARY_PATH` set to point to `libCwtch.so`
|
||||
- or drop a symlink into `/usr/lib`
|
||||
|
||||
## Android
|
||||
|
||||
- copy `cwtch.aar` into `flutter_app/android/cwtch`
|
||||
|
|
183
lib.go
183
lib.go
|
@ -21,19 +21,21 @@ import (
|
|||
)
|
||||
|
||||
var application app.Application
|
||||
var appBusQueue event.Queue
|
||||
var acnQueue event.Queue
|
||||
var contactEventsQueue event.Queue
|
||||
|
||||
//export HelloWorld
|
||||
func HelloWorld(a C.int, b C.int) C.int {
|
||||
return a+b
|
||||
//export c_StartCwtch
|
||||
func c_StartCwtch(dir_c *C.char, len C.int, tor_c *C.char, torLen C.int) {
|
||||
dir := C.GoStringN(dir_c, len)
|
||||
tor := C.GoStringN(tor_c, torLen)
|
||||
StartCwtch(dir, tor)
|
||||
}
|
||||
|
||||
//export StartCwtch
|
||||
func StartCwtch(dir_c *C.char, len C.int) {
|
||||
dir := C.GoStringN(dir_c, len)
|
||||
func StartCwtch(appDir string, torPath string) {
|
||||
log.SetLevel(log.LevelDebug)
|
||||
log.Infof("Loading Cwtch Directory %v", dir)
|
||||
|
||||
log.Infof("Loading Cwtch Directory %v and tor path: %v", appDir, torPath)
|
||||
|
||||
mrand.Seed(int64(time.Now().Nanosecond()))
|
||||
port := mrand.Intn(1000) + 9600
|
||||
|
@ -46,20 +48,28 @@ func StartCwtch(dir_c *C.char, len C.int) {
|
|||
panic(err)
|
||||
}
|
||||
|
||||
log.Infof("making directory %v", dir)
|
||||
os.MkdirAll(path.Join(dir, "/.tor","tor"),0700)
|
||||
tor.NewTorrc().WithSocksPort(port).WithOnionTrafficOnly().WithControlPort(controlPort).WithHashedPassword(base64.StdEncoding.EncodeToString(key)).Build(filepath.Join(dir, ".tor", "tor", "torrc"))
|
||||
acn, err := tor.NewTorACNWithAuth(path.Join(dir, "/.tor"), "", controlPort, tor.HashedPasswordAuthenticator{base64.StdEncoding.EncodeToString(key)})
|
||||
log.Infof("making directory %v", appDir)
|
||||
os.MkdirAll(path.Join(appDir, "/.tor", "tor"), 0700)
|
||||
tor.NewTorrc().WithSocksPort(port).WithOnionTrafficOnly().WithControlPort(controlPort).WithHashedPassword(base64.StdEncoding.EncodeToString(key)).Build(filepath.Join(appDir, ".tor", "tor", "torrc"))
|
||||
acn, err := tor.NewTorACNWithAuth(path.Join(appDir, "/.tor"), torPath, controlPort, tor.HashedPasswordAuthenticator{base64.StdEncoding.EncodeToString(key)})
|
||||
if err != nil {
|
||||
log.Errorf("\nError connecting to Tor: %v\n", err)
|
||||
}
|
||||
//acn.WaitTillBootstrapped()
|
||||
|
||||
|
||||
newApp := app.NewApp(acn, dir)
|
||||
id := mrand.Int31()
|
||||
newApp := app.NewApp(acn, appDir)
|
||||
acnQueue = event.NewQueue()
|
||||
newApp.GetPrimaryBus().Subscribe(event.ACNStatus, acnQueue)
|
||||
|
||||
appBusQueue = event.NewQueue()
|
||||
newApp.GetPrimaryBus().Subscribe(event.NewPeer, appBusQueue)
|
||||
newApp.GetPrimaryBus().Subscribe(event.PeerError, appBusQueue)
|
||||
newApp.GetPrimaryBus().Subscribe(event.AppError, appBusQueue)
|
||||
newApp.GetPrimaryBus().Subscribe(event.ACNStatus, appBusQueue)
|
||||
newApp.GetPrimaryBus().Subscribe(event.ReloadDone, appBusQueue)
|
||||
newApp.GetPrimaryBus().Subscribe(event.ACNVersion, appBusQueue)
|
||||
|
||||
// Lol this wasn't an intended use
|
||||
peer.DefaultEventsToHandle = []event.Type{
|
||||
event.EncryptedGroupMessage,
|
||||
event.NewMessageFromPeer,
|
||||
|
@ -73,41 +83,81 @@ func StartCwtch(dir_c *C.char, len C.int) {
|
|||
newApp.LoadProfiles("be gay do crime")
|
||||
newApp.LaunchPeers()
|
||||
application = newApp
|
||||
log.Infof("Providing Handle %v", id)
|
||||
log.Infof("libcwtch-go application SET\n")
|
||||
}
|
||||
|
||||
//export ACNEvents
|
||||
func ACNEvents() *C.char {
|
||||
//export c_ACNEvents
|
||||
func c_ACNEvents() *C.char {
|
||||
return C.CString(ACNEvents())
|
||||
}
|
||||
|
||||
func ACNEvents() string {
|
||||
select {
|
||||
case myevent := <- acnQueue.OutChan():
|
||||
return C.CString(fmt.Sprintf("%v", myevent))
|
||||
return fmt.Sprintf("%v", myevent)
|
||||
default:
|
||||
return C.CString("")
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
//export NextEvent
|
||||
func NextEvent() {
|
||||
|
||||
//export c_AppBusEvent
|
||||
func c_AppBusEvent() *C.char {
|
||||
return C.CString(GetAppBusEvent())
|
||||
}
|
||||
|
||||
//export GetProfiles
|
||||
func GetProfiles() *C.char {
|
||||
profiles := application.ListPeers()
|
||||
|
||||
// GetAppBusEvent blocks until an event
|
||||
func GetAppBusEvent() string {
|
||||
select {
|
||||
case myevent := <- acnQueue.OutChan():
|
||||
return fmt.Sprintf("%v", myevent)
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
event := appBusQueue.Next()
|
||||
return fmt.Sprintf("%v", event)
|
||||
}
|
||||
|
||||
type Profile struct {
|
||||
Name string `json:"name"`
|
||||
Onion string `json:"onion"`
|
||||
ImagePath string `json:"imagePath"`
|
||||
}
|
||||
|
||||
//export c_GetProfiles
|
||||
func c_GetProfiles() *C.char {
|
||||
return C.CString(GetProfiles())
|
||||
}
|
||||
|
||||
func GetProfiles() string {
|
||||
peerList := application.ListPeers()
|
||||
profiles := make([]Profile, len(peerList))
|
||||
i := 0
|
||||
for onion, name := range peerList {
|
||||
profiles[i] = Profile{
|
||||
Name: name,
|
||||
Onion: onion,
|
||||
ImagePath: "",
|
||||
}
|
||||
i += 1
|
||||
}
|
||||
jsonBytes,_ := json.Marshal(profiles)
|
||||
return C.CString(string(jsonBytes))
|
||||
return string(jsonBytes)
|
||||
}
|
||||
|
||||
|
||||
type Contact struct {
|
||||
Name string `json:"name"`
|
||||
Onion string `json:"onion"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
//export GetContacts
|
||||
func GetContacts(onion_ptr *C.char, onion_len C.int) *C.char {
|
||||
//export c_GetContacts
|
||||
func c_GetContacts(onion_ptr *C.char, onion_len C.int) *C.char {
|
||||
return C.CString(GetContacts(C.GoStringN(onion_ptr, onion_len)))
|
||||
}
|
||||
|
||||
onion := C.GoStringN(onion_ptr, onion_len)
|
||||
func GetContacts(onion string)string {
|
||||
log.Infof("Get Contacts for %v", onion)
|
||||
mypeer := application.GetPeer(onion)
|
||||
|
||||
|
@ -122,47 +172,92 @@ func GetContacts(onion_ptr *C.char, onion_len C.int) *C.char {
|
|||
}
|
||||
|
||||
bytes,_ := json.Marshal(contacts)
|
||||
return C.CString(string(bytes))
|
||||
return string(bytes)
|
||||
}
|
||||
|
||||
//export c_CreateProfile
|
||||
func c_CreateProfile(nick_ptr *C.char, nick_len C.int, pass_ptr *C.char, pass_len C.int) {
|
||||
CreateProfile(C.GoStringN(nick_ptr, nick_len), C.GoStringN(pass_ptr, pass_len))
|
||||
}
|
||||
|
||||
func CreateProfile(nick, pass string) {
|
||||
application.CreatePeer(nick, pass)
|
||||
}
|
||||
|
||||
//export SelectProfile
|
||||
func SelectProfile(onion_ptr *C.char, onion_len C.int) *C.char {
|
||||
onion := C.GoStringN(onion_ptr, onion_len)
|
||||
//export c_SelectProfile
|
||||
func c_SelectProfile(onion_ptr *C.char, onion_len C.int) *C.char {
|
||||
return C.CString(SelectProfile(C.GoStringN(onion_ptr, onion_len)))
|
||||
}
|
||||
|
||||
func SelectProfile(onion string) string {
|
||||
log.Infof("Select Profile: %v", onion)
|
||||
contactEventsQueue = event.NewQueue()
|
||||
application.GetEventBus(onion).Subscribe(event.PeerStateChange, contactEventsQueue)
|
||||
return C.CString("")
|
||||
return ""
|
||||
}
|
||||
|
||||
//export ContactEvents
|
||||
func ContactEvents() *C.char {
|
||||
//export c_LoadProfiles
|
||||
func c_LoadProfiles(passwordPtr *C.char, passwordLen C.int) {
|
||||
LoadProfiles(C.GoStringN(passwordPtr, passwordLen))
|
||||
}
|
||||
|
||||
func LoadProfiles(pass string) {
|
||||
application.LoadProfiles(pass)
|
||||
}
|
||||
|
||||
//export c_ContactEvents
|
||||
func c_ContactEvents() *C.char {
|
||||
return C.CString(ContactEvents())
|
||||
}
|
||||
|
||||
func ContactEvents() string {
|
||||
select {
|
||||
case myevent := <- contactEventsQueue.OutChan():
|
||||
return C.CString(fmt.Sprintf("%v", myevent))
|
||||
return fmt.Sprintf("%v", myevent)
|
||||
default:
|
||||
return C.CString("")
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
//export NumMessages
|
||||
func NumMessages(profile_ptr *C.char, profile_len C.int, handle_ptr *C.char, handle_len C.int) (n C.int) {
|
||||
//export c_NumMessages
|
||||
func c_NumMessages(profile_ptr *C.char, profile_len C.int, handle_ptr *C.char, handle_len C.int) (n C.int) {
|
||||
profile := C.GoStringN(profile_ptr, profile_len)
|
||||
handle := C.GoStringN(handle_ptr, handle_len)
|
||||
n = C.int(len(application.GetPeer(profile).GetContact(handle).Timeline.Messages))
|
||||
return C.int(NumMessages(profile, handle))
|
||||
}
|
||||
|
||||
func NumMessages(profile, handle string) (n int) {
|
||||
n = len(application.GetPeer(profile).GetContact(handle).Timeline.Messages)
|
||||
log.Infof("NumMessagse(%s, %s) = %d", profile, handle, n)
|
||||
return
|
||||
}
|
||||
|
||||
//export GetMessage
|
||||
func GetMessage(profile_ptr *C.char, profile_len C.int, handle_ptr *C.char, handle_len C.int, message_index C.int) *C.char {
|
||||
//export c_GetMessage
|
||||
func c_GetMessage(profile_ptr *C.char, profile_len C.int, handle_ptr *C.char, handle_len C.int, message_index C.int) *C.char {
|
||||
profile := C.GoStringN(profile_ptr, profile_len)
|
||||
handle := C.GoStringN(handle_ptr, handle_len)
|
||||
return C.CString(GetMessage(profile, handle, int(message_index)))
|
||||
}
|
||||
|
||||
// Deprecate - 2021.01.14 - not used
|
||||
func GetMessage(profile, handle string, message_index int) string {
|
||||
message := application.GetPeer(profile).GetContact(handle).Timeline.Messages[message_index]
|
||||
bytes,_ := json.Marshal(message)
|
||||
log.Infof("GetMessage(%s, %s, %d) = %s", profile, handle, message_index, string(bytes))
|
||||
return C.CString(string(bytes))
|
||||
return string(bytes)
|
||||
}
|
||||
|
||||
//export c_GetMessages
|
||||
func c_GetMessages(profile_ptr *C.char, profile_len C.int, handle_ptr *C.char, handle_len C.int, start C.int, end C.int) *C.char {
|
||||
profile := C.GoStringN(profile_ptr, profile_len)
|
||||
handle := C.GoStringN(handle_ptr, handle_len)
|
||||
return C.CString(GetMessages(profile, handle, int(start), int(end)))
|
||||
}
|
||||
|
||||
func GetMessages(profile, handle string, start, end int) string {
|
||||
messages := application.GetPeer(profile).GetContact(handle).Timeline.Messages[start:end]
|
||||
bytes,_ := json.Marshal(messages)
|
||||
return string(bytes)
|
||||
}
|
||||
|
||||
// Leave as is, needed by ffi
|
||||
|
|
Loading…
Reference in New Issue