C socket verbindet, Asterisk antwortet und dann Prob

chebrise

Neuer User
Mitglied seit
25 Jul 2006
Beiträge
69
Punkte für Reaktionen
0
Punkte
0
hallo wieder,

ich hab den C Code soweit, dass er sich mit dem Asterisk Server verbindet und auch der Asterisk antwortet.
Hier mal der C Code:
Code:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define BUF 1024

int main (int argc, char **argv) {
  int create_socket;
  char *buffer = malloc (BUF);
  struct sockaddr_in address;
  int size;

  if( argc < 2 ){
     printf("Usage: %s ServerAdresse\n", *argv);
     exit(EXIT_FAILURE);
  }

  printf ("\e[2J");
  if ((create_socket = socket (AF_INET, SOCK_STREAM, 0)) > 0)
    printf ("Socket wurde angelegt\n");

  address.sin_family = AF_INET;
  address.sin_port = htons (5038);
  inet_aton (argv[1], &address.sin_addr);

  if (connect ( create_socket,
                (struct sockaddr *) &address,
                sizeof (address)) == 0)
    printf ("Verbindung mit dem Server (%s) hergestellt\n",
       inet_ntoa (address.sin_addr));
  do {
      size = recv(create_socket, buffer, BUF-1, 0);
      if( size > 0)
         buffer[size] = '\0';
      printf ("Nachricht erhalten: %s\n", buffer);
      if (strcmp (buffer, "quit\n")) {
         printf ("Nachricht zum Versenden: ");
         fgets (buffer, BUF, stdin);
         send(create_socket, buffer, strlen (buffer), 0);
       }
  } while (strcmp (buffer, "quit\n") != 0);
  close (create_socket);
  return EXIT_SUCCESS;
}

diesen Code rufe ich mit der IP des Asterisk Servers auf und erhalte folgende Nachricht:
Code:
Socket wurde angelegt
Verbindung mit dem Server (192.168.1.7) hergestellt
Nachricht erhalten: Asterisk Call Manager/1.0

Nachricht zum Versenden:

dort mache ich folgendes, ganz nach dieser Webseite
Code:
Nachricht zum Versenden: Action: Login
ActionID: 1
Username: chebrise
Secret: passwort
und schließe dieses Befehlspaket mit einem doppelten Return ab.

Bei dem Asterisk Server tut sich garnichts, warum?
Erst wenn ich meinen C-Client schließe, sagt mir der Asterisk am anderen Ende:
== Connect attempt from '192.168.1.4' unable to authenticate

In der manager.conf des Asterisk Servers habe ich:
enabled = yes
webenabled = yes
read = system,call,log usw.
write = system,call,log usw.

Der Asterisk Server ist ein frisches Debian mit selbst compiliertem Asterisk 1.4.21

Der Client läuft auf einem aktuellen Ubuntu 8

Kann mir einer sagen was ich falsch mache, wo mein Denkfehler liegt oder was ich beim Asterisk vergessen habe?

Liegt es am C-Code, hoffe ich sehr, dass hier auch Kenner des C sind.

... würde mich schon sehr freuen wenn mir jemand auf den nächsten Sprung hilft!!!

so, dann hab ich es auch mal so wie es im das-asterisk-buch.de steht versucht, nämlich mit telnet. Da kam dann folgende Ausgabe:
failed to pass IP ACL as 'username'

mfg
 
Zuletzt bearbeitet:
die manager.conf muss so aussehen:
Code:
[general]
enabled = yes
bindaddr = 0.0.0.0
port = 5038
displaysystemname = yes
;webenabled = yes
;httptimeout = 60
;displayconnects = yes
;timestampevents = yes
 
[chebrise]
secret = password
deny = 0.0.0.0/0.0.0.0
permit = 127.0.0.0/255.0.0.0
permit = 10.0.0.0/255.0.0.0
;writetimeout = 100
read = all
write = all

also für jeden benutzer einen eigenen abschnitt. die reihenfolge von "deny" und "permit" ist wichtig, denn der letzte dieser zwei parameter, der zutrifft, zieht. im parameter "permit" musst du das ip netz angeben, von dem aus du zugreifen willst.

grundsätzliches problem dürfte aber der zeilenumbruch sein, es sollte "\r\n" pro zeile und "\r\n\r\n" pro anweisungsblock an die AMI gesendet werden. läuft der client unter linux, wird wahrscheinlich nur "\n" gesendet. check das mal mit "ngrep -x port 5038" auf dem asterisk server.

grüße,
laureen
 
Zuletzt bearbeitet:
Weiß ja nicht, ob das noch aktuell ist, aber das hört sich ganz so an, als würdest du deine Socket Buffer nicht flushen.
 
irgendwie noch aktuell

in PHP hab ich das gesehen:
Code:
# Output Buffer wird deaktiviert
# Alternativ könnten wir nach jeder Ausgabe
# fflush(STDOUT); aufrufen.
#################################################
ob_implicit_flush();

und das muss ich also auch in C machen!?
Wenn ich so drüber nachdenke, macht das Sinn.
Ich werds testen... danke dir
 
ok, falls es jemand interessiert. ich hab mir dann mal ordentlich nen Kopf gemacht welche Sprache denn nu die beste ist (für mich) um Asterisk fern zu steuern. Java kann auch mit Standart Sockets umgehen und mit folgendem Code aus der Java Bibel hört Asterisk wunderbar auf mich aus der ferne.
Code:
/* mitasteriskmanagerreden.java */



import java.net.*;

import java.io.*;



public class EchoClient

{

  public static void main(String[] args)

  {

    if (args.length != 1) {

      System.err.println("Usage: java EchoClient <host>");

      System.exit(1);

    }

    try {

      Socket sock = new Socket(args[0], 5038);

      InputStream in = sock.getInputStream();

      OutputStream out = sock.getOutputStream();

      //Timeout setzen

      sock.setSoTimeout(300); 

      //Ausgabethread erzeugen

      OutputThread th = new OutputThread(in);

      th.start();

      //Schleife fuer Benutzereingaben

      BufferedReader conin = new BufferedReader(

                             new InputStreamReader(System.in));

      String line = "";

      while (true) { 

        //Eingabezeile lesen

        line = conin.readLine();

        if (line.equalsIgnoreCase("QUIT")) {

          break;

        }

        //Eingabezeile an ECHO-Server schicken

        out.write(line.getBytes());

        out.write('\r');

        out.write('\n');

        //Ausgabe abwarten

        th.yield(); 

      }

      //Programm beenden

      System.out.println("terminating output thread...");

      th.requestStop();

      th.yield();

      try {

        Thread.sleep(1000);

      } catch (InterruptedException e) {

      }

      in.close(); 

      out.close();

      sock.close();

    } catch (IOException e) {

      System.err.println(e.toString());

      System.exit(1);

    }

  }

}



class OutputThread

extends Thread

{

  InputStream in;

  boolean     stoprequested;



  public OutputThread(InputStream in)

  {

    super();

    this.in = in;

    stoprequested = false;

  }



  public synchronized void requestStop()

  {

    stoprequested = true;

  }



  public void run()

  {

    int len;

    byte[] b = new byte[100];

    try {

      while (!stoprequested) { 

        try {

          if ((len = in.read(b)) == -1) { 

            break;

          }

          System.out.write(b, 0, len);

        } catch (InterruptedIOException e) { 

          //nochmal versuchen

        }

      }

    } catch (IOException e) {

      System.err.println("OutputThread: " + e.toString());

    }

  }

}
 
hast du dir schon mal asterisk-java (http://asterisk-java.org/) angesehen? da ersparst du dir das socket-handling, da dort beinahe alles abstrahiert ist...

grüße,
laureen
 
ich habe mir das asterisk-java mal angesehen. Das sieht ja gut aus... muss ich nur noch durchblicken womit ich da anfangen muss.

ich möchte von einem anderen PC aus auf Asterisk zu greifen also über STDIN und STDOUT.
Wenn ich z.B. per telnet mich mit Asterisk verbinden möchte meldet sich das AMI. Ich dachte das sind zwei verschiedene Paar Schuhe, komisch.

Also brauch ich auch mit asterisk-java immer die Verbindung mit dem AMI, also User und Pass und was der sonst noch so erwartet?!?

Ich hatte gehofft, dass ich Asterisk einfach per STDIN einen Befehl senden kann, ohne mich vorher zu authentisieren.
:( :confused:
 
:oops: :blonk:

mit STDOUT STDIN natürlich nur auf dem selben Rechner

asterisk-java super!!! ...funktioniert echt einfach und muss natürlich dann über das AMI

public static void verbinden(){
ManagerConnectionFactory factory;
ManagerConnection connection;

factory = new ManagerConnectionFactory(ip, user, passwd);
connection = factory.createManagerConnection();
try {
connection.login();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (AuthenticationFailedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TimeoutException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

connection.logoff();


}
 
Holen Sie sich 3CX - völlig kostenlos!
Verbinden Sie Ihr Team und Ihre Kunden Telefonie Livechat Videokonferenzen

Gehostet oder selbst-verwaltet. Für bis zu 10 Nutzer dauerhaft kostenlos. Keine Kreditkartendetails erforderlich. Ohne Risiko testen.

3CX
Für diese E-Mail-Adresse besteht bereits ein 3CX-Konto. Sie werden zum Kundenportal weitergeleitet, wo Sie sich anmelden oder Ihr Passwort zurücksetzen können, falls Sie dieses vergessen haben.