Bogusław Kempny

sms

×
Autor English
Początek HC-SR04 LCD Kamera fork() sms strfry() GPIO impulsy Klawiatura Brama GPIO PWM SG90 RFID Grafolog RCP Shutdown Temperatura ....











No to teraz jak tem program wysyłający smsy działa.

Pełny tekst źródłowy jest w pliku wskazywanym linkiem na poprzedniej stronie, więc pominiemy tu takie jego elementy, które nie są istotne dla jego zrozumienia.

Na początek otwieramy plik logów, gdzie będą zapisywane informacje o wysłanych smsach, wpisujemy do niego bieżący czas, numer telefonu, na który wysyłamy sms i jego treść. Plik logów otwieramy w trybie "a", wszystko będzie dopisywane na jego końcu, bez niczszenia zastanej zawartości.

fp=fopen("/var/log/sms.log", "a");
time (&czas);
loctime = localtime (&czas);
strftime (data, 50, "%Y-%m-%d %H:%M: ", loctime);
fprintf(fp, "%s %s ", data, argv[1]); fflush(0);
fprintf(fp, "%s ", argv[2]); fflush(0);

No i otwieramy port szeregowy, do którego podpięliśmy modem.
Nie chcemy, żeby w tym samym czasie jakiś inny proces też coś z naszym modemem kombinował, więc na cas kiedy wysyłamy sms zabraniamy innym procesom korzystać z naszego portu szeregowego.

inicjujemy w tym celu strukturę fl:

fl.l_type   = F_WRLCK;  /* F_RDLCK, F_WRLCK, F_UNLCK    */
fl.l_whence = SEEK_SET; /* SEEK_SET, SEEK_CUR, SEEK_END */
fl.l_start  = 0;        /* Offset from l_whence         */
fl.l_len    = 0;        /* length, 0 = to EOF           */
fl.l_pid    = getpid(); /* our PID                      */

Otwieramy nasz port szeregowy ustawiając flagi NOCTTY (nie twórz terminala sterującego), RDWR (na odczyt i zapis) NONBLOCK (jeśli nie czekaj az znak nadejdzie, jeśli nie ma niczego do odczytania, wróć natychmiast z błędem).
Flaga O_NOCTTY ma znaczenie, choć nie we wszystkich systemach Unix, przy otwieraniu urządzeń terminalowych. Lepiej ją ustawić. Pełny opis, o co chodzi znajdziesz w dokumentacji glibc

 
if ((fd2 = open ("/dev/ttyUSB0",
                   O_NOCTTY | O_RDWR | O_NONBLOCK)) != -1)
 {

Zakładamy natychmiast lock na nasz otwarty plik.
Do czasu jego zdjęcia, albo zakończenia naszego procesu nikt inny nie będzie miał do naszego portu dostępu.

  fcntl(fd2,F_SETLKW,&fl); // set lock, czekaj, jesli ktos inny to zrobil

Teraz musimy nasz port szeregowy zaprogramować. I tu kontynuacja rozważań o historii Linuxa z poprzedniej strony. Pu programowanie portu szeregowego to nie tylko ustawienie prędkości, liczby bitów stopu i sposobu sterowania transmisją. Ustawienia naszego portu szeregowego będą na przykład takie:

root@mobile3:/home/rcp# stty -a -F /dev/ttyUSB0
speed 9600 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>;
swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;
lnext = ^V; flush = ^O; min = 1; time = 5;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread clocal -crtscts
ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff
-iuclc -ixany -imaxbel -iutf8
-opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
-isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop -echoprt
-echoctl -echoke

Driver naszego portu szeregowego to jakby część oprogramowania terminala znakowego podpiętego do niego, potrafi zamieniać znaki sterujące (np. CR i LF), wstrzymywać transmisję, produkować lokalne echo wysyłanych znaków. Nie jest nam to potrzebne, ale trzeba powyłączać to, co może nam przeszkadzać, na przykład zamianę CR na LF.

No to programujemy. Czytamy zastane ostawienia (tcgetattr), ustawiamy prędkość (cfsetspeed), ustawiamy flagi i programujemy port (tcgetattr)

  tcgetattr (fd2, &opcje);
  predkosc = B4800;
  cfsetspeed (&opcje, predkosc);
  opcje.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
  opcje.c_cflag &= ~PARENB;
  opcje.c_cflag &= ~PARODD;
  opcje.c_cflag &= ~CSTOPB;
  opcje.c_cflag &= ~CSIZE;
  opcje.c_cflag |= CS8;
  opcje.c_cflag &= ~CRTSCTS;
  opcje.c_iflag &= ~IXON;
  opcje.c_iflag &= ~IXOFF;
  opcje.c_iflag &= ~INLCR;
  opcje.c_iflag &= ~ICRNL;
  opcje.c_oflag &= ~ONLCR;
  opcje.c_oflag &= ~OCRNL;
  tcsetattr (fd2, TCSANOW, &opcje);

No to port szeregowy załatwiony, możemy wysyłać smsy.