Reading time: 3 – 5 minutes
Aquest és un d’aquells posts que podria tenir 40 títols diferents. De fet, només vull passar-vos un parell de trossos de codi un en C i l’altre en perl, que el que fan és obrir el port serie virtual que crea el modem UMTS/GPRS PCMCIA de Vodafone després l’hi envia la comanda AT corresponent per introduir el PIN del SIM que porta la targeta i llestos.
Abans de passar als temes de codis un petit resum d’ordres AT útils per temes de PIN:
AT+CPIN=1234 -> Introduim el PIN a la SIM del mòdem. AT+CPIN? -> preguntem al mòdem si ja hem introduit la SIM. AT+CPWD="SC",old_pin,new_pin -> canviem el PIN de la SIM.
De fet, si no voleu fer un codi tan bonic com el que jo uso, també podeu fer una cosa tan senzilla com aquesta:
# echo AT+CPIN=1234 > /dev/tts/USB0
Sent 1234 el codi PIN i /dev/tts/USB0 el dispositiu serie que crea el modem PCMCIA de vodafone.
Anant a codis una miqueta més interessants aquí teniu un trosset de codi C per fer el mateix que em fet en l’ordre anterior:
#include <stdio.h> /* Standard input/output definitions */ #include <string.h> /* String function definitions */ #include <unistd.h> /* UNIX standard function definitions */ #include <fcntl.h> /* File control definitions */ #include <errno.h> /* Error number definitions */ #include <termios.h> /* POSIX terminal control definitions */ main() { int fd; fd = open_port(); init_modem(fd); close(fd); } int open_port(void) { int fd; /* File descriptor for the port */ struct termios options; fd = open("/dev/tts/USB0", O_RDWR | O_NOCTTY | O_NDELAY); if (fd == -1) { /* * Could not open the port. */ perror("open_port: Unable to open /dev/tts/USB0 - "); } else fcntl(fd, F_SETFL, 0); /* get the current options */ tcgetattr(fd, &options); cfsetispeed(&options, B19200); cfsetospeed(&options, B19200); /* set raw input, 1 second timeout */ options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; options.c_cflag |= (CLOCAL | CREAD); options.c_cflag &= ~CNEW_RTSCTS; /* set the options */ tcsetattr(fd, TCSANOW, &options); return (fd); } int /* O - 0 = MODEM ok, -1 = MODEM bad */ init_modem(int fd) /* I - Serial port file */ { char buffer[255]; /* Input buffer */ char *bufptr; /* Current char in buffer */ int nbytes; /* Number of bytes read */ int tries; /* Number of tries so far */ for (tries = 0; tries < 3; tries ++) { /* send an AT command followed by a CR */ if (write(fd, "AT+CPIN=1234\r", 13) < 13) continue; /* read characters into our string buffer until we get a CR or NL */ bufptr = buffer; while ((nbytes = read(fd, bufptr, buffer + sizeof(buffer) - bufptr - 1)) > 0) { bufptr += nbytes; if (bufptr[-1] == '\n' || bufptr[-1] == '\r') break; } /* nul terminate the string and see if we got an OK response */ *bufptr = '\0'; if (strncmp(buffer, "OK", 2) == 0) return (0); } return (-1); }
Com en l’exemple anterior el dispositiu serie és /dev/tts/USB0 i el codi PIN 1234. Aquest codi és un copy/paste de la part d’un serial howto que ja no recordo ni d’on el vaig treure. Només m’he quedat amb el codi que em calia i hi he afegit algunes otpions que hi havia al howto però no als exemples de codi.
A continuació penjo un codi equivalent fet en perl. Com podeu veure aquest codi en perl té una dependència de la llibreria CPAN: Device::Gsm. Amb aquest llibreria també és molt senzill enviar SMS i descobrir algunes informacions del telèfon, com el fabricant o l’imei.
use Device::Gsm; my $gsm = new Device::Gsm( port => '/dev/tts/USB0', pin => '4466' ); if( $gsm->connect() ) { print "connected!\n"; } else { print "sorry, no connection with gsm phone on serial port!\n"; } # Register to GSM network (you must supply PIN number in above new() call) print $gsm->register();