2005/12/05
No Comments
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();