Bueno chicos, como os comentaba en mi anterior post, una vez he terminado la aplcación para gestionar con el pic los mensajes por gsm os pongo el código, porque creo que le puede servir a mucha gente.
Aunque en mis pruebas funciona de lujo, veremos a ver si al tiempo se sigue comportando igual.
De todos modos lo llamaremos version 1.
CODIGO:
#include <18f4431.h>
#include <string.h>
#fuses intrc,nomclr,t1lowpower,noprotect,noput,nowdt,nobrownout,nolvp
#use delay (clock=4Mhz)
#use rs232 (baud=9600,xmit=pin_c6,rcv=pin_c7,parity=n,bits=8)
int const lenbuff=100;
int pregunta=0;
int xbuff=0x00,flagcommand=0,final=0,a=0,v=0;
int espera_ok=0,simbolo=0;
char cbuff[lenbuff];
char rcvchar=0x00;
char pos_sms=0x00;
char telefono[10];
void inicbuff(void);
void procesa_comando(void);
#int_rda
void comunica()
{
rcvchar=0x00;
if (kbhit())
{
rcvchar=getc(); // recojo dato que me llega del puerto serie.
if(rcvchar==0x20)
{
if(simbolo)
{
goto espera_simbolo;
}
}
if(rcvchar!=0x0a)
{ //si es el caracter de inicio de linea, no lo acumulo en la cadena cbuff.
if (xbuff<100)
{
cbuff[xbuff++]=rcvchar; //introduzco el caracter recibidi del rs-232 en una nueva posicion de la cadena.
}
}
if(rcvchar==0x0d)
{ //si recibo un intro, hago lo siguiente.
final++; //incremento la variable final
if(pregunta)
{ //si la variable pregunta está a "1", necesito recoger cuatro (intros) para irme a procesar la trama.
if(final==4)
{
flagcommand=1;
final=0;
pregunta=0;
}
}else
{
if(final==2)
{
espera_simbolo:
flagcommand=1; //Nota: todo esto es porque si al modem yo no le pregunto nada, solo me puede enviar una trama cuando se le manda un mensaje
final=0; //por movila que es +cmti: "mt",X donde X me da la posicion en el cual se ha guardado el mensaje recibido en el gsm. Pues bien, esta trama
}
} //que el modem me envia está siempre contenida entre dos intros.
} //Cuando yo la recibo, lo que hago es recoger la posición donde se ha guardado el sms, y preguntarle al modem para que me lo envíe.
} //la trama que el modem me envía esta vez, está contenida entre cuatro intros, y por lo tanto, cuando yo pregunto al modem por el sms
} //mediante at+cmgr=X pongo a uno la variable pregunta para no procesar la trama hasta que haya recibido los cuatro intros.
void main ()
{
inicbuff(); //incio la cadena que va ha guardar la trama
for (a=0;a<10;a++)
{
telefono[a]='\0';
}
enable_interrupts(int_rda);
enable_interrupts(global);
do
{
if(flagcommand)
{
flagcommand=0;
procesa_comando();
}
}while(true);
}
void inicbuff(void)
{
int i;
for(i=0;i<lenbuff;i++)
{
cbuff[i]='\0';
}
xbuff=0x00;
}
void procesa_comando(void)
{
char *retorno1;
char *retorno2;
char *coma;
char *clave;
char *numero;
char string1[10];
char string2[10];
char string3[10];
char s1[10];
char s2[10];
char s3[10];
int i=0;
for (i=0;i<10;i++)
{ //pongo los strings a cero
s1[i]='\0';
s2[i]='\0';
s3[i]='\0';
string1[i]='\0';
string2[i]='\0';
string3[i]='\0';
} //NUEVO MENSAJE RECIBIDO.........................
if(espera_ok)
{
espera_ok=0;
inicbuff();
printf("at+cmgs=%s\r",telefono);
simbolo=1;
goto fin;
}
if(simbolo)
{
simbolo=0;
inicbuff();
printf("mensaje enviado\r");
putc(0x1a);
goto fin;
}
strcpy(string1,"+CMTI:"); //copio en la cadena STRING1 "+cmti:"
retorno1=strchr(cbuff,0x0d); //posiciono el puntero retorno1 al primer intro recibido
retorno1++; //lo incremento una posición.
strncpy(s1,retorno1,6); //introduzco en la cadena S1 seis caracteres de la cadena cbuff a partir de la posición que me marca el puntero
if (!stricmp(s1,string1))
{ //comparo que S1 y String1 sean igual "+cmti:"
coma=strchr(cbuff,0x2c); //pongo el puntero en la posición de la coma de cbuff
coma+=1; //lo incremento para que me apunte al numero donde está guardado el mensaje del modem
pos_sms=*coma;
inicbuff(); //copio el numero al que apunta en el char pos-sms
printf("AT+CMGR=%c\r",pos_sms); //le pregunto para que me envíe el mensaje(el de los cuatro intros).
pregunta=1; //pongo el chivato a "1" para saber que tengo que recibir 4 intros para procesar la trama.
goto fin;
} // RESPUESTA AL LEER MENSAJE......................
strcpy(string2,"+CMGR:"); //Aqui empezamos el procesamiento de la segunda trama.
retorno2=strchr(cbuff,0x0d); //el primer intro, también busco que el mensaje contenga la palabra "paco" desde la primera P.
retorno2++; //el cual se que está 5 posiciones despues de la primera ","=0x2c.
strncpy(s2,retorno2,6);
if (!stricmp(s2,string2))
{
strcpy(string3,"paco");
clave=strchr(cbuff,0x70);
strncpy(s3,clave,4);
if(!stricmp(s3,string3))
{
numero=strchr(cbuff,0x2c);
numero=numero+5;
strncpy(telefono,numero,9);
inicbuff();
espera_ok=1;
printf("at+cmgd=%c\r",pos_sms);
goto fin;
}else
{
inicbuff();
printf("at+cmgd=%c\r",pos_sms);
goto fin;
}
}
inicbuff();
fin:
v=0;
} // Pues el proble es que la primera trama siempre me la analiza bien, pero la segunda solo me la aniza bien la primera vez, o sea, cuando reinicio el pic.
// He observado al concluir los intros y empezar a procesar la trama, que la segunda vez que proceso la trama de cuatro intros, antes de hacer nada leo la cadena cbuff y no esta la trama completa. Ejemplo:
// cbuff bueno=[(intro)+cmgr: "red unread","+34676767789",,"23/10/2007etc...."/(into)paco(intro)ok(intro)]
// cbuff malo =[(intro)+cmgr: "rec unread","+34] por lo tanto faltan muchos caracteres.
// Pues eso es lo que me hace a partir de la segunda vez que hago el proceso completo, y lo gracioso es que yo voy leyendo la cadena cbuff y tengo todos los caracteres, y es cuando entro en VOID PROCESA COMANDO cuando desaparecen todos los caracteres.
El programa recibe del gsm la alarma de que le ha llegado un nuevo mensaje, recoge la posición en donde quedó guardado, lee el mensaje y lo borra. Si el mensaje contiene la contraseña correcta, recoge el número de teléfono y responde al movil con el mensaje o dato que queramos.
Espero les guste.
Si necesitais alguna explicacion o teneis alguna duda sobre el código, os ayudaré con mucho gusto.(siempre que pueda.)
Un saludo.
Editado por nocturno: he modificado el asunto para que sea más fácil encontrar