PDA

Voir la version complète : Connexion Socket en C sur serv ASTERISK



overchip
25/03/2015, 13h17
Bonjour,
Je suis actuellement en BTS de développement informatique et mon entreprise me demande d'éffectuer une connexion socket sur un serveur ASTERISK je m'y suis donc mis et ce qu'il en ressort c'est une pauvre ligne qui s'affiche a la fin de l’exécution du programme la ligne étant:
Asterisk Call Manager/1.1
je suppose donc que la liaison s’effectue bien.
lors de la compilation du programme j'obtiens un message d’erreur qui est le suivant:

connexionsock.c: In function ‘main’:
connexionsock.c:84:30: warning: comparison between pointer and integer [enabled by default]

je ne comprend pas bien cette erreur car je ne pense pas avoir utilisé de pointeurs dans mon code.
voici donc mon code

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <resolv.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>

#define PORT_TIME 13 /* "time" (not available on RedHat) */
#define PORT_FTP 5038 /* FTP connection port */
#define SERVER_ADDR "192.168.112.238" /* localhost */
#define MAXBUF "1024" /* DEF Buffer*/
#define LOGINASTERISK "AppDWH" /*login connexion asterisk*/
#define PASSASTERISK "AppDWHSecret123" /*MDP connexion asterisk*/


int main()
{ int sockfd;
int errno;
struct sockaddr_in dest;
char buffer[1024];
int taille;


/*---Open socket for streaming---*/
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
{
printf("Socket open fail");
return 0;
}

/*---Initialize server address/port struct---*/
bzero(&dest, sizeof(dest));
dest.sin_family = AF_INET;
dest.sin_port = htons(PORT_FTP);
if ( inet_aton(SERVER_ADDR, &dest.sin_addr.s_addr) == 0 )
{
printf(SERVER_ADDR);
return 0;
}

/*---Connect to server---*/
if ( connect(sockfd, (struct sockaddr*)&dest, sizeof(dest)) != 0 )
{
printf("Connect fail ");
return 0;
}

/*---Get "Hello?"---*/
while(1)
{
taille=recv(sockfd,& buffer,sizeof(buffer),0);
buffer[taille]='\0';
printf("%s",buffer);
if ((taille=='\0')||(recv==-1)) break;
}
printf("\n");

/*---Clean up---*/
printf("close connexion\n");
close(sockfd);
return 0;
}

Si l'un d'entre vous a une petite idée sur les éventuelles erreurs que j'aurai fais je suis preneur.
cordialement un apprenti développeur dans l'impasse.
Bonne journée a tous :)

jean
25/03/2015, 15h01
fichtre, ça m'a tellement rappelé ma jeunesse que j'ai regardé, bien que ce soit une histoire de c et pas d'asterisk

pour moi, ca tilte sur la ligne
if ((taille=='\0')||(recv==-1)) break;

taille est un entier
'\0' est une chaine de caracteres, vide - implicitement, donc, dans cette ligne, tu as un pointeur vers une chaine de caracteres vides (il n'y a pas d'objet chaine/string en c de mémoire, que des caracteres)

si tu mets:
if ((taille==0)||(recv==-1)) break;

bon, mais c'est pas ca.... ah... je vieillis !

en fait, recv est une fonction, -1 une constante, donc, en mettant le nom de la fonction sans (), tu obtiens un pointeur vers cette fonction - et la, j'ai pas de solution, car je comprends pas ce que tu veux faire

en virant le recv==-1, ca compile, meme avec le '\0', mais si tu le laisses, je sais pas la logique qui fait que ca marche

overchip
25/03/2015, 17h54
Merci de ta réponse :)
j'ai résolu mon problème de warning la fonction recv n'avais rien a faire ici donc j'ai remplacé la ligne


if ((taille=='\0')||(recv==-1)) break;


par


if(taille < 1) break;


il faut maintenant que je trouve comment donner les identifiants de connexion a mon serveur Asterisk afin qu'il puisse m'afficher les log :)

jean
25/03/2015, 19h45
cool

la suite est là:

http://www.voip-info.org/wiki/view/Asterisk+manager+API

en gros, tu alternes les send (login) avec les recv (attendre le prompt que tu attendrais si tu étais devant la console), puis send ....

overchip
30/03/2015, 11h24
Bonjour a tous.
je me suis donc mis a tester les send afin de passer mes identifiants au serveur asterisk mais je crois ne pas avoir saisi cette fameuse fonction send si l'un d'entre vous pourais m'éclairer ca serait le top.
donc voici ce que jai commencer a faire:


/*--login-to-asterisk--*/
send(sockfd, "Action: Login\r\n");
recv(sockfd,& buffer,sizeof(buffer),0);
buffer[taille]='\0';
printf("%s",buffer);



bien évidement cella ne marche pas et m'affiche une erreur:

sock.c:58: warning: passing argument 1 of ‘send’ makes integer from pointer without a cast
/usr/include/sys/socket.h:141: note: expected ‘int’ but argument is of type ‘char *’
sock.c:58: error: too few arguments to function ‘send’

overchip
31/03/2015, 10h27
Bonjour,
je continue a mettre a jour ce post ça pourras toujours servir :)

Donc je pense presque toucher au but donc voici mon code:



/************************************************** ***************************/
/*** client-socket-Asterisk.c ***/
/*** ***/
/************************************************** ***************************/

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <resolv.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>

#define PORT_TIME 13 /* "time" (not available on RedHat) */
#define PORT_FTP 5038 /* FTP connection port */
#define SERVER_ADDR "192.168.112.238" /* localhost */
#define MAXBUF "1024" /* DEF Buffer*/
#define LOGINASTERISK "username: testA" /*login connexion asterisk*/
#define PASSASTERISK "secret: MDPtestA" /*MDP connexion asterisk*/
#define ACTION "Action: login" /*Action Serv Asterisk*/
#define EVENT "Events: on" /*Action Serv Asterisk*/
int main()
{ int sockfd;
int errno;
struct sockaddr_in dest;
char buffer[1024];
int taille;
char login;
int retour;

/*---Open socket for streaming---*/
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
{
printf("Socket open fail");
return 0;
}

/*---Initialize server address/port struct---*/
bzero(&dest, sizeof(dest));
dest.sin_family = AF_INET;
dest.sin_port = htons(PORT_FTP);
if ( inet_aton(SERVER_ADDR, &dest.sin_addr.s_addr) == 0 )
{
printf(SERVER_ADDR);
return 0;
}

/*---Connect to server---*/
if ( connect(sockfd, (struct sockaddr*)&dest, sizeof(dest)) != 0 )
{
printf("Connect fail ");
return 0;
}
/*--login-to-asterisk--*/
login = send(sockfd,ACTION,sizeof(buffer),0 );
if (retour == SOCK_STREAM){
return 0;
}
login = send(sockfd,LOGINASTERISK,sizeof(buffer),0 );
if (retour == SOCK_STREAM){
return 0;
}
login = send(sockfd,PASSASTERISK,sizeof(buffer),0 );
if (retour == SOCK_STREAM){
return 0;
}
login = send(sockfd,EVENT,sizeof(buffer),0 );
if (retour == SOCK_STREAM){
return 0;
}
/* login = send(sockfd,LOGINASTERISK,sizeof(buffer),0 );
if (retour == SOCK_STREAM){
return 0;
}*/

/*---Get "Hello?"---*/
while(1)
{
taille=recv(sockfd,& buffer,sizeof(buffer),0);
buffer[taille]='\0';
printf("%s",buffer);
}
printf("\n");

/*---Clean up---*/
printf("close connexion\n");
close(sockfd);
return 0;
}



Alors maintenant quand je lance mon application il me met un nouveau message d’erreur:
Asterisk Call Manager/1.1
Response: Error
Message: Authentication failed

Response: Error
Message: Authentication failed

ce qui me viens a l’esprit dans un premier temps est un problème de login mot de passe, mais je suis parti vérifier dans mon serv asterisk mes identifiants le chemin d’accès pour les identifiants est le suivant :

/etc/asterisk/manager.conf

voici un extrait de mon manager.conf avec mes identifiants

[testA]
secret = MDPtestA
deny=0.0.0.0/0.0.0.0
permit=127.0.0.1/255.255.255.255
permit=192.168.112.0/255.255.255.0
read = system,call,log,verbose,agent,user,config,dtmf,rep orting,cdr,dialplan
write = system,call,agent,user,config,command,reporting,or iginate
displayconnects = yes

Donc je suis toujours en pleine quête si quelqu'un i voit plus clair je suis prêt a écouter :)
Bonne journée.

jean
31/03/2015, 15h34
à mon avis, d'abord pour la "beauté" du code et sa logique, et probablement parce que c'est pour cela que ca ne marche pas, ne pas balancer toutes les données d'un coup comme un sauvage, mais attendre le retour du serveur.... après le connect, attendre qu'il demande username (ie, qu'un receive soit réussi à avec la chaine username - ou celle qui va bien), puis envoyer le username, puis attenre "password" - ou ce qui va bien, puis seulement balancer le password

si tu veux en etre sur, installe ngrep, ouvre une autre session, lance un ngrep port 5038 - tu verras les echanges se faire, et que tu envoies les infos au mauvais moment

ensuite, ton test if retour == sock_stream ne sert à rien, puisque ce n'est pas la valeur de retour de la fonction précédente, et que cette variable n'est jamais initialisée - donc, c'est de la chance que le test passe....

while (1) - et aucun break... donc, sans ctrl-c, on sort pas du programme.....

y'a du boulot........