user2957954
user2957954

Reputation: 1249

How do I do a SIP telephone call

I want to constract a telephone-caller inside my java application. For this pupose I used a JAIN-SIP library. After the first INVITE the system needs Proxy-Authentication. The second invite is conscructed with the help of "AuthenticationHelperImpl.class":https://gitorious.org/0xdroid/external_nist-sip/source/1e0f37693341071f316852c8e05a08deef2b7fc4:java/gov/nist/javax/sip/clientauthutils/AuthenticationHelperImpl.java#L311, includes Proxy-Authentication header and lloks like:

INVITE sip:[email protected];maddr=fpbx.de SIP/2.0
Call-ID: [email protected]
CSeq: 2 INVITE
From: "77735hk6iu" <sip:[email protected]>
To: "+111111111111111" <sip:[email protected]>
Via: SIP/2.0/UDP 192.168.17.107:34567;rport;branch=z9hG4bK-383337-5bc4fd6b7a616843fce9eaa243bcb10e
Max-Forwards: 70
Contact: <sip:[email protected]:5060>
Content-Type: application/sdp
Proxy-Authorization: Digest       username="77735hk6iu",realm="fpbx.de",nonce="VLaIxVS2h5muPS30F2zLdXHjup6ELyen",uri="sip:[email protected]:5060;maddr=fpbx.de",response="47ea578c6b01c99fd3ed2b41c60983df"
Content-Length: 61

v=0
o=- 130565705777141827 1 IN IP4 192.168.17.107
s=call

After that I receive at the beginning code 100 message ("your call is very important for us") followed with 408 code message ("Request Timeout").

What I did to imporve the situation:

  1. tried different phone number formats: 004930208488480, 04930208488480, 049, 0049, sdfhajfkhsk. For all these numbers I become the same combination on messages.

  2. tried to use port in request uri

  3. tried to remove maddr from request uri.

  4. tried to fullfill the message body with codek settings.

  5. to set and remove rport from via header

If you now what I'm doing wrong, please, help me. Thank you in advance.

Upvotes: 1

Views: 872

Answers (3)

korvus
korvus

Reputation: 395

The 100 message is hop-by-hop, that is to say it just means the next hop got your request. Other messages will typically be end-to-end (so, if you got a 180 Ringing, that typically means the endpoint being called sent the 180). A 408 typically shows up when one of the hops sent the INVITE but never got a response (and your SIP stack might be generating that internally when it doesn't get a provisional response in a reasonable timeframe -- usually about 32 seconds with the default SIP timers).

I don't know your network setup, but there are several private IPs in that message (of the 192.168.x.x variety). If I had to guess, your first hop is sending the 100 back to the IP/port it received it from, but the next response is following the Via headers (as it should), and the hop after you isn't respecting the rport parameter, so the response is getting lost. Alternately, your NAT is poorly configured and is closing the hole it created for the INVITE too quickly.

If you have a proxy on the edge of your network that this message is going out, it is either putting bad Via headers on the message (possibly with the internal IP instead of the external IP) or it is sending the INVITE to the wrong place (causing it to never get a response), and the 408 is coming from it.

Upvotes: 0

user2957954
user2957954

Reputation: 1249

The problem was partly solved when a removed "maddr=fpbx.de" from request URI and from proxy-auth. uri

fpr this a used handleCahllenge method with boolean arguments:

inviteTid = authenticationHelper.handleChallenge(response, tid, sipProvider, 15, **true**);

But I still don't know how I can a acchieve sponaneous telephone number.

Upvotes: 0

Tarık Yurtlu
Tarık Yurtlu

Reputation: 1270

I think, Maybe your Proxy-Authorization header is wrong. Maybe you is miscalculated. I wanted to share my resolve.

authUser is your phoneNumber. (for example: 77735hk6iu ) authPass is your user's password. msg is your invite request.(Headers !)

AccountManagerImpl accountManagerImp = new AccountManagerImpl(authUser, AuthPass);
        AuthenticationHelperImpl authenticationHelperImpl = new AuthenticationHelperImpl(accountManagerImp);

        try {
           this.authentication = authenticationHelperImpl.handleChallenge(msg, (SIPClientTransaction)trans);

AuthenticationHelperImple.java Class :

   public AuthorizationHeader handleChallenge(Response challenge, ClientTransaction challengedTransaction) throws SipException {


  SIPRequest challengedRequest = ((SIPRequest) challengedTransaction.getRequest());

  ListIterator authHeaders = null;

  if (challenge.getStatusCode() == Response.UNAUTHORIZED) {
     authHeaders = challenge.getHeaders(WWWAuthenticateHeader.NAME);
  }
  else {
     if (challenge.getStatusCode() == Response.PROXY_AUTHENTICATION_REQUIRED) {
        authHeaders = challenge.getHeaders(ProxyAuthenticateHeader.NAME);
     }
     else {
        throw new IllegalArgumentException("Unexpected status code ");
     }
  }

  if (authHeaders == null) {
     throw new IllegalArgumentException("Could not find WWWAuthenticate or ProxyAuthenticate headers");
  }

  WWWAuthenticateHeader authHeader = null;
  while (authHeaders.hasNext()) {
     authHeader = (WWWAuthenticateHeader) authHeaders.next();
     String realm = authHeader.getRealm();

     this.uri = challengedRequest.getRequestURI();

     this.requestMethod = challengedRequest.getMethod();
     this.requestBody = (challengedRequest.getContent() == null) ? "" : new String(challengedRequest.getRawContent());

     if (this.accountManager instanceof SecureAccountManager) {
        UserCredentialHash credHash = ((SecureAccountManager) this.accountManager).getCredentialHash(challengedTransaction,
                                                                                                     realm);
        if (credHash == null) {
           logger.logDebug("Could not find creds");
           throw new SipException("Cannot find user creds for the given user name and realm");
        }

        this.authorizationHeader = this.getAuthorization(requestMethod, uri.toString(), requestBody, authHeader, credHash);
     }
     else {
        UserCredentials userCreds = ((AccountManager) this.accountManager).getCredentials(challengedTransaction, realm);
        if (userCreds == null) {
           throw new SipException("Cannot find user creds for the given user name and realm");
        }
        // sipDomain = userCreds.getSipDomain();
        // we haven't yet authenticated this realm since we were
        // started.

       this.authorizationHeader = this.getAuthorization(requestMethod, uri.toString(), requestBody, authHeader, userCreds);
     }
  }

  return this.authorizationHeader;

}

getAuthorization function :

 public AuthorizationHeader getAuthorization(String method,
                                           String uri,
                                           String requestBody,
                                           WWWAuthenticateHeader authHeader,
                                           UserCredentials userCredentials) throws SecurityException {
  String response = null;
  String qopList = authHeader.getQop();
  String qop = (qopList != null) ? "auth" : null;
  String nc_value = "00000001";
  String cnonce = "xyz";

  try {
     response = MessageDigestAlgorithm.calculateResponse(authHeader.getAlgorithm(),
                                                        userCredentials.getUserName(), authHeader.getRealm(),userCredentials.getPassword(), authHeader.getNonce(), nc_value, // JvB added
                                                 cnonce, // JvB added
                                                 method, uri, requestBody, qop,logger);
  }
  catch (NullPointerException exc) {
     throw new SecurityException("The received authenticate header was malformatted: " + exc.getMessage());
  }

  AuthorizationHeader authorization = null;
  try {
      if (authHeader instanceof ProxyAuthenticateHeader) {
         if (this.headerFactory != null) {
            authorization = headerFactory.createProxyAuthorizationHeader(authHeader.getScheme());
         }
         else {
            authorization = new ProxyAuthorization();
            authorization.setScheme(authHeader.getScheme()); 
         }
      } 
      else {
         if (this.headerFactory != null) {
            authorization = headerFactory.createAuthorizationHeader(authHeader.getScheme());
         }
         else {
            authorization = new Authorization();
            authorization.setScheme(authHeader.getScheme());
         }
      }

      authorization.setUsername(userCredentials.getUserName());
      authorization.setRealm(authHeader.getRealm());
      authorization.setNonce(authHeader.getNonce());
      authorization.setParameter("uri", uri);
      authorization.setResponse(response);
      if (authHeader.getAlgorithm() != null) {
          authorization.setAlgorithm(authHeader.getAlgorithm());
      }

      if (authHeader.getOpaque() != null) {
          authorization.setOpaque(authHeader.getOpaque());
      }

      // jvb added
      if (qop != null) {
          authorization.setQop(qop);
          authorization.setCNonce(cnonce);
          authorization.setNonceCount(Integer.parseInt(nc_value));
      }

      authorization.setResponse(response);

  } catch (ParseException ex) {
      throw new RuntimeException("Failed to create an authorization header!");
  }

  return authorization;

}

Finally, your this.authentication variable is ProxyAuthorizationHeader. You must put this.authentication in your INVITE message. And than you will sent SipMessage from transaction or dialog to JAIN-SIP stack.

Good Luck !

Upvotes: 2

Related Questions