kopia lustrzana https://github.com/SP8EBC/ParaTNC
sim800 engineering data
rodzic
d6909c2cc7
commit
739ea29a82
|
@ -16,6 +16,7 @@
|
|||
#include "cmsis/stm32l4xx/system_stm32l4xx.h"
|
||||
|
||||
#include "gsm/sim800c.h"
|
||||
#include "gsm/sim800c_engineering.h"
|
||||
#endif
|
||||
|
||||
#include <delay.h>
|
||||
|
@ -983,6 +984,13 @@ int main(int argc, char* argv[]){
|
|||
|
||||
main_gsm_srl_ctx_ptr->srl_rx_state = SRL_RX_IDLE;
|
||||
}
|
||||
|
||||
if (main_gsm_srl_ctx_ptr->srl_tx_state == SRL_TX_IDLE) {
|
||||
gsm_sim800_tx_done_event_handler(main_gsm_srl_ctx_ptr, &main_gsm_state);
|
||||
}
|
||||
|
||||
gsm_sim800_engineering_enable(main_gsm_srl_ctx_ptr, &main_gsm_state);
|
||||
gsm_sim800_engineering_request_data(main_gsm_srl_ctx_ptr, &main_gsm_state);
|
||||
}
|
||||
|
||||
// if Victron VE.direct client is enabled
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* sim800c_state_t.h
|
||||
*
|
||||
* Created on: Jan 26, 2022
|
||||
* Author: mateusz
|
||||
*/
|
||||
|
||||
#ifndef INCLUDE_GSM_SIM800_STATE_T_H_
|
||||
#define INCLUDE_GSM_SIM800_STATE_T_H_
|
||||
|
||||
typedef enum gsm_sim800_state_t {
|
||||
SIM800_UNKNOWN,
|
||||
SIM800_POWERED_OFF,
|
||||
SIM800_NOT_YET_COMM,
|
||||
SIM800_HANDSHAKING,
|
||||
SIM800_INITIALIZING,
|
||||
SIM800_ALIVE,
|
||||
SIM800_ALIVE_SENDING_TO_MODEM,
|
||||
SIM800_ALIVE_WAITING_MODEM_RESP,
|
||||
}gsm_sim800_state_t;
|
||||
|
||||
#endif /* INCLUDE_GSM_SIM800_STATE_T_H_ */
|
|
@ -9,22 +9,22 @@
|
|||
#define INCLUDE_GSM_SIM800C_H_
|
||||
|
||||
#include "drivers/serial.h"
|
||||
#include "gsm/sim800_state_t.h"
|
||||
|
||||
typedef enum gsm_sim800_state_t {
|
||||
SIM800_UNKNOWN,
|
||||
SIM800_POWERED_OFF,
|
||||
SIM800_NOT_YET_COMM,
|
||||
SIM800_HANDSHAKING,
|
||||
SIM800_INITIALIZING,
|
||||
SIM800_INITIALIZING_WAIT_RESPONSE,
|
||||
SIM800_ALIVE,
|
||||
SIM800_GPRS_CONNECTED
|
||||
}gsm_sim800_state_t;
|
||||
extern const char * gsm_at_command_sent_last;
|
||||
|
||||
extern char gsm_sim800_sim_status[10];
|
||||
extern char gsm_sim800_registered_network[16];
|
||||
extern int8_t gsm_sim800_signal_level_dbm;
|
||||
extern float gsm_sim800_bcch_frequency;
|
||||
extern char gsm_sim800_cellid[5];
|
||||
extern char gsm_sim800_lac[5];
|
||||
|
||||
void gsm_sim800_init(gsm_sim800_state_t * state, uint8_t enable_echo);
|
||||
|
||||
void gsm_sim800_pool(srl_context_t * srl_context, gsm_sim800_state_t * state);
|
||||
uint8_t gsm_sim800_rx_terminating_callback(uint8_t current_data, const uint8_t * const rx_buffer, uint16_t rx_bytes_counter); // callback used to detect echo
|
||||
void gsm_sim800_rx_done_event_handler(srl_context_t * srl_context, gsm_sim800_state_t * state);
|
||||
void gsm_sim800_tx_done_event_handler(srl_context_t * srl_context, gsm_sim800_state_t * state);
|
||||
|
||||
#endif /* INCLUDE_GSM_SIM800C_H_ */
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* sim800c_engineering.h
|
||||
*
|
||||
* Created on: Jan 26, 2022
|
||||
* Author: mateusz
|
||||
*/
|
||||
|
||||
#ifndef INCLUDE_GSM_SIM800C_ENGINEERING_H_
|
||||
#define INCLUDE_GSM_SIM800C_ENGINEERING_H_
|
||||
|
||||
#include "gsm/sim800c.h"
|
||||
#include "gsm/sim800_state_t.h"
|
||||
|
||||
extern const char * ENGINEERING_ENABLE;
|
||||
extern const char * ENGINEERING_DISABLE;
|
||||
extern const char * ENGINEERING_GET;
|
||||
|
||||
void gsm_sim800_engineering_enable(srl_context_t * srl_context, gsm_sim800_state_t * state);
|
||||
void gsm_sim800_engineering_disable(srl_context_t * srl_context, gsm_sim800_state_t * state);
|
||||
void gsm_sim800_engineering_request_data(srl_context_t * srl_context, gsm_sim800_state_t * state);
|
||||
void gsm_sim800_engineering_response_callback(srl_context_t * srl_context, gsm_sim800_state_t * state, uint16_t gsm_response_start_idx);
|
||||
|
||||
|
||||
#endif /* INCLUDE_GSM_SIM800C_ENGINEERING_H_ */
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
#include "gsm/sim800c.h"
|
||||
#include "gsm/sim800c_engineering.h"
|
||||
|
||||
#include "main.h"
|
||||
|
||||
|
@ -19,6 +20,7 @@ static const char * GET_PIN_STATUS = "AT+CPIN?\r\0";
|
|||
static const char * GET_REGISTERED_NETWORK = "AT+COPS?\r\0";
|
||||
|
||||
static const char * OK = "OK\r\n\0";
|
||||
static const char * SIGNAL_LEVEL = "+CSQ:\0";
|
||||
static const char * NETWORK_REGISTRATION = "+CREG:\0";
|
||||
static const char * CPIN = "+CPIN:\0";
|
||||
static const char * CPIN_READY = "READY";
|
||||
|
@ -28,23 +30,47 @@ static const char * REGISTERED_NETWORK = "+COPS:\0";
|
|||
uint32_t gsm_time_of_last_command_send_to_module = 0;
|
||||
|
||||
// let's the library know if gsm module echoes every AT command send through serial port
|
||||
uint8_t gsm_at_comm_echo = 1;
|
||||
static uint8_t gsm_at_comm_echo = 1;
|
||||
|
||||
// used to receive echo and response separately
|
||||
uint8_t gsm_receive_newline_counter = 0;
|
||||
static uint8_t gsm_receive_newline_counter = 0;
|
||||
|
||||
// first character of non-echo response from the module
|
||||
uint16_t gsm_response_start_idx = 0;
|
||||
static uint16_t gsm_response_start_idx = 0;
|
||||
|
||||
// a pointer to the last command string which sent in SIM800_INITIALIZING state
|
||||
const char * gsm_at_command_sent_last = 0;
|
||||
|
||||
// set to one to lock 'gsm_sim800_pool' in SIM800_INITIALIZING state until the response is received
|
||||
uint8_t gsm_waiting_for_command_response = 0;
|
||||
static uint8_t gsm_waiting_for_command_response = 0;
|
||||
|
||||
uint8_t gsm_registration_status = 4; // unknown
|
||||
uint8_t gsm_sim800_registration_status = 4; // unknown
|
||||
|
||||
char gsm_sim_status[10];
|
||||
// string with sim status
|
||||
char gsm_sim800_sim_status[10];
|
||||
|
||||
char gsm_sim800_registered_network[16];
|
||||
|
||||
int8_t gsm_sim800_signal_level_dbm = 0;
|
||||
|
||||
float gsm_sim800_bcch_frequency = 0;
|
||||
|
||||
char gsm_sim800_cellid[5] = {0, 0, 0, 0, 0};
|
||||
|
||||
char gsm_sim800_lac[5] = {0, 0, 0, 0, 0};
|
||||
|
||||
|
||||
static void replace_non_printable_with_space(char * str) {
|
||||
for (int i = 0; *(str + i) != 0 ; i++) {
|
||||
char current = *(str + i);
|
||||
|
||||
if (current != 0x00) {
|
||||
if (current < 0x21 || current > 0x7A) {
|
||||
*(str + i) = ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gsm_sim800_init(gsm_sim800_state_t * state, uint8_t enable_echo) {
|
||||
|
||||
|
@ -126,6 +152,22 @@ void gsm_sim800_pool(srl_context_t * srl_context, gsm_sim800_state_t * state) {
|
|||
|
||||
srl_receive_data_with_callback(srl_context, gsm_sim800_rx_terminating_callback);
|
||||
}
|
||||
else if (gsm_at_command_sent_last == GET_REGISTERED_NETWORK) {
|
||||
// ask for signal level
|
||||
srl_send_data(srl_context, (const uint8_t*) GET_SIGNAL_LEVEL, SRL_MODE_ZERO, strlen(GET_SIGNAL_LEVEL), SRL_INTERNAL);
|
||||
|
||||
// wait for command completion
|
||||
srl_wait_for_tx_completion(srl_context);
|
||||
|
||||
gsm_at_command_sent_last = GET_SIGNAL_LEVEL;
|
||||
|
||||
gsm_waiting_for_command_response = 1;
|
||||
|
||||
srl_receive_data_with_callback(srl_context, gsm_sim800_rx_terminating_callback);
|
||||
}
|
||||
else if (gsm_at_command_sent_last == GET_SIGNAL_LEVEL) {
|
||||
*state = SIM800_ALIVE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,6 +180,13 @@ uint8_t gsm_sim800_rx_terminating_callback(uint8_t current_data, const uint8_t *
|
|||
|
||||
char before = '\0';
|
||||
|
||||
int8_t terminating_newline_counter = 1;
|
||||
|
||||
// special case for CENG request
|
||||
if (gsm_at_command_sent_last == ENGINEERING_GET) {
|
||||
terminating_newline_counter = 4;
|
||||
}
|
||||
|
||||
if (rx_bytes_counter > 0) {
|
||||
before = (char) *(rx_buffer + rx_bytes_counter - 1);
|
||||
}
|
||||
|
@ -148,13 +197,13 @@ uint8_t gsm_sim800_rx_terminating_callback(uint8_t current_data, const uint8_t *
|
|||
gsm_receive_newline_counter++;
|
||||
}
|
||||
|
||||
// check if this is first character of response
|
||||
if (current != '\n' && current != '\r' && (before == '\n' || before == '\r')) {
|
||||
// check if this is first character of response (first printable after the echo)
|
||||
if (current != '\n' && current != '\r' && (before == '\n' || before == '\r') && gsm_receive_newline_counter < 2) {
|
||||
gsm_response_start_idx = rx_bytes_counter;
|
||||
}
|
||||
|
||||
// if an echo is enabled and second newline has been received
|
||||
if (gsm_at_comm_echo == 1 && gsm_receive_newline_counter > 1 && gsm_response_start_idx > 0) {
|
||||
if (gsm_at_comm_echo == 1 && gsm_receive_newline_counter > terminating_newline_counter && gsm_response_start_idx > 0) {
|
||||
|
||||
gsm_receive_newline_counter = 0;
|
||||
|
||||
|
@ -190,20 +239,69 @@ void gsm_sim800_rx_done_event_handler(srl_context_t * srl_context, gsm_sim800_st
|
|||
comparision_result = strncmp(NETWORK_REGISTRATION, (const char *)(srl_context->srl_rx_buf_pointer + gsm_response_start_idx), 5);
|
||||
|
||||
if (comparision_result == 0) {
|
||||
gsm_registration_status = atoi((const char *)(srl_context->srl_rx_buf_pointer + gsm_response_start_idx + 9));
|
||||
comparision_result = atoi((const char *)(srl_context->srl_rx_buf_pointer + gsm_response_start_idx + 9));
|
||||
|
||||
if (comparision_result >= 0 && comparision_result < 6) {
|
||||
gsm_sim800_registration_status = (int8_t)comparision_result;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (gsm_at_command_sent_last == GET_PIN_STATUS) {
|
||||
comparision_result = strncmp(CPIN, (const char *)(srl_context->srl_rx_buf_pointer + gsm_response_start_idx), 5);
|
||||
|
||||
if (comparision_result == 0) {
|
||||
strncpy(gsm_sim_status, (const char *)(srl_context->srl_rx_buf_pointer + gsm_response_start_idx + 7), 10);
|
||||
strncpy(gsm_sim800_sim_status, (const char *)(srl_context->srl_rx_buf_pointer + gsm_response_start_idx + 7), 10);
|
||||
|
||||
replace_non_printable_with_space(gsm_sim800_sim_status);
|
||||
}
|
||||
|
||||
}
|
||||
else if (gsm_at_command_sent_last == GET_REGISTERED_NETWORK) {
|
||||
comparision_result = strncmp(REGISTERED_NETWORK, (const char *)(srl_context->srl_rx_buf_pointer + gsm_response_start_idx), 5);
|
||||
|
||||
if (comparision_result == 0) {
|
||||
strncpy(gsm_sim800_registered_network, (const char *)(srl_context->srl_rx_buf_pointer + gsm_response_start_idx + 12), 16);
|
||||
|
||||
replace_non_printable_with_space(gsm_sim800_registered_network);
|
||||
}
|
||||
}
|
||||
else if (gsm_at_command_sent_last == GET_SIGNAL_LEVEL) {
|
||||
comparision_result = strncmp(SIGNAL_LEVEL, (const char *)(srl_context->srl_rx_buf_pointer + gsm_response_start_idx), 5);
|
||||
|
||||
if (comparision_result == 0) {
|
||||
comparision_result = atoi((const char *)(srl_context->srl_rx_buf_pointer + gsm_response_start_idx + 6));
|
||||
|
||||
if (comparision_result > 1 && comparision_result < 32) {
|
||||
gsm_sim800_signal_level_dbm = -110 + 2 * comparision_result;
|
||||
}
|
||||
else if (comparision_result == 1) {
|
||||
gsm_sim800_signal_level_dbm = -111;
|
||||
}
|
||||
else {
|
||||
gsm_sim800_signal_level_dbm = -115;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else if (*state == SIM800_ALIVE_WAITING_MODEM_RESP) {
|
||||
|
||||
if (gsm_at_command_sent_last == ENGINEERING_ENABLE) {
|
||||
gsm_sim800_engineering_response_callback(srl_context, state, gsm_response_start_idx);
|
||||
}
|
||||
else if (gsm_at_command_sent_last == ENGINEERING_GET) {
|
||||
gsm_sim800_engineering_response_callback(srl_context, state, gsm_response_start_idx);
|
||||
}
|
||||
|
||||
*state = SIM800_ALIVE;
|
||||
}
|
||||
}
|
||||
|
||||
void gsm_sim800_tx_done_event_handler(srl_context_t * srl_context, gsm_sim800_state_t * state) {
|
||||
if (*state == SIM800_ALIVE_SENDING_TO_MODEM) {
|
||||
srl_receive_data_with_callback(srl_context, gsm_sim800_rx_terminating_callback);
|
||||
|
||||
*state = SIM800_ALIVE_WAITING_MODEM_RESP;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* sim800c_engineering.c
|
||||
*
|
||||
* Created on: Jan 26, 2022
|
||||
* Author: mateusz
|
||||
*/
|
||||
|
||||
|
||||
#include "gsm/sim800c_engineering.h"
|
||||
#include "gsm/sim800c.h"
|
||||
|
||||
#include "drivers/serial.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
const char * ENGINEERING_ENABLE = "AT+CENG=4,0\r\0";
|
||||
const char * ENGINEERING_DISABLE = "AT+CENG=4,0\r\0";
|
||||
const char * ENGINEERING_GET = "AT+CENG?\r\0";
|
||||
|
||||
static const char * OK = "OK\r\n\0";
|
||||
static const char * CENG0 = "+CENG: 0,\0";
|
||||
|
||||
#define CENG0_RECORD_LN 77 // including '+CENG' heading
|
||||
|
||||
#define ARFCN_OFFSET 10
|
||||
#define ARFCN_LN 4
|
||||
#define CELLID_OFFSET 31
|
||||
#define CELLID_LN 4
|
||||
#define LAC_OFFSET 42
|
||||
#define LAC_LN 4
|
||||
|
||||
uint8_t gsm_sim800_engineering_is_enabled = 0;
|
||||
|
||||
|
||||
static uint16_t gsm_sim800_rewind_to_ceng_0(uint8_t *srl_rx_buf_pointer, uint16_t buffer_ln, uint16_t gsm_response_start_idx) {
|
||||
|
||||
int comparision_result = 123;
|
||||
|
||||
// iterator over data returned by the modem
|
||||
int i = gsm_response_start_idx;
|
||||
|
||||
// calculate the length of CENG0 term to omit recalculation each loop iteration
|
||||
int ceng_ln = strlen(CENG0);
|
||||
|
||||
for (; (i < buffer_ln - ceng_ln) && *(srl_rx_buf_pointer + i) != 0; i++) {
|
||||
comparision_result = memcmp((const void*)CENG0, srl_rx_buf_pointer + i, ceng_ln);
|
||||
|
||||
if (comparision_result == 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0xFFFF;
|
||||
|
||||
}
|
||||
|
||||
static void gsm_sim800_engineering_parse_ceng_0(uint8_t *srl_rx_buf_pointer, uint16_t ceng_0_payload_start) {
|
||||
|
||||
// temporary buffer for strings
|
||||
char string_buffer[5];
|
||||
|
||||
// temporary variable for string -> int conversion
|
||||
int integer = 0;
|
||||
|
||||
// zeroing string buffer
|
||||
memset(string_buffer, 0x0, sizeof(string_buffer));
|
||||
|
||||
// check if the record has been found
|
||||
if (ceng_0_payload_start > (0xFFFF - CENG0_RECORD_LN)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// copying ARFCN
|
||||
memcpy(string_buffer, srl_rx_buf_pointer + ceng_0_payload_start + ARFCN_OFFSET, ARFCN_LN);
|
||||
|
||||
// converting ARFCN to integer
|
||||
integer = atoi(string_buffer);
|
||||
|
||||
if (integer < 125) {
|
||||
gsm_sim800_bcch_frequency = 890.0f + 0.2f * integer + 45.0f;
|
||||
}
|
||||
else if (integer > 511 && integer < 886) {
|
||||
gsm_sim800_bcch_frequency = 1710.2f + 0.2f * (integer - 512) + 95.0f;
|
||||
}
|
||||
else if (integer > 974 && integer < 1024) {
|
||||
gsm_sim800_bcch_frequency = 890.0f + 0.2f * (integer - 1024) + 45.0f;
|
||||
}
|
||||
|
||||
// zeroing string buffer
|
||||
memset(string_buffer, 0x0, sizeof(string_buffer));
|
||||
|
||||
// copying CELL-ID string
|
||||
memcpy(gsm_sim800_cellid, srl_rx_buf_pointer + ceng_0_payload_start + CELLID_OFFSET, CELLID_LN);
|
||||
|
||||
// copying LAC
|
||||
memcpy(gsm_sim800_lac, srl_rx_buf_pointer + ceng_0_payload_start + LAC_OFFSET, LAC_LN);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void gsm_sim800_engineering_enable(srl_context_t * srl_context, gsm_sim800_state_t * state) {
|
||||
if (*state == SIM800_ALIVE && gsm_sim800_engineering_is_enabled == 0) {
|
||||
// send a command to module
|
||||
srl_send_data(srl_context, (const uint8_t*) ENGINEERING_ENABLE, SRL_MODE_ZERO, strlen(ENGINEERING_ENABLE), SRL_INTERNAL);
|
||||
|
||||
// set what has been just send
|
||||
gsm_at_command_sent_last = ENGINEERING_ENABLE;
|
||||
|
||||
// switch the internal state
|
||||
*state = SIM800_ALIVE_SENDING_TO_MODEM;
|
||||
}
|
||||
}
|
||||
|
||||
void gsm_sim800_engineering_disable(srl_context_t * srl_context, gsm_sim800_state_t * state) {
|
||||
|
||||
}
|
||||
|
||||
void gsm_sim800_engineering_request_data(srl_context_t * srl_context, gsm_sim800_state_t * state) {
|
||||
|
||||
if (*state == SIM800_ALIVE && gsm_sim800_engineering_is_enabled == 1) {
|
||||
// send a command to module
|
||||
srl_send_data(srl_context, (const uint8_t*) ENGINEERING_GET, SRL_MODE_ZERO, strlen(ENGINEERING_GET), SRL_INTERNAL);
|
||||
|
||||
// set what has been just send
|
||||
gsm_at_command_sent_last = ENGINEERING_GET;
|
||||
|
||||
// switch the internal state
|
||||
*state = SIM800_ALIVE_SENDING_TO_MODEM;
|
||||
}
|
||||
}
|
||||
|
||||
void gsm_sim800_engineering_response_callback(srl_context_t * srl_context, gsm_sim800_state_t * state, uint16_t gsm_response_start_idx) {
|
||||
|
||||
if (gsm_at_command_sent_last == ENGINEERING_ENABLE) {
|
||||
int comparision_result = strcmp(OK, (const char *)(srl_context->srl_rx_buf_pointer + gsm_response_start_idx));
|
||||
|
||||
if (comparision_result == 0) {
|
||||
gsm_sim800_engineering_is_enabled = 1;
|
||||
|
||||
}
|
||||
else {
|
||||
gsm_sim800_engineering_is_enabled = 0;
|
||||
|
||||
}
|
||||
}
|
||||
else if (gsm_at_command_sent_last == ENGINEERING_GET) {
|
||||
// look for the start of '+CENG: 0,' record
|
||||
uint16_t ceng_start = gsm_sim800_rewind_to_ceng_0(srl_context->srl_rx_buf_pointer, srl_context->srl_rx_buf_ln, gsm_response_start_idx);
|
||||
|
||||
// if it has been found
|
||||
gsm_sim800_engineering_parse_ceng_0(srl_context->srl_rx_buf_pointer, ceng_start);
|
||||
}
|
||||
|
||||
}
|
Ładowanie…
Reference in New Issue