You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

124 lines
4.0 KiB

// This file is under GNU Affero General Public License 3.0
// see LICENSE.txt
#include "user_interface.hh"
#include <assert.h>
#include <time.h>
namespace pEp {
namespace PythonAdapter {
UserInterface *UserInterface::_ui = nullptr;
UserInterface::UserInterface()
{
if (_ui)
throw runtime_error("only one UserInterface thread allowed");
_ui = this;
}
UserInterface::~UserInterface()
{
_ui = nullptr;
}
UserInterface_callback::UserInterface_callback(PyObject *self) :
UserInterface(), _self(self)
{
adapter.ui_object(self);
PEP_STATUS status = ::register_sync_callbacks(adapter.session(),
(void *) this, _notifyHandshake, retrieve_next_sync_event);
assert(status == PEP_STATUS_OK);
if (status)
_throw_status(status);
}
UserInterface_callback::~UserInterface_callback()
{
::unregister_sync_callbacks(adapter.session());
}
PEP_STATUS UserInterface::_notifyHandshake(
pEp_identity *me, pEp_identity *partner,
sync_handshake_signal signal
)
{
if (!(me && partner))
return PEP_ILLEGAL_VALUE;
auto that = dynamic_cast< UserInterface_callback * >(_ui);
that->notifyHandshake(Identity(me), Identity(partner), signal);
return PEP_STATUS_OK;
}
void UserInterface::deliverHandshakeResult(int result, object identities)
{
identity_list *shared_identities = nullptr;
if (identities != boost::python::api::object()) {
shared_identities = new_identity_list(nullptr);
if (!shared_identities)
throw bad_alloc();
try {
identity_list *si = shared_identities;
for (int i=0; i < boost::python::len(identities); ++i) {
Identity ident = extract< Identity >(identities[i]);
si = identity_list_add(si, ident);
if (!si)
throw bad_alloc();
}
}
catch (exception& ex) {
free_identity_list(shared_identities);
throw ex;
}
}
PEP_STATUS status = ::deliverHandshakeResult(adapter.session(),
(sync_handshake_result) result, shared_identities);
free_identity_list(shared_identities);
_throw_status(status);
}
PEP_rating UserInterface::get_key_rating_for_user(string user_id, string fpr)
{
PEP_rating result;
PEP_STATUS status =
::get_key_rating_for_user(adapter.session(),
user_id.c_str(), fpr.c_str(), &result);
_throw_status(status);
return result;
}
SYNC_EVENT UserInterface::retrieve_next_sync_event(void *management, unsigned threshold)
{
time_t started = time(nullptr);
bool timeout = false;
while (adapter.queue().empty()) {
int i = 0;
++i;
if (i > 10) {
if (time(nullptr) > started + threshold) {
timeout = true;
break;
}
i = 0;
}
nanosleep((const struct timespec[]){{0, 100000000L}}, NULL);
}
if (timeout)
return new_sync_timeout_event();
return adapter.queue().pop_front();
}
void UserInterface_callback::notifyHandshake(
Identity me, Identity partner, sync_handshake_signal signal)
{
call_method< void >(_self, "notifyHandshake", me, partner, signal);
}
}
}