void GaduProtocol::sendStatusToServer() { if (!isConnected() && !isDisconnecting()) return; if (!GaduSession) return; // some services have per-status configuration configureServices(); Status newStatus = status(); int friends = account().privateStatus() ? GG_STATUS_FRIENDS_MASK : 0; int type = GaduProtocolHelper::gaduStatusFromStatus(newStatus); bool hasDescription = !newStatus.description().isEmpty(); setStatusFlags(); m_lastSentStatus = newStatus; auto writableSessionToken = Connection->writableSessionToken(); if (hasDescription) gg_change_status_descr( writableSessionToken.rawSession(), type | friends, newStatus.description().toUtf8().constData()); else gg_change_status(writableSessionToken.rawSession(), type | friends); account().accountContact().setCurrentStatus(status()); }
int GaduSession::changeStatus( int status, bool forFriends ) { kdDebug(14101)<<"## Changing to "<<status<<endl; if ( isConnected() ) { return gg_change_status( session_, status | ( forFriends ? GG_STATUS_FRIENDS_MASK : 0) ); } else { emit error( i18n("Not Connected"), i18n("You have to be connected to the server to change your status.") ); } return 1; }
int GGPROTO::refreshstatus(int status) { if (status == ID_STATUS_OFFLINE) { disconnect(); return TRUE; } if (!isonline()) { DWORD exitCode = 0; GetExitCodeThread(pth_sess.hThread, &exitCode); if (exitCode == STILL_ACTIVE) return TRUE; #ifdef DEBUGMODE debugLogA("refreshstatus(): Waiting pth_sess thread. Going to connect..."); #endif threadwait(&pth_sess); #ifdef DEBUGMODE debugLogA("refreshstatus(): Waiting pth_sess thread - OK"); debugLogA("refreshstatus(): ForkThreadEx 21 GGPROTO::mainthread"); #endif pth_sess.hThread = ForkThreadEx(&GGPROTO::mainthread, NULL, &pth_sess.dwThreadId); } else { TCHAR *szMsg = NULL; // Select proper msg gg_EnterCriticalSection(&modemsg_mutex, "refreshstatus", 69, "modemsg_mutex", 1); szMsg = getstatusmsg(status); gg_LeaveCriticalSection(&modemsg_mutex, "refreshstatus", 69, 1, "modemsg_mutex", 1); T2Utf szMsg_utf8(szMsg); if (szMsg_utf8) { debugLogA("refreshstatus(): Setting status and away message."); gg_EnterCriticalSection(&sess_mutex, "refreshstatus", 70, "sess_mutex", 1); gg_change_status_descr(sess, status_m2gg(status, szMsg_utf8 != NULL), szMsg_utf8); gg_LeaveCriticalSection(&sess_mutex, "refreshstatus", 70, 1, "sess_mutex", 1); } else { debugLogA("refreshstatus(): Setting just status."); gg_EnterCriticalSection(&sess_mutex, "refreshstatus", 71, "sess_mutex", 1); gg_change_status(sess, status_m2gg(status, 0)); gg_LeaveCriticalSection(&sess_mutex, "refreshstatus", 71, 1, "sess_mutex", 1); } // Change status of the contact with our own UIN (if got yourself added to the contact list) changecontactstatus( getDword(GG_KEY_UIN, 0), status_m2gg(status, szMsg != NULL), szMsg, 0, 0, 0, 0); broadcastnewstatus(status); } return TRUE; }
int session_send_status(Session *s){ int r; g_assert(s!=NULL); if (s->ggs==NULL) return -1; r=session_make_status(s, s->connected); if (r==0) return 0; if (s->gg_status_descr!=NULL){ debug(L_("Changing gg status to 0x%X (%s)"),s->gg_status,s->gg_status_descr); gg_change_status_descr(s->ggs,s->gg_status,s->gg_status_descr); }else{ debug(L_("Changing gg status to 0x%X"),s->gg_status); gg_change_status(s->ggs,s->gg_status); } if (r==-1) return -1; return 0; }
gint gnomegadu_protocol_change_status(GnomeGaduProtocolStatus status, gchar *descr) { gboolean set_descr = FALSE; gchar *descr_windows1250 = NULL; gint ret = -1; if (!gnomegadu_protocol_check_connected()) return FALSE; if (descr && g_utf8_strlen(descr,-1) > 0) { set_descr = TRUE; descr_windows1250 = g_convert (descr, strlen (descr), "WINDOWS-1250", "UTF-8", NULL, NULL, NULL); } if (set_descr) ret = gg_change_status_descr(gnomegadu_gadugadu_session,gnomegadu_gadugadu_to_protocol_status (status,set_descr ? TRUE : FALSE),descr_windows1250); else ret = gg_change_status(gnomegadu_gadugadu_session,gnomegadu_gadugadu_to_protocol_status (status, FALSE)); g_free(descr_windows1250); return ret; }
int main(int argc, char **argv) { struct gg_session *gs; struct gg_login_params glp; struct gg_dcc7 *gd = NULL; time_t ping = 0, last = 0; int once = 0; if (argc != 2) usage(argv[0]); /* strtol() ? */ if (!(argv[1][0] >= '0' && argv[1][0] <= '9')) usage(argv[0]); if (atoi(argv[1]) >= TEST_MODE_LAST) usage(argv[0]); test_mode = atoi(argv[1]); signal(SIGPIPE, SIG_IGN); gg_debug_file = stdout; gg_debug_level = ~0; if (config_read() == -1 || config_peer == 0) { perror("config"); exit(1); } memset(&glp, 0, sizeof(glp)); glp.uin = config_uin; glp.password = config_password; glp.async = 1; glp.status = GG_STATUS_AVAIL; #if 0 glp.client_addr = config_ip; glp.client_port = config_port; #endif glp.protocol_version = 0x2a; glp.has_audio = 1; glp.last_sysmsg = -1; gg_dcc_ip = config_ip; debug("Connecting...\n"); if (!(gs = gg_login(&glp))) { perror("gg_login"); exit(1); } for (;;) { fd_set rds, wds; struct timeval tv; time_t now; int res, maxfd = -1; FD_ZERO(&rds); FD_ZERO(&wds); tv.tv_sec = 1; tv.tv_usec = 0; maxfd = gs->fd; if ((gs->check & GG_CHECK_READ)) FD_SET(gs->fd, &rds); if ((gs->check & GG_CHECK_WRITE)) FD_SET(gs->fd, &wds); if (gd && gd->fd != -1) { if (gd->fd > maxfd) maxfd = gd->fd; if ((gd->check & GG_CHECK_READ)) FD_SET(gd->fd, &rds); if ((gd->check & GG_CHECK_WRITE)) FD_SET(gd->fd, &wds); } if (voice_fd != -1) { FD_SET(voice_fd, &rds); if (voice_fd > maxfd) maxfd = voice_fd; } if ((res = select(maxfd + 1, &rds, &wds, NULL, &tv)) == -1) { if (errno == EINTR) continue; perror("select"); exit(1); } now = time(NULL); if (last != now) { if (gs->timeout != -1 && gs->timeout-- == 0 && !gs->soft_timeout) { debug("Timeout\n"); exit(1); } /* vvvv XXX */ if (gd && gd->timeout && gd->timeout != -1 && gd->timeout-- == 0 && !gd->soft_timeout) { debug("Timeout\n"); exit(1); } last = now; } if (gs->state == GG_STATE_CONNECTED && ping && now - ping > 60) { ping = now; gg_ping(gs); } if (FD_ISSET(gs->fd, &rds) || FD_ISSET(gs->fd, &wds) || (gs->timeout == 0 && gs->soft_timeout)) { struct gg_event *ge; uin_t uin; int status; if (!(ge = gg_watch_fd(gs))) { debug("Connection broken\n"); exit(1); } switch (ge->type) { case GG_EVENT_CONN_SUCCESS: debug("Connected\n"); connected = 1; gg_notify(gs, &config_peer, 1); ping = time(NULL); break; case GG_EVENT_CONN_FAILED: debug("Connection failed\n"); exit(1); case GG_EVENT_NONE: break; case GG_EVENT_MSG: debug("Message from %d: %s\n", ge->event.msg.sender, ge->event.msg.message); break; case GG_EVENT_DISCONNECT: debug("Forced to disconnect\n"); exit(1); case GG_EVENT_NOTIFY60: uin = ge->event.notify60[0].uin; status = ge->event.notify60[0].status; /* fall-through */ case GG_EVENT_STATUS60: if (ge->type == GG_EVENT_STATUS60) { uin = ge->event.status60.uin; status = ge->event.status60.status; } if (!once && uin == config_peer && (GG_S_A(status) || GG_S_B(status)) && test_mode == TEST_MODE_SEND) { debug("Sending voice request...\n"); if (voice_open_ext("/dev/dsp", 8000, 16, 2, EKG_CODEC_GSM) == -1) { printf("voice_open_ext('/dev/dsp', " "8000, 16, 2, CODEC_GSM) failed\n"); exit(1); } printf("+OK\n"); gd = gg_dcc7_voice_chat(gs, config_peer, 0x00); if (!gd) { perror("gg_dcc7_voice_chat"); exit(1); } once = 1; } gg_change_status(gs, GG_STATUS_AVAIL); /* XXX, libgadu sobie nie radzi */ break; case GG_EVENT_DCC7_NEW: debug("Incoming direct connection\n"); if (test_mode == TEST_MODE_RECEIVE) { gd = ge->event.dcc7_new; if (voice_open_ext("/dev/dsp", 8000, 16, 2, EKG_CODEC_GSM) == -1) { printf("voice_open_ext('/dev/dsp', " "8000, 16, 2, CODEC_GSM) failed\n"); exit(1); } printf("+OK\n"); gg_dcc7_accept_voice(gd, 0x00); } break; case GG_EVENT_DCC7_ERROR: debug("Direct connection error\n"); exit(1); case GG_EVENT_DCC7_ACCEPT: debug("Accepted\n"); break; case GG_EVENT_DCC7_REJECT: debug("Rejected\n"); exit(1); default: debug("Unsupported event %d\n", ge->type); break; } gg_event_free(ge); } if (gd && gd->fd != -1 && (FD_ISSET(gd->fd, &rds) || FD_ISSET(gd->fd, &wds) || (gd->timeout == 0 && gd->soft_timeout))) { struct gg_event *ge; if (!(ge = gg_dcc7_watch_fd(gd))) { debug("Direct connection broken\n"); exit(1); } switch (ge->type) { case GG_EVENT_DCC7_ERROR: debug("Direct connection error\n"); exit(1); case GG_EVENT_DCC7_CONNECTED: debug("Direct connection established\n"); break; case GG_EVENT_DCC7_DONE: debug("Finished"); gg_event_free(ge); gg_dcc7_free(gd); gg_free_session(gs); config_free(); exit(1); case GG_EVENT_DCC7_VOICE_DATA: gg_debug(GG_DEBUG_MISC, "## GG_EVENT_DCC7_VOICE_DATA [%u]\n", ge->event.dcc7_voice_data.length); printf("## GG_EVENT_DCC7_VOICE_DATA [%u]\n", ge->event.dcc7_voice_data.length); if (voice_fd == -1) { printf("voice_fd == -1\n"); exit(1); } if (ge->event.dcc7_voice_data.length == GG_DCC7_VOICE_FRAME_GSM_LENGTH) voice_play(ge->event.dcc7_voice_data.data, ge->event.dcc7_voice_data.length, EKG_CODEC_GSM); else if (ge->event.dcc7_voice_data.length == GG_DCC7_VOICE_FRAME_SPEEX_LENGTH) voice_play(ge->event.dcc7_voice_data.data, ge->event.dcc7_voice_data.length, EKG_CODEC_SPEEX); else if (ge->event.dcc7_voice_data.length == GG_DCC7_VOICE_FRAME_MELP_LENGTH) voice_play(ge->event.dcc7_voice_data.data, ge->event.dcc7_voice_data.length, EKG_CODEC_MELP); break; case GG_EVENT_NONE: break; default: debug("Unsupported event %d\n", ge->type); break; } gg_event_free(ge); } if (voice_fd != -1 && FD_ISSET(voice_fd, &rds)) { char buf[GG_DCC_VOICE_FRAME_LENGTH]; /* dłuższy z buforów */ int length = GG_DCC_VOICE_FRAME_LENGTH; if (gd) { if (gd->state == GG_STATE_READING_VOICE_DATA) { /* XXX, implementowac speex */ length = GG_DCC7_VOICE_FRAME_GSM_LENGTH; voice_record(buf, length, EKG_CODEC_GSM); if (1) gg_dcc7_voice_send(gd, buf, length); else { /* ten pakiet mamy wysylac co 1s */ gg_dcc7_voice_mic_off(gd); } } else voice_record(buf, length, EKG_CODEC_NONE); } else voice_record(buf, length, EKG_CODEC_NONE); } } if (gg_debug_file != stdout) /* w sumie stdout, tez moglibysmy zamknac.. czemu nie. */ fclose(gg_debug_file); return 0; }
int main(int argc, char **argv) { struct gg_login_params glp; struct gg_session *gs; time_t last = 0; int hide_sysmsg = 0; int ch; gg_debug_level = 255; memset(&glp, 0, sizeof(glp)); glp.async = 1; config_read(); while ((ch = getopt(argc, argv, "DShHLs:p:l:y")) != -1) { switch (ch) { case 'D': gg_debug_level = 0; break; case 'S': glp.async = 0; break; case 'L': glp.tls = 1; break; case 's': free(config_server); config_server = strdup(optarg); break; case 'p': free(config_proxy); config_proxy = strdup(optarg); break; case 'H': gg_proxy_http_only = 1; break; case 'l': glp.last_sysmsg = atoi(optarg); break; case 'h': usage(argv[0]); return 0; case 'y': hide_sysmsg = 1; break; default: usage(argv[0]); return 1; } } if (argc - optind >= 1) { config_uin = atoi(argv[optind]); optind++; if (argc - optind >= 1) { free(config_password); config_password = strdup(argv[optind]); } } if (config_uin == 0 || config_password == NULL) { usage(argv[0]); return 1; } if (config_server != NULL) { char *host; int port; parse_address(config_server, &host, &port); glp.server_addr = inet_addr(host); glp.server_port = port; free(host); } if (config_proxy != NULL) { char *host; int port; parse_address(optarg, &host, &port); gg_proxy_enabled = 1; gg_proxy_host = host; gg_proxy_port = port; free(config_proxy); } glp.uin = config_uin; glp.password = config_password; signal(SIGINT, sigint); gs = gg_login(&glp); if (gs == NULL) { perror("gg_login"); free(gg_proxy_host); return 1; } for (;;) { struct timeval tv; fd_set rd, wd; int ret, fd, check; time_t now; if (disconnect_flag) { gg_change_status(gs, GG_STATUS_NOT_AVAIL); disconnect_flag = 0; } FD_ZERO(&rd); FD_ZERO(&wd); fd = gs->fd; check = gs->check; if ((check & GG_CHECK_READ)) FD_SET(fd, &rd); if ((check & GG_CHECK_WRITE)) FD_SET(fd, &wd); tv.tv_sec = 1; tv.tv_usec = 0; ret = select(fd + 1, &rd, &wd, NULL, &tv); if (ret == -1) { if (errno == EINTR) continue; perror("select"); break; } now = time(NULL); if (now != last) { if (gs->timeout != -1 && gs->timeout-- == 0 && !gs->soft_timeout) { printf("Timeout!\n"); break; } } if (gs != NULL && (FD_ISSET(fd, &rd) || FD_ISSET(fd, &wd) || (gs->timeout == 0 && gs->soft_timeout))) { struct gg_event *ge; ge = gg_watch_fd(gs); if (ge == NULL) { printf("Connection broken!\n"); break; } if (ge->type == GG_EVENT_CONN_SUCCESS) { printf("Connected (press Ctrl-C to disconnect)\n"); gg_notify(gs, NULL, 0); } if (ge->type == GG_EVENT_CONN_FAILED) { printf("Connection failed!\n"); gg_event_free(ge); break; } if (ge->type == GG_EVENT_DISCONNECT_ACK) { printf("Connection closed\n"); gg_event_free(ge); break; } if (ge->type == GG_EVENT_MSG) { if (ge->event.msg.sender != 0 || !hide_sysmsg) printf("Received message from %d:\n- plain text: %s\n- html: %s\n", ge->event.msg.sender, ge->event.msg.message, ge->event.msg.xhtml_message); } gg_event_free(ge); } } free(gg_proxy_host); gg_free_session(gs); config_free(); return 0; }