2010-02-10 23 views
3

J'ai actuellement un enregistrement SIP fonctionnant correctement avec Jain-SIP. Je reçois le défi, utilise MD5 sur le nonce etc et envoie ma réponse.Comment puis-je réenregistrer un serveur SIP correctement?

Je reçois alors le message 200 OK.

Donc tout va bien.

Cependant je veux réenregistrer automatiquement toutes les X secondes en fonction de l'heure d'expiration.

Pour ce faire, j'ai essayé d'utiliser une minuterie pour réexécuter le code toutes les X secondes.

Cependant, il conduit à deux problèmes:

Le SipProvider est déjà attaché et exécuter wont une deuxième fois. Ou Je reçois une erreur indiquant que la demande a déjà été envoyée.

Alors je me demandais si quelqu'un avait des conseils sur la meilleure façon de se réenregistrer avec le serveur toutes les X secondes? Comme dans les étapes recommandées à prendre?


code source registre public void() throws Exception {

// all this into a create request method 
    String fromName = "xxxxxxxx"; 
    String fromSipAddress = "sip.network.com"; 

    String toSipAddress = "sip.network.com"; 
    String toUser = "xxxxxxxx"; 

    SipURI fromAddress = addressFactory.createSipURI(fromName, 
      fromSipAddress); 

    Address fromNameAddress = addressFactory.createAddress(fromAddress); 
    FromHeader fromHeader = headerFactory.createFromHeader(
      fromNameAddress, null); 

    SipURI toAddress = addressFactory 
      .createSipURI(toUser, toSipAddress); 
    Address toNameAddress = addressFactory.createAddress(toAddress); 
    ToHeader toHeader = headerFactory.createToHeader(toNameAddress, 
      null); 

    URI requestURI = addressFactory.createURI(
      "sip:" + "sip.network.com"); 

    List<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); 
    String ipAddress = lp.getIPAddress(); 
    ViaHeader viaHeader = headerFactory.createViaHeader(ipAddress, 
      lp.getPort(), 
      lp.getTransport(), null); 

    viaHeaders.add(viaHeader); 

    CallIdHeader callIdHeader = sipProvider.getNewCallId(); 

    CSeqHeader cSeqHeader = headerFactory.createCSeqHeader(1L, 
      Request.REGISTER); 

    MaxForwardsHeader maxForwards = headerFactory 
      .createMaxForwardsHeader(70); 

    Request request = messageFactory.createRequest(requestURI, 
      Request.REGISTER, callIdHeader, cSeqHeader, fromHeader, 
      toHeader, viaHeaders, maxForwards); 

    SipURI contactUrl = addressFactory.createSipURI(fromName, fromSipAddress); 
    contactUrl.setPort(8002); 
    contactUrl.setLrParam(); 

    SipURI contactURI = addressFactory.createSipURI(fromName, "sip.network.com"); 
    contactURI.setPort(sipProvider.getListeningPoint(lp.getTransport()) 
      .getPort()); 

    Address contactAddress = addressFactory.createAddress(contactURI); 

    contactHeader = headerFactory.createContactHeader(contactAddress); 
    request.addHeader(contactHeader); 
    Header extensionHeader = headerFactory.createHeader("Expires", 
     "120"); 
    request.addHeader(extensionHeader); 

    inviteTid = sipProvider.getNewClientTransaction(request); 
    inviteTid.sendRequest(); 
    Log.d("AFTERSENDREQUEST", "SipProvider = : " + sipProvider.toString()); 

    Log.d("INVITETID", "inviteTid = " + inviteTid.getState()); 

    dialog = inviteTid.getDialog(); 

} 
public void processResponse(ResponseEvent responseEvent) { 
    Message message = Message.obtain(); 
    message.obj = "received response "+responseEvent.getResponse(); 
    handler.sendMessage(message); 
    Response response = (Response) responseEvent.getResponse(); 
    ClientTransaction tid = responseEvent.getClientTransaction(); 
    CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME); 

    if (response.getStatusCode() == Response.UNAUTHORIZED){ 
    try { 
     createAuthReply(authHeader, callid); 
    } catch (Exception e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

MISE À JOUR:

J'ai donc pensé que si je continue à créer de nouvelles méthodes les mêmes que le registre() Méthode et garder le même identifiant d'appel et le code de la configuration du numéro de port, je peux envoyer quelques messages comme celui-ci (pas en boucle).

Je dois donc changer quelque chose dans mon code de registre pour m'assurer que c'est une NOUVELLE demande envoyée à chaque fois ou quelque chose comme ça?

Quelqu'un a-t-il des idées?

Répondre

3

// Palm visage !!!!! Erreur était le SipProvider est attaché à l'activité (Android) et j'avais super.finish() dans le code qui a tué l'activité au mauvais moment de sorte que l'enregistrement a encore essayé, mais l'activité a disparu, donc le fournisseur de sip perdu son contexte.

Merci pour votre calvinscorner temps, vraiment l'apprécier

1

Vous n'avez pas besoin d'initialiser le fournisseur de services chaque fois que vous souhaitez envoyer une nouvelle demande d'enregistrement. Voici les étapes que je vous suggère de suivre.

  • Initialiser fournisseur de services
  • ENVOYAIENT première demande d'inscription.
  • Une fois que vous recevez 200 OK - récupérer le champ expire et démarrer un minuteur basé sur cette valeur expire.
  • Une fois que la minuterie est déclenchée, envoyez une nouvelle demande d'enregistrement - Ne réinitialisez pas le fournisseur de services. (Vous pouvez vérifier à nouveau le pointeur sipProvider pour NON NULL).
+0

J'ai essayé de faire cela, mais lorsque je tente de réinscrire je reçois cette erreur java.lang.NullPointerException gov.nist.javax.sip.SipProviderImpl.getNewCallId (SipProviderImpl.java:230) –

+1

Avez-vous une référence correcte de sipProvider pour initier sipProvider.getNewClientTransaction (request); ? Où perdez-vous cette référence? – calvinscorner

+0

J'ai ajouté plus de code ci-dessus, donc j'ai le init() pour configurer le SipProvider, puis le registre est créé et envoyé et je reçois 401 défi UnAuth, je réponds avec la réponse et obtenir 200 OK. Je réessaie alors de me réenregistrer mais quand j'essaye encore le getNewCAllId() jette une exception de pointeur nul –

2

Bon, j'ai passé pas mal de temps à analyser ce genre de choses. Et vraiment, je suis hors-indice sur ce que nous faisons mal? Tout me semble bien. Init/Envoi Registre/Démarrage d'une minuterie et expiration de la minuterie - Envoyez à nouveau une demande d'enregistrement. Il semble également que sipProvider est un objet global. Pouvez-vous juste pour le but de débogage effectuer deux choses

Fist, Invoke getNewCallId juste après que vous envoyez d'abord demande de registre, pour voir tout va bien.

callIdHeader = sipProvider.getNewCallId(); 

Ou peut-être essayer de changer

inviteTid = sipProvider.getNewClientTransaction(request); 

avant la getNewCallId dans la nouvelle Réenregistrer requst, à veify objet sipProvider est disponible. Ce que je dis est rien de plus que le style élémentaire de débogage.

+1

Ooops - Je viens de remarquer que j'ai ajouté une autre réponse au lieu de commenter.Sorries – calvinscorner

+1

Je l'ai compris, j'essayais d'obtenir un nouvel ID d'appel en essayant de réenregistrer mais il se trouve dans la spécification SIP que l'ID d'appel doit toujours être de même lors de l'envoi de messages de registre au serveur. J'ai un autre problème maintenant - inviteTid = sipProvider.getNewClientTransaction (request); lance une exception de pointeur nul !! :( –

+1

Non, l'identifiant d'appel ne doit pas forcément être le même, il peut aussi différer, c'est la raison pour laquelle le serveur défie et vérifie l'identité du client.Et je suis également d'avis que la méthode getNewcallId() ne devrait pas échouer. travail est de générer de nouveaux ID d'appel. il n'y a rien de mal à générer de nouvelles id d'appel. Comme on s'y attendait, toute référence à l'objet sipProvider est un échec. Auparavant, il ne parvenait pas à getNewCallId et maintenant getNewClientTransaction. est-il possible de Surveillez ce qui se passe sur cet objet une fois la première requête envoyée – calvinscorner