kopia lustrzana https://github.com/SP8EBC/ParaTNC
213 wiersze
6.0 KiB
C
213 wiersze
6.0 KiB
C
/*
|
|
* 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=0,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
|
|
|
|
/**
|
|
* Set to one if correct response to engineering enable AT command
|
|
* has been received
|
|
*/
|
|
uint8_t gsm_sim800_engineering_is_enabled = 0;
|
|
|
|
/**
|
|
* set to one if correct response has been received for engineering data request
|
|
* and new engineering data have been read. This is reset back to zero
|
|
* after disabling CENG or after 'gsm_sim800_engineering_request_data' is called
|
|
*/
|
|
uint8_t gsm_sim800_engineering_successed = 0;
|
|
|
|
/**
|
|
* Set to one in case of any failure during engineering AT commands communication
|
|
*/
|
|
uint8_t gsm_sim800_engineering_fail = 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) {
|
|
|
|
/**
|
|
* Details:0x20000828 <srl_usart3_rx_buffer>
|
|
* "AT+CENG?\r\r\n
|
|
* +CENG: 4,0\r\n\r\n
|
|
* +CENG: 0,\"0037,44,00,260,01,43,67f4,05,05,539d,255,-69,145,145,x,x,x,x,x,x,x\"\r\n
|
|
* +CENG: 1,\"0009,25,61,260,01,539d,80,56\"\r\n
|
|
* +CENG: 2,\"0008,25,15,260,01,539d,78,54\"\r\n+CENG: 3,\"0038"...
|
|
*
|
|
*/
|
|
|
|
// 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) {
|
|
if (*state == SIM800_ALIVE && gsm_sim800_engineering_is_enabled == 1) {
|
|
// send a command to module
|
|
srl_send_data(srl_context, (const uint8_t*) ENGINEERING_DISABLE, SRL_MODE_ZERO, strlen(ENGINEERING_DISABLE), SRL_INTERNAL);
|
|
|
|
// set what has been just send
|
|
gsm_at_command_sent_last = ENGINEERING_DISABLE;
|
|
|
|
// switch the internal state
|
|
*state = SIM800_ALIVE_SENDING_TO_MODEM;
|
|
|
|
// clear the flag
|
|
gsm_sim800_engineering_successed = 0;
|
|
}
|
|
}
|
|
|
|
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 && gsm_sim800_engineering_successed == 0) {
|
|
|
|
// clear the flag
|
|
gsm_sim800_engineering_successed = 0;
|
|
|
|
// 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;
|
|
|
|
gsm_sim800_engineering_fail = 1;
|
|
|
|
}
|
|
}
|
|
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 (ceng_start != 0xFFFF) {
|
|
// if it has been found
|
|
gsm_sim800_engineering_parse_ceng_0(srl_context->srl_rx_buf_pointer, ceng_start);
|
|
|
|
gsm_sim800_engineering_successed = 1;
|
|
}
|
|
else {
|
|
gsm_sim800_engineering_successed = 0;
|
|
|
|
gsm_sim800_engineering_fail = 1;
|
|
}
|
|
|
|
}
|
|
else if (gsm_at_command_sent_last == ENGINEERING_DISABLE) {
|
|
gsm_sim800_engineering_is_enabled = 0;
|
|
}
|
|
|
|
}
|