void __cdecl SessionThread(LPVOID param) { CSametimeProto* proto = (CSametimeProto*)param; HANDLE hNetlibUser = proto->m_hNetlibUser; proto->debugLog(_T("SessionThread() start")); continue_connect = true; //setup NETLIBOPENCONNECTION conn_data = { 0 }; conn_data.cbSize = sizeof(NETLIBOPENCONNECTION); conn_data.flags = NLOCF_V2; conn_data.szHost = proto->options.server_name; conn_data.wPort = proto->options.port; conn_data.timeout = 20; conn_data.waitcallback = waitcallback; proto->BroadcastNewStatus(ID_STATUS_CONNECTING); proto->server_connection = (HANDLE)CallService(MS_NETLIB_OPENCONNECTION, (WPARAM)hNetlibUser, (LPARAM)&conn_data); if (!proto->server_connection) { proto->BroadcastNewStatus(ID_STATUS_OFFLINE); if (continue_connect) { // real timeout - not user cancelled proto->showPopup(TranslateT("No server connection!"), SAMETIME_POPUP_ERROR); } proto->debugLog(_T("SessionThread() end, no server_connection, continue_connect=[%d]"), continue_connect); return; } mwSessionHandler handler = { 0 }; handler.clear = SessionClear; handler.io_write = SessionWrite; handler.io_close = SessionClose; handler.on_stateChange = SessionStateChange; handler.on_admin = SessionAdmin; handler.on_announce = SessionAnnounce; handler.on_setPrivacyInfo = SessionSetPrivacyInfo; handler.on_setUserStatus = SessionSetUserStatus; EnterCriticalSection(&proto->session_cs); proto->session = mwSession_new(&handler); proto->InitMeanwhileServices(); mwSession_start(proto->session); LeaveCriticalSection(&proto->session_cs); mir_forkthread(KeepAliveThread, (void*)proto); unsigned char* recv_buffer = (unsigned char*)mir_alloc(1024 * 32); int bytes; //while(session && server_connection && mwSession_getState(session) != mwSession_STOPPED) { while (proto->server_connection) {// && session) {// && !mwSession_isStopped(session)) { // break on error bytes = Netlib_Recv(proto->server_connection, (char *)recv_buffer, 1024 * 32, 0); proto->debugLog(_T("SessionThread() Netlib_Recv'ed bytes=[%d]"), bytes); if (bytes == 0) { break; } else if (bytes == SOCKET_ERROR) { // this is normal - e.g. socket closed due to log off, during blocking read above break; } else { EnterCriticalSection(&proto->session_cs); mwSession_recv(proto->session, recv_buffer, bytes); LeaveCriticalSection(&proto->session_cs); } } mir_free(recv_buffer); EnterCriticalSection(&proto->session_cs); proto->DeinitMeanwhileServices(); mwSession* old_session = proto->session; proto->session = 0; // kills keepalive thread, if awake mwSession_free(old_session); LeaveCriticalSection(&proto->session_cs); proto->BroadcastNewStatus(ID_STATUS_OFFLINE); proto->SetAllOffline(); proto->first_online = true; proto->debugLog(_T("SessionThread() end")); return; }
MeanwhileSession::MeanwhileSession(MeanwhileAccount *acc) : session(0), state(mwSession_STOPPED), account(acc), socket(0) { HERE; /* set up main session hander */ memset(&sessionHandler, 0, sizeof(sessionHandler)); set_session_handler(io_write, IOWrite); set_session_handler(io_close, IOClose); set_session_handler(on_stateChange, StateChange); set_session_handler(on_setPrivacyInfo, SetPrivacyInfo); set_session_handler(on_setUserStatus, SetUserStatus); set_session_handler(on_admin, Admin); set_session_handler(on_announce, Announce); set_session_handler(clear, Clear); session = mwSession_new(&sessionHandler); mwSession_setClientData(session, this, 0L); /* set up the aware service */ memset(&awareHandler, 0, sizeof(awareHandler)); set_aware_handler(on_attrib, Attrib); awareService = mwServiceAware_new(session, &awareHandler); mwSession_addService(session, (struct mwService *)awareService); /* create an aware list */ memset(&awareListHandler, 0, sizeof(awareListHandler)); set_aware_list_handler(on_aware, Aware); set_aware_list_handler(on_attrib, Attrib); awareList = mwAwareList_new(awareService, &awareListHandler); mwAwareList_setClientData(awareList, this, 0L); /* set up an im service */ memset(&imHandler, 0, sizeof(imHandler)); set_im_handler(conversation_opened, ConvOpened); set_im_handler(conversation_closed, ConvClosed); set_im_handler(conversation_recv, ConvReceived); imHandler.place_invite = 0L; imHandler.clear = 0L; imService = mwServiceIm_new(session, &imHandler); mwService_setClientData((struct mwService *)imService, this, 0L); mwSession_addService(session, (struct mwService *) imService); /* add resolve service */ resolveService = mwServiceResolve_new(session); mwService_setClientData((struct mwService *)resolveService, this, 0L); mwSession_addService(session, (struct mwService *) resolveService); /* storage service */ storageService = mwServiceStorage_new(session); mwService_setClientData((struct mwService *)storageService, this, 0L); mwSession_addService(session, (struct mwService *) storageService); #if 0 /* conference service setup - just declines invites for now. */ memset(&conf_handler, 0, sizeof(conf_handler)); conf_handler.on_invited = _conference_invite; srvc_conf = mwServiceConference_new(session, &conf_handler); mwService_setClientData((struct mwService *)srvc_conf, this, 0L); mwSession_addService(session, (struct mwService *) srvc_conf); #endif /* add a necessary cipher */ mwSession_addCipher(session, mwCipher_new_RC2_40(session)); mwSession_addCipher(session, mwCipher_new_RC2_128(session)); }