/**
 * Add a friend message to the message queue and tries to send it if the
 * friend is online. Handles splitting of messages. (TODO: actually split messages)
 */
void
twc_message_queue_add_friend_message(struct t_twc_profile *profile,
                                     int32_t friend_number,
                                     const char *message,
                                     enum TWC_MESSAGE_TYPE message_type)
{
    struct t_twc_queued_message *queued_message
        = malloc(sizeof(struct t_twc_queued_message));

    time_t rawtime = time(NULL);
    queued_message->time = malloc(sizeof(struct tm));
    memcpy(queued_message->time, gmtime(&rawtime), sizeof(struct tm));

    queued_message->message = strdup(message);
    queued_message->message_type = message_type;

    // create a queue if needed and add message
    struct t_twc_list *message_queue
        = twc_message_queue_get_or_create(profile, friend_number);
    twc_list_item_new_data_add(message_queue, queued_message);

    // flush if friend is online
    if (profile->tox
        && tox_get_friend_connection_status(profile->tox, friend_number) == 1)
        twc_message_queue_flush_friend(profile, friend_number);
}
Exemple #2
0
static void chat_onInit(ToxWindow *self, Tox *m)
{
    int x2, y2;
    getmaxyx(self->window, y2, x2);
    self->x = x2;

    /* Init statusbar info */
    StatusBar *statusbar = self->stb;
    statusbar->status = tox_get_user_status(m, self->num);
    statusbar->is_online = tox_get_friend_connection_status(m, self->num) == 1;

    uint8_t statusmsg[TOX_MAX_STATUSMESSAGE_LENGTH] = {'\0'};
    tox_get_status_message(m, self->num, statusmsg, TOX_MAX_STATUSMESSAGE_LENGTH);
    snprintf(statusbar->statusmsg, sizeof(statusbar->statusmsg), "%s", statusmsg);
    statusbar->statusmsg_len = tox_get_status_message_size(m, self->num);

    /* Init subwindows */
    ChatContext *ctx = self->chatwin;
    statusbar->topline = subwin(self->window, 2, x2, 0, 0);
    ctx->history = subwin(self->window, y2-CHATBOX_HEIGHT+1, x2, 0, 0);
    scrollok(ctx->history, 1);
    ctx->linewin = subwin(self->window, CHATBOX_HEIGHT, x2, y2-CHATBOX_HEIGHT, 0);
    wprintw(ctx->history, "\n\n");
    execute(ctx->history, self, m, "/help", CHAT_COMMAND_MODE);
    wmove(self->window, y2 - CURS_Y_OFFSET, 0);
}
Exemple #3
0
/**
 * read message from remote message queue, and send to remote
 * this will only send one message in the message queue
 * and write_data_remote will be block at the same time
 */
void send_data_remote(){
    MSGTask *mTask = front(msg_task_queue); // 开始处理
    int friend_num = tox_get_friend_number(my_tox,mTask->target_addr_bin);
    int res = -1;
    int retry_count = 0;
    //debug_msg_bin(mTask->msg);
    while(res <=0 && retry_count <5){
        res = tox_send_message(my_tox,friend_num,mTask->msg,MY_MESSAGE_LENGTH);
        retry_count += 1;
    }
    if(retry_count < 5){
        Dequeue(msg_task_queue);
        pthread_cond_broadcast(&msg_task_cond);
    }else{
        // check target online status
        if(tox_get_friend_connection_status(my_tox,friend_num) != 1){
            // target offline
            Dequeue(msg_task_queue);
            pthread_cond_broadcast(&msg_task_cond);
            // unpack msg to get uuid
            uint8_t *uuid = (uint8_t *)malloc(sizeof(uint8_t)*UUID_LENGTH+1);
            memset(uuid,'\0',UUID_LENGTH+1);
			uint8_t *cmd = (uint8_t *)malloc(sizeof(uint8_t)*CMD_STR_LENGTH);
            uint8_t *data = (uint8_t *)malloc(sizeof(uint8_t)*MY_MESSAGE_LENGTH);
            uint32_t *length = (uint32_t *)malloc(sizeof(uint32_t));
            unpack_msg_bin(mTask->msg, uuid, cmd, data, length);
            // get socket fd by uuid
            int32_t sockfd = get_local_socks(msocks_list,uuid);
            // close socket
            close_local_socks(msocks_list,sockfd);
            free(uuid);
            free(cmd);
            free(data);
            free(length);
            printf("target is offline. ******************************************************\n");
            printf("status %d\n", tox_get_friend_connection_status(my_tox,friend_num));
            printf("friend num %d\n", friend_num);
            //exit(1);
        }
    }
}
Exemple #4
0
static void chat_onInit(ToxWindow *self, Tox *m)
{
    curs_set(1);
    int x2, y2;
    getmaxyx(self->window, y2, x2);
    self->x = x2;

    /* Init statusbar info */
    StatusBar *statusbar = self->stb;

    statusbar->status = tox_get_user_status(m, self->num);
    statusbar->is_online = tox_get_friend_connection_status(m, self->num) == 1;

    char statusmsg[TOX_MAX_STATUSMESSAGE_LENGTH] = {'\0'};
    uint16_t s_len = tox_get_status_message(m, self->num, (uint8_t *) statusmsg, TOX_MAX_STATUSMESSAGE_LENGTH);
    statusmsg[s_len] = '\0';
    snprintf(statusbar->statusmsg, sizeof(statusbar->statusmsg), "%s", statusmsg);
    statusbar->statusmsg_len = s_len;

    char nick[TOX_MAX_NAME_LENGTH];
    int n_len = get_nick_truncate(m, nick, self->num);
    snprintf(statusbar->nick, sizeof(statusbar->nick), "%s", nick);
    statusbar->nick_len = n_len;

    /* Init subwindows */
    ChatContext *ctx = self->chatwin;

    statusbar->topline = subwin(self->window, 2, x2, 0, 0);
    ctx->history = subwin(self->window, y2 - CHATBOX_HEIGHT + 1, x2, 0, 0);
    ctx->linewin = subwin(self->window, CHATBOX_HEIGHT, x2, y2 - CHATBOX_HEIGHT, 0);

    ctx->hst = calloc(1, sizeof(struct history));
    ctx->log = calloc(1, sizeof(struct chatlog));

    if (ctx->log == NULL || ctx->hst == NULL)
        exit_toxic_err("failed in chat_onInit", FATALERR_MEMORY);

    line_info_init(ctx->hst);

    if (friends[self->num].logging_on)
        log_enable(nick, friends[self->num].pub_key, ctx->log);

    execute(ctx->history, self, m, "/log", GLOBAL_COMMAND_MODE);

    scrollok(ctx->history, 0);
    wmove(self->window, y2 - CURS_Y_OFFSET, 0);
}
Exemple #5
0
END_TEST

#define NUM_TOXES 66
#define NUM_FRIENDS 20

START_TEST(test_many_clients)
{
    long long unsigned int cur_time = time(NULL);
    Tox *toxes[NUM_TOXES];
    uint32_t i, j;
    uint32_t to_comp = 974536;

    for (i = 0; i < NUM_TOXES; ++i) {
        toxes[i] = tox_new(0);
        ck_assert_msg(toxes[i] != 0, "Failed to create tox instances %u", i);
        tox_callback_friend_request(toxes[i], accept_friend_request, &to_comp);
    }

    struct {
        uint16_t tox1;
        uint16_t tox2;
    } pairs[NUM_FRIENDS];

    uint8_t address[TOX_FRIEND_ADDRESS_SIZE];

    for (i = 0; i < NUM_FRIENDS; ++i) {
loop_top:
        pairs[i].tox1 = rand() % NUM_TOXES;
        pairs[i].tox2 = (pairs[i].tox1 + rand() % (NUM_TOXES - 1) + 1) % NUM_TOXES;

        for (j = 0; j < i; ++j) {
            if (pairs[j].tox2 == pairs[i].tox1 && pairs[j].tox1 == pairs[i].tox2)
                goto loop_top;
        }

        tox_get_address(toxes[pairs[i].tox1], address);
        int test = tox_add_friend(toxes[pairs[i].tox2], address, (uint8_t *)"Gentoo", 7);

        if (test == TOX_FAERR_ALREADYSENT) {
            goto loop_top;
        }

        ck_assert_msg(test >= 0, "Failed to add friend error code: %i", test);
    }

    while (1) {
        uint16_t counter = 0;

        for (i = 0; i < NUM_TOXES; ++i) {
            for (j = 0; j < tox_count_friendlist(toxes[i]); ++j)
                if (tox_get_friend_connection_status(toxes[i], j) == 1)
                    ++counter;
        }

        if (counter == NUM_FRIENDS * 2) {
            break;
        }

        for (i = 0; i < NUM_TOXES; ++i) {
            tox_do(toxes[i]);
        }

        c_sleep(50);
    }

    printf("test_many_clients succeeded, took %llu seconds\n", time(NULL) - cur_time);

    for (i = 0; i < NUM_TOXES; ++i) {
        tox_kill(toxes[i]);
    }
}
Exemple #6
0
int main(int argc, char *argv[])
{
    uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */
    int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled);

    if (argvoffset < 0)
        exit(1);

    /* with optional --ipvx, now it can be 1-4 arguments... */
    if ((argc != argvoffset + 3) && (argc != argvoffset + 5)) {
        printf("Usage: %s [--ipv4|--ipv6] ip port public_key (of the DHT bootstrap node) folder (to sync)\n", argv[0]);
        exit(0);
    }

    Tox *tox = tox_new(ipv6enabled);
    tox_callback_file_data(tox, write_file, NULL);
    tox_callback_file_control(tox, file_print_control, NULL);
    tox_callback_file_send_request(tox, file_request_accept, NULL);
    tox_callback_connection_status(tox, print_online, NULL);

    uint16_t port = htons(atoi(argv[argvoffset + 2]));
    unsigned char *binary_string = hex_string_to_bin(argv[argvoffset + 3]);
    int res = tox_bootstrap_from_address(tox, argv[argvoffset + 1], ipv6enabled, port, binary_string);
    free(binary_string);

    if (!res) {
        printf("Failed to convert \"%s\" into an IP address. Exiting...\n", argv[argvoffset + 1]);
        exit(1);
    }

    uint8_t address[TOX_FRIEND_ADDRESS_SIZE];
    tox_get_address(tox, address);
    uint32_t i;

    for (i = 0; i < TOX_FRIEND_ADDRESS_SIZE; i++) {
        printf("%02X", address[i]);
    }

    char temp_id[128];
    printf("\nEnter the address of the other id you want to sync with (38 bytes HEX format):\n");

    if (scanf("%s", temp_id) != 1) {
        return 1;
    }

    uint8_t *bin_id = hex_string_to_bin(temp_id);
    int num = tox_add_friend(tox, bin_id, (uint8_t *)"Install Gentoo", sizeof("Install Gentoo"));
    free(bin_id);

    if (num < 0) {
        printf("\nSomething went wrong when adding friend.\n");
        return 1;
    }

    memcpy(path, argv[argvoffset + 4], strlen(argv[argvoffset + 4]));
    DIR           *d;
    struct dirent *dir;
    uint8_t notconnected = 1;

    while (1) {
        if (tox_isconnected(tox) && notconnected) {
            printf("\nDHT connected.\n");
            notconnected = 0;
        }

        if (not_sending() && tox_get_friend_connection_status(tox, num)) {
            d = opendir(path);

            if (d) {
                while ((dir = readdir(d)) != NULL) {
                    if (dir->d_type == DT_REG) {
                        char fullpath[1024];

                        if (path[strlen(path) - 1] == '/')
                            sprintf(fullpath, "%s%s", path, dir->d_name);
                        else
                            sprintf(fullpath, "%s/%s", path, dir->d_name);

                        add_filesender(tox, num, fullpath);
                    }
                }

                closedir(d);

            } else {
                printf("\nFailed to open directory.\n");
                return 1;
            }
        }

        send_filesenders(tox);
        tox_do(tox);
        c_sleep(1);
    }

    return 0;
}