- Fix missing SIP accounts when we have no network connection

- Fix SIP behavior when user cancels the authorization process
- Improve messages on authorization
cusax-fix
Yana Stamcheva 18 years ago
parent e371d0a91a
commit f861464e29

@ -494,29 +494,54 @@ public void run()
}
catch (OperationFailedException ex)
{
int errorCode = ex.getErrorCode();
String errorMessage = "";
if (errorCode == OperationFailedException.GENERAL_ERROR)
{
logger.error("Provider could not be registered"
+ " due to the following general error: ", ex);
errorMessage = Messages.getI18NString("loginGeneralError",
new String[]{
protocolProvider.getAccountID().getUserID(),
protocolProvider.getAccountID().getService()
}).getText();
}
else if (errorCode == OperationFailedException.INTERNAL_ERROR)
{
logger.error("Provider could not be registered"
+ " due to the following internal error: ", ex);
errorMessage = Messages.getI18NString("loginInternalError",
new String[]{
protocolProvider.getAccountID().getUserID(),
protocolProvider.getAccountID().getService()
}).getText();
}
else if (errorCode == OperationFailedException.NETWORK_FAILURE)
{
logger.error("Provider could not be registered"
+ " due to a network failure: " + ex);
errorMessage = Messages.getI18NString("loginNetworkError",
new String[]{
protocolProvider.getAccountID().getUserID(),
protocolProvider.getAccountID().getService()
}).getText();
}
else if (errorCode
== OperationFailedException.INVALID_ACCOUNT_PROPERTIES)
{
logger.error("Provider could not be registered"
+ " due to an invalid account property: ", ex);
errorMessage = Messages.getI18NString("loginInvalidPropsError",
new String[]{
protocolProvider.getAccountID().getUserID(),
protocolProvider.getAccountID().getService()
}).getText();
}
else
{
@ -525,12 +550,8 @@ else if (errorCode
new ErrorDialog(mainFrame,
Messages.getI18NString("error").getText(),
Messages.getI18NString("loginNotSucceeded",
new String[]{
protocolProvider.getAccountID().getUserID(),
protocolProvider.getAccountID().getService()
}).getText(),
ex).showDialog();
errorMessage,
ex).showDialog();
mainFrame.getStatusPanel().updateStatus(protocolProvider);
}
@ -541,11 +562,11 @@ else if (errorCode
new ErrorDialog(
mainFrame,
Messages.getI18NString("error").getText(),
Messages.getI18NString("loginNotSucceeded",
new String[]
{ protocolProvider.getAccountID().getUserID(),
protocolProvider.getAccountID().getService() })
.getText())
Messages.getI18NString("loginGeneralError",
new String[]{
protocolProvider.getAccountID().getUserID(),
protocolProvider.getAccountID().getService()
}).getText())
.showDialog();
mainFrame.getStatusPanel().updateStatus(protocolProvider);

@ -103,7 +103,7 @@ public ContactSipImpl(
{
this.contactID = id;
this.parentProvider = parentProvider;
this.presenceStatus = parentProvider.getSipStatusEnum()
.getStatus(SipStatusEnum.UNKNOWN);
}

@ -2999,10 +2999,10 @@ private void processAuthenticationChallenge(
ClientTransaction retryTran
= this.parentProvider.getSipSecurityManager().handleChallenge(
response
, clientTransaction
, jainSipProvider);
response,
clientTransaction,
jainSipProvider);
if(retryTran == null)
{
logger.trace("No password supplied or error occured!");

@ -21,7 +21,7 @@
public class ProtocolIconSipImpl
implements ProtocolIcon
{
private static Logger logger = Logger.getLogger(ProtocolIconSipImpl.class);
private static Logger logger = Logger.getLogger(ProtocolIconSipImpl.class);
private String iconPath;

@ -123,8 +123,8 @@ public AccountID installAccount( String userIDStr,
//the register() method and it needs to acces the configuration service
//and check for a password.
this.storeAccount(
SipActivator.getBundleContext()
, accountID);
SipActivator.getBundleContext(),
accountID);
try
{
@ -178,7 +178,7 @@ protected AccountID loadAccount(Map accountProperties)
if (!accountProperties.containsKey(PROTOCOL))
accountProperties.put(PROTOCOL, ProtocolNames.SIP);
AccountID accountID =
SipAccountID accountID =
new SipAccountID(userIDStr, accountProperties, serverAddress);
//get a reference to the configuration service and register whatever
@ -194,6 +194,11 @@ protected AccountID loadAccount(Map accountProperties)
try
{
sipProtocolProvider.initialize(userIDStr, accountID);
// We store again the account in order to store all properties added
// during the protocol provider initialization.
this.storeAccount(
SipActivator.getBundleContext(), accountID);
}
catch (OperationFailedException ex)
{

@ -91,6 +91,11 @@ public class ProtocolProviderServiceSipImpl
*/
private SipStack jainSipStack;
/**
* The properties of the jainSipStack.
*/
private Properties jainSipStackProperties;
/**
* The default listening point that we use for UDP communication..
*/
@ -513,12 +518,25 @@ public void register(SecurityAuthority authority)
{
return;
}
//init the security manager before doing the actual registration to
//avoid being asked for credentials before being ready to provide them
sipSecurityManager.setSecurityAuthority(authority);
//connecto to the Registrar.
sipRegistrarConnection.register();
// We check here if the sipRegistrarConnection is initialized. This is
// needed in case that in the initialization process we had no internet
// connection.
if (sipRegistrarConnection == null)
initRegistrarConnection((SipAccountID) accountID);
// The same here, we check if the outbound proxy is initialized in case
// through the initialization process there was no internet connection.
if (outboundProxySocketAddress == null)
initOutboundProxy((SipAccountID)accountID, jainSipStackProperties);
//connect to the Registrar.
if (sipRegistrarConnection != null)
sipRegistrarConnection.register();
}
/**
@ -550,7 +568,9 @@ public void unregister()
* about to create
* @param accountID the identifier of the account that this protocol
* provider represents.
*
* @param isInstall indicates if this initialization is made due to a new
* account installation or just an existing account loading
*
* @throws OperationFailedException with code INTERNAL_ERROR if we fail
* initializing the SIP Stack.
* @throws java.lang.IllegalArgumentException if one or more of the account
@ -559,7 +579,7 @@ public void unregister()
* @see net.java.sip.communicator.service.protocol.AccountID
*/
protected void initialize(String sipAddress,
AccountID accountID)
SipAccountID accountID)
throws OperationFailedException, IllegalArgumentException
{
synchronized (initializationLock)
@ -593,34 +613,41 @@ protected void initialize(String sipAddress,
sipFactory = SipFactory.getInstance();
sipFactory.setPathName("gov.nist");
Properties properties = new Properties();
this.jainSipStackProperties = new Properties();
//init the proxy
initOutboundProxy(accountID, properties);
initOutboundProxy(accountID, jainSipStackProperties);
// If you want to use UDP then uncomment this.
properties.setProperty(JSPNAME_STACK_NAME, "SIP Communicator:"
jainSipStackProperties.setProperty(
JSPNAME_STACK_NAME, "SIP Communicator:"
+ getAccountID().getAccountUniqueID());
// NIST SIP specific properties
properties.setProperty(NSPNAME_DEBUG_LOG, NSPVALUE_DEBUG_LOG);
properties.setProperty(NSPNAME_SERVER_LOG, NSPVALUE_SERVER_LOG);
jainSipStackProperties
.setProperty(NSPNAME_DEBUG_LOG, NSPVALUE_DEBUG_LOG);
jainSipStackProperties
.setProperty(NSPNAME_SERVER_LOG, NSPVALUE_SERVER_LOG);
// Drop the client connection after we are done with the transaction.
properties.setProperty( NSPNAME_CACHE_CLIENT_CONNECTIONS
, NSPVALUE_CACHE_CLIENT_CONNECTIONS);
jainSipStackProperties
.setProperty( NSPNAME_CACHE_CLIENT_CONNECTIONS,
NSPVALUE_CACHE_CLIENT_CONNECTIONS);
// Log level
properties.setProperty(NSPNAME_TRACE_LEVEL, NSPVALUE_TRACE_LEVEL);
jainSipStackProperties
.setProperty(NSPNAME_TRACE_LEVEL, NSPVALUE_TRACE_LEVEL);
// deliver unsolicited NOTIFY
properties.setProperty(NSPNAME_DELIVER_UNSOLICITED_NOTIFY,
NSPVALUE_DELIVER_UNSOLICITED_NOTIFY);
jainSipStackProperties
.setProperty( NSPNAME_DELIVER_UNSOLICITED_NOTIFY,
NSPVALUE_DELIVER_UNSOLICITED_NOTIFY);
try
{
// Create SipStack object
jainSipStack = new SipStackImpl(properties);
jainSipStack = new SipStackImpl(jainSipStackProperties);
logger.debug("Created stack: " + jainSipStack);
}
catch (PeerUnavailableException exc)
@ -1711,7 +1738,7 @@ public SipSecurityManager getSipSecurityManager()
* @throws java.lang.IllegalArgumentException if one or more account
* properties have invalid values.
*/
private void initRegistrarConnection(AccountID accountID)
private void initRegistrarConnection(SipAccountID accountID)
throws IllegalArgumentException
{
//First init the registrar address
@ -1728,19 +1755,65 @@ private void initRegistrarConnection(AccountID accountID)
}
InetAddress registrarAddress = null;
try
{
registrarAddress = InetAddress.getByName(registrarAddressStr);
// We should set here the property to indicate that the server
// address is validated. When we load stored accounts we check
// this property in order to prevent checking again the server
// address. And this is needed because in the case we don't have
// network while loading the application we still want to have our
// accounts loaded.
accountID.putProperty(
ProtocolProviderFactory.SERVER_ADDRESS_VALIDATED,
Boolean.toString(true));
}
catch (UnknownHostException ex)
{
logger.error(registrarAddressStr
+ " appears to be an either invalid or inaccessible address: "
, ex);
throw new IllegalArgumentException(
registrarAddressStr
+ " appears to be an either invalid or inaccessible address: "
+ ex.getMessage());
String serverValidatedString
= (String) accountID.getAccountProperties()
.get(ProtocolProviderFactory.SERVER_ADDRESS_VALIDATED);
boolean isServerValidated = false;
if (serverValidatedString != null)
isServerValidated = new Boolean(serverValidatedString)
.booleanValue();
// We should check here if the server address was already validated.
// When we load stored accounts we want to prevent checking again the
// server address. This is needed because in the case we don't have
// network while loading the application we still want to have our
// accounts loaded.
if (serverValidatedString == null || !isServerValidated)
{
throw new IllegalArgumentException(
registrarAddressStr
+ " appears to be an either invalid or inaccessible address: "
+ ex.getMessage());
}
}
// If the registrar address is null we don't need to continue.
// If we still have problems with initializing the registrar we are
// telling the user. We'll enter here only if the server has been
// already validated (this means that the account is already created
// and we're trying to login, but we have no internet connection).
if(registrarAddress == null)
{
fireRegistrationStateChanged(
RegistrationState.UNREGISTERED,
RegistrationState.CONNECTION_FAILED,
RegistrationStateChangeEvent.REASON_SERVER_NOT_FOUND,
"Invalid or inaccessible server address.");
return;
}
//init registrar port
@ -1857,7 +1930,7 @@ public Address getOurSipAddress()
* jain sip stack when initialize it (that's where we'll put all proxy
* properties).
*/
private void initOutboundProxy(AccountID accountID,
private void initOutboundProxy(SipAccountID accountID,
Hashtable jainSipProperties)
{
//First init the proxy address
@ -1866,24 +1939,53 @@ private void initOutboundProxy(AccountID accountID,
InetAddress proxyAddress = null;
try
{
proxyAddress = InetAddress.getByName(proxyAddressStr);
proxyAddress = InetAddress.getByName(proxyAddressStr);
// We should set here the property to indicate that the proxy
// address is validated. When we load stored accounts we check
// this property in order to prevent checking again the proxy
// address. this is needed because in the case we don't have
// network while loading the application we still want to have
// our accounts loaded.
accountID.putProperty(
ProtocolProviderFactory.PROXY_ADDRESS_VALIDATED,
Boolean.toString(true));
}
catch (UnknownHostException ex)
{
logger.error(proxyAddressStr
+ " appears to be an either invalid or inaccessible address"
, ex);
throw new IllegalArgumentException(
proxyAddressStr
+ " appears to be an either invalid or inaccessible address "
+ ex.getMessage());
String proxyValidatedString = (String) accountID
.getAccountProperties().get(
ProtocolProviderFactory.PROXY_ADDRESS_VALIDATED);
boolean isProxyValidated = false;
if (proxyValidatedString != null)
isProxyValidated
= new Boolean(proxyValidatedString).booleanValue();
// We should check here if the proxy address was already validated.
// When we load stored accounts we want to prevent checking again the
// proxy address. This is needed because in the case we don't have
// network while loading the application we still want to have our
// accounts loaded.
if (proxyValidatedString == null || !isProxyValidated)
{
throw new IllegalArgumentException(
proxyAddressStr
+ " appears to be an either invalid or inaccessible address "
+ ex.getMessage());
}
}
//return if no proxy is specified.
if(proxyAddressStr == null || proxyAddressStr.length() == 0)
// Return if no proxy is specified or if the proxyAddress is null.
if(proxyAddressStr == null
|| proxyAddressStr.length() == 0
|| proxyAddress == null)
{
return;
}
@ -1953,8 +2055,8 @@ private void initOutboundProxy(AccountID accountID,
proxyStringBuffer.append(proxyTransport);
//done parsing. init properties.
jainSipProperties.put(JSPNAME_OUTBOUND_PROXY
, proxyStringBuffer.toString());
jainSipProperties.put( JSPNAME_OUTBOUND_PROXY,
proxyStringBuffer.toString());
//store a reference to our sip proxy so that we can use it when
//constructing via and contact headers.

@ -17,7 +17,6 @@
public class SipAccountID
extends AccountID
{
/**
* Creates a SIP account id from the specified ide and account properties.
*
@ -53,4 +52,14 @@ public String getAccountAddress()
return "sip:" + getUserID() + "@" + getService();
}
/**
* Adds a property to the map of properties for this account identifier.
*
* @param key the key of the property
* @param value the property value
*/
public void putProperty(Object key, Object value)
{
accountProperties.put(key, value);
}
}

@ -346,16 +346,18 @@ void register()
catch (TransactionUnavailableException ex)
{
logger.error("Could not create a register transaction!\n"
+ "Check that the Registrar address is correct!"
, ex);
setRegistrationState(RegistrationState.CONNECTION_FAILED
, RegistrationStateChangeEvent.REASON_INTERNAL_ERROR
, ex.getMessage());
+ "Check that the Registrar address is correct!",
ex);
setRegistrationState(RegistrationState.CONNECTION_FAILED,
RegistrationStateChangeEvent.REASON_INTERNAL_ERROR,
ex.getMessage());
throw new OperationFailedException(
"Could not create a register transaction!\n"
+ "Check that the Registrar address is correct!"
, OperationFailedException.INTERNAL_ERROR
, ex);
+ "Check that the Registrar address is correct!",
OperationFailedException.NETWORK_FAILURE,
ex);
}
try
{
@ -503,7 +505,7 @@ private void unregister(boolean sendUnregister) throws OperationFailedException
"Could not find the initial register request."
, OperationFailedException.INTERNAL_ERROR);
}
setRegistrationState(RegistrationState.UNREGISTERING,
RegistrationStateChangeEvent.REASON_USER_REQUEST, "");
@ -886,9 +888,9 @@ private void processAuthenticationChallenge(
ClientTransaction retryTran
= sipProvider.getSipSecurityManager().handleChallenge(
response
, clientTransaction
, jainSipProvider);
response,
clientTransaction,
jainSipProvider);
if(retryTran == null)
{
@ -896,10 +898,30 @@ private void processAuthenticationChallenge(
unregister(false);
return;
}
retryTran.sendRequest();
return;
}
catch (OperationFailedException exc)
{
if(exc.getErrorCode()
== OperationFailedException.AUTHENTICATION_CANCELED)
{
this.setRegistrationState(
RegistrationState.UNREGISTERED,
RegistrationStateChangeEvent.REASON_USER_REQUEST,
"User has canceled the authentication process.");
}
else
{
//tell the others we couldn't register
this.setRegistrationState(
RegistrationState.AUTHENTICATION_FAILED,
RegistrationStateChangeEvent.REASON_AUTHENTICATION_FAILED,
"We failed to authenticate with the server."
);
}
}
catch (Exception exc)
{
logger.error("We failed to authenticate a Register request.", exc);

@ -109,13 +109,18 @@ public class OperationFailedException
* room join error.
*/
public static final int REGISTRATION_REQUIRED = 13;
/**
* Indicates that we are currently not joined to the chat room, over which
* we try to perform an operation.
*/
public static final int CHAT_ROOM_NOT_JOINED = 14;
/**
* Indicates that the authentication process has been canceled.
*/
public static final int AUTHENTICATION_CANCELED = 15;
/**
* The error code of the exception
*/

@ -9,6 +9,7 @@
import java.util.*;
import org.osgi.framework.*;
import net.java.sip.communicator.service.configuration.*;
import net.java.sip.communicator.util.*;
@ -16,7 +17,7 @@
* The ProtocolProviderFactory is what actually creates instances of a
* ProtocolProviderService implementation. A provider factory would register,
* persistently store, and remove when necessary, ProtocolProviders. The way
* things are in the SIP Communicator, a user account is representedy (in a 1:1
* things are in the SIP Communicator, a user account is represented (in a 1:1
* relationship) by an AccountID and a ProtocolProvider. In other words - one
* would have as many protocol providers installed in a given moment as they
* would user account registered through the various services.
@ -172,9 +173,20 @@ public abstract class ProtocolProviderFactory
* The name of the property under which we store the chosen default
* subscription expiration value for SIMPLE.
*/
public static final String SUBSCRIPTION_EXPIRATION =
"SUBSCRIPTION_EXPIRATION";
public static final String SUBSCRIPTION_EXPIRATION
= "SUBSCRIPTION_EXPIRATION";
/**
* Indicates if the server address has been validated.
*/
public static final String SERVER_ADDRESS_VALIDATED
= "SERVER_ADDRESS_VALIDATED";
/**
* Indicates if the proxy address has been validated.
*/
public static final String PROXY_ADDRESS_VALIDATED
= "PROXY_ADDRESS_VALIDATED";
/**
* Initializes and creates an account corresponding to the specified
* accountProperties and registers the resulting ProtocolProvider in the
@ -252,36 +264,63 @@ public abstract ServiceReference getProviderForAccount(
* like to store.
*/
protected void storeAccount(BundleContext bundleContext,
AccountID accountID)
AccountID accountID)
{
String sourcePackageName = getFactoryImplPackageName();
//create a unique node name fo the properties node that will contain
//this account's properties.
String accNodeName
= "acc" + Long.toString(System.currentTimeMillis());
String accountNodeName = null;
ServiceReference confReference
= bundleContext.getServiceReference(
ConfigurationService.class.getName());
ConfigurationService.class.getName());
ConfigurationService configurationService
= (ConfigurationService) bundleContext.getService(confReference);
//set a value for the persistent node so that we could later retrieve it
//as a property
configurationService.setProperty(
sourcePackageName //prefix
+ "." + accNodeName
, accNodeName);
//register the account in the configuration service.
//we register all the properties in the following hierarchy
//net.java.sip.communicator.impl.protocol.PROTO_NAME.ACC_ID.PROP_NAME
configurationService.setProperty(
sourcePackageName //prefix
+ "." + accNodeName // node name for the account id
+ "." + ACCOUNT_UID // propname
, accountID.getAccountUniqueID()); // value
// First check if such accountID already exist in the configuration.
List accounts = configurationService
.getPropertyNamesByPrefix(sourcePackageName, true);
Iterator accountsIter = accounts.iterator();
while(accountsIter.hasNext())
{
String accountRootPropName
= (String) accountsIter.next();
String accountIDString
= configurationService.getString(
accountRootPropName + ".ACCOUNT_UID");
if(accountIDString.equals(accountID.getAccountUniqueID()))
{
accountNodeName
= configurationService.getString(accountRootPropName);
}
}
//Create a unique node name of the properties node that will contain
//this account's properties.
if (accountNodeName == null)
{
accountNodeName = "acc" + Long.toString(System.currentTimeMillis());
//set a value for the persistent node so that we could later
// retrieve it as a property
configurationService.setProperty(
sourcePackageName //prefix
+ "." + accountNodeName,
accountNodeName);
//register the account in the configuration service.
//we register all the properties in the following hierarchy
//net.java.sip.communicator.impl.protocol.PROTO_NAME.ACC_ID.PROP_NAME
configurationService.setProperty(
sourcePackageName//prefix
+ "." + accountNodeName // node name for the account id
+ "." + ACCOUNT_UID, // propname
accountID.getAccountUniqueID()); // value
}
//store the rest of the properties
Iterator accountPropKeys
@ -300,15 +339,13 @@ protected void storeAccount(BundleContext bundleContext,
configurationService.setProperty(
sourcePackageName //prefix
+ "." + accNodeName // a uniew node name for the account id
+ "." + propKey // propname
, propValue); // value
+ "." + accountNodeName // a uniew node name for the account id
+ "." + propKey, // propname
propValue); // value
}
logger.debug("Stored account for id " + accountID.getAccountUniqueID()
+ " for package " + getFactoryImplPackageName());
+ " for package " + getFactoryImplPackageName());
}
/**
@ -487,9 +524,10 @@ protected void loadStoredAccounts(BundleContext bundleContext)
*
* @param accountProperties a set of protocol (or implementation)
* specific properties defining the new account.
*
* @return the AccountID of the newly loaded account
*/
protected abstract AccountID loadAccount(Map accountProperties);
protected abstract AccountID loadAccount( Map accountProperties);
/**

Loading…
Cancel
Save