1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

refactor(core): parse and log all toxcore errors

Use a macro to embed line number of call sight, instead of just using line
number of log site, since logger functions can be called from different
toxcore API usages.
This commit is contained in:
Anthony Bilinski 2019-09-11 14:21:24 -07:00
parent 2e173ec6ad
commit f77396a09e
No known key found for this signature in database
GPG Key ID: 2AA8E0DA1B31FB3C

View File

@ -47,148 +47,427 @@ const QString Core::TOX_EXT = ".tox";
#define ASSERT_CORE_THREAD assert(QThread::currentThread() == coreThread.get())
namespace {
bool LogConferenceTitleError(TOX_ERR_CONFERENCE_TITLE error)
/**
* @brief Parse and log toxcore error enums.
* @param error Error to handle.
* @return True if no error, false otherwise.
*/
#define PARSE_ERR(ERROR_TYPE, err) parse##ERROR_TYPE(err, __LINE__)
bool parseToxErrConferenceTitle(Tox_Err_Conference_Title error, int line)
{
switch (error) {
case TOX_ERR_CONFERENCE_TITLE_OK:
break;
return true;
case TOX_ERR_CONFERENCE_TITLE_CONFERENCE_NOT_FOUND:
qWarning() << "Conference title not found";
break;
qCritical() << line << ": Conference title not found";
return false;
case TOX_ERR_CONFERENCE_TITLE_INVALID_LENGTH:
qWarning() << "Invalid conference title length";
break;
qCritical() << line << ": Invalid conference title length";
return false;
case TOX_ERR_CONFERENCE_TITLE_FAIL_SEND:
qWarning() << "Failed to send title packet";
qCritical() << line << ": Failed to send title packet";
return false;
default:
qCritical() << line << ": Unknown Tox_Err_Conference_Title error code:" << error;
return false;
}
return error;
}
bool parseFriendSendMessageError(Tox_Err_Friend_Send_Message error)
bool parseToxErrFriendSendMessage(Tox_Err_Friend_Send_Message error, int line)
{
switch (error) {
case TOX_ERR_FRIEND_SEND_MESSAGE_OK:
return true;
case TOX_ERR_FRIEND_SEND_MESSAGE_NULL:
qCritical() << "Send friend message passed an unexpected null argument";
qCritical() << line << "Send friend message passed an unexpected null argument";
return false;
case TOX_ERR_FRIEND_SEND_MESSAGE_FRIEND_NOT_FOUND:
qCritical() << "Send friend message could not find friend";
qCritical() << line << "Send friend message could not find friend";
return false;
case TOX_ERR_FRIEND_SEND_MESSAGE_FRIEND_NOT_CONNECTED:
qCritical() << "Send friend message: friend is offline";
qCritical() << line << "Send friend message: friend is offline";
return false;
case TOX_ERR_FRIEND_SEND_MESSAGE_SENDQ:
qCritical() << "Failed to allocate more message queue";
qCritical() << line << "Failed to allocate more message queue";
return false;
case TOX_ERR_FRIEND_SEND_MESSAGE_TOO_LONG:
qCritical() << "Attemped to send message that's too long";
qCritical() << line << "Attemped to send message that's too long";
return false;
case TOX_ERR_FRIEND_SEND_MESSAGE_EMPTY:
qCritical() << "Attempted to send an empty message";
qCritical() << line << "Attempted to send an empty message";
return false;
default:
qCritical() << "Unknown friend send message error:" << static_cast<int>(error);
qCritical() << line << "Unknown friend send message error:" << static_cast<int>(error);
return false;
}
}
bool parseConferenceSendMessageError(Tox_Err_Conference_Send_Message error)
bool parseToxErrConferenceSendMessage(Tox_Err_Conference_Send_Message error, int line)
{
switch (error) {
case TOX_ERR_CONFERENCE_SEND_MESSAGE_OK:
return true;
case TOX_ERR_CONFERENCE_SEND_MESSAGE_CONFERENCE_NOT_FOUND:
qCritical() << "Conference not found";
qCritical() << line << "Conference not found";
return false;
case TOX_ERR_CONFERENCE_SEND_MESSAGE_FAIL_SEND:
qCritical() << "Conference message failed to send";
qCritical() << line << "Conference message failed to send";
return false;
case TOX_ERR_CONFERENCE_SEND_MESSAGE_NO_CONNECTION:
qCritical() << "No connection";
qCritical() << line << "No connection";
return false;
case TOX_ERR_CONFERENCE_SEND_MESSAGE_TOO_LONG:
qCritical() << "Message too long";
qCritical() << line << "Message too long";
return false;
default:
qCritical() << "Unknown Tox_Err_Conference_Send_Message error:" << static_cast<int>(error);
qCritical() << line << "Unknown Tox_Err_Conference_Send_Message error:" << static_cast<int>(error);
return false;
}
}
/**
* @brief Print in console text of error.
* @param error Error to handle.
* @return True if no error, false otherwise.
*/
bool parsePeerQueryError(Tox_Err_Conference_Peer_Query error)
bool parseToxErrConferencePeerQuery(Tox_Err_Conference_Peer_Query error, int line)
{
switch (error) {
case TOX_ERR_CONFERENCE_PEER_QUERY_OK:
return true;
case TOX_ERR_CONFERENCE_PEER_QUERY_CONFERENCE_NOT_FOUND:
qCritical() << "Conference not found";
qCritical() << line << "Conference not found";
return false;
case TOX_ERR_CONFERENCE_PEER_QUERY_NO_CONNECTION:
qCritical() << "No connection";
qCritical() << line << "No connection";
return false;
case TOX_ERR_CONFERENCE_PEER_QUERY_PEER_NOT_FOUND:
qCritical() << "Peer not found";
qCritical() << line << "Peer not found";
return false;
default:
qCritical() << "Unknown error code:" << error;
qCritical() << line << "Unknown Tox_Err_Conference_Peer_Query error code:" << error;
return false;
}
}
/**
* @brief Print in console text of error.
* @param error Error to handle.
* @return True if no error, false otherwise.
*/
bool parseConferenceJoinError(Tox_Err_Conference_Join error)
bool parseToxErrConferenceJoin(Tox_Err_Conference_Join error, int line)
{
switch (error) {
case TOX_ERR_CONFERENCE_JOIN_OK:
return true;
case TOX_ERR_CONFERENCE_JOIN_DUPLICATE:
qCritical() << "Conference duplicate";
qCritical() << line << "Conference duplicate";
return false;
case TOX_ERR_CONFERENCE_JOIN_FAIL_SEND:
qCritical() << "Conference join failed to send";
qCritical() << line << "Conference join failed to send";
return false;
case TOX_ERR_CONFERENCE_JOIN_FRIEND_NOT_FOUND:
qCritical() << "Friend not found";
qCritical() << line << "Friend not found";
return false;
case TOX_ERR_CONFERENCE_JOIN_INIT_FAIL:
qCritical() << "Init fail";
qCritical() << line << "Init fail";
return false;
case TOX_ERR_CONFERENCE_JOIN_INVALID_LENGTH:
qCritical() << "Invalid length";
qCritical() << line << "Invalid length";
return false;
case TOX_ERR_CONFERENCE_JOIN_WRONG_TYPE:
qCritical() << "Wrong conference type";
qCritical() << line << "Wrong conference type";
return false;
default:
qCritical() << "Unknown error code:" << error;
qCritical() << line << "Unknown Tox_Err_Conference_Join error code:" << error;
return false;
}
}
bool parseToxErrConferenceGetType(Tox_Err_Conference_Get_Type error, int line)
{
switch (error) {
case TOX_ERR_CONFERENCE_GET_TYPE_OK:
return true;
case TOX_ERR_CONFERENCE_GET_TYPE_CONFERENCE_NOT_FOUND:
qCritical() << line << "Conference not found";
return false;
default:
qCritical() << line << "Unknown Tox_Err_Conference_Get_Type error code:" << error;
return false;
}
}
bool parseToxErrConferenceInvite(Tox_Err_Conference_Invite error, int line)
{
switch (error) {
case TOX_ERR_CONFERENCE_INVITE_OK:
return true;
case TOX_ERR_CONFERENCE_INVITE_CONFERENCE_NOT_FOUND:
qCritical() << line << "Conference not found";
return false;
case TOX_ERR_CONFERENCE_INVITE_FAIL_SEND:
qCritical() << line << "Conference invite failed to send";
return false;
case TOX_ERR_CONFERENCE_INVITE_NO_CONNECTION:
qCritical() << line << "Cannot invite to conference that we're not connected to";
return false;
default:
qWarning() << "Unknown Tox_Err_Conference_Invite error code:" << error;
return false;
}
}
bool parseToxErrConferenceNew(Tox_Err_Conference_New error, int line)
{
switch (error) {
case TOX_ERR_CONFERENCE_NEW_OK:
return true;
case TOX_ERR_CONFERENCE_NEW_INIT:
qCritical() << line << "The conference instance failed to initialize";
return false;
default:
qCritical() << line << "Unknown Tox_Err_Conference_New error code:" << error;
return false;
}
}
bool parseToxErrFriendByPublicKey(Tox_Err_Friend_By_Public_Key error, int line)
{
switch (error) {
case TOX_ERR_FRIEND_BY_PUBLIC_KEY_OK:
return true;
case TOX_ERR_FRIEND_BY_PUBLIC_KEY_NULL:
qCritical() << line << "null argument when not expected";
return false;
case TOX_ERR_FRIEND_BY_PUBLIC_KEY_NOT_FOUND:
// we use this as a check for friendship, so this can be an expected result
return false;
default:
qCritical() << line << "Unknown Tox_Err_Friend_By_Public_Key error code:" << error;
return false;
}
}
bool parseToxErrBootstrap(Tox_Err_Bootstrap error, int line)
{
switch(error) {
case TOX_ERR_BOOTSTRAP_OK:
return true;
case TOX_ERR_BOOTSTRAP_NULL:
qCritical() << line << "null argument when not expected";
return false;
case TOX_ERR_BOOTSTRAP_BAD_HOST:
qCritical() << line << "Could not resolve hostname, or invalid IP address";
return false;
case TOX_ERR_BOOTSTRAP_BAD_PORT:
qCritical() << line << "out of range port";
return false;
default:
qCritical() << line << "Unknown Tox_Err_bootstrap error code:" << error;
return false;
}
}
bool parseToxErrFriendAdd(Tox_Err_Friend_Add error, int line)
{
switch(error) {
case TOX_ERR_FRIEND_ADD_OK:
return true;
case TOX_ERR_FRIEND_ADD_NULL:
qCritical() << line << "null argument when not expected";
return false;
case TOX_ERR_FRIEND_ADD_TOO_LONG:
qCritical() << line << "The length of the friend request message exceeded";
return false;
case TOX_ERR_FRIEND_ADD_NO_MESSAGE:
qCritical() << line << "The friend request message was empty.";
return false;
case TOX_ERR_FRIEND_ADD_OWN_KEY:
qCritical() << line << "The friend address belongs to the sending client.";
return false;
case TOX_ERR_FRIEND_ADD_ALREADY_SENT:
qCritical() << line << "The address belongs to a friend that is already on the friend list.";
return false;
case TOX_ERR_FRIEND_ADD_BAD_CHECKSUM:
qCritical() << line << "The friend address checksum failed.";
return false;
case TOX_ERR_FRIEND_ADD_SET_NEW_NOSPAM:
qCritical() << line << "The address belongs to a friend that is already on the friend list.";
return false;
case TOX_ERR_FRIEND_ADD_MALLOC:
qCritical() << line << "A memory allocation failed when trying to increase the friend list size.";
return false;
default:
qCritical() << line << "Unknown Tox_Err_Friend_Add error code:" << error;
return false;
}
}
bool parseToxErrFriendDelete(Tox_Err_Friend_Delete error, int line)
{
switch(error) {
case TOX_ERR_FRIEND_DELETE_OK:
return true;
case TOX_ERR_FRIEND_DELETE_FRIEND_NOT_FOUND:
qCritical() << line << "There is no friend with the given friend number";
return false;
default:
qCritical() << line << "Unknown Tox_Err_Friend_Delete error code:" << error;
return false;
}
}
bool parseToxErrSetInfo(Tox_Err_Set_Info error, int line)
{
switch (error) {
case TOX_ERR_SET_INFO_OK:
return true;
case TOX_ERR_SET_INFO_NULL:
qCritical() << line << "null argument when not expected";
return false;
case TOX_ERR_SET_INFO_TOO_LONG:
qCritical() << line << "Information length exceeded maximum permissible size.";
return false;
default:
qCritical() << line << "Unknown Tox_Err_Set_Info error code:" << error;
return false;
}
}
bool parseToxErrFriendQuery(Tox_Err_Friend_Query error, int line)
{
switch (error) {
case TOX_ERR_FRIEND_QUERY_OK:
return true;
case TOX_ERR_FRIEND_QUERY_NULL:
qCritical() << line << "null argument when not expected";
return false;
case TOX_ERR_FRIEND_QUERY_FRIEND_NOT_FOUND:
qCritical() << line << "The friend_number did not designate a valid friend.";
return false;
default:
qCritical() << line << "Unknown Tox_Err_Friend_Query error code:" << error;
return false;
}
}
bool parseToxErrFriendGetPublicKey(Tox_Err_Friend_Get_Public_Key error, int line)
{
switch (error) {
case TOX_ERR_FRIEND_GET_PUBLIC_KEY_OK:
return true;
case TOX_ERR_FRIEND_GET_PUBLIC_KEY_FRIEND_NOT_FOUND:
qCritical() << line << "There is no friend with the given friend number";
return false;
default:
qCritical() << line << "Unknown Tox_Err_Friend_Get_Public_Key error code:" << error;
return false;
}
}
bool parseToxErrFriendGetLastOnline(Tox_Err_Friend_Get_Last_Online error, int line)
{
switch (error) {
case TOX_ERR_FRIEND_GET_LAST_ONLINE_OK:
return true;
case TOX_ERR_FRIEND_GET_LAST_ONLINE_FRIEND_NOT_FOUND:
qCritical() << line << "There is no friend with the given friend number";
return false;
default:
qCritical() << line << "Unknown Tox_Err_Friend_Get_Last_Online error code:" << error;
return false;
}
}
bool parseToxErrSetTyping(Tox_Err_Set_Typing error, int line)
{
switch (error) {
case TOX_ERR_SET_TYPING_OK:
return true;
case TOX_ERR_SET_TYPING_FRIEND_NOT_FOUND:
qCritical() << line << "There is no friend with the given friend number";
return false;
default:
qCritical() << line << "Unknown Tox_Err_Set_Typing error code:" << error;
return false;
}
}
bool parseToxErrConferenceDelete(Tox_Err_Conference_Delete error, int line)
{
switch (error) {
case TOX_ERR_CONFERENCE_DELETE_OK:
return true;
case TOX_ERR_CONFERENCE_DELETE_CONFERENCE_NOT_FOUND:
qCritical() << line << "The conference number passed did not designate a valid conference.";
return false;
default:
qCritical() << line << "Unknown Tox_Err_Conference_Delete error code:" << error;
return false;
}
}
} // namespace
Core::Core(QThread* coreThread)
@ -526,11 +805,14 @@ void Core::bootstrapDht()
const uint8_t* pkPtr = pk.getData();
if (!tox_bootstrap(tox.get(), address.constData(), dhtServer.port, pkPtr, nullptr)) {
Tox_Err_Bootstrap error;
tox_bootstrap(tox.get(), address.constData(), dhtServer.port, pkPtr, &error);
if (!PARSE_ERR(ToxErrBootstrap, error)) {
qDebug() << "Error bootstrapping from " + dhtServer.name;
}
if (!tox_add_tcp_relay(tox.get(), address.constData(), dhtServer.port, pkPtr, nullptr)) {
tox_add_tcp_relay(tox.get(), address.constData(), dhtServer.port, pkPtr, &error);
if (!PARSE_ERR(ToxErrBootstrap, error)) {
qDebug() << "Error adding TCP relay from " + dhtServer.name;
}
@ -675,13 +957,13 @@ void Core::onReadReceiptCallback(Tox*, uint32_t friendId, uint32_t receipt, void
void Core::acceptFriendRequest(const ToxPk& friendPk)
{
QMutexLocker ml{&coreLoopLock};
// TODO: error handling
uint32_t friendId = tox_friend_add_norequest(tox.get(), friendPk.getData(), nullptr);
if (friendId == std::numeric_limits<uint32_t>::max()) {
emit failedToAddFriend(friendPk);
} else {
Tox_Err_Friend_Add error;
uint32_t friendId = tox_friend_add_norequest(tox.get(), friendPk.getData(), &error);
if (PARSE_ERR(ToxErrFriendAdd, error)) {
emit saveRequest();
emit friendAdded(friendId, friendPk);
} else {
emit failedToAddFriend(friendPk);
}
}
@ -728,18 +1010,18 @@ void Core::requestFriendship(const ToxId& friendId, const QString& message)
}
ToxString cMessage(message);
Tox_Err_Friend_Add error;
uint32_t friendNumber =
tox_friend_add(tox.get(), friendId.getBytes(), cMessage.data(), cMessage.size(), nullptr);
if (friendNumber == std::numeric_limits<uint32_t>::max()) {
qDebug() << "Failed to send friend request";
emit failedToAddFriend(friendPk);
} else {
tox_friend_add(tox.get(), friendId.getBytes(), cMessage.data(), cMessage.size(), &error);
if (PARSE_ERR(ToxErrFriendAdd, error)) {
qDebug() << "Requested friendship from " << friendNumber;
emit saveRequest();
emit friendAdded(friendNumber, friendPk);
emit requestSent(friendPk, message);
} else {
qDebug() << "Failed to send friend request";
emit failedToAddFriend(friendPk);
}
emit saveRequest();
}
bool Core::sendMessageWithType(uint32_t friendId, const QString& message, Tox_Message_Type type,
@ -757,7 +1039,7 @@ bool Core::sendMessageWithType(uint32_t friendId, const QString& message, Tox_Me
Tox_Err_Friend_Send_Message error;
receipt = ReceiptNum{tox_friend_send_message(tox.get(), friendId, type, cMessage.data(),
cMessage.size(), &error)};
if (parseFriendSendMessageError(error)) {
if (PARSE_ERR(ToxErrFriendSendMessage, error)) {
return true;
}
return false;
@ -779,7 +1061,9 @@ void Core::sendTyping(uint32_t friendId, bool typing)
{
QMutexLocker ml{&coreLoopLock};
if (!tox_self_set_typing(tox.get(), friendId, typing, nullptr)) {
Tox_Err_Set_Typing error;
tox_self_set_typing(tox.get(), friendId, typing, &error);
if (!PARSE_ERR(ToxErrSetTyping, error)) {
emit failedToSetTyping(typing);
}
}
@ -799,7 +1083,7 @@ void Core::sendGroupMessageWithType(int groupId, const QString& message, Tox_Mes
ToxString cMsg(message);
Tox_Err_Conference_Send_Message error;
tox_conference_send_message(tox.get(), groupId, type, cMsg.data(), cMsg.size(), &error);
if (!parseConferenceSendMessageError(error)) {
if (!PARSE_ERR(ToxErrConferenceSendMessage, error)) {
emit groupSentFailed(groupId);
return;
}
@ -825,29 +1109,10 @@ void Core::changeGroupTitle(int groupId, const QString& title)
ToxString cTitle(title);
Tox_Err_Conference_Title error;
bool success = tox_conference_set_title(tox.get(), groupId, cTitle.data(), cTitle.size(), &error);
if (success && error == TOX_ERR_CONFERENCE_TITLE_OK) {
tox_conference_set_title(tox.get(), groupId, cTitle.data(), cTitle.size(), &error);
if (PARSE_ERR(ToxErrConferenceTitle, error)) {
emit saveRequest();
emit groupTitleChanged(groupId, getUsername(), title);
return;
}
qCritical() << "Fail of tox_conference_set_title";
switch (error) {
case TOX_ERR_CONFERENCE_TITLE_CONFERENCE_NOT_FOUND:
qCritical() << "Conference not found";
break;
case TOX_ERR_CONFERENCE_TITLE_FAIL_SEND:
qCritical() << "Conference title failed to send";
break;
case TOX_ERR_CONFERENCE_TITLE_INVALID_LENGTH:
qCritical() << "Invalid length";
break;
default:
break;
}
}
@ -855,7 +1120,9 @@ void Core::removeFriend(uint32_t friendId)
{
QMutexLocker ml{&coreLoopLock};
if (!tox_friend_delete(tox.get(), friendId, nullptr)) {
Tox_Err_Friend_Delete error;
tox_friend_delete(tox.get(), friendId, &error);
if (!PARSE_ERR(ToxErrFriendDelete, error)) {
emit failedToRemoveFriend(friendId);
return;
}
@ -869,21 +1136,10 @@ void Core::removeGroup(int groupId)
QMutexLocker ml{&coreLoopLock};
Tox_Err_Conference_Delete error;
bool success = tox_conference_delete(tox.get(), groupId, &error);
if (success && error == TOX_ERR_CONFERENCE_DELETE_OK) {
tox_conference_delete(tox.get(), groupId, &error);
if (PARSE_ERR(ToxErrConferenceDelete, error)) {
emit saveRequest();
av->leaveGroupCall(groupId);
return;
}
qCritical() << "Fail of tox_conference_delete";
switch (error) {
case TOX_ERR_CONFERENCE_DELETE_CONFERENCE_NOT_FOUND:
qCritical() << "Conference not found";
break;
default:
break;
}
}
@ -916,7 +1172,9 @@ void Core::setUsername(const QString& username)
}
ToxString cUsername(username);
if (!tox_self_set_name(tox.get(), cUsername.data(), cUsername.size(), nullptr)) {
Tox_Err_Set_Info error;
tox_self_set_name(tox.get(), cUsername.data(), cUsername.size(), &error);
if (!PARSE_ERR(ToxErrSetInfo, error)) {
emit failedToSetUsername(username);
return;
}
@ -1008,7 +1266,9 @@ void Core::setStatusMessage(const QString& message)
}
ToxString cMessage(message);
if (!tox_self_set_status_message(tox.get(), cMessage.data(), cMessage.size(), nullptr)) {
Tox_Err_Set_Info error;
tox_self_set_status_message(tox.get(), cMessage.data(), cMessage.size(), &error);
if (!PARSE_ERR(ToxErrSetInfo, error)) {
emit failedToSetStatusMessage(message);
return;
}
@ -1059,19 +1319,6 @@ QByteArray Core::getToxSaveData()
return data;
}
// Declared to avoid code duplication
#define GET_FRIEND_PROPERTY(property, function, checkSize) \
const size_t property##Size = function##_size(tox.get(), ids[i], nullptr); \
if ((!checkSize || property##Size) && property##Size != SIZE_MAX) { \
uint8_t* prop = new uint8_t[property##Size]; \
if (function(tox.get(), ids[i], prop, nullptr)) { \
QString propStr = ToxString(prop, property##Size).getQString(); \
emit friend##property##Changed(ids[i], propStr); \
} \
\
delete[] prop; \
}
void Core::loadFriends()
{
QMutexLocker ml{&coreLoopLock};
@ -1085,13 +1332,21 @@ void Core::loadFriends()
tox_self_get_friend_list(tox.get(), ids);
uint8_t friendPk[TOX_PUBLIC_KEY_SIZE] = {0x00};
for (size_t i = 0; i < friendCount; ++i) {
if (!tox_friend_get_public_key(tox.get(), ids[i], friendPk, nullptr)) {
Tox_Err_Friend_Get_Public_Key keyError;
tox_friend_get_public_key(tox.get(), ids[i], friendPk, &keyError);
if (!PARSE_ERR(ToxErrFriendGetPublicKey, keyError)) {
continue;
}
emit friendAdded(ids[i], ToxPk(friendPk));
GET_FRIEND_PROPERTY(Username, tox_friend_get_name, true);
GET_FRIEND_PROPERTY(StatusMessage, tox_friend_get_status_message, false);
emit friendUsernameChanged(ids[i], getFriendUsername(ids[i]));
Tox_Err_Friend_Query queryError;
size_t statusMessageSize = tox_friend_get_status_message_size(tox.get(), ids[i], &queryError);
if (PARSE_ERR(ToxErrFriendQuery, queryError)) {
std::vector<uint8_t> messageData(statusMessageSize);
tox_friend_get_status_message(tox.get(), ids[i], messageData.data(), &queryError);
QString friendStatusMessage = ToxString(messageData.data(), statusMessageSize).getQString();
emit friendStatusMessageChanged(ids[i], friendStatusMessage);
}
checkLastOnline(ids[i]);
}
delete[] ids;
@ -1110,23 +1365,23 @@ void Core::loadGroups()
tox_conference_get_chatlist(tox.get(), groupNumbers);
for (size_t i = 0; i < groupCount; ++i) {
TOX_ERR_CONFERENCE_TITLE error;
Tox_Err_Conference_Title error;
QString name;
const auto groupNumber = groupNumbers[i];
size_t titleSize = tox_conference_get_title_size(tox.get(), groupNumber, &error);
const GroupId persistentId = getGroupPersistentId(groupNumber);
const QString defaultName = tr("Groupchat %1").arg(persistentId.toString().left(8));
if (LogConferenceTitleError(error)) {
name = defaultName;
} else {
if (PARSE_ERR(ToxErrConferenceTitle, error)) {
QByteArray nameByteArray = QByteArray(static_cast<int>(titleSize), Qt::Uninitialized);
tox_conference_get_title(tox.get(), groupNumber,
reinterpret_cast<uint8_t*>(nameByteArray.data()), &error);
if (LogConferenceTitleError(error)) {
name = defaultName;
} else {
if (PARSE_ERR(ToxErrConferenceTitle, error)) {
name = ToxString(nameByteArray).getQString();
} else {
name = defaultName;
}
} else {
name = defaultName;
}
if (getGroupAvEnabled(groupNumber)) {
if (toxav_groupchat_enable_av(tox.get(), groupNumber, CoreAV::groupCallCallback, this)) {
@ -1143,8 +1398,9 @@ void Core::checkLastOnline(uint32_t friendId)
{
QMutexLocker ml{&coreLoopLock};
const uint64_t lastOnline = tox_friend_get_last_online(tox.get(), friendId, nullptr);
if (lastOnline != std::numeric_limits<uint64_t>::max()) {
Tox_Err_Friend_Get_Last_Online error;
const uint64_t lastOnline = tox_friend_get_last_online(tox.get(), friendId, &error);
if (PARSE_ERR(ToxErrFriendGetLastOnline, error)) {
emit friendLastSeenChanged(friendId, QDateTime::fromTime_t(lastOnline));
}
}
@ -1187,7 +1443,7 @@ uint32_t Core::getGroupNumberPeers(int groupId) const
Tox_Err_Conference_Peer_Query error;
uint32_t count = tox_conference_peer_count(tox.get(), groupId, &error);
if (!parsePeerQueryError(error)) {
if (!PARSE_ERR(ToxErrConferencePeerQuery, error)) {
return std::numeric_limits<uint32_t>::max();
}
@ -1203,14 +1459,14 @@ QString Core::getGroupPeerName(int groupId, int peerId) const
Tox_Err_Conference_Peer_Query error;
size_t length = tox_conference_peer_get_name_size(tox.get(), groupId, peerId, &error);
if (!parsePeerQueryError(error)) {
if (!PARSE_ERR(ToxErrConferencePeerQuery, error)) {
return QString{};
}
QByteArray name(length, Qt::Uninitialized);
uint8_t* namePtr = reinterpret_cast<uint8_t*>(name.data());
bool success = tox_conference_peer_get_name(tox.get(), groupId, peerId, namePtr, &error);
if (!parsePeerQueryError(error)) {
if (!PARSE_ERR(ToxErrConferencePeerQuery, error)) {
return QString{};
}
assert(success);
@ -1228,7 +1484,7 @@ ToxPk Core::getGroupPeerPk(int groupId, int peerId) const
uint8_t friendPk[TOX_PUBLIC_KEY_SIZE] = {0x00};
Tox_Err_Conference_Peer_Query error;
bool success = tox_conference_peer_get_public_key(tox.get(), groupId, peerId, friendPk, &error);
if (!parsePeerQueryError(error)) {
if (!PARSE_ERR(ToxErrConferencePeerQuery, error)) {
return ToxPk{};
}
assert(success);
@ -1253,16 +1509,16 @@ QStringList Core::getGroupPeerNames(int groupId) const
QStringList names;
for (uint32_t i = 0; i < nPeers; ++i) {
TOX_ERR_CONFERENCE_PEER_QUERY error;
Tox_Err_Conference_Peer_Query error;
size_t length = tox_conference_peer_get_name_size(tox.get(), groupId, i, &error);
if (!parsePeerQueryError(error)) {
if (!PARSE_ERR(ToxErrConferencePeerQuery, error)) {
continue;
}
QByteArray name(length, Qt::Uninitialized);
uint8_t* namePtr = reinterpret_cast<uint8_t*>(name.data());
bool ok = tox_conference_peer_get_name(tox.get(), groupId, i, namePtr, &error);
if (ok && parsePeerQueryError(error)) {
if (ok && PARSE_ERR(ToxErrConferencePeerQuery, error)) {
names.append(ToxString(name).getQString());
}
}
@ -1278,19 +1534,10 @@ QStringList Core::getGroupPeerNames(int groupId) const
bool Core::getGroupAvEnabled(int groupId) const
{
QMutexLocker ml{&coreLoopLock};
TOX_ERR_CONFERENCE_GET_TYPE error;
TOX_CONFERENCE_TYPE type = tox_conference_get_type(tox.get(), groupId, &error);
switch (error) {
case TOX_ERR_CONFERENCE_GET_TYPE_OK:
break;
case TOX_ERR_CONFERENCE_GET_TYPE_CONFERENCE_NOT_FOUND:
qWarning() << "Conference not found";
break;
default:
qWarning() << "Unknown error code:" << QString::number(error);
break;
}
Tox_Err_Conference_Get_Type error;
Tox_Conference_Type type = tox_conference_get_type(tox.get(), groupId, &error);
PARSE_ERR(ToxErrConferenceGetType, error);
// would be nice to indicate to caller that we don't actually know..
return type == TOX_CONFERENCE_TYPE_AV;
}
@ -1315,7 +1562,7 @@ uint32_t Core::joinGroupchat(const GroupInvite& inviteInfo)
qDebug() << QString("Trying to accept invite for text group chat sent by friend %1").arg(friendId);
Tox_Err_Conference_Join error;
groupNum = tox_conference_join(tox.get(), friendId, cookie, cookieLength, &error);
if (!parseConferenceJoinError(error)) {
if (!PARSE_ERR(ToxErrConferenceJoin, error)) {
groupNum = std::numeric_limits<uint32_t>::max();
}
break;
@ -1342,22 +1589,7 @@ void Core::groupInviteFriend(uint32_t friendId, int groupId)
Tox_Err_Conference_Invite error;
tox_conference_invite(tox.get(), friendId, groupId, &error);
switch (error) {
case TOX_ERR_CONFERENCE_INVITE_OK:
break;
case TOX_ERR_CONFERENCE_INVITE_CONFERENCE_NOT_FOUND:
qCritical() << "Conference not found";
break;
case TOX_ERR_CONFERENCE_INVITE_FAIL_SEND:
qCritical() << "Conference invite failed to send";
break;
default:
break;
}
PARSE_ERR(ToxErrConferenceInvite, error);
}
int Core::createGroup(uint8_t type)
@ -1367,24 +1599,23 @@ int Core::createGroup(uint8_t type)
if (type == TOX_CONFERENCE_TYPE_TEXT) {
Tox_Err_Conference_New error;
uint32_t groupId = tox_conference_new(tox.get(), &error);
switch (error) {
case TOX_ERR_CONFERENCE_NEW_OK:
if (PARSE_ERR(ToxErrConferenceNew, error)) {
emit saveRequest();
emit emptyGroupCreated(groupId, getGroupPersistentId(groupId));
return groupId;
case TOX_ERR_CONFERENCE_NEW_INIT:
qCritical() << "The conference instance failed to initialize";
return std::numeric_limits<uint32_t>::max();
default:
} else {
return std::numeric_limits<uint32_t>::max();
}
} else if (type == TOX_CONFERENCE_TYPE_AV) {
uint32_t groupId = toxav_add_av_groupchat(tox.get(), CoreAV::groupCallCallback, this);
emit saveRequest();
emit emptyGroupCreated(groupId, getGroupPersistentId(groupId));
// unlike tox_conference_new, toxav_add_av_groupchat does not have an error enum, so -1 group number is our
// only indication of an error
int groupId = toxav_add_av_groupchat(tox.get(), CoreAV::groupCallCallback, this);
if (groupId != -1) {
emit saveRequest();
emit emptyGroupCreated(groupId, getGroupPersistentId(groupId));
} else {
qCritical() << "Unknown error creating AV groupchat";
}
return groupId;
} else {
qWarning() << "createGroup: Unknown type " << type;
@ -1399,7 +1630,9 @@ bool Core::isFriendOnline(uint32_t friendId) const
{
QMutexLocker ml{&coreLoopLock};
Tox_Connection connection = tox_friend_get_connection_status(tox.get(), friendId, nullptr);
Tox_Err_Friend_Query error;
Tox_Connection connection = tox_friend_get_connection_status(tox.get(), friendId, &error);
PARSE_ERR(ToxErrFriendQuery, error);
return connection != TOX_CONNECTION_NONE;
}
@ -1414,9 +1647,9 @@ bool Core::hasFriendWithPublicKey(const ToxPk& publicKey) const
return false;
}
// TODO: error handling
uint32_t friendId = tox_friend_by_public_key(tox.get(), publicKey.getData(), nullptr);
return friendId != std::numeric_limits<uint32_t>::max();
Tox_Err_Friend_By_Public_Key error;
uint32_t friendId = tox_friend_by_public_key(tox.get(), publicKey.getData(), &error);
return PARSE_ERR(ToxErrFriendByPublicKey, error);
}
/**
@ -1427,7 +1660,9 @@ ToxPk Core::getFriendPublicKey(uint32_t friendNumber) const
QMutexLocker ml{&coreLoopLock};
uint8_t rawid[TOX_PUBLIC_KEY_SIZE];
if (!tox_friend_get_public_key(tox.get(), friendNumber, rawid, nullptr)) {
Tox_Err_Friend_Get_Public_Key error;
tox_friend_get_public_key(tox.get(), friendNumber, rawid, &error);
if (!PARSE_ERR(ToxErrFriendGetPublicKey, error)) {
qWarning() << "getFriendPublicKey: Getting public key failed";
return ToxPk();
}
@ -1442,14 +1677,20 @@ QString Core::getFriendUsername(uint32_t friendnumber) const
{
QMutexLocker ml{&coreLoopLock};
size_t namesize = tox_friend_get_name_size(tox.get(), friendnumber, nullptr);
if (namesize == SIZE_MAX) {
Tox_Err_Friend_Query error;
size_t namesize = tox_friend_get_name_size(tox.get(), friendnumber, &error);
if (!PARSE_ERR(ToxErrFriendQuery, error)) {
qWarning() << "getFriendUsername: Failed to get name size for friend " << friendnumber;
return QString();
}
uint8_t* name = new uint8_t[namesize];
tox_friend_get_name(tox.get(), friendnumber, name, nullptr);
tox_friend_get_name(tox.get(), friendnumber, name, &error);
if (!PARSE_ERR(ToxErrFriendQuery, error)) {
qWarning() << "getFriendUsername: Failed to get name of friend " << friendnumber;
delete[] name;
return QString();
}
ToxString sname(name, namesize);
delete[] name;
return sname.getQString();
@ -1504,19 +1745,22 @@ QString Core::getPeerName(const ToxPk& id) const
QMutexLocker ml{&coreLoopLock};
QString name;
uint32_t friendId = tox_friend_by_public_key(tox.get(), id.getData(), nullptr);
if (friendId == std::numeric_limits<uint32_t>::max()) {
Tox_Err_Friend_By_Public_Key keyError;
uint32_t friendId = tox_friend_by_public_key(tox.get(), id.getData(), &keyError);
if (!PARSE_ERR(ToxErrFriendByPublicKey, keyError)) {
qWarning() << "getPeerName: No such peer";
return name;
}
const size_t nameSize = tox_friend_get_name_size(tox.get(), friendId, nullptr);
if (nameSize == SIZE_MAX) {
Tox_Err_Friend_Query queryError;
const size_t nameSize = tox_friend_get_name_size(tox.get(), friendId, &queryError);
if (!PARSE_ERR(ToxErrFriendQuery, queryError)) {
return name;
}
uint8_t* cname = new uint8_t[nameSize < tox_max_name_length() ? tox_max_name_length() : nameSize];
if (!tox_friend_get_name(tox.get(), friendId, cname, nullptr)) {
tox_friend_get_name(tox.get(), friendId, cname, &queryError);
if (!PARSE_ERR(ToxErrFriendQuery, queryError)) {
qWarning() << "getPeerName: Can't get name of friend " + QString().setNum(friendId);
delete[] cname;
return name;