PageRenderTime 110ms CodeModel.GetById 12ms app.highlight 85ms RepoModel.GetById 1ms app.codeStats 1ms

/indra/newview/llvoicevivox.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 1035 lines | 643 code | 209 blank | 183 comment | 0 complexity | 6c9b15d3162a0a4c00200b6f913f8abf MD5 | raw file
   1/** 
   2 * @file llvoicevivox.h
   3 * @brief Declaration of LLDiamondwareVoiceClient class which is the interface to the voice client process.
   4 *
   5 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
   6 * Second Life Viewer Source Code
   7 * Copyright (C) 2010, Linden Research, Inc.
   8 * 
   9 * This library is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU Lesser General Public
  11 * License as published by the Free Software Foundation;
  12 * version 2.1 of the License only.
  13 * 
  14 * This library is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17 * Lesser General Public License for more details.
  18 * 
  19 * You should have received a copy of the GNU Lesser General Public
  20 * License along with this library; if not, write to the Free Software
  21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  22 * 
  23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  24 * $/LicenseInfo$
  25 */
  26#ifndef LL_VOICE_VIVOX_H
  27#define LL_VOICE_VIVOX_H
  28
  29class LLVOAvatar;
  30class LLVivoxProtocolParser;
  31
  32#include "lliopipe.h"
  33#include "llpumpio.h"
  34#include "llchainio.h"
  35#include "lliosocket.h"
  36#include "v3math.h"
  37#include "llframetimer.h"
  38#include "llviewerregion.h"
  39#include "llcallingcard.h"   // for LLFriendObserver
  40
  41#ifdef LL_STANDALONE
  42# include "expat.h"
  43#else
  44# include "expat/expat.h"
  45#endif
  46#include "llvoiceclient.h"
  47
  48class LLAvatarName;
  49class LLVivoxVoiceAccountProvisionResponder;
  50class LLVivoxVoiceClientMuteListObserver;
  51class LLVivoxVoiceClientFriendsObserver;	
  52
  53
  54class LLVivoxVoiceClient :	public LLSingleton<LLVivoxVoiceClient>,
  55							virtual public LLVoiceModuleInterface,
  56							virtual public LLVoiceEffectInterface
  57{
  58	LOG_CLASS(LLVivoxVoiceClient);
  59public:
  60	LLVivoxVoiceClient();	
  61	virtual ~LLVivoxVoiceClient();
  62	
  63	
  64	/// @name LLVoiceModuleInterface virtual implementations
  65	///  @see LLVoiceModuleInterface
  66	//@{
  67	virtual void init(LLPumpIO *pump);	// Call this once at application startup (creates connector)
  68	virtual void terminate();	// Call this to clean up during shutdown
  69	
  70	virtual const LLVoiceVersionInfo& getVersion();
  71	
  72	virtual void updateSettings(); // call after loading settings and whenever they change
  73
  74	// Returns true if vivox has successfully logged in and is not in error state	
  75	virtual bool isVoiceWorking() const;
  76
  77	/////////////////////
  78	/// @name Tuning
  79	//@{
  80	virtual void tuningStart();
  81	virtual void tuningStop();
  82	virtual bool inTuningMode();
  83	
  84	virtual void tuningSetMicVolume(float volume);
  85	virtual void tuningSetSpeakerVolume(float volume);
  86	virtual float tuningGetEnergy(void);
  87	//@}
  88	
  89	/////////////////////
  90	/// @name Devices
  91	//@{
  92	// This returns true when it's safe to bring up the "device settings" dialog in the prefs.
  93	// i.e. when the daemon is running and connected, and the device lists are populated.
  94	virtual bool deviceSettingsAvailable();
  95	
  96	// Requery the vivox daemon for the current list of input/output devices.
  97	// If you pass true for clearCurrentList, deviceSettingsAvailable() will be false until the query has completed
  98	// (use this if you want to know when it's done).
  99	// If you pass false, you'll have no way to know when the query finishes, but the device lists will not appear empty in the interim.
 100	virtual void refreshDeviceLists(bool clearCurrentList = true);
 101	
 102	virtual void setCaptureDevice(const std::string& name);
 103	virtual void setRenderDevice(const std::string& name);
 104	
 105	virtual LLVoiceDeviceList& getCaptureDevices();
 106	virtual LLVoiceDeviceList& getRenderDevices();
 107	//@}	
 108	
 109	virtual void getParticipantList(std::set<LLUUID> &participants);
 110	virtual bool isParticipant(const LLUUID& speaker_id);
 111
 112	// Send a text message to the specified user, initiating the session if necessary.
 113	virtual BOOL sendTextMessage(const LLUUID& participant_id, const std::string& message);
 114	
 115	// close any existing text IM session with the specified user
 116	virtual void endUserIMSession(const LLUUID &uuid);
 117	
 118	// Returns true if calling back the session URI after the session has closed is possible.
 119	// Currently this will be false only for PSTN P2P calls.		
 120	// NOTE: this will return true if the session can't be found. 
 121	virtual BOOL isSessionCallBackPossible(const LLUUID &session_id);
 122	
 123	// Returns true if the session can accepte text IM's.
 124	// Currently this will be false only for PSTN P2P calls.
 125	// NOTE: this will return true if the session can't be found. 
 126	virtual BOOL isSessionTextIMPossible(const LLUUID &session_id);
 127	
 128	
 129	////////////////////////////
 130	/// @name Channel stuff
 131	//@{
 132	// returns true iff the user is currently in a proximal (local spatial) channel.
 133	// Note that gestures should only fire if this returns true.
 134	virtual bool inProximalChannel();
 135	
 136	virtual void setNonSpatialChannel(const std::string &uri,
 137									  const std::string &credentials);
 138	
 139	virtual void setSpatialChannel(const std::string &uri,
 140								   const std::string &credentials);
 141	
 142	virtual void leaveNonSpatialChannel();
 143	
 144	virtual void leaveChannel(void);	
 145	
 146	// Returns the URI of the current channel, or an empty string if not currently in a channel.
 147	// NOTE that it will return an empty string if it's in the process of joining a channel.
 148	virtual std::string getCurrentChannel();
 149	//@}
 150	
 151	
 152	//////////////////////////
 153	/// @name invitations
 154	//@{
 155	// start a voice channel with the specified user
 156	virtual void callUser(const LLUUID &uuid);	
 157	virtual bool isValidChannel(std::string &channelHandle);
 158	virtual bool answerInvite(std::string &channelHandle);
 159	virtual void declineInvite(std::string &channelHandle);
 160	//@}
 161	
 162	/////////////////////////
 163	/// @name Volume/gain
 164	//@{
 165	virtual void setVoiceVolume(F32 volume);
 166	virtual void setMicGain(F32 volume);
 167	//@}
 168	
 169	/////////////////////////
 170	/// @name enable disable voice and features
 171	//@{
 172	virtual bool voiceEnabled();
 173	virtual void setVoiceEnabled(bool enabled);
 174	virtual BOOL lipSyncEnabled();	
 175	virtual void setLipSyncEnabled(BOOL enabled);
 176	virtual void setMuteMic(bool muted);		// Set the mute state of the local mic.
 177	//@}
 178		
 179	//////////////////////////
 180	/// @name nearby speaker accessors
 181	//@{
 182	virtual BOOL getVoiceEnabled(const LLUUID& id);		// true if we've received data for this avatar
 183	virtual std::string getDisplayName(const LLUUID& id);
 184	virtual BOOL isOnlineSIP(const LLUUID &id);
 185	virtual BOOL isParticipantAvatar(const LLUUID &id);
 186	virtual BOOL getIsSpeaking(const LLUUID& id);
 187	virtual BOOL getIsModeratorMuted(const LLUUID& id);
 188	virtual F32 getCurrentPower(const LLUUID& id);		// "power" is related to "amplitude" in a defined way.  I'm just not sure what the formula is...
 189	virtual BOOL getOnMuteList(const LLUUID& id);
 190	virtual F32 getUserVolume(const LLUUID& id);
 191	virtual void setUserVolume(const LLUUID& id, F32 volume); // set's volume for specified agent, from 0-1 (where .5 is nominal)	
 192	//@}
 193	
 194	// authorize the user
 195	virtual void userAuthorized(const std::string& user_id,
 196								const LLUUID &agentID);
 197	
 198	//////////////////////////////
 199	/// @name Status notification
 200	//@{
 201	virtual void addObserver(LLVoiceClientStatusObserver* observer);
 202	virtual void removeObserver(LLVoiceClientStatusObserver* observer);
 203	virtual void addObserver(LLFriendObserver* observer);
 204	virtual void removeObserver(LLFriendObserver* observer);		
 205	virtual void addObserver(LLVoiceClientParticipantObserver* observer);
 206	virtual void removeObserver(LLVoiceClientParticipantObserver* observer);
 207	//@}
 208	
 209	virtual std::string sipURIFromID(const LLUUID &id);
 210	//@}
 211
 212	/// @name LLVoiceEffectInterface virtual implementations
 213	///  @see LLVoiceEffectInterface
 214	//@{
 215
 216	//////////////////////////
 217	/// @name Accessors
 218	//@{
 219	virtual bool setVoiceEffect(const LLUUID& id);
 220	virtual const LLUUID getVoiceEffect();
 221	virtual LLSD getVoiceEffectProperties(const LLUUID& id);
 222
 223	virtual void refreshVoiceEffectLists(bool clear_lists);
 224	virtual const voice_effect_list_t& getVoiceEffectList() const;
 225	virtual const voice_effect_list_t& getVoiceEffectTemplateList() const;
 226	//@}
 227
 228	//////////////////////////////
 229	/// @name Status notification
 230	//@{
 231	virtual void addObserver(LLVoiceEffectObserver* observer);
 232	virtual void removeObserver(LLVoiceEffectObserver* observer);
 233	//@}
 234
 235	//////////////////////////////
 236	/// @name Effect preview buffer
 237	//@{
 238	virtual void enablePreviewBuffer(bool enable);
 239	virtual void recordPreviewBuffer();
 240	virtual void playPreviewBuffer(const LLUUID& effect_id = LLUUID::null);
 241	virtual void stopPreviewBuffer();
 242
 243	virtual bool isPreviewRecording();
 244	virtual bool isPreviewPlaying();
 245	//@}
 246
 247	//@}
 248
 249
 250protected:
 251	//////////////////////
 252	// Vivox Specific definitions	
 253	
 254	friend class LLVivoxVoiceAccountProvisionResponder;
 255	friend class LLVivoxVoiceClientMuteListObserver;
 256	friend class LLVivoxVoiceClientFriendsObserver;	
 257	
 258	enum streamState
 259	{
 260		streamStateUnknown = 0,
 261		streamStateIdle = 1,
 262		streamStateConnected = 2,
 263		streamStateRinging = 3,
 264	};	
 265	struct participantState
 266	{
 267	public:
 268		participantState(const std::string &uri);
 269		
 270	        bool updateMuteState();	// true if mute state has changed
 271		bool isAvatar();
 272		
 273		std::string mURI;
 274		LLUUID mAvatarID;
 275		std::string mAccountName;
 276		std::string mDisplayName;
 277		LLFrameTimer mSpeakingTimeout;
 278		F32	mLastSpokeTimestamp;
 279		F32 mPower;
 280		F32 mVolume;
 281		std::string mGroupID;
 282		int mUserVolume;
 283		bool mPTT;
 284		bool mIsSpeaking;
 285		bool mIsModeratorMuted;
 286		bool mOnMuteList;		// true if this avatar is on the user's mute list (and should be muted)
 287		bool mVolumeSet;		// true if incoming volume messages should not change the volume
 288		bool mVolumeDirty;		// true if this participant needs a volume command sent (either mOnMuteList or mUserVolume has changed)
 289		bool mAvatarIDValid;
 290		bool mIsSelf;
 291	};
 292	
 293	typedef std::map<const std::string, participantState*> participantMap;
 294	typedef std::map<const LLUUID, participantState*> participantUUIDMap;
 295	
 296	struct sessionState
 297	{
 298	public:
 299		sessionState();
 300		~sessionState();
 301		
 302		participantState *addParticipant(const std::string &uri);
 303		// Note: after removeParticipant returns, the participant* that was passed to it will have been deleted.
 304		// Take care not to use the pointer again after that.
 305		void removeParticipant(participantState *participant);
 306		void removeAllParticipants();
 307		
 308		participantState *findParticipant(const std::string &uri);
 309		participantState *findParticipantByID(const LLUUID& id);
 310		
 311		bool isCallBackPossible();
 312		bool isTextIMPossible();
 313		
 314		std::string mHandle;
 315		std::string mGroupHandle;
 316		std::string mSIPURI;
 317		std::string mAlias;
 318		std::string mName;
 319		std::string mAlternateSIPURI;
 320		std::string mHash;			// Channel password
 321		std::string mErrorStatusString;
 322		std::queue<std::string> mTextMsgQueue;
 323		
 324		LLUUID		mIMSessionID;
 325		LLUUID		mCallerID;
 326		int			mErrorStatusCode;
 327		int			mMediaStreamState;
 328		int			mTextStreamState;
 329		bool		mCreateInProgress;	// True if a Session.Create has been sent for this session and no response has been received yet.
 330		bool		mMediaConnectInProgress;	// True if a Session.MediaConnect has been sent for this session and no response has been received yet.
 331		bool		mVoiceInvitePending;	// True if a voice invite is pending for this session (usually waiting on a name lookup)
 332		bool		mTextInvitePending;		// True if a text invite is pending for this session (usually waiting on a name lookup)
 333		bool		mSynthesizedCallerID;	// True if the caller ID is a hash of the SIP URI -- this means we shouldn't do a name lookup.
 334		bool		mIsChannel;	// True for both group and spatial channels (false for p2p, PSTN)
 335		bool		mIsSpatial;	// True for spatial channels
 336		bool		mIsP2P;
 337		bool		mIncoming;
 338		bool		mVoiceEnabled;
 339		bool		mReconnect;	// Whether we should try to reconnect to this session if it's dropped
 340
 341		// Set to true when the volume/mute state of someone in the participant list changes.
 342		// The code will have to walk the list to find the changed participant(s).
 343		bool		mVolumeDirty;
 344		bool		mMuteDirty;
 345
 346		bool		mParticipantsChanged;
 347		participantMap mParticipantsByURI;
 348		participantUUIDMap mParticipantsByUUID;
 349
 350		LLUUID		mVoiceFontID;
 351	};
 352
 353	// internal state for a simple state machine.  This is used to deal with the asynchronous nature of some of the messages.
 354	// Note: if you change this list, please make corresponding changes to LLVivoxVoiceClient::state2string().
 355	enum state
 356	{
 357		stateDisableCleanup,
 358		stateDisabled,				// Voice is turned off.
 359		stateStart,					// Class is initialized, socket is created
 360		stateDaemonLaunched,		// Daemon has been launched
 361		stateConnecting,			// connect() call has been issued
 362		stateConnected,				// connection to the daemon has been made, send some initial setup commands.
 363		stateIdle,					// socket is connected, ready for messaging
 364		stateMicTuningStart,
 365		stateMicTuningRunning,		
 366		stateMicTuningStop,
 367		stateCaptureBufferPaused,
 368		stateCaptureBufferRecStart,
 369		stateCaptureBufferRecording,
 370		stateCaptureBufferPlayStart,
 371		stateCaptureBufferPlaying,
 372		stateConnectorStart,		// connector needs to be started
 373		stateConnectorStarting,		// waiting for connector handle
 374		stateConnectorStarted,		// connector handle received
 375		stateLoginRetry,			// need to retry login (failed due to changing password)
 376		stateLoginRetryWait,		// waiting for retry timer
 377		stateNeedsLogin,			// send login request
 378		stateLoggingIn,				// waiting for account handle
 379		stateLoggedIn,				// account handle received
 380		stateVoiceFontsWait,		// Awaiting the list of voice fonts
 381		stateVoiceFontsReceived,	// List of voice fonts received
 382		stateCreatingSessionGroup,	// Creating the main session group
 383		stateNoChannel,				// Need to join a channel
 384		stateRetrievingParcelVoiceInfo,    // waiting for parcel voice info request to return with spatial credentials
 385		stateJoiningSession,		// waiting for session handle
 386		stateSessionJoined,			// session handle received
 387		stateRunning,				// in session, steady state
 388		stateLeavingSession,		// waiting for terminate session response
 389		stateSessionTerminated,		// waiting for terminate session response
 390		
 391		stateLoggingOut,			// waiting for logout response
 392		stateLoggedOut,				// logout response received
 393		stateConnectorStopping,		// waiting for connector stop
 394		stateConnectorStopped,		// connector stop received
 395		
 396		// We go to this state if the login fails because the account needs to be provisioned.
 397		
 398		// error states.  No way to recover from these yet.
 399		stateConnectorFailed,
 400		stateConnectorFailedWaiting,
 401		stateLoginFailed,
 402		stateLoginFailedWaiting,
 403		stateJoinSessionFailed,
 404		stateJoinSessionFailedWaiting,
 405		
 406		stateJail					// Go here when all else has failed.  Nothing will be retried, we're done.
 407	};
 408	
 409	typedef std::map<std::string, sessionState*> sessionMap;
 410	
 411	
 412	
 413	///////////////////////////////////////////////////////
 414	// Private Member Functions
 415	//////////////////////////////////////////////////////
 416	
 417	//////////////////////////////
 418	/// @name TVC/Server management and communication
 419	//@{
 420	// Call this if the connection to the daemon terminates unexpectedly.  It will attempt to reset everything and relaunch.
 421	void daemonDied();
 422	
 423	// Call this if we're just giving up on voice (can't provision an account, etc.).  It will clean up and go away.
 424	void giveUp();	
 425	
 426	// write to the tvc
 427	bool writeString(const std::string &str);
 428	
 429	void connectorCreate();
 430	void connectorShutdown();	
 431	void closeSocket(void);	
 432	
 433	void requestVoiceAccountProvision(S32 retries = 3);
 434	void login(
 435			   const std::string& account_name,
 436			   const std::string& password,
 437			   const std::string& voice_sip_uri_hostname,
 438			   const std::string& voice_account_server_uri);
 439	void loginSendMessage();
 440	void logout();
 441	void logoutSendMessage();	
 442	
 443	
 444	//@}
 445	
 446	//------------------------------------
 447	// tuning
 448	
 449	void tuningRenderStartSendMessage(const std::string& name, bool loop);
 450	void tuningRenderStopSendMessage();
 451
 452	void tuningCaptureStartSendMessage(int duration);
 453	void tuningCaptureStopSendMessage();
 454
 455	//----------------------------------
 456	// devices
 457	void clearCaptureDevices();
 458	void addCaptureDevice(const std::string& name);
 459	void clearRenderDevices();
 460	void addRenderDevice(const std::string& name);	
 461	void buildSetAudioDevices(std::ostringstream &stream);
 462	
 463	void getCaptureDevicesSendMessage();
 464	void getRenderDevicesSendMessage();
 465	
 466	// local audio updates
 467	void buildLocalAudioUpdates(std::ostringstream &stream);		
 468
 469
 470	/////////////////////////////
 471	// Response/Event handlers
 472	void connectorCreateResponse(int statusCode, std::string &statusString, std::string &connectorHandle, std::string &versionID);
 473	void loginResponse(int statusCode, std::string &statusString, std::string &accountHandle, int numberOfAliases);
 474	void sessionCreateResponse(std::string &requestId, int statusCode, std::string &statusString, std::string &sessionHandle);
 475	void sessionGroupAddSessionResponse(std::string &requestId, int statusCode, std::string &statusString, std::string &sessionHandle);
 476	void sessionConnectResponse(std::string &requestId, int statusCode, std::string &statusString);
 477	void logoutResponse(int statusCode, std::string &statusString);
 478	void connectorShutdownResponse(int statusCode, std::string &statusString);
 479
 480	void accountLoginStateChangeEvent(std::string &accountHandle, int statusCode, std::string &statusString, int state);
 481	void mediaCompletionEvent(std::string &sessionGroupHandle, std::string &mediaCompletionType);
 482	void mediaStreamUpdatedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, int statusCode, std::string &statusString, int state, bool incoming);
 483	void textStreamUpdatedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, bool enabled, int state, bool incoming);
 484	void sessionAddedEvent(std::string &uriString, std::string &alias, std::string &sessionHandle, std::string &sessionGroupHandle, bool isChannel, bool incoming, std::string &nameString, std::string &applicationString);
 485	void sessionGroupAddedEvent(std::string &sessionGroupHandle);
 486	void sessionRemovedEvent(std::string &sessionHandle, std::string &sessionGroupHandle);
 487	void participantAddedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, std::string &nameString, std::string &displayNameString, int participantType);
 488	void participantRemovedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, std::string &nameString);
 489	void participantUpdatedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, bool isModeratorMuted, bool isSpeaking, int volume, F32 energy);
 490	void auxAudioPropertiesEvent(F32 energy);
 491	void buddyPresenceEvent(std::string &uriString, std::string &alias, std::string &statusString, std::string &applicationString);
 492	void messageEvent(std::string &sessionHandle, std::string &uriString, std::string &alias, std::string &messageHeader, std::string &messageBody, std::string &applicationString);
 493	void sessionNotificationEvent(std::string &sessionHandle, std::string &uriString, std::string &notificationType);
 494	void subscriptionEvent(std::string &buddyURI, std::string &subscriptionHandle, std::string &alias, std::string &displayName, std::string &applicationString, std::string &subscriptionType);
 495	
 496	void buddyListChanged();
 497	void muteListChanged();
 498	void updateFriends(U32 mask);
 499		
 500	/////////////////////////////
 501	// Sending updates of current state
 502	void updatePosition(void);
 503	void setCameraPosition(const LLVector3d &position, const LLVector3 &velocity, const LLMatrix3 &rot);
 504	void setAvatarPosition(const LLVector3d &position, const LLVector3 &velocity, const LLMatrix3 &rot);
 505	bool channelFromRegion(LLViewerRegion *region, std::string &name);
 506
 507	void setEarLocation(S32 loc);
 508
 509	
 510	/////////////////////////////
 511	// Accessors for data related to nearby speakers
 512
 513	// MBW -- XXX -- Not sure how to get this data out of the TVC
 514	BOOL getUsingPTT(const LLUUID& id);
 515	std::string getGroupID(const LLUUID& id);		// group ID if the user is in group chat (empty string if not applicable)
 516
 517	/////////////////////////////
 518	BOOL getAreaVoiceDisabled();		// returns true if the area the avatar is in is speech-disabled.
 519										// Use this to determine whether to show a "no speech" icon in the menu bar.
 520		
 521	
 522	/////////////////////////////
 523	// Recording controls
 524	void recordingLoopStart(int seconds = 3600, int deltaFramesPerControlFrame = 200);
 525	void recordingLoopSave(const std::string& filename);
 526	void recordingStop();
 527	
 528	// Playback controls
 529	void filePlaybackStart(const std::string& filename);
 530	void filePlaybackStop();
 531	void filePlaybackSetPaused(bool paused);
 532	void filePlaybackSetMode(bool vox = false, float speed = 1.0f);
 533	
 534	participantState *findParticipantByID(const LLUUID& id);
 535	
 536
 537	////////////////////////////////////////
 538	// voice sessions.
 539	typedef std::set<sessionState*> sessionSet;
 540			
 541	typedef sessionSet::iterator sessionIterator;
 542	sessionIterator sessionsBegin(void);
 543	sessionIterator sessionsEnd(void);
 544
 545	sessionState *findSession(const std::string &handle);
 546	sessionState *findSessionBeingCreatedByURI(const std::string &uri);
 547	sessionState *findSession(const LLUUID &participant_id);
 548	sessionState *findSessionByCreateID(const std::string &create_id);
 549	
 550	sessionState *addSession(const std::string &uri, const std::string &handle = LLStringUtil::null);
 551	void setSessionHandle(sessionState *session, const std::string &handle = LLStringUtil::null);
 552	void setSessionURI(sessionState *session, const std::string &uri);
 553	void deleteSession(sessionState *session);
 554	void deleteAllSessions(void);
 555
 556	void verifySessionState(void);
 557
 558	void joinedAudioSession(sessionState *session);
 559	void leftAudioSession(sessionState *session);
 560
 561	// This is called in several places where the session _may_ need to be deleted.
 562	// It contains logic for whether to delete the session or keep it around.
 563	void reapSession(sessionState *session);
 564	
 565	// Returns true if the session seems to indicate we've moved to a region on a different voice server
 566	bool sessionNeedsRelog(sessionState *session);
 567	
 568	
 569	//////////////////////////////////////
 570	// buddy list stuff, needed for SLIM later
 571	struct buddyListEntry
 572	{
 573		buddyListEntry(const std::string &uri);
 574		std::string mURI;
 575		std::string mDisplayName;
 576		LLUUID	mUUID;
 577		bool mOnlineSL;
 578		bool mOnlineSLim;
 579		bool mCanSeeMeOnline;
 580		bool mHasBlockListEntry;
 581		bool mHasAutoAcceptListEntry;
 582		bool mNameResolved;
 583		bool mInSLFriends;
 584		bool mInVivoxBuddies;
 585		bool mNeedsNameUpdate;
 586	};
 587
 588	typedef std::map<std::string, buddyListEntry*> buddyListMap;
 589	
 590	// This should be called when parsing a buddy list entry sent by SLVoice.		
 591	void processBuddyListEntry(const std::string &uri, const std::string &displayName);
 592
 593	buddyListEntry *addBuddy(const std::string &uri);
 594	buddyListEntry *addBuddy(const std::string &uri, const std::string &displayName);
 595	buddyListEntry *findBuddy(const std::string &uri);
 596	buddyListEntry *findBuddy(const LLUUID &id);
 597	buddyListEntry *findBuddyByDisplayName(const std::string &name);
 598	void deleteBuddy(const std::string &uri);
 599	void deleteAllBuddies(void);
 600
 601	void deleteAllBlockRules(void);
 602	void addBlockRule(const std::string &blockMask, const std::string &presenceOnly);
 603	void deleteAllAutoAcceptRules(void);
 604	void addAutoAcceptRule(const std::string &autoAcceptMask, const std::string &autoAddAsBuddy);
 605	void accountListBlockRulesResponse(int statusCode, const std::string &statusString);						
 606	void accountListAutoAcceptRulesResponse(int statusCode, const std::string &statusString);
 607
 608	/////////////////////////////
 609	// session control messages
 610
 611	void accountListBlockRulesSendMessage();
 612	void accountListAutoAcceptRulesSendMessage();
 613	
 614	void sessionGroupCreateSendMessage();
 615	void sessionCreateSendMessage(sessionState *session, bool startAudio = true, bool startText = false);
 616	void sessionGroupAddSessionSendMessage(sessionState *session, bool startAudio = true, bool startText = false);
 617	void sessionMediaConnectSendMessage(sessionState *session);		// just joins the audio session
 618	void sessionTextConnectSendMessage(sessionState *session);		// just joins the text session
 619	void sessionTerminateSendMessage(sessionState *session);
 620	void sessionGroupTerminateSendMessage(sessionState *session);
 621	void sessionMediaDisconnectSendMessage(sessionState *session);
 622	void sessionTextDisconnectSendMessage(sessionState *session);
 623
 624	
 625	
 626	// Pokes the state machine to leave the audio session next time around.
 627	void sessionTerminate();	
 628	
 629	// Pokes the state machine to shut down the connector and restart it.
 630	void requestRelog();
 631	
 632	// Does the actual work to get out of the audio session
 633	void leaveAudioSession();
 634	
 635	// notifies the voice client that we've received parcel voice info
 636	bool parcelVoiceInfoReceived(state requesting_state);
 637	
 638	friend class LLVivoxVoiceClientCapResponder;
 639	
 640	
 641	void lookupName(const LLUUID &id);
 642	void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name);
 643	void avatarNameResolved(const LLUUID &id, const std::string &name);
 644
 645	/////////////////////////////
 646	// Voice fonts
 647
 648	void addVoiceFont(const S32 id,
 649					  const std::string &name,
 650					  const std::string &description,
 651					  const LLDate &expiration_date,
 652					  bool  has_expired,
 653					  const S32 font_type,
 654					  const S32 font_status,
 655					  const bool template_font = false);
 656	void accountGetSessionFontsResponse(int statusCode, const std::string &statusString);
 657	void accountGetTemplateFontsResponse(int statusCode, const std::string &statusString); 
 658
 659private:
 660	LLVoiceVersionInfo mVoiceVersion;
 661
 662	/// Clean up objects created during a voice session.
 663	void cleanUp();
 664
 665	state mState;
 666	bool mSessionTerminateRequested;
 667	bool mRelogRequested;
 668	// Number of times (in a row) "stateJoiningSession" case for spatial channel is reached in stateMachine().
 669	// The larger it is the greater is possibility there is a problem with connection to voice server.
 670	// Introduced while fixing EXT-4313.
 671	int mSpatialJoiningNum;
 672	
 673	void setState(state inState);
 674	state getState(void)  { return mState; };
 675	std::string state2string(state inState);
 676	
 677	void stateMachine();
 678	static void idle(void *user_data);
 679	
 680	LLHost mDaemonHost;
 681	LLSocket::ptr_t mSocket;
 682	bool mConnected;
 683	
 684	
 685	LLPumpIO *mPump;
 686	friend class LLVivoxProtocolParser;
 687	
 688	std::string mAccountName;
 689	std::string mAccountPassword;
 690	std::string mAccountDisplayName;
 691			
 692	bool mTuningMode;
 693	float mTuningEnergy;
 694	std::string mTuningAudioFile;
 695	int mTuningMicVolume;
 696	bool mTuningMicVolumeDirty;
 697	int mTuningSpeakerVolume;
 698	bool mTuningSpeakerVolumeDirty;
 699	state mTuningExitState;					// state to return to when we leave tuning mode.
 700	
 701	std::string mSpatialSessionURI;
 702	std::string mSpatialSessionCredentials;
 703
 704	std::string mMainSessionGroupHandle; // handle of the "main" session group.
 705	
 706	std::string mChannelName;			// Name of the channel to be looked up 
 707	bool mAreaVoiceDisabled;
 708	sessionState *mAudioSession;		// Session state for the current audio session
 709	bool mAudioSessionChanged;			// set to true when the above pointer gets changed, so observers can be notified.
 710
 711	sessionState *mNextAudioSession;	// Session state for the audio session we're trying to join
 712
 713//		std::string mSessionURI;			// URI of the session we're in.
 714//		std::string mSessionHandle;		// returned by ?
 715	
 716	S32 mCurrentParcelLocalID;			// Used to detect parcel boundary crossings
 717	std::string mCurrentRegionName;		// Used to detect parcel boundary crossings
 718	
 719	std::string mConnectorHandle;	// returned by "Create Connector" message
 720	std::string mAccountHandle;		// returned by login message		
 721	int 		mNumberOfAliases;
 722	U32 mCommandCookie;
 723
 724	std::string mVoiceAccountServerURI;
 725	std::string mVoiceSIPURIHostName;
 726	
 727	int mLoginRetryCount;
 728	
 729	sessionMap mSessionsByHandle;				// Active sessions, indexed by session handle.  Sessions which are being initiated may not be in this map.
 730	sessionSet mSessions;						// All sessions, not indexed.  This is the canonical session list.
 731	
 732	bool mBuddyListMapPopulated;
 733	bool mBlockRulesListReceived;
 734	bool mAutoAcceptRulesListReceived;
 735	buddyListMap mBuddyListMap;
 736	
 737	LLVoiceDeviceList mCaptureDevices;
 738	LLVoiceDeviceList mRenderDevices;
 739
 740	std::string mCaptureDevice;
 741	std::string mRenderDevice;
 742	bool mCaptureDeviceDirty;
 743	bool mRenderDeviceDirty;
 744	
 745	
 746	bool checkParcelChanged(bool update = false);
 747	// This should be called when the code detects we have changed parcels.
 748	// It initiates the call to the server that gets the parcel channel.
 749	bool requestParcelVoiceInfo();
 750	
 751	void switchChannel(std::string uri = std::string(), bool spatial = true, bool no_reconnect = false, bool is_p2p = false, std::string hash = "");
 752	void joinSession(sessionState *session);
 753	
 754	std::string nameFromAvatar(LLVOAvatar *avatar);
 755	std::string nameFromID(const LLUUID &id);
 756	bool IDFromName(const std::string name, LLUUID &uuid);
 757	std::string displayNameFromAvatar(LLVOAvatar *avatar);
 758	std::string sipURIFromAvatar(LLVOAvatar *avatar);
 759	std::string sipURIFromName(std::string &name);
 760	
 761	// Returns the name portion of the SIP URI if the string looks vaguely like a SIP URI, or an empty string if not.
 762	std::string nameFromsipURI(const std::string &uri);		
 763
 764	bool inSpatialChannel(void);
 765	std::string getAudioSessionURI();
 766	std::string getAudioSessionHandle();
 767			
 768	void sendPositionalUpdate(void);
 769	
 770	void buildSetCaptureDevice(std::ostringstream &stream);
 771	void buildSetRenderDevice(std::ostringstream &stream);
 772	
 773	void clearAllLists();
 774	void checkFriend(const LLUUID& id);
 775	void sendFriendsListUpdates();
 776
 777	// start a text IM session with the specified user
 778	// This will be asynchronous, the session may be established at a future time.
 779	sessionState* startUserIMSession(const LLUUID& uuid);
 780	void sendQueuedTextMessages(sessionState *session);
 781	
 782	void enforceTether(void);
 783	
 784	bool		mSpatialCoordsDirty;
 785	
 786	LLVector3d	mCameraPosition;
 787	LLVector3d	mCameraRequestedPosition;
 788	LLVector3	mCameraVelocity;
 789	LLMatrix3	mCameraRot;
 790
 791	LLVector3d	mAvatarPosition;
 792	LLVector3	mAvatarVelocity;
 793	LLMatrix3	mAvatarRot;
 794	
 795	bool		mMuteMic;
 796	bool		mMuteMicDirty;
 797			
 798	// Set to true when the friends list is known to have changed.
 799	bool		mFriendsListDirty;
 800	
 801	enum
 802	{
 803		earLocCamera = 0,		// ear at camera
 804		earLocAvatar,			// ear at avatar
 805		earLocMixed				// ear at avatar location/camera direction
 806	};
 807	
 808	S32			mEarLocation;  
 809	
 810	bool		mSpeakerVolumeDirty;
 811	bool		mSpeakerMuteDirty;
 812	int			mSpeakerVolume;
 813
 814	int			mMicVolume;
 815	bool		mMicVolumeDirty;
 816	
 817	bool		mVoiceEnabled;
 818	bool		mWriteInProgress;
 819	std::string mWriteString;
 820	size_t		mWriteOffset;
 821	
 822	LLTimer		mUpdateTimer;
 823	
 824	BOOL		mLipSyncEnabled;
 825
 826	typedef std::set<LLVoiceClientParticipantObserver*> observer_set_t;
 827	observer_set_t mParticipantObservers;
 828
 829	void notifyParticipantObservers();
 830
 831	typedef std::set<LLVoiceClientStatusObserver*> status_observer_set_t;
 832	status_observer_set_t mStatusObservers;
 833	
 834	void notifyStatusObservers(LLVoiceClientStatusObserver::EStatusType status);
 835
 836	typedef std::set<LLFriendObserver*> friend_observer_set_t;
 837	friend_observer_set_t mFriendObservers;
 838	void notifyFriendObservers();
 839
 840	// Voice Fonts
 841
 842	void expireVoiceFonts();
 843	void deleteVoiceFont(const LLUUID& id);
 844	void deleteAllVoiceFonts();
 845	void deleteVoiceFontTemplates();
 846
 847	S32 getVoiceFontIndex(const LLUUID& id) const;
 848	S32 getVoiceFontTemplateIndex(const LLUUID& id) const;
 849
 850	void accountGetSessionFontsSendMessage();
 851	void accountGetTemplateFontsSendMessage();
 852	void sessionSetVoiceFontSendMessage(sessionState *session);
 853
 854	void notifyVoiceFontObservers();
 855
 856	typedef enum e_voice_font_type
 857	{
 858		VOICE_FONT_TYPE_NONE = 0,
 859		VOICE_FONT_TYPE_ROOT = 1,
 860		VOICE_FONT_TYPE_USER = 2,
 861		VOICE_FONT_TYPE_UNKNOWN
 862	} EVoiceFontType;
 863
 864	typedef enum e_voice_font_status
 865	{
 866		VOICE_FONT_STATUS_NONE = 0,
 867		VOICE_FONT_STATUS_FREE = 1,
 868		VOICE_FONT_STATUS_NOT_FREE = 2,
 869		VOICE_FONT_STATUS_UNKNOWN
 870	} EVoiceFontStatus;
 871
 872	struct voiceFontEntry
 873	{
 874		voiceFontEntry(LLUUID& id);
 875		~voiceFontEntry();
 876
 877		LLUUID		mID;
 878		S32			mFontIndex;
 879		std::string mName;
 880		LLDate		mExpirationDate;
 881		S32			mFontType;
 882		S32			mFontStatus;
 883		bool		mIsNew;
 884
 885		LLFrameTimer	mExpiryTimer;
 886		LLFrameTimer	mExpiryWarningTimer;
 887	};
 888
 889	bool mVoiceFontsReceived;
 890	bool mVoiceFontsNew;
 891	bool mVoiceFontListDirty;
 892	voice_effect_list_t	mVoiceFontList;
 893	voice_effect_list_t	mVoiceFontTemplateList;
 894
 895	typedef std::map<const LLUUID, voiceFontEntry*> voice_font_map_t;
 896	voice_font_map_t	mVoiceFontMap;
 897	voice_font_map_t	mVoiceFontTemplateMap;
 898
 899	typedef std::set<LLVoiceEffectObserver*> voice_font_observer_set_t;
 900	voice_font_observer_set_t mVoiceFontObservers;
 901
 902	LLFrameTimer	mVoiceFontExpiryTimer;
 903
 904
 905	// Audio capture buffer
 906
 907	void captureBufferRecordStartSendMessage();
 908	void captureBufferRecordStopSendMessage();
 909	void captureBufferPlayStartSendMessage(const LLUUID& voice_font_id = LLUUID::null);
 910	void captureBufferPlayStopSendMessage();
 911
 912	bool mCaptureBufferMode;		// Disconnected from voice channels while using the capture buffer.
 913	bool mCaptureBufferRecording;	// A voice sample is being captured.
 914	bool mCaptureBufferRecorded;	// A voice sample is captured in the buffer ready to play.
 915	bool mCaptureBufferPlaying;		// A voice sample is being played.
 916
 917	LLTimer	mCaptureTimer;
 918	LLUUID mPreviewVoiceFont;
 919	LLUUID mPreviewVoiceFontLast;
 920	S32 mPlayRequestCount;
 921};
 922
 923/** 
 924 * @class LLVivoxProtocolParser
 925 * @brief This class helps construct new LLIOPipe specializations
 926 * @see LLIOPipe
 927 *
 928 * THOROUGH_DESCRIPTION
 929 */
 930class LLVivoxProtocolParser : public LLIOPipe
 931{
 932	LOG_CLASS(LLVivoxProtocolParser);
 933public:
 934	LLVivoxProtocolParser();
 935	virtual ~LLVivoxProtocolParser();
 936	
 937protected:
 938	/* @name LLIOPipe virtual implementations
 939	 */
 940	//@{
 941	/** 
 942	 * @brief Process the data in buffer
 943	 */
 944	virtual EStatus process_impl(
 945								 const LLChannelDescriptors& channels,
 946								 buffer_ptr_t& buffer,
 947								 bool& eos,
 948								 LLSD& context,
 949								 LLPumpIO* pump);
 950	//@}
 951	
 952	std::string 	mInput;
 953	
 954	// Expat control members
 955	XML_Parser		parser;
 956	int				responseDepth;
 957	bool			ignoringTags;
 958	bool			isEvent;
 959	int				ignoreDepth;
 960	
 961	// Members for processing responses. The values are transient and only valid within a call to processResponse().
 962	bool			squelchDebugOutput;
 963	int				returnCode;
 964	int				statusCode;
 965	std::string		statusString;
 966	std::string		requestId;
 967	std::string		actionString;
 968	std::string		connectorHandle;
 969	std::string		versionID;
 970	std::string		accountHandle;
 971	std::string		sessionHandle;
 972	std::string		sessionGroupHandle;
 973	std::string		alias;
 974	std::string		applicationString;
 975	
 976	// Members for processing events. The values are transient and only valid within a call to processResponse().
 977	std::string		eventTypeString;
 978	int				state;
 979	std::string		uriString;
 980	bool			isChannel;
 981	bool			incoming;
 982	bool			enabled;
 983	std::string		nameString;
 984	std::string		audioMediaString;
 985	std::string     deviceString;
 986	std::string		displayNameString;
 987	int				participantType;
 988	bool			isLocallyMuted;
 989	bool			isModeratorMuted;
 990	bool			isSpeaking;
 991	int				volume;
 992	F32				energy;
 993	std::string		messageHeader;
 994	std::string		messageBody;
 995	std::string		notificationType;
 996	bool			hasText;
 997	bool			hasAudio;
 998	bool			hasVideo;
 999	bool			terminated;
1000	std::string		blockMask;
1001	std::string		presenceOnly;
1002	std::string		autoAcceptMask;
1003	std::string		autoAddAsBuddy;
1004	int				numberOfAliases;
1005	std::string		subscriptionHandle;
1006	std::string		subscriptionType;
1007	S32				id;
1008	std::string		descriptionString;
1009	LLDate			expirationDate;
1010	bool			hasExpired;
1011	S32				fontType;
1012	S32				fontStatus;
1013	std::string		mediaCompletionType;
1014	
1015	// Members for processing text between tags
1016	std::string		textBuffer;
1017	bool			accumulateText;
1018	
1019	void			reset();
1020	
1021	void			processResponse(std::string tag);
1022	
1023	static void XMLCALL ExpatStartTag(void *data, const char *el, const char **attr);
1024	static void XMLCALL ExpatEndTag(void *data, const char *el);
1025	static void XMLCALL ExpatCharHandler(void *data, const XML_Char *s, int len);
1026	
1027	void			StartTag(const char *tag, const char **attr);
1028	void			EndTag(const char *tag);
1029	void			CharData(const char *buffer, int length);
1030	LLDate			expiryTimeStampToLLDate(const std::string& vivox_ts);
1031};
1032
1033
1034#endif //LL_VIVOX_VOICE_CLIENT_H
1035