Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
gsm.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2009 ENAC, Arnaud Quintard, Pascal Brisset
3 *
4 * This file is part of paparazzi.
5 *
6 * paparazzi is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * paparazzi is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with paparazzi; see the file COPYING. If not, write to
18 * the Free Software Foundation, 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 *
21 */
22
23/*
24http://www.telit.com/en/products/gsm-gprs.php?p_ac=show&p=12#downloads
25
26Init:
27 Out: ATE0
28 In: OK
29 Out: AT+CMGF=1
30 In: OK
31 Out: AT+CNMI=1,1,0,0,0
32 In: OK
33 Out : AT+CPMS=\"SM\"
34 In: +CPMS:
35
36Reporting:
37 Out: AT+CSQ
38 In: +CSQ: <rssi>,<ber>
39 In: OK
40 Out: AT+CMGS=\"GCS_NUMBER\"
41 In: >
42 Out: gps.utm_pos.east, gps.utm_pos.north, gps.course, gps.hmsl, gps.gspeed, -gps.ned_vel.z, electrical.vsupply, autopilot.flight_time, rssi CTRLZ
43
44Receiving:
45 In: +CMTI: ...,<number>
46 Out: AT+CMGR=<number>
47 In: +CMGR ...
48 In: B42 (or S42 3.14)
49 Out: AT+CMGD=<number>
50 In: OK
51*/
52
53#include <stdbool.h>
54#include <string.h>
55#include <stdio.h>
56#include <stdlib.h>
57
58#include "gsm.h"
59#include "mcu_periph/uart.h"
60#include "std.h"
62#include "modules/gps/gps.h"
63#include "autopilot.h"
65//#include "modules/nav/common_nav.h" //why is should this be needed?
66#include "generated/settings.h"
67#include "led.h"
68
69#ifndef GSM_LINK
70#define GSM_LINK UART3100
71#endif
72
73#define GSM_MAX_PAYLOAD 160
74
75#define GSMLinkDev (&(GSM_LINK).device)
76
77#define GSMLinkChAvailable() GSMLinkDev->check_available(GSMLinkDev->periph)
78#define GSMLinkTransmit(_c) GSMLinkDev->put_byte(GSMLinkDev->periph, 0, _c)
79#define GSMLinkGetch() GSMLinkDev->get_byte(GSMLinkDev->periph)
80#define ReadGSMBuffer() { while (GSMLinkChAvailable&&!gsm_line_received) gsm_parse(GSMLinkGetch()); }
81
82
83#define CTRLZ 0x1A
84#define GSM_ORIGIN_MAXLEN 32
85#define DATA_MAXLEN 128
86
87#define CMTI "+CMTI:"
88#define MAXLEN_CMTI_ANSWER 32
89#define MAXLEN_SMS_CONTENT DATA_MAXLEN
90
92static bool prompt_received;
93static bool waiting_for_reply; /* An AT command has been sent and an answer is expected */
94
95// static char msg_status[16];
96// static char msg_date[32];
97
98static char expected_ack[10];
103
104#define STATUS_NONE 0
105#define STATUS_CSQ 1
106#define STATUS_REQUESTING_MESSAGE 2
107#define STATUS_SEND_AT 3
108#define STATUS_SEND_CMGF 4
109#define STATUS_SEND_CNMI 5
110#define STATUS_SEND_CPMS 6
111#define STATUS_RECEPTION_SMS2 7
112#define STATUS_WAITING_DATA 8
113#define STATUS_IDLE 9
114#define STATUS_WAITING_PROMPT 10
115#define STATUS_DELETE_SMS 11
116#define STATUS_POWERON 12
117
119
121
122static void Send_AT(void);
123static void Send_CMGF(void);
124static void Send_CNMI(void);
125static void Send_CPMS(void);
126static void Suppr_SMS(int);
127static void gsm_send_report_continue(void);
128static void gsm_parse(uint8_t c);
129static void gsm_got_line(void);
130static void gsm_got_prompt(void);
131static void gsm_receive_content(void);
132static void request_for_msg(void);
133static void Send_CSQ(void);
134static void Send(const char string[]);
135static void parse_msg_header(void);
136static char *indexn(char *, char, uint8_t);
137
138
141
142
143/*****************************************************************************/
144void gsm_init(void)
145{
146 if (gsm_status == STATUS_NONE) { /* First call */
149 //} else { /* Second call */
150 // gsm_buf_idx = 0;
151 // gsm_line_received = false;
152 //
153 // Send_AT();
154 // gsm_status = STATUS_SEND_AT;
155 // gsm_gsm_init_status = false;
156 }
157 gcs_index = 0;
158 gcs_index_max = 0;
159#ifdef GCS_NUMBER_1
161#endif
162#ifdef GCS_NUMBER_2
164#endif
165}
166
167void gsm_init_report(void) /* Second call */
168{
169 if (gsm_status != STATUS_NONE) {
170 gsm_buf_idx = 0;
171 gsm_line_received = false;
172
173 Send_AT();
176 }
177}
178
195
196
197// A line of length gsm_buf_len is available in the gsm_buf buffer
198static void gsm_got_line(void)
199{
200 if (gsm_status == STATUS_WAITING_DATA) { // Currently receiving a SMS
204 } else if (gsm_status == STATUS_IDLE
205 && strncmp(CMTI, gsm_buf, strlen(CMTI)) == 0) {
206 /* A SMS is available */
207 /* Extracting the index of the message */
209 if (first_comma) {
213 }
214 } else if (waiting_for_reply) { // Other cases
215 // Do we get what we were expecting
216
218 if (gsm_answer) {
219 waiting_for_reply = false;
220
221 switch (gsm_status) {
222 case STATUS_CSQ :
225 break;
226
230 break;
231
232 case STATUS_SEND_AT :
233 gsm_answer = false;
234 Send_CMGF();
236 break;
237
238 case STATUS_SEND_CMGF :
239 gsm_answer = false;
240 Send_CNMI();
242 break;
243
244 case STATUS_SEND_CNMI :
245 gsm_answer = false;
246 Send_CPMS();
248 break;
249
250 case STATUS_SEND_CPMS :
251 gsm_answer = false;
254 break;
255
256 case STATUS_DELETE_SMS :
258 break;
259
260 default:
261 break;
262 }
263 } else {
264 /* Let's wait for the next line */
265 }
266 }
267}
268
269
270
271// Receiving a SMS, first step: asking for a given message
272static void request_for_msg(void)
273{
274 char demande_lecture_SMS[16];
275
276 strcpy(expected_ack, "+CMGR");
277 sprintf(demande_lecture_SMS, "AT+CMGR=%d", index_msg);
278 waiting_for_reply = true;
280}
281
282
288static void gsm_receive_content(void)
289{
290 // ?????? sprintf(data_to_send, "%d %s %s %s %s", index_msg, flag, expediteur, dateheure, data_recue);
291 // ?????? Send(data_to_send);
292
293 // Checking the number of the sender
294 if (
295//#if ! (defined GCS_NUMBER_1 || defined GCS_NUMBER_2 || defined SAFETY_NUMBER_1 || defined SAFETY_NUMBER_2)
296 true
297//#else
298// false
299//#endif
301 || strncmp((char *)GCS_NUMBER_1, origin, strlen(GCS_NUMBER_1)) == 0
302#endif
304 || strncmp((char *)GCS_NUMBER_2, origin, strlen(GCS_NUMBER_2)) == 0
305#endif
308#endif
311#endif
312 ) {
313 // Decoding the message ...
314
315 // Search for the instruction
316 switch (gsm_buf[0]) {
317 case 'B' : {
319 if (block_index > 0) { /* Warning: no way to go to the first block */
321 }
322 break;
323 }
324 case 'S' : {
326 if (var_index > 0) {
327 float value = atof(indexn(gsm_buf, ' ', MAXLEN_SMS_CONTENT) + 1);
328 DlSetting(var_index, value);
329 }
330 }
331
332 default:
333 // Report an error ???
334 break;
335 }
336 }
337}
338
339
340// Deleting a SMS
342{
343 char demande_suppression[20];
344
345 sprintf(demande_suppression, "AT+CMGD=%d", index_);
346 strcpy(expected_ack, "OK");
347 waiting_for_reply = true;
349}
350
351
352// We just have received a prompt ">" (we are sending a SMS)
353static void gsm_got_prompt(void)
354{
355 if (gsm_status == STATUS_WAITING_PROMPT) { // We were waiting for a prompt
356 char string[strlen(data_to_send) + 3];
357
358 sprintf(string, "%s%c", data_to_send, CTRLZ);
359 Send(string);
360 }
361
363}
364
367static void parse_msg_header(void)
368{
369 /* Extraction du flag*/
372 /* Extraction de l'expediteur*/
373 // Extraction(buffer2, '"', 2, 1, '"', 1, 0, origin);
374
375 /* Extraction de date heure*/
376 // Extraction(buffer2, '"', 4, 1, '"', 1, 0, msg_date);
377
378 //pb d'ecriture du flag => solution de fortune (pb si flag != rec unread)
379 //??????? strncpy(flag, flag, 10);
380}
381
382
383
384// Periodic message, first step (called every 60s)
386{
388 if (gsm_status == STATUS_IDLE) {
389 // Checking the network coverage
390 Send_CSQ();
392 }
393}
394
395
396// Sending a message, second step; we have asked for network quality
398{
399 //We got "+CSQ: <rssi>,<ber>" <rssi> and <ber> on 2 digits (cf 3.5.4.4.4)
400 // and we expect "OK" on the second line
401 uint8_t rssi = atoi(gsm_buf + strlen("+CSQ: "));
402
403 // Donnee GPS :ne sont pas envoyes gps_mode, gps.tow, gps.utm_pos.zone, gps_nb_ovrn
404 // Donnees batterie (seuls vsupply et autopilot.flight_time sont envoyes)
405 // concatenation de toutes les infos en un seul message à transmettre
406 sprintf(data_to_send, "%ld %ld %d %ld %d %d %d %d %d", gps.utm_pos.east, gps.utm_pos.north, gps_course, gps.hmsl,
408
409 // send the number and wait for the prompt
410 char buf[32];
411 switch (gcs_index) {
412#ifdef GCS_NUMBER_1
413 case 0 :
414 sprintf(buf, "AT+CMGS=\"%s\"", GCS_NUMBER_1);
415 Send(buf);
416 break;
417#endif
418#ifdef GCS_NUMBER_2
419 case 1 :
420 sprintf(buf, "AT+CMGS=\"%s\"", GCS_NUMBER_2);
421 Send(buf);
422 break;
423#endif
424 default :
425 gcs_index = 0;
426 break;
427 }
428 gcs_index++;
429 if (gcs_index == gcs_index_max) { gcs_index = 0; }
430}
431
432
433
434
435static void Send_AT(void)
436{
437 strcpy(expected_ack, "OK");
438 waiting_for_reply = true;
439
440 Send("ATE0");
441}
442
443static void Send_CMGF(void)
444{
445 strcpy(expected_ack, "OK");
446 waiting_for_reply = true;
447 Send("AT+CMGF=1");
448}
449
450static void Send_CSQ(void)
451{
452 /***** FIXME ****** strcpy(expected_ack, "+CSQ:"); ****/
453 strcpy(expected_ack, "OK");
454 waiting_for_reply = true;
455 Send("AT+CSQ");
456}
457
458static void Send_CNMI(void)
459{
460 strcpy(expected_ack, "OK");
461 waiting_for_reply = true;
462 Send("AT+CNMI=1,1,0,0,0");
463}
464
465static void Send_CPMS(void)
466{
467 strcpy(expected_ack, "+CPMS:");
468 waiting_for_reply = true;
469 Send("AT+CPMS=\"SM\"");
470}
471
472
473static void gsm_parse(uint8_t c)
474{
475 switch (c) {
477 break;
478 case '>':
479 prompt_received = true;
480 break;
482 gsm_buf[gsm_buf_idx] = '\0';
483 gsm_line_received = true;
485 gsm_buf_idx = 0;
486 break;
487 default:
489 gsm_buf[gsm_buf_idx] = c;
490 gsm_buf_idx++;
491 } /* else extra characters are ignored */
492 break;
493 }
494}
495
496
497// Sending a string to the GSM module (through the UART)
498static void Send(const char string[])
499{
500 int i = 0;
501
502 while (string[i]) {
503 GSMTransmit(string[i++]);
504 }
506
508}
509
510/* Returns a pointer to the first occurrence of the character c in the firtn
511 n chars of string s. Return NULL if not found */
512static char *indexn(char *s, char c, uint8_t n)
513{
514 while (n && (*s != c)) {
515 n--;
516 s++;
517 }
518 return (n ? s : NULL);
519}
struct pprz_autopilot autopilot
Global autopilot structure.
Definition autopilot.c:49
Core autopilot interface common to all firmwares.
uint16_t flight_time
flight time in seconds
Definition autopilot.h:65
static uint16_t rssi
Definition cc2500_rx.c:85
#define LED_ON(i)
Definition led_hw.h:51
void nav_goto_block(uint8_t b)
struct Electrical electrical
Definition electrical.c:92
Interface for electrical status: supply voltage, current, battery status, etc.
float vsupply
supply voltage in V
Definition electrical.h:45
struct GpsState gps
global GPS state
Definition gps.c:74
Device independent GPS code (interface)
int32_t hmsl
height above mean sea level (MSL) in mm
Definition gps.h:94
struct UtmCoor_i utm_pos
position in UTM (north,east: cm; alt: mm over MSL)
Definition gps.h:93
struct NedCoor_i ned_vel
speed NED in cm/s
Definition gps.h:96
uint16_t gspeed
norm of 2d ground speed in cm/s
Definition gps.h:97
int32_t z
Down.
int32_t east
in centimeters
int32_t north
in centimeters
#define STATUS_IDLE
Definition gsm.c:113
#define GSM_ORIGIN_MAXLEN
Definition gsm.c:84
void gsm_init(void)
Definition gsm.c:144
static void gsm_got_line(void)
Definition gsm.c:198
static void parse_msg_header(void)
Message header in gsm_bug.
Definition gsm.c:367
static void gsm_parse(uint8_t c)
Definition gsm.c:473
static void request_for_msg(void)
Definition gsm.c:272
void gsm_init_report(void)
Definition gsm.c:167
static void gsm_receive_content(void)
Receiving a SMS, third step, content in gsm_buf Message can be Bdd where dd is a block index on two d...
Definition gsm.c:288
static void Send_CMGF(void)
Definition gsm.c:443
void gsm_event(void)
Definition gsm.c:179
static bool waiting_for_reply
Definition gsm.c:93
static uint8_t gsm_status
Definition gsm.c:118
static void gsm_got_prompt(void)
Definition gsm.c:353
#define DATA_MAXLEN
Definition gsm.c:85
static void Suppr_SMS(int)
Definition gsm.c:341
#define STATUS_WAITING_PROMPT
Definition gsm.c:114
#define STATUS_SEND_CMGF
Definition gsm.c:108
static char gsm_buf[GSM_MAX_PAYLOAD]
Definition gsm.c:99
#define STATUS_REQUESTING_MESSAGE
Definition gsm.c:106
#define MAXLEN_CMTI_ANSWER
Definition gsm.c:88
#define STATUS_SEND_CPMS
Definition gsm.c:110
static void Send_CPMS(void)
Definition gsm.c:465
#define CMTI
Definition gsm.c:87
static char origin[GSM_ORIGIN_MAXLEN]
Definition gsm.c:101
static void Send(const char string[])
Definition gsm.c:498
#define STATUS_CSQ
Definition gsm.c:105
static void gsm_send_report_continue(void)
Definition gsm.c:397
#define STATUS_WAITING_DATA
Definition gsm.c:112
static uint8_t gcs_index
Definition gsm.c:139
#define STATUS_SEND_AT
Definition gsm.c:107
static char expected_ack[10]
Definition gsm.c:98
#define STATUS_DELETE_SMS
Definition gsm.c:115
#define STATUS_NONE
Definition gsm.c:104
void gsm_send_report()
Definition gsm.c:385
static void Send_AT(void)
Definition gsm.c:435
#define MAXLEN_SMS_CONTENT
Definition gsm.c:89
#define ReadGSMBuffer()
Definition gsm.c:80
static uint8_t index_msg
Definition gsm.c:120
static char data_to_send[DATA_MAXLEN]
Definition gsm.c:102
static uint8_t gsm_buf_len
Definition gsm.c:100
#define CTRLZ
Definition gsm.c:83
#define GSMLinkChAvailable()
Definition gsm.c:77
static bool prompt_received
Definition gsm.c:92
static char * indexn(char *, char, uint8_t)
Definition gsm.c:512
#define GSM_MAX_PAYLOAD
Definition gsm.c:73
#define STATUS_POWERON
Definition gsm.c:116
#define STATUS_SEND_CNMI
Definition gsm.c:109
static bool gsm_line_received
Definition gsm.c:91
static uint8_t gsm_buf_idx
Definition gsm.c:100
static uint8_t gcs_index_max
Definition gsm.c:140
static void Send_CNMI(void)
Definition gsm.c:458
static void Send_CSQ(void)
Definition gsm.c:450
Communications through GSM.
arch independent LED (Light Emitting Diodes) API
static uint32_t s
uint16_t foo
Definition main_demo5.c:58
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.