/* ** Universidade do Estado do Rio de Janeiro ** Faculdade de Engenharia ** Departamento de Sistemas e Computacao ** Autora: Elaine de Mattos Silva ** Projeto de Graduacao - Adequacao do Software ** de Simulacao Scicos para Aquisicao de Dados ** e o Controle em Tempo Real ** ------------------------------------------------------------------------------------------ ** Interface com o Scilab para funcao que carrega driver da placa de aquisicao remotamente ** Versao: ** 0.1 - 29/06/2009 - iniciados testes. ** 0.2 - 21/07/2009 - inseridas funcoes de remocao de espacos em branco e ** chamadas as funcoes remotas. ** ------------------------------------------------------------------------------------------ ** intconf.c -- chama modprobe e comedi_config remotamente com argumentos vindos do Scilab */ #include "/home/elaine/scilab-4.1.2/routines/stack-c.h" //funcoes de pilha do Scilab #include #include #include #include #include #include #include #include #include #include /* Interface para : --> [modprobeStat, configStat] = sci_modprobe (IP,ACQ,DEV,IO,IRQ) */ char *sci_modprobe __PARAMS((char *ip, char *acq,char *dev, char *io, char *irq, char *modprobeStat, char *configStat)); int conecta (char *ip); void remoteModprobe(char *acq, char *modprobeStat); void remoteComediConfig(char *dev, char *acq, char *io, char *irq, char *configStat); void removeBrancosFim(char str[], int tam); void removeBrancosIn(char str[], int tam); void sender(char *msg,char *Stat); int intconf(char *fname){ static int pos1,pos2,pos3,pos4, pos5, pos6, pos7; static int m1, m2, m3, m4, m5, m6, m7; static int n1, n2, n3, n4, n5, n6, n7; static char *varip = NULL; static char *varacq = NULL; static char *vardev = NULL; static char *vario = NULL; static char *varirq = NULL; /**************LOG***********************/ FILE *log = fopen("log.txt","w"); fprintf(log,"Antes das verificacoes da interface\n"); fflush(log); /* verifica numero de entradas de [modprobeStat, configStat] = sci_modprobe(IP,ACQ,DEV,IO,IRQ)*/ static int minlhs = 2, maxlhs = 2, minrhs = 3, maxrhs = 5; CheckRhs(minrhs, maxrhs); // lado direito: min 3 argumentos, max 5 argumentos. CheckLhs(minlhs, maxlhs); // lado esquerdo: min 2 arg., max 2 arg. fprintf(log,"lhs min: %d, lhs max: %d, rhs min: %d, rhs max %d\n",minlhs,maxlhs, minrhs, maxrhs); fflush(log); /* testa tipo do argumento */ if ( GetType(1) != sci_strings ){ Scierror(814, "%s: esperando por uma string",fname); fprintf(log,"Erro na string1\n"); fflush(log); exit (0); }else{ /* coloca argumento na pilha */ /* argumentos tipo string. Insere dimensoes em m1 e n1; pos1 eh ponteiro para a pilha de char (cstk)*/ GetRhsVar(1, "c", &m1, &n1, &pos1); varip = strdup (cstk(pos1)); } if ( GetType(2) != sci_strings) { Scierror(814, "%s: esperando por uma string",fname); fprintf(log,"Erro na string2"); fflush(log); exit(0); }else{ GetRhsVar(2,"c", &m2, &n2, &pos2); varacq = strdup(cstk(pos2)); } if ( GetType(3) != sci_strings) { Scierror(814, "%s: esperando por uma string",fname); fprintf(log,"Erro na string3"); fflush(log); exit(0); }else{ GetRhsVar(3,"c", &m3, &n3, &pos3); vardev = strdup(cstk(pos3)); } if ( GetType(4) != sci_strings) { Scierror(814, "%s: esperando por uma string",fname); fprintf(log,"Erro na string4"); fflush(log); exit(0); }else{ GetRhsVar(4,"c", &m4, &n4, &pos4); vario = strdup(cstk(pos4)); } if ( GetType(5) != sci_strings) { Scierror(814, "%s: esperando por uma string",fname); fprintf(log,"Erro na string5"); fflush(log); exit(0); }else{ GetRhsVar(5,"c", &m5, &n5, &pos5); varirq = strdup(cstk(pos5)); } fprintf(log,"dimensoes do primeiro arg: %d, %d. Dimensoes do segundo arg: %d, %d.\n",m1,n1, m2, n2); fflush(log); /*Cria uma variavel para saida e coloca na pilha */ CreateVar(6, "c", &m6, &n6, &pos6); CreateVar(7, "c", &m7, &n7, &pos7); fprintf(log,"Depois de criar variavel de saida\n"); fflush(log); fprintf(log,"Impressao de CVAR1 e CVAR2 '%s', '%s' '%s', '%s', '%s' \n",varip, varacq, vardev, vario, varirq); fflush; //nao podem existir espacos em branco nas strings removeBrancosFim(varip,strlen(varip)); removeBrancosFim(varacq,strlen(varacq)); removeBrancosFim(vardev,strlen(vardev)); removeBrancosFim(vario,strlen(vario)); removeBrancosFim(varirq,strlen(varirq)); fprintf(log,"Impressao de CVAR1 e CVAR2 '%s', '%s' '%s', '%s', '%s' \n",varip, varacq, vardev, vario, varirq); fflush; removeBrancosIn(varip,strlen(varip)); removeBrancosIn(varacq,strlen(varacq)); removeBrancosIn(vardev,strlen(vardev)); removeBrancosIn(vario,strlen(vario)); removeBrancosIn(varirq,strlen(varirq)); fprintf(log,"Impressao das variaveis depois de remover brancos '%s', '%s' '%s', '%s', '%s' \n",varip, varacq, vardev, vario, varirq); fflush; /*Chama funcao de usuario com os valores da pilha */ sci_modprobe(varip,varacq,vardev,vario,varirq,cstk(pos6),cstk(pos7)); /*primeiro argumento de saida, result, assume o valor da var na terceira posicao da pilha */ LhsVar(1) = 6; LhsVar(2) = 7; return 0; } char *sci_modprobe(char *ip, char *acq,char *dev, char *io, char *irq, char *modprobeStat, char *configStat){ printf("Dentro da funcao\n"); if (conecta(ip) != 0){ printf("ja conectado\n"); printf("testando variaveis: ip: '%s', acq: '%s', io: '%s', irq: '%s', dev: '%s'\n", ip, acq, io, irq, dev); remoteModprobe(acq, modprobeStat); } if (conecta(ip) != 0){ remoteComediConfig(dev,acq,io,irq,configStat); } printf("Retornos: modprobe: '%s', config: '%s'\n",modprobeStat, configStat); return modprobeStat; return configStat; } //define se IPv4 ou IPv6 void *get_in_addr(struct sockaddr *sa); int sockfd, numbytes; int conecta(char *ip){ #define PORTA "3490" #define BUFFERSIZE 1024 struct addrinfo hints,*servinfo, *p; //aponta para lista de resultados int status; struct sockaddr_storage client_addr; char s[INET6_ADDRSTRLEN]; socklen_t sin_size; memset(&hints, 0, sizeof hints); // zera estrutura addrinfo hints.ai_family = AF_UNSPEC; // nao importa se eh IPv4 ou 6 hints.ai_socktype = SOCK_STREAM; //escolhe TCP/IP //faz servinfo apontar para uma lista encadeada de 1 ou mais addrinfos. if ((status = getaddrinfo(ip,PORTA,&hints,&servinfo)) != 0){ fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status)); return 0; } //percorre lista e conecta com o primeiro resultado valido for(p = servinfo; p != NULL; p = p->ai_next){ if((sockfd = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == -1){ perror("cliente: socket\n"); return 0; continue; } if(connect(sockfd,p->ai_addr,p->ai_addrlen) == -1){ close(sockfd); perror("cliente: connect\n"); return 0; continue; } break; } if(p == NULL){ fprintf(stderr, "cliente: nao foi possivel conectar ao servidor\n"); return 0; } inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr),s,sizeof s); printf("cliente: conectado a %s\n",s); return 1; freeaddrinfo(servinfo); } void remoteModprobe(char *acq,char *modprobeStat){ char *modprobeMsg = malloc(BUFFERSIZE *sizeof(char)); bzero(modprobeMsg, BUFFERSIZE * sizeof(char)); char *msg = "comedi_modprobe/-v/"; strcat(modprobeMsg,msg); strcat(modprobeMsg, acq); strcat(modprobeMsg, "/"); printf("Mensagem enviada pela remoteModprobe '%s'\n",modprobeMsg); sender(modprobeMsg, modprobeStat); } void remoteComediConfig(char *dev,char *acq,char *io,char *irq, char *configStat){ char *configMsg = malloc(BUFFERSIZE * sizeof(char)); bzero(configMsg, BUFFERSIZE * sizeof(char)); char *msg = "comedi_config/"; strcat(configMsg,msg); strcat(configMsg,dev); strcat(configMsg, "/"); strcat(configMsg,acq); strcat(configMsg,"/"); printf("Msg enviada pelo comedi_config: '%s' \n", configMsg); if (strcmp(io," ")) strcat(configMsg,io); if(strcmp(irq, " ")){ strcat(configMsg,"/"); strcat(configMsg,irq); } printf("Mensagem enviada pela remoteComediConfig '%s'\n", configMsg); sender(configMsg, configStat); } void sender(char *msg,char *Stat){ //prepara mensagem a ser enviada ao servidor (usando protocolo HTTP) char *httpSendHeader = "GET /"; char *sendBuffer = malloc(sizeof(char) * BUFFERSIZE); bzero(sendBuffer, sizeof sendBuffer); strcpy(sendBuffer,httpSendHeader); int sentBytes, argnum; //concatena mensagens strcat(sendBuffer,msg); strcat(sendBuffer," HTTP/1.1"); printf("Argumentos a ser enviados para servidor: %s\n",sendBuffer); //envia dados para o servidor sentBytes = write(sockfd,sendBuffer,strlen(sendBuffer)); printf("Enviados %d bytes\n",sentBytes); if(sentBytes < 0){ perror("cliente: write"); close(sockfd); } //recebe dados do servidor int bytesRead = 0; int numBytes = 0; char buff[BUFFERSIZE]; bzero(buff, sizeof buff); numBytes = read(sockfd, buff, BUFFERSIZE -1); if(numbytes == -1){ perror("read"); close(sockfd); }else{ printf("%s\n",buff); } //copia buffer com mensagens do servidor para variavel que esta na pilha do Scilab strcpy(Stat,buff); close(sockfd); } void *get_in_addr(struct sockaddr *sa){ if (sa->sa_family == AF_INET){ return &(((struct sockaddr_in*) sa)->sin_addr); } return &(((struct sockaddr_in6*)sa)->sin6_addr); } void removeBrancosFim(char str[], int tam){ int i; for(i = tam; i >0 ; --i){ if (isspace(str[i]) && (str[i-1] != ' ')) str[i] = '\0'; } } void removeBrancosIn(char str[], int tam){ int i,j; char *str2; str2 = malloc(sizeof(char) * tam); bzero(str2,sizeof(char) * tam); j = 0; printf("String auxiliar '%s'\n",str); for (i = 0; i < tam; i++){ if(str[i] != ' '){ str2[j++] = str[i]; } } str2[j] = '\0'; bzero(str,strlen(str)); printf("String auxiliar depois '%s'\n",str2); strcpy(str,str2); }