int main(int argc, char *argv[]) { // 添加系统事件监听 signal(SIGINT, intHandler); #ifndef _WIN32 signal(SIGPIPE, SIG_IGN); #endif my_tox = init_tox(); init_tox_connection(my_tox); load_data(my_tox); // 处理参数 if(argc >3){ local_port = atoi(argv[1]); target_id = argv[2]; target_ip = argv[3]; target_port = atoi(argv[4]); uint8_t my_address_bin[TOX_FRIEND_ADDRESS_SIZE+1]; uint8_t my_address_str[TOX_FRIEND_ADDRESS_SIZE*2+1]; tox_get_address(my_tox,my_address_bin); hex_bin_to_string(my_address_bin,TOX_FRIEND_ADDRESS_SIZE,my_address_str); printf("MYID:%s\n",my_address_str); }else{ local_port = 9990 ; target_id = "3E567CBCE8DA8A18ED3C30127ADB61D78AFA2D01B5CD12425C110E84F23AC365144CE2807378"; target_ip = "127.0.0.1"; target_port = 22; } // 虛擬參數 // 初始化消息隊列 msg_task_queue = createQueue(MAX_MSG_CACHE); // 远程操作消息队列 // 開始tox線程 pthread_t tox_thread; int iret1 = pthread_create( &tox_thread, NULL, tox_works,NULL); if(iret1){ exit(EXIT_FAILURE); } // 初始化本地连接 local_socksfd = init_local_sock_serv(local_port); // 等待tox成功連接 while(!tox_isconnected(my_tox)){ #ifdef _WIN32 Sleep(20); #else usleep(20000); #endif } printf("TOXCORE:ONLINE\n"); printf("SERVER:LISTEN ON %d\n",local_port); // 進入請求者模式 int res = init_connect(my_tox,target_id,&msg_listener_list); if(res == 402){ printf("CONNECT:OK\n"); } else{ printf("CONNECT:ERROR\n"); } // client mode // create local tcp server msocks_list = create_local_socks_list(); while(1){ struct sockaddr_in cli_addr; uint32_t clilen = sizeof(cli_addr); int32_t newsockfd = accept(local_socksfd, (struct sockaddr *) &cli_addr, &clilen); if (newsockfd < 0){ printf("socket error\n"); } else{ printf("accepted:%d\n", newsockfd); // 发送创建远程端口指令 uint32_t sockfd = newsockfd; uint8_t *target_addr_bin = (uint8_t *)malloc(sizeof(uint8_t)*TOX_FRIEND_ADDRESS_SIZE); hex_string_to_bin(target_addr_bin,target_id); add_local_socks(msocks_list,sockfd,target_addr_bin,target_ip,target_port); // create remote socket uint8_t uuid[UUID_LENGTH+1]; get_local_socks_uuid(msocks_list,sockfd,uuid); create_remote_socket(uuid,target_addr_bin,target_ip,target_port); free(target_addr_bin); } } printf("EXITED\n"); return 0; }
void Core::start() { // IPv6 needed for LAN discovery, but can crash some weird routers. On by default, can be disabled in options. bool enableIPv6 = Settings::getInstance().getEnableIPv6(); bool forceTCP = Settings::getInstance().getForceTCP(); bool useProxy = Settings::getInstance().getUseProxy(); if (enableIPv6) qDebug() << "Core starting with IPv6 enabled"; else qWarning() << "Core starting with IPv6 disabled. LAN discovery may not work properly."; Tox_Options toxOptions; toxOptions.ipv6enabled = enableIPv6; toxOptions.udp_disabled = forceTCP; // No proxy by default toxOptions.proxy_enabled = false; toxOptions.proxy_address[0] = 0; toxOptions.proxy_port = 0; if (useProxy) { QString proxyAddr = Settings::getInstance().getProxyAddr(); int proxyPort = Settings::getInstance().getProxyPort(); if (proxyAddr.length() > 255) { qWarning() << "Core: proxy address" << proxyAddr << "is too long"; } else if (proxyAddr != "" && proxyPort > 0) { qDebug() << "Core: using proxy" << proxyAddr << ":" << proxyPort; toxOptions.proxy_enabled = true; uint16_t sz = CString::fromString(proxyAddr, (unsigned char*)toxOptions.proxy_address); toxOptions.proxy_address[sz] = 0; toxOptions.proxy_port = proxyPort; } } tox = tox_new(&toxOptions); if (tox == nullptr) { if (enableIPv6) // Fallback to IPv4 { toxOptions.ipv6enabled = false; tox = tox_new(&toxOptions); if (tox == nullptr) { if (toxOptions.proxy_enabled) { //QMessageBox::critical(Widget::getInstance(), tr("Proxy failure", "popup title"), //tr("toxcore failed to start with your proxy settings. qTox cannot run; please modify your " //"settings and restart.", "popup text")); qCritical() << "Core: bad proxy! no toxcore!"; emit badProxy(); } else { qCritical() << "Tox core failed to start"; emit failedToStart(); } return; } else qWarning() << "Core failed to start with IPv6, falling back to IPv4. LAN discovery may not work properly."; } else if (toxOptions.proxy_enabled) { emit badProxy(); return; } else { qCritical() << "Tox core failed to start"; emit failedToStart(); return; } } toxav = toxav_new(tox, TOXAV_MAX_CALLS); if (toxav == nullptr) { qCritical() << "Toxav core failed to start"; emit failedToStart(); return; } qsrand(time(nullptr)); if (!loadConfiguration()) { emit failedToStart(); tox_kill(tox); tox = nullptr; return; } tox_callback_friend_request(tox, onFriendRequest, this); tox_callback_friend_message(tox, onFriendMessage, this); tox_callback_friend_action(tox, onAction, this); tox_callback_name_change(tox, onFriendNameChange, this); tox_callback_typing_change(tox, onFriendTypingChange, this); tox_callback_status_message(tox, onStatusMessageChanged, this); tox_callback_user_status(tox, onUserStatusChanged, this); tox_callback_connection_status(tox, onConnectionStatusChanged, this); tox_callback_group_invite(tox, onGroupInvite, this); tox_callback_group_message(tox, onGroupMessage, this); tox_callback_group_namelist_change(tox, onGroupNamelistChange, this); tox_callback_file_send_request(tox, onFileSendRequestCallback, this); tox_callback_file_control(tox, onFileControlCallback, this); tox_callback_file_data(tox, onFileDataCallback, this); tox_callback_avatar_info(tox, onAvatarInfoCallback, this); tox_callback_avatar_data(tox, onAvatarDataCallback, this); toxav_register_callstate_callback(toxav, onAvInvite, av_OnInvite, this); toxav_register_callstate_callback(toxav, onAvStart, av_OnStart, this); toxav_register_callstate_callback(toxav, onAvCancel, av_OnCancel, this); toxav_register_callstate_callback(toxav, onAvReject, av_OnReject, this); toxav_register_callstate_callback(toxav, onAvEnd, av_OnEnd, this); toxav_register_callstate_callback(toxav, onAvRinging, av_OnRinging, this); toxav_register_callstate_callback(toxav, onAvStarting, av_OnStarting, this); toxav_register_callstate_callback(toxav, onAvEnding, av_OnEnding, this); toxav_register_callstate_callback(toxav, onAvMediaChange, av_OnMediaChange, this); toxav_register_callstate_callback(toxav, onAvRequestTimeout, av_OnRequestTimeout, this); toxav_register_callstate_callback(toxav, onAvPeerTimeout, av_OnPeerTimeout, this); toxav_register_audio_recv_callback(toxav, playCallAudio, this); toxav_register_video_recv_callback(toxav, playCallVideo, this); uint8_t friendAddress[TOX_FRIEND_ADDRESS_SIZE]; tox_get_address(tox, friendAddress); emit friendAddressGenerated(CFriendAddress::toString(friendAddress)); QPixmap pic = Settings::getInstance().getSavedAvatar(getSelfId().toString()); if (!pic.isNull() && !pic.size().isEmpty()) { QByteArray data; QBuffer buffer(&data); buffer.open(QIODevice::WriteOnly); pic.save(&buffer, "PNG"); buffer.close(); setAvatar(TOX_AVATAR_FORMAT_PNG, data); } else qDebug() << "Core: Error loading self avatar"; process(); // starts its own timer }
ToxID Core::getSelfId() { uint8_t friendAddress[TOX_FRIEND_ADDRESS_SIZE]; tox_get_address(tox, friendAddress); return ToxID::fromString(CFriendAddress::toString(friendAddress)); }
void tox_thread(void *UNUSED(args)) { Tox *tox; ToxAv *av; uint8_t id[TOX_FRIEND_ADDRESS_SIZE]; TOP:; debug("new tox object ipv6: %u no_udp: %u proxy: %u %s %u\n", options.ipv6enabled, options.udp_disabled, options.proxy_enabled, options.proxy_address, options.proxy_port); if((tox = tox_new(&options)) == NULL) { debug("trying without proxy\n"); if(!options.proxy_enabled || (options.proxy_enabled = 0, (tox = tox_new(&options)) == NULL)) { debug("trying without ipv6\n"); if(!options.ipv6enabled || (options.ipv6enabled = 0, (tox = tox_new(&options)) == NULL)) { debug("tox_new() failed\n"); exit(1); } dropdown_ipv6.selected = dropdown_ipv6.over = 1; } dropdown_proxy.selected = dropdown_proxy.over = 0; } if(!load_save(tox)) { debug("No save file, using defaults\n"); load_defaults(tox); } edit_setstr(&edit_name, self.name, self.name_length); edit_setstr(&edit_status, self.statusmsg, self.statusmsg_length); tox_get_address(tox, id); id_to_string(self.id, id); debug("Tox ID: %.*s\n", (int)sizeof(self.id), self.id); set_callbacks(tox); do_bootstrap(tox); av = toxav_new(tox, MAX_CALLS); set_av_callbacks(av); global_av = av; tox_thread_init = 1; thread(audio_thread, av); thread(video_thread, av); thread(toxav_thread, av); _Bool connected = 0, reconfig; uint64_t last_save = get_time(), time; while(1) { tox_do(tox); if(tox_isconnected(tox) != connected) { connected = !connected; postmessage(DHT_CONNECTED, connected, 0, NULL); debug("Connected to DHT: %u\n", connected); } time = get_time(); if(time - last_save >= (uint64_t)10 * 1000 * 1000 * 1000) { last_save = time; if(!connected) { do_bootstrap(tox); } write_save(tox); } if(tox_thread_msg) { TOX_MSG *msg = &tox_msg; if(!msg->msg) { reconfig = msg->param1; tox_thread_msg = 0; break; } tox_thread_message(tox, av, time, msg->msg, msg->param1, msg->param2, msg->data); tox_thread_msg = 0; } utox_thread_work_for_transfers(tox, time); utox_thread_work_for_typing_notifications(tox, time); uint32_t interval = tox_do_interval(tox); yieldcpu((interval > 20) ? 20 : interval); } write_save(tox); while(audio_thread_init || video_thread_init || toxav_thread_init) { yieldcpu(1); } debug("av_thread exit, tox thread ending\n"); toxav_kill(av); tox_kill(tox); if(reconfig) { goto TOP; } tox_thread_init = 0; }