diff --git a/.gitignore b/.gitignore
index 93d2a28d..a872aadf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,12 +16,14 @@
*.sct
*.MajerleT
*.tjuln
+*.tilen
*.dbgconf
*.uvguix
*.uvoptx
*.__i
*.i
*.txt
+!docs/*.txt
RTE/
# IAR Settings
@@ -73,6 +75,7 @@ bld/
[Bb]in/
[Oo]bj/
[Ll]og/
+_build/
# Visual Studio 2015/2017 cache/options directory
.vs/
@@ -377,7 +380,6 @@ log_file.txt
.metadata/
.mxproject
.settings/
-template/
project.ioc
mx.scratch
*.tilen majerle
diff --git a/.gitmodules b/.gitmodules
index 23b80ae4..cab36ce5 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,3 @@
-[submodule "third_party/Embedded_Libs"]
- path = third_party/Embedded_Libs
- url = https://github.com/MaJerle/Embedded_Libs
+[submodule "third_party/embedded-libs"]
+ path = third_party/embedded-libs
+ url = https://github.com/MaJerle/embedded-libs
diff --git a/LICENSE b/LICENSE
index 68bd738f..aa603174 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2018 Tilen Majerle
+Copyright (c) 2020 Tilen MAJERLE
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index ef7f23f8..4892610a 100644
--- a/README.md
+++ b/README.md
@@ -1,17 +1,36 @@
-# GSM AT commands parser for RTOS systems
+# Lightweight GSM-AT parser
-GSM-AT Library commands parser is a generic, platform independent, library for communicating with SIMCOM based modules SIM800/SIM900 or SIM70xx. Module is written in C99 and is independent from used platform. Its main targets are embedded system devices like ARM Cortex-M, AVR, PIC and others, but can easily work under `Windows`, `Linux` or `MAC` environments.
+LwGSM is lightweight, platform independent, AT commands parser, targeting for communicion with SIMCOM based modules SIM800/SIM900 or SIM70xx. Module is written in C99 and is independent from used platform. Its main targets are embedded system devices like ARM Cortex-M, AVR, PIC and others, but can easily work under `Windows`, `Linux` or `MAC` environments.
-## Features
-
-- Supports `SIM800/SIM900 (2G)` and `SIM7000/SIM7020 (NB-Iot LTE)` modules
-
-## Documentation
+
-Full API documentation with description and examples is available and is regulary updated with the source changes
-
-http://majerle.eu/documentation/gsm_at/html/index.html
-
-## Contribution
+## Features
-I invite you to give feature request or report a bug. Please use issues tracker.
+* Supports ``SIM800/SIM900 (2G)`` and ``SIM7000/SIM7020 (NB-Iot LTE)`` modules
+* Platform independent and very easy to port
+ * Development of library under Win32 platform
+ * Provided examples for ARM Cortex-M or Win32 platforms
+* Written in C language (C99)
+* Allows different configurations to optimize user requirements
+* Supports implementation with operating systems with advanced inter-thread communications
+ * Currently only OS mode is supported
+ * 2 different threads handling user data and received data
+ * First (producer) thread (collects user commands from user threads and starts the command processing)
+ * Second (process) thread reads the data from GSM device and does the job accordingly
+* Allows sequential API for connections in client and server mode
+* Includes several applications built on top of library:
+ * MQTT client for MQTT connection
+* User friendly MIT license
+
+## Contribute
+
+Fresh contributions are always welcome. Simple instructions to proceed::
+
+1. Fork Github repository
+2. Respect [C style & coding rules](https://github.com/MaJerle/c-code-style) used by the library
+3. Create a pull request to develop branch with new features or bug fixes
+
+Alternatively you may:
+
+1. Report a bug
+2. Ask for a feature request
\ No newline at end of file
diff --git a/dev/VisualStudio/gsm_config.h b/dev/VisualStudio/gsm_config.h
deleted file mode 100644
index 6102100e..00000000
--- a/dev/VisualStudio/gsm_config.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/**
- * \file gsm_config.h
- * \brief Configuration for GSM
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#ifndef GSM_HDR_CONFIG_H
-#define GSM_HDR_CONFIG_H
-
-/**
- * User specific config which overwrites setup from gsm_config_default.h file
- */
-
-#if !__DOXYGEN__
-#define GSM_CFG_DBG GSM_DBG_ON
-#define GSM_CFG_DBG_TYPES_ON GSM_DBG_TYPE_TRACE | GSM_DBG_TYPE_STATE
-#define GSM_CFG_DBG_MQTT GSM_DBG_OFF
-
-#define GSM_CFG_IPD_MAX_BUFF_SIZE 1460
-#define GSM_CFG_INPUT_USE_PROCESS 1
-#define GSM_CFG_AT_ECHO 0
-
-#define GSM_CFG_NETWORK 1
-
-#define GSM_CFG_CONN 1
-#define GSM_CFG_SMS 1
-#define GSM_CFG_CALL 1
-#define GSM_CFG_PHONEBOOK 1
-#define GSM_CFG_USSD 1
-
-#define GSM_CFG_USE_API_FUNC_EVT 1
-
-#define GSM_CFG_NETCONN 1
-
-#define GSM_CFG_MEM_CUSTOM 1
-
-#if defined(WIN32)
-#define GSM_CFG_SYS_PORT GSM_SYS_PORT_WIN32
-#endif
-
-#endif /* !__DOXYGEN__ */
-
-/* Include default configuration setup */
-#include "gsm/gsm_config_default.h"
-
-/**
- * \}
- */
-
-#endif /* GSM_HDR_CONFIG_H */
diff --git a/dev/VisualStudio/gsm_at_lib_dev.sln b/dev/VisualStudio/lwgsm_dev.sln
similarity index 88%
rename from dev/VisualStudio/gsm_at_lib_dev.sln
rename to dev/VisualStudio/lwgsm_dev.sln
index 1dbe6fed..0c851a0f 100644
--- a/dev/VisualStudio/gsm_at_lib_dev.sln
+++ b/dev/VisualStudio/lwgsm_dev.sln
@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28803.452
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gsm_at_lib_dev", "gsm_at_lib_dev.vcxproj", "{87E5EEE1-1C99-458B-A893-DDDB00775631}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lwgsm_dev", "lwgsm_dev.vcxproj", "{87E5EEE1-1C99-458B-A893-DDDB00775631}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -13,8 +13,8 @@ Global
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {87E5EEE1-1C99-458B-A893-DDDB00775631}.Debug|x64.ActiveCfg = Debug|Win32
- {87E5EEE1-1C99-458B-A893-DDDB00775631}.Debug|x64.Build.0 = Debug|Win32
+ {87E5EEE1-1C99-458B-A893-DDDB00775631}.Debug|x64.ActiveCfg = Debug|x64
+ {87E5EEE1-1C99-458B-A893-DDDB00775631}.Debug|x64.Build.0 = Debug|x64
{87E5EEE1-1C99-458B-A893-DDDB00775631}.Debug|x86.ActiveCfg = Debug|Win32
{87E5EEE1-1C99-458B-A893-DDDB00775631}.Debug|x86.Build.0 = Debug|Win32
{87E5EEE1-1C99-458B-A893-DDDB00775631}.Release|x64.ActiveCfg = Release|x64
diff --git a/dev/VisualStudio/gsm_at_lib_dev.vcxproj b/dev/VisualStudio/lwgsm_dev.vcxproj
similarity index 71%
rename from dev/VisualStudio/gsm_at_lib_dev.vcxproj
rename to dev/VisualStudio/lwgsm_dev.vcxproj
index 0cf840ad..75d614b4 100644
--- a/dev/VisualStudio/gsm_at_lib_dev.vcxproj
+++ b/dev/VisualStudio/lwgsm_dev.vcxproj
@@ -22,7 +22,7 @@
15.0{87E5EEE1-1C99-458B-A893-DDDB00775631}Win32Proj
- gsm_dev_os
+ lwgsm_dev_os10.0
@@ -72,17 +72,19 @@
true
- .;..\..\snippets\include;..\..\GSM_AT_Lib\src\include;..\..\..\lwmem\lwmem\src\include;$(IncludePath)
+ .;..\..\lwgsm\src\include;..\..\lwgsm\src\include\system\port\win32;..\..\snippets\include;..\..\..\lwmem\lwmem\src\include;$(IncludePath)true
- .;..\..\snippets\include;..\..\GSM_AT_Lib\src\include;$(IncludePath)
+ .;..\..\lwgsm\src\include;..\..\lwgsm\src\include\system\port\win32;..\..\snippets\include;$(IncludePath)false
+ .;..\..\lwgsm\src\include;..\..\lwgsm\src\include\system\port\win32;..\..\snippets\include;$(IncludePath)false
+ .;..\..\lwgsm\src\include;..\..\lwgsm\src\include\system\port\win32;..\..\snippets\include;$(IncludePath)
@@ -142,42 +144,47 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/VisualStudio/gsm_at_lib_dev.vcxproj.filters b/dev/VisualStudio/lwgsm_dev.vcxproj.filters
similarity index 60%
rename from dev/VisualStudio/gsm_at_lib_dev.vcxproj.filters
rename to dev/VisualStudio/lwgsm_dev.vcxproj.filters
index cd91658e..1c6956f0 100644
--- a/dev/VisualStudio/gsm_at_lib_dev.vcxproj.filters
+++ b/dev/VisualStudio/lwgsm_dev.vcxproj.filters
@@ -28,119 +28,134 @@
Source Files
-
- Source Files\GSM CORE
+
+ Source Files\GSM SNIPPETS
-
- Source Files\GSM CORE
+
+ Source Files\GSM SNIPPETS
-
- Source Files\GSM CORE
+
+ Source Files\GSM SNIPPETS
-
- Source Files\GSM CORE
+
+ Source Files\GSM SNIPPETS
-
- Source Files\GSM CORE
+
+ Source Files\GSM SNIPPETS
-
- Source Files\GSM CORE
+
+ Source Files\LWMEM
-
- Source Files\GSM CORE
+
+ Source Files\LWMEM
-
- Source Files\GSM CORE
+
+ Source Files\GSM SNIPPETS
-
- Source Files\GSM CORE
+
+ Source Files\GSM SNIPPETS
-
- Source Files\GSM CORE
+
+ Source Files\GSM SNIPPETS
-
- Source Files\GSM CORE
+
+ Source Files\GSM SNIPPETS
-
- Source Files\GSM LL
+
+ Source Files\GSM SNIPPETS
-
- Source Files\GSM LL
+
+ Source Files\GSM CORE
-
+ Source Files\GSM CORE
-
+ Source Files\GSM CORE
-
+ Source Files\GSM CORE
-
+ Source Files\GSM CORE
-
+ Source Files\GSM CORE
-
+ Source Files\GSM CORE
-
+ Source Files\GSM CORE
-
+ Source Files\GSM CORE
-
+ Source Files\GSM CORE
-
- Source Files\GSM API
+
+ Source Files\GSM LL
+
+
+ Source Files\LWMEM
+
+
+ Source Files\GSM CORE
-
+ Source Files\GSM APP MQTT
-
+ Source Files\GSM APP MQTT
-
+ Source Files\GSM APP MQTT
-
- Source Files\GSM SNIPPETS
+
+ Source Files\GSM API
-
- Source Files\GSM SNIPPETS
+
+ Source Files\GSM CORE
-
- Source Files\GSM SNIPPETS
+
+ Source Files\GSM CORE
-
- Source Files\GSM SNIPPETS
+
+ Source Files\GSM CORE
-
+ Source Files\GSM CORE
-
+ Source Files\GSM CORE
-
+
+ Source Files\GSM CORE
+
+
+ Source Files\GSM CORE
+
+
+ Source Files\GSM CORE
+
+ Source Files\GSM LL
-
- Source Files\GSM SNIPPETS
+
+ Source Files\GSM CORE
-
- Source Files\GSM API
+
+ Source Files\GSM CORE
-
+ Source Files\GSM CORE
-
- Source Files\LWMEM
+
+ Source Files\GSM CORE
-
- Source Files\LWMEM
+
+ Source Files\GSM CORE
\ No newline at end of file
diff --git a/dev/VisualStudio/lwgsm_opts.h b/dev/VisualStudio/lwgsm_opts.h
new file mode 100644
index 00000000..686224fe
--- /dev/null
+++ b/dev/VisualStudio/lwgsm_opts.h
@@ -0,0 +1,72 @@
+/**
+ * \file lwgsm_opts.h
+ * \brief GSM application options
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+#ifndef LWGSM_HDR_OPTS_H
+#define LWGSM_HDR_OPTS_H
+
+/* Rename this file to "lwgsm_opts.h" for your application */
+
+/*
+ * Open "include/lwgsm/lwgsm_opt.h" and
+ * copy & replace here settings you want to change values
+ */
+#if !__DOXYGEN__
+#define LWGSM_CFG_DBG LWGSM_DBG_ON
+#define LWGSM_CFG_DBG_TYPES_ON LWGSM_DBG_TYPE_TRACE | LWGSM_DBG_TYPE_STATE
+#define LWGSM_CFG_DBG_MQTT LWGSM_DBG_OFF
+
+#define LWGSM_CFG_IPD_MAX_BUFF_SIZE 1460
+#define LWGSM_CFG_INPUT_USE_PROCESS 1
+#define LWGSM_CFG_AT_ECHO 0
+
+#define LWGSM_CFG_NETWORK 1
+
+#define LWGSM_CFG_CONN 1
+#define LWGSM_CFG_SMS 1
+#define LWGSM_CFG_CALL 1
+#define LWGSM_CFG_PHONEBOOK 1
+#define LWGSM_CFG_USSD 1
+
+#define LWGSM_CFG_USE_API_FUNC_EVT 1
+
+#define LWGSM_CFG_NETCONN 1
+
+#define LWGSM_CFG_MEM_CUSTOM 1
+
+#if defined(WIN32)
+#define LWGSM_CFG_SYS_PORT LWGSM_SYS_PORT_WIN32
+#endif
+
+#endif /* !__DOXYGEN__ */
+
+#endif /* LWGSM_HDR_OPTS_H */
diff --git a/dev/VisualStudio/lwmem_config.h b/dev/VisualStudio/lwmem_opts.h
similarity index 75%
rename from dev/VisualStudio/lwmem_config.h
rename to dev/VisualStudio/lwmem_opts.h
index 225127fe..08ea296b 100644
--- a/dev/VisualStudio/lwmem_config.h
+++ b/dev/VisualStudio/lwmem_opts.h
@@ -1,10 +1,10 @@
/**
- * \file lwmem_config.h
- * \brief LwMEM configuration file
+ * \file lwmem_opts.h
+ * \brief LwMEM application options
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -29,23 +29,20 @@
* This file is part of LwMEM - Lightweight dynamic memory manager library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#ifndef LWMEM_HDR_CONFIG_H
-#define LWMEM_HDR_CONFIG_H
+#ifndef LWMEM_HDR_OPTS_H
+#define LWMEM_HDR_OPTS_H
-/* Rename this file to "lwmem_config.h" for your application */
+/* Rename this file to "lwmem_opts.h" for your application */
#include "windows.h"
/*
- * Open "include/lwmem/lwmem_config_default.h" and
+ * Open "include/lwmem/lwmem_opt.h" and
* copy & replace here settings you want to change values
*/
#define LWMEM_CFG_OS 1
#define LWMEM_CFG_OS_MUTEX_HANDLE HANDLE
-/* After user configuration, call default config to merge config together */
-#include "lwmem/lwmem_config_default.h"
-
-#endif /* LWMEM_HDR_CONFIG_H */
+#endif /* LWMEM_HDR_OPTS_H */
diff --git a/dev/VisualStudio/main.c b/dev/VisualStudio/main.c
index d7c37c46..9c4a8718 100644
--- a/dev/VisualStudio/main.c
+++ b/dev/VisualStudio/main.c
@@ -1,36 +1,39 @@
-// gsm_dev_os.cpp : Defines the entry point for the console application.
+// lwgsm_dev_os.cpp : Defines the entry point for the console application.
//
#include "windows.h"
-#include "gsm/gsm.h"
+#include "lwgsm/lwgsm.h"
-#include "gsm/apps/gsm_mqtt_client_api.h"
-#include "gsm/gsm_mem.h"
-#include "gsm/gsm_network_api.h"
+#include "lwgsm/apps/lwgsm_mqtt_client_api.h"
+#include "lwgsm/lwgsm_mem.h"
+#include "lwgsm/lwgsm_network_api.h"
#include "mqtt_client_api.h"
#include "netconn_client.h"
#include "sms_send_receive.h"
+#include "network_apn_settings.h"
+#include "sms_send_receive_thread.h"
+#include "client.h"
#include "lwmem/lwmem.h"
static void main_thread(void* arg);
DWORD main_thread_id;
-static gsmr_t gsm_evt(gsm_evt_t* evt);
-static gsmr_t gsm_conn_evt(gsm_evt_t* evt);
+static lwgsmr_t lwgsm_evt(lwgsm_evt_t* evt);
+static lwgsmr_t lwgsm_conn_evt(lwgsm_evt_t* evt);
-gsm_operator_t operators[10];
+lwgsm_operator_t operators[10];
size_t operators_len;
-static gsm_sms_entry_t sms_entry;
+static lwgsm_sms_entry_t sms_entry;
-gsm_sms_entry_t sms_entries[10];
+lwgsm_sms_entry_t sms_entries[10];
size_t sms_entries_read;
-gsm_pb_entry_t pb_entries[10];
+lwgsm_pb_entry_t pb_entries[10];
size_t pb_entries_read;
-gsm_operator_curr_t operator_curr;
+lwgsm_operator_curr_t operator_curr;
char model_str[20];
@@ -40,8 +43,8 @@ typedef struct {
const char* puk;
} my_sim_t;
my_sim_t sim = {
- .pin = "7600",
- .puk = "08475703",
+ .pin = "7958",
+ .puk = "10663647",
};
uint8_t lwmem_region_1[0x4000];
@@ -66,7 +69,7 @@ main() {
/* Do nothing at this point but do not close the program */
while (1) {
- gsm_delay(1000);
+ lwgsm_delay(1000);
}
}
@@ -79,12 +82,12 @@ uint8_t request_data[] = ""
"\r\n";
void
-pin_evt(gsmr_t res, void* arg) {
+pin_evt(lwgsmr_t res, void* arg) {
printf("PIN EVT function!\r\n");
}
void
-puk_evt(gsmr_t res, void* arg) {
+puk_evt(lwgsmr_t res, void* arg) {
printf("PUK EVT function!\r\n");
}
@@ -106,93 +109,95 @@ input_thread(void* arg) {
fgets(buff, sizeof(buff), stdin);
if (IS_LINE("reset")) {
- gsm_reset(NULL, NULL, 1);
+ lwgsm_reset(NULL, NULL, 1);
} else if (IS_LINE("devicemanufacturer")) {
- gsm_device_get_manufacturer(model_str, sizeof(model_str), NULL, NULL, 1);
+ lwgsm_device_get_manufacturer(model_str, sizeof(model_str), NULL, NULL, 1);
printf("Manuf: %s\r\n", model_str);
} else if (IS_LINE("devicemodel")) {
- gsm_device_get_model(model_str, sizeof(model_str), NULL, NULL, 1);
+ lwgsm_device_get_model(model_str, sizeof(model_str), NULL, NULL, 1);
printf("Model: %s\r\n", model_str);
} else if (IS_LINE("deviceserial")) {
- gsm_device_get_serial_number(model_str, sizeof(model_str), NULL, NULL, 1);
+ lwgsm_device_get_serial_number(model_str, sizeof(model_str), NULL, NULL, 1);
printf("Serial: %s\r\n", model_str);
} else if (IS_LINE("devicerevision")) {
- gsm_device_get_revision(model_str, sizeof(model_str), NULL, NULL, 1);
+ lwgsm_device_get_revision(model_str, sizeof(model_str), NULL, NULL, 1);
printf("Revision: %s\r\n", model_str);
} else if (IS_LINE("simstatus")) {
- switch (gsm_sim_get_current_state()) {
- case GSM_SIM_STATE_READY: printf("SIM state ready!\r\n"); break;
- case GSM_SIM_STATE_PIN: printf("SIM state PIN\r\n"); break;
- case GSM_SIM_STATE_PUK: printf("SIM state PIN\r\n"); break;
- case GSM_SIM_STATE_NOT_READY: printf("SIM state not ready\r\n"); break;
- case GSM_SIM_STATE_NOT_INSERTED: printf("SIM state not inserted\r\n"); break;
+ switch (lwgsm_sim_get_current_state()) {
+ case LWGSM_SIM_STATE_READY: printf("SIM state ready!\r\n"); break;
+ case LWGSM_SIM_STATE_PIN: printf("SIM state PIN\r\n"); break;
+ case LWGSM_SIM_STATE_PUK: printf("SIM state PIN\r\n"); break;
+ case LWGSM_SIM_STATE_NOT_READY: printf("SIM state not ready\r\n"); break;
+ case LWGSM_SIM_STATE_NOT_INSERTED: printf("SIM state not inserted\r\n"); break;
default: printf("Unknown pin state\r\n"); break;
}
} else if (IS_LINE("simpinadd")) {
- gsm_sim_pin_add(sim.pin, NULL, NULL, 1);
+ lwgsm_sim_pin_add(sim.pin, NULL, NULL, 1);
} else if (IS_LINE("simpinchange")) {
- gsm_sim_pin_change(sim.pin, "1234", NULL, NULL, 1);
- gsm_sim_pin_change("1234", sim.pin, NULL, NULL, 1);
+ lwgsm_sim_pin_change(sim.pin, "1234", NULL, NULL, 1);
+ lwgsm_sim_pin_change("1234", sim.pin, NULL, NULL, 1);
} else if (IS_LINE("simpinremove")) {
- gsm_sim_pin_remove(sim.pin, NULL, NULL, 1);
+ lwgsm_sim_pin_remove(sim.pin, NULL, NULL, 1);
} else if (IS_LINE("simpinenter")) {
- gsm_sim_pin_enter(sim.pin, NULL, NULL, 1);
+ lwgsm_sim_pin_enter(sim.pin, NULL, NULL, 1);
} else if (IS_LINE("simpuk")) {
- gsm_sim_puk_enter(sim.puk, sim.pin, puk_evt, NULL, 1);
+ lwgsm_sim_puk_enter(sim.puk, sim.pin, puk_evt, NULL, 1);
} else if (IS_LINE("operatorscan")) {
- gsm_operator_scan(operators, GSM_ARRAYSIZE(operators), &operators_len, NULL, NULL, 1);
+ lwgsm_operator_scan(operators, LWGSM_ARRAYSIZE(operators), &operators_len, NULL, NULL, 1);
} else if (IS_LINE("join")) {
- gsm_network_request_attach();
+ lwgsm_network_request_attach();
} else if (IS_LINE("quit")) {
- gsm_network_request_detach();
+ lwgsm_network_request_detach();
} else if (IS_LINE("netconnclient")) {
- gsm_sys_sem_t sem;
- gsm_sys_sem_create(&sem, 0);
- gsm_sys_thread_create(NULL, "netconn_client", (gsm_sys_thread_fn)netconn_client_thread, &sem, GSM_SYS_THREAD_SS, GSM_SYS_THREAD_PRIO);
- gsm_sys_sem_wait(&sem, 0);
- gsm_sys_sem_delete(&sem);
-#if GSM_CFG_SMS
+ lwgsm_sys_sem_t sem;
+ lwgsm_sys_sem_create(&sem, 0);
+ lwgsm_sys_thread_create(NULL, "netconn_client", (lwgsm_sys_thread_fn)netconn_client_thread, &sem, LWGSM_SYS_THREAD_SS, LWGSM_SYS_THREAD_PRIO);
+ lwgsm_sys_sem_wait(&sem, 0);
+ lwgsm_sys_sem_delete(&sem);
+#if LWGSM_CFG_SMS
} else if (IS_LINE("smsenable")) {
- gsm_sms_enable(NULL, NULL, 1);
+ lwgsm_sms_enable(NULL, NULL, 1);
} else if (IS_LINE("smsdisable")) {
- gsm_sms_disable(NULL, NULL, 1);
+ lwgsm_sms_disable(NULL, NULL, 1);
} else if (IS_LINE("smssend")) {
- gsm_sms_send("+38631779982", "Hello world!", NULL, NULL, 1);
+ lwgsm_sms_send("+38631779982", "Hello world!", NULL, NULL, 1);
} else if (IS_LINE("smslist")) {
- gsm_sms_list(GSM_MEM_CURRENT, GSM_SMS_STATUS_ALL, sms_entries, GSM_ARRAYSIZE(sms_entries), &sms_entries_read, 0, NULL, NULL, 1);
+ lwgsm_sms_list(LWGSM_MEM_CURRENT, LWGSM_SMS_STATUS_ALL, sms_entries, LWGSM_ARRAYSIZE(sms_entries), &sms_entries_read, 0, NULL, NULL, 1);
} else if (IS_LINE("smsdeleteall")) {
- gsm_sms_delete_all(GSM_SMS_STATUS_ALL, NULL, NULL, 1);
+ lwgsm_sms_delete_all(LWGSM_SMS_STATUS_ALL, NULL, NULL, 1);
} else if (IS_LINE("smsthread")) {
- gsm_sys_thread_create(NULL, "sms_recv_send", (gsm_sys_thread_fn)sms_send_receive_thread, NULL, GSM_SYS_THREAD_SS, GSM_SYS_THREAD_PRIO);
-#endif /* GSM_CFG_SMS */
-#if GSM_CFG_CALL
+ lwgsm_sys_thread_create(NULL, "sms_recv_send", (lwgsm_sys_thread_fn)sms_send_receive_thread, NULL, LWGSM_SYS_THREAD_SS, LWGSM_SYS_THREAD_PRIO);
+#endif /* LWGSM_CFG_SMS */
+#if LWGSM_CFG_CALL
} else if (IS_LINE("callenable")) {
- gsm_call_enable(NULL, NULL, 1);
+ lwgsm_call_enable(NULL, NULL, 1);
} else if (IS_LINE("calldisable")) {
- gsm_call_disable(NULL, NULL, 1);
+ lwgsm_call_disable(NULL, NULL, 1);
} else if (IS_LINE("callstart")) {
- gsm_call_start("+38631779982", NULL, NULL, 1);
+ lwgsm_call_start("+38631779982", NULL, NULL, 1);
} else if (IS_LINE("callhangup")) {
- gsm_call_hangup(NULL, NULL, 1);
+ lwgsm_call_hangup(NULL, NULL, 1);
} else if (IS_LINE("callanswer")) {
- gsm_call_answer(NULL, NULL, 1);
-#endif /* GSM_CFG_CALL */
-#if GSM_CFG_PHONEBOOK
+ lwgsm_call_answer(NULL, NULL, 1);
+#endif /* LWGSM_CFG_CALL */
+#if LWGSM_CFG_PHONEBOOK
} else if (IS_LINE("pbenable")) {
- gsm_pb_enable(NULL, NULL, 1);
+ lwgsm_pb_enable(NULL, NULL, 1);
} else if (IS_LINE("pbread")) {
- gsm_pb_read(GSM_MEM_CURRENT, 1, pb_entries, NULL, NULL, 1);
+ lwgsm_pb_read(LWGSM_MEM_CURRENT, 1, pb_entries, NULL, NULL, 1);
} else if (IS_LINE("pblist")) {
- gsm_pb_list(GSM_MEM_CURRENT, 1, pb_entries, GSM_ARRAYSIZE(pb_entries), &pb_entries_read, NULL, NULL, 1);
-#endif /* GSM_CFG_PHONEBOOK */
+ lwgsm_pb_list(LWGSM_MEM_CURRENT, 1, pb_entries, LWGSM_ARRAYSIZE(pb_entries), &pb_entries_read, NULL, NULL, 1);
+#endif /* LWGSM_CFG_PHONEBOOK */
} else if (IS_LINE("mqttthread")) {
- gsm_sys_thread_create(NULL, "mqtt_client_api", (gsm_sys_thread_fn)mqtt_client_api_thread, NULL, GSM_SYS_THREAD_SS, GSM_SYS_THREAD_PRIO);
-#if GSM_CFG_USSD
+ lwgsm_sys_thread_create(NULL, "mqtt_client_api", (lwgsm_sys_thread_fn)mqtt_client_api_thread, NULL, LWGSM_SYS_THREAD_SS, LWGSM_SYS_THREAD_PRIO);
+ } else if (IS_LINE("client")) {
+ client_connect();
+#if LWGSM_CFG_USSD
} else if (IS_LINE("ussd")) {
char response[128];
- gsm_ussd_run("*123#", response, sizeof(response), NULL, NULL, 1);
+ lwgsm_ussd_run("*123#", response, sizeof(response), NULL, NULL, 1);
printf("Command finished!\r\n");
-#endif /* GSM_CFG_USSD */
+#endif /* LWGSM_CFG_USSD */
} else {
printf("Unknown input!\r\n");
}
@@ -204,144 +209,144 @@ input_thread(void* arg) {
*/
static void
main_thread(void* arg) {
- gsm_sim_state_t sim_state;
+ lwgsm_sim_state_t sim_state;
/* Init GSM library */
- gsm_init(gsm_evt, 1);
+ lwgsm_init(lwgsm_evt, 1);
/* Set global network credentials */
- gsm_network_set_credentials("internet", "", "");
+ lwgsm_network_set_credentials(NETWORK_APN, NETWORK_APN_USER, NETWORK_APN_PASS);
/* Start input thread */
- gsm_sys_thread_create(NULL, "input", (gsm_sys_thread_fn)input_thread, NULL, 0, GSM_SYS_THREAD_PRIO);
+ lwgsm_sys_thread_create(NULL, "input", (lwgsm_sys_thread_fn)input_thread, NULL, 0, LWGSM_SYS_THREAD_PRIO);
while (1) {
/* Check for sim card */
- while ((sim_state = gsm_sim_get_current_state()) != GSM_SIM_STATE_READY) {
- if (sim_state == GSM_SIM_STATE_PIN) {
+ while ((sim_state = lwgsm_sim_get_current_state()) != LWGSM_SIM_STATE_READY) {
+ if (sim_state == LWGSM_SIM_STATE_PIN) {
printf("GSM state PIN\r\n");
- gsm_sim_pin_enter(sim.pin, pin_evt, NULL, 1);
- } else if (sim_state == GSM_SIM_STATE_PUK) {
+ lwgsm_sim_pin_enter(sim.pin, pin_evt, NULL, 1);
+ } else if (sim_state == LWGSM_SIM_STATE_PUK) {
printf("GSM state PUK\r\n");
- gsm_sim_puk_enter(sim.puk, sim.pin, puk_evt, NULL, 1);
- } else if (sim_state == GSM_SIM_STATE_NOT_READY) {
+ lwgsm_sim_puk_enter(sim.puk, sim.pin, puk_evt, NULL, 1);
+ } else if (sim_state == LWGSM_SIM_STATE_NOT_READY) {
printf("GSM SIM state not ready!\r\n");
- } else if (sim_state == GSM_SIM_STATE_NOT_INSERTED) {
+ } else if (sim_state == LWGSM_SIM_STATE_NOT_INSERTED) {
printf("GSM SIM not inserted!\r\n");
}
- gsm_delay(1000);
+ lwgsm_delay(1000);
}
/* Some delay */
- gsm_delay(1000);
+ lwgsm_delay(1000);
}
/* Terminate thread */
- gsm_sys_thread_terminate(NULL);
+ lwgsm_sys_thread_terminate(NULL);
}
-static gsmr_t
-gsm_conn_evt(gsm_evt_t* evt) {
- gsm_conn_p c;
- c = gsm_conn_get_from_evt(evt);
- switch (gsm_evt_get_type(evt)) {
-#if GSM_CFG_CONN
- case GSM_EVT_CONN_ACTIVE: {
+static lwgsmr_t
+lwgsm_conn_evt(lwgsm_evt_t* evt) {
+ lwgsm_conn_p c;
+ c = lwgsm_conn_get_from_evt(evt);
+ switch (lwgsm_evt_get_type(evt)) {
+#if LWGSM_CFG_CONN
+ case LWGSM_EVT_CONN_ACTIVE: {
printf("Connection active\r\n");
- //gsm_conn_send(c, request_data, sizeof(request_data) - 1, NULL, 0);
+ //lwgsm_conn_send(c, request_data, sizeof(request_data) - 1, NULL, 0);
break;
}
- case GSM_EVT_CONN_ERROR: {
+ case LWGSM_EVT_CONN_ERROR: {
printf("Connection error\r\n");
break;
}
- case GSM_EVT_CONN_CLOSE: {
+ case LWGSM_EVT_CONN_CLOSE: {
printf("Connection closed\r\n");
break;
}
- case GSM_EVT_CONN_SEND: {
- gsmr_t res = gsm_evt_conn_send_get_result(evt);
- if (res == gsmOK) {
+ case LWGSM_EVT_CONN_SEND: {
+ lwgsmr_t res = lwgsm_evt_conn_send_get_result(evt);
+ if (res == lwgsmOK) {
printf("Data sent!\r\n");
} else {
printf("Data send error!\r\n");
}
break;
}
- case GSM_EVT_CONN_RECV: {
- gsm_pbuf_p p = gsm_evt_conn_recv_get_buff(evt);
- printf("DATA RECEIVED: %d\r\n", (int)gsm_pbuf_length(p, 1));
- gsm_conn_recved(c, p);
+ case LWGSM_EVT_CONN_RECV: {
+ lwgsm_pbuf_p p = lwgsm_evt_conn_recv_get_buff(evt);
+ printf("DATA RECEIVED: %d\r\n", (int)lwgsm_pbuf_length(p, 1));
+ lwgsm_conn_recved(c, p);
break;
}
-#endif /* GSM_CFG_CONN */
+#endif /* LWGSM_CFG_CONN */
default: break;
}
- return gsmOK;
+ return lwgsmOK;
}
/**
* \brief Global GSM event function callback
* \param[in] cb: Event information
- * \return gsmOK on success, member of \ref gsmr_t otherwise
+ * \return lwgsmOK on success, member of \ref lwgsmr_t otherwise
*/
-static gsmr_t
-gsm_evt(gsm_evt_t* evt) {
- switch (gsm_evt_get_type(evt)) {
- case GSM_EVT_INIT_FINISH: {
+static lwgsmr_t
+lwgsm_evt(lwgsm_evt_t* evt) {
+ switch (lwgsm_evt_get_type(evt)) {
+ case LWGSM_EVT_INIT_FINISH: {
break;
}
- case GSM_EVT_RESET: {
- if (gsm_evt_reset_get_result(evt) == gsmOK) {
+ case LWGSM_EVT_RESET: {
+ if (lwgsm_evt_reset_get_result(evt) == lwgsmOK) {
printf("Reset sequence finished with success!\r\n");
}
break;
}
- case GSM_EVT_SIM_STATE_CHANGED: {
+ case LWGSM_EVT_SIM_STATE_CHANGED: {
break;
}
- case GSM_EVT_DEVICE_IDENTIFIED: {
+ case LWGSM_EVT_DEVICE_IDENTIFIED: {
printf("Device has been identified!\r\n");
break;
}
- case GSM_EVT_SIGNAL_STRENGTH: {
- int16_t rssi = gsm_evt_signal_strength_get_rssi(evt);
+ case LWGSM_EVT_SIGNAL_STRENGTH: {
+ int16_t rssi = lwgsm_evt_signal_strength_get_rssi(evt);
printf("Signal strength: %d\r\n", (int)rssi);
break;
}
- case GSM_EVT_NETWORK_REG_CHANGED: {
- gsm_network_reg_status_t status = gsm_network_get_reg_status();
+ case LWGSM_EVT_NETWORK_REG_CHANGED: {
+ lwgsm_network_reg_status_t status = lwgsm_network_get_reg_status();
printf("Network registration changed. New status: %d! ", (int)status);
switch (status) {
- case GSM_NETWORK_REG_STATUS_CONNECTED: printf("Connected to home network!\r\n"); break;
- case GSM_NETWORK_REG_STATUS_CONNECTED_ROAMING: printf("Connected to network and roaming!\r\n"); break;
- case GSM_NETWORK_REG_STATUS_SEARCHING: printf("Searching for network!\r\n"); break;
- case GSM_NETWORK_REG_STATUS_SIM_ERR: printf("SIM error\r\n"); break;
+ case LWGSM_NETWORK_REG_STATUS_CONNECTED: printf("Connected to home network!\r\n"); break;
+ case LWGSM_NETWORK_REG_STATUS_CONNECTED_ROAMING: printf("Connected to network and roaming!\r\n"); break;
+ case LWGSM_NETWORK_REG_STATUS_SEARCHING: printf("Searching for network!\r\n"); break;
+ case LWGSM_NETWORK_REG_STATUS_SIM_ERR: printf("SIM error\r\n"); break;
default: break;
}
break;
}
- case GSM_EVT_NETWORK_OPERATOR_CURRENT: {
- const gsm_operator_curr_t* op = gsm_evt_network_operator_get_current(evt);
+ case LWGSM_EVT_NETWORK_OPERATOR_CURRENT: {
+ const lwgsm_operator_curr_t* op = lwgsm_evt_network_operator_get_current(evt);
if (op != NULL) {
- if (op->format == GSM_OPERATOR_FORMAT_LONG_NAME) {
+ if (op->format == LWGSM_OPERATOR_FORMAT_LONG_NAME) {
printf("Operator long name: %s\r\n", op->data.long_name);
- } else if (op->format == GSM_OPERATOR_FORMAT_SHORT_NAME) {
+ } else if (op->format == LWGSM_OPERATOR_FORMAT_SHORT_NAME) {
printf("Operator short name: %s\r\n", op->data.short_name);
- } else if (op->format == GSM_OPERATOR_FORMAT_NUMBER) {
+ } else if (op->format == LWGSM_OPERATOR_FORMAT_NUMBER) {
printf("Operator number: %d\r\n", (int)op->data.num);
}
}
break;
}
- case GSM_EVT_OPERATOR_SCAN: {
- gsm_operator_t* ops;
+ case LWGSM_EVT_OPERATOR_SCAN: {
+ lwgsm_operator_t* ops;
size_t length;
printf("Operator scan finished!\r\n");
- if (gsm_evt_operator_scan_get_result(evt) == gsmOK) {
- ops = gsm_evt_operator_scan_get_entries(evt);
- length = gsm_evt_operator_scan_get_length(evt);
+ if (lwgsm_evt_operator_scan_get_result(evt) == lwgsmOK) {
+ ops = lwgsm_evt_operator_scan_get_entries(evt);
+ length = lwgsm_evt_operator_scan_get_length(evt);
for (size_t i = 0; i < length; i++) {
printf("Operator %2d: %s: %s\r\n", (int)i, ops[i].short_name, ops[i].long_name);
@@ -351,66 +356,66 @@ gsm_evt(gsm_evt_t* evt) {
}
break;
}
-#if GSM_CFG_NETWORK
- case GSM_EVT_NETWORK_ATTACHED: {
- gsm_ip_t ip;
+#if LWGSM_CFG_NETWORK
+ case LWGSM_EVT_NETWORK_ATTACHED: {
+ lwgsm_ip_t ip;
printf("\r\n---\r\n--- Network attached! ---\r\n---\r\n");
- if (gsm_network_copy_ip(&ip) == gsmOK) {
+ if (lwgsm_network_copy_ip(&ip) == lwgsmOK) {
printf("\r\n---\r\n--- IP: %d.%d.%d.%d ---\r\n---\r\n",
(int)ip.ip[0], (int)ip.ip[1], (int)ip.ip[2], (int)ip.ip[3]
);
}
break;
}
- case GSM_EVT_NETWORK_DETACHED: {
+ case LWGSM_EVT_NETWORK_DETACHED: {
printf("\r\n---\r\n--- Network detached! ---\r\n---\r\n");
break;
}
-#endif /* GSM_CFG_NETWORK */
-#if GSM_CFG_CALL
- case GSM_EVT_CALL_READY: {
+#endif /* LWGSM_CFG_NETWORK */
+#if LWGSM_CFG_CALL
+ case LWGSM_EVT_CALL_READY: {
printf("Call is ready!\r\n");
break;
}
- case GSM_EVT_CALL_CHANGED: {
- const gsm_call_t* call = evt->evt.call_changed.call;
+ case LWGSM_EVT_CALL_CHANGED: {
+ const lwgsm_call_t* call = evt->evt.call_changed.call;
printf("Call changed!\r\n");
- if (call->state == GSM_CALL_STATE_ACTIVE) {
+ if (call->state == LWGSM_CALL_STATE_ACTIVE) {
printf("Call active!\r\n");
- } else if (call->state == GSM_CALL_STATE_INCOMING) {
+ } else if (call->state == LWGSM_CALL_STATE_INCOMING) {
printf("Incoming call. Answering...\r\n");
}
break;
}
-#endif /* GSM_CFG_CALL */
-#if GSM_CFG_SMS
- case GSM_EVT_SMS_READY: {
+#endif /* LWGSM_CFG_CALL */
+#if LWGSM_CFG_SMS
+ case LWGSM_EVT_SMS_READY: {
printf("SMS is ready!\r\n");
- //gsm_sms_send("+38640167724", "Device reset and ready for more operations!", 0);
+ //lwgsm_sms_send("+38640167724", "Device reset and ready for more operations!", 0);
break;
}
- case GSM_EVT_SMS_SEND: {
- if (evt->evt.sms_send.res == gsmOK) {
+ case LWGSM_EVT_SMS_SEND: {
+ if (evt->evt.sms_send.res == lwgsmOK) {
printf("SMS sent successfully!\r\n");
} else {
printf("SMS was not sent!\r\n");
}
break;
}
- case GSM_EVT_SMS_RECV: {
+ case LWGSM_EVT_SMS_RECV: {
printf("SMS received: %d\r\n", (int)evt->evt.sms_recv.pos);
- gsm_sms_read(evt->evt.sms_recv.mem, evt->evt.sms_recv.pos, &sms_entry, 0, NULL, NULL, 0);
- //gsm_sms_delete(evt->evt.sms_recv.mem, evt->evt.sms_recv.pos, NULL, NULL, 0);
+ lwgsm_sms_read(evt->evt.sms_recv.mem, evt->evt.sms_recv.pos, &sms_entry, 0, NULL, NULL, 0);
+ //lwgsm_sms_delete(evt->evt.sms_recv.mem, evt->evt.sms_recv.pos, NULL, NULL, 0);
break;
}
- case GSM_EVT_SMS_READ: {
- gsm_sms_entry_t* e = evt->evt.sms_read.entry;
+ case LWGSM_EVT_SMS_READ: {
+ lwgsm_sms_entry_t* e = evt->evt.sms_read.entry;
printf("SMS read: num: %s, name: %s, data: %s\r\n", e->number, e->name, e->data);
break;
}
- case GSM_EVT_SMS_LIST: {
- gsm_sms_entry_t* e = evt->evt.sms_list.entries;
+ case LWGSM_EVT_SMS_LIST: {
+ lwgsm_sms_entry_t* e = evt->evt.sms_list.entries;
size_t i;
for (i = 0; i < evt->evt.sms_list.size; i++) {
@@ -420,10 +425,10 @@ gsm_evt(gsm_evt_t* evt) {
}
break;
}
-#endif /* GSM_CFG_SMS */
-#if GSM_CFG_PHONEBOOK
- case GSM_EVT_PB_LIST: {
- gsm_pb_entry_t* e = evt->evt.pb_list.entries;
+#endif /* LWGSM_CFG_SMS */
+#if LWGSM_CFG_PHONEBOOK
+ case LWGSM_EVT_PB_LIST: {
+ lwgsm_pb_entry_t* e = evt->evt.pb_list.entries;
size_t i;
for (i = 0; i < evt->evt.pb_list.size; i++) {
@@ -433,8 +438,8 @@ gsm_evt(gsm_evt_t* evt) {
}
break;
}
- case GSM_EVT_PB_SEARCH: {
- gsm_pb_entry_t* e = evt->evt.pb_search.entries;
+ case LWGSM_EVT_PB_SEARCH: {
+ lwgsm_pb_entry_t* e = evt->evt.pb_search.entries;
size_t i;
for (i = 0; i < evt->evt.pb_search.size; i++) {
@@ -444,16 +449,16 @@ gsm_evt(gsm_evt_t* evt) {
}
break;
}
-#endif /* GSM_CFG_PHONECALL */
+#endif /* LWGSM_CFG_PHONECALL */
default: break;
}
- return gsmOK;
+ return lwgsmOK;
}
-#if GSM_CFG_MEM_CUSTOM && 0
+#if LWGSM_CFG_MEM_CUSTOM && 0
void *
-gsm_mem_malloc(size_t size) {
+lwgsm_mem_malloc(size_t size) {
void* ptr;
while (WaitForSingleObject(allocation_mutex, INFINITE) != WAIT_OBJECT_0) {}
@@ -463,7 +468,7 @@ gsm_mem_malloc(size_t size) {
}
void *
-gsm_mem_realloc(void* ptr, size_t size) {
+lwgsm_mem_realloc(void* ptr, size_t size) {
void* p;
while (WaitForSingleObject(allocation_mutex, INFINITE) != WAIT_OBJECT_0) {}
@@ -473,7 +478,7 @@ gsm_mem_realloc(void* ptr, size_t size) {
}
void *
-gsm_mem_calloc(size_t num, size_t size) {
+lwgsm_mem_calloc(size_t num, size_t size) {
void* ptr;
while (WaitForSingleObject(allocation_mutex, INFINITE) != WAIT_OBJECT_0) {}
@@ -483,9 +488,9 @@ gsm_mem_calloc(size_t num, size_t size) {
}
void
-gsm_mem_free(void* ptr) {
+lwgsm_mem_free(void* ptr) {
while (WaitForSingleObject(allocation_mutex, INFINITE) != WAIT_OBJECT_0) {}
free(ptr);
ReleaseMutex(allocation_mutex);
}
-#endif /* GSM_CFG_MEM_CUSTOM */
+#endif /* LWGSM_CFG_MEM_CUSTOM */
diff --git a/docs/4a-esp8266_at_instruction_set_en.pdf b/docs/4a-esp8266_at_instruction_set_en.pdf
new file mode 100644
index 00000000..8ce6e9f9
Binary files /dev/null and b/docs/4a-esp8266_at_instruction_set_en.pdf differ
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644
index 00000000..d4bb2cbb
--- /dev/null
+++ b/docs/Makefile
@@ -0,0 +1,20 @@
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line, and also
+# from the environment for the first two.
+SPHINXOPTS ?=
+SPHINXBUILD ?= sphinx-build
+SOURCEDIR = .
+BUILDDIR = _build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/docs/api-reference/apps/index.rst b/docs/api-reference/apps/index.rst
new file mode 100644
index 00000000..86bb8c46
--- /dev/null
+++ b/docs/api-reference/apps/index.rst
@@ -0,0 +1,10 @@
+.. _api_apps:
+
+Applications
+============
+
+.. toctree::
+ :maxdepth: 2
+ :glob:
+
+ *
\ No newline at end of file
diff --git a/docs/api-reference/apps/mqtt_client.rst b/docs/api-reference/apps/mqtt_client.rst
new file mode 100644
index 00000000..6e17b43f
--- /dev/null
+++ b/docs/api-reference/apps/mqtt_client.rst
@@ -0,0 +1,14 @@
+.. _api_app_mqtt_client:
+
+MQTT Client
+===========
+
+MQTT client v3.1.1 implementation, based on callback (non-netconn) connection API.
+
+.. literalinclude:: ../../../snippets/mqtt_client.c
+ :language: c
+ :linenos:
+ :caption: MQTT application example code
+
+.. doxygengroup:: LWGSM_APP_MQTT_CLIENT
+.. doxygengroup:: LWGSM_APP_MQTT_CLIENT_EVT
\ No newline at end of file
diff --git a/docs/api-reference/apps/mqtt_client_api.rst b/docs/api-reference/apps/mqtt_client_api.rst
new file mode 100644
index 00000000..3220fc4f
--- /dev/null
+++ b/docs/api-reference/apps/mqtt_client_api.rst
@@ -0,0 +1,13 @@
+.. _api_app_mqtt_client_api:
+
+MQTT Client API
+===============
+
+*MQTT Client API* provides sequential API built on top of :ref:`api_app_mqtt_client`.
+
+.. literalinclude:: ../../../snippets/mqtt_client_api.c
+ :language: c
+ :linenos:
+ :caption: MQTT API application example code
+
+.. doxygengroup:: LWGSM_APP_MQTT_CLIENT_API
\ No newline at end of file
diff --git a/docs/api-reference/apps/netconn.rst b/docs/api-reference/apps/netconn.rst
new file mode 100644
index 00000000..33dbd489
--- /dev/null
+++ b/docs/api-reference/apps/netconn.rst
@@ -0,0 +1,55 @@
+.. _api_app_netconn:
+
+Netconn API
+===========
+
+*Netconn API* is addon on top of existing connection module and allows sending and receiving data with sequential API calls, similar to *POSIX socket* API.
+
+It can operate in client mode and uses operating system features, such as message queues and semaphore to link non-blocking callback API for connections with sequential API for application thread.
+
+.. note::
+ Connection API does not directly allow receiving data with sequential and linear code execution.
+ All is based on connection event system.
+ Netconn adds this functionality as it is implemented on top of regular connection API.
+
+.. warning::
+ Netconn API are designed to be called from application threads ONLY.
+ It is not allowed to call any of *netconn API* functions from within interrupt or callback event functions.
+
+Netconn client
+^^^^^^^^^^^^^^
+
+.. figure:: ../../static/images/netconn_client.svg
+ :align: center
+ :alt: Netconn API client block diagram
+
+ Netconn API client block diagram
+
+Above block diagram shows basic architecture of netconn client application.
+There is always one application thread (in green) which calls *netconn API* functions to interact with connection API in synchronous mode.
+
+Every netconn connection uses dedicated structure to handle message queue for data received packet buffers.
+Each time new packet is received (red block, *data received event*), reference to it is written to message queue of netconn structure, while application thread reads new entries from the same queue to get packets.
+
+.. literalinclude:: ../../../snippets/netconn_client.c
+ :language: c
+ :linenos:
+ :caption: Netconn client example
+
+Non-blocking receive
+^^^^^^^^^^^^^^^^^^^^
+
+By default, netconn API is written to only work in separate application thread,
+dedicated for network connection processing. Because of that, by default every function is fully blocking.
+It will wait until result is ready to be used by application.
+
+It is, however, possible to enable timeout feature for receiving data only.
+When this feature is enabled, :cpp:func:`lwgsm_netconn_receive` will block for maximal timeout set with
+:cpp:func:`lwgsm_netconn_set_receive_timeout` function.
+
+When enabled, if there is no received data for timeout amount of time, function will return with timeout status and application needs to process it accordingly.
+
+.. tip::
+ :c:macro:`LWGSM_CFG_NETCONN_RECEIVE_TIMEOUT` must be set to ``1`` to use this feature.
+
+.. doxygengroup:: LWGSM_NETCONN
\ No newline at end of file
diff --git a/docs/api-reference/index.rst b/docs/api-reference/index.rst
new file mode 100644
index 00000000..5abaa6fa
--- /dev/null
+++ b/docs/api-reference/index.rst
@@ -0,0 +1,14 @@
+.. _api_reference:
+
+API reference
+=============
+
+List of all the modules:
+
+.. toctree::
+ :maxdepth: 2
+
+ lwgsm/index
+ opt
+ port/index
+ apps/index
\ No newline at end of file
diff --git a/docs/api-reference/lwgsm/buff.rst b/docs/api-reference/lwgsm/buff.rst
new file mode 100644
index 00000000..d64b47ff
--- /dev/null
+++ b/docs/api-reference/lwgsm/buff.rst
@@ -0,0 +1,6 @@
+.. _api_lwgsm_buff:
+
+Ring buffer
+===========
+
+.. doxygengroup:: LWGSM_BUFF
\ No newline at end of file
diff --git a/docs/api-reference/lwgsm/conn.rst b/docs/api-reference/lwgsm/conn.rst
new file mode 100644
index 00000000..949f2946
--- /dev/null
+++ b/docs/api-reference/lwgsm/conn.rst
@@ -0,0 +1,69 @@
+.. _api_lwgsm_conn:
+
+Connections
+===========
+
+Connections are essential feature of WiFi device and middleware.
+It is developed with strong focus on its performance and since it may interact with huge amount of data,
+it tries to use zero-copy (when available) feature, to decrease processing time.
+
+*GSM AT Firmware* by default supports up to ``5`` connections being active at the same time and supports:
+
+* Up to ``5`` TCP connections active at the same time
+* Up to ``5`` UDP connections active at the same time
+* Up to ``1`` SSL connection active at a time
+
+.. note::
+ Client or server connections are available.
+ Same API function call are used to send/receive data or close connection.
+
+Architecture of the connection API is using callback event functions.
+This allows maximal optimization in terms of responsiveness on different kind of events.
+
+Example below shows *bare minimum* implementation to:
+
+* Start a new connection to remote host
+* Send *HTTP GET* request to remote host
+* Process received data in event and print number of received bytes
+
+.. literalinclude:: ../../../snippets/client.c
+ :language: c
+ :linenos:
+ :caption: Client connection minimum example
+
+Sending data
+^^^^^^^^^^^^
+
+Receiving data flow is always the same. Whenever new data packet arrives, corresponding event is called to notify application layer.
+When it comes to sending data, application may decide between ``2`` options (*this is valid only for non-UDP connections):
+
+* Write data to temporary transmit buffer
+* Execute *send command* for every API function call
+
+Temporary transmit buffer
+*************************
+
+By calling :cpp:func:`lwgsm_conn_write` on active connection, temporary buffer is allocated and input data are copied to it.
+There is always up to ``1`` internal buffer active. When it is full (or if input data length is longer than maximal size),
+data are immediately send out and are not written to buffer.
+
+*GSM AT Firmware* allows (current revision) to transmit up to ``2048`` bytes at a time with single command.
+When trying to send more than this, application would need to issue multiple *send commands* on *AT commands level*.
+
+Write option is used mostly when application needs to write many different small chunks of data.
+Temporary buffer hence prevents many *send command* instructions as it is faster to send single command with big buffer,
+than many of them with smaller chunks of bytes.
+
+.. literalinclude:: ../../examples_src/conn_write.c
+ :language: c
+ :linenos:
+ :caption: Write data to connection output buffer
+
+Transmit packet manually
+************************
+
+In some cases it is not possible to use temporary buffers,
+mostly because of memory constraints.
+Application can directly start *send data* instructions on *AT* level by using :cpp:func:`lwgsm_conn_send` or :cpp:func:`lwgsm_conn_sendto` functions.
+
+.. doxygengroup:: LWGSM_CONN
\ No newline at end of file
diff --git a/docs/api-reference/lwgsm/debug.rst b/docs/api-reference/lwgsm/debug.rst
new file mode 100644
index 00000000..a9953e53
--- /dev/null
+++ b/docs/api-reference/lwgsm/debug.rst
@@ -0,0 +1,39 @@
+.. _api_lwgsm_debug:
+
+Debug support
+=============
+
+Middleware has extended debugging capabilities.
+These consist of different debugging levels and types of debug messages,
+allowing to track and catch different types of warnings, severe problems or simply output messages
+program flow messages (trace messages).
+
+Module is highly configurable using library configuration methods.
+Application must enable some options to decide what type of messages and for which modules it would like to output messages.
+
+With default configuration, ``printf`` is used as output function.
+This behavior can be changed with :c:macro:`LWGSM_CFG_DBG_OUT` configuration.
+
+For successful debugging, application must:
+
+* Enable global debugging by setting :c:macro:`LWGSM_CFG_DBG` to :c:macro:`LWGSM_DBG_ON`
+* Configure which types of messages to output
+* Configure debugging level, from all messages to severe only
+* Enable specific modules to debug, by setting its configuration value to :c:macro:`LWGSM_DBG_ON`
+
+.. tip::
+ Check :ref:`api_lwgsm_opt` for all modules with debug implementation.
+
+An example code with config and latter usage:
+
+.. literalinclude:: ../../examples_src/debug_opts.h
+ :language: c
+ :linenos:
+ :caption: Debug configuration setup
+
+.. literalinclude:: ../../examples_src/debug.c
+ :language: c
+ :linenos:
+ :caption: Debug usage within middleware
+
+.. doxygengroup:: LWGSM_DEBUG
\ No newline at end of file
diff --git a/docs/api-reference/lwgsm/device_info.rst b/docs/api-reference/lwgsm/device_info.rst
new file mode 100644
index 00000000..17386aa5
--- /dev/null
+++ b/docs/api-reference/lwgsm/device_info.rst
@@ -0,0 +1,6 @@
+.. _api_lwgsm_device_info:
+
+Device info
+===========
+
+.. doxygengroup:: LWGSM_DEVICE_INFO
\ No newline at end of file
diff --git a/docs/api-reference/lwgsm/evt.rst b/docs/api-reference/lwgsm/evt.rst
new file mode 100644
index 00000000..3029e7a0
--- /dev/null
+++ b/docs/api-reference/lwgsm/evt.rst
@@ -0,0 +1,6 @@
+.. _api_lwgsm_evt:
+
+Event management
+================
+
+.. doxygengroup:: LWGSM_EVT
\ No newline at end of file
diff --git a/docs/api-reference/lwgsm/ftp.rst b/docs/api-reference/lwgsm/ftp.rst
new file mode 100644
index 00000000..1f64016a
--- /dev/null
+++ b/docs/api-reference/lwgsm/ftp.rst
@@ -0,0 +1,6 @@
+.. _api_lwgsm_ftp:
+
+File Transfer Protocol
+======================
+
+.. doxygengroup:: LWGSM_FTP
\ No newline at end of file
diff --git a/docs/api-reference/lwgsm/http.rst b/docs/api-reference/lwgsm/http.rst
new file mode 100644
index 00000000..31717e33
--- /dev/null
+++ b/docs/api-reference/lwgsm/http.rst
@@ -0,0 +1,6 @@
+.. _api_lwgsm_http:
+
+HTTP
+====
+
+.. doxygengroup:: LWGSM_HTTP
\ No newline at end of file
diff --git a/docs/api-reference/lwgsm/index.rst b/docs/api-reference/lwgsm/index.rst
new file mode 100644
index 00000000..3fe6d2fe
--- /dev/null
+++ b/docs/api-reference/lwgsm/index.rst
@@ -0,0 +1,12 @@
+.. _api_lwgsm:
+
+LwGSM
+=====
+
+.. toctree::
+ :maxdepth: 2
+ :glob:
+
+ *
+
+.. doxygengroup:: LWGSM
\ No newline at end of file
diff --git a/docs/api-reference/lwgsm/input.rst b/docs/api-reference/lwgsm/input.rst
new file mode 100644
index 00000000..ba8c05b6
--- /dev/null
+++ b/docs/api-reference/lwgsm/input.rst
@@ -0,0 +1,43 @@
+.. _api_lwgsm_input:
+
+Input module
+============
+
+Input module is used to input received data from *GSM* device to *LwGSM-Lib* middleware part.
+``2`` processing options are possible:
+
+* Indirect processing with :cpp:func:`lwgsm_input` (default mode)
+* Direct processing with :cpp:func:`lwgsm_input_process`
+
+.. tip::
+ Direct or indirect processing mode is select by setting :c:macro:`LWGSM_CFG_INPUT_USE_PROCESS` configuration value.
+
+Indirect processing
+^^^^^^^^^^^^^^^^^^^
+
+With indirect processing mode, every received character from *GSM* physical device is written to
+intermediate buffer between low-level driver and *processing* thread.
+
+Function :cpp:func:`lwgsm_input` is used to write data to buffer, which is later processed
+by *processing* thread.
+
+Indirect processing mode allows embedded systems to write received data to buffer from interrupt context (outside threads).
+As a drawback, its performance is decreased as it involves copying every receive character to intermediate buffer,
+and may also introduce RAM memory footprint increase.
+
+Direct processing
+^^^^^^^^^^^^^^^^^
+
+Direct processing is targeting more advanced host controllers, like STM32 or WIN32 implementation use.
+It is developed with DMA support in mind, allowing low-level drivers to skip intermediate data buffer
+and process input bytes directly.
+
+.. note::
+ When using this mode, function :cpp:func:`lwgsm_input_process` must be used and it may
+ only be called from thread context. Processing of input bytes is done in low-level
+ input thread, started by application.
+
+.. tip::
+ Check :ref:`um_porting_guide` for implementation examples.
+
+.. doxygengroup:: LWGSM_INPUT
\ No newline at end of file
diff --git a/docs/api-reference/lwgsm/mem.rst b/docs/api-reference/lwgsm/mem.rst
new file mode 100644
index 00000000..d832e187
--- /dev/null
+++ b/docs/api-reference/lwgsm/mem.rst
@@ -0,0 +1,6 @@
+.. _api_lwgsm_mem:
+
+Memory manager
+==============
+
+.. doxygengroup:: LWGSM_MEM
\ No newline at end of file
diff --git a/docs/api-reference/lwgsm/network.rst b/docs/api-reference/lwgsm/network.rst
new file mode 100644
index 00000000..d7cababd
--- /dev/null
+++ b/docs/api-reference/lwgsm/network.rst
@@ -0,0 +1,6 @@
+.. _api_lwgsm_network:
+
+Network
+=======
+
+.. doxygengroup:: LWGSM_NETWORK
\ No newline at end of file
diff --git a/docs/api-reference/lwgsm/network_api.rst b/docs/api-reference/lwgsm/network_api.rst
new file mode 100644
index 00000000..0ac40da8
--- /dev/null
+++ b/docs/api-reference/lwgsm/network_api.rst
@@ -0,0 +1,11 @@
+.. _api_lwgsm_network_api:
+
+Network API
+===========
+
+Network API provides functions for multi-thread application network management.
+It allows multiple threads to request to join to network (internet access).
+
+Network API module controls when network connection shall be active or can be closed.
+
+.. doxygengroup:: LWGSM_NETWORK_API
\ No newline at end of file
diff --git a/docs/api-reference/lwgsm/operator.rst b/docs/api-reference/lwgsm/operator.rst
new file mode 100644
index 00000000..bb5af651
--- /dev/null
+++ b/docs/api-reference/lwgsm/operator.rst
@@ -0,0 +1,6 @@
+.. _api_lwgsm_operator:
+
+Network operator
+================
+
+.. doxygengroup:: LWGSM_OPERATOR
\ No newline at end of file
diff --git a/docs/api-reference/lwgsm/pbuf.rst b/docs/api-reference/lwgsm/pbuf.rst
new file mode 100644
index 00000000..31499c86
--- /dev/null
+++ b/docs/api-reference/lwgsm/pbuf.rst
@@ -0,0 +1,164 @@
+.. _api_lwgsm_pbuf:
+
+Packet buffer
+=============
+
+Packet buffer (or *pbuf*) is buffer manager to handle received data from any connection.
+It is optimized to construct big buffer of smaller chunks of fragmented data as received bytes are not always coming as single packet.
+
+Pbuf block diagram
+^^^^^^^^^^^^^^^^^^
+
+.. figure:: ../../static/images/pbuf_block_diagram.svg
+ :align: center
+ :alt: Block diagram of pbuf chain
+
+ Block diagram of pbuf chain
+
+Image above shows structure of *pbuf* chain. Each *pbuf* consists of:
+
+* Pointer to next *pbuf*, or ``NULL`` when it is last in chain
+* Length of current packet length
+* Length of current packet and all next in chain
+
+ * If *pbuf* is last in chain, total length is the same as current packet length
+
+* Reference counter, indicating how many pointers point to current *pbuf*
+* Actual buffer data
+
+Top image shows ``3`` pbufs connected to single chain.
+There are ``2`` custom pointer variables to point at different *pbuf* structures. Second *pbuf* has reference counter set to ``2``, as ``2`` variables point to it:
+
+* *next* of *pbuf 1* is the first one
+* *User variable 2* is the second one
+
+.. table:: Block structure
+
+ +--------------+-----------+------------+---------------------+-------------------+
+ | Block number | Next pbuf | Block size | Total size in chain | Reference counter |
+ +==============+===========+============+=====================+===================+
+ | Block 1 | *Block 2* | ``150`` | ``550`` | ``1`` |
+ +--------------+-----------+------------+---------------------+-------------------+
+ | Block 2 | *Block 3* | ``130`` | ``400`` | ``2`` |
+ +--------------+-----------+------------+---------------------+-------------------+
+ | Block 3 | ``NULL`` | ``270`` | ``270`` | ``1`` |
+ +--------------+-----------+------------+---------------------+-------------------+
+
+Reference counter
+^^^^^^^^^^^^^^^^^
+
+Reference counter holds number of references (or variables) pointing to this block.
+It is used to properly handle memory free operation, especially when *pbuf* is used by lib core and application layer.
+
+.. note::
+ If there would be no reference counter information and application would free memory while another part of library still uses its reference, application would invoke *undefined behavior* and system could crash instantly.
+
+When application tries to free pbuf chain as on first image, it would normally call :cpp:func:`lwgsm_pbuf_free` function. That would:
+
+* Decrease reference counter by ``1``
+* If reference counter ``== 0``, it removes it from chain list and frees packet buffer memory
+* If reference counter ``!= 0`` after decrease, it stops free procedure
+* Go to next pbuf in chain and repeat steps
+
+As per first example, result of freeing from *user variable 1* would look similar to image and table below.
+First block (blue) had reference counter set to ``1`` prior freeing operation.
+It was successfully removed as *user variable 1* was the only one pointing to it,
+while second (green) block had reference counter set to ``2``, preventing free operation.
+
+.. figure:: ../../static/images/pbuf_block_diagram_after_free.svg
+ :align: center
+ :alt: Block diagram of pbuf chain after free from *user variable 1*
+
+ Block diagram of pbuf chain after free from *user variable 1*
+
+.. table:: Block diagram of pbuf chain after free from *user variable 1*
+
+ +--------------+-----------+------------+---------------------+-------------------+
+ | Block number | Next pbuf | Block size | Total size in chain | Reference counter |
+ +==============+===========+============+=====================+===================+
+ | Block 2 | *Block 3* | ``130`` | ``400`` | ``1`` |
+ +--------------+-----------+------------+---------------------+-------------------+
+ | Block 3 | ``NULL`` | ``270`` | ``270`` | ``1`` |
+ +--------------+-----------+------------+---------------------+-------------------+
+
+.. note::
+ *Block 1* has been successfully freed, but since *block 2* had reference counter set to ``2`` before, it was only decreased by ``1`` to a new value ``1`` and free operation stopped instead.
+ *User variable 2* is still using *pbuf* starting at *block 2* and must manually call :cpp:func:`lwgsm_pbuf_free` to free it.
+
+Concatenating vs chaining
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This section will explain difference between *concat* and *chain* operations.
+Both operations link ``2`` pbufs together in a chain of pbufs,
+difference is that *chain* operation increases *reference counter* to linked pbuf,
+while *concat* keeps *reference counter* at its current status.
+
+.. figure:: ../../static/images/pbuf_cat_vs_chain_1.svg
+ :align: center
+ :alt: Different pbufs, each pointed to by its own variable
+
+ Different pbufs, each pointed to by its own variable
+
+Concat operation
+****************
+
+Concat operation shall be used when ``2`` pbufs are linked together and reference to *second* is no longer used.
+
+.. figure:: ../../static/images/pbuf_cat_vs_chain_2.svg
+ :align: center
+ :alt: Structure after pbuf concat
+
+ Structure after pbuf concat
+
+After concating *2 pbufs* together, reference counter of second is still set to ``1``, however we can see that ``2`` pointers point to *second pbuf*.
+
+.. note::
+ After application calls :cpp:func:`lwgsm_pbuf_cat`, it must not use pointer which points to *second pbuf*.
+ This would invoke *undefined behavior* if one pointer tries to free memory while second still points to it.
+
+An example code showing proper usage of concat operation:
+
+.. literalinclude:: ../../examples_src/pbuf_cat.c
+ :language: c
+ :linenos:
+ :caption: Packet buffer concat example
+
+Chain operation
+***************
+
+Chain operation shall be used when ``2`` pbufs are linked together and reference to *second* is still required.
+
+.. figure:: ../../static/images/pbuf_cat_vs_chain_3.svg
+ :align: center
+ :alt: Structure after pbuf chain
+
+ Structure after pbuf chain
+
+After chainin *2 pbufs* together, reference counter of second is increased by ``1``, which allows application to reference second *pbuf* separatelly.
+
+.. note::
+ After application calls :cpp:func:`lwgsm_pbuf_chain`,
+ it also has to manually free its reference using :cpp:func:`lwgsm_pbuf_free` function.
+ Forgetting to free pbuf invokes memory leak
+
+An example code showing proper usage of chain operation:
+
+.. literalinclude:: ../../examples_src/pbuf_chain.c
+ :language: c
+ :linenos:
+ :caption: Packet buffer chain example
+
+Extract pbuf data
+*****************
+
+Each *pbuf* holds some amount of data bytes. When multiple *pbufs* are linked together (either chained or concated), blocks of raw data are not linked to contiguous memory block.
+It is necessary to process block by block manually.
+
+An example code showing proper reading of any *pbuf*:
+
+.. literalinclude:: ../../examples_src/pbuf_extract.c
+ :language: c
+ :linenos:
+ :caption: Packet buffer data extraction
+
+.. doxygengroup:: LWGSM_PBUF
\ No newline at end of file
diff --git a/docs/api-reference/lwgsm/phonebook.rst b/docs/api-reference/lwgsm/phonebook.rst
new file mode 100644
index 00000000..6c8b9c46
--- /dev/null
+++ b/docs/api-reference/lwgsm/phonebook.rst
@@ -0,0 +1,6 @@
+.. _api_lwgsm_pb:
+
+Phonebook
+=========
+
+.. doxygengroup:: LWGSM_PHONEBOOK
\ No newline at end of file
diff --git a/docs/api-reference/lwgsm/ping.rst b/docs/api-reference/lwgsm/ping.rst
new file mode 100644
index 00000000..4834d61b
--- /dev/null
+++ b/docs/api-reference/lwgsm/ping.rst
@@ -0,0 +1,6 @@
+.. _api_lwgsm_ping:
+
+Ping support
+============
+
+.. doxygengroup:: LWGSM_PING
\ No newline at end of file
diff --git a/docs/api-reference/lwgsm/sim.rst b/docs/api-reference/lwgsm/sim.rst
new file mode 100644
index 00000000..930c131b
--- /dev/null
+++ b/docs/api-reference/lwgsm/sim.rst
@@ -0,0 +1,6 @@
+.. _api_lwgsm_sim:
+
+SIM card
+========
+
+.. doxygengroup:: LWGSM_SIM
\ No newline at end of file
diff --git a/docs/api-reference/lwgsm/sms.rst b/docs/api-reference/lwgsm/sms.rst
new file mode 100644
index 00000000..8c57adf5
--- /dev/null
+++ b/docs/api-reference/lwgsm/sms.rst
@@ -0,0 +1,6 @@
+.. _api_lwgsm_sms:
+
+SMS
+===
+
+.. doxygengroup:: LWGSM_SMS
\ No newline at end of file
diff --git a/docs/api-reference/lwgsm/timeout.rst b/docs/api-reference/lwgsm/timeout.rst
new file mode 100644
index 00000000..3bae5147
--- /dev/null
+++ b/docs/api-reference/lwgsm/timeout.rst
@@ -0,0 +1,18 @@
+.. _api_lwgsm_timeout:
+
+Timeout manager
+===============
+
+Timeout manager allows application to call specific function at desired time.
+It is used in middleware (and can be used by application too) to poll active connections.
+
+.. note::
+ Callback function is called from *processing* thread.
+ It is not allowed to call any blocking API function from it.
+
+When application registers timeout, it needs to set timeout, callback function and optional user argument.
+When timeout elapses, GSM middleware will call timeout callback.
+
+This feature can be considered as single-shot software timer.
+
+.. doxygengroup:: LWGSM_TIMEOUT
\ No newline at end of file
diff --git a/docs/api-reference/lwgsm/typedefs.rst b/docs/api-reference/lwgsm/typedefs.rst
new file mode 100644
index 00000000..c5086ee1
--- /dev/null
+++ b/docs/api-reference/lwgsm/typedefs.rst
@@ -0,0 +1,6 @@
+.. _api_lwgsm_typedefs:
+
+Structures and enumerations
+===========================
+
+.. doxygengroup:: LWGSM_TYPEDEFS
\ No newline at end of file
diff --git a/docs/api-reference/lwgsm/unicode.rst b/docs/api-reference/lwgsm/unicode.rst
new file mode 100644
index 00000000..4e19ad12
--- /dev/null
+++ b/docs/api-reference/lwgsm/unicode.rst
@@ -0,0 +1,12 @@
+.. _api_lwgsm_unicode:
+
+Unicode
+=======
+
+Unicode decoder block. It can decode sequence of *UTF-8* characters,
+between ``1`` and ``4`` bytes long.
+
+.. note::
+ This is simple implementation and does not support string encoding.
+
+.. doxygengroup:: LWGSM_UNICODE
\ No newline at end of file
diff --git a/docs/api-reference/lwgsm/ussd.rst b/docs/api-reference/lwgsm/ussd.rst
new file mode 100644
index 00000000..15f01118
--- /dev/null
+++ b/docs/api-reference/lwgsm/ussd.rst
@@ -0,0 +1,6 @@
+.. _api_lwgsm_ussd:
+
+Unstructured Supplementary Service Data
+=======================================
+
+.. doxygengroup:: LWGSM_USSD
\ No newline at end of file
diff --git a/docs/api-reference/lwgsm/utils.rst b/docs/api-reference/lwgsm/utils.rst
new file mode 100644
index 00000000..13a4005e
--- /dev/null
+++ b/docs/api-reference/lwgsm/utils.rst
@@ -0,0 +1,9 @@
+.. _api_lwgsm_utils:
+
+Utilities
+=========
+
+Utility functions for various cases.
+These function are used across entire middleware and can also be used by application.
+
+.. doxygengroup:: LWGSM_UTILS
\ No newline at end of file
diff --git a/docs/api-reference/opt.rst b/docs/api-reference/opt.rst
new file mode 100644
index 00000000..cdbee775
--- /dev/null
+++ b/docs/api-reference/opt.rst
@@ -0,0 +1,18 @@
+.. _api_lwgsm_opt:
+
+Configuration
+=============
+
+This is the default configuration of the middleware.
+When any of the settings shall be modified, it shall be done in dedicated application config ``lwgsm_opts.h`` file.
+
+.. note::
+ Check :ref:`getting_started` for guidelines on how to create and use configuration file.
+
+.. doxygengroup:: LWGSM_OPT
+.. doxygengroup:: LWGSM_OPT_DBG
+.. doxygengroup:: LWGSM_OPT_OS
+.. doxygengroup:: LWGSM_OPT_STD_LIB
+.. doxygengroup:: LWGSM_OPT_MODULES
+.. doxygengroup:: LWGSM_OPT_MODULES_NETCONN
+.. doxygengroup:: LWGSM_OPT_MODULES_MQTT
diff --git a/docs/api-reference/port/index.rst b/docs/api-reference/port/index.rst
new file mode 100644
index 00000000..171db230
--- /dev/null
+++ b/docs/api-reference/port/index.rst
@@ -0,0 +1,12 @@
+.. _api_lwgsm_port:
+
+Platform specific
+=================
+
+List of all the modules:
+
+.. toctree::
+ :maxdepth: 2
+ :glob:
+
+ *
\ No newline at end of file
diff --git a/docs/api-reference/port/ll.rst b/docs/api-reference/port/ll.rst
new file mode 100644
index 00000000..1db83deb
--- /dev/null
+++ b/docs/api-reference/port/ll.rst
@@ -0,0 +1,12 @@
+.. _api_lwgsm_ll:
+
+Low-Level functions
+===================
+
+Low-level module consists of callback-only functions, which are called by middleware
+and must be implemented by final application.
+
+.. tip::
+ Check :ref:`um_porting_guide` for actual implementation
+
+.. doxygengroup:: LWGSM_LL
\ No newline at end of file
diff --git a/docs/api-reference/port/sys.rst b/docs/api-reference/port/sys.rst
new file mode 100644
index 00000000..6702a6cd
--- /dev/null
+++ b/docs/api-reference/port/sys.rst
@@ -0,0 +1,20 @@
+.. _api_lwgsm_sys:
+
+System functions
+================
+
+System functions are bridge between operating system system calls and middleware system calls.
+Middleware is tightly coupled with operating system features hence it is important to include OS features directly.
+
+It includes support for:
+
+* Thread management, to start/stop threads
+* Mutex management for recursive mutexes
+* Semaphore management for binary-only semaphores
+* Message queues for thread-safe data exchange between threads
+* Core system protection for mutual exclusion to access shared resources
+
+.. tip::
+ Check :ref:`um_porting_guide` for actual implementation guidelines.
+
+.. doxygengroup:: LWGSM_SYS
\ No newline at end of file
diff --git a/docs/conf.py b/docs/conf.py
new file mode 100644
index 00000000..0a19cb89
--- /dev/null
+++ b/docs/conf.py
@@ -0,0 +1,129 @@
+# Configuration file for the Sphinx documentation builder.
+#
+# This file only contains a selection of the most common options. For a full
+# list see the documentation:
+# https://www.sphinx-doc.org/en/master/usage/configuration.html
+
+# -- Path setup --------------------------------------------------------------
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+# import os
+# import sys
+# sys.path.insert(0, os.path.abspath('.'))
+from sphinx.builders.html import StandaloneHTMLBuilder
+import subprocess, os
+
+# Run doxygen first
+# read_the_docs_build = os.environ.get('READTHEDOCS', None) == 'True'
+# if read_the_docs_build:
+subprocess.call('doxygen doxyfile.doxy', shell=True)
+# -- Project information -----------------------------------------------------
+
+project = 'LwGSM'
+copyright = '2020, Tilen MAJERLE'
+author = 'Tilen MAJERLE'
+
+# The full version, including alpha/beta/rc tags
+version = '0.1.0'
+
+# Try to get branch at which this is running
+# and try to determine which version to display in sphinx
+git_branch = ''
+res = os.popen('git branch').read().strip()
+for line in res.split("\n"):
+ if line[0] == '*':
+ git_branch = line[1:].strip()
+
+# Decision for display version
+try:
+ if git_branch.index('develop') >= 0:
+ version = "latest-develop"
+except Exception:
+ print("Exception for index check")
+
+# For debugging purpose
+print("GIT BRANCH: " + git_branch)
+print("VERSION: " + version)
+
+# -- General configuration ---------------------------------------------------
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+ 'sphinx.ext.autodoc',
+ 'sphinx.ext.intersphinx',
+ 'sphinx.ext.autosectionlabel',
+ 'sphinx.ext.todo',
+ 'sphinx.ext.coverage',
+ 'sphinx.ext.mathjax',
+ 'sphinx.ext.ifconfig',
+ 'sphinx.ext.viewcode',
+ 'sphinx_sitemap',
+
+ 'breathe',
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['templates']
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This pattern also affects html_static_path and html_extra_path.
+exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
+
+highlight_language = 'c'
+
+# -- Options for HTML output -------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+#
+html_theme = 'sphinx_rtd_theme'
+html_theme_options = {
+ 'canonical_url': '',
+ 'analytics_id': '', # Provided by Google in your dashboard
+ 'display_version': True,
+ 'prev_next_buttons_location': 'bottom',
+ 'style_external_links': False,
+
+ 'logo_only': False,
+
+ # Toc options
+ 'collapse_navigation': True,
+ 'sticky_navigation': True,
+ 'navigation_depth': 4,
+ 'includehidden': True,
+ 'titles_only': False
+}
+html_logo = 'static/images/logo_tm.png'
+github_url = 'https://github.com/MaJerle/gsm-at-lib'
+html_baseurl = 'https://docs.majerle.eu/projects/gsm-at-lib/'
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['static']
+html_css_files = [
+ 'css/common.css',
+ 'css/custom.css',
+]
+html_js_files = [
+ 'https://kit.fontawesome.com/3102794088.js'
+]
+
+master_doc = 'index'
+
+#
+# Breathe configuration
+#
+#
+#
+breathe_projects = {
+ "gsm_at_lib": "_build/xml/"
+}
+breathe_default_project = "gsm_at_lib"
+breathe_default_members = ('members', 'undoc-members')
\ No newline at end of file
diff --git a/docs/doxyfile.doxy b/docs/doxyfile.doxy
new file mode 100644
index 00000000..8c7e3e0b
--- /dev/null
+++ b/docs/doxyfile.doxy
@@ -0,0 +1,2456 @@
+# Doxyfile 1.8.10
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all text
+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
+# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
+# for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME = "LwGSM"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER = ""
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF = "LwGSM"
+
+# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
+# in the documentation. The maximum height of the logo should not exceed 55
+# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
+# the logo to the output directory.
+
+PROJECT_LOGO =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = "_build"
+
+# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS = NO
+
+# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
+# characters to appear in the names of generated files. If set to NO, non-ASCII
+# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
+# U+3044.
+# The default value is: NO.
+
+ALLOW_UNICODE_NAMES = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF = "The $name class" \
+ "The $name widget" \
+ "The $name file" \
+ is \
+ provides \
+ specifies \
+ contains \
+ represents \
+ a \
+ an \
+ the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES = NO
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
+# page for each member. If set to NO, the documentation of a member will be part
+# of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE = 4
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
+
+ALIASES =
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
+# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
+# Fortran. In the later case the parser tries to guess whether the code is fixed
+# or free formatted code, this is the default for Fortran type files), VHDL. For
+# instance to make doxygen treat .inc files as Fortran files (default is PHP),
+# and .f files as C (default is Fortran), use: inc=Fortran f=C.
+#
+# Note: For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT = YES
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# If one adds a struct or class to a group and this option is enabled, then also
+# any nested class or struct is added to the same group. By default this option
+# is disabled and one has to add nested compounds explicitly via \ingroup.
+# The default value is: NO.
+
+GROUP_NESTED_COMPOUNDS = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT = YES
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE = NO
+
+# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO,
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. If set to YES, local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO, only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO, these classes will be included in the various overviews. This option
+# has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO, these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO, these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES, upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES, the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES = YES
+
+# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
+# append additional text to a page's title, such as Class Reference. If set to
+# YES the compound reference will be hidden.
+# The default value is: NO.
+
+HIDE_COMPOUND_REFERENCE= NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+SHOW_GROUPED_MEMB_INC = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
+# list. This list is created by putting \todo commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
+# list. This list is created by putting \test commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if ... \endif and \cond
+# ... \endcond blocks.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES, the
+# list will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES = NO
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE =
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. See also \cite for info how to create references.
+
+CITE_BIB_FILES =
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO, doxygen will only warn about wrong or incomplete
+# parameter documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
+# Note: If this tag is empty the current directory is searched.
+
+INPUT = "../lwgsm/"
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# read by doxygen.
+#
+# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
+# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
+# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
+# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd,
+# *.vhdl, *.ucf, *.qsf, *.as and *.js.
+
+FILE_PATTERNS = *.c \
+ *.cc \
+ *.cxx \
+ *.cpp \
+ *.c++ \
+ *.java \
+ *.ii \
+ *.ixx \
+ *.ipp \
+ *.i++ \
+ *.inl \
+ *.idl \
+ *.ddl \
+ *.odl \
+ *.h \
+ *.hh \
+ *.hxx \
+ *.hpp \
+ *.h++ \
+ *.cs \
+ *.d \
+ *.php \
+ *.php4 \
+ *.php5 \
+ *.phtml \
+ *.inc \
+ *.m \
+ *.markdown \
+ *.md \
+ *.mm \
+ *.dox \
+ *.py \
+ *.f90 \
+ *.f \
+ *.for \
+ *.tcl \
+ *.vhd \
+ *.vhdl \
+ *.ucf \
+ *.qsf \
+ *.as \
+ *.js
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+#
+#
+# where is the value of the INPUT_FILTER tag, and is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS =
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see http://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS = YES
+
+# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
+# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
+# cost of reduced performance. This can be particularly helpful with template
+# rich C++ code for which doxygen's built-in parser lacks the necessary type
+# information.
+# Note: The availability of this option depends on whether or not doxygen was
+# compiled with the --with-libclang option.
+# The default value is: NO.
+
+CLANG_ASSISTED_PARSING = NO
+
+# If clang assisted parsing is enabled you can provide the compiler with command
+# line options that you would normally use when invoking the compiler. Note that
+# the include paths will already be set by doxygen for the files and directories
+# specified with INPUT and INCLUDE_PATH.
+# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
+
+CLANG_OPTIONS =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX = YES
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER = ""
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER = ""
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# cascading style sheets that are included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefore more robust against future updates.
+# Doxygen will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list). For an example see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the style sheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to YES can help to show when doxygen was last run and thus if the
+# documentation is up to date.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE =
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler (hhc.exe). If non-empty,
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION =
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated
+# (YES) or that it should be included in the master .chm file (NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING =
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated
+# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
+# enables the Previous and Next buttons.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS =
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW = YES
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH = 250
+
+# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# http://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX = YES
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from http://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS =
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use + S
+# (what the is depends on the OS and browser, but it is typically
+# , /
-
- Source Files
- Source Files\GSM API
@@ -109,5 +106,11 @@
Source Files\GSM CORE
+
+ Source Files
+
+
+ Source Files\GSM SNIPPETS
+
\ No newline at end of file
diff --git a/examples/win32/call_rtos/gsm_config.h b/examples/win32/call_rtos/gsm_config.h
deleted file mode 100644
index 8d66b547..00000000
--- a/examples/win32/call_rtos/gsm_config.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * \file gsm_config.h
- * \brief Configuration file
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#ifndef GSM_HDR_CONFIG_H
-#define GSM_HDR_CONFIG_H
-
-/*
- * Rename this file to "gsm_config.h" for your application
- */
-
-/* First include debug before any config changes */
-#include "gsm/gsm_debug.h"
-
-/*
- * Check default configuration settings for more information
- */
-#define GSM_CFG_AT_ECHO 1
-#define GSM_CFG_SYS_PORT GSM_SYS_PORT_WIN32
-#define GSM_CFG_INPUT_USE_PROCESS 1
-
-#define GSM_CFG_CALL 1
-
-/* After user configuration, call default config to merge config together */
-#include "gsm/gsm_config_default.h"
-
-#endif /* GSM_HDR_CONFIG_H */
diff --git a/examples/win32/call_rtos/lwgsm_opts.h b/examples/win32/call_rtos/lwgsm_opts.h
new file mode 100644
index 00000000..f46d0829
--- /dev/null
+++ b/examples/win32/call_rtos/lwgsm_opts.h
@@ -0,0 +1,48 @@
+/**
+ * \file lwgsm_opts.h
+ * \brief GSM application options
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM - Lightweight GSM-AT library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+#ifndef LWGSM_HDR_OPTS_H
+#define LWGSM_HDR_OPTS_H
+
+/* Rename this file to "lwgsm_opts.h" for your application */
+
+/*
+ * Open "include/lwgsm/lwgsm_opt.h" and
+ * copy & replace here settings you want to change values
+ */
+#define LWGSM_CFG_AT_ECHO 1
+#define LWGSM_CFG_INPUT_USE_PROCESS 1
+
+#define LWGSM_CFG_CALL 1
+
+#endif /* LWGSM_HDR_OPTS_H */
diff --git a/examples/win32/call_rtos/main.c b/examples/win32/call_rtos/main.c
index 6555ade6..f8998103 100644
--- a/examples/win32/call_rtos/main.c
+++ b/examples/win32/call_rtos/main.c
@@ -4,38 +4,39 @@
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Before you start using WIN32 implementation with USB and VCP,
- * check gsm_ll_win32.c implementation and choose your COM port!
+ * check lwgsm_ll_win32.c implementation and choose your COM port!
*/
-#include "gsm/gsm.h"
+#include "lwgsm/lwgsm.h"
#include "sim_manager.h"
#include "network_utils.h"
+#include "call.h"
-static gsmr_t gsm_callback_func(gsm_evt_t* evt);
+static lwgsmr_t lwgsm_callback_func(lwgsm_evt_t* evt);
/**
* \brief Program entry point
@@ -45,32 +46,28 @@ main(void) {
printf("Starting GSM application!\r\n");
/* Initialize GSM with default callback function */
- if (gsm_init(gsm_callback_func, 1) != gsmOK) {
- printf("Cannot initialize GSM-AT Library\r\n");
+ if (lwgsm_init(lwgsm_callback_func, 1) != lwgsmOK) {
+ printf("Cannot initialize LwGSM\r\n");
}
/* Configure device by unlocking SIM card */
if (configure_sim_card()) {
printf("SIM card configured. Adding delay to stabilize SIM card.\r\n");
- gsm_delay(10000);
+ lwgsm_delay(10000);
} else {
printf("Cannot configure SIM card! Is it inserted, pin valid and not under PUK? Closing down...\r\n");
- while (1) { gsm_delay(1000); }
+ while (1) { lwgsm_delay(1000); }
}
- /* Enable calls */
- if (gsm_call_enable(NULL, NULL, 1) == gsmOK) {
- printf("Calls enabled. You may take your phone and call modem.\r\n");
- } else {
- printf("Could not enabled call functionality!\r\n");
- }
+ /* Start call example */
+ call_start();
/*
* Do not stop program here.
* New threads were created for GSM processing
*/
while (1) {
- gsm_delay(1000);
+ lwgsm_delay(1000);
}
return 0;
@@ -79,43 +76,22 @@ main(void) {
/**
* \brief Event callback function for GSM stack
* \param[in] evt: Event information with data
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
*/
-static gsmr_t
-gsm_callback_func(gsm_evt_t* evt) {
- switch (gsm_evt_get_type(evt)) {
- case GSM_EVT_INIT_FINISH: printf("Library initialized!\r\n"); break;
+static lwgsmr_t
+lwgsm_callback_func(lwgsm_evt_t* evt) {
+ switch (lwgsm_evt_get_type(evt)) {
+ case LWGSM_EVT_INIT_FINISH: printf("Library initialized!\r\n"); break;
/* Process and print registration change */
- case GSM_EVT_NETWORK_REG_CHANGED: network_utils_process_reg_change(evt); break;
+ case LWGSM_EVT_NETWORK_REG_CHANGED: network_utils_process_reg_change(evt); break;
/* Process current network operator */
- case GSM_EVT_NETWORK_OPERATOR_CURRENT: network_utils_process_curr_operator(evt); break;
+ case LWGSM_EVT_NETWORK_OPERATOR_CURRENT: network_utils_process_curr_operator(evt); break;
/* Process signal strength */
- case GSM_EVT_SIGNAL_STRENGTH: network_utils_process_rssi(evt); break;
+ case LWGSM_EVT_SIGNAL_STRENGTH: network_utils_process_rssi(evt); break;
/* Other user events here... */
-#if GSM_CFG_CALL
- case GSM_EVT_CALL_CHANGED: {
- const gsm_call_t* call = gsm_evt_call_changed_get_call(evt);
- if (call->state == GSM_CALL_STATE_ACTIVE) {
- printf("Call is active!\r\n");
-
- /* In case of mobile originated direction */
- if (call->dir == GSM_CALL_DIR_MO) {
- gsm_call_hangup(NULL, NULL, 0); /* Manually hangup call */
- }
- } else if (call->state == GSM_CALL_STATE_INCOMING) {
- printf("We received incoming call! Phone number: %s\r\n", call->number);
- gsm_call_answer(NULL, NULL, 0); /* Answer to a call */
- } else if (call->state == GSM_CALL_STATE_DIALING) {
- printf("Call is dialing!\r\n");
- } else if (call->state == GSM_CALL_STATE_DISCONNECT) {
- printf("Call ended!\r\n");
- }
- break;
- }
-#endif /* GSM_CFG_CALL */
default: break;
}
- return gsmOK;
+ return lwgsmOK;
}
diff --git a/examples/win32/call_sms_rtos/call_sms_rtos.vcxproj b/examples/win32/call_sms_rtos/call_sms_rtos.vcxproj
index 852ae6f1..ab08d50d 100644
--- a/examples/win32/call_sms_rtos/call_sms_rtos.vcxproj
+++ b/examples/win32/call_sms_rtos/call_sms_rtos.vcxproj
@@ -73,18 +73,18 @@
true
- ..\..\..\GSM_AT_Lib\src\include;.;..\..\..\snippets\include;$(IncludePath)
+ .;..\..\..\lwgsm\src\include;..\..\..\lwgsm\src\include\system\port\win32;..\..\..\snippets\include;$(IncludePath)
- ..\..\..\ESP_AT_Lib\src\include;.;..\..\..\snippets\include;$(IncludePath)
+ .;..\..\..\lwgsm\src\include;..\..\..\lwgsm\src\include\system\port\win32;..\..\..\snippets\include;$(IncludePath)true
- ..\..\..\ESP_AT_Lib\src\include;.;..\..\..\snippets\include;$(IncludePath)
+ .;..\..\..\lwgsm\src\include;..\..\..\lwgsm\src\include\system\port\win32;..\..\..\snippets\include;$(IncludePath)false
- ..\..\..\ESP_AT_Lib\src\include;.;..\..\..\snippets\include;$(IncludePath)
+ .;..\..\..\lwgsm\src\include;..\..\..\lwgsm\src\include\system\port\win32;..\..\..\snippets\include;$(IncludePath)false
@@ -140,33 +140,34 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/win32/call_sms_rtos/call_sms_rtos.vcxproj.filters b/examples/win32/call_sms_rtos/call_sms_rtos.vcxproj.filters
index f0dc5fee..d0a65c04 100644
--- a/examples/win32/call_sms_rtos/call_sms_rtos.vcxproj.filters
+++ b/examples/win32/call_sms_rtos/call_sms_rtos.vcxproj.filters
@@ -109,5 +109,8 @@
Source Files\GSM CORE
+
+ Source Files\GSM SNIPPETS
+
\ No newline at end of file
diff --git a/examples/win32/call_sms_rtos/gsm_config.h b/examples/win32/call_sms_rtos/gsm_config.h
deleted file mode 100644
index 441ea47f..00000000
--- a/examples/win32/call_sms_rtos/gsm_config.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * \file gsm_config.h
- * \brief Configuration file
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#ifndef GSM_HDR_CONFIG_H
-#define GSM_HDR_CONFIG_H
-
-/*
- * Rename this file to "gsm_config.h" for your application
- */
-
-/* First include debug before any config changes */
-#include "gsm/gsm_debug.h"
-
-/*
- * Check default configuration settings for more information
- */
-#define GSM_CFG_AT_ECHO 1
-#define GSM_CFG_SYS_PORT GSM_SYS_PORT_WIN32
-#define GSM_CFG_INPUT_USE_PROCESS 1
-
-#define GSM_CFG_SMS 1
-#define GSM_CFG_CALL 1
-
-/* After user configuration, call default config to merge config together */
-#include "gsm/gsm_config_default.h"
-
-#endif /* GSM_HDR_CONFIG_H */
diff --git a/examples/win32/call_sms_rtos/lwgsm_opts.h b/examples/win32/call_sms_rtos/lwgsm_opts.h
new file mode 100644
index 00000000..8eb2bc30
--- /dev/null
+++ b/examples/win32/call_sms_rtos/lwgsm_opts.h
@@ -0,0 +1,49 @@
+/**
+ * \file lwgsm_opts.h
+ * \brief GSM application options
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM - Lightweight GSM-AT library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+#ifndef LWGSM_HDR_OPTS_H
+#define LWGSM_HDR_OPTS_H
+
+/* Rename this file to "lwgsm_opts.h" for your application */
+
+/*
+ * Open "include/lwgsm/lwgsm_opt.h" and
+ * copy & replace here settings you want to change values
+ */
+#define LWGSM_CFG_AT_ECHO 1
+#define LWGSM_CFG_INPUT_USE_PROCESS 1
+
+#define LWGSM_CFG_SMS 1
+#define LWGSM_CFG_CALL 1
+
+#endif /* LWGSM_HDR_OPTS_H */
diff --git a/examples/win32/call_sms_rtos/main.c b/examples/win32/call_sms_rtos/main.c
index 5b40b347..227cd824 100644
--- a/examples/win32/call_sms_rtos/main.c
+++ b/examples/win32/call_sms_rtos/main.c
@@ -4,43 +4,44 @@
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Before you start using WIN32 implementation with USB and VCP,
- * check gsm_ll_win32.c implementation and choose your COM port!
+ * check lwgsm_ll_win32.c implementation and choose your COM port!
*/
-#include "gsm/gsm.h"
+#include "lwgsm/lwgsm.h"
#include "sim_manager.h"
#include "network_utils.h"
+#include "call_sms.h"
-static gsmr_t gsm_callback_func(gsm_evt_t* evt);
+static lwgsmr_t lwgsm_callback_func(lwgsm_evt_t* evt);
/**
* \brief SMS entry
*/
-gsm_sms_entry_t
+lwgsm_sms_entry_t
sms_entry;
/**
@@ -51,39 +52,28 @@ main(void) {
printf("Starting GSM application!\r\n");
/* Initialize GSM with default callback function */
- if (gsm_init(gsm_callback_func, 1) != gsmOK) {
- printf("Cannot initialize GSM-AT Library\r\n");
+ if (lwgsm_init(lwgsm_callback_func, 1) != lwgsmOK) {
+ printf("Cannot initialize LwGSM\r\n");
}
/* Configure device by unlocking SIM card */
if (configure_sim_card()) {
printf("SIM card configured. Adding delay to stabilize SIM card.\r\n");
- gsm_delay(10000);
+ lwgsm_delay(10000);
} else {
printf("Cannot configure SIM card! Is it inserted, pin valid and not under PUK? Closing down...\r\n");
- while (1) { gsm_delay(1000); }
+ while (1) { lwgsm_delay(1000); }
}
- /* First enable SMS functionality */
- if (gsm_sms_enable(NULL, NULL, 1) == gsmOK) {
- printf("SMS enabled. Send new SMS from your phone to device.\r\n");
- } else {
- printf("Cannot enable SMS functionality!\r\n");
- }
-
- /* Then enable call functionality */
- if (gsm_call_enable(NULL, NULL, 1) == gsmOK) {
- printf("Call enabled. You may now take your phone and call modem\r\n");
- } else {
- printf("Cannot enable call functionality!\r\n");
- }
+ /* Start call & SMS example */
+ call_sms_start();
/*
* Do not stop program here.
* New threads were created for GSM processing
*/
while (1) {
- gsm_delay(1000);
+ lwgsm_delay(1000);
}
return 0;
@@ -92,82 +82,22 @@ main(void) {
/**
* \brief Event callback function for GSM stack
* \param[in] evt: Event information with data
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
*/
-static gsmr_t
-gsm_callback_func(gsm_evt_t* evt) {
- switch (gsm_evt_get_type(evt)) {
- case GSM_EVT_INIT_FINISH: printf("Library initialized!\r\n"); break;
+static lwgsmr_t
+lwgsm_callback_func(lwgsm_evt_t* evt) {
+ switch (lwgsm_evt_get_type(evt)) {
+ case LWGSM_EVT_INIT_FINISH: printf("Library initialized!\r\n"); break;
/* Process and print registration change */
- case GSM_EVT_NETWORK_REG_CHANGED: network_utils_process_reg_change(evt); break;
+ case LWGSM_EVT_NETWORK_REG_CHANGED: network_utils_process_reg_change(evt); break;
/* Process current network operator */
- case GSM_EVT_NETWORK_OPERATOR_CURRENT: network_utils_process_curr_operator(evt); break;
+ case LWGSM_EVT_NETWORK_OPERATOR_CURRENT: network_utils_process_curr_operator(evt); break;
/* Process signal strength */
- case GSM_EVT_SIGNAL_STRENGTH: network_utils_process_rssi(evt); break;
+ case LWGSM_EVT_SIGNAL_STRENGTH: network_utils_process_rssi(evt); break;
/* Other user events here... */
-
- case GSM_EVT_SMS_READY: { /* SMS is ready notification from device */
- printf("SIM device SMS service is ready!\r\n");
- break;
- }
- case GSM_EVT_SMS_RECV: { /* New SMS received indicator */
- gsmr_t res;
-
- printf("New SMS received!\r\n"); /* Notify user */
-
- /* Try to read SMS */
- res = gsm_sms_read(gsm_evt_sms_recv_get_mem(evt), gsm_evt_sms_recv_get_pos(evt), &sms_entry, 1, NULL, NULL, 0);
- if (res == gsmOK) {
- printf("SMS read in progress!\r\n");
- } else {
- printf("Cannot start SMS read procedure!\r\n");
- }
- break;
- }
- case GSM_EVT_SMS_READ: { /* SMS read event */
- gsm_sms_entry_t* entry = gsm_evt_sms_read_get_entry(evt);
- if (gsm_evt_sms_read_get_result(evt) == gsmOK && entry != NULL) {
- /* Print SMS data */
- printf("SMS read. From: %s, content: %s\r\n",
- entry->number, entry->data
- );
-
- /* Try to send SMS back */
- if (gsm_sms_send(entry->number, entry->data, NULL, NULL, 0) == gsmOK) {
- printf("SMS send in progress!\r\n");
- } else {
- printf("Cannot start SMS send procedure!\r\n");
- }
-
- /* Delete SMS from device memory */
- gsm_sms_delete(entry->mem, entry->pos, NULL, NULL, 0);
- }
- break;
- }
- case GSM_EVT_SMS_SEND: { /* SMS send event */
- if (gsm_evt_sms_send_get_result(evt) == gsmOK) {
- printf("SMS has been successfully sent!\r\n");
- } else {
- printf("SMS has not been sent successfully!\r\n");
- }
- break;
- }
-
- case GSM_EVT_CALL_READY: { /* Call is ready notification from device */
- printf("SIM device Call service is ready!\r\n");
- break;
- }
- case GSM_EVT_CALL_CHANGED: {
- const gsm_call_t* call = gsm_evt_call_changed_get_call(evt);
- if (call->state == GSM_CALL_STATE_INCOMING) { /* On incoming call */
- gsm_call_hangup(NULL, NULL, 0); /* Hangup call */
- gsm_sms_send(call->number, "Cannot answer call. Please send SMS\r\n", NULL, NULL, 0);
- }
- break;
- }
default: break;
}
- return gsmOK;
+ return lwgsmOK;
}
diff --git a/examples/win32/device_info_rtos/device_info_rtos.vcxproj b/examples/win32/device_info_rtos/device_info_rtos.vcxproj
index b66891e5..23c98ba5 100644
--- a/examples/win32/device_info_rtos/device_info_rtos.vcxproj
+++ b/examples/win32/device_info_rtos/device_info_rtos.vcxproj
@@ -73,18 +73,18 @@
true
- ..\..\..\GSM_AT_Lib\src\include;.;..\..\..\snippets\include;$(IncludePath)
+ .;..\..\..\lwgsm\src\include;..\..\..\lwgsm\src\include\system\port\win32;..\..\..\snippets\include;$(IncludePath)
- ..\..\..\ESP_AT_Lib\src\include;.;..\..\..\snippets\include;$(IncludePath)
+ .;..\..\..\lwgsm\src\include;..\..\..\lwgsm\src\include\system\port\win32;..\..\..\snippets\include;$(IncludePath)true
- ..\..\..\ESP_AT_Lib\src\include;.;..\..\..\snippets\include;$(IncludePath)
+ .;..\..\..\lwgsm\src\include;..\..\..\lwgsm\src\include\system\port\win32;..\..\..\snippets\include;$(IncludePath)false
- ..\..\..\ESP_AT_Lib\src\include;.;..\..\..\snippets\include;$(IncludePath)
+ .;..\..\..\lwgsm\src\include;..\..\..\lwgsm\src\include\system\port\win32;..\..\..\snippets\include;$(IncludePath)false
@@ -140,33 +140,34 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/win32/device_info_rtos/device_info_rtos.vcxproj.filters b/examples/win32/device_info_rtos/device_info_rtos.vcxproj.filters
index f0dc5fee..f4e7cdbd 100644
--- a/examples/win32/device_info_rtos/device_info_rtos.vcxproj.filters
+++ b/examples/win32/device_info_rtos/device_info_rtos.vcxproj.filters
@@ -109,5 +109,8 @@
Source Files\GSM CORE
+
+ Source Files\GSM SNIPPETS
+
\ No newline at end of file
diff --git a/examples/win32/device_info_rtos/gsm_config.h b/examples/win32/device_info_rtos/gsm_config.h
deleted file mode 100644
index a1b7ac9f..00000000
--- a/examples/win32/device_info_rtos/gsm_config.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * \file gsm_config.h
- * \brief Configuration file
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#ifndef GSM_HDR_CONFIG_H
-#define GSM_HDR_CONFIG_H
-
-/*
- * Rename this file to "gsm_config.h" for your application
- */
-
-/* First include debug before any config changes */
-#include "gsm/gsm_debug.h"
-
-/*
- * Check default configuration settings for more information
- */
-#define GSM_CFG_AT_ECHO 1
-#define GSM_CFG_SYS_PORT GSM_SYS_PORT_WIN32
-#define GSM_CFG_INPUT_USE_PROCESS 1
-
-/* Enable SMS API */
-#define GSM_CFG_SMS 1
-
-/* After user configuration, call default config to merge config together */
-#include "gsm/gsm_config_default.h"
-
-#endif /* GSM_HDR_CONFIG_H */
diff --git a/examples/win32/device_info_rtos/lwgsm_opts.h b/examples/win32/device_info_rtos/lwgsm_opts.h
new file mode 100644
index 00000000..d2a82e98
--- /dev/null
+++ b/examples/win32/device_info_rtos/lwgsm_opts.h
@@ -0,0 +1,49 @@
+/**
+ * \file lwgsm_opts.h
+ * \brief GSM application options
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM - Lightweight GSM-AT library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+#ifndef LWGSM_HDR_OPTS_H
+#define LWGSM_HDR_OPTS_H
+
+/* Rename this file to "lwgsm_opts.h" for your application */
+
+/*
+ * Open "include/lwgsm/lwgsm_opt.h" and
+ * copy & replace here settings you want to change values
+ */
+#define LWGSM_CFG_AT_ECHO 1
+#define LWGSM_CFG_INPUT_USE_PROCESS 1
+
+/* Enable SMS API */
+#define LWGSM_CFG_SMS 1
+
+#endif /* LWGSM_HDR_OPTS_H */
diff --git a/examples/win32/device_info_rtos/main.c b/examples/win32/device_info_rtos/main.c
index 621cff67..3276e3ac 100644
--- a/examples/win32/device_info_rtos/main.c
+++ b/examples/win32/device_info_rtos/main.c
@@ -4,41 +4,39 @@
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Before you start using WIN32 implementation with USB and VCP,
- * check gsm_ll_win32.c implementation and choose your COM port!
+ * check lwgsm_ll_win32.c implementation and choose your COM port!
*/
-#include "gsm/gsm.h"
+#include "lwgsm/lwgsm.h"
#include "sim_manager.h"
#include "network_utils.h"
+#include "device_info.h"
-static gsmr_t gsm_callback_func(gsm_evt_t* evt);
-
-/* Device info string array */
-char dev_str[20];
+static lwgsmr_t lwgsm_callback_func(lwgsm_evt_t* evt);
/**
* \brief Program entry point
@@ -48,34 +46,19 @@ main(void) {
printf("Starting GSM application!\r\n");
/* Initialize GSM with default callback function */
- if (gsm_init(gsm_callback_func, 1) != gsmOK) {
- printf("Cannot initialize GSM-AT Library\r\n");
+ if (lwgsm_init(lwgsm_callback_func, 1) != lwgsmOK) {
+ printf("Cannot initialize LwGSM\r\n");
}
- /* Read information */
-
- /* Read device manufacturer */
- gsm_device_get_manufacturer(dev_str, sizeof(dev_str), NULL, NULL, 1);
- printf("Manuf: %s\r\n", dev_str);
-
- /* Read device model */
- gsm_device_get_model(dev_str, sizeof(dev_str), NULL, NULL, 1);
- printf("Model: %s\r\n", dev_str);
-
- /* Read device serial number */
- gsm_device_get_serial_number(dev_str, sizeof(dev_str), NULL, NULL, 1);
- printf("Serial: %s\r\n", dev_str);
-
- /* Read device revision */
- gsm_device_get_revision(dev_str, sizeof(dev_str), NULL, NULL, 1);
- printf("Revision: %s\r\n", dev_str);
+ /* Read device info */
+ read_device_info();
/*
* Do not stop program here.
* New threads were created for GSM processing
*/
while (1) {
- gsm_delay(1000);
+ lwgsm_delay(1000);
}
return 0;
@@ -84,23 +67,23 @@ main(void) {
/**
* \brief Event callback function for GSM stack
* \param[in] evt: Event information with data
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
*/
-static gsmr_t
-gsm_callback_func(gsm_evt_t* evt) {
- switch (gsm_evt_get_type(evt)) {
- case GSM_EVT_INIT_FINISH: printf("Library initialized!\r\n"); break;
+static lwgsmr_t
+lwgsm_callback_func(lwgsm_evt_t* evt) {
+ switch (lwgsm_evt_get_type(evt)) {
+ case LWGSM_EVT_INIT_FINISH: printf("Library initialized!\r\n"); break;
/* Process and print registration change */
- case GSM_EVT_NETWORK_REG_CHANGED: network_utils_process_reg_change(evt); break;
+ case LWGSM_EVT_NETWORK_REG_CHANGED: network_utils_process_reg_change(evt); break;
/* Process current network operator */
- case GSM_EVT_NETWORK_OPERATOR_CURRENT: network_utils_process_curr_operator(evt); break;
+ case LWGSM_EVT_NETWORK_OPERATOR_CURRENT: network_utils_process_curr_operator(evt); break;
/* Process signal strength */
- case GSM_EVT_SIGNAL_STRENGTH: network_utils_process_rssi(evt); break;
+ case LWGSM_EVT_SIGNAL_STRENGTH: network_utils_process_rssi(evt); break;
/* Other user events here... */
default: break;
}
- return gsmOK;
+ return lwgsmOK;
}
diff --git a/examples/win32/gsm_examples.sln b/examples/win32/lwgsm_examples.sln
similarity index 100%
rename from examples/win32/gsm_examples.sln
rename to examples/win32/lwgsm_examples.sln
diff --git a/examples/win32/mqtt_client_api_rtos/gsm_config.h b/examples/win32/mqtt_client_api_rtos/gsm_config.h
deleted file mode 100644
index 19afce73..00000000
--- a/examples/win32/mqtt_client_api_rtos/gsm_config.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * \file gsm_config.h
- * \brief Configuration file
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#ifndef GSM_HDR_CONFIG_H
-#define GSM_HDR_CONFIG_H
-
-/*
- * Rename this file to "gsm_config.h" for your application
- */
-
-/* First include debug before any config changes */
-#include "gsm/gsm_debug.h"
-
-/*
- * Check default configuration settings for more information
- */
-#define GSM_CFG_AT_ECHO 1
-#define GSM_CFG_SYS_PORT GSM_SYS_PORT_WIN32
-#define GSM_CFG_INPUT_USE_PROCESS 1
-
-/* Enable network, conn and netconn APIs */
-#define GSM_CFG_NETWORK 1
-#define GSM_CFG_CONN 1
-#define GSM_CFG_NETCONN 1
-
-/* After user configuration, call default config to merge config together */
-#include "gsm/gsm_config_default.h"
-
-#endif /* GSM_HDR_CONFIG_H */
diff --git a/examples/win32/mqtt_client_api_rtos/lwgsm_opts.h b/examples/win32/mqtt_client_api_rtos/lwgsm_opts.h
new file mode 100644
index 00000000..c1a64fe2
--- /dev/null
+++ b/examples/win32/mqtt_client_api_rtos/lwgsm_opts.h
@@ -0,0 +1,51 @@
+/**
+ * \file lwgsm_opts.h
+ * \brief GSM application options
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM - Lightweight GSM-AT library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+#ifndef LWGSM_HDR_OPTS_H
+#define LWGSM_HDR_OPTS_H
+
+/* Rename this file to "lwgsm_opts.h" for your application */
+
+/*
+ * Open "include/lwgsm/lwgsm_opt.h" and
+ * copy & replace here settings you want to change values
+ */
+#define LWGSM_CFG_AT_ECHO 1
+#define LWGSM_CFG_INPUT_USE_PROCESS 1
+
+/* Enable network, conn and netconn APIs */
+#define LWGSM_CFG_NETWORK 1
+#define LWGSM_CFG_CONN 1
+#define LWGSM_CFG_NETCONN 1
+
+#endif /* LWGSM_HDR_OPTS_H */
diff --git a/examples/win32/mqtt_client_api_rtos/main.c b/examples/win32/mqtt_client_api_rtos/main.c
index b35ca48b..f180a4f2 100644
--- a/examples/win32/mqtt_client_api_rtos/main.c
+++ b/examples/win32/mqtt_client_api_rtos/main.c
@@ -4,40 +4,40 @@
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Before you start using WIN32 implementation with USB and VCP,
- * check gsm_ll_win32.c implementation and choose your COM port!
+ * check lwgsm_ll_win32.c implementation and choose your COM port!
*/
-#include "gsm/gsm.h"
+#include "lwgsm/lwgsm.h"
#include "sim_manager.h"
#include "network_utils.h"
#include "network_apn_settings.h"
#include "mqtt_client_api.h"
-static gsmr_t gsm_callback_func(gsm_evt_t* evt);
+static lwgsmr_t lwgsm_callback_func(lwgsm_evt_t* evt);
/**
* \brief Program entry point
@@ -47,35 +47,31 @@ main(void) {
printf("Starting GSM application!\r\n");
/* Initialize GSM with default callback function */
- if (gsm_init(gsm_callback_func, 1) != gsmOK) {
- printf("Cannot initialize GSM-AT Library\r\n");
+ if (lwgsm_init(lwgsm_callback_func, 1) != lwgsmOK) {
+ printf("Cannot initialize LwGSM\r\n");
}
/* Configure device by unlocking SIM card */
if (configure_sim_card()) {
printf("SIM card configured. Adding delay to stabilize SIM card.\r\n");
- gsm_delay(10000);
+ lwgsm_delay(10000);
} else {
printf("Cannot configure SIM card! Is it inserted, pin valid and not under PUK? Closing down...\r\n");
- while (1) { gsm_delay(1000); }
+ while (1) { lwgsm_delay(1000); }
}
- /* Connect to network for TCP/IP */
- if (gsm_network_attach(NETWORK_APN, NETWORK_APN_USER, NETWORK_APN_PASS, NULL, NULL, 1) == gsmOK) {
- printf("Attached to network!\r\n");
+ /* Set APN credentials */
+ lwgsm_network_set_credentials(NETWORK_APN, NETWORK_APN_USER, NETWORK_APN_PASS);
- /* Start netconn thread */
- gsm_sys_thread_create(NULL, "mqtt_thread", (gsm_sys_thread_t)mqtt_client_api_thread, NULL, GSM_SYS_THREAD_SS, GSM_SYS_THREAD_PRIO);
- } else {
- printf("Cannot attach to network!\r\n");
- }
+ /* Start MQTT thread */
+ lwgsm_sys_thread_create(NULL, "mqtt_thread", (lwgsm_sys_thread_t)mqtt_client_api_thread, NULL, LWGSM_SYS_THREAD_SS, LWGSM_SYS_THREAD_PRIO);
/*
* Do not stop program here.
* New threads were created for GSM processing
*/
while (1) {
- gsm_delay(1000);
+ lwgsm_delay(1000);
}
return 0;
@@ -84,22 +80,22 @@ main(void) {
/**
* \brief Event callback function for GSM stack
* \param[in] evt: Event information with data
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
*/
-static gsmr_t
-gsm_callback_func(gsm_evt_t* evt) {
- switch (gsm_evt_get_type(evt)) {
- case GSM_EVT_INIT_FINISH: printf("Library initialized!\r\n"); break;
+static lwgsmr_t
+lwgsm_callback_func(lwgsm_evt_t* evt) {
+ switch (lwgsm_evt_get_type(evt)) {
+ case LWGSM_EVT_INIT_FINISH: printf("Library initialized!\r\n"); break;
/* Process and print registration change */
- case GSM_EVT_NETWORK_REG_CHANGED: network_utils_process_reg_change(evt); break;
+ case LWGSM_EVT_NETWORK_REG_CHANGED: network_utils_process_reg_change(evt); break;
/* Process current network operator */
- case GSM_EVT_NETWORK_OPERATOR_CURRENT: network_utils_process_curr_operator(evt); break;
+ case LWGSM_EVT_NETWORK_OPERATOR_CURRENT: network_utils_process_curr_operator(evt); break;
/* Process signal strength */
- case GSM_EVT_SIGNAL_STRENGTH: network_utils_process_rssi(evt); break;
+ case LWGSM_EVT_SIGNAL_STRENGTH: network_utils_process_rssi(evt); break;
/* Other user events here... */
default: break;
}
- return gsmOK;
+ return lwgsmOK;
}
diff --git a/examples/win32/mqtt_client_api_rtos/mqtt_client_api_rtos.vcxproj b/examples/win32/mqtt_client_api_rtos/mqtt_client_api_rtos.vcxproj
index ff0792b4..444315e2 100644
--- a/examples/win32/mqtt_client_api_rtos/mqtt_client_api_rtos.vcxproj
+++ b/examples/win32/mqtt_client_api_rtos/mqtt_client_api_rtos.vcxproj
@@ -73,18 +73,18 @@
true
- ..\..\..\GSM_AT_Lib\src\include;.;..\..\..\snippets\include;$(IncludePath)
+ .;..\..\..\lwgsm\src\include;..\..\..\lwgsm\src\include\system\port\win32;..\..\..\snippets\include;$(IncludePath)
- ..\..\..\ESP_AT_Lib\src\include;.;..\..\..\snippets\include;$(IncludePath)
+ .;..\..\..\lwgsm\src\include;..\..\..\lwgsm\src\include\system\port\win32;..\..\..\snippets\include;$(IncludePath)true
- ..\..\..\ESP_AT_Lib\src\include;.;..\..\..\snippets\include;$(IncludePath)
+ .;..\..\..\lwgsm\src\include;..\..\..\lwgsm\src\include\system\port\win32;..\..\..\snippets\include;$(IncludePath)false
- ..\..\..\ESP_AT_Lib\src\include;.;..\..\..\snippets\include;$(IncludePath)
+ .;..\..\..\lwgsm\src\include;..\..\..\lwgsm\src\include\system\port\win32;..\..\..\snippets\include;$(IncludePath)false
@@ -140,37 +140,37 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/win32/netconn_client_rtos/gsm_config.h b/examples/win32/netconn_client_rtos/gsm_config.h
deleted file mode 100644
index 19afce73..00000000
--- a/examples/win32/netconn_client_rtos/gsm_config.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * \file gsm_config.h
- * \brief Configuration file
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#ifndef GSM_HDR_CONFIG_H
-#define GSM_HDR_CONFIG_H
-
-/*
- * Rename this file to "gsm_config.h" for your application
- */
-
-/* First include debug before any config changes */
-#include "gsm/gsm_debug.h"
-
-/*
- * Check default configuration settings for more information
- */
-#define GSM_CFG_AT_ECHO 1
-#define GSM_CFG_SYS_PORT GSM_SYS_PORT_WIN32
-#define GSM_CFG_INPUT_USE_PROCESS 1
-
-/* Enable network, conn and netconn APIs */
-#define GSM_CFG_NETWORK 1
-#define GSM_CFG_CONN 1
-#define GSM_CFG_NETCONN 1
-
-/* After user configuration, call default config to merge config together */
-#include "gsm/gsm_config_default.h"
-
-#endif /* GSM_HDR_CONFIG_H */
diff --git a/examples/win32/netconn_client_rtos/lwgsm_opts.h b/examples/win32/netconn_client_rtos/lwgsm_opts.h
new file mode 100644
index 00000000..c1a64fe2
--- /dev/null
+++ b/examples/win32/netconn_client_rtos/lwgsm_opts.h
@@ -0,0 +1,51 @@
+/**
+ * \file lwgsm_opts.h
+ * \brief GSM application options
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM - Lightweight GSM-AT library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+#ifndef LWGSM_HDR_OPTS_H
+#define LWGSM_HDR_OPTS_H
+
+/* Rename this file to "lwgsm_opts.h" for your application */
+
+/*
+ * Open "include/lwgsm/lwgsm_opt.h" and
+ * copy & replace here settings you want to change values
+ */
+#define LWGSM_CFG_AT_ECHO 1
+#define LWGSM_CFG_INPUT_USE_PROCESS 1
+
+/* Enable network, conn and netconn APIs */
+#define LWGSM_CFG_NETWORK 1
+#define LWGSM_CFG_CONN 1
+#define LWGSM_CFG_NETCONN 1
+
+#endif /* LWGSM_HDR_OPTS_H */
diff --git a/examples/win32/netconn_client_rtos/main.c b/examples/win32/netconn_client_rtos/main.c
index 873003a4..5529e173 100644
--- a/examples/win32/netconn_client_rtos/main.c
+++ b/examples/win32/netconn_client_rtos/main.c
@@ -4,40 +4,40 @@
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Before you start using WIN32 implementation with USB and VCP,
- * check gsm_ll_win32.c implementation and choose your COM port!
+ * check lwgsm_ll_win32.c implementation and choose your COM port!
*/
-#include "gsm/gsm.h"
+#include "lwgsm/lwgsm.h"
#include "sim_manager.h"
#include "network_utils.h"
#include "netconn_client.h"
#include "network_apn_settings.h"
-static gsmr_t gsm_callback_func(gsm_evt_t* evt);
+static lwgsmr_t lwgsm_callback_func(lwgsm_evt_t* evt);
/**
* \brief Program entry point
@@ -47,35 +47,31 @@ main(void) {
printf("Starting GSM application!\r\n");
/* Initialize GSM with default callback function */
- if (gsm_init(gsm_callback_func, 1) != gsmOK) {
- printf("Cannot initialize GSM-AT Library\r\n");
+ if (lwgsm_init(lwgsm_callback_func, 1) != lwgsmOK) {
+ printf("Cannot initialize LwGSM\r\n");
}
/* Configure device by unlocking SIM card */
if (configure_sim_card()) {
printf("SIM card configured. Adding delay to stabilize SIM card.\r\n");
- gsm_delay(10000);
+ lwgsm_delay(10000);
} else {
printf("Cannot configure SIM card! Is it inserted, pin valid and not under PUK? Closing down...\r\n");
- while (1) { gsm_delay(1000); }
+ while (1) { lwgsm_delay(1000); }
}
- /* Connect to network for TCP/IP */
- if (gsm_network_attach(NETWORK_APN, NETWORK_APN_USER, NETWORK_APN_PASS, NULL, NULL, 1) == gsmOK) {
- printf("Attached to network!\r\n");
+ /* Set APN credentials */
+ lwgsm_network_set_credentials(NETWORK_APN, NETWORK_APN_USER, NETWORK_APN_PASS);
- /* Start netconn thread */
- gsm_sys_thread_create(NULL, "netconn_thread", (gsm_sys_thread_t)netconn_client_thread, NULL, GSM_SYS_THREAD_SS, GSM_SYS_THREAD_PRIO);
- } else {
- printf("Cannot attach to network!\r\n");
- }
+ /* Start netconn thread */
+ lwgsm_sys_thread_create(NULL, "netconn_thread", (lwgsm_sys_thread_t)netconn_client_thread, NULL, LWGSM_SYS_THREAD_SS, LWGSM_SYS_THREAD_PRIO);
/*
* Do not stop program here.
* New threads were created for GSM processing
*/
while (1) {
- gsm_delay(1000);
+ lwgsm_delay(1000);
}
return 0;
@@ -84,22 +80,22 @@ main(void) {
/**
* \brief Event callback function for GSM stack
* \param[in] evt: Event information with data
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
*/
-static gsmr_t
-gsm_callback_func(gsm_evt_t* evt) {
- switch (gsm_evt_get_type(evt)) {
- case GSM_EVT_INIT_FINISH: printf("Library initialized!\r\n"); break;
+static lwgsmr_t
+lwgsm_callback_func(lwgsm_evt_t* evt) {
+ switch (lwgsm_evt_get_type(evt)) {
+ case LWGSM_EVT_INIT_FINISH: printf("Library initialized!\r\n"); break;
/* Process and print registration change */
- case GSM_EVT_NETWORK_REG_CHANGED: network_utils_process_reg_change(evt); break;
+ case LWGSM_EVT_NETWORK_REG_CHANGED: network_utils_process_reg_change(evt); break;
/* Process current network operator */
- case GSM_EVT_NETWORK_OPERATOR_CURRENT: network_utils_process_curr_operator(evt); break;
+ case LWGSM_EVT_NETWORK_OPERATOR_CURRENT: network_utils_process_curr_operator(evt); break;
/* Process signal strength */
- case GSM_EVT_SIGNAL_STRENGTH: network_utils_process_rssi(evt); break;
+ case LWGSM_EVT_SIGNAL_STRENGTH: network_utils_process_rssi(evt); break;
/* Other user events here... */
default: break;
}
- return gsmOK;
+ return lwgsmOK;
}
diff --git a/examples/win32/netconn_client_rtos/netconn_client_rtos.vcxproj b/examples/win32/netconn_client_rtos/netconn_client_rtos.vcxproj
index af18f75a..21cbe55c 100644
--- a/examples/win32/netconn_client_rtos/netconn_client_rtos.vcxproj
+++ b/examples/win32/netconn_client_rtos/netconn_client_rtos.vcxproj
@@ -73,18 +73,18 @@
true
- ..\..\..\GSM_AT_Lib\src\include;.;..\..\..\snippets\include;$(IncludePath)
+ .;..\..\..\lwgsm\src\include;..\..\..\lwgsm\src\include\system\port\win32;..\..\..\snippets\include;$(IncludePath)
- ..\..\..\ESP_AT_Lib\src\include;.;..\..\..\snippets\include;$(IncludePath)
+ .;..\..\..\lwgsm\src\include;..\..\..\lwgsm\src\include\system\port\win32;..\..\..\snippets\include;$(IncludePath)true
- ..\..\..\ESP_AT_Lib\src\include;.;..\..\..\snippets\include;$(IncludePath)
+ .;..\..\..\lwgsm\src\include;..\..\..\lwgsm\src\include\system\port\win32;..\..\..\snippets\include;$(IncludePath)false
- ..\..\..\ESP_AT_Lib\src\include;.;..\..\..\snippets\include;$(IncludePath)
+ .;..\..\..\lwgsm\src\include;..\..\..\lwgsm\src\include\system\port\win32;..\..\..\snippets\include;$(IncludePath)false
@@ -140,34 +140,34 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/win32/sms_send_receive_rtos/gsm_config.h b/examples/win32/sms_send_receive_rtos/gsm_config.h
deleted file mode 100644
index a1b7ac9f..00000000
--- a/examples/win32/sms_send_receive_rtos/gsm_config.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * \file gsm_config.h
- * \brief Configuration file
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#ifndef GSM_HDR_CONFIG_H
-#define GSM_HDR_CONFIG_H
-
-/*
- * Rename this file to "gsm_config.h" for your application
- */
-
-/* First include debug before any config changes */
-#include "gsm/gsm_debug.h"
-
-/*
- * Check default configuration settings for more information
- */
-#define GSM_CFG_AT_ECHO 1
-#define GSM_CFG_SYS_PORT GSM_SYS_PORT_WIN32
-#define GSM_CFG_INPUT_USE_PROCESS 1
-
-/* Enable SMS API */
-#define GSM_CFG_SMS 1
-
-/* After user configuration, call default config to merge config together */
-#include "gsm/gsm_config_default.h"
-
-#endif /* GSM_HDR_CONFIG_H */
diff --git a/examples/win32/sms_send_receive_rtos/lwgsm_opts.h b/examples/win32/sms_send_receive_rtos/lwgsm_opts.h
new file mode 100644
index 00000000..d2a82e98
--- /dev/null
+++ b/examples/win32/sms_send_receive_rtos/lwgsm_opts.h
@@ -0,0 +1,49 @@
+/**
+ * \file lwgsm_opts.h
+ * \brief GSM application options
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM - Lightweight GSM-AT library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+#ifndef LWGSM_HDR_OPTS_H
+#define LWGSM_HDR_OPTS_H
+
+/* Rename this file to "lwgsm_opts.h" for your application */
+
+/*
+ * Open "include/lwgsm/lwgsm_opt.h" and
+ * copy & replace here settings you want to change values
+ */
+#define LWGSM_CFG_AT_ECHO 1
+#define LWGSM_CFG_INPUT_USE_PROCESS 1
+
+/* Enable SMS API */
+#define LWGSM_CFG_SMS 1
+
+#endif /* LWGSM_HDR_OPTS_H */
diff --git a/examples/win32/sms_send_receive_rtos/main.c b/examples/win32/sms_send_receive_rtos/main.c
index 220b93f7..7078eaab 100644
--- a/examples/win32/sms_send_receive_rtos/main.c
+++ b/examples/win32/sms_send_receive_rtos/main.c
@@ -4,44 +4,39 @@
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Before you start using WIN32 implementation with USB and VCP,
- * check gsm_ll_win32.c implementation and choose your COM port!
+ * check lwgsm_ll_win32.c implementation and choose your COM port!
*/
-#include "gsm/gsm.h"
+#include "lwgsm/lwgsm.h"
#include "sim_manager.h"
#include "network_utils.h"
+#include "sms_send_receive.h"
-static gsmr_t gsm_callback_func(gsm_evt_t* evt);
-
-/**
- * \brief SMS entry
- */
-gsm_sms_entry_t
-sms_entry;
+static lwgsmr_t lwgsm_callback_func(lwgsm_evt_t* evt);
/**
* \brief Program entry point
@@ -51,37 +46,28 @@ main(void) {
printf("Starting GSM application!\r\n");
/* Initialize GSM with default callback function */
- if (gsm_init(gsm_callback_func, 1) != gsmOK) {
- printf("Cannot initialize GSM-AT Library\r\n");
+ if (lwgsm_init(lwgsm_callback_func, 1) != lwgsmOK) {
+ printf("Cannot initialize LwGSM\r\n");
}
/* Configure device by unlocking SIM card */
if (configure_sim_card()) {
printf("SIM card configured. Adding delay to stabilize SIM card.\r\n");
- gsm_delay(10000);
+ lwgsm_delay(10000);
} else {
printf("Cannot configure SIM card! Is it inserted, pin valid and not under PUK? Closing down...\r\n");
- while (1) { gsm_delay(1000); }
- }
-
-#if GSM_CFG_SMS
- /* First enable SMS functionality */
- if (gsm_sms_enable(NULL, NULL, 1) == gsmOK) {
- printf("SMS enabled. Send new SMS from your phone to device.\r\n");
- } else {
- printf("Cannot enable SMS functionality!\r\n");
+ while (1) { lwgsm_delay(1000); }
}
- /* Now send SMS from phone to device */
- printf("Start by sending SMS message to device...\r\n");
-#endif /* GSM_CFG_SMS */
+ /* Start SMS send receive example */
+ sms_send_receive_start();
/*
* Do not stop program here.
* New threads were created for GSM processing
*/
while (1) {
- gsm_delay(1000);
+ lwgsm_delay(1000);
}
return 0;
@@ -90,79 +76,22 @@ main(void) {
/**
* \brief Event callback function for GSM stack
* \param[in] evt: Event information with data
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
*/
-static gsmr_t
-gsm_callback_func(gsm_evt_t* evt) {
- switch (gsm_evt_get_type(evt)) {
- case GSM_EVT_INIT_FINISH: printf("Library initialized!\r\n"); break;
+static lwgsmr_t
+lwgsm_callback_func(lwgsm_evt_t* evt) {
+ switch (lwgsm_evt_get_type(evt)) {
+ case LWGSM_EVT_INIT_FINISH: printf("Library initialized!\r\n"); break;
/* Process and print registration change */
- case GSM_EVT_NETWORK_REG_CHANGED: network_utils_process_reg_change(evt); break;
+ case LWGSM_EVT_NETWORK_REG_CHANGED: network_utils_process_reg_change(evt); break;
/* Process current network operator */
- case GSM_EVT_NETWORK_OPERATOR_CURRENT: network_utils_process_curr_operator(evt); break;
+ case LWGSM_EVT_NETWORK_OPERATOR_CURRENT: network_utils_process_curr_operator(evt); break;
/* Process signal strength */
- case GSM_EVT_SIGNAL_STRENGTH: network_utils_process_rssi(evt); break;
+ case LWGSM_EVT_SIGNAL_STRENGTH: network_utils_process_rssi(evt); break;
/* Other user events here... */
-#if GSM_CFG_SMS
- case GSM_EVT_SMS_READY: { /* SMS is ready notification from device */
- printf("SIM device SMS service is ready!\r\n");
- break;
- }
- case GSM_EVT_SMS_RECV: { /* New SMS received indicator */
- gsmr_t res;
-
- printf("New SMS received!\r\n"); /* Notify user */
-
- /* Try to read SMS */
- res = gsm_sms_read(gsm_evt_sms_recv_get_mem(evt), gsm_evt_sms_recv_get_pos(evt), &sms_entry, 1, NULL, NULL, 0);
- if (res == gsmOK) {
- printf("SMS read in progress!\r\n");
- } else {
- printf("Cannot start SMS read procedure!\r\n");
- }
- break;
- }
- case GSM_EVT_SMS_READ: { /* SMS read event */
- gsm_sms_entry_t* entry = gsm_evt_sms_read_get_entry(evt);
- if (gsm_evt_sms_read_get_result(evt) == gsmOK && entry != NULL) {
- /* Print SMS data */
- printf("SMS read. From: %s, content: %s\r\n",
- entry->number, entry->data
- );
-
- /* Try to send SMS back */
- if (gsm_sms_send(entry->number, entry->data, NULL, NULL, 0) == gsmOK) {
- printf("SMS send in progress!\r\n");
- } else {
- printf("Cannot start SMS send procedure!\r\n");
- }
-
- /* Delete SMS from device memory */
- gsm_sms_delete(entry->mem, entry->pos, NULL, NULL, 0);
- }
- break;
- }
- case GSM_EVT_SMS_SEND: { /* SMS send event */
- if (gsm_evt_sms_send_get_result(evt) == gsmOK) {
- printf("SMS has been successfully sent!\r\n");
- } else {
- printf("SMS has not been sent successfully!\r\n");
- }
- break;
- }
- case GSM_EVT_SMS_DELETE: {
- if (gsm_evt_sms_delete_get_result(evt) == gsmOK) {
- printf("SMS deleted, memory position: %d\r\n", (int)gsm_evt_sms_delete_get_pos(evt));
- } else {
- printf("SMS delete operation failed!\r\n");
- }
- break;
- }
-#endif /* GSM_CFG_SMS */
-
default: break;
}
- return gsmOK;
+ return lwgsmOK;
}
diff --git a/examples/win32/sms_send_receive_rtos/sms_send_receive_rtos.vcxproj b/examples/win32/sms_send_receive_rtos/sms_send_receive_rtos.vcxproj
index d7e1a2df..0eef6d7e 100644
--- a/examples/win32/sms_send_receive_rtos/sms_send_receive_rtos.vcxproj
+++ b/examples/win32/sms_send_receive_rtos/sms_send_receive_rtos.vcxproj
@@ -73,18 +73,18 @@
true
- ..\..\..\GSM_AT_Lib\src\include;.;..\..\..\snippets\include;$(IncludePath)
+ .;..\..\..\lwgsm\src\include;..\..\..\lwgsm\src\include\system\port\win32;..\..\..\snippets\include;$(IncludePath)
- ..\..\..\ESP_AT_Lib\src\include;.;..\..\..\snippets\include;$(IncludePath)
+ .;..\..\..\lwgsm\src\include;..\..\..\lwgsm\src\include\system\port\win32;..\..\..\snippets\include;$(IncludePath)true
- ..\..\..\ESP_AT_Lib\src\include;.;..\..\..\snippets\include;$(IncludePath)
+ .;..\..\..\lwgsm\src\include;..\..\..\lwgsm\src\include\system\port\win32;..\..\..\snippets\include;$(IncludePath)false
- ..\..\..\ESP_AT_Lib\src\include;.;..\..\..\snippets\include;$(IncludePath)
+ .;..\..\..\lwgsm\src\include;..\..\..\lwgsm\src\include\system\port\win32;..\..\..\snippets\include;$(IncludePath)false
@@ -140,35 +140,36 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/win32/sms_send_receive_rtos/sms_send_receive_rtos.vcxproj.filters b/examples/win32/sms_send_receive_rtos/sms_send_receive_rtos.vcxproj.filters
index f0dc5fee..44fede1f 100644
--- a/examples/win32/sms_send_receive_rtos/sms_send_receive_rtos.vcxproj.filters
+++ b/examples/win32/sms_send_receive_rtos/sms_send_receive_rtos.vcxproj.filters
@@ -109,5 +109,8 @@
Source Files\GSM CORE
+
+ Source Files\GSM SNIPPETS
+
\ No newline at end of file
diff --git a/gsm_at_lib/src/apps/mqtt/gsm_mqtt_client_api.c b/gsm_at_lib/src/apps/mqtt/gsm_mqtt_client_api.c
deleted file mode 100644
index adde5f6f..00000000
--- a/gsm_at_lib/src/apps/mqtt/gsm_mqtt_client_api.c
+++ /dev/null
@@ -1,523 +0,0 @@
-/**
- * \file gsm_mqtt_client_api.c
- * \brief MQTT client API
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#include "gsm/apps/gsm_mqtt_client_api.h"
-#include "gsm/gsm_mem.h"
-
-/* Tracing debug message */
-#define GSM_CFG_DBG_MQTT_API_TRACE (GSM_CFG_DBG_MQTT_API | GSM_DBG_TYPE_TRACE)
-#define GSM_CFG_DBG_MQTT_API_STATE (GSM_CFG_DBG_MQTT_API | GSM_DBG_TYPE_STATE)
-#define GSM_CFG_DBG_MQTT_API_TRACE_WARNING (GSM_CFG_DBG_MQTT_API | GSM_DBG_TYPE_TRACE | GSM_DBG_LVL_WARNING)
-#define GSM_CFG_DBG_MQTT_API_TRACE_SEVERE (GSM_CFG_DBG_MQTT_API | GSM_DBG_TYPE_TRACE | GSM_DBG_LVL_SEVERE)
-
-/**
- * \brief MQTT API client structure
- */
-struct gsm_mqtt_client_api {
- gsm_mqtt_client_p mc; /*!< MQTT client handle */
- gsm_sys_mbox_t rcv_mbox; /*!< Received data mbox */
- gsm_sys_sem_t sync_sem; /*!< Synchronization semaphore */
- gsm_sys_mutex_t mutex; /*!< Mutex handle */
- uint8_t release_sem; /*!< Set to `1` to release semaphore */
- gsm_mqtt_conn_status_t connect_resp; /*!< Response when connecting to server */
- gsmr_t sub_pub_resp; /*!< Subscribe/Unsubscribe/Publish response */
-} gsm_mqtt_client_api_t;
-
-/**
- * \brief Variable used as pointer for message queue when MQTT connection is closed
- */
-static uint8_t
-mqtt_closed = 0xFF;
-
-/**
- * \brief Release user semaphore
- * \param[in] client: Client handle
- */
-static void
-release_sem(gsm_mqtt_client_api_p client) {
- if (client->release_sem) {
- client->release_sem = 0;
- gsm_sys_sem_release(&client->sync_sem);
- }
-}
-
-/**
- * \brief MQTT event callback function
- */
-static void
-mqtt_evt(gsm_mqtt_client_p client, gsm_mqtt_evt_t* evt) {
- gsm_mqtt_client_api_p api_client = gsm_mqtt_client_get_arg(client);
- if (api_client == NULL) {
- return;
- }
- switch (gsm_mqtt_client_evt_get_type(client, evt)) {
- case GSM_MQTT_EVT_CONNECT: {
- gsm_mqtt_conn_status_t status = gsm_mqtt_client_evt_connect_get_status(client, evt);
-
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_API_TRACE,
- "[MQTT API] Connect event with status: %d\r\n", (int)status);
-
- api_client->connect_resp = status;
-
- /*
- * By MQTT 3.1.1 specification, broker must close connection
- * if client CONNECT packet was not accepted.
- *
- * If client is accepted or connection did not even start,
- * release semaphore, otherwise wait CLOSED event
- * and release semaphore from there,
- * to make sure we are fully ready for next connection
- */
- if (status == GSM_MQTT_CONN_STATUS_TCP_FAILED
- || status == GSM_MQTT_CONN_STATUS_ACCEPTED) {
- release_sem(api_client); /* Release semaphore */
- }
-
- break;
- }
- case GSM_MQTT_EVT_PUBLISH_RECV: {
- /* Check valid receive mbox */
- if (gsm_sys_mbox_isvalid(&api_client->rcv_mbox)) {
- gsm_mqtt_client_api_buf_p buf;
- size_t size, buf_size, topic_size, payload_size;
-
- /* Get event data */
- const char* topic = gsm_mqtt_client_evt_publish_recv_get_topic(client, evt);
- size_t topic_len = gsm_mqtt_client_evt_publish_recv_get_topic_len(client, evt);
- const uint8_t* payload = gsm_mqtt_client_evt_publish_recv_get_payload(client, evt);
- size_t payload_len = gsm_mqtt_client_evt_publish_recv_get_payload_len(client, evt);
- gsm_mqtt_qos_t qos = gsm_mqtt_client_evt_publish_recv_get_qos(client, evt);
-
- /* Print debug message */
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_API_TRACE,
- "[MQTT API] New publish received on topic %.*s\r\n", (int)topic_len, topic);
-
- /* Calculate memory sizes */
- buf_size = GSM_MEM_ALIGN(sizeof(*buf));
- topic_size = GSM_MEM_ALIGN(sizeof(*topic) * (topic_len + 1));
- payload_size = GSM_MEM_ALIGN(sizeof(*payload) * (payload_len + 1));
-
- size = buf_size + topic_size + payload_size;
- buf = gsm_mem_malloc(size);
- if (buf != NULL) {
- GSM_MEMSET(buf, 0x00, size);
- buf->topic = (void *)((uint8_t *)buf + buf_size);
- buf->payload = (void *)((uint8_t *)buf + buf_size + topic_size);
- buf->topic_len = topic_len;
- buf->payload_len = payload_len;
- buf->qos = qos;
-
- /* Copy content to new memory */
- GSM_MEMCPY(buf->topic, topic, sizeof(*topic) * topic_len);
- GSM_MEMCPY(buf->payload, payload, sizeof(*payload) * payload_len);
-
- /* Write to receive queue */
- if (!gsm_sys_mbox_putnow(&api_client->rcv_mbox, buf)) {
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_API_TRACE_WARNING,
- "[MQTT API] Cannot put new received MQTT publish to queue\r\n");
- gsm_mem_free_s((void **)&buf);
- }
- } else {
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_API_TRACE_WARNING,
- "[MQTT API] Cannot allocate memory for packet buffer of size %d bytes\r\n",
- (int)size);
- }
- }
- break;
- }
- case GSM_MQTT_EVT_PUBLISH: {
- api_client->sub_pub_resp = gsm_mqtt_client_evt_publish_get_result(client, evt);
-
- /* Print debug message */
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_API_TRACE,
- "[MQTT API] Publish event with response: %d\r\n",
- (int)api_client->sub_pub_resp);
-
- release_sem(api_client); /* Release semaphore */
- break;
- }
- case GSM_MQTT_EVT_SUBSCRIBE: {
- api_client->sub_pub_resp = gsm_mqtt_client_evt_subscribe_get_result(client, evt);
-
- /* Print debug message */
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_API_TRACE,
- "[MQTT API] Subscribe event with response: %d\r\n",
- (int)api_client->sub_pub_resp);
-
- release_sem(api_client); /* Release semaphore */
- break;
- }
- case GSM_MQTT_EVT_UNSUBSCRIBE: {
- api_client->sub_pub_resp = gsm_mqtt_client_evt_unsubscribe_get_result(client, evt);
-
- /* Print debug message */
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_API_TRACE,
- "[MQTT API] Unsubscribe event with response: %d\r\n",
- (int)api_client->sub_pub_resp);
-
- release_sem(api_client); /* Release semaphore */
- break;
- }
- case GSM_MQTT_EVT_DISCONNECT: {
- uint8_t is_accepted = gsm_mqtt_client_evt_disconnect_is_accepted(client, evt);
- /* Disconnect event happened */
- //api_client->connect_resp = MQTT_CONN_STATUS_TCP_FAILED;
-
- /* Print debug message */
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_API_TRACE,
- "[MQTT API] Disconnect event\r\n");
-
- /* Write to receive mbox to wakeup receive thread */
- if (is_accepted && gsm_sys_mbox_isvalid(&api_client->rcv_mbox)) {
- gsm_sys_mbox_putnow(&api_client->rcv_mbox, &mqtt_closed);
- }
-
- release_sem(api_client); /* Release semaphore */
- break;
- }
- default: break;
- }
-}
-
-/**
- * \brief Create new MQTT client API
- * \param[in] tx_buff_len: Maximal TX buffer for maximal packet length
- * \param[in] rx_buff_len: Maximal RX buffer
- * \return Client handle on success, `NULL` otherwise
- */
-gsm_mqtt_client_api_p
-gsm_mqtt_client_api_new(size_t tx_buff_len, size_t rx_buff_len) {
- gsm_mqtt_client_api_p client;
- size_t size;
-
- size = GSM_MEM_ALIGN(sizeof(*client)); /* Get size of client itself */
-
- /* Create client APi structure */
- client = gsm_mem_calloc(1, size); /* Allocate client memory */
- if (client != NULL) {
- /* Create MQTT raw client structure */
- client->mc = gsm_mqtt_client_new(tx_buff_len, rx_buff_len);
- if (client->mc != NULL) {
- /* Create receive mbox queue */
- if (gsm_sys_mbox_create(&client->rcv_mbox, 5)) {
- /* Create synchronization semaphore */
- if (gsm_sys_sem_create(&client->sync_sem, 1)) {
- /* Create mutex */
- if (gsm_sys_mutex_create(&client->mutex)) {
- gsm_mqtt_client_set_arg(client->mc, client);/* Set client to mqtt client argument */
- return client;
- } else {
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_API,
- "[MQTT API] Cannot allocate mutex\r\n");
- }
- } else {
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_API,
- "[MQTT API] Cannot allocate sync semaphore\r\n");
- }
- } else {
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_API,
- "[MQTT API] Cannot allocate receive queue\r\n");
- }
- } else {
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_API,
- "[MQTT API] Cannot allocate MQTT client\r\n");
- }
- } else {
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_API,
- "[MQTT API] Cannot allocate memory for client\r\n");
- }
-
- gsm_mqtt_client_api_delete(client);
- client = NULL;
- return NULL;
-}
-
-/**
- * \brief Delete client from memory
- * \param[in] client: MQTT API client handle
- */
-void
-gsm_mqtt_client_api_delete(gsm_mqtt_client_api_p client) {
- if (client == NULL) {
- return;
- }
- if (gsm_sys_sem_isvalid(&client->sync_sem)) {
- gsm_sys_sem_delete(&client->sync_sem);
- gsm_sys_sem_invalid(&client->sync_sem);
- }
- if (gsm_sys_mutex_isvalid(&client->mutex)) {
- gsm_sys_mutex_delete(&client->mutex);
- gsm_sys_mutex_invalid(&client->mutex);
- }
- if (gsm_sys_mbox_isvalid(&client->rcv_mbox)) {
- void* d;
- while (gsm_sys_mbox_getnow(&client->rcv_mbox, &d)) {
- if ((uint8_t *)d != (uint8_t *)&mqtt_closed) {
- gsm_mqtt_client_api_buf_free(d);
- }
- }
- gsm_sys_mbox_delete(&client->rcv_mbox);
- gsm_sys_mbox_invalid(&client->rcv_mbox);
- }
- if (client->mc != NULL) {
- gsm_mqtt_client_delete(client->mc);
- client->mc = NULL;
- }
- gsm_mem_free_s((void **)&client);
-}
-
-/**
- * \brief Connect to MQTT broker
- * \param[in] client: MQTT API client handle
- * \param[in] host: TCP host
- * \param[in] port: TCP port
- * \param[in] info: MQTT client info
- * \return \ref GSM_MQTT_CONN_STATUS_ACCEPTED on success, member of \ref gsm_mqtt_conn_status_t otherwise
- */
-gsm_mqtt_conn_status_t
-gsm_mqtt_client_api_connect(gsm_mqtt_client_api_p client, const char* host,
- gsm_port_t port, const gsm_mqtt_client_info_t* info) {
- if (client == NULL || host == NULL
- || !port || info == NULL) {
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_API_TRACE_WARNING,
- "[MQTT API] Invalid parameters in function\r\n");
- return GSM_MQTT_CONN_STATUS_TCP_FAILED;
- }
-
- gsm_sys_mutex_lock(&client->mutex);
- client->connect_resp = GSM_MQTT_CONN_STATUS_TCP_FAILED;
- gsm_sys_sem_wait(&client->sync_sem, 0);
- client->release_sem = 1;
- if (gsm_mqtt_client_connect(client->mc, host, port, mqtt_evt, info) == gsmOK) {
- gsm_sys_sem_wait(&client->sync_sem, 0);
- } else {
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_API_TRACE_WARNING,
- "[MQTT API] Cannot connect to %s\r\n", host);
- }
- client->release_sem = 0;
- gsm_sys_sem_release(&client->sync_sem);
- gsm_sys_mutex_unlock(&client->mutex);
- return client->connect_resp;
-}
-
-/**
- * \brief Close MQTT connection
- * \param[in] client: MQTT API client handle
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
- */
-gsmr_t
-gsm_mqtt_client_api_close(gsm_mqtt_client_api_p client) {
- gsmr_t res = gsmERR;
-
- GSM_ASSERT("client != NULL", client != NULL);
-
- gsm_sys_mutex_lock(&client->mutex);
- gsm_sys_sem_wait(&client->sync_sem, 0);
- client->release_sem = 1;
- if (gsm_mqtt_client_disconnect(client->mc) == gsmOK) {
- res = gsmOK;
- gsm_sys_sem_wait(&client->sync_sem, 0);
- } else {
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_API_TRACE_WARNING,
- "[MQTT API] Cannot close API connection\r\n");
- }
- client->release_sem = 0;
- gsm_sys_sem_release(&client->sync_sem);
- gsm_sys_mutex_unlock(&client->mutex);
- return res;
-}
-
-/**
- * \brief Subscribe to topic
- * \param[in] client: MQTT API client handle
- * \param[in] topic: Topic to subscribe on
- * \param[in] qos: Quality of service. This parameter can be a value of \ref gsm_mqtt_qos_t
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
- */
-gsmr_t
-gsm_mqtt_client_api_subscribe(gsm_mqtt_client_api_p client, const char* topic,
- gsm_mqtt_qos_t qos) {
- gsmr_t res = gsmERR;
-
- GSM_ASSERT("client != NULL", client != NULL);
- GSM_ASSERT("topic != NULL", topic != NULL);
-
- gsm_sys_mutex_lock(&client->mutex);
- gsm_sys_sem_wait(&client->sync_sem, 0);
- client->release_sem = 1;
- if (gsm_mqtt_client_subscribe(client->mc, topic, qos, NULL) == gsmOK) {
- gsm_sys_sem_wait(&client->sync_sem, 0);
- res = client->sub_pub_resp;
- } else {
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_API_TRACE_WARNING,
- "[MQTT API] Cannot subscribe to topic %s\r\n", topic);
- }
- client->release_sem = 0;
- gsm_sys_sem_release(&client->sync_sem);
- gsm_sys_mutex_unlock(&client->mutex);
-
- return res;
-}
-
-/**
- * \brief Unsubscribe from topic
- * \param[in] client: MQTT API client handle
- * \param[in] topic: Topic to unsubscribe from
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
- */
-gsmr_t
-gsm_mqtt_client_api_unsubscribe(gsm_mqtt_client_api_p client, const char* topic) {
- gsmr_t res = gsmERR;
-
- GSM_ASSERT("client != NULL", client != NULL);
- GSM_ASSERT("topic != NULL", topic != NULL);
-
- gsm_sys_mutex_lock(&client->mutex);
- gsm_sys_sem_wait(&client->sync_sem, 0);
- client->release_sem = 1;
- if (gsm_mqtt_client_unsubscribe(client->mc, topic, NULL) == gsmOK) {
- gsm_sys_sem_wait(&client->sync_sem, 0);
- res = client->sub_pub_resp;
- } else {
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_API_TRACE_WARNING,
- "[MQTT API] Cannot unsubscribe from topic %s\r\n", topic);
- }
- client->release_sem = 0;
- gsm_sys_sem_release(&client->sync_sem);
- gsm_sys_mutex_unlock(&client->mutex);
-
- return res;
-}
-
-/**
- * \brief Publish new packet to MQTT network
- * \param[in] client: MQTT API client handle
- * \param[in] topic: Topic to publish on
- * \param[in] data: Data to send
- * \param[in] btw: Number of bytes to send for data parameter
- * \param[in] qos: Quality of service. This parameter can be a value of \ref gsm_mqtt_qos_t
- * \param[in] retain: Set to `1` for retain flag, `0` otherwise
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
- */
-gsmr_t
-gsm_mqtt_client_api_publish(gsm_mqtt_client_api_p client, const char* topic, const void* data,
- size_t btw, gsm_mqtt_qos_t qos, uint8_t retain) {
- gsmr_t res = gsmERR;
-
- GSM_ASSERT("client != NULL", client != NULL);
- GSM_ASSERT("topic != NULL", topic != NULL);
- GSM_ASSERT("data != NULL", data != NULL);
- GSM_ASSERT("btw > 0", btw > 0);
-
- gsm_sys_mutex_lock(&client->mutex);
- gsm_sys_sem_wait(&client->sync_sem, 0);
- client->release_sem = 1;
- if (gsm_mqtt_client_publish(client->mc, topic, data, GSM_U16(btw), qos, retain, NULL) == gsmOK) {
- gsm_sys_sem_wait(&client->sync_sem, 0);
- res = client->sub_pub_resp;
- } else {
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_API_TRACE_WARNING,
- "[MQTT API] Cannot publish new packet\r\n");
- }
- client->release_sem = 0;
- gsm_sys_sem_release(&client->sync_sem);
- gsm_sys_mutex_unlock(&client->mutex);
-
- return res;
-}
-
-/**
- * \brief Check if client MQTT connection is active
- * \param[in] client: MQTT API client handle
- * \return `1` on success, `0` otherwise
- */
-uint8_t
-gsm_mqtt_client_api_is_connected(gsm_mqtt_client_api_p client) {
- uint8_t ret;
-
- if (client == NULL) {
- return 0;
- }
-
- gsm_sys_mutex_lock(&client->mutex);
- ret = gsm_mqtt_client_is_connected(client->mc);
- gsm_sys_mutex_unlock(&client->mutex);
- return ret;
-}
-
-/**
- * \brief Receive next packet in specific timeout time
- * \note This function can be called from separate thread
- * than the rest of API function, which allows you to
- * handle receive data separated with custom timeout
- * \param[in] client: MQTT API client handle
- * \param[in] p: Pointer to output buffer
- * \param[in] timeout: Maximal time to wait before function returns timeout
- * \return \ref gsmOK on success, \ref gsmCLOSED if MQTT is closed, \ref gsmTIMEOUT on timeout
- */
-gsmr_t
-gsm_mqtt_client_api_receive(gsm_mqtt_client_api_p client, gsm_mqtt_client_api_buf_p* p,
- uint32_t timeout) {
- GSM_ASSERT("client != NULL", client != NULL);
- GSM_ASSERT("p != NULL", p != NULL);
-
- *p = NULL;
-
- /* Get new entry from mbox */
- if (timeout == 0) {
- if (!gsm_sys_mbox_getnow(&client->rcv_mbox, (void **)p)) {
- return gsmTIMEOUT;
- }
- } else if (gsm_sys_mbox_get(&client->rcv_mbox, (void **)p, timeout) == GSM_SYS_TIMEOUT) {
- return gsmTIMEOUT;
- }
-
- /* Check for MQTT closed event */
- if ((uint8_t *)(*p) == (uint8_t *)&mqtt_closed) {
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_API_TRACE,
- "[MQTT API] Closed event received from queue\r\n");
-
- *p = NULL;
- return gsmCLOSED;
- }
- return gsmOK;
-}
-
-/**
- * \brief Free buffer memory after usage
- * \param[in] p: Buffer to free
- */
-void
-gsm_mqtt_client_api_buf_free(gsm_mqtt_client_api_buf_p p) {
- gsm_mem_free_s((void **)&p);
-}
diff --git a/gsm_at_lib/src/gsm/gsm.c b/gsm_at_lib/src/gsm/gsm.c
deleted file mode 100644
index 564d40ec..00000000
--- a/gsm_at_lib/src/gsm/gsm.c
+++ /dev/null
@@ -1,334 +0,0 @@
-/**
- * \file gsm.c
- * \brief Main GSM core file
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#include "gsm/gsm_private.h"
-#include "gsm/gsm_mem.h"
-#include "gsm/gsm_threads.h"
-#include "system/gsm_ll.h"
-
-#if GSM_CFG_OS != 1
-#error GSM_CFG_OS must be set to 1!
-#endif
-
-static gsmr_t def_callback(gsm_evt_t* cb);
-static gsm_evt_func_t def_evt_link;
-
-gsm_t gsm;
-
-/**
- * \brief Default callback function for events
- * \param[in] evt: Pointer to callback data structure
- * \return Member of \ref gsmr_t enumeration
- */
-static gsmr_t
-def_callback(gsm_evt_t* evt) {
- GSM_UNUSED(evt);
- return gsmOK;
-}
-
-/**
- * \brief Init and prepare GSM stack for device operation
- * \note Function must be called from operating system thread context.
- * It creates necessary threads and waits them to start, thus running operating system is important.
- * - When \ref GSM_CFG_RESET_ON_INIT is enabled, reset sequence will be sent to device
- * otherwise manual call to \ref gsm_reset is required to setup device
- *
- * \param[in] evt_func: Global event callback function for all major events
- * \param[in] blocking: Status whether command should be blocking or not.
- * Used when \ref GSM_CFG_RESET_ON_INIT is enabled.
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
- */
-gsmr_t
-gsm_init(gsm_evt_fn evt_func, const uint32_t blocking) {
- gsmr_t res = gsmOK;
-
- gsm.status.f.initialized = 0; /* Clear possible init flag */
-
- def_evt_link.fn = evt_func != NULL ? evt_func : def_callback;
- gsm.evt_func = &def_evt_link; /* Set callback function */
-
- if (!gsm_sys_init()) { /* Init low-level system */
- goto cleanup;
- }
-
- if (!gsm_sys_sem_create(&gsm.sem_sync, 1)) {/* Create sync semaphore between threads */
- GSM_DEBUGF(GSM_CFG_DBG_INIT | GSM_DBG_LVL_SEVERE | GSM_DBG_TYPE_TRACE,
- "[CORE] Cannot allocate sync semaphore!\r\n");
- goto cleanup;
- }
-
- /* Create message queues */
- if (!gsm_sys_mbox_create(&gsm.mbox_producer, GSM_CFG_THREAD_PRODUCER_MBOX_SIZE)) { /* Producer */
- GSM_DEBUGF(GSM_CFG_DBG_INIT | GSM_DBG_LVL_SEVERE | GSM_DBG_TYPE_TRACE,
- "[CORE] Cannot allocate producer mbox queue!\r\n");
- goto cleanup;
- }
- if (!gsm_sys_mbox_create(&gsm.mbox_process, GSM_CFG_THREAD_PROCESS_MBOX_SIZE)) { /* Process */
- GSM_DEBUGF(GSM_CFG_DBG_INIT | GSM_DBG_LVL_SEVERE | GSM_DBG_TYPE_TRACE,
- "[CORE] Cannot allocate process mbox queue!\r\n");
- goto cleanup;
- }
-
- /* Create threads */
- gsm_sys_sem_wait(&gsm.sem_sync, 0); /* Lock semaphore */
- if (!gsm_sys_thread_create(&gsm.thread_produce, "gsm_produce", gsm_thread_produce, &gsm.sem_sync, GSM_SYS_THREAD_SS, GSM_SYS_THREAD_PRIO)) {
- GSM_DEBUGF(GSM_CFG_DBG_INIT | GSM_DBG_LVL_SEVERE | GSM_DBG_TYPE_TRACE,
- "[CORE] Cannot create producing thread!\r\n");
- gsm_sys_sem_release(&gsm.sem_sync); /* Release semaphore and return */
- goto cleanup;
- }
- gsm_sys_sem_wait(&gsm.sem_sync, 0); /* Wait semaphore, should be unlocked in produce thread */
- if (!gsm_sys_thread_create(&gsm.thread_process, "gsm_process", gsm_thread_process, &gsm.sem_sync, GSM_SYS_THREAD_SS, GSM_SYS_THREAD_PRIO)) {
- GSM_DEBUGF(GSM_CFG_DBG_INIT | GSM_DBG_LVL_SEVERE | GSM_DBG_TYPE_TRACE,
- "[CORE] Cannot allocate processing thread!\r\n");
- gsm_sys_thread_terminate(&gsm.thread_produce); /* Delete produce thread */
- gsm_sys_sem_release(&gsm.sem_sync); /* Release semaphore and return */
- goto cleanup;
- }
- gsm_sys_sem_wait(&gsm.sem_sync, 0); /* Wait semaphore, should be unlocked in produce thread */
- gsm_sys_sem_release(&gsm.sem_sync); /* Release semaphore manually */
-
- gsm_core_lock();
- gsm.ll.uart.baudrate = GSM_CFG_AT_PORT_BAUDRATE;
- gsm_ll_init(&gsm.ll); /* Init low-level communication */
-
-#if !GSM_CFG_INPUT_USE_PROCESS
- gsm_buff_init(&gsm.buff, GSM_CFG_RCV_BUFF_SIZE); /* Init buffer for input data */
-#endif /* !GSM_CFG_INPUT_USE_PROCESS */
-
- gsm.status.f.initialized = 1; /* We are initialized now */
- gsm.status.f.dev_present = 1; /* We assume device is present at this point */
-
- gsmi_send_cb(GSM_EVT_INIT_FINISH); /* Call user callback function */
-
- /*
- * Call reset command and call default
- * AT commands to prepare basic setup for device
- */
-#if GSM_CFG_RESET_ON_INIT
- if (gsm.status.f.dev_present) {
- gsm_core_unlock();
- res = gsm_reset_with_delay(GSM_CFG_RESET_DELAY_DEFAULT, NULL, NULL, blocking); /* Send reset sequence with delay */
- gsm_core_lock();
- }
-#else /* GSM_CFG_RESET_ON_INIT */
- GSM_UNUSED(blocking); /* Unused variable */
-#endif /* !GSM_CFG_RESET_ON_INIT */
- gsm_core_unlock();
-
- return res;
-
-cleanup:
- if (gsm_sys_mbox_isvalid(&gsm.mbox_producer)) {
- gsm_sys_mbox_delete(&gsm.mbox_producer);
- gsm_sys_mbox_invalid(&gsm.mbox_producer);
- }
- if (gsm_sys_mbox_isvalid(&gsm.mbox_process)) {
- gsm_sys_mbox_delete(&gsm.mbox_process);
- gsm_sys_mbox_invalid(&gsm.mbox_process);
- }
- if (gsm_sys_sem_isvalid(&gsm.sem_sync)) {
- gsm_sys_sem_delete(&gsm.sem_sync);
- gsm_sys_sem_invalid(&gsm.sem_sync);
- }
- return gsmERRMEM;
-}
-
-/**
- * \brief Execute reset and send default commands
- * \param[in] evt_fn: Callback function called when command is finished. Set to `NULL` when not used
- * \param[in] evt_arg: Custom argument for event callback function
- * \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
- */
-gsmr_t
-gsm_reset(const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- return gsm_reset_with_delay(0, evt_fn, evt_arg, blocking);
-}
-
-/**
- * \brief Execute reset and send default commands with delay
- * \param[in] delay: Number of milliseconds to wait before initiating first command to device
- * \param[in] evt_fn: Callback function called when command is finished. Set to `NULL` when not used
- * \param[in] evt_arg: Custom argument for event callback function
- * \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
- */
-gsmr_t
-gsm_reset_with_delay(uint32_t delay,
- const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
-
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_RESET;
- GSM_MSG_VAR_REF(msg).msg.reset.delay = delay;
-
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 60000);
-}
-
-/**
- * \brief Lock stack from multi-thread access, enable atomic access to core
- *
- * If lock was `0` prior funcion call, lock is enabled and increased
- *
- * \note Function may be called multiple times to increase locks.
- * Application must take care to call \ref gsm_core_unlock
- * the same amount of time to make sure lock gets back to `0`
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
- */
-gsmr_t
-gsm_core_lock(void) {
- gsm_sys_protect();
- gsm.locked_cnt++;
- return gsmOK;
-}
-
-/**
- * \brief Unlock stack for multi-thread access
- *
- * Used in conjunction with \ref gsm_core_lock function
- *
- * If lock was non-zero before function call, lock is decreased.
- * When `lock == 0`, protection is disabled and other threads may access to core
- *
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
- */
-gsmr_t
-gsm_core_unlock(void) {
- gsm.locked_cnt--;
- gsm_sys_unprotect();
- return gsmOK;
-}
-
-/**
- * \brief Delay for amount of milliseconds
- *
- * Delay is based on operating system semaphores.
- * It locks semaphore and waits for timeout in `ms` time.
- * Based on operating system, thread may be put to \e blocked list during delay and may improve execution speed
- *
- * \param[in] ms: Milliseconds to delay
- * \return `1` on success, `0` otherwise
- */
-uint8_t
-gsm_delay(uint32_t ms) {
- gsm_sys_sem_t sem;
- if (ms == 0) {
- return 1;
- }
- if (gsm_sys_sem_create(&sem, 0)) {
- gsm_sys_sem_wait(&sem, ms);
- gsm_sys_sem_release(&sem);
- gsm_sys_sem_delete(&sem);
- return 1;
- }
- return 0;
-}
-
-/**
- * \brief Set modem function mode
- * \note Use this function to set modem to normal or low-power mode
- * \param[in] mode: Mode status. Set to `1` for full functionality or `0` for low-power mode (no functionality)
- * \param[in] evt_fn: Callback function called when command is finished. Set to `NULL` when not used
- * \param[in] evt_arg: Custom argument for event callback function
- * \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
- */
-gsmr_t
-gsm_set_func_mode(uint8_t mode,
- const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
-
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_CFUN_SET;
- GSM_MSG_VAR_REF(msg).msg.cfun.mode = mode;
-
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 60000);
-}
-
-/**
- * \brief Notify stack if device is present or not
- *
- * Use this function to notify stack that device is not physically connected
- * and not ready to communicate with host device
- *
- * \param[in] present: Flag indicating device is present
- * \param[in] evt_fn: Callback function called when command is finished. Set to `NULL` when not used
- * \param[in] evt_arg: Custom argument for event callback function
- * \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
- */
-gsmr_t
-gsm_device_set_present(uint8_t present,
- const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- gsmr_t res = gsmOK;
- gsm_core_lock();
- present = present ? 1 : 0;
- if (present != gsm.status.f.dev_present) {
- gsm.status.f.dev_present = present;
-
- if (!gsm.status.f.dev_present) {
- /* Manually reset stack to default device state */
- gsmi_reset_everything(1);
- } else {
-#if GSM_CFG_RESET_ON_DEVICE_PRESENT
- gsm_core_unlock();
- res = gsm_reset_with_delay(GSM_CFG_RESET_DELAY_DEFAULT, evt_fn, evt_arg, blocking); /* Reset with delay */
- gsm_core_lock();
-#endif /* GSM_CFG_RESET_ON_DEVICE_PRESENT */
- }
- gsmi_send_cb(GSM_EVT_DEVICE_PRESENT); /* Send present event */
- }
- gsm_core_unlock();
-
- GSM_UNUSED(evt_fn);
- GSM_UNUSED(evt_arg);
- GSM_UNUSED(blocking);
-
- return res;
-}
-
-/**
- * \brief Check if device is present
- * \return `1` on success, `0` otherwise
- */
-uint8_t
-gsm_device_is_present(void) {
- uint8_t res;
- gsm_core_lock();
- res = gsm.status.f.dev_present;
- gsm_core_unlock();
- return res;
-}
diff --git a/gsm_at_lib/src/gsm/gsm_int.c b/gsm_at_lib/src/gsm/gsm_int.c
deleted file mode 100644
index 095f58ef..00000000
--- a/gsm_at_lib/src/gsm/gsm_int.c
+++ /dev/null
@@ -1,2305 +0,0 @@
-/**
- * \file gsm_int.c
- * \brief Internal functions
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#include "gsm/gsm_private.h"
-#include "gsm/gsm.h"
-#include "gsm/gsm_int.h"
-#include "gsm/gsm_mem.h"
-#include "gsm/gsm_parser.h"
-#include "gsm/gsm_unicode.h"
-#include "system/gsm_ll.h"
-
-#if !__DOXYGEN__
-/**
- * \brief Receive character structure to handle full line terminated with `\n` character
- */
-typedef struct {
- char data[128]; /*!< Received characters */
- size_t len; /*!< Length of valid characters */
-} gsm_recv_t;
-
-/* Receive character macros */
-#define RECV_ADD(ch) do { if (recv_buff.len < (sizeof(recv_buff.data)) - 1) { recv_buff.data[recv_buff.len++] = ch; recv_buff.data[recv_buff.len] = 0; } } while (0)
-#define RECV_RESET() do { recv_buff.len = 0; recv_buff.data[0] = 0; } while (0)
-#define RECV_LEN() ((size_t)recv_buff.len)
-#define RECV_IDX(index) recv_buff.data[index]
-
-/* Send data over AT port */
-#define AT_PORT_SEND_STR(str) gsm.ll.send_fn((const void *)(str), (size_t)strlen(str))
-#define AT_PORT_SEND_CONST_STR(str) gsm.ll.send_fn((const void *)(str), (size_t)(sizeof(str) - 1))
-#define AT_PORT_SEND_CHR(ch) gsm.ll.send_fn((const void *)(ch), (size_t)1)
-#define AT_PORT_SEND_FLUSH() gsm.ll.send_fn(NULL, 0)
-#define AT_PORT_SEND(d, l) gsm.ll.send_fn((const void *)(d), (size_t)(l))
-#define AT_PORT_SEND_WITH_FLUSH(d, l) do { AT_PORT_SEND((d), (l)); AT_PORT_SEND_FLUSH(); } while (0)
-
-/* Beginning and end of every AT command */
-#define AT_PORT_SEND_BEGIN_AT() do { AT_PORT_SEND_CONST_STR("AT"); } while (0)
-#define AT_PORT_SEND_END_AT() do { AT_PORT_SEND(CRLF, CRLF_LEN); AT_PORT_SEND(NULL, 0); } while (0)
-
-/* Send special characters over AT port with condition */
-#define AT_PORT_SEND_QUOTE_COND(q) do { if ((q)) { AT_PORT_SEND_CONST_STR("\""); } } while (0)
-#define AT_PORT_SEND_COMMA_COND(c) do { if ((c)) { AT_PORT_SEND_CONST_STR(","); } } while (0)
-#define AT_PORT_SEND_EQUAL_COND(e) do { if ((e)) { AT_PORT_SEND_CONST_STR("="); } } while (0)
-
-/* Send special characters */
-#define AT_PORT_SEND_CTRL_Z() AT_PORT_SEND_STR("\x1A")
-#define AT_PORT_SEND_ESC() AT_PORT_SEND_STR("\x1B")
-#endif /* !__DOXYGEN__ */
-
-static gsm_recv_t recv_buff;
-static gsmr_t gsmi_process_sub_cmd(gsm_msg_t* msg, uint8_t* is_ok, uint16_t* is_error);
-
-/**
- * \brief Memory mapping
- */
-const gsm_dev_mem_map_t
-gsm_dev_mem_map[] = {
-#define GSM_DEV_MEMORY_ENTRY(name, str_code) { GSM_MEM_ ## name, str_code },
-#include "gsm/gsm_memories.h"
-};
-
-/**
- * \brief Size of device memory mapping array
- */
-const size_t
-gsm_dev_mem_map_size = GSM_ARRAYSIZE(gsm_dev_mem_map);
-
-/**
- * \brief List of supported devices
- */
-const gsm_dev_model_map_t
-gsm_dev_model_map[] = {
-#define GSM_DEVICE_MODEL_ENTRY(name, str_id, is_2g, is_lte) { GSM_DEVICE_MODEL_ ## name, str_id, is_2g, is_lte },
-#include "gsm/gsm_models.h"
-};
-
-/**
- * \brief Size of device models mapping array
- */
-const size_t
-gsm_dev_model_map_size = GSM_ARRAYSIZE(gsm_dev_model_map);
-
-/**
- * \brief Free connection send data memory
- * \param[in] m: Send data message type
- */
-#define CONN_SEND_DATA_FREE(m) do { \
- if ((m) != NULL && (m)->msg.conn_send.fau) { \
- (m)->msg.conn_send.fau = 0; \
- if ((m)->msg.conn_send.data != NULL) { \
- GSM_DEBUGF(GSM_CFG_DBG_CONN | GSM_DBG_TYPE_TRACE, \
- "[CONN] Free write buffer fau: %p\r\n", (void *)(m)->msg.conn_send.data); \
- gsm_mem_free_s((void **)&((m)->msg.conn_send.data)); \
- } \
- } \
-} while (0)
-
-/**
- * \brief Send connection callback for "data send"
- * \param[in] m: Command message
- * \param[in] err: Error of type \ref gsmr_t
- */
-#define CONN_SEND_DATA_SEND_EVT(m, err) do { \
- CONN_SEND_DATA_FREE(m); \
- gsm.evt.type = GSM_EVT_CONN_SEND; \
- gsm.evt.evt.conn_data_send.res = err; \
- gsm.evt.evt.conn_data_send.conn = (m)->msg.conn_send.conn; \
- gsm.evt.evt.conn_data_send.sent = (m)->msg.conn_send.sent_all; \
- gsmi_send_conn_cb((m)->msg.conn_send.conn, NULL); \
-} while (0)
-
-/**
- * \brief Send reset sequence event
- * \param[in] m: Command message
- * \param[in] err: Error of type \ref gsmr_t
- */
-#define RESET_SEND_EVT(m, err) do { \
- gsm.evt.evt.reset.res = err; \
- gsmi_send_cb(GSM_EVT_RESET); \
-} while (0)
-
-/**
- * \brief Send restore sequence event
- * \param[in] m: Connection send message
- * \param[in] err: Error of type \ref gsmr_t
- */
-#define RESTORE_SEND_EVT(m, err) do { \
- gsm.evt.evt.restore.res = err; \
- gsmi_send_cb(GSM_EVT_RESTORE); \
-} while (0)
-
-/**
- * \brief Send operator scan sequence event
- * \param[in] m: Command message
- * \param[in] err: Error of type \ref gsmr_t
- */
-#define OPERATOR_SCAN_SEND_EVT(m, err) do { \
- gsm.evt.evt.operator_scan.res = err; \
- gsm.evt.evt.operator_scan.ops = (m)->msg.cops_scan.ops; \
- gsm.evt.evt.operator_scan.opf = *(m)->msg.cops_scan.opf;\
- gsmi_send_cb(GSM_EVT_OPERATOR_SCAN); \
-} while (0)
-
- /**
- * \brief Send SMS delete operation event
- * \param[in] m: SMS delete message
- * \param[in] err: Error of type \ref gsmr_t
- */
-#define SMS_SEND_DELETE_EVT(m, err) do { \
- gsm.evt.evt.sms_delete.res = err; \
- gsm.evt.evt.sms_delete.mem = (m)->msg.sms_delete.mem; \
- gsm.evt.evt.sms_delete.pos = (m)->msg.sms_delete.pos; \
- gsmi_send_cb(GSM_EVT_SMS_DELETE); \
-} while (0)
-
-/**
- * \brief Send SMS read operation event
- * \param[in] m: SMS read message
- * \param[in] err: Error of type \ref gsmr_t
- */
-#define SMS_SEND_READ_EVT(m, err) do { \
- gsm.evt.evt.sms_read.res = err; \
- gsm.evt.evt.sms_read.entry = (m)->msg.sms_read.entry; \
- gsmi_send_cb(GSM_EVT_SMS_READ); \
-} while (0)
-
-/**
- * \brief Send SMS read operation event
- * \param[in] _m_: SMS list message
- * \param[in] err: Error of type \ref gsmr_t
- */
-#define SMS_SEND_LIST_EVT(_m_, err) do { \
- gsm.evt.evt.sms_list.mem = gsm.m.sms.mem[0].current;\
- gsm.evt.evt.sms_list.entries = (_m_)->msg.sms_list.entries; \
- gsm.evt.evt.sms_list.size = (_m_)->msg.sms_list.ei; \
- gsm.evt.evt.sms_list.res = err; \
- gsmi_send_cb(GSM_EVT_SMS_LIST); \
-} while (0)
-
-/**
- * \brief Send SMS send operation event
- * \param[in] m: SMS send message
- * \param[in] err: Error of type \ref gsmr_t
- */
-#define SMS_SEND_SEND_EVT(m, err) do { \
- gsm.evt.evt.sms_send.pos = (m)->msg.sms_send.pos; \
- gsm.evt.evt.sms_send.res = err; \
- gsmi_send_cb(GSM_EVT_SMS_SEND); \
-} while (0)
-
-/**
- * \brief Get SIM info when SIM is ready
- * \param[in] blocking: Blocking command
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
- */
-gsmr_t
-gsmi_get_sim_info(const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
-
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_SIM_PROCESS_BASIC_CMDS;
- GSM_MSG_VAR_REF(msg).cmd = GSM_CMD_CNUM;
-
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 60000);
-}
-
-/**
- * \brief Send IP or MAC address to AT port
- * \param[in] d: Pointer to IP or MAC address
- * \param[in] is_ip: Set to `1` when sending IP, `0` when MAC
- * \param[in] q: Set to `1` to include start and ending quotes
- * \param[in] c: Set to `1` to include comma before string
- */
-void
-gsmi_send_ip_mac(const void* d, uint8_t is_ip, uint8_t q, uint8_t c) {
- uint8_t ch;
- char str[4];
- const gsm_mac_t* mac = d;
- const gsm_ip_t* ip = d;
-
- AT_PORT_SEND_COMMA_COND(c); /* Send comma */
- if (d == NULL) {
- return;
- }
- AT_PORT_SEND_QUOTE_COND(q); /* Send quote */
- ch = is_ip ? '.' : ':'; /* Get delimiter character */
- for (uint8_t i = 0; i < (is_ip ? 4 : 6); i++) { /* Process byte by byte */
- if (is_ip) { /* In case of IP ... */
- gsm_u8_to_str(ip->ip[i], str); /* ... go to decimal format ... */
- } else { /* ... in case of MAC ... */
- gsm_u8_to_hex_str(mac->mac[i], str, 2); /* ... go to HEX format */
- }
- AT_PORT_SEND_STR(str); /* Send str */
- if (i < (is_ip ? 4 : 6) - 1) { /* Check end if characters */
- AT_PORT_SEND_CHR(&ch); /* Send character */
- }
- }
- AT_PORT_SEND_QUOTE_COND(q); /* Send quote */
-}
-
-/**
- * \brief Send string to AT port, either plain or escaped
- * \param[in] str: Pointer to input string to string
- * \param[in] e: Value to indicate string send format, escaped (`1`) or plain (`0`)
- * \param[in] q: Value to indicate starting and ending quotes, enabled (`1`) or disabled (`0`)
- * \param[in] c: Set to `1` to include comma before string
- */
-void
-gsmi_send_string(const char* str, uint8_t e, uint8_t q, uint8_t c) {
- char special = '\\';
-
- AT_PORT_SEND_COMMA_COND(c); /* Send comma */
- AT_PORT_SEND_QUOTE_COND(q); /* Send quote */
- if (str != NULL) {
- if (e) { /* Do we have to escape string? */
- while (*str) { /* Go through string */
- if (*str == ',' || *str == '"' || *str == '\\') { /* Check for special character */
- AT_PORT_SEND_CHR(&special); /* Send special character */
- }
- AT_PORT_SEND_CHR(str); /* Send character */
- str++;
- }
- } else {
- AT_PORT_SEND_STR(str); /* Send plain string */
- }
- }
- AT_PORT_SEND_QUOTE_COND(q); /* Send quote */
-}
-
-/**
- * \brief Send number (decimal) to AT port
- * \param[in] num: Number to send to AT port
- * \param[in] q: Value to indicate starting and ending quotes, enabled (`1`) or disabled (`0`)
- * \param[in] c: Set to `1` to include comma before string
- */
-void
-gsmi_send_number(uint32_t num, uint8_t q, uint8_t c) {
- char str[11];
-
- gsm_u32_to_str(num, str); /* Convert digit to decimal string */
-
- AT_PORT_SEND_COMMA_COND(c); /* Send comma */
- AT_PORT_SEND_QUOTE_COND(q); /* Send quote */
- AT_PORT_SEND_STR(str); /* Send string with number */
- AT_PORT_SEND_QUOTE_COND(q); /* Send quote */
-}
-
-/**
- * \brief Send port number to AT port
- * \param[in] port: Port number to send
- * \param[in] q: Value to indicate starting and ending quotes, enabled (`1`) or disabled (`0`)
- * \param[in] c: Set to `1` to include comma before string
- */
-void
-gsmi_send_port(gsm_port_t port, uint8_t q, uint8_t c) {
- char str[6];
-
- gsm_u16_to_str(GSM_PORT2NUM(port), str); /* Convert digit to decimal string */
-
- AT_PORT_SEND_COMMA_COND(c); /* Send comma */
- AT_PORT_SEND_QUOTE_COND(q); /* Send quote */
- AT_PORT_SEND_STR(str); /* Send string with number */
- AT_PORT_SEND_QUOTE_COND(q); /* Send quote */
-}
-
-/**
- * \brief Send signed number to AT port
- * \param[in] num: Number to send to AT port
- * \param[in] q: Value to indicate starting and ending quotes, enabled (`1`) or disabled (`0`)
- * \param[in] c: Set to `1` to include comma before string
- */
-void
-gsmi_send_signed_number(int32_t num, uint8_t q, uint8_t c) {
- char str[11];
-
- gsm_i32_to_str(num, str); /* Convert digit to decimal string */
-
- AT_PORT_SEND_COMMA_COND(c); /* Send comma */
- AT_PORT_SEND_QUOTE_COND(q); /* Send quote */
- AT_PORT_SEND_STR(str); /* Send string with number */
- AT_PORT_SEND_QUOTE_COND(q); /* Send quote */
-}
-
-/**
- * \brief Send memory string to device
- * \param[in] mem: Memory index to send
- * \param[in] q: Value to indicate starting and ending quotes, enabled (`1`) or disabled (`0`)
- * \param[in] c: Set to `1` to include comma before string
- */
-void
-gsmi_send_dev_memory(gsm_mem_t mem, uint8_t q, uint8_t c) {
- if (mem < GSM_MEM_END) { /* Check valid range */
- gsmi_send_string(gsm_dev_mem_map[GSM_SZ(mem)].mem_str, 0, q, c);
- }
-}
-
-#if GSM_CFG_SMS || __DOXYGEN__
-
-/**
- * \brief Send SMS status text
- * \param[in] status: SMS status
- * \param[in] q: Value to indicate starting and ending quotes, enabled (`1`) or disabled (`0`)
- * \param[in] c: Set to `1` to include comma before string
- */
-void
-gsmi_send_sms_stat(gsm_sms_status_t status, uint8_t q, uint8_t c) {
- const char* t;
- switch (status) {
- case GSM_SMS_STATUS_UNREAD: t = "REC UNREAD"; break;
- case GSM_SMS_STATUS_READ: t = "REC READ"; break;
- case GSM_SMS_STATUS_UNSENT: t = "STO UNSENT"; break;
- case GSM_SMS_STATUS_SENT: t = "STO SENT"; break;
- case GSM_SMS_STATUS_ALL:
- default: t = "ALL"; break;
- }
- gsmi_send_string(t, 0, q, c);
-}
-
-#endif /* GSM_CFG_SMS */
-
-#if GSM_CFG_CONN || __DOXYGEN__
-
-/**
- * \brief Reset all connections
- * \note Used to notify upper layer stack to close everything and reset the memory if necessary
- * \param[in] forced: Flag indicating reset was forced by user
- */
-static void
-reset_connections(uint8_t forced) {
- gsm.evt.type = GSM_EVT_CONN_CLOSE;
- gsm.evt.evt.conn_active_close.forced = forced;
- gsm.evt.evt.conn_active_close.res = gsmOK;
-
- for (size_t i = 0; i < GSM_CFG_MAX_CONNS; i++) {/* Check all connections */
- if (gsm.m.conns[i].status.f.active) {
- gsm.m.conns[i].status.f.active = 0;
-
- gsm.evt.evt.conn_active_close.conn = &gsm.m.conns[i];
- gsm.evt.evt.conn_active_close.client = gsm.m.conns[i].status.f.client;
- gsmi_send_conn_cb(&gsm.m.conns[i], NULL); /* Send callback function */
- }
- }
-}
-
-#endif /* GSM_CFG_CONN || __DOXYGEN__ */
-
-/**
- * \brief Reset everything after reset was detected
- * \param[in] forced: Set to `1` if reset forced by user
- */
-void
-gsmi_reset_everything(uint8_t forced) {
- /**
- * \todo: Put stack to default state:
- * - Close all the connection in memory
- * - Clear entire data memory
- * - Reset GSM structure
- */
-
-#if GSM_CFG_CONN
- /* Manually close all connections in memory */
- reset_connections(forced);
-
- /* Check if IPD active */
- if (gsm.m.ipd.buff != NULL) {
- gsm_pbuf_free(gsm.m.ipd.buff);
- gsm.m.ipd.buff = NULL;
- }
-#endif /* GSM_CFG_CONN */
-
-#if GSM_CFG_NETWORK
- /* Notify app about detached network PDP context */
- if (gsm.m.network.is_attached) {
- gsm.m.network.is_attached = 0;
- gsmi_send_cb(GSM_EVT_NETWORK_DETACHED);
- }
-#endif /* GSM_CFG_NETWORK */
-
- /* Invalid GSM modules */
- GSM_MEMSET(&gsm.m, 0x00, sizeof(gsm.m));
-
- /* Manually set states */
- gsm.m.sim.state = (gsm_sim_state_t)-1;
- gsm.m.model = GSM_DEVICE_MODEL_UNKNOWN;
-}
-
-/**
- * \brief Process callback function to user with specific type
- * \param[in] type: Callback event type
- * \return Member of \ref gsmr_t enumeration
- */
-gsmr_t
-gsmi_send_cb(gsm_evt_type_t type) {
- gsm.evt.type = type; /* Set callback type to process */
-
- /* Call callback function for all registered functions */
- for (gsm_evt_func_t* link = gsm.evt_func; link != NULL; link = link->next) {
- link->fn(&gsm.evt);
- }
- return gsmOK;
-}
-
-#if GSM_CFG_CONN || __DOXYGEN__
-
-/**
- * \brief Process connection callback
- * \note Before calling function, callback structure must be prepared
- * \param[in] conn: Pointer to connection to use as callback
- * \param[in] evt: Event callback function for connection
- * \return Member of \ref gsmr_t enumeration
- */
-gsmr_t
-gsmi_send_conn_cb(gsm_conn_t* conn, gsm_evt_fn evt) {
- if (conn->status.f.in_closing && gsm.evt.type != GSM_EVT_CONN_CLOSE) { /* Do not continue if in closing mode */
- /* return gsmOK; */
- }
-
- if (evt != NULL) { /* Try with user connection */
- return evt(&gsm.evt); /* Call temporary function */
- } else if (conn != NULL && conn->evt_func != NULL) {/* Connection custom callback? */
- return conn->evt_func(&gsm.evt); /* Process callback function */
- } else if (conn == NULL) {
- return gsmOK;
- }
-
- /*
- * On normal API operation,
- * we should never enter to this part of code
- */
-
- /*
- * If connection doesn't have callback function
- * automatically close the connection?
- *
- * Since function call is non-blocking,
- * it will set active connection to closing mode
- * and further callback events should not be executed anymore
- */
- return gsm_conn_close(conn, 0);
-}
-
-/**
- * \brief Process and send data from device buffer
- * \return Member of \ref gsmr_t enumeration
- */
-static gsmr_t
-gsmi_tcpip_process_send_data(void) {
- gsm_conn_t* c = gsm.msg->msg.conn_send.conn;
- if (!gsm_conn_is_active(c) || /* Is the connection already closed? */
- gsm.msg->msg.conn_send.val_id != c->val_id /* Did validation ID change after we set parameter? */
- ) {
- /* Send event to user about failed send event */
- CONN_SEND_DATA_SEND_EVT(gsm.msg, gsmCLOSED);
- return gsmERR;
- }
- gsm.msg->msg.conn_send.sent = GSM_MIN(gsm.msg->msg.conn_send.btw, GSM_CFG_CONN_MAX_DATA_LEN);
-
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CIPSEND=");
- gsmi_send_number(GSM_U32(c->num), 0, 0); /* Send connection number */
- gsmi_send_number(GSM_U32(gsm.msg->msg.conn_send.sent), 0, 1); /* Send length number */
-
- /* On UDP connections, IP address and port may be selected */
- if (c->type == GSM_CONN_TYPE_UDP) {
- if (gsm.msg->msg.conn_send.remote_ip != NULL && gsm.msg->msg.conn_send.remote_port) {
- gsmi_send_ip_mac(gsm.msg->msg.conn_send.remote_ip, 1, 1, 1);/* Send IP address including quotes */
- gsmi_send_port(gsm.msg->msg.conn_send.remote_port, 0, 1); /* Send length number */
- }
- }
- AT_PORT_SEND_END_AT();
- return gsmOK;
-}
-
-/**
- * \brief Process data sent and send remaining
- * \param[in] sent: Status whether data were sent or not,
- * info received from GSM with "SEND OK" or "SEND FAIL"
- * \return `1` in case we should stop sending or `0` if we still have data to process
- */
-static uint8_t
-gsmi_tcpip_process_data_sent(uint8_t sent) {
- if (sent) { /* Data were successfully sent */
- gsm.msg->msg.conn_send.sent_all += gsm.msg->msg.conn_send.sent;
- gsm.msg->msg.conn_send.btw -= gsm.msg->msg.conn_send.sent;
- gsm.msg->msg.conn_send.ptr += gsm.msg->msg.conn_send.sent;
- if (gsm.msg->msg.conn_send.bw != NULL) {
- *gsm.msg->msg.conn_send.bw += gsm.msg->msg.conn_send.sent;
- }
- gsm.msg->msg.conn_send.tries = 0;
- } else { /* We were not successful */
- gsm.msg->msg.conn_send.tries++; /* Increase number of tries */
- if (gsm.msg->msg.conn_send.tries == GSM_CFG_MAX_SEND_RETRIES) { /* In case we reached max number of retransmissions */
- return 1; /* Return 1 and indicate error */
- }
- }
- if (gsm.msg->msg.conn_send.btw > 0) { /* Do we still have data to send? */
- if (gsmi_tcpip_process_send_data() != gsmOK) { /* Check if we can continue */
- return 1; /* Finish at this point */
- }
- return 0; /* We still have data to send */
- }
- return 1; /* Everything was sent, we can stop execution */
-}
-
-/**
- * \brief Process CIPSEND response
- * \param[in] rcv: Received data
- * \param[in,out] is_ok: Pointer to current ok status
- * \param[in,out] is_ok: Pointer to current error status
- */
-void
-gsmi_process_cipsend_response(gsm_recv_t* rcv, uint8_t* is_ok, uint16_t* is_error) {
- if (gsm.msg->msg.conn_send.wait_send_ok_err) {
- if (GSM_CHARISNUM(rcv->data[0]) && rcv->data[1] == ',') {
- uint8_t num = GSM_CHARTONUM(rcv->data[0]);
- if (!strncmp(&rcv->data[3], "SEND OK" CRLF, 7 + CRLF_LEN)) {
- gsm.msg->msg.conn_send.wait_send_ok_err = 0;
- *is_ok = gsmi_tcpip_process_data_sent(1); /* Process as data were sent */
- if (*is_ok && gsm.msg->msg.conn_send.conn->status.f.active) {
- CONN_SEND_DATA_SEND_EVT(gsm.msg, gsmOK);
- }
- } else if (!strncmp(&rcv->data[3], "SEND FAIL" CRLF, 9 + CRLF_LEN)) {
- gsm.msg->msg.conn_send.wait_send_ok_err = 0;
- *is_error = gsmi_tcpip_process_data_sent(0);/* Data were not sent due to SEND FAIL or command didn't even start */
- if (*is_error && gsm.msg->msg.conn_send.conn->status.f.active) {
- CONN_SEND_DATA_SEND_EVT(gsm.msg, gsmERR);
- }
- }
- GSM_UNUSED(num);
- }
- /* Check for an error or if connection closed in the meantime */
- } else if (*is_error) {
- CONN_SEND_DATA_SEND_EVT(gsm.msg, gsmERR);
- }
-}
-
-/**
- * \brief Send error event to application layer
- * \param[in] msg: Message from user with connection start
- */
-static void
-gsmi_send_conn_error_cb(gsm_msg_t* msg, gsmr_t error) {
- gsm.evt.type = GSM_EVT_CONN_ERROR; /* Connection error */
- gsm.evt.evt.conn_error.host = gsm.msg->msg.conn_start.host;
- gsm.evt.evt.conn_error.port = gsm.msg->msg.conn_start.port;
- gsm.evt.evt.conn_error.type = gsm.msg->msg.conn_start.type;
- gsm.evt.evt.conn_error.arg = gsm.msg->msg.conn_start.arg;
- gsm.evt.evt.conn_error.err = error;
-
- /* Call callback specified by user on connection startup */
- gsm.msg->msg.conn_start.evt_func(&gsm.evt);
- GSM_UNUSED(msg);
-}
-
-/**
- * \brief Checks if connection pointer has valid address
- * \param[in] conn: Address to check if valid connection ptr
- * \return 1 on success, 0 otherwise
- */
-uint8_t
-gsmi_is_valid_conn_ptr(gsm_conn_p conn) {
- uint8_t i = 0;
- for (i = 0; i < GSM_ARRAYSIZE(gsm.m.conns); i++) {
- if (conn == &gsm.m.conns[i]) {
- return 1;
- }
- }
- return 0;
-}
-
-/**
- * \brief Connection close event detected, process with callback to user
- * \param[in] conn_num: Connection number
- * \param[in] forced: Set to `1` if close forced by command, `0` otherwise
- * \return `1` on success, `0` otherwise
- */
-uint8_t
-gsmi_conn_closed_process(uint8_t conn_num, uint8_t forced) {
- gsm_conn_t* conn = &gsm.m.conns[conn_num];
-
- conn->status.f.active = 0;
-
- /* Check if write buffer is set */
- if (conn->buff.buff != NULL) {
- GSM_DEBUGF(GSM_CFG_DBG_CONN | GSM_DBG_TYPE_TRACE,
- "[CONN] Free write buffer: %p\r\n", conn->buff.buff);
- gsm_mem_free_s((void **)&conn->buff.buff);
- }
-
- /* Send event */
- gsm.evt.type = GSM_EVT_CONN_CLOSE;
- gsm.evt.evt.conn_active_close.conn = conn;
- gsm.evt.evt.conn_active_close.forced = forced;
- gsm.evt.evt.conn_active_close.res = gsmOK;
- gsm.evt.evt.conn_active_close.client = conn->status.f.client;
- gsmi_send_conn_cb(conn, NULL);
-
- return 1;
-}
-
-#endif /* GSM_CFG_CONN || __DOXYGEN__ */
-
-/**
- * \brief Process received string from GSM
- * \param[in] recv: Pointer to \ref gsm_rect_t structure with input string
- */
-static void
-gsmi_parse_received(gsm_recv_t* rcv) {
- uint8_t is_ok = 0;
- uint16_t is_error = 0;
-
- /* Try to remove non-parsable strings */
- if (rcv->len == 2 && rcv->data[0] == '\r' && rcv->data[1] == '\n') {
- return;
- }
-
- /* Check OK response */
- is_ok = rcv->len == (2 + CRLF_LEN) && !strcmp(rcv->data, "OK" CRLF); /* Check if received string is OK */
- if (!is_ok) { /* Check for SHUT OK string */
- is_ok = rcv->len == (7 + CRLF_LEN) && !strcmp(rcv->data, "SEND OK" CRLF);
- }
-
- /* Check error response */
- if (!is_ok) { /* If still not ok, check if error? */
- is_error = rcv->data[0] == '+' && !strncmp(rcv->data, "+CME ERROR", 10); /* First check +CME coded errors */
- if (!is_error) { /* Check basic error aswell */
- is_error = rcv->data[0] == '+' && !strncmp(rcv->data, "+CMS ERROR", 10); /* First check +CME coded errors */
- if (!is_error) {
- is_error = !strcmp(rcv->data, "ERROR" CRLF) || !strcmp(rcv->data, "FAIL" CRLF);
- }
- }
- }
-
- /* Scan received strings which start with '+' */
- if (rcv->data[0] == '+') {
- if (!strncmp(rcv->data, "+CSQ", 4)) {
- gsmi_parse_csq(rcv->data); /* Parse +CSQ response */
-#if GSM_CFG_NETWORK
- } else if (!strncmp(rcv->data, "+PDP: DEACT", 11)) {
- /* PDP has been deactivated */
- gsm_network_check_status(NULL, NULL, 0);/* Update status */
-#endif /* GSM_CFG_NETWORK */
-#if GSM_CFG_CONN
- } else if (!strncmp(rcv->data, "+RECEIVE", 8)) {
- gsmi_parse_ipd(rcv->data); /* Parse IPD */
-#endif /* GSM_CFG_CONN */
- } else if (!strncmp(rcv->data, "+CREG", 5)) { /* Check for +CREG indication */
- gsmi_parse_creg(rcv->data, GSM_U8(CMD_IS_CUR(GSM_CMD_CREG_GET))); /* Parse +CREG response */
- } else if (!strncmp(rcv->data, "+CPIN", 5)) { /* Check for +CPIN indication for SIM */
- gsmi_parse_cpin(rcv->data, 1 /* !CMD_IS_DEF(GSM_CMD_CPIN_SET) */); /* Parse +CPIN response */
- } else if (CMD_IS_CUR(GSM_CMD_COPS_GET) && !strncmp(rcv->data, "+COPS", 5)) {
- gsmi_parse_cops(rcv->data); /* Parse current +COPS */
-#if GSM_CFG_SMS
- } else if (CMD_IS_CUR(GSM_CMD_CMGS) && !strncmp(rcv->data, "+CMGS", 5)) {
- gsmi_parse_cmgs(rcv->data, &gsm.msg->msg.sms_send.pos); /* Parse +CMGS response */
- } else if (CMD_IS_CUR(GSM_CMD_CMGR) && !strncmp(rcv->data, "+CMGR", 5)) {
- if (gsmi_parse_cmgr(rcv->data)) { /* Parse +CMGR response */
- gsm.msg->msg.sms_read.read = 2; /* Set read flag and process the data */
- } else {
- gsm.msg->msg.sms_read.read = 1; /* Read but ignore data */
- }
- } else if (CMD_IS_CUR(GSM_CMD_CMGL) && !strncmp(rcv->data, "+CMGL", 5)) {
- if (gsmi_parse_cmgl(rcv->data)) { /* Parse +CMGL response */
- gsm.msg->msg.sms_list.read = 2; /* Set read flag and process the data */
- } else {
- gsm.msg->msg.sms_list.read = 1; /* Read but ignore data */
- }
- } else if (!strncmp(rcv->data, "+CMTI", 5)) {
- gsmi_parse_cmti(rcv->data, 1); /* Parse +CMTI response with received SMS */
- } else if (CMD_IS_CUR(GSM_CMD_CPMS_GET_OPT) && !strncmp(rcv->data, "+CPMS", 5)) {
- gsmi_parse_cpms(rcv->data, 0); /* Parse +CPMS with SMS memories info */
- } else if (CMD_IS_CUR(GSM_CMD_CPMS_GET) && !strncmp(rcv->data, "+CPMS", 5)) {
- gsmi_parse_cpms(rcv->data, 1); /* Parse +CPMS with SMS memories info */
- } else if (CMD_IS_CUR(GSM_CMD_CPMS_SET) && !strncmp(rcv->data, "+CPMS", 5)) {
- gsmi_parse_cpms(rcv->data, 2); /* Parse +CPMS with SMS memories info */
-#endif /* GSM_CFG_SMS */
-#if GSM_CFG_CALL
- } else if (!strncmp(rcv->data, "+CLCC", 5)) {
- gsmi_parse_clcc(rcv->data, 1); /* Parse +CLCC response with call info change */
-#endif /* GSM_CFG_CALL */
-#if GSM_CFG_PHONEBOOK
- } else if (CMD_IS_CUR(GSM_CMD_CPBS_GET_OPT) && !strncmp(rcv->data, "+CPBS", 5)) {
- gsmi_parse_cpbs(rcv->data, 0); /* Parse +CPBS response */
- } else if (CMD_IS_CUR(GSM_CMD_CPBS_GET) && !strncmp(rcv->data, "+CPBS", 5)) {
- gsmi_parse_cpbs(rcv->data, 1); /* Parse +CPBS response */
- } else if (CMD_IS_CUR(GSM_CMD_CPBS_SET) && !strncmp(rcv->data, "+CPBS", 5)) {
- gsmi_parse_cpbs(rcv->data, 2); /* Parse +CPBS response */
- } else if (CMD_IS_CUR(GSM_CMD_CPBR) && !strncmp(rcv->data, "+CPBR", 5)) {
- gsmi_parse_cpbr(rcv->data); /* Parse +CPBR statement */
- } else if (CMD_IS_CUR(GSM_CMD_CPBF) && !strncmp(rcv->data, "+CPBF", 5)) {
- gsmi_parse_cpbf(rcv->data); /* Parse +CPBR statement */
-#endif /* GSM_CFG_PHONEBOOK */
- }
-
- /* Messages not starting with '+' sign */
- } else {
- if (rcv->data[0] == 'S' && !strncmp(rcv->data, "SHUT OK" CRLF, 7 + CRLF_LEN)) {
- is_ok = 1;
-#if GSM_CFG_CONN
- } else if (GSM_CHARISNUM(rcv->data[0]) && rcv->data[1] == ',' && rcv->data[2] == ' '
- && (!strncmp(&rcv->data[3], "CLOSE OK" CRLF, 8 + CRLF_LEN) || !strncmp(&rcv->data[3], "CLOSED" CRLF, 6 + CRLF_LEN))) {
- uint8_t forced = 0, num;
-
- num = GSM_CHARTONUM(rcv->data[0]); /* Get connection number */
- if (CMD_IS_CUR(GSM_CMD_CIPCLOSE) && gsm.msg->msg.conn_close.conn->num == num) {
- forced = 1;
- is_ok = 1; /* If forced and connection is closed, command is OK */
- }
-
- /* Manually stop send command? */
- if (CMD_IS_CUR(GSM_CMD_CIPSEND) && gsm.msg->msg.conn_send.conn->num == num) {
- /*
- * If active command is CIPSEND and CLOSED event received,
- * manually set error and process usual "ERROR" event on senddata
- */
- is_error = 1; /* This is an error in response */
- gsmi_process_cipsend_response(rcv, &is_ok, &is_error);
- }
- gsmi_conn_closed_process(num, forced); /* Connection closed, process */
-#endif /* GSM_CFG_CONN */
-#if GSM_CFG_CALL
- } else if (rcv->data[0] == 'C' && !strncmp(rcv->data, "Call Ready" CRLF, 10 + CRLF_LEN)) {
- gsm.m.call.ready = 1;
- gsmi_send_cb(GSM_EVT_CALL_READY); /* Send CALL ready event */
- } else if (rcv->data[0] == 'R' && !strncmp(rcv->data, "RING" CRLF, 4 + CRLF_LEN)) {
- gsmi_send_cb(GSM_EVT_CALL_RING); /* Send call ring */
- } else if (rcv->data[0] == 'N' && !strncmp(rcv->data, "NO CARRIER" CRLF, 10 + CRLF_LEN)) {
- gsmi_send_cb(GSM_EVT_CALL_NO_CARRIER); /* Send call no carrier event */
- } else if (rcv->data[0] == 'B' && !strncmp(rcv->data, "BUSY" CRLF, 4 + CRLF_LEN)) {
- gsmi_send_cb(GSM_EVT_CALL_BUSY); /* Send call busy message */
-#endif /* GSM_CFG_CALL */
-#if GSM_CFG_SMS
- } else if (rcv->data[0] == 'S' && !strncmp(rcv->data, "SMS Ready" CRLF, 9 + CRLF_LEN)) {
- gsm.m.sms.ready = 1; /* SMS ready flag */
- gsmi_send_cb(GSM_EVT_SMS_READY); /* Send SMS ready event */
-#endif /* GSM_CFG_SMS */
- } else if ((CMD_IS_CUR(GSM_CMD_CGMI_GET) || CMD_IS_CUR(GSM_CMD_CGMM_GET) || CMD_IS_CUR(GSM_CMD_CGSN_GET) || CMD_IS_CUR(GSM_CMD_CGMR_GET))
- && !is_ok && !is_error && strncmp(rcv->data, "AT+", 3)) {
- const char* tmp = rcv->data;
- size_t tocopy;
- if (CMD_IS_CUR(GSM_CMD_CGMI_GET)) { /* Check device manufacturer */
- gsmi_parse_string(&tmp, gsm.m.model_manufacturer, sizeof(gsm.m.model_manufacturer), 1);
- if (CMD_IS_DEF(GSM_CMD_CGMI_GET)) {
- tocopy = GSM_MIN(sizeof(gsm.m.model_manufacturer), gsm.msg->msg.device_info.len);
- GSM_MEMCPY(gsm.msg->msg.device_info.str, gsm.m.model_manufacturer, tocopy);
- gsm.msg->msg.device_info.str[tocopy - 1] = 0;
- }
- } else if (CMD_IS_CUR(GSM_CMD_CGMM_GET)) { /* Check device model number */
- gsmi_parse_string(&tmp, gsm.m.model_number, sizeof(gsm.m.model_number), 1);
- if (CMD_IS_DEF(GSM_CMD_CGMM_GET)) {
- tocopy = GSM_MIN(sizeof(gsm.m.model_number), gsm.msg->msg.device_info.len);
- GSM_MEMCPY(gsm.msg->msg.device_info.str, gsm.m.model_number, tocopy);
- gsm.msg->msg.device_info.str[tocopy - 1] = 0;
- }
- for (size_t i = 0; i < gsm_dev_model_map_size; i++) {
- if (strstr(gsm.m.model_number, gsm_dev_model_map[i].id_str) != NULL) {
- gsm.m.model = gsm_dev_model_map[i].model;
- break;
- }
- }
- } else if (CMD_IS_CUR(GSM_CMD_CGSN_GET)) { /* Check device serial number */
- gsmi_parse_string(&tmp, gsm.m.model_serial_number, sizeof(gsm.m.model_serial_number), 1);
- if (CMD_IS_DEF(GSM_CMD_CGSN_GET)) {
- tocopy = GSM_MIN(sizeof(gsm.m.model_serial_number), gsm.msg->msg.device_info.len);
- GSM_MEMCPY(gsm.msg->msg.device_info.str, gsm.m.model_serial_number, tocopy);
- gsm.msg->msg.device_info.str[tocopy - 1] = 0;
- }
- } else if (CMD_IS_CUR(GSM_CMD_CGMR_GET)) { /* Check device revision */
- if (!strncmp(tmp, "Revision:", 9)) {
- tmp += 9;
- }
- gsmi_parse_string(&tmp, gsm.m.model_revision, sizeof(gsm.m.model_revision), 1);
- if (CMD_IS_DEF(GSM_CMD_CGMR_GET)) {
- tocopy = GSM_MIN(sizeof(gsm.m.model_revision), gsm.msg->msg.device_info.len);
- GSM_MEMCPY(gsm.msg->msg.device_info.str, gsm.m.model_revision, tocopy);
- gsm.msg->msg.device_info.str[tocopy - 1] = 0;
- }
- }
- } else if (CMD_IS_CUR(GSM_CMD_CIFSR) && GSM_CHARISNUM(rcv->data[0])) {
- const char* tmp = rcv->data;
- gsmi_parse_ip(&tmp, &gsm.m.network.ip_addr);/* Parse IP address */
-
- is_ok = 1; /* Manually set OK flag as we don't expect OK in CIFSR command */
- }
- }
-
- /* Check general responses for active commands */
- if (gsm.msg != NULL) {
- if (0) {
-#if GSM_CFG_SMS
- } else if (CMD_IS_CUR(GSM_CMD_CMGS) && is_ok) {
- /* At this point we have to wait for "> " to send data */
-#endif /* GSM_CFG_SMS */
-#if GSM_CFG_CONN
- } else if (CMD_IS_CUR(GSM_CMD_CIPSTATUS)) {
- /* For CIPSTATUS, OK is returned before important data */
- if (is_ok) {
- is_ok = 0;
- }
- /* Check if connection data received */
- if (rcv->len > 3) {
- uint8_t continueScan, processed = 0;
- if (rcv->data[0] == 'C' && rcv->data[1] == ':' && rcv->data[2] == ' ') {
- processed = 1;
- gsmi_parse_cipstatus_conn(rcv->data, 1, &continueScan);
-
- if (gsm.m.active_conns_cur_parse_num == (GSM_CFG_MAX_CONNS - 1)) {
- is_ok = 1;
- }
- } else if (!strncmp(rcv->data, "STATE:", 6)) {
- processed = 1;
- gsmi_parse_cipstatus_conn(rcv->data, 0, &continueScan);
- }
-
- /* Check if we shall stop processing at this stage */
- if (processed && !continueScan) {
- is_ok = 1;
- }
- }
- } else if (CMD_IS_CUR(GSM_CMD_CIPSTART)) {
- /* For CIPSTART, OK is returned before important data */
- if (is_ok) {
- is_ok = 0;
- }
-
- /* Wait here for CONNECT status before we cancel connection */
- if (GSM_CHARISNUM(rcv->data[0])
- && rcv->data[1] == ',' && rcv->data[2] == ' ') {
- uint8_t num = GSM_CHARTONUM(rcv->data[0]);
- if (num < GSM_CFG_MAX_CONNS) {
- uint8_t id;
- gsm_conn_t* conn = &gsm.m.conns[num]; /* Get connection handle */
-
- if (!strncmp(&rcv->data[3], "CONNECT OK" CRLF, 10 + CRLF_LEN)) {
- id = conn->val_id;
- GSM_MEMSET(conn, 0x00, sizeof(*conn)); /* Reset connection parameters */
- conn->num = num;
- conn->status.f.active = 1;
- conn->val_id = ++id; /* Set new validation ID */
-
- /* Set connection parameters */
- conn->status.f.client = 1;
- conn->evt_func = gsm.msg->msg.conn_start.evt_func;
- conn->arg = gsm.msg->msg.conn_start.arg;
-
- /* Set status */
- gsm.msg->msg.conn_start.conn_res = GSM_CONN_CONNECT_OK;
- is_ok = 1;
- } else if (!strncmp(&rcv->data[3], "CONNECT FAIL" CRLF, 12 + CRLF_LEN)) {
- gsm.msg->msg.conn_start.conn_res = GSM_CONN_CONNECT_ERROR;
- is_error = 1;
- } else if (!strncmp(&rcv->data[3], "ALREADY CONNECT" CRLF, 15 + CRLF_LEN)) {
- gsm.msg->msg.conn_start.conn_res = GSM_CONN_CONNECT_ALREADY;
- is_error = 1;
- }
- }
- }
- } else if (CMD_IS_CUR(GSM_CMD_CIPSEND)) {
- if (is_ok) {
- is_ok = 0;
- }
- gsmi_process_cipsend_response(rcv, &is_ok, &is_error);
-#endif /* GSM_CFG_CONN */
-#if GSM_CFG_USSD
- } else if (CMD_IS_CUR(GSM_CMD_CUSD)) {
- /* OK is returned before +CUSD */
- /* Command is not finished yet, unless it was an ERROR */
- if (is_ok) {
- is_ok = 0;
- }
-
- /* Check for manual CUSTOM OK message */
- if (!strcmp(rcv->data, "CUSTOM_OK\r\n")) {
- is_ok = 1;
- }
-#endif /* GSM_CFG_USSD */
- }
- }
-
- /*
- * In case of any of these events, simply release semaphore
- * and proceed with next command
- */
- if (is_ok || is_error) {
- gsmr_t res = gsmOK;
- if (gsm.msg != NULL) { /* Do we have active message? */
- res = gsmi_process_sub_cmd(gsm.msg, &is_ok, &is_error);
- if (res != gsmCONT) { /* Shall we continue with next subcommand under this one? */
- if (is_ok) { /* Check OK status */
- res = gsm.msg->res = gsmOK;
- } else { /* Or error status */
- res = gsm.msg->res = res; /* Set the error status */
- }
- } else {
- gsm.msg->i++; /* Number of continue calls */
- }
-
- /*
- * When the command is finished,
- * release synchronization semaphore
- * from user thread and start with next command
- */
- if (res != gsmCONT) { /* Do we have to continue to wait for command? */
- gsm_sys_sem_release(&gsm.sem_sync); /* Release semaphore */
- }
- }
- }
-}
-
-#if !GSM_CFG_INPUT_USE_PROCESS || __DOXYGEN__
-/**
- * \brief Process data from input buffer
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
- */
-gsmr_t
-gsmi_process_buffer(void) {
- void* data;
- size_t len;
-
- do {
- /*
- * Get length of linear memory in buffer
- * we can process directly as memory
- */
- len = gsm_buff_get_linear_block_read_length(&gsm.buff);
- if (len > 0) {
- /*
- * Get memory address of first element
- * in linear block of data to process
- */
- data = gsm_buff_get_linear_block_read_address(&gsm.buff);
-
- /* Process actual received data */
- gsmi_process(data, len);
-
- /*
- * Once data is processed, simply skip
- * the buffer memory and start over
- */
- gsm_buff_skip(&gsm.buff, len);
- }
- } while (len);
- return gsmOK;
-}
-#endif /* !GSM_CFG_INPUT_USE_PROCESS || __DOXYGEN__ */
-
-/**
- * \brief Process input data received from GSM device
- * \param[in] data: Pointer to data to process
- * \param[in] data_len: Length of data to process in units of bytes
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
- */
-gsmr_t
-gsmi_process(const void* data, size_t data_len) {
- uint8_t ch;
- const uint8_t* d = data;
- size_t d_len = data_len;
- static uint8_t ch_prev1, ch_prev2;
- static gsm_unicode_t unicode;
-
- /* Check status if device is available */
- if (!gsm.status.f.dev_present) {
- return gsmERRNODEVICE;
- }
-
- while (d_len) { /* Read entire set of characters from buffer */
- ch = *d++; /* Get next character */
- d_len--; /* Decrease remaining length */
-
- if (0) {
-#if GSM_CFG_CONN
- } else if (gsm.m.ipd.read) { /* Read connection data */
- size_t len;
-
- if (gsm.m.ipd.buff != NULL) { /* Do we have active buffer? */
- gsm.m.ipd.buff->payload[gsm.m.ipd.buff_ptr] = ch; /* Save data character */
- }
- gsm.m.ipd.buff_ptr++;
- gsm.m.ipd.rem_len--;
-
- /* Try to read more data directly from buffer */
- len = GSM_MIN(d_len, GSM_MIN(gsm.m.ipd.rem_len, gsm.m.ipd.buff != NULL ? (gsm.m.ipd.buff->len - gsm.m.ipd.buff_ptr) : gsm.m.ipd.rem_len));
- GSM_DEBUGF(GSM_CFG_DBG_IPD | GSM_DBG_TYPE_TRACE,
- "[IPD] New length to read: %d bytes\r\n", (int)len);
- if (len > 0) {
- if (gsm.m.ipd.buff != NULL) { /* Is buffer valid? */
- GSM_MEMCPY(&gsm.m.ipd.buff->payload[gsm.m.ipd.buff_ptr], d, len);
- GSM_DEBUGF(GSM_CFG_DBG_IPD | GSM_DBG_TYPE_TRACE,
- "[IPD] Bytes read: %d\r\n", (int)len);
- } else { /* Simply skip the data in buffer */
- GSM_DEBUGF(GSM_CFG_DBG_IPD | GSM_DBG_TYPE_TRACE,
- "[IPD] Bytes skipped: %d\r\n", (int)len);
- }
- d_len -= len; /* Decrease effective length */
- d += len; /* Skip remaining length */
- gsm.m.ipd.buff_ptr += len; /* Forward buffer pointer */
- gsm.m.ipd.rem_len -= len; /* Decrease remaining length */
- }
-
- /* Did we reach end of buffer or no more data? */
- if (gsm.m.ipd.rem_len == 0 || (gsm.m.ipd.buff != NULL && gsm.m.ipd.buff_ptr == gsm.m.ipd.buff->len)) {
- gsmr_t res = gsmOK;
-
- /* Call user callback function with received data */
- if (gsm.m.ipd.buff != NULL) { /* Do we have valid buffer? */
- gsm.m.ipd.conn->total_recved += gsm.m.ipd.buff->tot_len;/* Increase number of bytes received */
-
- /*
- * Send data buffer to upper layer
- *
- * From this moment, user is responsible for packet
- * buffer and must free it manually
- */
- gsm.evt.type = GSM_EVT_CONN_RECV;
- gsm.evt.evt.conn_data_recv.buff = gsm.m.ipd.buff;
- gsm.evt.evt.conn_data_recv.conn = gsm.m.ipd.conn;
- res = gsmi_send_conn_cb(gsm.m.ipd.conn, NULL);
-
- gsm_pbuf_free(gsm.m.ipd.buff); /* Free packet buffer at this point */
- GSM_DEBUGF(GSM_CFG_DBG_IPD | GSM_DBG_TYPE_TRACE,
- "[IPD] Free packet buffer\r\n");
- if (res == gsmOKIGNOREMORE) { /* We should ignore more data */
- GSM_DEBUGF(GSM_CFG_DBG_IPD | GSM_DBG_TYPE_TRACE,
- "[IPD] Ignoring more data from this IPD if available\r\n");
- gsm.m.ipd.buff = NULL; /* Set to NULL to ignore more data if possibly available */
- }
-
- /*
- * Create new data packet if case if:
- *
- * - Previous one was successful and more data to read and
- * - Connection is not in closing state
- */
- if (gsm.m.ipd.buff != NULL && gsm.m.ipd.rem_len > 0 && !gsm.m.ipd.conn->status.f.in_closing) {
- size_t new_len = GSM_MIN(gsm.m.ipd.rem_len, GSM_CFG_IPD_MAX_BUFF_SIZE); /* Calculate new buffer length */
-
- GSM_DEBUGF(GSM_CFG_DBG_IPD | GSM_DBG_TYPE_TRACE,
- "[IPD] Allocating new packet buffer of size: %d bytes\r\n", (int)new_len);
- gsm.m.ipd.buff = gsm_pbuf_new(new_len); /* Allocate new packet buffer */
-
- GSM_DEBUGW(GSM_CFG_DBG_IPD | GSM_DBG_TYPE_TRACE | GSM_DBG_LVL_WARNING,
- gsm.m.ipd.buff == NULL, "[IPD] Buffer allocation failed for %d bytes\r\n", (int)new_len);
- } else {
- gsm.m.ipd.buff = NULL; /* Reset it */
- }
- }
- if (gsm.m.ipd.rem_len == 0) { /* Check if we read everything */
- gsm.m.ipd.buff = NULL; /* Reset buffer pointer */
- gsm.m.ipd.read = 0; /* Stop reading data */
- }
- gsm.m.ipd.buff_ptr = 0; /* Reset input buffer pointer */
- }
-#endif /* GSM_CFG_CONN */
- /*
- * Check if operators scan command is active
- * and if we are ready to read the incoming data
- */
- } else if (CMD_IS_CUR(GSM_CMD_COPS_GET_OPT) && gsm.msg->msg.cops_scan.read) {
- if (ch == '\n') {
- gsm.msg->msg.cops_scan.read = 0;
- } else {
- gsmi_parse_cops_scan(ch, 0); /* Parse character by character */
- }
-#if GSM_CFG_SMS
- } else if (CMD_IS_CUR(GSM_CMD_CMGR) && gsm.msg->msg.sms_read.read) {
- gsm_sms_entry_t* e = gsm.msg->msg.sms_read.entry;
- if (gsm.msg->msg.sms_read.read == 2) { /* Read only if set to 2 */
- if (e != NULL) { /* Check if valid entry */
- if (e->length < (sizeof(e->data) - 1)) {
- e->data[e->length++] = ch;
- }
- } else {
- gsm.msg->msg.sms_read.read = 1; /* Read but ignore data */
- }
- }
- if (ch == '\n' && ch_prev1 == '\r') {
- if (gsm.msg->msg.sms_read.read == 2) {
-
- }
- gsm.msg->msg.sms_read.read = 0;
- }
- } else if (CMD_IS_CUR(GSM_CMD_CMGL) && gsm.msg->msg.sms_list.read) {
- if (gsm.msg->msg.sms_list.read == 2) {
- gsm_sms_entry_t* e = &gsm.msg->msg.sms_list.entries[gsm.msg->msg.sms_list.ei];
- if (e->length < (sizeof(e->data) - 1)) {
- e->data[e->length++] = ch;
- }
- }
- if (ch == '\n' && ch_prev1 == '\r') {
- if (gsm.msg->msg.sms_list.read == 2) {
- gsm.msg->msg.sms_list.ei++; /* Go to next entry */
- if (gsm.msg->msg.sms_list.er != NULL) { /* Check and update user variable */
- *gsm.msg->msg.sms_list.er = gsm.msg->msg.sms_list.ei;
- }
- }
- gsm.msg->msg.sms_list.read = 0;
- }
-#endif /* GSM_CFG_SMS */
-#if GSM_CFG_USSD
- } else if (CMD_IS_CUR(GSM_CMD_CUSD) && gsm.msg->msg.ussd.read) {
- if (ch == '"') {
- gsm.msg->msg.ussd.resp[gsm.msg->msg.ussd.resp_write_ptr] = 0;
- gsm.msg->msg.ussd.quote_det = !gsm.msg->msg.ussd.quote_det;
- } else if (gsm.msg->msg.ussd.quote_det) {
- if (gsm.msg->msg.ussd.resp_write_ptr < gsm.msg->msg.ussd.resp_len) {
- gsm.msg->msg.ussd.resp[gsm.msg->msg.ussd.resp_write_ptr++] = ch;
- gsm.msg->msg.ussd.resp[gsm.msg->msg.ussd.resp_write_ptr] = 0;
- }
- } else if (ch == '\n' && ch_prev1 == '\r') {
- /* End of reading, command finished! */
- /* Return OK at this point! */
- strcpy(recv_buff.data, "CUSTOM_OK\r\n");
- recv_buff.len = strlen(recv_buff.data);
- gsmi_parse_received(&recv_buff);
- }
-#endif /* GSM_CFG_USSD */
- /*
- * We are in command mode where we have to process byte by byte
- * Simply check for ASCII and unicode format and process data accordingly
- */
- } else {
- gsmr_t res = gsmERR;
- if (GSM_ISVALIDASCII(ch)) { /* Manually check if valid ASCII character */
- res = gsmOK;
- unicode.t = 1; /* Manually set total to 1 */
- unicode.r = 0; /* Reset remaining bytes */
- } else if (ch >= 0x80) { /* Process only if more than ASCII can hold */
- res = gsmi_unicode_decode(&unicode, ch); /* Try to decode unicode format */
- }
-
- if (res == gsmERR) { /* In case of an ERROR */
- unicode.r = 0;
- }
- if (res == gsmOK) { /* Can we process the character(s) */
- if (unicode.t == 1) { /* Totally 1 character? */
- switch (ch) {
- case '\n':
- RECV_ADD(ch); /* Add character to input buffer */
- gsmi_parse_received(&recv_buff); /* Parse received string */
- RECV_RESET(); /* Reset received string */
- break;
- default:
- RECV_ADD(ch); /* Any ASCII valid character */
- break;
- }
-
-#if GSM_CFG_CONN
- /* Check if we have to read data */
- if (ch == '\n' && gsm.m.ipd.read) {
- size_t len;
- GSM_DEBUGF(GSM_CFG_DBG_IPD | GSM_DBG_TYPE_TRACE,
- "[IPD] Data on connection %d with total size %d byte(s)\r\n",
- (int)gsm.m.ipd.conn->num, (int)gsm.m.ipd.tot_len);
-
- len = GSM_MIN(gsm.m.ipd.rem_len, GSM_CFG_IPD_MAX_BUFF_SIZE);
-
- /*
- * Read received data in case of:
- *
- * - Connection is active and
- * - Connection is not in closing mode
- */
- if (gsm.m.ipd.conn->status.f.active && !gsm.m.ipd.conn->status.f.in_closing) {
- gsm.m.ipd.buff = gsm_pbuf_new(len); /* Allocate new packet buffer */
- GSM_DEBUGW(GSM_CFG_DBG_IPD | GSM_DBG_TYPE_TRACE | GSM_DBG_LVL_WARNING, gsm.m.ipd.buff == NULL,
- "[IPD] Buffer allocation failed for %d byte(s)\r\n", (int)len);
- } else {
- gsm.m.ipd.buff = NULL; /* Ignore reading on closed connection */
- GSM_DEBUGF(GSM_CFG_DBG_IPD | GSM_DBG_TYPE_TRACE,
- "[IPD] Connection %d closed or in closing, skipping %d byte(s)\r\n",
- (int)gsm.m.ipd.conn->num, (int)len);
- }
- gsm.m.ipd.conn->status.f.data_received = 1; /* We have first received data */
-
- gsm.m.ipd.buff_ptr = 0; /* Reset buffer write pointer */
- }
-#endif /* GSM_CFG_CONN */
-
- /*
- * Do we have a special sequence "> "?
- *
- * Check if any command active which may expect that kind of response
- */
- if (ch_prev2 == '\n' && ch_prev1 == '>' && ch == ' ') {
- if (0) {
-#if GSM_CFG_CONN
- } else if (CMD_IS_CUR(GSM_CMD_CIPSEND)) {
- RECV_RESET(); /* Reset received object */
-
- /* Now actually send the data prepared before */
- AT_PORT_SEND_WITH_FLUSH(&gsm.msg->msg.conn_send.data[gsm.msg->msg.conn_send.ptr], gsm.msg->msg.conn_send.sent);
- gsm.msg->msg.conn_send.wait_send_ok_err = 1; /* Now we are waiting for "SEND OK" or "SEND ERROR" */
-#endif /* GSM_CFG_CONN */
-#if GSM_CFG_SMS
- } else if (CMD_IS_CUR(GSM_CMD_CMGS)) { /* Send SMS? */
- AT_PORT_SEND(gsm.msg->msg.sms_send.text, strlen(gsm.msg->msg.sms_send.text));
- AT_PORT_SEND_CTRL_Z();
- AT_PORT_SEND_FLUSH();
-#endif /* GSM_CFG_SMS */
- }
- } else if (CMD_IS_CUR(GSM_CMD_COPS_GET_OPT)) {
- if (RECV_LEN() > 5 && !strncmp(recv_buff.data, "+COPS:", 6)) {
- RECV_RESET(); /* Reset incoming buffer */
- gsmi_parse_cops_scan(0, 1); /* Reset parser state */
- gsm.msg->msg.cops_scan.read = 1; /* Start reading incoming bytes */
- }
-#if GSM_CFG_USSD
- } else if (CMD_IS_CUR(GSM_CMD_CUSD)) {
- if (RECV_LEN() > 5 && !strncmp(recv_buff.data, "+CUSD:", 6)) {
- RECV_RESET(); /* Reset incoming buffer */
- gsm.msg->msg.ussd.read = 1; /* Start reading incoming bytes */
- }
-#endif /* GSM_CFG_USSD */
- }
- } else { /* We have sequence of unicode characters */
- /*
- * Unicode sequence characters are not "meta" characters
- * so it is safe to just add them to receive array without checking
- * what are the actual values
- */
- for (uint8_t i = 0; i < unicode.t; i++) {
- RECV_ADD(unicode.ch[i]);/* Add character to receive array */
- }
- }
- } else if (res != gsmINPROG) { /* Not in progress? */
- RECV_RESET(); /* Invalid character in sequence */
- }
- }
-
- ch_prev2 = ch_prev1; /* Save previous character as previous previous */
- ch_prev1 = ch; /* Set current as previous */
- }
- return gsmOK;
-}
-
-/* Temporary macros, only available for inside gsmi_process_sub_cmd function */
-/* Set new command, but first check for error on previous */
-#define SET_NEW_CMD_CHECK_ERROR(new_cmd) do { \
- if (!*(is_error)) { \
- n_cmd = (new_cmd); \
- } \
-} while (0)
-
-/* Set new command, ignore result of previous */
-#define SET_NEW_CMD(new_cmd) do { \
- n_cmd = (new_cmd); \
-} while (0)
-
-/**
- * \brief Process current command with known execution status and start another if necessary
- * \param[in] msg: Pointer to current message
- * \param[in] is_ok: pointer to status whether last command result was OK
- * \param[in] is_error: Pointer to status whether last command result was ERROR
- * \return \ref gsmCONT if you sent more data and we need to process more data, \ref gsmOK on success, or \ref gsmERR on error
- */
-static gsmr_t
-gsmi_process_sub_cmd(gsm_msg_t* msg, uint8_t* is_ok, uint16_t* is_error) {
- gsm_cmd_t n_cmd = GSM_CMD_IDLE;
- if (CMD_IS_DEF(GSM_CMD_RESET)) {
- switch (CMD_GET_CUR()) { /* Check current command */
- case GSM_CMD_RESET: {
- gsmi_reset_everything(1); /* Reset everything */
- SET_NEW_CMD(GSM_CFG_AT_ECHO ? GSM_CMD_ATE1 : GSM_CMD_ATE0); /* Set ECHO mode */
- gsm_delay(5000); /* Delay for some time before we can continue after reset */
- break;
- }
- case GSM_CMD_ATE0:
- case GSM_CMD_ATE1: SET_NEW_CMD(GSM_CMD_CFUN_SET); break; /* Set full functionality */
- case GSM_CMD_CFUN_SET: SET_NEW_CMD(GSM_CMD_CMEE_SET); break; /* Set detailed error reporting */
- case GSM_CMD_CMEE_SET: SET_NEW_CMD(GSM_CMD_CGMI_GET); break; /* Get manufacturer */
- case GSM_CMD_CGMI_GET: SET_NEW_CMD(GSM_CMD_CGMM_GET); break; /* Get model */
- case GSM_CMD_CGMM_GET: SET_NEW_CMD(GSM_CMD_CGSN_GET); break; /* Get product serial number */
- case GSM_CMD_CGSN_GET: SET_NEW_CMD(GSM_CMD_CGMR_GET); break; /* Get product revision */
- case GSM_CMD_CGMR_GET: {
- /*
- * At this point we have modem info.
- * It is now time to send info to user
- * to select between device drivers
- */
- gsmi_send_cb(GSM_EVT_DEVICE_IDENTIFIED);
-
- SET_NEW_CMD(GSM_CMD_CREG_SET); /* Enable unsolicited code for CREG */
- break;
- }
- case GSM_CMD_CREG_SET: SET_NEW_CMD(GSM_CMD_CLCC_SET); break;/* Set call state */
- case GSM_CMD_CLCC_SET: SET_NEW_CMD(GSM_CMD_CPIN_GET); break;/* Get SIM state */
- case GSM_CMD_CPIN_GET: break;
- default: break;
- }
-
- /* Send event */
- if (n_cmd == GSM_CMD_IDLE) {
- RESET_SEND_EVT(msg, gsmOK);
- }
- } else if (CMD_IS_DEF(GSM_CMD_COPS_GET)) {
- if (CMD_IS_CUR(GSM_CMD_COPS_GET)) {
- gsm.evt.evt.operator_current.operator_current = &gsm.m.network.curr_operator;
- gsmi_send_cb(GSM_EVT_NETWORK_OPERATOR_CURRENT);
- }
- } else if (CMD_IS_DEF(GSM_CMD_COPS_GET_OPT)) {
- if (CMD_IS_CUR(GSM_CMD_COPS_GET_OPT)) {
- OPERATOR_SCAN_SEND_EVT(gsm.msg, *is_ok ? gsmOK : gsmERR);
- }
- } else if (CMD_IS_DEF(GSM_CMD_SIM_PROCESS_BASIC_CMDS)) {
- switch (CMD_GET_CUR()) {
- case GSM_CMD_CNUM: { /* Get own phone number */
- if (!*is_ok) {
- /* Sometimes SIM is not ready just after PIN entered */
- if (msg->msg.sim_info.cnum_tries < 5) {
- msg->msg.sim_info.cnum_tries++;
- SET_NEW_CMD(GSM_CMD_CNUM);
- gsm_delay(1000);
- }
- }
- }
- default: break;
- }
- } else if (CMD_IS_DEF(GSM_CMD_CPIN_SET)) { /* Set PIN code */
- switch (CMD_GET_CUR()) {
- case GSM_CMD_CPIN_GET: { /* Get own phone number */
- if (*is_ok && gsm.m.sim.state == GSM_SIM_STATE_PIN) {
- SET_NEW_CMD(GSM_CMD_CPIN_SET); /* Set command to write PIN */
- } else if (gsm.m.sim.state != GSM_SIM_STATE_READY) {
- *is_ok = 0;
- *is_error = 1;
- }
- break;
- }
- case GSM_CMD_CPIN_SET: { /* Set CPIN */
- if (*is_ok) {
- gsm_delay(5000); /* Make delay to make sure SIM is ready */
- }
- break;
- }
- default:
- break;
- }
-#if GSM_CFG_SMS
- } else if (CMD_IS_DEF(GSM_CMD_SMS_ENABLE)) {
- switch (CMD_GET_CUR()) {
- case GSM_CMD_CPMS_GET_OPT: SET_NEW_CMD(GSM_CMD_CPMS_GET); break;
- case GSM_CMD_CPMS_GET: break;
- default: break;
- }
- if (!*is_ok || n_cmd == GSM_CMD_IDLE) { /* Stop execution on any command */
- SET_NEW_CMD(GSM_CMD_IDLE);
- gsm.m.sms.enabled = n_cmd == GSM_CMD_IDLE; /* Set enabled status */
- gsm.evt.evt.sms_enable.status = gsm.m.sms.enabled ? gsmOK : gsmERR;
- gsmi_send_cb(GSM_EVT_SMS_ENABLE); /* Send to user */
- }
- } else if (CMD_IS_DEF(GSM_CMD_CMGS)) { /* Send SMS default command */
- if (CMD_IS_CUR(GSM_CMD_CMGF) && *is_ok) { /* Set message format current command */
- SET_NEW_CMD(GSM_CMD_CMGS); /* Now send actual message */
- }
-
- /* Send event on finish */
- if (n_cmd == GSM_CMD_IDLE) {
- SMS_SEND_SEND_EVT(gsm.msg, *is_ok ? gsmOK : gsmERR);
- }
- } else if (CMD_IS_DEF(GSM_CMD_CMGR)) { /* Read SMS message */
- if (CMD_IS_CUR(GSM_CMD_CPMS_GET) && *is_ok) {
- SET_NEW_CMD(GSM_CMD_CPMS_SET); /* Set memory */
- } else if (CMD_IS_CUR(GSM_CMD_CPMS_SET) && *is_ok) {
- SET_NEW_CMD(GSM_CMD_CMGF); /* Set text mode */
- } else if (CMD_IS_CUR(GSM_CMD_CMGF) && *is_ok) {/* Set message format current command*/
- SET_NEW_CMD(GSM_CMD_CMGR); /* Start message read */
- } else if (CMD_IS_CUR(GSM_CMD_CMGR) && *is_ok) {
- msg->msg.sms_read.mem = gsm.m.sms.mem[0].current; /* Set current memory */
- }
-
- /* Send event on finish */
- if (n_cmd == GSM_CMD_IDLE) {
- SMS_SEND_READ_EVT(gsm.msg, *is_ok ? gsmOK : gsmERR);
- }
- } else if (CMD_IS_DEF(GSM_CMD_CMGD)) { /* Delete SMS message*/
- if (CMD_IS_CUR(GSM_CMD_CPMS_GET) && *is_ok) {
- SET_NEW_CMD(GSM_CMD_CPMS_SET); /* Set memory */
- } else if (CMD_IS_CUR(GSM_CMD_CPMS_SET) && *is_ok) {
- SET_NEW_CMD(GSM_CMD_CMGD); /* Delete message */
- }
-
- /* Send event on finish */
- if (n_cmd == GSM_CMD_IDLE) {
- SMS_SEND_DELETE_EVT(msg, *is_ok ? gsmOK : gsmERR);
- }
- } else if (CMD_IS_DEF(GSM_CMD_CMGDA)) {
- if (CMD_IS_CUR(GSM_CMD_CMGF) && *is_ok) {
- SET_NEW_CMD(GSM_CMD_CMGDA); /* Mass storage */
- }
- } else if (CMD_IS_DEF(GSM_CMD_CMGL)) { /* List SMS messages */
- if (CMD_IS_CUR(GSM_CMD_CPMS_GET) && *is_ok) {
- SET_NEW_CMD(GSM_CMD_CPMS_SET); /* Set memory */
- } else if (CMD_IS_CUR(GSM_CMD_CPMS_SET) && *is_ok) {
- SET_NEW_CMD(GSM_CMD_CMGF); /* Set text format */
- } else if (CMD_IS_CUR(GSM_CMD_CMGF) && *is_ok) {
- SET_NEW_CMD(GSM_CMD_CMGL); /* List messages */
- }
-
- /* Send event on finish */
- if (n_cmd == GSM_CMD_IDLE) {
- SMS_SEND_LIST_EVT(msg, *is_ok ? gsmOK : gsmERR);
- }
- } else if (CMD_IS_DEF(GSM_CMD_CPMS_SET)) { /* Set preferred memory */
- if (CMD_IS_CUR(GSM_CMD_CPMS_GET) && *is_ok) {
- SET_NEW_CMD(GSM_CMD_CPMS_SET); /* Now set the command */
- }
-#endif /* GSM_CFG_SMS */
-#if GSM_CFG_CALL
- } else if (CMD_IS_DEF(GSM_CMD_CALL_ENABLE)) {
- gsm.m.call.enabled = *is_ok; /* Set enabled status */
- gsm.evt.evt.call_enable.res = gsm.m.call.enabled ? gsmOK : gsmERR;
- gsmi_send_cb(GSM_EVT_CALL_ENABLE); /* Send to user */
-#endif /* GSM_CFG_CALL */
-#if GSM_CFG_PHONEBOOK
- } else if (CMD_IS_DEF(GSM_CMD_PHONEBOOK_ENABLE)) {
- gsm.m.pb.enabled = *is_ok; /* Set enabled status */
- gsm.evt.evt.pb_enable.res = gsm.m.pb.enabled ? gsmOK : gsmERR;
- gsmi_send_cb(GSM_EVT_PB_ENABLE); /* Send to user */
- } else if (CMD_IS_DEF(GSM_CMD_CPBW_SET)) { /* Write phonebook entry */
- if (CMD_IS_CUR(GSM_CMD_CPBS_GET) && *is_ok) { /* Get current memory */
- SET_NEW_CMD(GSM_CMD_CPBS_SET); /* Set current memory */
- } else if (CMD_IS_CUR(GSM_CMD_CPBS_SET) && *is_ok) {
- SET_NEW_CMD(GSM_CMD_CPBW_SET); /* Write entry to phonebook */
- }
- } else if (CMD_IS_DEF(GSM_CMD_CPBR)) {
- if (CMD_IS_CUR(GSM_CMD_CPBS_GET) && *is_ok) {/* Get current memory */
- SET_NEW_CMD(GSM_CMD_CPBS_SET); /* Set current memory */
- } else if (CMD_IS_CUR(GSM_CMD_CPBS_SET) && *is_ok) {
- SET_NEW_CMD(GSM_CMD_CPBR); /* Read entries */
- } else if (CMD_IS_CUR(GSM_CMD_CPBR)) {
- gsm.evt.evt.pb_list.mem = gsm.m.pb.mem.current;
- gsm.evt.evt.pb_list.entries = gsm.msg->msg.pb_list.entries;
- gsm.evt.evt.pb_list.size = gsm.msg->msg.pb_list.ei;
- gsm.evt.evt.pb_list.res = *is_ok ? gsmOK : gsmERR;
- gsmi_send_cb(GSM_EVT_PB_LIST);
- }
- } else if (CMD_IS_DEF(GSM_CMD_CPBF)) {
- if (CMD_IS_CUR(GSM_CMD_CPBS_GET) && *is_ok) {/* Get current memory */
- SET_NEW_CMD(GSM_CMD_CPBS_SET); /* Set current memory */
- } else if (CMD_IS_CUR(GSM_CMD_CPBS_SET) && *is_ok) {
- SET_NEW_CMD(GSM_CMD_CPBF); /* Read entries */
- } else if (CMD_IS_CUR(GSM_CMD_CPBF)) {
- gsm.evt.evt.pb_search.mem = gsm.m.pb.mem.current;
- gsm.evt.evt.pb_search.search = gsm.msg->msg.pb_search.search;
- gsm.evt.evt.pb_search.entries = gsm.msg->msg.pb_search.entries;
- gsm.evt.evt.pb_search.size = gsm.msg->msg.pb_search.ei;
- gsm.evt.evt.pb_search.res = *is_ok ? gsmOK : gsmERR;
- gsmi_send_cb(GSM_EVT_PB_SEARCH);
- }
-#endif /* GSM_CFG_PHONEBOOK */
-#if GSM_CFG_NETWORK
- } if (CMD_IS_DEF(GSM_CMD_NETWORK_ATTACH)) {
- switch (msg->i) {
- case 0: SET_NEW_CMD_CHECK_ERROR(GSM_CMD_CGACT_SET_0); break;
- case 1: SET_NEW_CMD(GSM_CMD_CGACT_SET_1); break;
-#if GSM_CFG_NETWORK_IGNORE_CGACT_RESULT
- case 2: SET_NEW_CMD(GSM_CMD_CGATT_SET_0); break;
-#else /* GSM_CFG_NETWORK_IGNORE_CGACT_RESULT */
- case 2: SET_NEW_CMD_CHECK_ERROR(GSM_CMD_CGATT_SET_0); break;
-#endif /* !GSM_CFG_NETWORK_IGNORE_CGACT_RESULT */
- case 3: SET_NEW_CMD(GSM_CMD_CGATT_SET_1); break;
- case 4: SET_NEW_CMD_CHECK_ERROR(GSM_CMD_CIPSHUT); break;
- case 5: SET_NEW_CMD_CHECK_ERROR(GSM_CMD_CIPMUX_SET); break;
- case 6: SET_NEW_CMD_CHECK_ERROR(GSM_CMD_CIPRXGET_SET); break;
- case 7: SET_NEW_CMD_CHECK_ERROR(GSM_CMD_CSTT_SET); break;
- case 8: SET_NEW_CMD_CHECK_ERROR(GSM_CMD_CIICR); break;
- case 9: SET_NEW_CMD_CHECK_ERROR(GSM_CMD_CIFSR); break;
- case 10: SET_NEW_CMD(GSM_CMD_CIPSTATUS); break;
- default: break;
- }
- } else if (CMD_IS_DEF(GSM_CMD_NETWORK_DETACH)) {
- switch (msg->i) {
- case 0: SET_NEW_CMD(GSM_CMD_CGATT_SET_0); break;
- case 1: SET_NEW_CMD(GSM_CMD_CGACT_SET_0); break;
-#if GSM_CFG_CONN
- case 2: SET_NEW_CMD(GSM_CMD_CIPSTATUS); break;
-#endif /* GSM_CFG_CONN */
- default: break;
- }
- if (!n_cmd) {
- *is_ok = 1;
- }
-#endif /* GSM_CFG_NETWORK */
-#if GSM_CFG_CONN
- } else if (CMD_IS_DEF(GSM_CMD_CIPSTART)) {
- if (!msg->i && CMD_IS_CUR(GSM_CMD_CIPSTATUS)) { /* Was the current command status info? */
- if (*is_ok) {
- SET_NEW_CMD(GSM_CMD_CIPSSL); /* Set SSL */
- }
- } else if (msg->i == 1 && CMD_IS_CUR(GSM_CMD_CIPSSL)) {
- SET_NEW_CMD(GSM_CMD_CIPSTART); /* Now actually start connection */
- } else if (msg->i == 2 && CMD_IS_CUR(GSM_CMD_CIPSTART)) {
- SET_NEW_CMD(GSM_CMD_CIPSTATUS); /* Go to status mode */
- if (*is_error) {
- msg->msg.conn_start.conn_res = GSM_CONN_CONNECT_ERROR;
- }
- } else if (msg->i == 3 && CMD_IS_CUR(GSM_CMD_CIPSTATUS)) {
- /* After second CIP status, define what to do next */
- switch (msg->msg.conn_start.conn_res) {
- case GSM_CONN_CONNECT_OK: { /* Successfully connected */
- gsm_conn_t* conn = &gsm.m.conns[msg->msg.conn_start.num]; /* Get connection number */
-
- gsm.evt.type = GSM_EVT_CONN_ACTIVE; /* Connection just active */
- gsm.evt.evt.conn_active_close.client = 1;
- gsm.evt.evt.conn_active_close.conn = conn;
- gsm.evt.evt.conn_active_close.forced = 1;
- gsmi_send_conn_cb(conn, NULL);
- gsmi_conn_start_timeout(conn); /* Start connection timeout timer */
- break;
- }
- case GSM_CONN_CONNECT_ERROR: { /* Connection error */
- gsmi_send_conn_error_cb(msg, gsmERRCONNFAIL);
- *is_error = 1; /* Manually set error */
- *is_ok = 0; /* Reset success */
- break;
- }
- default: {
- /* Do nothing as of now */
- break;
- }
- }
- }
- } else if (CMD_IS_DEF(GSM_CMD_CIPCLOSE)) {
- /*
- * It is unclear in which state connection is when ERROR is received on close command.
- * Stack checks if connection is closed before it allows and sends close command,
- * however it was detected that no automatic close event has been received from device
- * and AT+CIPCLOSE returned ERROR.
- *
- * Is it device firmware bug?
- */
- if (CMD_IS_CUR(GSM_CMD_CIPCLOSE) && *is_error) {
- /* Notify upper layer about failed close event */
- gsm.evt.type = GSM_EVT_CONN_CLOSE;
- gsm.evt.evt.conn_active_close.conn = msg->msg.conn_close.conn;
- gsm.evt.evt.conn_active_close.forced = 1;
- gsm.evt.evt.conn_active_close.res = gsmERR;
- gsm.evt.evt.conn_active_close.client = msg->msg.conn_close.conn->status.f.active && msg->msg.conn_close.conn->status.f.client;
- gsmi_send_conn_cb(msg->msg.conn_close.conn, NULL);
- }
-#endif /* GSM_CFG_CONN */
-#if GSM_CFG_USSD
- } else if (CMD_IS_DEF(GSM_CMD_CUSD)) {
- if (CMD_IS_CUR(GSM_CMD_CUSD_GET)) {
- if (*is_ok) {
- SET_NEW_CMD(GSM_CMD_CUSD); /* Run next command */
- }
- }
- /* The rest is handled in one layer above */
-#endif /* GSM_CFG_USSD */
- }
-
- /* Check if new command was set for execution */
- if (n_cmd != GSM_CMD_IDLE) {
- gsmr_t res;
- msg->cmd = n_cmd;
- if ((res = msg->fn(msg)) == gsmOK) {
- return gsmCONT;
- } else {
- *is_ok = 0;
- *is_error = 1;
- return res;
- }
- } else {
- msg->cmd = GSM_CMD_IDLE;
- }
- return *is_ok ? gsmOK : gsmERR;
-}
-
-/**
- * \brief Function to initialize every AT command
- * \note Never call this function directly. Set as initialization function for command and use `msg->fn(msg)`
- * \param[in] msg: Pointer to \ref gsm_msg_t with data
- * \return Member of \ref gsmr_t enumeration
- */
-gsmr_t
-gsmi_initiate_cmd(gsm_msg_t* msg) {
- switch (CMD_GET_CUR()) { /* Check current message we want to send over AT */
- case GSM_CMD_RESET: { /* Reset modem with AT commands */
- /* Try with hardware reset */
- if (gsm.ll.reset_fn != NULL && gsm.ll.reset_fn(1)) {
- gsm_delay(2);
- gsm.ll.reset_fn(0);
- gsm_delay(500);
- }
-
- /* Send manual AT command */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CFUN=1,1");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_RESET_DEVICE_FIRST_CMD: { /* First command for device driver specific reset */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_ATE0:
- case GSM_CMD_ATE1: {
- AT_PORT_SEND_BEGIN_AT();
- if (CMD_IS_CUR(GSM_CMD_ATE0)) {
- AT_PORT_SEND_CONST_STR("E0");
- } else {
- AT_PORT_SEND_CONST_STR("E1");
- }
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CMEE_SET: { /* Enable detailed error messages */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CMEE=1");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CLCC_SET: { /* Enable detailed call info */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CLCC=1");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CGMI_GET: { /* Get manufacturer */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CGMI");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CGMM_GET: { /* Get model */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CGMM");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CGSN_GET: { /* Get serial number */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CGSN");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CGMR_GET: { /* Get revision */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CGMR");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CREG_SET: { /* Enable +CREG message */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CREG=1");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CREG_GET: { /* Get network registration status */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CREG?");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CFUN_SET: {
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CFUN=");
- /**
- * \todo: If CFUN command forced, check value
- */
- if (CMD_IS_DEF(GSM_CMD_RESET)
- || (CMD_IS_DEF(GSM_CMD_CFUN_SET) && msg->msg.cfun.mode)) {
- AT_PORT_SEND_CONST_STR("1");
- } else {
- AT_PORT_SEND_CONST_STR("0");
- }
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CPIN_GET: { /* Read current SIM status */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CPIN?");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CPIN_SET: { /* Set SIM pin code */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CPIN=");
- gsmi_send_string(msg->msg.cpin_enter.pin, 0, 1, 0);
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CPIN_ADD: { /* Add new pin code */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CLCK=\"SC\",1,");
- gsmi_send_string(msg->msg.cpin_add.pin, 0, 1, 0);
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CPIN_CHANGE: { /* Change already active SIM */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CPWD=\"SC\"");
- gsmi_send_string(msg->msg.cpin_change.current_pin, 0, 1, 1);
- gsmi_send_string(msg->msg.cpin_change.new_pin, 0, 1, 1);
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CPIN_REMOVE: { /* Remove current PIN */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CLCK=\"SC\",0,");
- gsmi_send_string(msg->msg.cpin_remove.pin, 0, 1, 0);
- AT_PORT_SEND_END_AT();
- break;
- }
- case GMM_CMD_CPUK_SET: { /* Enter PUK and set new PIN */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CPIN=");
- gsmi_send_string(msg->msg.cpuk_enter.puk, 0, 1, 0);
- gsmi_send_string(msg->msg.cpuk_enter.pin, 0, 1, 1);
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_COPS_SET: { /* Set current operator */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+COPS=");
- gsmi_send_number(GSM_U32(msg->msg.cops_set.mode), 0, 0);
- if (msg->msg.cops_set.mode != GSM_OPERATOR_MODE_AUTO) {
- gsmi_send_number(GSM_U32(msg->msg.cops_set.format), 0, 1);
- switch (msg->msg.cops_set.format) {
- case GSM_OPERATOR_FORMAT_LONG_NAME:
- case GSM_OPERATOR_FORMAT_SHORT_NAME:
- gsmi_send_string(msg->msg.cops_set.name, 1, 1, 1);
- break;
- default:
- gsmi_send_number(GSM_U32(msg->msg.cops_set.num), 0, 1);
- }
- }
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_COPS_GET: { /* Get current operator */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+COPS?");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_COPS_GET_OPT: { /* Get list of available operators */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+COPS=?");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CSQ_GET: { /* Get signal strength */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CSQ");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CNUM: { /* Get SIM number */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CNUM");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CIPSHUT: { /* Shut down network connection and put to reset state */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CIPSHUT");
- AT_PORT_SEND_END_AT();
- break;
- }
-#if GSM_CFG_CONN
- case GSM_CMD_CIPMUX: { /* Enable multiple connections */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CIPMUX=1");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CIPHEAD: { /* Enable information on receive data about connection and length */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CIPHEAD=1");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CIPSRIP: {
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CIPSRIP=1");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CIPSSL: { /* Set SSL configuration */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CIPSSL=");
- gsmi_send_number((msg->msg.conn_start.type == GSM_CONN_TYPE_SSL) ? 1 : 0, 0, 0);
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CIPSTART: { /* Start a new connection */
- gsm_conn_t* c = NULL;
-
- /* Do we have network connection? */
- /* Check if we are connected to network */
-
- msg->msg.conn_start.num = 0; /* Start with max value = invalidated */
- for (int16_t i = GSM_CFG_MAX_CONNS - 1; i >= 0; i--) { /* Find available connection */
- if (!gsm.m.conns[i].status.f.active) {
- c = &gsm.m.conns[i];
- c->num = GSM_U8(i);
- msg->msg.conn_start.num = GSM_U8(i); /* Set connection number for message structure */
- break;
- }
- }
- if (c == NULL) {
- gsmi_send_conn_error_cb(msg, gsmERRNOFREECONN);
- return gsmERRNOFREECONN; /* We don't have available connection */
- }
-
- if (msg->msg.conn_start.conn != NULL) { /* Is user interested about connection info? */
- *msg->msg.conn_start.conn = c; /* Save connection for user */
- }
-
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CIPSTART=");
- gsmi_send_number(GSM_U32(c->num), 0, 0);
- if (msg->msg.conn_start.type == GSM_CONN_TYPE_TCP) {
- gsmi_send_string("TCP", 0, 1, 1);
- } else if (msg->msg.conn_start.type == GSM_CONN_TYPE_UDP) {
- gsmi_send_string("UDP", 0, 1, 1);
- }
- gsmi_send_string(msg->msg.conn_start.host, 0, 1, 1);
- gsmi_send_port(msg->msg.conn_start.port, 0, 1);
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CIPCLOSE: { /* Close the connection */
- gsm_conn_p c = msg->msg.conn_close.conn;
- if (c != NULL &&
- /* Is connection already closed or command for this connection is not valid anymore? */
- (!gsm_conn_is_active(c) || c->val_id != msg->msg.conn_close.val_id)) {
- return gsmERR;
- }
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CIPCLOSE=");
- gsmi_send_number(GSM_U32(msg->msg.conn_close.conn ? msg->msg.conn_close.conn->num : GSM_CFG_MAX_CONNS), 0, 0);
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CIPSEND: { /* Send data to connection */
- return gsmi_tcpip_process_send_data(); /* Process send data */
- }
- case GSM_CMD_CIPSTATUS: { /* Get status of device and all connections */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CIPSTATUS");
- AT_PORT_SEND_END_AT();
- break;
- }
-#endif /* GSM_CFG_CONN */
-#if GSM_CFG_SMS
- case GSM_CMD_CMGF: { /* Select SMS message format */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CMGF=");
- if (CMD_IS_DEF(GSM_CMD_CMGS)) {
- gsmi_send_number(GSM_U32(!!msg->msg.sms_send.format), 0, 0);
- } else if (CMD_IS_DEF(GSM_CMD_CMGR)) {
- gsmi_send_number(GSM_U32(!!msg->msg.sms_read.format), 0, 0);
- } else if (CMD_IS_DEF(GSM_CMD_CMGL)) {
- gsmi_send_number(GSM_U32(!!msg->msg.sms_list.format), 0, 0);
- } else {
- /* Used for all other operations like delete all messages, etc */
- AT_PORT_SEND_CONST_STR("1");
- }
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CMGS: { /* Send SMS */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CMGS=");
- gsmi_send_string(msg->msg.sms_send.num, 0, 1, 0);
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CMGR: { /* Read message */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CMGR=");
- gsmi_send_number(GSM_U32(msg->msg.sms_read.pos), 0, 0);
- gsmi_send_number(GSM_U32(!msg->msg.sms_read.update), 0, 1);
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CMGD: { /* Delete SMS message */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CMGD=");
- gsmi_send_number(GSM_U32(msg->msg.sms_delete.pos), 0, 0);
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CMGDA: { /* Mass delete SMS messages */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CMGDA=");
- switch (msg->msg.sms_delete_all.status) {
- case GSM_SMS_STATUS_READ: gsmi_send_string("DEL READ", 0, 1, 0); break;
- case GSM_SMS_STATUS_UNREAD: gsmi_send_string("DEL UNREAD", 0, 1, 0); break;
- case GSM_SMS_STATUS_SENT: gsmi_send_string("DEL SENT", 0, 1, 0); break;
- case GSM_SMS_STATUS_UNSENT: gsmi_send_string("DEL UNSENT", 0, 1, 0); break;
- case GSM_SMS_STATUS_INBOX: gsmi_send_string("DEL INBOX", 0, 1, 0); break;
- case GSM_SMS_STATUS_ALL: gsmi_send_string("DEL ALL", 0, 1, 0); break;
- default: break;
- }
- AT_PORT_SEND_END_AT();
- break;
- }
-
- case GSM_CMD_CMGL: { /* Delete SMS message */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CMGL=");
- gsmi_send_sms_stat(msg->msg.sms_list.status, 1, 0);
- gsmi_send_number(GSM_U32(!msg->msg.sms_list.update), 0, 1);
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CPMS_GET_OPT: { /* Get available SMS storages */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CPMS=?");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CPMS_GET: { /* Get current SMS storage info */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CPMS?");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CPMS_SET: { /* Set active SMS storage(s) */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CPMS=");
- if (CMD_IS_DEF(GSM_CMD_CMGR)) { /* Read SMS original command? */
- gsmi_send_dev_memory(msg->msg.sms_read.mem == GSM_MEM_CURRENT ? gsm.m.sms.mem[0].current : msg->msg.sms_read.mem, 1, 0);
- } else if(CMD_IS_DEF(GSM_CMD_CMGD)) { /* Delete SMS original command? */
- gsmi_send_dev_memory(msg->msg.sms_delete.mem == GSM_MEM_CURRENT ? gsm.m.sms.mem[0].current : msg->msg.sms_delete.mem, 1, 0);
- } else if(CMD_IS_DEF(GSM_CMD_CMGL)) { /* List SMS original command? */
- gsmi_send_dev_memory(msg->msg.sms_list.mem == GSM_MEM_CURRENT ? gsm.m.sms.mem[0].current : msg->msg.sms_list.mem, 1, 0);
- } else if (CMD_IS_DEF(GSM_CMD_CPMS_SET)) { /* Do we want to set memory for read/delete,sent/write,receive? */
- for (size_t i = 0; i < 3; i++) {/* Write 3 memories */
- gsmi_send_dev_memory(msg->msg.sms_memory.mem[i] == GSM_MEM_CURRENT ? gsm.m.sms.mem[i].current : msg->msg.sms_memory.mem[i], 1, !!i);
- }
- }
- AT_PORT_SEND_END_AT();
- break;
- }
-#endif /* GSM_CFG_SMS */
-#if GSM_CFG_CALL
- case GSM_CMD_ATD: { /* Start new call */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("D");
- gsmi_send_string(msg->msg.call_start.number, 0, 0, 0);
- AT_PORT_SEND_CONST_STR(";");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_ATA: { /* Answer phone call */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("A");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_ATH: { /* Disconnect existing connection (hang-up phone call) */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("H");
- AT_PORT_SEND_END_AT();
- break;
- }
-#endif /* GSM_CFG_CALL */
-#if GSM_CFG_PHONEBOOK
- case GSM_CMD_CPBS_GET_OPT: { /* Get available phonebook storages */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CPBS=?");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CPBS_GET: { /* Get current memory info */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CPBS?");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CPBS_SET: { /* Get current memory info */
- gsm_mem_t mem;
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CPBS=");
- switch (CMD_GET_DEF()) {
- case GSM_CMD_CPBW_SET: mem = msg->msg.pb_write.mem; break;
- case GSM_CMD_CPBR: mem = msg->msg.pb_list.mem; break;
- case GSM_CMD_CPBF: mem = msg->msg.pb_search.mem; break;
- default: break;
- }
- gsmi_send_dev_memory(mem == GSM_MEM_CURRENT ? gsm.m.pb.mem.current : mem, 1, 0);
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CPBW_SET: { /* Write/Delete new/old entry */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CPBW=");
- if (msg->msg.pb_write.pos > 0) { /* Write number if more than 0 */
- gsmi_send_number(GSM_U32(msg->msg.pb_write.pos), 0, 0);
- }
- if (!msg->msg.pb_write.del) {
- gsmi_send_string(msg->msg.pb_write.num, 0, 1, 1);
- gsmi_send_number(GSM_U32(msg->msg.pb_write.type), 0, 1);
- gsmi_send_string(msg->msg.pb_write.name, 0, 1, 1);
- }
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CPBR: { /* Read entires */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CPBR=");
- gsmi_send_number(GSM_U32(msg->msg.pb_list.start_index), 0, 0);
- gsmi_send_number(GSM_U32(msg->msg.pb_list.etr), 0, 1);
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CPBF: { /* Find entires */
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CPBF=");
- gsmi_send_string(msg->msg.pb_search.search, 1, 1, 0);
- AT_PORT_SEND_END_AT();
- break;
- }
-#endif /* GSM_CFG_PHONEBOOK */
-#if GSM_CFG_NETWORK
- case GSM_CMD_NETWORK_ATTACH:
- case GSM_CMD_CGACT_SET_0: {
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CGACT=0");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CGACT_SET_1: {
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CGACT=1");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_NETWORK_DETACH:
- case GSM_CMD_CGATT_SET_0: {
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CGATT=0");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CGATT_SET_1: {
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CGATT=1");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CIPMUX_SET: {
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CIPMUX=1");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CIPRXGET_SET: {
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CIPRXGET=0");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CSTT_SET: {
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CSTT=");
- gsmi_send_string(msg->msg.network_attach.apn, 1, 1, 0);
- gsmi_send_string(msg->msg.network_attach.user, 1, 1, 1);
- gsmi_send_string(msg->msg.network_attach.pass, 1, 1, 1);
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CIICR: {
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CIICR");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CIFSR: {
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CIFSR");
- AT_PORT_SEND_END_AT();
- break;
- }
-#endif /* GSM_CFG_NETWORK */
-#if GSM_CFG_USSD
- case GSM_CMD_CUSD_GET: {
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CUSD?");
- AT_PORT_SEND_END_AT();
- break;
- }
- case GSM_CMD_CUSD: {
- AT_PORT_SEND_BEGIN_AT();
- AT_PORT_SEND_CONST_STR("+CUSD=1,");
- gsmi_send_string(msg->msg.ussd.code, 1, 1, 0);
- AT_PORT_SEND_END_AT();
- break;
- }
-#endif /* GSM_CFG_USSD */
- default:
- return gsmERR; /* Invalid command */
- }
- return gsmOK; /* Valid command */
-}
-
-/**
- * \brief Send message from API function to producer queue for further processing
- * \param[in] msg: New message to process
- * \param[in] process_fn: callback function used to process message
- * \param[in] max_block_time: Maximal time command can block in units of milliseconds
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
- */
-gsmr_t
-gsmi_send_msg_to_producer_mbox(gsm_msg_t* msg, gsmr_t (*process_fn)(gsm_msg_t *), uint32_t max_block_time) {
- gsmr_t res = msg->res = gsmOK;
-
- /* Check here if stack is even enabled or shall we disable new command entry? */
- gsm_core_lock();
- /* If locked more than 1 time, means we were called from callback or internally */
- if (gsm.locked_cnt > 1 && msg->is_blocking) {
- res = gsmERRBLOCKING; /* Blocking mode not allowed */
- }
- /* Check if device present */
- if (res == gsmOK && !gsm.status.f.dev_present) {
- res = gsmERRNODEVICE; /* No device connected */
- }
- gsm_core_unlock();
- if (res != gsmOK) {
- GSM_MSG_VAR_FREE(msg); /* Free memory and return */
- return res;
- }
-
- if (msg->is_blocking) { /* In case message is blocking */
- if (!gsm_sys_sem_create(&msg->sem, 0)) {/* Create semaphore and lock it immediatelly */
- GSM_MSG_VAR_FREE(msg); /* Release memory and return */
- return gsmERRMEM;
- }
- }
- if (!msg->cmd) { /* Set start command if not set by user */
- msg->cmd = msg->cmd_def; /* Set it as default */
- }
- msg->block_time = max_block_time; /* Set blocking status if necessary */
- msg->fn = process_fn; /* Save processing function to be called as callback */
- if (msg->is_blocking) {
- gsm_sys_mbox_put(&gsm.mbox_producer, msg); /* Write message to producer queue and wait forever */
- } else {
- if (!gsm_sys_mbox_putnow(&gsm.mbox_producer, msg)) { /* Write message to producer queue immediatelly */
- GSM_MSG_VAR_FREE(msg); /* Release message */
- return gsmERRMEM;
- }
- }
- if (res == gsmOK && msg->is_blocking) { /* In case we have blocking request */
- uint32_t time;
- time = gsm_sys_sem_wait(&msg->sem, 0); /* Wait forever for semaphore */
- if (time == GSM_SYS_TIMEOUT) { /* If semaphore was not accessed in given time */
- res = gsmTIMEOUT; /* Semaphore not released in time */
- } else {
- res = msg->res; /* Set response status from message response */
- }
- GSM_MSG_VAR_FREE(msg); /* Release message */
- }
- return res;
-}
-
-/**
- * \brief Process events in case of timeout on command or invalid message (if device is not present)
- *
- * Function is called from processing thread:
- *
- * - On command timeout error
- * - If command was sent to queue and before processed, device present status changed
- *
- * \param[in] msg: Current message
- * \param[in] err: Error message to send
- */
-void
-gsmi_process_events_for_timeout_or_error(gsm_msg_t* msg, gsmr_t err) {
- switch (msg->cmd_def) {
- case GSM_CMD_RESET: {
- /* Reset command error */
- RESET_SEND_EVT(msg, err);
- break;
- }
-
- case GSM_CMD_RESTORE: {
- /* Restore command error */
- RESTORE_SEND_EVT(msg, err);
- break;
- }
-
- case GSM_CMD_COPS_GET_OPT: {
- /* Operator scan command error */
- OPERATOR_SCAN_SEND_EVT(msg, err);
- break;
- }
-
-#if GSM_CFG_CONN
- case GSM_CMD_CIPSTART: {
- /* Start connection error */
- gsmi_send_conn_error_cb(msg, err);
- break;
- }
-
- case GSM_CMD_CIPSEND: {
- /* Send data error event */
- CONN_SEND_DATA_SEND_EVT(msg, err);
- break;
- }
-#endif /* GSM_CFG_CONN */
-
-#if GSM_CFG_SMS
- case GSM_CMD_CMGS: {
- /* Send error event */
- SMS_SEND_SEND_EVT(msg, err);
- break;
- }
-
- case GSM_CMD_CMGR: {
- /* Read error event */
- SMS_SEND_READ_EVT(msg, err);
- break;
- }
-
- case GSM_CMD_CMGL: {
- /* List error event */
- SMS_SEND_LIST_EVT(msg, err);
- break;
- }
-
- case GSM_CMD_CMGD: {
- /* Delete error event */
- SMS_SEND_DELETE_EVT(msg, err);
- break;
- }
-#endif /* GSM_CFG_SMS */
-
- default: break;
- }
-}
diff --git a/gsm_at_lib/src/gsm/gsm_network.c b/gsm_at_lib/src/gsm/gsm_network.c
deleted file mode 100644
index 1869942d..00000000
--- a/gsm_at_lib/src/gsm/gsm_network.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/**
- * \file gsm_network.c
- * \brief Network API
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#include "gsm/gsm_private.h"
-#include "gsm/gsm_network.h"
-#include "gsm/gsm_mem.h"
-
-#if GSM_CFG_NETWORK || __DOXYGEN__
-
-/**
- * \brief Attach to network and active PDP context
- * \param[in] apn: APN name
- * \param[in] user: User name to attach. Set to `NULL` if not used
- * \param[in] pass: User password to attach. Set to `NULL` if not used
- * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
- * \param[in] evt_arg: Custom argument for event callback function
- * \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
- */
-gsmr_t
-gsm_network_attach(const char* apn, const char* user, const char* pass,
- const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
-
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_NETWORK_ATTACH;
-#if GSM_CFG_CONN
- GSM_MSG_VAR_REF(msg).cmd = GSM_CMD_CIPSTATUS;
-#endif /* GSM_CFG_CONN */
- GSM_MSG_VAR_REF(msg).msg.network_attach.apn = apn;
- GSM_MSG_VAR_REF(msg).msg.network_attach.user = user;
- GSM_MSG_VAR_REF(msg).msg.network_attach.pass = pass;
-
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 200000);
-}
-
-/**
- * \brief Detach from network
- * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
- * \param[in] evt_arg: Custom argument for event callback function
- * \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
- */
-gsmr_t
-gsm_network_detach(const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
-
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_NETWORK_DETACH;
-#if GSM_CFG_CONN
- /* GSM_MSG_VAR_REF(msg).cmd = GSM_CMD_CIPSTATUS; */
-#endif /* GSM_CFG_CONN */
-
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 60000);
-}
-
-/**
- * \brief Check network PDP status
- * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
- * \param[in] evt_arg: Custom argument for event callback function
- * \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
- */
-gsmr_t
-gsm_network_check_status(const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
-
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_CIPSTATUS;
-
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 60000);
-}
-
-/**
- * \brief Copy IP address from internal value to user variable
- * \param[out] ip: Pointer to output IP variable
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
- */
-gsmr_t
-gsm_network_copy_ip(gsm_ip_t* ip) {
- if (gsm_network_is_attached()) {
- gsm_core_lock();
- GSM_MEMCPY(ip, &gsm.m.network.ip_addr, sizeof(*ip));
- gsm_core_unlock();
- return gsmOK;
- }
- return gsmERR;
-}
-
-/**
- * \brief Check if device is attached to network and PDP context is active
- * \return `1` on success, `0` otherwise
- */
-uint8_t
-gsm_network_is_attached(void) {
- uint8_t res;
- gsm_core_lock();
- res = GSM_U8(gsm.m.network.is_attached);
- gsm_core_unlock();
- return res;
-}
-
-#endif /* GSM_CFG_NETWORK || __DOXYGEN__ */
-
-/**
- * \brief Read RSSI signal from network operator
- * \param[out] rssi: RSSI output variable. When set to `0`, RSSI is not valid
- * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
- * \param[in] evt_arg: Custom argument for event callback function
- * \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
- */
-gsmr_t
-gsm_network_rssi(int16_t* rssi,
- const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
-
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_CSQ_GET;
- GSM_MSG_VAR_REF(msg).msg.csq.rssi = rssi;
-
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 120000);
-}
-
-/**
- * \brief Get network registration status
- * \return Member of \ref gsm_network_reg_status_t enumeration
- */
-gsm_network_reg_status_t
-gsm_network_get_reg_status(void) {
- gsm_network_reg_status_t ret;
- gsm_core_lock();
- ret = gsm.m.network.status;
- gsm_core_unlock();
- return ret;
-}
diff --git a/gsm_at_lib/src/gsm/gsm_phonebook.c b/gsm_at_lib/src/gsm/gsm_phonebook.c
deleted file mode 100644
index e7e3b01f..00000000
--- a/gsm_at_lib/src/gsm/gsm_phonebook.c
+++ /dev/null
@@ -1,334 +0,0 @@
-/**
- * \file gsm_phonebook.c
- * \brief Phonebook API
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#include "gsm/gsm_private.h"
-#include "gsm/gsm_phonebook.h"
-#include "gsm/gsm_mem.h"
-
-#if GSM_CFG_PHONEBOOK || __DOXYGEN__
-
-#if !__DOXYGEN__
-#define CHECK_ENABLED() if (!(check_enabled() == gsmOK)) { return gsmERRNOTENABLED; }
-#endif /* !__DOXYGEN__ */
-
-/**
- * \brief Check if phonebook is enabled
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
- */
-static gsmr_t
-check_enabled(void) {
- gsmr_t res;
- gsm_core_lock();
- res = gsm.m.pb.enabled ? gsmOK : gsmERR;
- gsm_core_unlock();
- return res;
-}
-
-/**
- * \brief Check if input memory is available in modem
- * \param[in] mem: Memory to test
- * \param[in] can_curr: Flag indicates if \ref GSM_MEM_CURRENT option can be used
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
- */
-static gsmr_t
-check_mem(gsm_mem_t mem, uint8_t can_curr) {
- gsmr_t res = gsmERRMEM;
- gsm_core_lock();
- if ((mem < GSM_MEM_END && gsm.m.pb.mem.mem_available & (1 << (uint32_t)mem)) ||
- (can_curr && mem == GSM_MEM_CURRENT)) {
- res = gsmOK;
- }
- gsm_core_unlock();
- return res;
-}
-
-/**
- * \brief Enable phonebook functionality
- * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
- * \param[in] evt_arg: Custom argument for event callback function
- * \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
- */
-gsmr_t
-gsm_pb_enable(const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
-
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_PHONEBOOK_ENABLE;
- GSM_MSG_VAR_REF(msg).cmd = GSM_CMD_CPBS_GET_OPT;
-
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 60000);
-}
-
-/**
- * \brief Disable phonebook functionality
- * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
- * \param[in] evt_arg: Custom argument for event callback function
- * \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
- */
-gsmr_t
-gsm_pb_disable(const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- gsm_core_lock();
- gsm.m.pb.enabled = 0;
- if (evt_fn != NULL) {
- evt_fn(gsmOK, evt_arg);
- }
- gsm_core_unlock();
- return gsmOK;
-}
-
-/**
- * \brief Add new phonebook entry to desired memory
- * \param[in] mem: Memory to use to save entry. Use \ref GSM_MEM_CURRENT to use current memory
- * \param[in] name: Entry name
- * \param[in] num: Entry phone number
- * \param[in] type: Entry phone number type
- * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
- * \param[in] evt_arg: Custom argument for event callback function
- * \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
- */
-gsmr_t
-gsm_pb_add(gsm_mem_t mem, const char* name, const char* num, gsm_number_type_t type,
- const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
-
- GSM_ASSERT("name != NULL", name != NULL);
- GSM_ASSERT("num != NULL", num != NULL);
- CHECK_ENABLED(); /* Check if enabled */
- GSM_ASSERT("check_mem() == gsmOK", check_mem(mem, 1) == gsmOK);
-
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_CPBW_SET;
- if (mem == GSM_MEM_CURRENT) { /* Should be always false */
- GSM_MSG_VAR_REF(msg).cmd = GSM_CMD_CPBS_GET;/* First get memory */
- } else {
- GSM_MSG_VAR_REF(msg).cmd = GSM_CMD_CPBS_SET;/* First set memory */
- }
-
- GSM_MSG_VAR_REF(msg).msg.pb_write.pos = 0;
- GSM_MSG_VAR_REF(msg).msg.pb_write.mem = mem;
- GSM_MSG_VAR_REF(msg).msg.pb_write.name = name;
- GSM_MSG_VAR_REF(msg).msg.pb_write.num = num;
- GSM_MSG_VAR_REF(msg).msg.pb_write.type = type;
-
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 60000);
-}
-
-/**
- * \brief Read single phonebook entry
- * \param[in] mem: Memory to use to save entry. Use \ref GSM_MEM_CURRENT to use current memory
- * \param[in] pos: Entry position in memory to read
- * \param[out] entry: Pointer to entry variable to save data
- * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
- * \param[in] evt_arg: Custom argument for event callback function
- * \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
- */
-gsmr_t
-gsm_pb_read(gsm_mem_t mem, size_t pos, gsm_pb_entry_t* entry,
- const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- return gsm_pb_list(mem, pos, entry, 1, NULL, evt_fn, evt_arg, blocking);
-}
-
-/**
- * \brief Edit or overwrite phonebook entry at desired memory and position
- * \param[in] mem: Memory to use to save entry. Use \ref GSM_MEM_CURRENT to use current memory
- * \param[in] pos: Entry position in memory to edit
- * \param[in] name: New entry name
- * \param[in] num: New entry phone number
- * \param[in] type: New entry phone number type
- * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
- * \param[in] evt_arg: Custom argument for event callback function
- * \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
- */
-gsmr_t
-gsm_pb_edit(gsm_mem_t mem, size_t pos, const char* name, const char* num, gsm_number_type_t type,
- const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
-
- GSM_ASSERT("name != NULL", name != NULL);
- GSM_ASSERT("num != NULL", num != NULL);
- CHECK_ENABLED(); /* Check if enabled */
- GSM_ASSERT("check_mem() == mem", check_mem(mem, 1) == gsmOK);
-
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_CPBW_SET;
- if (mem == GSM_MEM_CURRENT) { /* Should be always false */
- GSM_MSG_VAR_REF(msg).cmd = GSM_CMD_CPBS_GET;/* First get memory */
- } else {
- GSM_MSG_VAR_REF(msg).cmd = GSM_CMD_CPBS_SET;/* First set memory */
- }
-
- GSM_MSG_VAR_REF(msg).msg.pb_write.pos = pos;
- GSM_MSG_VAR_REF(msg).msg.pb_write.mem = mem;
- GSM_MSG_VAR_REF(msg).msg.pb_write.name = name;
- GSM_MSG_VAR_REF(msg).msg.pb_write.num = num;
- GSM_MSG_VAR_REF(msg).msg.pb_write.type = type;
-
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 60000);
-}
-
-/**
- * \brief Delete phonebook entry at desired memory and position
- * \param[in] mem: Memory to use to save entry. Use \ref GSM_MEM_CURRENT to use current memory
- * \param[in] pos: Entry position in memory to delete
- * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
- * \param[in] evt_arg: Custom argument for event callback function
- * \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
- */
-gsmr_t
-gsm_pb_delete(gsm_mem_t mem, size_t pos,
- const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
-
- GSM_ASSERT("pos > 0", pos > 0);
- CHECK_ENABLED(); /* Check if enabled */
- GSM_ASSERT("check_mem() == gsmOK", check_mem(mem, 1) == gsmOK);
-
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_CPBW_SET;
- if (mem == GSM_MEM_CURRENT) { /* Should be always false */
- GSM_MSG_VAR_REF(msg).cmd = GSM_CMD_CPBS_GET; /* First get memory */
- } else {
- GSM_MSG_VAR_REF(msg).cmd = GSM_CMD_CPBS_SET; /* First set memory */
- }
-
- GSM_MSG_VAR_REF(msg).msg.pb_write.mem = mem;
- GSM_MSG_VAR_REF(msg).msg.pb_write.pos = pos;
- GSM_MSG_VAR_REF(msg).msg.pb_write.del = 1;
-
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 60000);
-}
-
-/**
- * \brief List entires from specific memory
- * \param[in] mem: Memory to use to save entry. Use \ref GSM_MEM_CURRENT to use current memory
- * \param[in] start_index: Start position in memory to list
- * \param[out] entries: Pointer to array to save entries
- * \param[in] etr: Number of entries to read
- * \param[out] er: Pointer to output variable to save entries listed
- * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
- * \param[in] evt_arg: Custom argument for event callback function
- * \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
- */
-gsmr_t
-gsm_pb_list(gsm_mem_t mem, size_t start_index, gsm_pb_entry_t* entries, size_t etr, size_t* er,
- const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
-
- GSM_ASSERT("start_index", start_index);
- GSM_ASSERT("entries != NULL", entries != NULL);
- GSM_ASSERT("etr > 0", etr > 0);
- CHECK_ENABLED();
- GSM_ASSERT("check_mem() == gsmOK", check_mem(mem, 1) == gsmOK);
-
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
-
- if (er != NULL) {
- *er = 0;
- }
- GSM_MEMSET(entries, 0x00, sizeof(*entries) * etr); /* Reset data structure */
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_CPBR;
- if (mem == GSM_MEM_CURRENT) { /* Should be always false */
- GSM_MSG_VAR_REF(msg).cmd = GSM_CMD_CPBS_GET; /* First get memory */
- } else {
- GSM_MSG_VAR_REF(msg).cmd = GSM_CMD_CPBS_SET; /* First set memory */
- }
-
- GSM_MSG_VAR_REF(msg).msg.pb_list.mem = mem;
- GSM_MSG_VAR_REF(msg).msg.pb_list.start_index = start_index;
- GSM_MSG_VAR_REF(msg).msg.pb_list.entries = entries;
- GSM_MSG_VAR_REF(msg).msg.pb_list.etr = etr;
- GSM_MSG_VAR_REF(msg).msg.pb_list.er = er;
-
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 60000);
-}
-
-/**
- * \brief Search for entires with specific name from specific memory
- * \note Search works by entry name only. Phone number search is not available
- * \param[in] mem: Memory to use to save entry. Use \ref GSM_MEM_CURRENT to use current memory
- * \param[in] search: String to search for
- * \param[out] entries: Pointer to array to save entries
- * \param[in] etr: Number of entries to read
- * \param[out] er: Pointer to output variable to save entries found
- * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
- * \param[in] evt_arg: Custom argument for event callback function
- * \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
- */
-gsmr_t
-gsm_pb_search(gsm_mem_t mem, const char* search, gsm_pb_entry_t* entries, size_t etr, size_t* er,
- const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
-
- GSM_ASSERT("search != NULL", search != NULL);
- GSM_ASSERT("entries != NULL", entries != NULL);
- GSM_ASSERT("etr > 0", etr > 0);
- CHECK_ENABLED(); /* Check if enabled */
- GSM_ASSERT("check_mem() == mem", check_mem(mem, 1) == gsmOK);
-
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
-
- if (er != NULL) {
- *er = 0;
- }
- GSM_MEMSET(entries, 0x00, sizeof(*entries) * etr); /* Reset data structure */
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_CPBF;
- if (mem == GSM_MEM_CURRENT) { /* Should be always false */
- GSM_MSG_VAR_REF(msg).cmd = GSM_CMD_CPBS_GET; /* First get memory */
- } else {
- GSM_MSG_VAR_REF(msg).cmd = GSM_CMD_CPBS_SET; /* First set memory */
- }
-
- GSM_MSG_VAR_REF(msg).msg.pb_search.mem = mem;
- GSM_MSG_VAR_REF(msg).msg.pb_search.search = search;
- GSM_MSG_VAR_REF(msg).msg.pb_search.entries = entries;
- GSM_MSG_VAR_REF(msg).msg.pb_search.etr = etr;
- GSM_MSG_VAR_REF(msg).msg.pb_search.er = er;
-
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 60000);
-}
-
-#endif /* GSM_CFG_PHONEBOOK || __DOXYGEN__ */
diff --git a/gsm_at_lib/src/gsm/gsm_sim.c b/gsm_at_lib/src/gsm/gsm_sim.c
deleted file mode 100644
index 371790ee..00000000
--- a/gsm_at_lib/src/gsm/gsm_sim.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/**
- * \file gsm_sim.c
- * \brief SIM API
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#include "gsm/gsm_private.h"
-#include "gsm/gsm_sim.h"
-#include "gsm/gsm_mem.h"
-
-/**
- * \brief Get current cached SIM state from stack
- * \note Information is always valid, starting after successful device reset using \ref gsm_reset function call
- * \return Member of \ref gsm_sim_state_t enumeration
- */
-gsm_sim_state_t
-gsm_sim_get_current_state(void) {
- gsm_sim_state_t state;
- gsm_core_lock();
- state = gsm.m.sim.state;
- gsm_core_unlock();
- return state;
-}
-
-/**
- * \brief Enter pin code to unlock SIM
- * \param[in] pin: Pin code in string format
- * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
- * \param[in] evt_arg: Custom argument for event callback function
- * \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
- */
-gsmr_t
-gsm_sim_pin_enter(const char* pin,
- const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
-
- GSM_ASSERT("pin != NULL", pin != NULL);
-
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_CPIN_SET;
- GSM_MSG_VAR_REF(msg).cmd = GSM_CMD_CPIN_GET;
- GSM_MSG_VAR_REF(msg).msg.cpin_enter.pin = pin;
-
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 30000);
-}
-
-/**
- * \brief Add pin number to open SIM card
- * \note Use this function only if your SIM card doesn't have PIN code.
- * If you wish to change current pin, use \ref gsm_sim_pin_change instead
- * \param[in] pin: Current SIM pin code
- * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
- * \param[in] evt_arg: Custom argument for event callback function
- * \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
- */
-gsmr_t
-gsm_sim_pin_add(const char* pin,
- const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
-
- GSM_ASSERT("pin != NULL", pin != NULL);
-
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_CPIN_ADD;
- GSM_MSG_VAR_REF(msg).msg.cpin_add.pin = pin;
-
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 10000);
-}
-
-/**
- * \brief Change current pin code
- * \param[in] pin: Current pin code
- * \param[in] new_pin: New pin code
- * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
- * \param[in] evt_arg: Custom argument for event callback function
- * \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
- */
-gsmr_t
-gsm_sim_pin_change(const char* pin, const char* new_pin,
- const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
-
- GSM_ASSERT("pin != NULL", pin != NULL);
- GSM_ASSERT("new_pin != NULL", new_pin != NULL);
-
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_CPIN_CHANGE;
- GSM_MSG_VAR_REF(msg).msg.cpin_change.current_pin = pin;
- GSM_MSG_VAR_REF(msg).msg.cpin_change.new_pin = new_pin;
-
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 10000);
-}
-
-/**
- * \brief Remove pin code from SIM
- * \param[in] pin: Current pin code
- * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
- * \param[in] evt_arg: Custom argument for event callback function
- * \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
- */
-gsmr_t
-gsm_sim_pin_remove(const char* pin,
- const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
-
- GSM_ASSERT("pin != NULL", pin != NULL);
-
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_CPIN_REMOVE;
- GSM_MSG_VAR_REF(msg).msg.cpin_remove.pin = pin;
-
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 10000);
-}
-
-/**
- * \brief Enter PUK code and new PIN to unlock SIM card
- * \param[in] puk: PUK code associated with SIM card
- * \param[in] new_pin: New PIN code to use
- * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
- * \param[in] evt_arg: Custom argument for event callback function
- * \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
- */
-gsmr_t
-gsm_sim_puk_enter(const char* puk, const char* new_pin,
- const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
-
- GSM_ASSERT("puk != NULL", puk != NULL);
- GSM_ASSERT("new_pin != NULL", new_pin != NULL);
-
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GMM_CMD_CPUK_SET;
- GSM_MSG_VAR_REF(msg).msg.cpuk_enter.puk = puk;
- GSM_MSG_VAR_REF(msg).msg.cpuk_enter.pin = new_pin;
-
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 10000);
-}
diff --git a/gsm_at_lib/src/gsm/gsm_sms.c b/gsm_at_lib/src/gsm/gsm_sms.c
deleted file mode 100644
index 39dd449d..00000000
--- a/gsm_at_lib/src/gsm/gsm_sms.c
+++ /dev/null
@@ -1,346 +0,0 @@
-/**
- * \file gsm_sms.c
- * \brief SMS API
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#include "gsm/gsm_private.h"
-#include "gsm/gsm_sms.h"
-#include "gsm/gsm_mem.h"
-
-#if GSM_CFG_SMS || __DOXYGEN__
-
-#define GSM_SMS_OPERATION_IDX 0 /*!< Operation index for memory array (read, delete, list) */
-#define GSM_SMS_SEND_IDX 1 /*!< Send index for memory array */
-#define GSM_SMS_RECEIVE_IDX 2 /*!< Receive index for memory array */
-
-#if !__DOXYGEN__
-#define CHECK_ENABLED() if (!(check_enabled() == gsmOK)) { return gsmERRNOTENABLED; }
-#define CHECK_READY() if (!(check_ready() == gsmOK)) { return gsmERR; }
-#endif /* !__DOXYGEN__ */
-
-/**
- * \brief Check if sms is enabled
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
- */
-static gsmr_t
-check_enabled(void) {
- gsmr_t res;
- gsm_core_lock();
- res = gsm.m.sms.enabled ? gsmOK : gsmERR;
- gsm_core_unlock();
- return res;
-}
-
-/**
- * \brief Check if SMS is available
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
- */
-static gsmr_t
-check_ready(void) {
- gsmr_t res;
- gsm_core_lock();
- res = gsm.m.sms.ready ? gsmOK : gsmERR;
- gsm_core_unlock();
- return res;
-}
-
-/**
- * \brief Check if input memory is available in modem
- * \param[in] mem: Memory to test
- * \param[in] can_curr: Flag indicates if \ref GSM_MEM_CURRENT option can be used
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
- */
-static gsmr_t
-check_sms_mem(gsm_mem_t mem, uint8_t can_curr) {
- gsmr_t res = gsmERRMEM;
- gsm_core_lock();
- if ((mem < GSM_MEM_END && gsm.m.sms.mem[GSM_SMS_OPERATION_IDX].mem_available & (1 << (uint32_t)mem)) ||
- (can_curr && mem == GSM_MEM_CURRENT)) {
- res = gsmOK;
- }
- gsm_core_unlock();
- return res;
-}
-
-/**
- * \brief Enable SMS functionality
- * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
- * \param[in] evt_arg: Custom argument for event callback function
- * \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
- */
-gsmr_t
-gsm_sms_enable(const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
-
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_SMS_ENABLE;
- GSM_MSG_VAR_REF(msg).cmd = GSM_CMD_CPMS_GET_OPT;
-
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 60000);
-}
-
-/**
- * \brief Disable SMS functionality
- * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
- * \param[in] evt_arg: Custom argument for event callback function
- * \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
- */
-gsmr_t
-gsm_sms_disable(const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- gsm_core_lock();
- gsm.m.sms.enabled = 0;
- if (evt_fn != NULL) {
- evt_fn(gsmOK, evt_arg);
- }
- gsm_core_unlock();
- GSM_UNUSED(blocking);
- return gsmOK;
-}
-
-/**
- * \brief Send SMS text to phone number
- * \param[in] num: String number
- * \param[in] text: Text to send. Maximal `160` characters
- * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
- * \param[in] evt_arg: Custom argument for event callback function
- * \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
- */
-gsmr_t
-gsm_sms_send(const char* num, const char* text,
- const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
-
- GSM_ASSERT("num != NULL && num[0] > 0", num != NULL && num[0] > 0);
- GSM_ASSERT("text != NULL && text[0] > 0 && strlen(text) <= 160", text != NULL && text[0] > 0 && strlen(text) <= 160);
- CHECK_ENABLED(); /* Check if enabled */
- CHECK_READY(); /* Check if ready */
-
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_CMGS;
- GSM_MSG_VAR_REF(msg).cmd = GSM_CMD_CMGF;
- GSM_MSG_VAR_REF(msg).msg.sms_send.num = num;
- GSM_MSG_VAR_REF(msg).msg.sms_send.text = text;
- GSM_MSG_VAR_REF(msg).msg.sms_send.format = 1; /* Send as plain text */
-
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 60000);
-}
-
-/**
- * \brief Read SMS entry at specific memory and position
- * \param[in] mem: Memory used to read message from
- * \param[in] pos: Position number in memory to read
- * \param[out] entry: Pointer to SMS entry structure to fill data to
- * \param[in] update: Flag indicates update. Set to `1` to change `UNREAD` messages to `READ` or `0` to leave as is
- * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
- * \param[in] evt_arg: Custom argument for event callback function
- * \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
- */
-gsmr_t
-gsm_sms_read(gsm_mem_t mem, size_t pos, gsm_sms_entry_t* entry, uint8_t update,
- const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
-
- GSM_ASSERT("entry != NULL", entry != NULL);
- CHECK_ENABLED(); /* Check if enabled */
- CHECK_READY(); /* Check if ready */
- GSM_ASSERT("check_sms_mem() == gsmOK", check_sms_mem(mem, 1) == gsmOK);
-
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
-
- GSM_MEMSET(entry, 0x00, sizeof(*entry)); /* Reset data structure */
-
- entry->mem = mem; /* Set memory */
- entry->pos = pos; /* Set device position */
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_CMGR;
- if (mem == GSM_MEM_CURRENT) { /* Should be always false */
- GSM_MSG_VAR_REF(msg).cmd = GSM_CMD_CPMS_GET; /* First get memory */
- } else {
- GSM_MSG_VAR_REF(msg).cmd = GSM_CMD_CPMS_SET; /* First set memory */
- }
- GSM_MSG_VAR_REF(msg).msg.sms_read.mem = mem;
- GSM_MSG_VAR_REF(msg).msg.sms_read.pos = pos;
- GSM_MSG_VAR_REF(msg).msg.sms_read.entry = entry;
- GSM_MSG_VAR_REF(msg).msg.sms_read.update = update;
- GSM_MSG_VAR_REF(msg).msg.sms_read.format = 1; /* Send as plain text */
-
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 60000);
-}
-
-/**
- * \brief Delete SMS entry at specific memory and position
- * \param[in] mem: Memory used to read message from
- * \param[in] pos: Position number in memory to read
- * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
- * \param[in] evt_arg: Custom argument for event callback function
- * \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
- */
-gsmr_t
-gsm_sms_delete(gsm_mem_t mem, size_t pos,
- const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
-
- CHECK_ENABLED(); /* Check if enabled */
- CHECK_READY(); /* Check if ready */
- GSM_ASSERT("check_sms_mem() == gsmOK", check_sms_mem(mem, 1) == gsmOK);
-
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_CMGD;
- if (mem == GSM_MEM_CURRENT) { /* Should be always false */
- GSM_MSG_VAR_REF(msg).cmd = GSM_CMD_CPMS_GET; /* First get memory */
- } else {
- GSM_MSG_VAR_REF(msg).cmd = GSM_CMD_CPMS_SET; /* First set memory */
- }
- GSM_MSG_VAR_REF(msg).msg.sms_delete.mem = mem;
- GSM_MSG_VAR_REF(msg).msg.sms_delete.pos = pos;
-
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 1000);
-}
-
-/**
- * \brief Delete all SMS entries with specific status
- * \param[in] status: SMS status. This parameter can be one of all possible types in \ref gsm_sms_status_t enumeration
- * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
- * \param[in] evt_arg: Custom argument for event callback function
- * \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
- */
-gsmr_t
-gsm_sms_delete_all(gsm_sms_status_t status,
- const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
-
- CHECK_ENABLED(); /* Check if enabled */
- CHECK_READY(); /* Check if ready */
-
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_CMGDA;
- GSM_MSG_VAR_REF(msg).cmd = GSM_CMD_CMGF; /* By default format = 1 */
- GSM_MSG_VAR_REF(msg).msg.sms_delete_all.status = status;
-
- /* This command may take a while */
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 60000);
-}
-
-/**
- * \brief List SMS from SMS memory
- * \param[in] mem: Memory to read entries from. Use \ref GSM_MEM_CURRENT to read from current memory
- * \param[in] stat: SMS status to read, either `read`, `unread`, `sent`, `unsent` or `all`
- * \param[out] entries: Pointer to array to save SMS entries
- * \param[in] etr: Number of entries to read
- * \param[out] er: Pointer to output variable to save number of entries in array
- * \param[in] update: Flag indicates update. Set to `1` to change `UNREAD` messages to `READ` or `0` to leave as is
- * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
- * \param[in] evt_arg: Custom argument for event callback function
- * \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
- */
-gsmr_t
-gsm_sms_list(gsm_mem_t mem, gsm_sms_status_t stat, gsm_sms_entry_t* entries, size_t etr, size_t* er, uint8_t update,
- const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
-
- GSM_ASSERT("entires != NULL", entries != NULL);
- GSM_ASSERT("etr > 0", etr > 0);
- CHECK_ENABLED(); /* Check if enabled */
- CHECK_READY(); /* Check if ready */
- GSM_ASSERT("check_sms_mem() == gsmOK", check_sms_mem(mem, 1) == gsmOK);
-
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
-
- if (er != NULL) {
- *er = 0;
- }
- GSM_MEMSET(entries, 0x00, sizeof(*entries) * etr); /* Reset data structure */
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_CMGL;
- if (mem == GSM_MEM_CURRENT) { /* Should be always false */
- GSM_MSG_VAR_REF(msg).cmd = GSM_CMD_CPMS_GET; /* First get memory */
- } else {
- GSM_MSG_VAR_REF(msg).cmd = GSM_CMD_CPMS_SET; /* First set memory */
- }
- GSM_MSG_VAR_REF(msg).msg.sms_list.mem = mem;
- GSM_MSG_VAR_REF(msg).msg.sms_list.status = stat;
- GSM_MSG_VAR_REF(msg).msg.sms_list.entries = entries;
- GSM_MSG_VAR_REF(msg).msg.sms_list.etr = etr;
- GSM_MSG_VAR_REF(msg).msg.sms_list.er = er;
- GSM_MSG_VAR_REF(msg).msg.sms_list.update = update;
- GSM_MSG_VAR_REF(msg).msg.sms_list.format = 1; /* Send as plain text */
-
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 60000);
-}
-
-/**
- * \brief Set preferred storage for SMS
- * \param[in] mem1: Preferred memory for read/delete SMS operations. Use \ref GSM_MEM_CURRENT to keep it as is
- * \param[in] mem2: Preferred memory for sent/write SMS operations. Use \ref GSM_MEM_CURRENT to keep it as is
- * \param[in] mem3: Preferred memory for received SMS entries. Use \ref GSM_MEM_CURRENT to keep it as is
- * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
- * \param[in] evt_arg: Custom argument for event callback function
- * \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
- */
-gsmr_t
-gsm_sms_set_preferred_storage(gsm_mem_t mem1, gsm_mem_t mem2, gsm_mem_t mem3,
- const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
-
- CHECK_ENABLED(); /* Check if enabled */
- CHECK_READY(); /* Check if ready */
- GSM_ASSERT("check_sms_mem(1) == gsmOK", check_sms_mem(mem1, 1) == gsmOK);
- GSM_ASSERT("check_sms_mem(2) == gsmOK", check_sms_mem(mem2, 1) == gsmOK);
- GSM_ASSERT("check_sms_mem(3) == gsmOK", check_sms_mem(mem3, 1) == gsmOK);
-
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_CPMS_SET;
-
- /* In case any of memories is set to current, read current status first from device */
- if (mem1 == GSM_MEM_CURRENT || mem2 == GSM_MEM_CURRENT || mem3 == GSM_MEM_CURRENT) {
- GSM_MSG_VAR_REF(msg).cmd = GSM_CMD_CPMS_GET;
- }
- GSM_MSG_VAR_REF(msg).msg.sms_memory.mem[0] = mem1;
- GSM_MSG_VAR_REF(msg).msg.sms_memory.mem[1] = mem2;
- GSM_MSG_VAR_REF(msg).msg.sms_memory.mem[2] = mem3;
-
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 60000);
-}
-
-#endif /* GSM_CFG_SMS || __DOXYGEN__ */
diff --git a/gsm_at_lib/src/include/gsm/apps/gsm_mqtt_client_api.h b/gsm_at_lib/src/include/gsm/apps/gsm_mqtt_client_api.h
deleted file mode 100644
index 4b3c4896..00000000
--- a/gsm_at_lib/src/include/gsm/apps/gsm_mqtt_client_api.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/**
- * \file gsm_mqtt_client_api.h
- * \brief MQTT client API
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#ifndef GSM_HDR_APP_MQTT_CLIENT_API_H
-#define GSM_HDR_APP_MQTT_CLIENT_API_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "gsm/gsm.h"
-#include "gsm/apps/gsm_mqtt_client.h"
-
-/**
- * \ingroup GSM_APPS
- * \defgroup GSM_APP_MQTT_CLIENT_API MQTT client API
- * \brief Sequential, single thread MQTT client API
- * \{
- */
-
-/**
- * \brief MQTT API client structure
- */
-struct gsm_mqtt_client_api;
-
-/**
- * \brief MQTT API RX buffer
- */
-typedef struct gsm_mqtt_client_api_buf {
- char* topic; /*!< Topic data */
- size_t topic_len; /*!< Topic length */
- uint8_t* payload; /*!< Payload data */
- size_t payload_len; /*!< Payload length */
- gsm_mqtt_qos_t qos; /*!< Quality of service */
-} gsm_mqtt_client_api_buf_t;
-
-/**
- * \brief Pointer to \ref gsm_mqtt_client_api structure
- */
-typedef struct gsm_mqtt_client_api* gsm_mqtt_client_api_p;
-
-/**
- * \brief Pointer to \ref gsm_mqtt_client_api_buf_t structure
- */
-typedef struct gsm_mqtt_client_api_buf* gsm_mqtt_client_api_buf_p;
-
-gsm_mqtt_client_api_p gsm_mqtt_client_api_new(size_t tx_buff_len, size_t rx_buff_len);
-void gsm_mqtt_client_api_delete(gsm_mqtt_client_api_p client);
-gsm_mqtt_conn_status_t gsm_mqtt_client_api_connect(gsm_mqtt_client_api_p client, const char* host, gsm_port_t port, const gsm_mqtt_client_info_t* info);
-gsmr_t gsm_mqtt_client_api_close(gsm_mqtt_client_api_p client);
-gsmr_t gsm_mqtt_client_api_subscribe(gsm_mqtt_client_api_p client, const char* topic, gsm_mqtt_qos_t qos);
-gsmr_t gsm_mqtt_client_api_unsubscribe(gsm_mqtt_client_api_p client, const char* topic);
-gsmr_t gsm_mqtt_client_api_publish(gsm_mqtt_client_api_p client, const char* topic, const void* data, size_t btw, gsm_mqtt_qos_t qos, uint8_t retain);
-uint8_t gsm_mqtt_client_api_is_connected(gsm_mqtt_client_api_p client);
-gsmr_t gsm_mqtt_client_api_receive(gsm_mqtt_client_api_p client, gsm_mqtt_client_api_buf_p* p, uint32_t timeout);
-void gsm_mqtt_client_api_buf_free(gsm_mqtt_client_api_buf_p p);
-
-/**
- * \}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GSM_HDR_APP_MQTT_CLIENT_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_conn.h b/gsm_at_lib/src/include/gsm/gsm_conn.h
deleted file mode 100644
index d8864abf..00000000
--- a/gsm_at_lib/src/include/gsm/gsm_conn.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * \file gsm_conn.h
- * \brief Connection API
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#ifndef GSM_HDR_CONN_H
-#define GSM_HDR_CONN_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "gsm/gsm.h"
-
-/**
- * \ingroup GSM
- * \defgroup GSM_CONN Connection API
- * \brief Connection API functions
- * \{
- */
-
-gsmr_t gsm_conn_start(gsm_conn_p* conn, gsm_conn_type_t type, const char* const host, gsm_port_t port, void* const arg, gsm_evt_fn conn_evt_fn, const uint32_t blocking);
-gsmr_t gsm_conn_close(gsm_conn_p conn, const uint32_t blocking);
-gsmr_t gsm_conn_send(gsm_conn_p conn, const void* data, size_t btw, size_t* const bw, const uint32_t blocking);
-gsmr_t gsm_conn_sendto(gsm_conn_p conn, const gsm_ip_t* const ip, gsm_port_t port, const void* data, size_t btw, size_t* bw, const uint32_t blocking);
-gsmr_t gsm_conn_set_arg(gsm_conn_p conn, void* const arg);
-void * gsm_conn_get_arg(gsm_conn_p conn);
-uint8_t gsm_conn_is_client(gsm_conn_p conn);
-uint8_t gsm_conn_is_active(gsm_conn_p conn);
-uint8_t gsm_conn_is_closed(gsm_conn_p conn);
-int8_t gsm_conn_getnum(gsm_conn_p conn);
-gsmr_t gsm_get_conns_status(const uint32_t blocking);
-gsm_conn_p gsm_conn_get_from_evt(gsm_evt_t* evt);
-gsmr_t gsm_conn_write(gsm_conn_p conn, const void* data, size_t btw, uint8_t flush, size_t* const mem_available);
-gsmr_t gsm_conn_recved(gsm_conn_p conn, gsm_pbuf_p pbuf);
-size_t gsm_conn_get_total_recved_count(gsm_conn_p conn);
-
-uint8_t gsm_conn_get_remote_ip(gsm_conn_p conn, gsm_ip_t* ip);
-gsm_port_t gsm_conn_get_remote_port(gsm_conn_p conn);
-gsm_port_t gsm_conn_get_local_port(gsm_conn_p conn);
-
-/**
- * \}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GSM_HDR_CONN_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_debug.h b/gsm_at_lib/src/include/gsm/gsm_debug.h
deleted file mode 100644
index 6d4b6116..00000000
--- a/gsm_at_lib/src/include/gsm/gsm_debug.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/**
- * \file gsm_debug.h
- * \brief Debugging inside GSM stack
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#ifndef GSM_HDR_DEBUG_H
-#define GSM_HDR_DEBUG_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include
-#include
-
-/**
- * \ingroup GSM
- * \defgroup GSM_DEBUG Debugging support
- * \brief Debugging support module to track stack
- * \{
- */
-
-#define GSM_DBG_ON 0x80 /*!< Indicates debug is enabled */
-#define GSM_DBG_OFF 0 /*!< Indicates debug is disabled */
-
-/**
- * \anchor GSM_DBG_LVL
- * \name Debug levels
- * \brief List of debug levels
- * \{
- */
-
-#define GSM_DBG_LVL_ALL 0x00 /*!< Print all messages of all types */
-#define GSM_DBG_LVL_WARNING 0x01 /*!< Print warning and upper messages */
-#define GSM_DBG_LVL_DANGER 0x02 /*!< Print danger errors */
-#define GSM_DBG_LVL_SEVERE 0x03 /*!< Print severe problems affecting program flow */
-#define GSM_DBG_LVL_MASK 0x03 /*!< Mask for getting debug level */
-
-/**
- * \}
- */
-
-/**
- * \anchor GSM_DBG_TYPE
- * \name Debug types
- * \brief List of possible debugging types
- * \{
- */
-
-#define GSM_DBG_TYPE_TRACE 0x40 /*!< Debug trace messages for program flow */
-#define GSM_DBG_TYPE_STATE 0x20 /*!< Debug state messages (such as state machines) */
-#define GSM_DBG_TYPE_ALL (GSM_DBG_TYPE_TRACE | GSM_DBG_TYPE_STATE) /*!< All debug types */
-
-/**
- * \}
- */
-
-#if GSM_CFG_DBG && !defined(GSM_CFG_DBG_OUT)
-#warning "GSM_CFG_DBG_OUT is not defined but debugging is enabled!"
-#endif
-
-#if (GSM_CFG_DBG && defined(GSM_CFG_DBG_OUT)) || __DOXYGEN__
-/**
- * \brief Print message to the debug "window" if enabled
- * \param[in] c: Condition if debug of specific type is enabled
- * \param[in] fmt: Formatted string for debug
- * \param[in] ...: Variable parameters for formatted string
- */
-#define GSM_DEBUGF(c, fmt, ...) do {\
- if (((c) & (GSM_DBG_ON)) && ((c) & (GSM_CFG_DBG_TYPES_ON)) && ((c) & GSM_DBG_LVL_MASK) >= (GSM_CFG_DBG_LVL_MIN)) { \
- GSM_CFG_DBG_OUT(fmt, ## __VA_ARGS__); \
- } \
-} while (0)
-
-/**
- * \brief Print message to the debug "window" if enabled when specific condition is met
- * \param[in] c: Condition if debug of specific type is enabled
- * \param[in] cond: Debug only if this condition is true
- * \param[in] fmt: Formatted string for debug
- * \param[in] ...: Variable parameters for formatted string
- */
-#define GSM_DEBUGW(c, cond, fmt, ...) do {\
- if (cond) { \
- GSM_DEBUGF(c, fmt, ## __VA_ARGS__); \
- } \
-} while (0)
-#else
-#undef GSM_CFG_DBG
-#define GSM_CFG_DBG GSM_DBG_OFF
-#define GSM_DEBUGF(c, fmt, ...)
-#define GSM_DEBUGW(c, cond, fmt, ...)
-#endif /* (GSM_CFG_DBG && defined(GSM_CFG_DBG_OUT)) || __DOXYGEN__ */
-
-/**
- * \}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GSM_HDR_DEBUG_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_evt.h b/gsm_at_lib/src/include/gsm/gsm_evt.h
deleted file mode 100644
index 5dc5a5e2..00000000
--- a/gsm_at_lib/src/include/gsm/gsm_evt.h
+++ /dev/null
@@ -1,272 +0,0 @@
-/**
- * \file gsm_evt.h
- * \brief Event helper functions
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#ifndef GSM_HDR_EVT_H
-#define GSM_HDR_EVT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "gsm/gsm.h"
-
-/**
- * \ingroup GSM
- * \defgroup GSM_EVT Events management
- * \brief Event helper functions
- * \{
- */
-
-gsmr_t gsm_evt_register(gsm_evt_fn fn);
-gsmr_t gsm_evt_unregister(gsm_evt_fn fn);
-gsm_evt_type_t gsm_evt_get_type(gsm_evt_t* cc);
-
-/**
- * \anchor GSM_EVT_RESET
- * \name Reset event
- * \brief Event helper functions for \ref GSM_EVT_RESET event
- */
-
-gsmr_t gsm_evt_reset_get_result(gsm_evt_t* cc);
-
-/**
- * \}
- */
-
-/**
- * \anchor GSM_EVT_RESTORE
- * \name Restore event
- * \brief Event helper functions for \ref GSM_EVT_RESTORE event
- */
-
-gsmr_t gsm_evt_restore_get_result(gsm_evt_t* cc);
-
-/**
- * \}
- */
-
-/**
- * \anchor GSM_EVT_NETWORK_OPERATOR_CURRENT
- * \name Current network operator
- * \brief Event helper functions for \ref GSM_EVT_NETWORK_OPERATOR_CURRENT event
- */
-
-const gsm_operator_curr_t* gsm_evt_network_operator_get_current(gsm_evt_t* cc);
-
-/**
- * \}
- */
-
-/**
- * \anchor GSM_EVT_CONN_RECV
- * \name Connection data received
- * \brief Event helper functions for \ref GSM_EVT_CONN_RECV event
- */
-
-gsm_pbuf_p gsm_evt_conn_recv_get_buff(gsm_evt_t* cc);
-gsm_conn_p gsm_evt_conn_recv_get_conn(gsm_evt_t* cc);
-
-/**
- * \}
- */
-
-/**
- * \anchor GSM_EVT_CONN_SEND
- * \name Connection data send
- * \brief Event helper functions for \ref GSM_EVT_CONN_SEND event
- */
-
-gsm_conn_p gsm_evt_conn_send_get_conn(gsm_evt_t* cc);
-size_t gsm_evt_conn_send_get_length(gsm_evt_t* cc);
-gsmr_t gsm_evt_conn_send_get_result(gsm_evt_t* cc);
-
-/**
- * \}
- */
-
-/**
- * \anchor GSM_EVT_CONN_ACTIVE
- * \name Connection active
- * \brief Event helper functions for \ref GSM_EVT_CONN_ACTIVE event
- */
-
-gsm_conn_p gsm_evt_conn_active_get_conn(gsm_evt_t* cc);
-uint8_t gsm_evt_conn_active_is_client(gsm_evt_t* cc);
-
-/**
- * \}
- */
-
-/**
- * \anchor GSM_EVT_CONN_CLOSE
- * \name Connection close event
- * \brief Event helper functions for \ref GSM_EVT_CONN_CLOSE event
- */
-
-gsm_conn_p gsm_evt_conn_close_get_conn(gsm_evt_t* cc);
-uint8_t gsm_evt_conn_close_is_client(gsm_evt_t* cc);
-uint8_t gsm_evt_conn_close_is_forced(gsm_evt_t* cc);
-gsmr_t gsm_evt_conn_close_get_result(gsm_evt_t* cc);
-
-/**
- * \}
- */
-
-/**
- * \anchor GSM_EVT_CONN_POLL
- * \name Connection poll
- * \brief Event helper functions for \ref GSM_EVT_CONN_POLL event
- */
-
-gsm_conn_p gsm_evt_conn_poll_get_conn(gsm_evt_t* cc);
-
-/**
- * \}
- */
-
-/**
- * \anchor GSM_EVT_CONN_ERROR
- * \name Connection error
- * \brief Event helper functions for \ref GSM_EVT_CONN_ERROR event
- */
-
-gsmr_t gsm_evt_conn_error_get_error(gsm_evt_t* cc);
-gsm_conn_type_t gsm_evt_conn_error_get_type(gsm_evt_t* cc);
-const char* gsm_evt_conn_error_get_host(gsm_evt_t* cc);
-gsm_port_t gsm_evt_conn_error_get_port(gsm_evt_t* cc);
-void* gsm_evt_conn_error_get_arg(gsm_evt_t* cc);
-
-/**
- * \}
- */
-
-/**
- * \anchor GSM_EVT_SIGNAL_STRENGTH
- * \name Signal strength
- * \brief Event helper functions for \ref GSM_EVT_CONN_RECV event
- */
-
-int16_t gsm_evt_signal_strength_get_rssi(gsm_evt_t* cc);
-
-/**
- * \}
- */
-
-/**
- * \anchor GSM_EVT_SMS_RECV
- * \name SMS received
- * \brief Event helper functions for \ref GSM_EVT_SMS_RECV event
- */
-
-size_t gsm_evt_sms_recv_get_pos(gsm_evt_t* cc);
-gsm_mem_t gsm_evt_sms_recv_get_mem(gsm_evt_t* cc);
-
-/**
- * \}
- */
-
-/**
- * \anchor GSM_EVT_SMS_READ
- * \name SMS content read
- * \brief Event helper functions for \ref GSM_EVT_SMS_READ event
- */
-
-gsm_sms_entry_t* gsm_evt_sms_read_get_entry(gsm_evt_t* cc);
-gsmr_t gsm_evt_sms_read_get_result(gsm_evt_t* cc);
-
-/**
- * \}
- */
-
-/**
- * \anchor GSM_EVT_SMS_SEND
- * \name SMS send
- * \brief Event helper functions for \ref GSM_EVT_SMS_SEND event
- */
-
-gsmr_t gsm_evt_sms_send_get_result(gsm_evt_t* cc);
-size_t gsm_evt_sms_send_get_pos(gsm_evt_t* cc);
-
-/**
- * \}
- */
-
-/**
- * \anchor GSM_EVT_SMS_DELETE
- * \name SMS delete
- * \brief Event helper functions for \ref GSM_EVT_SMS_DELETE event
- */
-
-gsmr_t gsm_evt_sms_delete_get_result(gsm_evt_t* cc);
-size_t gsm_evt_sms_delete_get_pos(gsm_evt_t* cc);
-gsm_mem_t gsm_evt_sms_delete_get_mem(gsm_evt_t* cc);
-
-/**
- * \}
- */
-
-/**
- * \anchor GSM_EVT_CALL_CHANGED
- * \name Call status changed
- * \brief Event helper functions for \ref GSM_EVT_CALL_CHANGED event
- */
-
-const gsm_call_t* gsm_evt_call_changed_get_call(gsm_evt_t* cc);
-
-/**
- * \}
- */
-
-/**
- * \anchor GSM_EVT_OPERATOR_SCAN
- * \name Operator scan
- * \brief Event helper functions for \ref GSM_EVT_OPERATOR_SCAN event
- */
-
-gsmr_t gsm_evt_operator_scan_get_result(gsm_evt_t* cc);
-gsm_operator_t* gsm_evt_operator_scan_get_entries(gsm_evt_t* cc);
-size_t gsm_evt_operator_scan_get_length(gsm_evt_t* cc);
-
-/**
- * \}
- */
-
-/**
- * \}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GSM_HDR_EVT_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_includes.h b/gsm_at_lib/src/include/gsm/gsm_includes.h
deleted file mode 100644
index a3a5fa0b..00000000
--- a/gsm_at_lib/src/include/gsm/gsm_includes.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * \file gsm_includes.h
- * \brief All main includes
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#ifndef GSM_HDR_INCLUDES_H
-#define GSM_HDR_INCLUDES_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#include "gsm_config.h"
-#include "gsm/gsm_typedefs.h"
-#include "gsm/gsm_buff.h"
-#include "gsm/gsm_input.h"
-#include "gsm/gsm_debug.h"
-#include "gsm/gsm_utils.h"
-#include "gsm/gsm_pbuf.h"
-#include "gsm/gsm_sim.h"
-#include "gsm/gsm_operator.h"
-#include "gsm/gsm_evt.h"
-#include "gsm/gsm_network.h"
-#include "gsm/gsm_device_info.h"
-#include "system/gsm_sys.h"
-
-#if GSM_CFG_SMS || __DOXYGEN__
-#include "gsm/gsm_sms.h"
-#endif /* GSM_CFG_SMS || __DOXYGEN__ */
-#if GSM_CFG_CALL || __DOXYGEN__
-#include "gsm/gsm_call.h"
-#endif /* GSM_CFG_CALL || __DOXYGEN__ */
-#if GSM_CFG_PHONEBOOK || __DOXYGEN__
-#include "gsm/gsm_phonebook.h"
-#endif /* GSM_CFG_PHONEBOOK || __DOXYGEN__ */
-#if GSM_CFG_CONN || __DOXYGEN__
-#include "gsm/gsm_conn.h"
-#endif /* GSM_CFG_CONN || __DOXYGEN__ */
-#if GSM_CFG_NETCONN || __DOXYGEN__
-#include "gsm/gsm_netconn.h"
-#endif /* GSM_CFG_NETCONN || __DOXYGEN__ */
-#if GSM_CFG_USSD || __DOXYGEN__
-#include "gsm/gsm_ussd.h"
-#endif /* GSM_CFG_USSD || __DOXYGEN__ */
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* GSM_HDR_INCLUDES_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_netconn.h b/gsm_at_lib/src/include/gsm/gsm_netconn.h
deleted file mode 100644
index 9d0dc870..00000000
--- a/gsm_at_lib/src/include/gsm/gsm_netconn.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/**
- * \file gsm_netconn.h
- * \brief API functions for sequential calls
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#ifndef GSM_HDR_NETCONN_H
-#define GSM_HDR_NETCONN_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#include "gsm/gsm.h"
-
-/**
- * \ingroup GSM_API
- * \defgroup GSM_NETCONN Network connection
- * \brief Network connection
- * \{
- */
-
-struct gsm_netconn;
-
-/**
- * \brief Netconn object structure
- */
-typedef struct gsm_netconn* gsm_netconn_p;
-
-/**
- * \brief Netconn connection type
- */
-typedef enum {
- GSM_NETCONN_TYPE_TCP = GSM_CONN_TYPE_TCP, /*!< TCP connection */
- GSM_NETCONN_TYPE_UDP = GSM_CONN_TYPE_UDP, /*!< UDP connection */
- GSM_NETCONN_TYPE_SSL = GSM_CONN_TYPE_SSL, /*!< TCP connection over SSL */
-} gsm_netconn_type_t;
-
-gsm_netconn_p gsm_netconn_new(gsm_netconn_type_t type);
-gsmr_t gsm_netconn_delete(gsm_netconn_p nc);
-gsmr_t gsm_netconn_connect(gsm_netconn_p nc, const char* host, gsm_port_t port);
-gsmr_t gsm_netconn_receive(gsm_netconn_p nc, gsm_pbuf_p* pbuf);
-gsmr_t gsm_netconn_close(gsm_netconn_p nc);
-int8_t gsm_netconn_getconnnum(gsm_netconn_p nc);
-void gsm_netconn_set_receive_timeout(gsm_netconn_p nc, uint32_t timeout);
-uint32_t gsm_netconn_get_receive_timeout(gsm_netconn_p nc);
-
-/* TCP only */
-gsmr_t gsm_netconn_write(gsm_netconn_p nc, const void* data, size_t btw);
-gsmr_t gsm_netconn_flush(gsm_netconn_p nc);
-
-/* UDP only */
-gsmr_t gsm_netconn_send(gsm_netconn_p nc, const void* data, size_t btw);
-gsmr_t gsm_netconn_sendto(gsm_netconn_p nc, const gsm_ip_t* ip, gsm_port_t port, const void* data, size_t btw);
-
-/**
- * \}
- */
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* GSM_HDR_NETCONN_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_parser.h b/gsm_at_lib/src/include/gsm/gsm_parser.h
deleted file mode 100644
index d772e7ae..00000000
--- a/gsm_at_lib/src/include/gsm/gsm_parser.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * \file gsm_parser.h
- * \brief Parser of AT responses
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#ifndef GSM_HDR_PARSER_H
-#define GSM_HDR_PARSER_H
-
-#if defined(__cplusplus)
-extern "C" {
-#endif /* defined(__cplusplus) */
-
-#include "gsm/gsm.h"
-
-int32_t gsmi_parse_number(const char** str);
-uint8_t gsmi_parse_string(const char** src, char* dst, size_t dst_len, uint8_t trim);
-uint8_t gsmi_parse_ip(const char** src, gsm_ip_t* ip);
-uint8_t gsmi_parse_mac(const char** src, gsm_mac_t* mac);
-
-uint8_t gsmi_parse_cpin(const char* str, uint8_t send_evt);
-uint8_t gsmi_parse_creg(const char* str, uint8_t skip_first);
-uint8_t gsmi_parse_csq(const char* str);
-
-uint8_t gsmi_parse_cmgs(const char* str, size_t* num);
-uint8_t gsmi_parse_cmti(const char* str, uint8_t send_evt);
-uint8_t gsmi_parse_cmgr(const char* str);
-uint8_t gsmi_parse_cmgl(const char* str);
-
-uint8_t gsmi_parse_at_sdk_version(const char* str, uint32_t* version_out);
-
-uint8_t gsmi_parse_cops_scan(uint8_t ch, uint8_t reset);
-uint8_t gsmi_parse_cops(const char* str);
-uint8_t gsmi_parse_clcc(const char* str, uint8_t send_evt);
-
-uint8_t gsmi_parse_cpbs(const char* str, uint8_t opt);
-uint8_t gsmi_parse_cpms(const char* str, uint8_t opt);
-uint8_t gsmi_parse_cpbr(const char* str);
-uint8_t gsmi_parse_cpbf(const char* str);
-
-uint8_t gsmi_parse_cipstatus_conn(const char* str, uint8_t is_conn_line, uint8_t* continueScan);
-
-uint8_t gsmi_parse_ipd(const char* str);
-
-#if defined(__cplusplus)
-}
-#endif /* defined(__cplusplus) */
-
-#endif /* GSM_HDR_PARSER_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_pbuf.h b/gsm_at_lib/src/include/gsm/gsm_pbuf.h
deleted file mode 100644
index 1942c37d..00000000
--- a/gsm_at_lib/src/include/gsm/gsm_pbuf.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * \file gsm_pbuf.h
- * \brief Packet buffer manager
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#ifndef GSM_HDR_PBUF_H
-#define GSM_HDR_PBUF_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "gsm/gsm.h"
-
-/**
- * \ingroup GSM
- * \defgroup GSM_PBUF Packet buffer
- * \brief Packet buffer manager
- * \{
- */
-
-gsm_pbuf_p gsm_pbuf_new(size_t len);
-size_t gsm_pbuf_free(gsm_pbuf_p pbuf);
-void * gsm_pbuf_data(const gsm_pbuf_p pbuf);
-size_t gsm_pbuf_length(const gsm_pbuf_p pbuf, uint8_t tot);
-gsmr_t gsm_pbuf_take(gsm_pbuf_p pbuf, const void* data, size_t len, size_t offset);
-size_t gsm_pbuf_copy(gsm_pbuf_p pbuf, void* data, size_t len, size_t offset);
-
-gsmr_t gsm_pbuf_cat(gsm_pbuf_p head, const gsm_pbuf_p tail);
-gsmr_t gsm_pbuf_chain(gsm_pbuf_p head, gsm_pbuf_p tail);
-gsmr_t gsm_pbuf_ref(gsm_pbuf_p pbuf);
-
-uint8_t gsm_pbuf_get_at(const gsm_pbuf_p pbuf, size_t pos, uint8_t* el);
-size_t gsm_pbuf_memcmp(const gsm_pbuf_p pbuf, const void* data, size_t len, size_t offset);
-size_t gsm_pbuf_strcmp(const gsm_pbuf_p pbuf, const char* str, size_t offset);
-size_t gsm_pbuf_memfind(const gsm_pbuf_p pbuf, const void* data, size_t len, size_t off);
-size_t gsm_pbuf_strfind(const gsm_pbuf_p pbuf, const char* str, size_t off);
-
-uint8_t gsm_pbuf_advance(gsm_pbuf_p pbuf, int len);
-gsm_pbuf_p gsm_pbuf_skip(gsm_pbuf_p pbuf, size_t offset, size_t* new_offset);
-
-void * gsm_pbuf_get_linear_addr(const gsm_pbuf_p pbuf, size_t offset, size_t* new_len);
-
-void gsm_pbuf_set_ip(gsm_pbuf_p pbuf, const gsm_ip_t* ip, gsm_port_t port);
-
-/**
- * \}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GSM_HDR_PBUF_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_phonebook.h b/gsm_at_lib/src/include/gsm/gsm_phonebook.h
deleted file mode 100644
index b2a902e1..00000000
--- a/gsm_at_lib/src/include/gsm/gsm_phonebook.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * \file gsm_phonebook.h
- * \brief Phonebook API
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#ifndef GSM_HDR_PHONEBOOK_H
-#define GSM_HDR_PHONEBOOK_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "gsm/gsm.h"
-
-/**
- * \ingroup GSM
- * \defgroup GSM_PHONEBOOK Phonebook API
- * \brief Phonebook manager
- * \{
- */
-
-gsmr_t gsm_pb_enable(const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-gsmr_t gsm_pb_disable(const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-
-gsmr_t gsm_pb_add(gsm_mem_t mem, const char* name, const char* num, gsm_number_type_t type, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-gsmr_t gsm_pb_edit(gsm_mem_t mem, size_t pos, const char* name, const char* num, gsm_number_type_t type, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-gsmr_t gsm_pb_delete(gsm_mem_t mem, size_t pos, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-gsmr_t gsm_pb_read(gsm_mem_t mem, size_t pos, gsm_pb_entry_t* entry, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-gsmr_t gsm_pb_list(gsm_mem_t mem, size_t start_index, gsm_pb_entry_t* entries, size_t etr, size_t* er, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-gsmr_t gsm_pb_search(gsm_mem_t mem, const char* search, gsm_pb_entry_t* entries, size_t etr, size_t* er, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-
-/**
- * \}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GSM_HDR_PHONEBOOK_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_private.h b/gsm_at_lib/src/include/gsm/gsm_private.h
deleted file mode 100644
index 8b2adb5c..00000000
--- a/gsm_at_lib/src/include/gsm/gsm_private.h
+++ /dev/null
@@ -1,803 +0,0 @@
-/**
- * \file gsm_private.h
- * \brief Private structures and enumerations
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#ifndef __GSM_PRIV_H
-#define __GSM_PRIV_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#include "gsm/gsm.h"
-#include "gsm/gsm_typedefs.h"
-#include "gsm/gsm_debug.h"
-
-/**
- * \addtogroup GSM_TYPEDEFS
- * \{
- */
-
-/**
- * \brief List of possible messages
- */
-typedef enum {
- GSM_CMD_IDLE = 0, /*!< IDLE mode */
-
- /* Basic AT commands */
- GSM_CMD_RESET, /*!< Reset device */
- GSM_CMD_RESET_DEVICE_FIRST_CMD, /*!< Reset device first driver specific command */
- GSM_CMD_ATE0, /*!< Disable ECHO mode on AT commands */
- GSM_CMD_ATE1, /*!< Enable ECHO mode on AT commands */
- GSM_CMD_GSLP, /*!< Set GSM to sleep mode */
- GSM_CMD_RESTORE, /*!< Restore GSM internal settings to default values */
- GSM_CMD_UART,
-
- GSM_CMD_CGACT_SET_0,
- GSM_CMD_CGACT_SET_1,
- GSM_CMD_CGATT_SET_0,
- GSM_CMD_CGATT_SET_1,
- GSM_CMD_NETWORK_ATTACH, /*!< Attach to a network */
- GSM_CMD_NETWORK_DETACH, /*!< Detach from network */
-
- GSM_CMD_CIPMUX_SET,
- GSM_CMD_CIPRXGET_SET,
- GSM_CMD_CSTT_SET,
-
-
-
- /* AT commands according to the V.25TER */
- GSM_CMD_CALL_ENABLE,
- GSM_CMD_A, /*!< Re-issues the Last Command Given */
- GSM_CMD_ATA, /*!< Answer an Incoming Call */
- GSM_CMD_ATD, /*!< Mobile Originated Call to Dial A Number */
- GSM_CMD_ATD_N, /*!< Originate Call to Phone Number in Current Memory: ATD */
- GSM_CMD_ATD_STR, /*!< Originate Call to Phone Number in Memory Which Corresponds to Field "str": ATD>str */
- GSM_CMD_ATDL, /*!< Redial Last Telephone Number Used */
- GSM_CMD_ATE, /*!< Set Command Echo Mode */
- GSM_CMD_ATH, /*!< Disconnect Existing */
- GSM_CMD_ATI, /*!< Display Product Identification Information */
- GSM_CMD_ATL, /*!< Set Monitor speaker */
- GSM_CMD_ATM, /*!< Set Monitor Speaker Mode */
- GSM_CMD_PPP, /*!< Switch from Data Mode or PPP Online Mode to Command Mode, "+++" originally */
- GSM_CMD_ATO, /*!< Switch from Command Mode to Data Mode */
- GSM_CMD_ATP, /*!< Select Pulse Dialing */
- GSM_CMD_ATQ, /*!< Set Result Code Presentation Mode */
- GSM_CMD_ATS0, /*!< Set Number of Rings before Automatically Answering the Call */
- GSM_CMD_ATS3, /*!< Set Command Line Termination Character */
- GSM_CMD_ATS4, /*!< Set Response Formatting Character */
- GSM_CMD_ATS5, /*!< Set Command Line Editing Character */
- GSM_CMD_ATS6, /*!< Pause Before Blind */
- GSM_CMD_ATS7, /*!< Set Number of Seconds to Wait for Connection Completion */
- GSM_CMD_ATS8, /*!< Set Number of Seconds to Wait for Comma Dial Modifier Encountered in Dial String of D Command */
- GSM_CMD_ATS10, /*!< Set Disconnect Delay after Indicating the Absence of Data Carrier */
- GSM_CMD_ATT, /*!< Select Tone Dialing */
- GSM_CMD_ATV, /*!< TA Response Format */
- GSM_CMD_ATX, /*!< Set CONNECT Result Code Format and Monitor Call Progress */
- GSM_CMD_ATZ, /*!< Reset Default Configuration */
- GSM_CMD_AT_C, /*!< Set DCD Function Mode, AT&C */
- GSM_CMD_AT_D, /*!< Set DTR Function, AT&D */
- GSM_CMD_AT_F, /*!< Factory Defined Configuration, AT&F */
- GSM_CMD_AT_V, /*!< Display Current Configuration, AT&V */
- GSM_CMD_AT_W, /*!< Store Active Profile, AT&W */
- GSM_CMD_GCAP, /*!< Request Complete TA Capabilities List */
- GSM_CMD_GMI, /*!< Request Manufacturer Identification */
- GSM_CMD_GMM, /*!< Request TA Model Identification */
- GSM_CMD_GMR, /*!< Request TA Revision Identification of Software Release */
- GSM_CMD_GOI, /*!< Request Global Object Identification */
- GSM_CMD_GSN, /*!< Request TA Serial Number Identification (IMEI) */
- GSM_CMD_ICF, /*!< Set TE-TA Control Character Framing */
- GSM_CMD_IFC, /*!< Set TE-TA Local Data Flow Control */
- GSM_CMD_IPR, /*!< Set TE-TA Fixed Local Rate */
- GSM_CMD_HVOIC, /*!< Disconnect Voice Call Only */
-
- /* AT commands according to 3GPP TS 27.007 */
- GSM_CMD_COPS_SET, /*!< Set operator */
- GSM_CMD_COPS_GET, /*!< Get current operator */
- GSM_CMD_COPS_GET_OPT, /*!< Get a list of available operators */
- GSM_CMD_CPAS, /*!< Phone Activity Status */
- GSM_CMD_CGMI_GET, /*!< Request Manufacturer Identification */
- GSM_CMD_CGMM_GET, /*!< Request Model Identification */
- GSM_CMD_CGMR_GET, /*!< Request TA Revision Identification of Software Release */
- GSM_CMD_CGSN_GET, /*!< Request Product Serial Number Identification (Identical with +GSN) */
-
- GSM_CMD_CLCC_SET, /*!< List Current Calls of ME */
- GSM_CMD_CLCK, /*!< Facility Lock */
-
- GSM_CMD_CACM, /*!< Accumulated Call Meter (ACM) Reset or Query */
- GSM_CMD_CAMM, /*!< Accumulated Call Meter Maximum (ACM max) Set or Query */
- GSM_CMD_CAOC, /*!< Advice of Charge */
- GSM_CMD_CBST, /*!< Select Bearer Service Type */
- GSM_CMD_CCFC, /*!< Call Forwarding Number and Conditions Control */
- GSM_CMD_CCWA, /*!< Call Waiting Control */
- GSM_CMD_CEER, /*!< Extended Error Report */
- GSM_CMD_CSCS, /*!< Select TE Character Set */
- GSM_CMD_CSTA, /*!< Select Type of Address */
- GSM_CMD_CHLD, /*!< Call Hold and Multiparty */
- GSM_CMD_CIMI, /*!< Request International Mobile Subscriber Identity */
- GSM_CMD_CLIP, /*!< Calling Line Identification Presentation */
- GSM_CMD_CLIR, /*!< Calling Line Identification Restriction */
- GSM_CMD_CMEE_SET, /*!< Report Mobile Equipment Error */
- GSM_CMD_COLP, /*!< Connected Line Identification Presentation */
-
- GSM_CMD_PHONEBOOK_ENABLE,
- GSM_CMD_CPBF, /*!< Find Phonebook Entries */
- GSM_CMD_CPBR, /*!< Read Current Phonebook Entries */
- GSM_CMD_CPBS_SET, /*!< Select Phonebook Memory Storage */
- GSM_CMD_CPBS_GET, /*!< Get current Phonebook Memory Storage */
- GSM_CMD_CPBS_GET_OPT, /*!< Get available Phonebook Memory Storages */
- GSM_CMD_CPBW_SET, /*!< Write Phonebook Entry */
- GSM_CMD_CPBW_GET_OPT, /*!< Get options for write Phonebook Entry */
-
- GSM_CMD_SIM_PROCESS_BASIC_CMDS, /*!< Command setup, executed when SIM is in READY state */
- GSM_CMD_CPIN_SET, /*!< Enter PIN */
- GSM_CMD_CPIN_GET, /*!< Read current SIM status */
- GSM_CMD_CPIN_ADD, /*!< Add new PIN to SIM if pin is not set */
- GSM_CMD_CPIN_CHANGE, /*!< Change already active SIM */
- GSM_CMD_CPIN_REMOVE, /*!< Remove current PIN */
- GMM_CMD_CPUK_SET, /*!< Enter PUK and set new PIN */
-
- GSM_CMD_CSQ_GET, /*!< Signal Quality Report */
- GSM_CMD_CFUN_SET, /*!< Set Phone Functionality */
- GSM_CMD_CFUN_GET, /*!< Get Phone Functionality */
- GSM_CMD_CREG_SET, /*!< Network Registration set output */
- GSM_CMD_CREG_GET, /*!< Get current network registration status */
- GSM_CMD_CBC, /*!< Battery Charge */
- GSM_CMD_CNUM, /*!< Subscriber Number */
-
- GSM_CMD_CPWD, /*!< Change Password */
- GSM_CMD_CR, /*!< Service Reporting Control */
- GSM_CMD_CRC, /*!< Set Cellular Result Codes for Incoming Call Indication */
- GSM_CMD_CRLP, /*!< Select Radio Link Protocol Parameters */
- GSM_CMD_CRSM, /*!< Restricted SIM Access */
- GSM_CMD_VTD, /*!< Tone Duration */
- GSM_CMD_VTS, /*!< DTMF and Tone Generation */
- GSM_CMD_CMUX, /*!< Multiplexer Control */
- GSM_CMD_CPOL, /*!< Preferred Operator List */
- GSM_CMD_COPN, /*!< Read Operator Names */
- GSM_CMD_CCLK, /*!< Clock */
- GSM_CMD_CSIM, /*!< Generic SIM Access */
- GSM_CMD_CALM, /*!< Alert Sound Mode */
- GSM_CMD_CALS, /*!< Alert Sound Select */
- GSM_CMD_CRSL, /*!< Ringer Sound Level */
- GSM_CMD_CLVL, /*!< Loud Speaker Volume Level */
- GSM_CMD_CMUT, /*!< Mute Control */
- GSM_CMD_CPUC, /*!< Price Per Unit and Currency Table */
- GSM_CMD_CCWE, /*!< Call Meter Maximum Event */
- GSM_CMD_CUSD_SET, /*!< Unstructured Supplementary Service Data, Set command */
- GSM_CMD_CUSD_GET, /*!< Unstructured Supplementary Service Data, Get command */
- GSM_CMD_CUSD, /*!< Unstructured Supplementary Service Data, Execute command */
- GSM_CMD_CSSN, /*!< Supplementary Services Notification */
-
- GSM_CMD_CIPMUX, /*!< Start Up Multi-IP Connection */
- GSM_CMD_CIPSTART, /*!< Start Up TCP or UDP Connection */
- GSM_CMD_CIPSEND, /*!< Send Data Through TCP or UDP Connection */
- GSM_CMD_CIPQSEND, /*!< Select Data Transmitting Mode */
- GSM_CMD_CIPACK, /*!< Query Previous Connection Data Transmitting State */
- GSM_CMD_CIPCLOSE, /*!< Close TCP or UDP Connection */
- GSM_CMD_CIPSHUT, /*!< Deactivate GPRS PDP Context */
- GSM_CMD_CLPORT, /*!< Set Local Port */
- GSM_CMD_CSTT, /*!< Start Task and Set APN, username, password */
- GSM_CMD_CIICR, /*!< Bring Up Wireless Connection with GPRS or CSD */
- GSM_CMD_CIFSR, /*!< Get Local IP Address */
- GSM_CMD_CIPSTATUS, /*!< Query Current Connection Status */
- GSM_CMD_CDNSCFG, /*!< Configure Domain Name Server */
- GSM_CMD_CDNSGIP, /*!< Query the IP Address of Given Domain Name */
- GSM_CMD_CIPHEAD, /*!< Add an IP Head at the Beginning of a Package Received */
- GSM_CMD_CIPATS, /*!< Set Auto Sending Timer */
- GSM_CMD_CIPSPRT, /*!< Set Prompt of ‘>’ When Module Sends Data */
- GSM_CMD_CIPSERVER, /*!< Configure Module as Server */
- GSM_CMD_CIPCSGP, /*!< Set CSD or GPRS for Connection Mode */
- GSM_CMD_CIPSRIP, /*!< Show Remote IP Address and Port When Received Data */
- GSM_CMD_CIPDPDP, /*!< Set Whether to Check State of GPRS Network Timing */
- GSM_CMD_CIPMODE, /*!< Select TCPIP Application Mode */
- GSM_CMD_CIPCCFG, /*!< Configure Transparent Transfer Mode */
- GSM_CMD_CIPSHOWTP, /*!< Display Transfer Protocol in IP Head When Received Data */
- GSM_CMD_CIPUDPMODE, /*!< UDP Extended Mode */
- GSM_CMD_CIPRXGET, /*!< Get Data from Network Manually */
- GSM_CMD_CIPSCONT, /*!< Save TCPIP Application Context */
- GSM_CMD_CIPRDTIMER, /*!< Set Remote Delay Timer */
- GSM_CMD_CIPSGTXT, /*!< Select GPRS PDP context */
- GSM_CMD_CIPTKA, /*!< Set TCP Keepalive Parameters */
- GSM_CMD_CIPSSL, /*!< Connection SSL function */
-
- GSM_CMD_SMS_ENABLE,
- GSM_CMD_CMGD, /*!< Delete SMS Message */
- GSM_CMD_CMGF, /*!< Select SMS Message Format */
- GSM_CMD_CMGL, /*!< List SMS Messages from Preferred Store */
- GSM_CMD_CMGR, /*!< Read SMS Message */
- GSM_CMD_CMGS, /*!< Send SMS Message */
- GSM_CMD_CMGW, /*!< Write SMS Message to Memory */
- GSM_CMD_CMSS, /*!< Send SMS Message from Storage */
- GSM_CMD_CMGDA, /*!< MASS SMS delete */
- GSM_CMD_CNMI, /*!< New SMS Message Indications */
- GSM_CMD_CPMS_SET, /*!< Set preferred SMS Message Storage */
- GSM_CMD_CPMS_GET, /*!< Get preferred SMS Message Storage */
- GSM_CMD_CPMS_GET_OPT, /*!< Get optional SMS message storages */
- GSM_CMD_CRES, /*!< Restore SMS Settings */
- GSM_CMD_CSAS, /*!< Save SMS Settings */
- GSM_CMD_CSCA, /*!< SMS Service Center Address */
- GSM_CMD_CSCB, /*!< Select Cell Broadcast SMS Messages */
- GSM_CMD_CSDH, /*!< Show SMS Text Mode Parameters */
- GSM_CMD_CSMP, /*!< Set SMS Text Mode Parameters */
- GSM_CMD_CSMS, /*!< Select Message Service */
-
- GSM_CMD_END, /*!< Last CMD entry */
-} gsm_cmd_t;
-
-/**
- * \brief Connection structure
- */
-typedef struct gsm_conn {
- gsm_conn_type_t type; /*!< Connection type */
- uint8_t num; /*!< Connection number */
- gsm_ip_t remote_ip; /*!< Remote IP address */
- gsm_port_t remote_port; /*!< Remote port number */
- gsm_port_t local_port; /*!< Local IP address */
- gsm_evt_fn evt_func; /*!< Callback function for connection */
- void* arg; /*!< User custom argument */
-
- uint8_t val_id; /*!< Validation ID number. It is increased each time a new connection is established.
- It protects sending data to wrong connection in case we have data in send queue,
- and connection was closed and active again in between. */
-
- gsm_linbuff_t buff; /*!< Linear buffer structure */
-
- size_t total_recved; /*!< Total number of bytes received */
-
- union {
- struct {
- uint8_t active:1; /*!< Status whether connection is active */
- uint8_t client:1; /*!< Status whether connection is in client mode */
- uint8_t data_received:1; /*!< Status whether first data were received on connection */
- uint8_t in_closing:1; /*!< Status if connection is in closing mode.
- When in closing mode, ignore any possible received data from function */
- uint8_t bearer:1; /*!< Bearer used. Can be `1` or `0` */
- } f; /*!< Connection flags */
- } status; /*!< Connection status union with flag bits */
-} gsm_conn_t;
-
-/**
- * \ingroup GSM_PBUF
- * \brief Packet buffer structure
- */
-typedef struct gsm_pbuf {
- struct gsm_pbuf* next; /*!< Next pbuf in chain list */
- size_t tot_len; /*!< Total length of pbuf chain */
- size_t len; /*!< Length of payload */
- size_t ref; /*!< Number of references to this structure */
- uint8_t* payload; /*!< Pointer to payload memory */
- gsm_ip_t ip; /*!< Remote address for received IPD data */
- gsm_port_t port; /*!< Remote port for received IPD data */
-} gsm_pbuf_t;
-
-/**
- * \brief Incoming network data read structure
- */
-typedef struct {
- uint8_t read; /*!< Set to 1 when we should process input data as connection data */
- size_t tot_len; /*!< Total length of packet */
- size_t rem_len; /*!< Remaining bytes to read in current +IPD statement */
- gsm_conn_p conn; /*!< Pointer to connection for network data */
-
- size_t buff_ptr; /*!< Buffer pointer to save data to.
- When set to `NULL` while `read = 1`, reading should ignore incoming data */
- gsm_pbuf_p buff; /*!< Pointer to data buffer used for receiving data */
-} gsm_ipd_t;
-
-/**
- * \brief Connection result on connect command
- */
-typedef enum {
- GSM_CONN_CONNECT_UNKNOWN, /*!< No valid result */
- GSM_CONN_CONNECT_OK, /*!< Connected OK */
- GSM_CONN_CONNECT_ERROR, /*!< Error on connection */
- GSM_CONN_CONNECT_ALREADY, /*!< Already connected */
-} gsm_conn_connect_res_t;
-
-/**
- * \brief Message queue structure to share between threads
- */
-typedef struct gsm_msg {
- gsm_cmd_t cmd_def; /*!< Default message type received from queue */
- gsm_cmd_t cmd; /*!< Since some commands can have different subcommands, sub command is used here */
- uint8_t i; /*!< Variable to indicate order number of subcommands */
- gsm_sys_sem_t sem; /*!< Semaphore for the message */
- uint8_t is_blocking; /*!< Status if command is blocking */
- uint32_t block_time; /*!< Maximal blocking time in units of milliseconds. Use 0 to for non-blocking call */
- gsmr_t res; /*!< Result of message operation */
- gsmr_t (*fn)(struct gsm_msg *); /*!< Processing callback function to process packet */
-
-#if GSM_CFG_USE_API_FUNC_EVT
- gsm_api_cmd_evt_fn evt_fn; /*!< Command callback API function */
- void* evt_arg; /*!< Command callback API callback parameter */
-#endif /* GSM_CFG_USE_API_FUNC_EVT */
-
- union {
- struct {
- uint32_t delay; /*!< Delay to use before sending first reset AT command */
- } reset; /*!< Reset device */
- struct {
- uint32_t baudrate; /*!< Baudrate for AT port */
- } uart; /*!< UART configuration */
-
- struct {
- uint8_t mode; /*!< Functionality mode */
- } cfun; /*!< Set phone functionality */
-
- struct {
- const char* pin; /*!< Pin code to write */
- } cpin_enter; /*!< Enter pin code */
- struct {
- const char* pin; /*!< New pin code */
- } cpin_add; /*!< Add pin code if previously wasn't set */
- struct {
- const char* current_pin; /*!< Current pin code */
- const char* new_pin; /*!< New pin code */
- } cpin_change; /*!< Change current pin code */
- struct {
- const char* pin; /*!< Current pin code */
- } cpin_remove; /*!< Remove PIN code */
- struct {
- const char* puk; /*!< PUK code */
- const char* pin; /*!< New PIN code */
- } cpuk_enter; /*!< Enter PUK and new PIN */
- struct {
- size_t cnum_tries; /*!< Number of tries */
- } sim_info; /*!< Get information for SIM card */
-
- struct {
- char* str; /*!< Pointer to output string array */
- size_t len; /*!< Length of output string array including trailing zero memory */
- } device_info; /*!< All kind of device info, serial number, model, manufacturer, revision */
-
- struct {
- int16_t* rssi; /*!< Pointer to RSSI variable */
- } csq; /*!< Signal strength */
- struct {
- uint8_t read; /*!< Flag indicating we can read the COPS actual data */
- gsm_operator_t* ops; /*!< Pointer to operators array */
- size_t opsl; /*!< Length of operators array */
- size_t opsi; /*!< Current operator index array */
- size_t* opf; /*!< Pointer to number of operators found */
- } cops_scan; /*!< Scan operators */
- struct {
- gsm_operator_curr_t* curr; /*!< Pointer to output current operator */
- } cops_get; /*!< Get current operator info */
- struct {
- gsm_operator_mode_t mode; /*!< COPS mode */
- gsm_operator_format_t format; /*!< Operator format to print */
- const char* name; /*!< Short or long name, according to format */
- uint32_t num; /*!< Number in case format is number */
- } cops_set; /*!< Set operator settings */
-
-#if GSM_CFG_CONN || __DOXYGEN__
- /* Connection based commands */
- struct {
- gsm_conn_t** conn; /*!< Pointer to pointer to save connection used */
- const char* host; /*!< Host to use for connection */
- gsm_port_t port; /*!< Remote port used for connection */
- gsm_conn_type_t type; /*!< Connection type */
- void* arg; /*!< Connection custom argument */
- gsm_evt_fn evt_func; /*!< Callback function to use on connection */
- uint8_t num; /*!< Connection number used for start */
- gsm_conn_connect_res_t conn_res; /*!< Connection result status */
- } conn_start; /*!< Structure for starting new connection */
- struct {
- gsm_conn_t* conn; /*!< Pointer to connection to close */
- uint8_t val_id; /*!< Connection current validation ID when command was sent to queue */
- } conn_close; /*!< Close connection */
- struct {
- gsm_conn_t* conn; /*!< Pointer to connection to send data */
- size_t btw; /*!< Number of remaining bytes to write */
- size_t ptr; /*!< Current write pointer for data */
- const uint8_t* data; /*!< Data to send */
- size_t sent; /*!< Number of bytes sent in last packet */
- size_t sent_all; /*!< Number of bytes sent all together */
- uint8_t tries; /*!< Number of tries used for last packet */
- uint8_t wait_send_ok_err; /*!< Set to 1 when we wait for SEND OK or SEND ERROR */
- const gsm_ip_t* remote_ip; /*!< Remote IP address for UDP connection */
- gsm_port_t remote_port; /*!< Remote port address for UDP connection */
- uint8_t fau; /*!< Free after use flag to free memory after data are sent (or not) */
- size_t* bw; /*!< Number of bytes written so far */
- uint8_t val_id; /*!< Connection current validation ID when command was sent to queue */
- } conn_send; /*!< Structure to send data on connection */
-#endif /* GSM_CFG_CONN || __DOXYGEN__ */
-#if GSM_CFG_SMS || __DOXYGEN__
- struct {
- const char* num; /*!< Phone number */
- const char* text; /*!< SMS content to send */
- uint8_t format; /*!< SMS format, `0 = PDU`, `1 = text` */
- size_t pos; /*!< Set on +CMGS response if command is OK */
- } sms_send; /*!< Send SMS */
- struct {
- gsm_mem_t mem; /*!< Memory to read from */
- size_t pos; /*!< SMS position in memory */
- gsm_sms_entry_t* entry; /*!< Pointer to entry to write info */
- uint8_t update; /*!< Update SMS status after read operation */
- uint8_t format; /*!< SMS format, `0 = PDU`, `1 = text` */
- uint8_t read; /*!< Read the data flag */
- } sms_read; /*!< Read single SMS */
- struct {
- gsm_mem_t mem; /*!< Memory to delete from */
- size_t pos; /*!< SMS position in memory */
- } sms_delete; /*!< Delete SMS message */
- struct {
- gsm_sms_status_t status; /*!< SMS status to delete */
- } sms_delete_all; /*!< Mass delete SMS messages */
- struct {
- gsm_mem_t mem; /*!< Memory to use for read */
- gsm_sms_status_t status; /*!< SMS entries status */
- gsm_sms_entry_t* entries; /*!< Pointer to entries */
- size_t etr; /*!< Entries to read (array length) */
- size_t ei; /*!< Current entry index in array */
- size_t* er; /*!< Final entries read pointer for user */
- uint8_t update; /*!< Update SMS status after read operation */
- uint8_t format; /*!< SMS format, `0 = PDU`, `1 = text` */
- uint8_t read; /*!< Read the data flag */
- } sms_list; /*!< List SMS messages */
- struct {
- gsm_mem_t mem[3]; /*!< Array of memories */
- } sms_memory; /*!< Set preferred memories */
-#endif /* GSM_CFG_SMS || __DOXYGEN__ */
-#if GSM_CFG_CALL || __DOXYGEN__
- struct {
- const char* number; /*!< Phone number to dial */
- } call_start; /*!< Start a new call */
-#endif /* GSM_CFG_CALL || __DOXYGEN__ */
-#if GSM_CFG_PHONEBOOK || __DOXYGEN__
- struct {
- gsm_mem_t mem; /*!< Memory to use */
- size_t pos; /*!< Memory position. Set to 0 to use new one or SIZE_T MAX to delete entry */
- const char* name; /*!< Entry name */
- const char* num; /*!< Entry number */
- gsm_number_type_t type; /*!< Entry phone number type */
- uint8_t del; /*!< Flag indicates delete */
- } pb_write; /*!< Write/Edit/Delete entry */
- struct {
- gsm_mem_t mem; /*!< Memory to use */
- size_t start_index; /*!< Start index in phonebook to read */
- gsm_pb_entry_t* entries; /*!< Pointer to entries array */
- size_t etr; /*!< NUmber of entries to read */
- size_t ei; /*!< Current entry index */
- size_t* er; /*!< Final entries read pointer for user */
- } pb_list; /*!< List phonebook entries */
- struct {
- gsm_mem_t mem; /*!< Memory to use */
- gsm_pb_entry_t* entries; /*!< Pointer to entries array */
- size_t etr; /*!< NUmber of entries to read */
- size_t ei; /*!< Current entry index */
- size_t* er; /*!< Final entries read pointer for user */
- const char* search; /*!< Search string */
- } pb_search; /*!< Search phonebook entries */
-#endif /* GSM_CFG_PHONEBOOK || __DOXYGEN__ */
- struct {
- const char* code; /*!< Code to send */
- char* resp; /*!< Response array */
- size_t resp_len; /*!< Length of response array */
- uint8_t read; /*!< Flag indicating we can read the COPS actual data */
- size_t resp_write_ptr; /*!< Write pointer for response */
- uint8_t quote_det; /*!< Information if quote has been detected */
- } ussd; /*!< Execute USSD command */
-#if GSM_CFG_NETWORK || __DOXYGEN__
- struct {
- const char* apn; /*!< APN address */
- const char* user; /*!< APN username */
- const char* pass; /*!< APN password */
- } network_attach; /*!< Settings for network attach */
-#endif /* GSM_CFG_NETWORK || __DOXYGEN__ */
- } msg; /*!< Group of different possible message contents */
-} gsm_msg_t;
-
-/**
- * \brief IP and MAC structure with netmask and gateway addresses
- */
-typedef struct {
- gsm_ip_t ip; /*!< IP address */
- gsm_ip_t gw; /*!< Gateway address */
- gsm_ip_t nm; /*!< Netmask address */
- gsm_mac_t mac; /*!< MAC address */
-} gsm_ip_mac_t;
-
-/**
- * \brief Link connection active info
- */
-typedef struct {
- uint8_t failed; /*!< Status if connection successful */
- uint8_t num; /*!< Connection number */
- uint8_t is_server; /*!< Status if connection is client or server */
- gsm_conn_type_t type; /*!< Connection type */
- gsm_ip_t remote_ip; /*!< Remote IP address */
- gsm_port_t remote_port; /*!< Remote port */
- gsm_port_t local_port; /*!< Local port number */
-} gsm_link_conn_t;
-
-/**
- * \brief Callback function linked list prototype
- */
-typedef struct gsm_evt_func {
- struct gsm_evt_func* next; /*!< Next function in the list */
- gsm_evt_fn fn; /*!< Function pointer itself */
-} gsm_evt_func_t;
-
-/**
- * \ingroup GSM_SMS
- * \brief SMS memory information
- */
-typedef struct {
- uint32_t mem_available; /*!< Bit field of available memories */
- gsm_mem_t current; /*!< Current memory choice */
- size_t total; /*!< Size of memory in units of entries */
- size_t used; /*!< Number of used entries */
-} gsm_sms_mem_t;
-
-/**
- * \ingroup GSM_SMS
- * \brief SMS structure
- */
-typedef struct {
- uint8_t ready; /*!< Flag indicating feature ready by device */
- uint8_t enabled; /*!< Flag indicating feature enabled */
-
- gsm_sms_mem_t mem[3]; /*!< 3 memory info for operation,receive,sent storage */
-} gsm_sms_t;
-
-/**
- * \ingroup GSM_SMS
- * \brief SMS memory information
- */
-typedef struct {
- uint32_t mem_available; /*!< Bit field of available memories */
- gsm_mem_t current; /*!< Current memory choice */
- size_t total; /*!< Size of memory in units of entries */
- size_t used; /*!< Number of used entries */
-} gsm_pb_mem_t;
-
-/**
- * \ingroup GSM_PB
- * \brief Phonebook structure
- */
-typedef struct {
- uint8_t ready; /*!< Flag indicating feature ready by device */
- uint8_t enabled; /*!< Flag indicating feature enabled */
-
- gsm_pb_mem_t mem; /*!< Memory information */
-} gsm_pb_t;
-
-/**
- * \brief SIM structure
- */
-typedef struct {
- gsm_sim_state_t state; /*!< Current SIM status */
-} gsm_sim_t;
-
-/**
- * \brief Network info
- */
-typedef struct {
- gsm_network_reg_status_t status; /*!< Network registration status */
- gsm_operator_curr_t curr_operator; /*!< Current operator information */
-
- uint8_t is_attached; /*!< Flag indicating device is attached and PDP context is active */
- gsm_ip_t ip_addr; /*!< Device IP address when network PDP context is enabled */
-} gsm_network_t;
-
-/**
- * \brief GSM modules structure
- */
-typedef struct {
- /* Device identification */
- char model_manufacturer[20]; /*!< Device manufacturer */
- char model_number[20]; /*!< Device model number */
- char model_serial_number[20];/*!< Device serial number */
- char model_revision[20]; /*!< Device revision */
- gsm_device_model_t model; /*!< Device model */
-
- /* Network&operator specific */
- gsm_sim_t sim; /*!< SIM data */
- gsm_network_t network; /*!< Network status */
- int16_t rssi; /*!< RSSI signal strength. `0` = invalid, `-53 % -113` = valid */
-
- /* Device specific */
-#if GSM_CFG_CONN || __DOXYGEN__
- uint8_t active_conns_cur_parse_num; /*!< Current connection number used for parsing */
-
- gsm_conn_t conns[GSM_CFG_MAX_CONNS]; /*!< Array of all connection structures */
- gsm_ipd_t ipd; /*!< Connection incoming data structure */
- uint8_t conn_val_id; /*!< Validation ID increased each time device connects to network */
-#endif /* GSM_CFG_CONNS || __DOXYGEN__ */
-#if GSM_CFG_SMS || __DOXYGEN__
- gsm_sms_t sms; /*!< SMS information */
-#endif /* GSM_CFG_SMS || __DOXYGEN__ */
-#if GSM_CFG_PHONEBOOK || __DOXYGEN__
- gsm_pb_t pb; /*!< Phonebook information */
-#endif /* GSM_CFG_PHONEBOOK || __DOXYGEN__ */
-#if GSM_CFG_CALL || __DOXYGEN__
- gsm_call_t call; /*!< Call information */
-#endif /* GSM_CFG_CALL || __DOXYGEN__ */
-} gsm_modules_t;
-
-/**
- * \brief GSM global structure
- */
-typedef struct {
- size_t locked_cnt; /*!< Counter how many times (recursive) stack is currently locked */
-
- gsm_sys_sem_t sem_sync; /*!< Synchronization semaphore between threads */
- gsm_sys_mbox_t mbox_producer; /*!< Producer message queue handle */
- gsm_sys_mbox_t mbox_process; /*!< Consumer message queue handle */
- gsm_sys_thread_t thread_produce; /*!< Producer thread handle */
- gsm_sys_thread_t thread_process; /*!< Processing thread handle */
-#if !GSM_CFG_INPUT_USE_PROCESS || __DOXYGEN__
- gsm_buff_t buff; /*!< Input processing buffer */
-#endif /* !GSM_CFG_INPUT_USE_PROCESS || __DOXYGEN__ */
- gsm_ll_t ll; /*!< Low level functions */
-
- gsm_msg_t* msg; /*!< Pointer to current user message being executed */
-
- gsm_evt_t evt; /*!< Callback processing structure */
- gsm_evt_func_t* evt_func; /*!< Callback function linked list */
-
- gsm_modules_t m; /*!< All modules. When resetting, reset structure */
-
- union {
- struct {
- uint8_t initialized:1; /*!< Flag indicating GSM library is initialized */
- uint8_t dev_present:1; /*!< Flag indicating GSM device is present */
- } f; /*!< Flags structure */
- } status; /*!< Status structure */
-} gsm_t;
-
-/**
- * \brief Memory mapping structure between string and value in app
- */
-typedef struct {
- gsm_mem_t mem; /*!< Mem indication */
- const char* mem_str; /*!< Memory string */
-} gsm_dev_mem_map_t;
-
-/**
- * \brief Device models map between model and other information
- */
-typedef struct {
- gsm_device_model_t model; /*!< Device model */
- const char* id_str; /*!< Model string identification */
- uint8_t is_2g; /*!< Status if modem is 2G */
- uint8_t is_lte; /*!< Status if modem is LTE */
-} gsm_dev_model_map_t;
-
-/**
- * \ingroup GSM_UNICODE
- * \brief Unicode support structure
- */
-typedef struct {
- uint8_t ch[4]; /*!< UTF-8 max characters */
- uint8_t t; /*!< Total expected length in UTF-8 sequence */
- uint8_t r; /*!< Remaining bytes in UTF-8 sequence */
- gsmr_t res; /*!< Current result of processing */
-} gsm_unicode_t;
-
-/**
- * \}
- */
-
-#if !__DOXYGEN__
-
-/**
- * \ingroup GSM
- * \defgroup GSM_PRIVATE Internal functions
- * \brief Functions, structures and enumerations
- * \{
- */
-
-extern gsm_t gsm;
-
-extern const gsm_dev_mem_map_t gsm_dev_mem_map[];
-extern const size_t gsm_dev_mem_map_size;
-
-extern const gsm_dev_model_map_t gsm_dev_model_map[];
-extern const size_t gsm_dev_model_map_size;
-
-#define CMD_IS_CUR(c) (gsm.msg != NULL && gsm.msg->cmd == (c))
-#define CMD_IS_DEF(c) (gsm.msg != NULL && gsm.msg->cmd_def == (c))
-#define CMD_GET_CUR() ((gsm_cmd_t)(((gsm.msg != NULL) ? gsm.msg->cmd : GSM_CMD_IDLE)))
-#define CMD_GET_DEF() ((gsm_cmd_t)(((gsm.msg != NULL) ? gsm.msg->cmd_def : GSM_CMD_IDLE)))
-
-#define CRLF "\r\n"
-#define CRLF_LEN 2
-
-#define GSM_MSG_VAR_DEFINE(name) gsm_msg_t* name
-#define GSM_MSG_VAR_ALLOC(name, blocking) do {\
- (name) = gsm_mem_malloc(sizeof(*(name))); \
- GSM_DEBUGW(GSM_CFG_DBG_VAR | GSM_DBG_TYPE_TRACE, (name) != NULL, "[MSG VAR] Allocated %d bytes at %p\r\n", sizeof(*(name)), (name)); \
- GSM_DEBUGW(GSM_CFG_DBG_VAR | GSM_DBG_TYPE_TRACE, (name) == NULL, "[MSG VAR] Error allocating %d bytes\r\n", sizeof(*(name))); \
- if ((name) == NULL) { \
- return gsmERRMEM; \
- } \
- GSM_MEMSET((name), 0x00, sizeof(*(name))); \
- (name)->is_blocking = GSM_U8((blocking) > 0); \
-} while (0)
-#define GSM_MSG_VAR_REF(name) (*(name))
-#define GSM_MSG_VAR_FREE(name) do {\
- GSM_DEBUGF(GSM_CFG_DBG_VAR | GSM_DBG_TYPE_TRACE, "[MSG VAR] Free memory: %p\r\n", (name)); \
- if (gsm_sys_sem_isvalid(&((name)->sem))) { \
- gsm_sys_sem_delete(&((name)->sem)); \
- gsm_sys_sem_invalid(&((name)->sem)); \
- } \
- gsm_mem_free_s((void **)&(name)); \
-} while (0)
-#if GSM_CFG_USE_API_FUNC_EVT
-#define GSM_MSG_VAR_SET_EVT(name, evt_fn, evt_arg) do {\
- (name)->evt_fn = (evt_fn); \
- (name)->evt_arg = (evt_arg); \
-} while (0)
-#else /* GSM_CFG_USE_API_FUNC_EVT */
-#define GSM_MSG_VAR_SET_EVT(name, evt_fn, evt_arg) do { GSM_UNUSED(evt_fn); GSM_UNUSED(evt_arg); } while (0)
-#endif /* !GSM_CFG_USE_API_FUNC_EVT */
-
-#define GSM_CHARISNUM(x) ((x) >= '0' && (x) <= '9')
-#define GSM_CHARTONUM(x) ((x) - '0')
-#define GSM_CHARISHEXNUM(x) (((x) >= '0' && (x) <= '9') || ((x) >= 'a' && (x) <= 'f') || ((x) >= 'A' && (x) <= 'F'))
-#define GSM_CHARHEXTONUM(x) (((x) >= '0' && (x) <= '9') ? ((x) - '0') : (((x) >= 'a' && (x) <= 'f') ? ((x) - 'a' + 10) : (((x) >= 'A' && (x) <= 'F') ? ((x) - 'A' + 10) : 0)))
-#define GSM_ISVALIDASCII(x) (((x) >= 32 && (x) <= 126) || (x) == '\r' || (x) == '\n')
-
-#define GSM_PORT2NUM(port) ((uint32_t)(port))
-
-const char * gsmi_dbg_msg_to_string(gsm_cmd_t cmd);
-gsmr_t gsmi_process(const void* data, size_t len);
-gsmr_t gsmi_process_buffer(void);
-gsmr_t gsmi_initiate_cmd(gsm_msg_t* msg);
-uint8_t gsmi_is_valid_conn_ptr(gsm_conn_p conn);
-gsmr_t gsmi_send_cb(gsm_evt_type_t type);
-gsmr_t gsmi_send_conn_cb(gsm_conn_t* conn, gsm_evt_fn cb);
-void gsmi_conn_init(void);
-gsmr_t gsmi_send_msg_to_producer_mbox(gsm_msg_t* msg, gsmr_t (*process_fn)(gsm_msg_t *), uint32_t max_block_time);
-uint32_t gsmi_get_from_mbox_with_timeout_checks(gsm_sys_mbox_t* b, void** m, uint32_t timeout);
-uint8_t gsmi_conn_closed_process(uint8_t conn_num, uint8_t forced);
-void gsmi_conn_start_timeout(gsm_conn_p conn);
-
-gsmr_t gsmi_get_sim_info(const uint32_t blocking);
-
-void gsmi_reset_everything(uint8_t forced);
-void gsmi_process_events_for_timeout_or_error(gsm_msg_t* msg, gsmr_t err);
-
-/**
- * \}
- */
-
-#endif /* !__DOXYGEN__ */
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __GSM_PRIV_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_sms.h b/gsm_at_lib/src/include/gsm/gsm_sms.h
deleted file mode 100644
index 2cac273b..00000000
--- a/gsm_at_lib/src/include/gsm/gsm_sms.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * \file gsm_sms.h
- * \brief SMS API
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#ifndef GSM_HDR_SMS_H
-#define GSM_HDR_SMS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "gsm/gsm.h"
-
-/**
- * \ingroup GSM
- * \defgroup GSM_SMS SMS API
- * \brief SMS manager
- * \{
- */
-
-gsmr_t gsm_sms_enable(const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-gsmr_t gsm_sms_disable(const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-
-gsmr_t gsm_sms_send(const char* num, const char* text, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-gsmr_t gsm_sms_read(gsm_mem_t mem, size_t pos, gsm_sms_entry_t* entry, uint8_t update, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-gsmr_t gsm_sms_delete(gsm_mem_t mem, size_t pos, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-gsmr_t gsm_sms_delete_all(gsm_sms_status_t status, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-gsmr_t gsm_sms_list(gsm_mem_t mem, gsm_sms_status_t stat, gsm_sms_entry_t* entries, size_t etr, size_t* er, uint8_t update, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-gsmr_t gsm_sms_set_preferred_storage(gsm_mem_t mem1, gsm_mem_t mem2, gsm_mem_t mem3, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-
-/**
- * \}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GSM_HDR_SMS_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_typedefs.h b/gsm_at_lib/src/include/gsm/gsm_typedefs.h
deleted file mode 100644
index a9b5b190..00000000
--- a/gsm_at_lib/src/include/gsm/gsm_typedefs.h
+++ /dev/null
@@ -1,629 +0,0 @@
-/**
- * \file gsm_typedefs.h
- * \brief List of structures and enumerations for public usage
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#ifndef GSM_HDR_DEFS_H
-#define GSM_HDR_DEFS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#include
-#include
-#include
-#include
-
-/**
- * \ingroup GSM
- * \defgroup GSM_TYPEDEFS Structures and enumerations
- * \brief List of core structures and enumerations
- * \{
- */
-
-/**
- * \}
- */
-
-/**
- * \ingroup GSM_TYPEDEFS
- * \brief Result enumeration used across application functions
- */
-typedef enum {
- gsmOK = 0, /*!< Function returned OK */
- gsmOKIGNOREMORE, /*!< Function succedded, should continue as gsmOK but ignore sending more data. This result is possible on connection data receive callback */
- gsmERR,
- gsmPARERR, /*!< Wrong parameters on function call */
- gsmERRMEM, /*!< Memory error occurred */
- gsmTIMEOUT, /*!< Timeout occurred on command */
- gsmCONT, /*!< There is still some command to be processed in current command */
- gsmCLOSED, /*!< Connection just closed */
- gsmINPROG, /*!< Operation is in progress */
-
- gsmERRNOTENABLED, /*!< Feature not enabled error */
- gsmERRNOIP, /*!< Station does not have IP address */
- gsmERRNOFREECONN, /*!< There is no free connection available to start */
- gsmERRCONNTIMEOUT, /*!< Timeout received when connection to access point */
- gsmERRPASS, /*!< Invalid password for access point */
- gsmERRNOAP, /*!< No access point found with specific SSID and MAC address */
- gsmERRCONNFAIL, /*!< Connection failed to access point */
- gsmERRWIFINOTCONNECTED, /*!< Wifi not connected to access point */
- gsmERRNODEVICE, /*!< Device is not present */
- gsmERRBLOCKING, /*!< Blocking mode command is not allowed */
-} gsmr_t;
-
-/**
- * \ingroup GSM_TYPEDEFS
- * \brief GSM device model type
- */
-typedef enum {
-#define GSM_DEVICE_MODEL_ENTRY(name, str_id, is_2g, is_lte) GSM_DEVICE_MODEL_ ## name,
-#include "gsm/gsm_models.h"
- GSM_DEVICE_MODEL_END, /*!< End of device model */
- GSM_DEVICE_MODEL_UNKNOWN, /*!< Unknown device model */
-} gsm_device_model_t;
-
-/**
- * \ingroup GSM_SIM
- * \brief SIM state
- */
-typedef enum {
- GSM_SIM_STATE_NOT_INSERTED, /*!< SIM is not inserted in socket */
- GSM_SIM_STATE_READY, /*!< SIM is ready for operations */
- GSM_SIM_STATE_NOT_READY, /*!< SIM is not ready for any operation */
- GSM_SIM_STATE_PIN, /*!< SIM is waiting for SIM to be given */
- GSM_SIM_STATE_PUK, /*!< SIM is waiting for PUT to be given */
- GSM_SIM_STATE_PH_PIN,
- GSM_SIM_STATE_PH_PUK,
-} gsm_sim_state_t;
-
-/**
- * \ingroup GSM_TYPEDEFS
- * \brief IP structure
- */
-typedef struct {
- uint8_t ip[4]; /*!< IPv4 address */
-} gsm_ip_t;
-
-/**
- * \ingroup GSM_TYPEDEFS
- * \brief Port variable
- */
-typedef uint16_t gsm_port_t;
-
-/**
- * \ingroup GSM_TYPEDEFS
- * \brief MAC address
- */
-typedef struct {
- uint8_t mac[6]; /*!< MAC address */
-} gsm_mac_t;
-
-/**
- * \ingroup GSM_TYPEDEFS
- * \brief Date and time structure
- */
-typedef struct {
- uint8_t date; /*!< Day in a month, from `1` to up to `31` */
- uint8_t month; /*!< Month in a year, from `1` to `12` */
- uint16_t year; /*!< Year */
- uint8_t day; /*!< Day in a week, from `1` to `7`, 0 = invalid */
- uint8_t hours; /*!< Hours in a day, from `0` to `23` */
- uint8_t minutes; /*!< Minutes in a hour, from `0` to `59` */
- uint8_t seconds; /*!< Seconds in a minute, from `0` to `59` */
-} gsm_datetime_t;
-
-/**
- * \ingroup GSM_CONN
- * \brief List of possible connection types
- */
-typedef enum {
- GSM_CONN_TYPE_TCP, /*!< Connection type is TCP */
- GSM_CONN_TYPE_UDP, /*!< Connection type is UDP */
- GSM_CONN_TYPE_SSL, /*!< Connection type is TCP over SSL */
-} gsm_conn_type_t;
-
-/**
- * \ingroup GSM_TYPEDEFS
- * \brief Available device memories
- */
-typedef enum {
-#define GSM_DEV_MEMORY_ENTRY(name, str_code) GSM_MEM_ ## name,
-#include "gsm/gsm_memories.h"
- GSM_MEM_END, /*!< End of memory list */
- GSM_MEM_CURRENT, /*!< Use current memory for read/delete operation */
- GSM_MEM_UNKNOWN = 0x1F, /*!< Unknown memory */
-} gsm_mem_t;
-
-/**
- * \ingroup GSM_TYPEDEFS
- * \brief GSM number type
- */
-typedef enum {
- GSM_NUMBER_TYPE_NATIONAL = 129, /*!< Number is national */
- GSM_NUMBER_TYPE_INTERNATIONAL = 145, /*!< Number is international */
-} gsm_number_type_t;
-
-/**
- * \ingroup GSM_SMS
- * \brief SMS status in current memory
- */
-typedef enum {
- GSM_SMS_STATUS_ALL, /*!< Process all SMS, used for mass delete or SMS list */
- GSM_SMS_STATUS_READ, /*!< SMS status is read */
- GSM_SMS_STATUS_UNREAD, /*!< SMS status is unread */
- GSM_SMS_STATUS_SENT, /*!< SMS status is sent */
- GSM_SMS_STATUS_UNSENT, /*!< SMS status is unsent */
- GSM_SMS_STATUS_INBOX, /*!< SMS status, used only for mass delete operation */
-} gsm_sms_status_t;
-
-/**
- * \ingroup GSM_SMS
- * \brief SMS entry structure
- */
-typedef struct {
- gsm_mem_t mem; /*!< Memory storage */
- size_t pos; /*!< Memory position */
- gsm_datetime_t datetime; /*!< Date and time */
- gsm_sms_status_t status; /*!< Message status */
- char number[26]; /*!< Phone number */
- char name[20]; /*!< Name in phonebook if exists */
- char data[161]; /*!< Data memory */
- size_t length; /*!< Length of SMS data */
-} gsm_sms_entry_t;
-
-/**
- * \ingroup GSM_PB
- * \brief Phonebook entry structure
- */
-typedef struct {
- gsm_mem_t mem; /*!< Memory position */
- size_t pos; /*!< Position in memory */
- char name[20]; /*!< Name of phonebook entry */
- char number[26]; /*!< Phone number */
- gsm_number_type_t type; /*!< Phone number type */
-} gsm_pb_entry_t;
-
-/**
- * \ingroup GSM_OPERATOR
- * \brief Operator status value
- */
-typedef enum {
- GSM_OPERATOR_STATUS_UNKNOWN = 0x00, /*!< Unknown operator */
- GSM_OPERATOR_STATUS_AVAILABLE, /*!< Operator is available */
- GSM_OPERATOR_STATUS_CURRENT, /*!< Operator is currently active */
- GSM_OPERATOR_STATUS_FORBIDDEN /*!< Operator is forbidden */
-} gsm_operator_status_t;
-
-/**
- * \ingroup GSM_OPERATOR
- * \brief Operator selection mode
- */
-typedef enum {
- GSM_OPERATOR_MODE_AUTO = 0x00, /*!< Operator automatic mode */
- GSM_OPERATOR_MODE_MANUAL = 0x01, /*!< Operator manual mode */
- GSM_OPERATOR_MODE_DEREGISTER = 0x02, /*!< Operator deregistered from network */
- GSM_OPERATOR_MODE_MANUAL_AUTO = 0x04, /*!< Operator manual mode first. If fails, auto mode enabled */
-} gsm_operator_mode_t;
-
-/**
- * \ingroup GSM_OPERATOR
- * \brief Operator data format
- */
-typedef enum {
- GSM_OPERATOR_FORMAT_LONG_NAME = 0x00, /*!< COPS command returned long name */
- GSM_OPERATOR_FORMAT_SHORT_NAME, /*!< COPS command returned short name */
- GSM_OPERATOR_FORMAT_NUMBER, /*!< COPS command returned number */
- GSM_OPERATOR_FORMAT_INVALID /*!< Unknown format */
-} gsm_operator_format_t;
-
-/**
- * \ingroup GSM_OPERATOR
- * \brief Operator details for scan
- */
-typedef struct {
- gsm_operator_status_t stat; /*!< Operator status */
- char long_name[20]; /*!< Operator long name */
- char short_name[20]; /*!< Operator short name */
- uint32_t num; /*!< Operator numeric value */
-} gsm_operator_t;
-
-/**
- * \ingroup GSM_OPERATOR
- * \brief Current operator info
- */
-typedef struct {
- gsm_operator_mode_t mode; /*!< Operator mode */
- gsm_operator_format_t format; /*!< Data format */
- union {
- char long_name[20]; /*!< Long name format */
- char short_name[20]; /*!< Short name format */
- uint32_t num; /*!< Number format */
- } data; /*!< Operator data union */
-} gsm_operator_curr_t;
-
-/**
- * \ingroup GSM_NETWORK
- * \brief Network Registration status
- */
-typedef enum {
- GSM_NETWORK_REG_STATUS_SIM_ERR = 0x00, /*!< SIM card error */
- GSM_NETWORK_REG_STATUS_CONNECTED = 0x01, /*!< Device is connected to network */
- GSM_NETWORK_REG_STATUS_SEARCHING = 0x02, /*!< Network search is in progress */
- GSM_NETWORK_REG_STATUS_DENIED = 0x03, /*!< Registration denied */
- GSM_NETWORK_REG_STATUS_CONNECTED_ROAMING = 0x05,/*!< Device is connected and is roaming */
- GSM_NETWORK_REG_STATUS_CONNECTED_SMS_ONLY = 0x06, /*!< Device is connected to home network in SMS-only mode */
- GSM_NETWORK_REG_STATUS_CONNECTED_ROAMING_SMS_ONLY = 0x07/*!< Device is roaming in SMS-only mode */
-} gsm_network_reg_status_t;
-
-/**
- * \ingroup GSM_CALL
- * \brief List of call directions
- */
-typedef enum {
- GSM_CALL_DIR_MO = 0x00, /*!< Mobile Originated, outgoing call */
- GSM_CALL_DIR_MT, /*!< Mobile Terminated, incoming call */
-} gsm_call_dir_t;
-
-/**
- * \ingroup GSM_CALL
- * \brief List of call states
- */
-typedef enum {
- GSM_CALL_STATE_ACTIVE = 0x00, /*!< Call is active */
- GSM_CALL_STATE_HELD, /*!< Call is held */
- GSM_CALL_STATE_DIALING, /*!< Call is dialing */
- GSM_CALL_STATE_ALERTING, /*!< Call is alerting */
- GSM_CALL_STATE_INCOMING, /*!< Call is incoming */
- GSM_CALL_STATE_WAITING, /*!< Call is waiting */
- GSM_CALL_STATE_DISCONNECT, /*!< Call disconnected, call finished */
-} gsm_call_state_t;
-
-/**
- * \ingroup GSM_CALL
- * \brief List of call types
- */
-typedef enum {
- GSM_CALL_TYPE_VOICE = 0x00, /*!< Voice call */
- GSM_CALL_TYPE_DATA, /*!< Data call */
- GSM_CALL_TYPE_FAX, /*!< Fax call */
-} gsm_call_type_t;
-
-/**
- * \ingroup GSM_CALL
- * \brief Call information
- * \note Data received on `+CLCC` info
- */
-typedef struct {
- uint8_t ready; /*!< Flag indicating feature ready by device */
- uint8_t enabled; /*!< Flag indicating feature enabled */
-
- uint8_t id; /*!< Call identification number, 0-7 */
- gsm_call_dir_t dir; /*!< Call direction */
- gsm_call_state_t state; /*!< Call state */
- gsm_call_type_t type; /*!< Call type */
- char number[20]; /*!< Phone number */
- char is_multipart; /*!< Multipart status */
- uint8_t addr_type; /*!< Address type */
- char name[20]; /*!< Phone book name if exists for current number */
-} gsm_call_t;
-
-/* Forward declarations */
-struct gsm_evt;
-struct gsm_conn;
-struct gsm_pbuf;
-
-/**
- * \ingroup GSM_CONN
- * \brief Pointer to \ref gsm_conn_t structure
- */
-typedef struct gsm_conn* gsm_conn_p;
-
-/**
- * \ingroup GSM_PBUF
- * \brief Pointer to \ref gsm_pbuf_t structure
- */
-typedef struct gsm_pbuf* gsm_pbuf_p;
-
-/**
- * \ingroup GSM_EVT
- * \brief Event function prototype
- * \param[in] evt: Callback event data
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
- */
-typedef gsmr_t (*gsm_evt_fn)(struct gsm_evt* evt);
-
-/**
- * \ingroup GSM_EVT
- * \brief List of possible callback types received to user
- */
-typedef enum gsm_cb_type_t {
- GSM_EVT_INIT_FINISH, /*!< Initialization has been finished at this point */
-
- GSM_EVT_RESET, /*!< Device reset operation finished */
- GSM_EVT_RESTORE, /*!< Device restore operation finished */
-
- GSM_EVT_CMD_TIMEOUT, /*!< Timeout on command.
- When application receives this event,
- it may reset system as there was (maybe) a problem in device */
-
- GSM_EVT_DEVICE_PRESENT, /*!< Notification when device present status changes */
- GSM_EVT_DEVICE_IDENTIFIED, /*!< Device identified event */
-
- GSM_EVT_SIGNAL_STRENGTH, /*!< Signal strength event */
-
- GSM_EVT_SIM_STATE_CHANGED, /*!< SIM card state changed */
-
- GSM_EVT_OPERATOR_SCAN, /*!< Operator scan finished event */
-
- GSM_EVT_NETWORK_OPERATOR_CURRENT, /*!< Current operator event */
- GSM_EVT_NETWORK_REG_CHANGED, /*!< Network registration changed. Available even when \ref GSM_CFG_NETWORK is disabled */
-#if GSM_CFG_NETWORK || __DOXYGEN__
- GSM_EVT_NETWORK_ATTACHED, /*!< Attached to network, PDP context active and ready for TCP/IP application */
- GSM_EVT_NETWORK_DETACHED, /*!< Detached from network, PDP context not active anymore */
-#endif /* GSM_CFG_NETWORK || __DOXYGEN__ */
-
-#if GSM_CFG_CONN || __DOXYGEN__
- GSM_EVT_CONN_RECV, /*!< Connection data received */
- GSM_EVT_CONN_SEND, /*!< Connection data send */
- GSM_EVT_CONN_ACTIVE, /*!< Connection just became active */
- GSM_EVT_CONN_ERROR, /*!< Client connection start was not successful */
- GSM_EVT_CONN_CLOSE, /*!< Connection close event. Check status if successful */
- GSM_EVT_CONN_POLL, /*!< Poll for connection if there are any changes */
-#endif /* GSM_CFG_CONN || __DOXYGEN__ */
-
-#if GSM_CFG_SMS || __DOXYGEN__
- GSM_EVT_SMS_ENABLE, /*!< SMS enable event */
- GSM_EVT_SMS_READY, /*!< SMS ready event */
- GSM_EVT_SMS_SEND, /*!< SMS send event */
- GSM_EVT_SMS_RECV, /*!< SMS received */
- GSM_EVT_SMS_READ, /*!< SMS read */
- GSM_EVT_SMS_DELETE, /*!< SMS delete */
- GSM_EVT_SMS_LIST, /*!< SMS list */
-#endif /* GSM_CFG_SMS || __DOXYGEN__ */
-#if GSM_CFG_CALL || __DOXYGEN__
- GSM_EVT_CALL_ENABLE, /*!< Call enable event */
- GSM_EVT_CALL_READY, /*!< Call ready event */
- GSM_EVT_CALL_CHANGED, /*!< Call info changed, `+CLCK` statement received */
- GSM_EVT_CALL_RING, /*!< Call is ringing event */
- GSM_EVT_CALL_BUSY, /*!< Call is busy */
- GSM_EVT_CALL_NO_CARRIER, /*!< No carrier to make a call */
-#endif /* GSM_CFG_CALL || __DOXYGEN__ */
-#if GSM_CFG_PHONEBOOK || __DOXYGEN__
- GSM_EVT_PB_ENABLE, /*!< Phonebook enable event */
- GSM_EVT_PB_LIST, /*!< Phonebook list event */
- GSM_EVT_PB_SEARCH, /*!< Phonebook search event */
-#endif /* GSM_CFG_PHONEBOOK || __DOXYGEN__ */
-} gsm_evt_type_t;
-
-/**
- * \ingroup GSM_EVT
- * \brief Global callback structure to pass as parameter to callback function
- */
-typedef struct gsm_evt {
- gsm_evt_type_t type; /*!< Callback type */
- union {
- struct {
- gsmr_t res; /*!< Reset operation result */
- } reset; /*!< Reset sequence finish. Use with \ref GSM_EVT_RESET event */
- struct {
- gsmr_t res; /*!< Restore operation result */
- } restore; /*!< Restore sequence finish. Use with \ref GSM_EVT_RESTORE event */
-
- struct {
- gsm_sim_state_t state; /*!< SIM state */
- } cpin; /*!< CPIN event */
- struct {
- const gsm_operator_curr_t* operator_current; /*!< Current operator info */
- } operator_current; /*!< Current operator event. Use with \ref GSM_EVT_NETWORK_OPERATOR_CURRENT event */
- struct {
- gsm_operator_t* ops; /*!< Pointer to operators */
- size_t opf; /*!< Number of operators found */
- gsmr_t res; /*!< Scan operation result */
- } operator_scan; /*!< Operator scan event. Use with \ref GSM_EVT_OPERATOR_SCAN event */
-
- struct {
- int16_t rssi; /*!< Strength in units of dBm */
- } rssi; /*!< Signal strength event. Use with \ref GSM_EVT_SIGNAL_STRENGTH event */
-
-#if GSM_CFG_CONN || __DOXYGEN__
- struct {
- gsm_conn_p conn; /*!< Connection where data were received */
- gsm_pbuf_p buff; /*!< Pointer to received data */
- } conn_data_recv; /*!< Network data received. Use with \ref GSM_EVT_CONN_RECV event */
- struct {
- gsm_conn_p conn; /*!< Connection where data were sent */
- size_t sent; /*!< Number of bytes sent on connection */
- gsmr_t res; /*!< Send data result */
- } conn_data_send; /*!< Data successfully sent. Use with \ref GSM_EVT_CONN_SEND event */
- struct {
- const char* host; /*!< Host to use for connection */
- gsm_port_t port; /*!< Remote port used for connection */
- gsm_conn_type_t type; /*!< Connection type */
- void* arg; /*!< Connection argument used on connection */
- gsmr_t err; /*!< Error value */
- } conn_error; /*!< Client connection start error. Use with \ref GSM_EVT_CONN_ERROR event */
- struct {
- gsm_conn_p conn; /*!< Pointer to connection */
- uint8_t client; /*!< Set to `1` if connection is/was client mode */
- uint8_t forced; /*!< Set to `1` if connection action was forced (when active: 1 = CLIENT, 0 = SERVER: when closed, 1 = CMD, 0 = REMOTE) */
- gsmr_t res; /*!< Result of close event. Set to \ref gsmOK on success. */
- } conn_active_close; /*!< Process active and closed statuses at the same time. Use with \ref GSM_EVT_CONN_ACTIVE or \ref GSM_EVT_CONN_CLOSE events */
- struct {
- gsm_conn_p conn; /*!< Set connection pointer */
- } conn_poll; /*!< Polling active connection to check for timeouts. Use with \ref GSM_EVT_CONN_POLL event */
-#endif /* GSM_CFG_CONN || __DOXYGEN__ */
-
-#if GSM_CFG_SMS || __DOXYGEN__
- struct {
- gsmr_t status; /*!< Enable status */
- } sms_enable; /*!< SMS enable event. Use with \ref GSM_EVT_SMS_ENABLE event */
- struct {
- size_t pos; /*!< Position in memory */
- gsmr_t res; /*!< SMS send result information */
- } sms_send; /*!< SMS sent info. Use with \ref GSM_EVT_SMS_SEND event */
- struct {
- gsm_mem_t mem; /*!< Memory of received message */
- size_t pos; /*!< Received position in memory for sent SMS */
- } sms_recv; /*!< SMS received info. Use with \ref GSM_EVT_SMS_RECV event */
- struct {
- gsm_sms_entry_t* entry; /*!< SMS entry */
- gsmr_t res; /*!< SMS read result information */
- } sms_read; /*!< SMS read. Use with \ref GSM_EVT_SMS_READ event */
- struct {
- gsm_mem_t mem; /*!< Memory of deleted message */
- size_t pos; /*!< Deleted position in memory for sent SMS */
- gsmr_t res; /*!< Operation success */
- } sms_delete; /*!< SMS delete. Use with \ref GSM_EVT_SMS_DELETE event */
- struct {
- gsm_mem_t mem; /*!< Memory used for scan */
- gsm_sms_entry_t* entries; /*!< Pointer to entries */
- size_t size; /*!< Number of valid entries */
- gsmr_t res; /*!< Result on command */
- } sms_list; /*!< SMS list. Use with \ref GSM_EVT_SMS_LIST event */
-#endif /* GSM_CFG_SMS || __DOXYGEN__ */
-#if GSM_CFG_CALL || __DOXYGEN__
- struct {
- gsmr_t res; /*!< Enable status */
- } call_enable; /*!< Call enable event. Use with \ref GSM_EVT_CALL_ENABLE event */
- struct {
- const gsm_call_t* call; /*!< Call information */
- } call_changed; /*!< Call changed info. Use with \ref GSM_EVT_CALL_CHANGED event */
-#endif /* GSM_CFG_CALL || __DOXYGEN__ */
-#if GSM_CFG_PHONEBOOK || __DOXYGEN__
- struct {
- gsmr_t res; /*!< Enable status */
- } pb_enable; /*!< Phonebook enable event. Use with \ref GSM_EVT_PB_ENABLE event */
- struct {
- gsm_mem_t mem; /*!< Memory used for scan */
- gsm_pb_entry_t* entries; /*!< Pointer to entries */
- size_t size; /*!< Number of valid entries */
- gsmr_t res; /*!< Operation success */
- } pb_list; /*!< Phonebok list. Use with \ref GSM_EVT_PB_LIST event */
- struct {
- const char* search; /*!< Search string */
- gsm_mem_t mem; /*!< Memory used for scan */
- gsm_pb_entry_t* entries; /*!< Pointer to entries */
- size_t size; /*!< Number of valid entries */
- gsmr_t res; /*!< Operation success */
- } pb_search; /*!< Phonebok search list. Use with \ref GSM_EVT_PB_SEARCH event */
-#endif /* GSM_CFG_PHONEBOOK || __DOXYGEN__ */
- } evt; /*!< Callback event union */
-} gsm_evt_t;
-
-#define GSM_SIZET_MAX ((size_t)(-1)) /*!< Maximal value of size_t variable type */
-
-/**
- * \ingroup GSM_LL
- * \brief Function prototype for AT output data
- * \param[in] data: Pointer to data to send. This parameter can be set to `NULL`
- * \param[in] len: Number of bytes to send. This parameter can be set to `0`
- * to indicate that internal buffer can be flushed to stream.
- * This is implementation defined and feature might be ignored
- * \return Number of bytes sent
- */
-typedef size_t (*gsm_ll_send_fn)(const void* data, size_t len);
-
-/**
- * \ingroup GSM_LL
- * \brief Function prototype for hardware reset of GSM device
- * \param[in] state: State indicating reset. When set to `1`, reset must be active (usually pin active low),
- * or set to `0` when reset is cleared
- * \return `1` on successful action, `0` otherwise
- */
-typedef uint8_t (*gsm_ll_reset_fn)(uint8_t state);
-
-/**
- * \ingroup GSM_LL
- * \brief Low level user specific functions
- */
-typedef struct {
- gsm_ll_send_fn send_fn; /*!< Callback function to transmit data */
- gsm_ll_reset_fn reset_fn; /*!< Reset callback function */
- struct {
- uint32_t baudrate; /*!< UART baudrate value */
- } uart; /*!< UART communication parameters */
-} gsm_ll_t;
-
-/**
- * \ingroup GSM_TIMEOUT
- * \brief Timeout callback function prototype
- * \param[in] arg: Custom user argument
- */
-typedef void (*gsm_timeout_fn)(void* arg);
-
-/**
- * \ingroup GSM_TIMEOUT
- * \brief Timeout structure
- */
-typedef struct gsm_timeout {
- struct gsm_timeout* next; /*!< Pointer to next timeout entry */
- uint32_t time; /*!< Time difference from previous entry */
- void* arg; /*!< Argument to pass to callback function */
- gsm_timeout_fn fn; /*!< Callback function for timeout */
-} gsm_timeout_t;
-
-/**
- * \ingroup GSM_BUFF
- * \brief Buffer structure
- */
-typedef struct {
- uint8_t* buff; /*!< Pointer to buffer data.
- Buffer is considered initialized when `buff != NULL` */
- size_t size; /*!< Size of buffer data. Size of actual buffer is `1` byte less than this value */
- size_t r; /*!< Next read pointer. Buffer is considered empty when `r == w` and full when `w == r - 1` */
- size_t w; /*!< Next write pointer. Buffer is considered empty when `r == w` and full when `w == r - 1` */
-} gsm_buff_t;
-
-/**
- * \ingroup GSM_TYPEDEFS
- * \brief Linear buffer structure
- */
-typedef struct {
- uint8_t* buff; /*!< Pointer to buffer data array */
- size_t len; /*!< Length of buffer array */
- size_t ptr; /*!< Current buffer pointer */
-} gsm_linbuff_t;
-
-/**
- * \ingroup GSM_TYPEDEFS
- * \brief Function declaration for API function command event callback function
- * \param[in] res: Operation result, member of \ref gsmr_t enumeration
- * \param[in] arg: Custom user argument
- */
-typedef void (*gsm_api_cmd_evt_fn) (gsmr_t res, void* arg);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* GSM_HDR_DEFS_H */
diff --git a/gsm_at_lib/src/include/system/gsm_sys.h b/gsm_at_lib/src/include/system/gsm_sys.h
deleted file mode 100644
index dbcff241..00000000
--- a/gsm_at_lib/src/include/system/gsm_sys.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/**
- * \file gsm_sys.h
- * \brief Main system include file which decides later include file
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#ifndef GSM_HDR_MAIN_SYS_H
-#define GSM_HDR_MAIN_SYS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#include "gsm_config.h"
-
-/**
- * \ingroup GSM_PORT
- * \defgroup GSM_SYS System functions
- * \brief System based function for OS management, timings, etc
- * \{
- */
-
-/**
- * \brief Thread function prototype
- */
-typedef void (*gsm_sys_thread_fn)(void *);
-
-/**
- * \anchor GSM_SYS_PORTS
- * \name System ports
- * \{
- *
- * List of already available system ports.
- * Configure \ref GSM_CFG_SYS_PORT with one of these values to use preconfigured ports
- */
-
-#define GSM_SYS_PORT_CMSIS_OS 1 /*!< CMSIS-OS based port for OS systems capable of ARM CMSIS standard */
-#define GSM_SYS_PORT_WIN32 2 /*!< WIN32 based port to use GSM library with Windows applications */
-#define GSM_SYS_PORT_CMSIS_OS2 3 /*!< CMSIS-OS v2 based port for OS systems capable of ARM CMSIS standard */
-#define GSM_SYS_PORT_USER 99 /*!< User custom implementation.
- When port is selected to user mode, user must provide "gsm_sys_user.h" file,
- which is not provided with library. Refer to `system/gsm_sys_template.h` file for more information
- */
-
-/**
- * \}
- */
-
-/* Decide which port to include */
-#if GSM_CFG_SYS_PORT == GSM_SYS_PORT_CMSIS_OS
-#include "system/gsm_sys_cmsis_os.h"
-#elif ESP_CFG_SYS_PORT == GSM_SYS_PORT_CMSIS_OS2
-#include "system/esp_sys_cmsis_os2.h"
-#elif GSM_CFG_SYS_PORT == GSM_SYS_PORT_WIN32
-#include "system/gsm_sys_win32.h"
-#elif GSM_CFG_SYS_PORT == GSM_SYS_PORT_USER
-#include "gsm_sys_user.h"
-#endif
-
-uint8_t gsm_sys_init(void);
-uint32_t gsm_sys_now(void);
-
-uint8_t gsm_sys_protect(void);
-uint8_t gsm_sys_unprotect(void);
-
-uint8_t gsm_sys_mutex_create(gsm_sys_mutex_t* p);
-uint8_t gsm_sys_mutex_delete(gsm_sys_mutex_t* p);
-uint8_t gsm_sys_mutex_lock(gsm_sys_mutex_t* p);
-uint8_t gsm_sys_mutex_unlock(gsm_sys_mutex_t* p);
-uint8_t gsm_sys_mutex_isvalid(gsm_sys_mutex_t* p);
-uint8_t gsm_sys_mutex_invalid(gsm_sys_mutex_t* p);
-
-uint8_t gsm_sys_sem_create(gsm_sys_sem_t* p, uint8_t cnt);
-uint8_t gsm_sys_sem_delete(gsm_sys_sem_t* p);
-uint32_t gsm_sys_sem_wait(gsm_sys_sem_t* p, uint32_t timeout);
-uint8_t gsm_sys_sem_release(gsm_sys_sem_t* p);
-uint8_t gsm_sys_sem_isvalid(gsm_sys_sem_t* p);
-uint8_t gsm_sys_sem_invalid(gsm_sys_sem_t* p);
-
-uint8_t gsm_sys_mbox_create(gsm_sys_mbox_t* b, size_t size);
-uint8_t gsm_sys_mbox_delete(gsm_sys_mbox_t* b);
-uint32_t gsm_sys_mbox_put(gsm_sys_mbox_t* b, void* m);
-uint32_t gsm_sys_mbox_get(gsm_sys_mbox_t* b, void** m, uint32_t timeout);
-uint8_t gsm_sys_mbox_putnow(gsm_sys_mbox_t* b, void* m);
-uint8_t gsm_sys_mbox_getnow(gsm_sys_mbox_t* b, void** m);
-uint8_t gsm_sys_mbox_isvalid(gsm_sys_mbox_t* b);
-uint8_t gsm_sys_mbox_invalid(gsm_sys_mbox_t* b);
-
-uint8_t gsm_sys_thread_create(gsm_sys_thread_t* t, const char* name, gsm_sys_thread_fn thread_func, void* const arg, size_t stack_size, gsm_sys_thread_prio_t prio);
-uint8_t gsm_sys_thread_terminate(gsm_sys_thread_t* t);
-uint8_t gsm_sys_thread_yield(void);
-
-/**
- * \}
- */
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* GSM_HDR_MAIN_LL_H */
diff --git a/gsm_at_lib/src/include/system/gsm_sys_cmsis_os2.h b/gsm_at_lib/src/include/system/gsm_sys_cmsis_os2.h
deleted file mode 100644
index 04d9d572..00000000
--- a/gsm_at_lib/src/include/system/gsm_sys_cmsis_os2.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * \file gsm_sys_cmsis_os2.h
- * \brief CMSIS-OS V2 based system file
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#ifndef GSM_HDR_SYSTEM_CMSIS_OS2_H
-#define GSM_HDR_SYSTEM_CMSIS_OS2_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#include
-#include
-
-#include "gsm_config.h"
-
-#if GSM_CFG_OS && !__DOXYGEN__
-
-#include "cmsis_os2.h"
-
-typedef osMutexId_t gsm_sys_mutex_t;
-typedef osSemaphoreId_t gsm_sys_sem_t;
-typedef osMessageQueueId_t gsm_sys_mbox_t;
-typedef osThreadId_t gsm_sys_thread_t;
-typedef osPriority_t gsm_sys_thread_prio_t;
-#define GSM_SYS_MBOX_NULL (gsm_sys_mbox_t)0
-#define GSM_SYS_SEM_NULL (gsm_sys_sem_t)0
-#define GSM_SYS_MUTEX_NULL (gsm_sys_mutex_t)0
-#define GSM_SYS_TIMEOUT ((uint32_t)osWaitForever)
-#define GSM_SYS_THREAD_PRIO (osPriorityNormal)
-#define GSM_SYS_THREAD_SS (256)
-
-#endif /* GSM_CFG_OS && !__DOXYGEN__ */
-
-#ifdef __cplusplus
-};
-#endif /* __cplusplus */
-
-#endif /* GSM_HDR_SYSTEM_CMSIS_OS2_H */
diff --git a/gsm_at_lib/src/include/system/gsm_sys_template.h b/gsm_at_lib/src/include/system/gsm_sys_template.h
deleted file mode 100644
index 9d7ab38e..00000000
--- a/gsm_at_lib/src/include/system/gsm_sys_template.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/**
- * \file gsm_sys_template.h
- * \brief Template file for system functions
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#ifndef GSM_HDR_SYSTEM_H
-#define GSM_HDR_SYSTEM_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#include
-#include
-
-#include "gsm_config.h"
-
-/**
- * \addtogroup GSM_SYS
- * \{
- */
-
-#if GSM_CFG_OS || __DOXYGEN__
-#include "cmsis_os.h"
-
-/**
- * \brief GSM system mutex ID type
- * \note Keep as is in case of CMSIS based OS, otherwise change for your OS
- */
-typedef osMutexId gsm_sys_mutex_t;
-
-/**
- * \brief GSM system semaphore ID type
- * \note Keep as is in case of CMSIS based OS, otherwise change for your OS
- */
-typedef osSemaphoreId gsm_sys_sem_t;
-
-/**
- * \brief GSM system message queue ID type
- * \note Keep as is in case of CMSIS based OS, otherwise change for your OS
- */
-typedef osMessageQId gsm_sys_mbox_t;
-
-/**
- * \brief GSM system thread ID type
- * \note Keep as is in case of CMSIS based OS, otherwise change for your OS
- */
-typedef osThreadId gsm_sys_thread_t;
-
-/**
- * \brief GSM system thread priority type
- * \note Keep as is in case of CMSIS based OS, otherwise change for your OS
- */
-typedef osPriority gsm_sys_thread_prio_t;
-
-/**
- * \brief Value indicating message queue is not valid
- * \note Keep as is in case of CMSIS based OS, otherwise change for your OS
- */
-#define GSM_SYS_MBOX_NULL (osMessageQId)0
-
-/**
- * \brief Value indicating semaphore is not valid
- * \note Keep as is in case of CMSIS based OS, otherwise change for your OS
- */
-#define GSM_SYS_SEM_NULL (osSemaphoreId)0
-
-/**
- * \brief Value indicating mutex is not valid
- * \note Keep as is in case of CMSIS based OS, otherwise change for your OS
- */
-#define GSM_SYS_MUTEX_NULL (osMutexId)0
-
-/**
- * \brief Value indicating timeout for OS timings
- * \note Keep as is in case of CMSIS based OS, otherwise change for your OS
- */
-#define GSM_SYS_TIMEOUT ((uint32_t)osWaitForever)
-
-/**
- * \brief GSM stack threads priority parameter
- * \note Usually normal priority is ok. If many threads are in the system and high traffic is introduced
- * This value might need to be set to higher value
- * \note Keep as is in case of CMSIS based OS, otherwise change for your OS
- */
-#define GSM_SYS_THREAD_PRIO (osPriorityNormal)
-
-/**
- * \brief Stack size of system threads
- * \note Keep as is in case of CMSIS based OS, otherwise change for your OS
- */
-#define GSM_SYS_THREAD_SS (1024)
-#endif /* GSM_CFG_OS || __DOXYGEN__ */
-
-/**
- * \}
- */
-
-#ifdef __cplusplus
-};
-#endif /* __cplusplus */
-
-#endif /* GSM_HDR_SYSTEM_H */
diff --git a/gsm_at_lib/src/system/gsm_ll_stm32.c b/gsm_at_lib/src/system/gsm_ll_stm32.c
deleted file mode 100644
index a6f062dc..00000000
--- a/gsm_at_lib/src/system/gsm_ll_stm32.c
+++ /dev/null
@@ -1,409 +0,0 @@
-/**
- * \file gsm_ll_stm32.c
- * \brief Generic STM32 driver, included in various STM32 driver variants
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-
-/*
- * How it works
- *
- * On first call to \ref gsm_ll_init, new thread is created and processed in usart_ll_thread function.
- * USART is configured in RX DMA mode and any incoming bytes are processed inside thread function.
- * DMA and USART implement interrupt handlers to notify main thread about new data ready to send to upper layer.
- *
- * More about UART + RX DMA: https://github.com/MaJerle/STM32_USART_DMA_RX
- *
- * \ref GSM_CFG_INPUT_USE_PROCESS must be enabled in `gsm_config.h` to use this driver.
- */
-#include "gsm/gsm.h"
-#include "gsm/gsm_mem.h"
-#include "gsm/gsm_input.h"
-#include "system/gsm_ll.h"
-
-#if !__DOXYGEN__
-
-#if !GSM_CFG_INPUT_USE_PROCESS
-#error "GSM_CFG_INPUT_USE_PROCESS must be enabled in `gsm_config.h` to use this driver."
-#endif /* GSM_CFG_INPUT_USE_PROCESS */
-
-#if !defined(GSM_USART_DMA_RX_BUFF_SIZE)
-#define GSM_USART_DMA_RX_BUFF_SIZE 0x1000
-#endif /* !defined(GSM_USART_DMA_RX_BUFF_SIZE) */
-
-#if !defined(GSM_MEM_SIZE)
-#define GSM_MEM_SIZE 0x1000
-#endif /* !defined(GSM_MEM_SIZE) */
-
-#if !defined(GSM_USART_RDR_NAME)
-#define GSM_USART_RDR_NAME RDR
-#endif /* !defined(GSM_USART_RDR_NAME) */
-
-/* USART memory */
-static uint8_t usart_mem[GSM_USART_DMA_RX_BUFF_SIZE];
-static uint8_t is_running, initialized;
-static size_t old_pos;
-
-/* USART thread */
-static void usart_ll_thread(void const * arg);
-static osThreadDef(usart_ll_thread, usart_ll_thread, osPriorityNormal, 0, 1024);
-static osThreadId usart_ll_thread_id;
-
-/* Message queue */
-static osMessageQDef(usart_ll_mbox, 10, uint8_t);
-static osMessageQId usart_ll_mbox_id;
-
-/**
- * \brief USART data processing
- */
-static void
-usart_ll_thread(void const * arg) {
- osEvent evt;
- size_t pos;
- static size_t old_pos;
-
- GSM_UNUSED(arg);
-
- while (1) {
- /* Wait for the event message from DMA or USART */
- evt = osMessageGet(usart_ll_mbox_id, osWaitForever);
- if (evt.status != osEventMessage) {
- continue;
- }
-
- /* Read data */
-#if defined(GSM_USART_DMA_RX_STREAM)
- pos = sizeof(usart_mem) - LL_DMA_GetDataLength(GSM_USART_DMA, GSM_USART_DMA_RX_STREAM);
-#else
- pos = sizeof(usart_mem) - LL_DMA_GetDataLength(GSM_USART_DMA, GSM_USART_DMA_RX_CH);
-#endif /* defined(GSM_USART_DMA_RX_STREAM) */
- if (pos != old_pos && is_running) {
- if (pos > old_pos) {
- gsm_input_process(&usart_mem[old_pos], pos - old_pos);
- } else {
- gsm_input_process(&usart_mem[old_pos], sizeof(usart_mem) - old_pos);
- if (pos > 0) {
- gsm_input_process(&usart_mem[0], pos);
- }
- }
- old_pos = pos;
- if (old_pos == sizeof(usart_mem)) {
- old_pos = 0;
- }
- }
- }
-}
-
-/**
- * \brief Configure UART using DMA for receive in double buffer mode and IDLE line detection
- */
-static void
-configure_uart(uint32_t baudrate) {
- static LL_USART_InitTypeDef usart_init;
- static LL_DMA_InitTypeDef dma_init;
- LL_GPIO_InitTypeDef gpio_init;
-
- if (!initialized) {
- /* Enable peripheral clocks */
- GSM_USART_CLK;
- GSM_USART_DMA_CLK;
- GSM_USART_TX_PORT_CLK;
- GSM_USART_RX_PORT_CLK;
-
-#if defined(GSM_RESET_PIN)
- GSM_RESET_PORT_CLK;
-#endif /* defined(GSM_RESET_PIN) */
-
-#if defined(GSM_GPIO0_PIN)
- GSM_GPIO0_PORT_CLK;
-#endif /* defined(GSM_GPIO0_PIN) */
-
-#if defined(GSM_GPIO2_PIN)
- GSM_GPIO2_PORT_CLK;
-#endif /* defined(GSM_GPIO2_PIN) */
-
-#if defined(GSM_CH_PD_PIN)
- GSM_CH_PD_PORT_CLK;
-#endif /* defined(GSM_CH_PD_PIN) */
-
- /* Global pin configuration */
- LL_GPIO_StructInit(&gpio_init);
- gpio_init.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
- gpio_init.Pull = LL_GPIO_PULL_UP;
- gpio_init.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
- gpio_init.Mode = LL_GPIO_MODE_OUTPUT;
-
-#if defined(GSM_RESET_PIN)
- /* Configure RESET pin */
- gpio_init.Pin = GSM_RESET_PIN;
- LL_GPIO_Init(GSM_RESET_PORT, &gpio_init);
-#endif /* defined(GSM_RESET_PIN) */
-
-#if defined(GSM_GPIO0_PIN)
- /* Configure GPIO0 pin */
- gpio_init.Pin = GSM_GPIO0_PIN;
- LL_GPIO_Init(GSM_GPIO0_PORT, &gpio_init);
- LL_GPIO_SetOutputPin(GSM_GPIO0_PORT, GSM_GPIO0_PIN);
-#endif /* defined(GSM_GPIO0_PIN) */
-
-#if defined(GSM_GPIO2_PIN)
- /* Configure GPIO2 pin */
- gpio_init.Pin = GSM_GPIO2_PIN;
- LL_GPIO_Init(GSM_GPIO2_PORT, &gpio_init);
- LL_GPIO_SetOutputPin(GSM_GPIO2_PORT, GSM_GPIO2_PIN);
-#endif /* defined(GSM_GPIO2_PIN) */
-
-#if defined(GSM_CH_PD_PIN)
- /* Configure CH_PD pin */
- gpio_init.Pin = GSM_CH_PD_PIN;
- LL_GPIO_Init(GSM_CH_PD_PORT, &gpio_init);
- LL_GPIO_SetOutputPin(GSM_CH_PD_PORT, GSM_CH_PD_PIN);
-#endif /* defined(GSM_CH_PD_PIN) */
-
- /* Configure USART pins */
- gpio_init.Mode = LL_GPIO_MODE_ALTERNATE;
-
- /* TX PIN */
- gpio_init.Alternate = GSM_USART_TX_PIN_AF;
- gpio_init.Pin = GSM_USART_TX_PIN;
- LL_GPIO_Init(GSM_USART_TX_PORT, &gpio_init);
-
- /* RX PIN */
- gpio_init.Alternate = GSM_USART_RX_PIN_AF;
- gpio_init.Pin = GSM_USART_RX_PIN;
- LL_GPIO_Init(GSM_USART_RX_PORT, &gpio_init);
-
- /* Configure UART */
- LL_USART_DeInit(GSM_USART);
- LL_USART_StructInit(&usart_init);
- usart_init.BaudRate = baudrate;
- usart_init.DataWidth = LL_USART_DATAWIDTH_8B;
- usart_init.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
- usart_init.OverSampling = LL_USART_OVERSAMPLING_16;
- usart_init.Parity = LL_USART_PARITY_NONE;
- usart_init.StopBits = LL_USART_STOPBITS_1;
- usart_init.TransferDirection = LL_USART_DIRECTION_TX_RX;
- LL_USART_Init(GSM_USART, &usart_init);
-
- /* Enable USART interrupts and DMA request */
- LL_USART_EnableIT_IDLE(GSM_USART);
- LL_USART_EnableIT_PE(GSM_USART);
- LL_USART_EnableIT_ERROR(GSM_USART);
- LL_USART_EnableDMAReq_RX(GSM_USART);
-
- /* Enable USART interrupts */
- NVIC_SetPriority(GSM_USART_IRQ, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0x07, 0x00));
- NVIC_EnableIRQ(GSM_USART_IRQ);
-
- /* Configure DMA */
- is_running = 0;
-#if defined(GSM_USART_DMA_RX_STREAM)
- LL_DMA_DeInit(GSM_USART_DMA, GSM_USART_DMA_RX_STREAM);
- dma_init.Channel = GSM_USART_DMA_RX_CH;
-#else
- LL_DMA_DeInit(GSM_USART_DMA, GSM_USART_DMA_RX_CH);
- dma_init.PeriphRequest = GSM_USART_DMA_RX_REQ_NUM;
-#endif /* defined(GSM_USART_DMA_RX_STREAM) */
- dma_init.PeriphOrM2MSrcAddress = (uint32_t)&GSM_USART->GSM_USART_RDR_NAME;
- dma_init.MemoryOrM2MDstAddress = (uint32_t)usart_mem;
- dma_init.Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
- dma_init.Mode = LL_DMA_MODE_CIRCULAR;
- dma_init.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT;
- dma_init.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT;
- dma_init.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_BYTE;
- dma_init.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_BYTE;
- dma_init.NbData = sizeof(usart_mem);
- dma_init.Priority = LL_DMA_PRIORITY_MEDIUM;
-#if defined(GSM_USART_DMA_RX_STREAM)
- LL_DMA_Init(GSM_USART_DMA, GSM_USART_DMA_RX_STREAM, &dma_init);
-#else
- LL_DMA_Init(GSM_USART_DMA, GSM_USART_DMA_RX_CH, &dma_init);
-#endif /* defined(GSM_USART_DMA_RX_STREAM) */
-
- /* Enable DMA interrupts */
-#if defined(GSM_USART_DMA_RX_STREAM)
- LL_DMA_EnableIT_HT(GSM_USART_DMA, GSM_USART_DMA_RX_STREAM);
- LL_DMA_EnableIT_TC(GSM_USART_DMA, GSM_USART_DMA_RX_STREAM);
- LL_DMA_EnableIT_TE(GSM_USART_DMA, GSM_USART_DMA_RX_STREAM);
- LL_DMA_EnableIT_FE(GSM_USART_DMA, GSM_USART_DMA_RX_STREAM);
- LL_DMA_EnableIT_DME(GSM_USART_DMA, GSM_USART_DMA_RX_STREAM);
-#else
- LL_DMA_EnableIT_HT(GSM_USART_DMA, GSM_USART_DMA_RX_CH);
- LL_DMA_EnableIT_TC(GSM_USART_DMA, GSM_USART_DMA_RX_CH);
- LL_DMA_EnableIT_TE(GSM_USART_DMA, GSM_USART_DMA_RX_CH);
-#endif /* defined(GSM_USART_DMA_RX_STREAM) */
-
- /* Enable DMA interrupts */
- NVIC_SetPriority(GSM_USART_DMA_RX_IRQ, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0x07, 0x00));
- NVIC_EnableIRQ(GSM_USART_DMA_RX_IRQ);
-
- old_pos = 0;
- is_running = 1;
-
- /* Start DMA and USART */
-#if defined(GSM_USART_DMA_RX_STREAM)
- LL_DMA_EnableStream(GSM_USART_DMA, GSM_USART_DMA_RX_STREAM);
-#else
- LL_DMA_EnableChannel(GSM_USART_DMA, GSM_USART_DMA_RX_CH);
-#endif /* defined(GSM_USART_DMA_RX_STREAM) */
- LL_USART_Enable(GSM_USART);
- } else {
- osDelay(10);
- LL_USART_Disable(GSM_USART);
- usart_init.BaudRate = baudrate;
- LL_USART_Init(GSM_USART, &usart_init);
- LL_USART_Enable(GSM_USART);
- }
-
- /* Create mbox and start thread */
- if (usart_ll_mbox_id == NULL) {
- usart_ll_mbox_id = osMessageCreate(osMessageQ(usart_ll_mbox), NULL);
- }
- if (usart_ll_thread_id == NULL) {
- usart_ll_thread_id = osThreadCreate(osThread(usart_ll_thread), usart_ll_mbox_id);
- }
-}
-
-#if defined(GSM_RESET_PIN)
-/**
- * \brief Hardware reset callback
- */
-static uint8_t
-reset_device(uint8_t state) {
- if (state) { /* Activate reset line */
- LL_GPIO_ResetOutputPin(GSM_RESET_PORT, GSM_RESET_PIN);
- } else {
- LL_GPIO_SetOutputPin(GSM_RESET_PORT, GSM_RESET_PIN);
- }
- return 1;
-}
-#endif /* defined(GSM_RESET_PIN) */
-
-/**
- * \brief Send data to GSM device
- * \param[in] data: Pointer to data to send
- * \param[in] len: Number of bytes to send
- * \return Number of bytes sent
- */
-static size_t
-send_data(const void* data, size_t len) {
- const uint8_t* d = data;
-
- for (size_t i = 0; i < len; i++, d++) {
- LL_USART_TransmitData8(GSM_USART, *d);
- while (!LL_USART_IsActiveFlag_TXE(GSM_USART)) {}
- }
- return len;
-}
-
-/**
- * \brief Callback function called from initialization process
- * \note This function may be called multiple times if AT baudrate is changed from application
- * \param[in,out] ll: Pointer to \ref gsm_ll_t structure to fill data for communication functions
- * \param[in] baudrate: Baudrate to use on AT port
- * \return Member of \ref gsmr_t enumeration
- */
-gsmr_t
-gsm_ll_init(gsm_ll_t* ll) {
-#if !GSM_CFG_MEM_CUSTOM
- static uint8_t memory[GSM_MEM_SIZE];
- gsm_mem_region_t mem_regions[] = {
- { memory, sizeof(memory) }
- };
-
- if (!initialized) {
- gsm_mem_assignmemory(mem_regions, GSM_ARRAYSIZE(mem_regions)); /* Assign memory for allocations */
- }
-#endif /* !GSM_CFG_MEM_CUSTOM */
-
- if (!initialized) {
- ll->send_fn = send_data; /* Set callback function to send data */
-#if defined(GSM_RESET_PIN)
- ll->reset_fn = reset_device; /* Set callback for hardware reset */
-#endif /* defined(GSM_RESET_PIN) */
- }
-
- configure_uart(ll->uart.baudrate); /* Initialize UART for communication */
- initialized = 1;
- return gsmOK;
-}
-
-/**
- * \brief Callback function to de-init low-level communication part
- * \param[in,out] ll: Pointer to \ref gsm_ll_t structure to fill data for communication functions
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
- */
-gsmr_t
-gsm_ll_deinit(gsm_ll_t* ll) {
- if (usart_ll_mbox_id != NULL) {
- osMessageQId tmp = usart_ll_mbox_id;
- usart_ll_mbox_id = NULL;
- osMessageDelete(tmp);
- }
- if (usart_ll_thread_id != NULL) {
- osThreadId tmp = usart_ll_thread_id;
- usart_ll_thread_id = NULL;
- osThreadTerminate(tmp);
- }
- initialized = 0;
- GSM_UNUSED(ll);
- return gsmOK;
-}
-
-/**
- * \brief UART global interrupt handler
- */
-void
-GSM_USART_IRQHANDLER(void) {
- LL_USART_ClearFlag_IDLE(GSM_USART);
- LL_USART_ClearFlag_PE(GSM_USART);
- LL_USART_ClearFlag_FE(GSM_USART);
- LL_USART_ClearFlag_ORE(GSM_USART);
- LL_USART_ClearFlag_NE(GSM_USART);
-
- if (usart_ll_mbox_id != NULL) {
- osMessagePut(usart_ll_mbox_id, 0, 0);
- }
-}
-
-/**
- * \brief UART DMA stream/channel handler
- */
-void
-GSM_USART_DMA_RX_IRQHANDLER(void) {
- GSM_USART_DMA_RX_CLEAR_TC;
- GSM_USART_DMA_RX_CLEAR_HT;
-
- if (usart_ll_mbox_id != NULL) {
- osMessagePut(usart_ll_mbox_id, 0, 0);
- }
-}
-
-#endif /* !__DOXYGEN__ */
diff --git a/gsm_at_lib/src/system/gsm_ll_stm32f429zi_nucleo.c b/gsm_at_lib/src/system/gsm_ll_stm32f429zi_nucleo.c
deleted file mode 100644
index 6b9749ff..00000000
--- a/gsm_at_lib/src/system/gsm_ll_stm32f429zi_nucleo.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/**
- * \file gsm_ll_stm32f429zi_nucleo.c
- * \brief Low-level communication with GSM device for STM32F429ZI-Nucleo using DMA
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-
-/*
- * Default UART configuration is:
- *
- * UART: USART6
- * STM32 TX (GSM RX): GPIOC, GPIO_PIN_6
- * STM32 RX (GSM TX): GPIOC, GPIO_PIN_7
- * RESET: GPIOC, GPIO_PIN_5
- *
- * USART_DMA: DMA2
- * USART_DMA_STREAM: DMA_STREAM_1
- * USART_DMA_CHANNEL: DMA_CHANNEL_5
- */
-#include "gsm/gsm.h"
-#include "gsm/gsm_mem.h"
-#include "gsm/gsm_input.h"
-#include "system/gsm_ll.h"
-
-#if !__DOXYGEN__
-
-#include "stm32f4xx_ll_bus.h"
-#include "stm32f4xx_ll_usart.h"
-#include "stm32f4xx_ll_gpio.h"
-#include "stm32f4xx_ll_dma.h"
-#include "stm32f4xx_ll_rcc.h"
-
-/* USART */
-#define GSM_USART USART6
-#define GSM_USART_CLK LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART6)
-#define GSM_USART_IRQ USART6_IRQn
-#define GSM_USART_IRQHANDLER USART6_IRQHandler
-#define GSM_USART_RDR_NAME DR
-
-/* DMA settings */
-#define GSM_USART_DMA DMA2
-#define GSM_USART_DMA_CLK LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA2)
-#define GSM_USART_DMA_RX_STREAM LL_DMA_STREAM_1
-#define GSM_USART_DMA_RX_CH LL_DMA_CHANNEL_5
-#define GSM_USART_DMA_RX_IRQ DMA2_Stream1_IRQn
-#define GSM_USART_DMA_RX_IRQHANDLER DMA2_Stream1_IRQHandler
-
-/* DMA flags management */
-#define GSM_USART_DMA_RX_IS_TC LL_DMA_IsActiveFlag_TC1(GSM_USART_DMA)
-#define GSM_USART_DMA_RX_IS_HT LL_DMA_IsActiveFlag_HT1(GSM_USART_DMA)
-#define GSM_USART_DMA_RX_CLEAR_TC LL_DMA_ClearFlag_TC1(GSM_USART_DMA)
-#define GSM_USART_DMA_RX_CLEAR_HT LL_DMA_ClearFlag_HT1(GSM_USART_DMA)
-
-/* USART TX PIN */
-#define GSM_USART_TX_PORT_CLK LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOC)
-#define GSM_USART_TX_PORT GPIOC
-#define GSM_USART_TX_PIN LL_GPIO_PIN_6
-#define GSM_USART_TX_PIN_AF LL_GPIO_AF_8
-
-/* USART RX PIN */
-#define GSM_USART_RX_PORT_CLK LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOC)
-#define GSM_USART_RX_PORT GPIOC
-#define GSM_USART_RX_PIN LL_GPIO_PIN_7
-#define GSM_USART_RX_PIN_AF LL_GPIO_AF_8
-
-/* RESET PIN */
-#define GSM_RESET_PORT_CLK LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOC)
-#define GSM_RESET_PORT GPIOC
-#define GSM_RESET_PIN LL_GPIO_PIN_5
-
-/* Include STM32 generic driver */
-#include "../system/gsm_ll_stm32.c"
-
-#endif /* !__DOXYGEN__ */
diff --git a/gsm_at_lib/src/system/gsm_sys_cmsis_os.c b/gsm_at_lib/src/system/gsm_sys_cmsis_os.c
deleted file mode 100644
index 079405d6..00000000
--- a/gsm_at_lib/src/system/gsm_sys_cmsis_os.c
+++ /dev/null
@@ -1,220 +0,0 @@
-/**
- * \file gsm_sys_cmsis_os.c
- * \brief System dependant functions for STM32 MCU with CMSIS OS
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#include "system/gsm_sys.h"
-#include "cmsis_os.h"
-
-#if !__DOXYGEN__
-
-static osMutexId sys_mutex; /* Mutex ID for main protection */
-
-uint8_t
-gsm_sys_init(void) {
- gsm_sys_mutex_create(&sys_mutex); /* Create system mutex */
- return 1;
-}
-
-uint32_t
-gsm_sys_now(void) {
- return osKernelSysTick(); /* Get current tick in units of milliseconds */
-}
-
-uint8_t
-gsm_sys_protect(void) {
- gsm_sys_mutex_lock(&sys_mutex); /* Lock system and protect it */
- return 1;
-}
-
-uint8_t
-gsm_sys_unprotect(void) {
- gsm_sys_mutex_unlock(&sys_mutex); /* Release lock */
- return 1;
-}
-
-uint8_t
-gsm_sys_mutex_create(gsm_sys_mutex_t* p) {
- osMutexDef(MUT); /* Define a mutex */
- *p = osRecursiveMutexCreate(osMutex(MUT)); /* Create recursive mutex */
- return *p != NULL; /* Return status */
-}
-
-uint8_t
-gsm_sys_mutex_delete(gsm_sys_mutex_t* p) {
- return osMutexDelete(*p) == osOK; /* Delete mutex */
-}
-
-uint8_t
-gsm_sys_mutex_lock(gsm_sys_mutex_t* p) {
- return osRecursiveMutexWait(*p, osWaitForever) == osOK; /* Wait forever for mutex */
-}
-
-uint8_t
-gsm_sys_mutex_unlock(gsm_sys_mutex_t* p) {
- return osRecursiveMutexRelease(*p) == osOK; /* Release mutex */
-}
-
-uint8_t
-gsm_sys_mutex_isvalid(gsm_sys_mutex_t* p) {
- return p != NULL && *p != NULL; /* Check if mutex is valid */
-}
-
-uint8_t
-gsm_sys_mutex_invalid(gsm_sys_mutex_t* p) {
- *p = GSM_SYS_MUTEX_NULL; /* Set mutex as invalid */
- return 1;
-}
-
-uint8_t
-gsm_sys_sem_create(gsm_sys_sem_t* p, uint8_t cnt) {
- osSemaphoreDef(SEM); /* Define semaphore info */
- *p = osSemaphoreCreate(osSemaphore(SEM), 1);/* Create semaphore with one token */
-
- if (*p != NULL && !cnt) { /* We have valid entry */
- osSemaphoreWait(*p, 0); /* Lock semaphore immediatelly */
- }
- return *p != NULL;
-}
-
-uint8_t
-gsm_sys_sem_delete(gsm_sys_sem_t* p) {
- return osSemaphoreDelete(*p) == osOK; /* Delete semaphore */
-}
-
-uint32_t
-gsm_sys_sem_wait(gsm_sys_sem_t* p, uint32_t timeout) {
- uint32_t tick = osKernelSysTick(); /* Get start tick time */
- return (osSemaphoreWait(*p, !timeout ? osWaitForever : timeout) == osOK) ? (osKernelSysTick() - tick) : GSM_SYS_TIMEOUT; /* Wait for semaphore with specific time */
-}
-
-uint8_t
-gsm_sys_sem_release(gsm_sys_sem_t* p) {
- return osSemaphoreRelease(*p) == osOK; /* Release semaphore */
-}
-
-uint8_t
-gsm_sys_sem_isvalid(gsm_sys_sem_t* p) {
- return p != NULL && *p != NULL; /* Check if valid */
-}
-
-uint8_t
-gsm_sys_sem_invalid(gsm_sys_sem_t* p) {
- *p = GSM_SYS_SEM_NULL; /* Invaldiate semaphore */
- return 1;
-}
-
-uint8_t
-gsm_sys_mbox_create(gsm_sys_mbox_t* b, size_t size) {
- osMessageQDef(MBOX, size, void *); /* Define message box */
- *b = osMessageCreate(osMessageQ(MBOX), NULL); /* Create message box */
- return *b != NULL;
-}
-
-uint8_t
-gsm_sys_mbox_delete(gsm_sys_mbox_t* b) {
- if (osMessageWaiting(*b)) { /* We still have messages in queue, should not delete queue */
- return 0; /* Return error as we still have entries in message queue */
- }
- return osMessageDelete(*b) == osOK; /* Delete message queue */
-}
-
-uint32_t
-gsm_sys_mbox_put(gsm_sys_mbox_t* b, void* m) {
- uint32_t tick = osKernelSysTick(); /* Get start time */
- return osMessagePut(*b, (uint32_t)m, osWaitForever) == osOK ? (osKernelSysTick() - tick) : GSM_SYS_TIMEOUT; /* Put new message with forever timeout */
-}
-
-uint32_t
-gsm_sys_mbox_get(gsm_sys_mbox_t* b, void** m, uint32_t timeout) {
- osEvent evt;
- uint32_t time = osKernelSysTick(); /* Get current time */
-
- evt = osMessageGet(*b, !timeout ? osWaitForever : timeout); /* Get message event */
- if (evt.status == osEventMessage) { /* Did we get a message? */
- *m = evt.value.p; /* Set value */
- return osKernelSysTick() - time; /* Return time required for reading message */
- }
- return GSM_SYS_TIMEOUT;
-}
-
-uint8_t
-gsm_sys_mbox_putnow(gsm_sys_mbox_t* b, void* m) {
- return osMessagePut(*b, (uint32_t)m, 0) == osOK; /* Put new message without timeout */
-}
-
-uint8_t
-gsm_sys_mbox_getnow(gsm_sys_mbox_t* b, void** m) {
- osEvent evt;
-
- evt = osMessageGet(*b, 0); /* Get message event */
- if (evt.status == osEventMessage) { /* Did we get a message? */
- *m = evt.value.p; /* Set value */
- return 1;
- }
- return 0;
-}
-
-uint8_t
-gsm_sys_mbox_isvalid(gsm_sys_mbox_t* b) {
- return b != NULL && *b != NULL; /* Return status if message box is valid */
-}
-
-uint8_t
-gsm_sys_mbox_invalid(gsm_sys_mbox_t* b) {
- *b = GSM_SYS_MBOX_NULL; /* Invalidate message box */
- return 1;
-}
-
-uint8_t
-gsm_sys_thread_create(gsm_sys_thread_t* t, const char* name, gsm_sys_thread_fn thread_func, void* const arg, size_t stack_size, gsm_sys_thread_prio_t prio) {
- gsm_sys_thread_t id;
- const osThreadDef_t thread_def = {(char *)name, (os_pthread)thread_func, (osPriority)prio, 0, stack_size ? stack_size : GSM_SYS_THREAD_SS }; /* Create thread description */
- id = osThreadCreate(&thread_def, arg); /* Create thread */
- if (t != NULL) {
- *t = id;
- }
- return id != NULL;
-}
-
-uint8_t
-gsm_sys_thread_terminate(gsm_sys_thread_t* t) {
- osThreadTerminate(t != NULL ? *t : NULL); /* Terminate thread */
- return 1;
-}
-
-uint8_t
-gsm_sys_thread_yield(void) {
- osThreadYield(); /* Yield current thread */
- return 1;
-}
-
-#endif /* !__DOXYGEN__ */
diff --git a/gsm_at_lib/src/system/gsm_sys_cmsis_os2.c b/gsm_at_lib/src/system/gsm_sys_cmsis_os2.c
deleted file mode 100644
index a986cfbd..00000000
--- a/gsm_at_lib/src/system/gsm_sys_cmsis_os2.c
+++ /dev/null
@@ -1,218 +0,0 @@
-/**
- * \file gsm_sys_cmsis_os2.c
- * \brief System dependant functions for CMSIS based operating system
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * This file is part of GSM-AT library.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#include "system/gsm_sys.h"
-#include "cmsis_os2.h"
-
-#if !__DOXYGEN__
-static osMutexId_t sys_mutex;
-
-uint8_t
-gsm_sys_init(void) {
- gsm_sys_mutex_create(&sys_mutex);
- return 1;
-}
-
-uint32_t
-gsm_sys_now(void) {
- return osKernelGetTickCount();
-}
-
-#if GSM_CFG_OS
-
-uint8_t
-gsm_sys_protect(void) {
- gsm_sys_mutex_lock(&sys_mutex);
- return 1;
-}
-
-uint8_t
-gsm_sys_unprotect(void) {
- gsm_sys_mutex_unlock(&sys_mutex);
- return 1;
-}
-
-uint8_t
-gsm_sys_mutex_create(gsm_sys_mutex_t* p) {
- const osMutexAttr_t attr = {
- .attr_bits = osMutexRecursive
- };
-
- *p = osMutexNew(&attr);
- return *p != NULL;
-}
-
-uint8_t
-gsm_sys_mutex_delete(gsm_sys_mutex_t* p) {
- return osMutexDelete(*p) == osOK;
-}
-
-uint8_t
-gsm_sys_mutex_lock(gsm_sys_mutex_t* p) {
- return osMutexAcquire(*p, osWaitForever) == osOK;
-}
-
-uint8_t
-gsm_sys_mutex_unlock(gsm_sys_mutex_t* p) {
- return osMutexRelease(*p);
-}
-
-uint8_t
-gsm_sys_mutex_isvalid(gsm_sys_mutex_t* p) {
- return p != NULL && *p != NULL;
-}
-
-uint8_t
-gsm_sys_mutex_invalid(gsm_sys_mutex_t* p) {
- *p = GSM_SYS_MUTEX_NULL;
- return 1;
-}
-
-uint8_t
-gsm_sys_sem_create(gsm_sys_sem_t* p, uint8_t cnt) {
- *p = osSemaphoreNew(1, cnt > 0, NULL);
- return *p != NULL;
-}
-
-uint8_t
-gsm_sys_sem_delete(gsm_sys_sem_t* p) {
- return osSemaphoreDelete(*p) == osOK;
-}
-
-uint32_t
-gsm_sys_sem_wait(gsm_sys_sem_t* p, uint32_t timeout) {
- uint32_t tick = osKernelGetTickCount();
- return (osSemaphoreAcquire(*p, !timeout ? osWaitForever : timeout) == osOK) ? (osKernelGetTickCount() - tick) : GSM_SYS_TIMEOUT;
-}
-
-uint8_t
-gsm_sys_sem_release(gsm_sys_sem_t* p) {
- return osSemaphoreRelease(*p) == osOK;
-}
-
-uint8_t
-gsm_sys_sem_isvalid(gsm_sys_sem_t* p) {
- return p != NULL && *p != NULL;
-}
-
-uint8_t
-gsm_sys_sem_invalid(gsm_sys_sem_t* p) {
- *p = GSM_SYS_SEM_NULL;
- return 1;
-}
-
-uint8_t
-gsm_sys_mbox_create(gsm_sys_mbox_t* b, size_t size) {
- *b = osMessageQueueNew(size, sizeof(void *), NULL);
- return *b != NULL;
-}
-
-uint8_t
-gsm_sys_mbox_delete(gsm_sys_mbox_t* b) {
- if (osMessageQueueGetCount(*b)) {
- return 0;
- }
- return osMessageQueueDelete(*b) == osOK;
-}
-
-uint32_t
-gsm_sys_mbox_put(gsm_sys_mbox_t* b, void* m) {
- uint32_t tick = osKernelGetTickCount();
- return osMessageQueuePut(*b, m, 0, osWaitForever) == osOK ? (osKernelGetTickCount() - tick) : GSM_SYS_TIMEOUT;
-}
-
-uint32_t
-gsm_sys_mbox_get(gsm_sys_mbox_t* b, void** m, uint32_t timeout) {
- osStatus_t evt;
- uint32_t time = osKernelGetTickCount();
-
- evt = osMessageQueueGet(*b, *m, NULL, !timeout ? osWaitForever : timeout);
- if (evt == osOK) {
- return osKernelGetTickCount() - time;
- }
- return GSM_SYS_TIMEOUT;
-}
-
-uint8_t
-gsm_sys_mbox_putnow(gsm_sys_mbox_t* b, void* m) {
- return osMessageQueuePut(*b, m, 0, 0) == osOK;
-}
-
-uint8_t
-gsm_sys_mbox_getnow(gsm_sys_mbox_t* b, void** m) {
- osStatus_t evt;
-
- evt = osMessageQueueGet(*b, *m, 0, 0);
- return evt == osOK;
-}
-
-uint8_t
-gsm_sys_mbox_isvalid(gsm_sys_mbox_t* b) {
- return b != NULL && *b != NULL;
-}
-
-uint8_t
-gsm_sys_mbox_invalid(gsm_sys_mbox_t* b) {
- *b = GSM_SYS_MBOX_NULL;
- return 1;
-}
-
-uint8_t
-gsm_sys_thread_create(gsm_sys_thread_t* t, const char* name, gsm_sys_thread_fn thread_func, void* const arg, size_t stack_size, gsm_sys_thread_prio_t prio) {
- gsm_sys_thread_t id;
- const osThreadAttr_t attr = {
- .name = name,
- .priority = prio,
- .stack_size = stack_size > 0 ? stack_size : GSM_SYS_THREAD_SS
- };
- id = osThreadNew(thread_func, arg, &attr);
- if (t != NULL) {
- *t = id;
- }
- return id != NULL;
-}
-
-uint8_t
-gsm_sys_thread_terminate(gsm_sys_thread_t* t) {
- osThreadTerminate(t != NULL ? *t : NULL);
- return 1;
-}
-
-uint8_t
-gsm_sys_thread_yield(void) {
- osThreadYield();
- return 1;
-}
-
-#endif /* GSM_CFG_OS */
-#endif /* !__DOXYGEN__ */
diff --git a/gsm_at_lib/src/system/gsm_sys_template.c b/gsm_at_lib/src/system/gsm_sys_template.c
deleted file mode 100644
index e7a4b8f2..00000000
--- a/gsm_at_lib/src/system/gsm_sys_template.c
+++ /dev/null
@@ -1,395 +0,0 @@
-/**
- * \file gsm_sys_template.c
- * \brief System dependant functions
- */
-
-/*
- * Copyright (c) 2019 Tilen MAJERLE
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Author: Tilen MAJERLE
- * Version: v0.6.0
- */
-#include "system/gsm_sys.h"
-#include "cmsis_os.h"
-
-/*******************************************/
-/*******************************************/
-/** Modify this file for your system **/
-/*******************************************/
-/*******************************************/
-
-static osMutexId sys_mutex; /* Mutex ID for main protection */
-
-/**
- * \brief Init system dependant parameters
- * \note Called from high-level application layer when required
- * \return 1 on success, 0 otherwise
- */
-uint8_t
-gsm_sys_init(void) {
- gsm_sys_mutex_create(&sys_mutex); /* Create system mutex */
- return 1;
-}
-
-/**
- * \brief Get current time in units of milliseconds
- * \return Current time in units of milliseconds
- */
-uint32_t
-gsm_sys_now(void) {
- return osKernelSysTick(); /* Get current tick in units of milliseconds */
-}
-
-/**
- * \brief Protect stack core
- * \note This function is required with OS
- *
- * \note This function may be called multiple times, recursive protection is required
- * \return 1 on success, 0 otherwise
- */
-uint8_t
-gsm_sys_protect(void) {
- gsm_sys_mutex_lock(&sys_mutex); /* Lock system and protect it */
- return 1;
-}
-
-/**
- * \brief Protect stack core
- * \note This function is required with OS
- * \return 1 on success, 0 otherwise
- */
-uint8_t
-gsm_sys_unprotect(void) {
- gsm_sys_mutex_unlock(&sys_mutex); /* Release lock */
- return 1;
-}
-
-/**
- * \brief Create a new mutex and pass it to input pointer
- * \note This function is required with OS
- * \note Recursive mutex must be created as it may be locked multiple times before unlocked
- * \param[out] p: Pointer to mutex structure to save result to
- * \return 1 on success, 0 otherwise
- */
-uint8_t
-gsm_sys_mutex_create(gsm_sys_mutex_t* p) {
- osMutexDef(MUT); /* Define a mutex */
- *p = osRecursiveMutexCreate(osMutex(MUT)); /* Create recursive mutex */
- return !!*p; /* Return status */
-}
-
-/**
- * \brief Delete mutex from OS
- * \note This function is required with OS
- * \param[in] p: Pointer to mutex structure
- * \return 1 on success, 0 otherwise
- */
-uint8_t
-gsm_sys_mutex_delete(gsm_sys_mutex_t* p) {
- return osMutexDelete(*p) == osOK; /* Delete mutex */
-}
-
-/**
- * \brief Wait forever to lock the mutex
- * \note This function is required with OS
- * \param[in] p: Pointer to mutex structure
- * \return 1 on success, 0 otherwise
- */
-uint8_t
-gsm_sys_mutex_lock(gsm_sys_mutex_t* p) {
- return osRecursiveMutexWait(*p, osWaitForever) == osOK; /* Wait forever for mutex */
-}
-
-/**
- * \brief Unlock mutex
- * \note This function is required with OS
- * \param[in] p: Pointer to mutex structure
- * \return 1 on success, 0 otherwise
- */
-uint8_t
-gsm_sys_mutex_unlock(gsm_sys_mutex_t* p) {
- return osRecursiveMutexRelease(*p) == osOK; /* Release mutex */
-}
-
-/**
- * \brief Check if mutex structure is valid OS entry
- * \note This function is required with OS
- * \param[in] p: Pointer to mutex structure
- * \return 1 on success, 0 otherwise
- */
-uint8_t
-gsm_sys_mutex_isvalid(gsm_sys_mutex_t* p) {
- return p != NULL && *p != NULL; /* Check if mutex is valid */
-}
-
-/**
- * \brief Set mutex structure as invalid
- * \note This function is required with OS
- * \param[in] p: Pointer to mutex structure
- * \return 1 on success, 0 otherwise
- */
-uint8_t
-gsm_sys_mutex_invalid(gsm_sys_mutex_t* p) {
- *p = GSM_SYS_MUTEX_NULL; /* Set mutex as invalid */
- return 1;
-}
-
-/**
- * \brief Create a new binary semaphore and set initial state
- * \note Semaphore may only have 1 token available
- * \note This function is required with OS
- * \param[out] p: Pointer to semaphore structure to fill with result
- * \param[in] cnt: Count indicating default semaphore state:
- * 0: Lock it immediteally
- * 1: Leave it unlocked
- * \return 1 on success, 0 otherwise
- */
-uint8_t
-gsm_sys_sem_create(gsm_sys_sem_t* p, uint8_t cnt) {
- osSemaphoreDef(SEM); /* Define semaphore info */
- *p = osSemaphoreCreate(osSemaphore(SEM), 1); /* Create semaphore with one token */
-
- if (*p && !cnt) { /* We have valid entry */
- osSemaphoreWait(*p, 0); /* Lock semaphore immediatelly */
- }
- return !!*p;
-}
-
-/**
- * \brief Delete binary semaphore
- * \note This function is required with OS
- * \param[in] p: Pointer to semaphore structure
- * \return 1 on success, 0 otherwise
- */
-uint8_t
-gsm_sys_sem_delete(gsm_sys_sem_t* p) {
- return osSemaphoreDelete(*p) == osOK; /* Delete semaphore */
-}
-
-/**
- * \brief Wait for semaphore to be available
- * \note This function is required with OS
- * \param[in] p: Pointer to semaphore structure
- * \param[in] timeout: Timeout to wait in milliseconds. When 0 is applied, wait forever
- * \return Number of milliseconds waited for semaphore to become available
- */
-uint32_t
-gsm_sys_sem_wait(gsm_sys_sem_t* p, uint32_t timeout) {
- uint32_t tick = osKernelSysTick(); /* Get start tick time */
- return (osSemaphoreWait(*p, !timeout ? osWaitForever : timeout) == osOK) ? (osKernelSysTick() - tick) : GSM_SYS_TIMEOUT; /* Wait for semaphore with specific time */
-}
-
-/**
- * \brief Release semaphore
- * \note This function is required with OS
- * \param[in] p: Pointer to semaphore structure
- * \return 1 on success, 0 otherwise
- */
-uint8_t
-gsm_sys_sem_release(gsm_sys_sem_t* p) {
- return osSemaphoreRelease(*p) == osOK; /* Release semaphore */
-}
-
-/**
- * \brief Check if semaphore is valid
- * \note This function is required with OS
- * \param[in] p: Pointer to semaphore structure
- * \return 1 on success, 0 otherwise
- */
-uint8_t
-gsm_sys_sem_isvalid(gsm_sys_sem_t* p) {
- return p != NULL && *p != NULL; /* Check if valid */
-}
-
-/**
- * \brief Invalid semaphore
- * \note This function is required with OS
- * \param[in] p: Pointer to semaphore structure
- * \return 1 on success, 0 otherwise
- */
-uint8_t
-gsm_sys_sem_invalid(gsm_sys_sem_t* p) {
- *p = GSM_SYS_SEM_NULL; /* Invaldiate semaphore */
- return 1;
-}
-
-/**
- * \brief Create a new message queue with entry type of "void *"
- * \note This function is required with OS
- * \param[out] b: Pointer to message queue structure
- * \param[in] size: Number of entries for message queue to hold
- * \return 1 on success, 0 otherwise
- */
-uint8_t
-gsm_sys_mbox_create(gsm_sys_mbox_t* b, size_t size) {
- osMessageQDef(MBOX, size, void *); /* Define message box */
- *b = osMessageCreate(osMessageQ(MBOX), NULL); /* Create message box */
- return !!*b;
-}
-
-/**
- * \brief Delete message queue
- * \note This function is required with OS
- * \param[in] b: Pointer to message queue structure
- * \return 1 on success, 0 otherwise
- */
-uint8_t
-gsm_sys_mbox_delete(gsm_sys_mbox_t* b) {
- if (osMessageWaiting(*b)) { /* We still have messages in queue, should not delete queue */
- return 0; /* Return error as we still have entries in message queue */
- }
- return osMessageDelete(*b) == osOK; /* Delete message queue */
-}
-
-/**
- * \brief Put a new entry to message queue and wait until memory available
- * \note This function is required with OS
- * \param[in] b: Pointer to message queue structure
- * \param[in] m: Pointer to entry to insert to message queue
- * \return Time in units of milliseconds needed to put a message to queue
- */
-uint32_t
-gsm_sys_mbox_put(gsm_sys_mbox_t* b, void* m) {
- uint32_t tick = osKernelSysTick(); /* Get start time */
- return osMessagePut(*b, (uint32_t)m, osWaitForever) == osOK ? (osKernelSysTick() - tick) : GSM_SYS_TIMEOUT; /* Put new message with forever timeout */
-}
-
-/**
- * \brief Get a new entry from message queue with timeout
- * \note This function is required with OS
- * \param[in] b: Pointer to message queue structure
- * \param[in] m: Pointer to pointer to result to save value from message queue to
- * \param[in] timeout: Maximal timeout to wait for new message. When 0 is applied, wait for unlimited time
- * \return Time in units of milliseconds needed to put a message to queue
- */
-uint32_t
-gsm_sys_mbox_get(gsm_sys_mbox_t* b, void** m, uint32_t timeout) {
- osEvent evt;
- uint32_t time = osKernelSysTick(); /* Get current time */
-
- evt = osMessageGet(*b, !timeout ? osWaitForever : timeout); /* Get message event */
- if (evt.status == osEventMessage) { /* Did we get a message? */
- *m = evt.value.p; /* Set value */
- return osKernelSysTick() - time; /* Return time required for reading message */
- }
- return GSM_SYS_TIMEOUT;
-}
-
-/**
- * \brief Put a new entry to message queue without timeout (now or fail)
- * \note This function is required with OS
- * \param[in] b: Pointer to message queue structure
- * \param[in] m: Pointer to message to save to queue
- * \return 1 on success, 0 otherwise
- */
-uint8_t
-gsm_sys_mbox_putnow(gsm_sys_mbox_t* b, void* m) {
- return osMessagePut(*b, (uint32_t)m, 0) == osOK; /* Put new message without timeout */
-}
-
-/**
- * \brief Get an entry from message queue immediatelly
- * \note This function is required with OS
- * \param[in] b: Pointer to message queue structure
- * \param[in] m: Pointer to pointer to result to save value from message queue to
- * \return 1 on success, 0 otherwise
- */
-uint8_t
-gsm_sys_mbox_getnow(gsm_sys_mbox_t* b, void** m) {
- osEvent evt;
-
- evt = osMessageGet(*b, 0); /* Get message event */
- if (evt.status == osEventMessage) { /* Did we get a message? */
- *m = evt.value.p; /* Set value */
- return 1;
- }
- return 0;
-}
-
-/**
- * \brief Check if message queue is valid
- * \note This function is required with OS
- * \param[in] b: Pointer to message queue structure
- * \return 1 on success, 0 otherwise
- */
-uint8_t
-gsm_sys_mbox_isvalid(gsm_sys_mbox_t* b) {
- return b != NULL && *b != NULL; /* Return status if message box is valid */
-}
-
-/**
- * \brief Invalid message queue
- * \note This function is required with OS
- * \param[in] b: Pointer to message queue structure
- * \return 1 on success, 0 otherwise
- */
-uint8_t
-gsm_sys_mbox_invalid(gsm_sys_mbox_t* b) {
- *b = GSM_SYS_MBOX_NULL; /* Invalidate message box */
- return 1;
-}
-
-/**
- * \brief Create a new thread
- * \note This function is required with OS
- * \param[out] t: Pointer to thread identifier if create was successful
- * \param[in] name: Name of a new thread
- * \param[in] thread_func: Thread function to use as thread body
- * \param[in] arg: Thread function argument
- * \param[in] stack_size: Size of thread stack in uints of bytes. If set to 0, reserve default stack size
- * \param[in] prio: Thread priority
- * \return 1 on success, 0 otherwise
- */
-uint8_t
-gsm_sys_thread_create(gsm_sys_thread_t* t, const char* name, gsm_sys_thread_fn thread_func, void* const arg, size_t stack_size, gsm_sys_thread_prio_t prio) {
- gsm_sys_thread_t id;
- const osThreadDef_t thread_def = {(char *)name, (os_pthread)thread_func, (osPriority)prio, 0, stack_size ? stack_size : GSM_SYS_THREAD_SS }; /* Create thread description */
- id = osThreadCreate(&thread_def, arg); /* Create thread */
- if (t != NULL) {
- *t = id;
- }
- return !!id;
-}
-
-/**
- * \brief Terminate thread (shut it down and remove)
- * \note This function is required with OS
- * \param[in] t: Pointer to thread handle to terminate. If set to NULL, terminate current thread (thread from where function is called)
- * \return 1 on success, 0 otherwise
- */
-uint8_t
-gsm_sys_thread_terminate(gsm_sys_thread_t* t) {
- osThreadTerminate(t != NULL ? *t : NULL); /* Terminate thread */
- return 1;
-}
-
-/**
- * \brief Yield current thread
- * \note This function is required with OS
- * \return 1 on success, 0 otherwise
- */
-uint8_t
-gsm_sys_thread_yield(void) {
- osThreadYield(); /* Yield current thread */
- return 1;
-}
diff --git a/gsm_at_lib/src/api/gsm_netconn.c b/lwgsm/src/api/lwgsm_netconn.c
similarity index 50%
rename from gsm_at_lib/src/api/gsm_netconn.c
rename to lwgsm/src/api/lwgsm_netconn.c
index b6ae8ca5..73e92dd5 100644
--- a/gsm_at_lib/src/api/gsm_netconn.c
+++ b/lwgsm/src/api/lwgsm_netconn.c
@@ -1,10 +1,10 @@
/**
- * \file gsm_netconn.c
+ * \file lwgsm_netconn.c
* \brief API functions for sequential calls
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,113 +26,118 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#include "gsm/gsm_netconn.h"
-#include "gsm/gsm_private.h"
-#include "gsm/gsm_conn.h"
-#include "gsm/gsm_mem.h"
+#include "lwgsm/lwgsm_netconn.h"
+#include "lwgsm/lwgsm_private.h"
+#include "lwgsm/lwgsm_conn.h"
+#include "lwgsm/lwgsm_mem.h"
-#if GSM_CFG_NETCONN || __DOXYGEN__
+#if LWGSM_CFG_NETCONN || __DOXYGEN__
/* Check conditions */
-#if !GSM_CFG_CONN
-#error "GSM_CFG_CONN must be enabled for NETCONN API!"
-#endif /* !GSM_CFG_CONN */
+#if !LWGSM_CFG_CONN
+#error "LWGSM_CFG_CONN must be enabled for NETCONN API!"
+#endif /* !LWGSM_CFG_CONN */
+
+#if LWGSM_CFG_NETCONN_RECEIVE_QUEUE_LEN < 2
+#error "LWGSM_CFG_NETCONN_RECEIVE_QUEUE_LEN must be greater or equal to 2"
+#endif /* LWGSM_CFG_NETCONN_RECEIVE_QUEUE_LEN < 2 */
/**
* \brief Sequential API structure
*/
-typedef struct gsm_netconn {
- struct gsm_netconn* next; /*!< Linked list entry */
+typedef struct lwgsm_netconn {
+ struct lwgsm_netconn* next; /*!< Linked list entry */
- gsm_netconn_type_t type; /*!< Netconn type */
+ lwgsm_netconn_type_t type; /*!< Netconn type */
size_t rcv_packets; /*!< Number of received packets so far on this connection */
- gsm_conn_p conn; /*!< Pointer to actual connection */
+ lwgsm_conn_p conn; /*!< Pointer to actual connection */
- gsm_sys_mbox_t mbox_receive; /*!< Message queue for receive mbox */
+ lwgsm_sys_mbox_t mbox_receive; /*!< Message queue for receive mbox */
- gsm_linbuff_t buff; /*!< Linear buffer structure */
+ lwgsm_linbuff_t buff; /*!< Linear buffer structure */
uint16_t conn_timeout; /*!< Connection timeout in units of seconds when
netconn is in server (listen) mode.
Connection will be automatically closed if there is no
data exchange in time. Set to `0` when timeout feature is disabled. */
-#if GSM_CFG_NETCONN_RECEIVE_TIMEOUT || __DOXYGEN__
+#if LWGSM_CFG_NETCONN_RECEIVE_TIMEOUT || __DOXYGEN__
uint32_t rcv_timeout; /*!< Receive timeout in unit of milliseconds */
#endif
-} gsm_netconn_t;
+} lwgsm_netconn_t;
static uint8_t recv_closed = 0xFF;
-static gsm_netconn_t* netconn_list; /*!< Linked list of netconn entries */
+static lwgsm_netconn_t* netconn_list; /*!< Linked list of netconn entries */
/**
* \brief Flush all mboxes and clear possible used memories
* \param[in] nc: Pointer to netconn to flush
+ * \param[in] protect: Set to 1 to protect against multi-thread access
*/
static void
-flush_mboxes(gsm_netconn_t* nc, uint8_t protect) {
- gsm_pbuf_p pbuf;
+flush_mboxes(lwgsm_netconn_t* nc, uint8_t protect) {
+ lwgsm_pbuf_p pbuf;
if (protect) {
- gsm_core_lock();
+ lwgsm_core_lock();
}
- if (gsm_sys_mbox_isvalid(&nc->mbox_receive)) {
- while (gsm_sys_mbox_getnow(&nc->mbox_receive, (void **)&pbuf)) {
- if (pbuf != NULL && (uint8_t *)pbuf != (uint8_t *)&recv_closed) {
- gsm_pbuf_free(pbuf); /* Free received data buffers */
+ if (lwgsm_sys_mbox_isvalid(&nc->mbox_receive)) {
+ while (lwgsm_sys_mbox_getnow(&nc->mbox_receive, (void**)&pbuf)) {
+ if (pbuf != NULL && (uint8_t*)pbuf != (uint8_t*)&recv_closed) {
+ lwgsm_pbuf_free(pbuf); /* Free received data buffers */
}
}
- gsm_sys_mbox_delete(&nc->mbox_receive); /* Delete message queue */
- gsm_sys_mbox_invalid(&nc->mbox_receive);/* Invalid handle */
+ lwgsm_sys_mbox_delete(&nc->mbox_receive); /* Delete message queue */
+ lwgsm_sys_mbox_invalid(&nc->mbox_receive); /* Invalid handle */
}
if (protect) {
- gsm_core_unlock();
+ lwgsm_core_unlock();
}
}
/**
* \brief Callback function for every server connection
* \param[in] evt: Pointer to callback structure
- * \return Member of \ref gsmr_t enumeration
+ * \return Member of \ref lwgsmr_t enumeration
*/
-static gsmr_t
-netconn_evt(gsm_evt_t* evt) {
- gsm_conn_p conn;
- gsm_netconn_t* nc = NULL;
+static lwgsmr_t
+netconn_evt(lwgsm_evt_t* evt) {
+ lwgsm_conn_p conn;
+ lwgsm_netconn_t* nc = NULL;
uint8_t close = 0;
- conn = gsm_conn_get_from_evt(evt); /* Get connection from event */
- switch (gsm_evt_get_type(evt)) {
+ conn = lwgsm_conn_get_from_evt(evt); /* Get connection from event */
+ switch (lwgsm_evt_get_type(evt)) {
/*
* A new connection has been active
* and should be handled by netconn API
*/
- case GSM_EVT_CONN_ACTIVE: { /* A new connection active is active */
- if (gsm_conn_is_client(conn)) { /* Was connection started by us? */
- nc = gsm_conn_get_arg(conn); /* Argument should be already set */
+ case LWGSM_EVT_CONN_ACTIVE: { /* A new connection active is active */
+ if (lwgsm_conn_is_client(conn)) { /* Was connection started by us? */
+ nc = lwgsm_conn_get_arg(conn); /* Argument should be already set */
if (nc != NULL) {
nc->conn = conn; /* Save actual connection */
} else {
close = 1; /* Close this connection, invalid netconn */
}
} else {
- GSM_DEBUGF(GSM_CFG_DBG_NETCONN | GSM_DBG_TYPE_TRACE | GSM_DBG_LVL_WARNING,
- "[NETCONN] Closing connection, it is not in client mode!\r\n");
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_NETCONN | LWGSM_DBG_TYPE_TRACE | LWGSM_DBG_LVL_WARNING,
+ "[NETCONN] Closing connection, it is not in client mode!\r\n");
close = 1; /* Close the connection at this point */
}
/* Decide if some events want to close the connection */
if (close) {
if (nc != NULL) {
- gsm_conn_set_arg(conn, NULL); /* Reset argument */
- gsm_netconn_delete(nc); /* Free memory for API */
+ lwgsm_conn_set_arg(conn, NULL); /* Reset argument */
+ lwgsm_netconn_delete(nc); /* Free memory for API */
}
- gsm_conn_close(conn, 0); /* Close the connection */
+ lwgsm_conn_close(conn, 0); /* Close the connection */
close = 0;
}
break;
@@ -142,60 +147,61 @@ netconn_evt(gsm_evt_t* evt) {
* We have a new data received which
* should have netconn structure as argument
*/
- case GSM_EVT_CONN_RECV: {
- gsm_pbuf_p pbuf;
+ case LWGSM_EVT_CONN_RECV: {
+ lwgsm_pbuf_p pbuf;
- nc = gsm_conn_get_arg(conn); /* Get API from connection */
- pbuf = gsm_evt_conn_recv_get_buff(evt);/* Get received buff */
+ nc = lwgsm_conn_get_arg(conn); /* Get API from connection */
+ pbuf = lwgsm_evt_conn_recv_get_buff(evt); /* Get received buff */
- gsm_conn_recved(conn, pbuf); /* Notify stack about received data */
+ lwgsm_conn_recved(conn, pbuf); /* Notify stack about received data */
- gsm_pbuf_ref(pbuf); /* Increase reference counter */
- if (nc == NULL || !gsm_sys_mbox_isvalid(&nc->mbox_receive)
- || !gsm_sys_mbox_putnow(&nc->mbox_receive, pbuf)) {
- GSM_DEBUGF(GSM_CFG_DBG_NETCONN,
- "[NETCONN] Ignoring more data for receive!\r\n");
- gsm_pbuf_free(pbuf); /* Free pbuf */
- return gsmOKIGNOREMORE; /* Return OK to free the memory and ignore further data */
+ lwgsm_pbuf_ref(pbuf); /* Increase reference counter */
+ if (nc == NULL || !lwgsm_sys_mbox_isvalid(&nc->mbox_receive)
+ || !lwgsm_sys_mbox_putnow(&nc->mbox_receive, pbuf)) {
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_NETCONN,
+ "[NETCONN] Ignoring more data for receive!\r\n");
+ lwgsm_pbuf_free(pbuf); /* Free pbuf */
+ return lwgsmOKIGNOREMORE; /* Return OK to free the memory and ignore further data */
}
- nc->rcv_packets++; /* Increase number of received packets */
- GSM_DEBUGF(GSM_CFG_DBG_NETCONN | GSM_DBG_TYPE_TRACE,
- "[NETCONN] Received pbuf contains %d bytes. Handle written to receive mbox\r\n",
- (int)gsm_pbuf_length(pbuf, 0));
+ ++nc->rcv_packets; /* Increase number of received packets */
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_NETCONN | LWGSM_DBG_TYPE_TRACE,
+ "[NETCONN] Received pbuf contains %d bytes. Handle written to receive mbox\r\n",
+ (int)lwgsm_pbuf_length(pbuf, 0));
break;
}
/* Connection was just closed */
- case GSM_EVT_CONN_CLOSE: {
- nc = gsm_conn_get_arg(conn); /* Get API from connection */
+ case LWGSM_EVT_CONN_CLOSE: {
+ nc = lwgsm_conn_get_arg(conn); /* Get API from connection */
/*
* In case we have a netconn available,
* simply write pointer to received variable to indicate closed state
*/
- if (nc != NULL && gsm_sys_mbox_isvalid(&nc->mbox_receive)) {
- gsm_sys_mbox_putnow(&nc->mbox_receive, (void *)&recv_closed);
+ if (nc != NULL && lwgsm_sys_mbox_isvalid(&nc->mbox_receive)) {
+ lwgsm_sys_mbox_putnow(&nc->mbox_receive, (void*)&recv_closed);
}
break;
}
default:
- return gsmERR;
+ return lwgsmERR;
}
- return gsmOK;
+ return lwgsmOK;
}
/**
* \brief Global event callback function
* \param[in] evt: Callback information and data
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
*/
-static gsmr_t
-gsm_evt(gsm_evt_t* evt) {
- switch (gsm_evt_get_type(evt)) {
- default: break;
+static lwgsmr_t
+lwgsm_evt(lwgsm_evt_t* evt) {
+ switch (lwgsm_evt_get_type(evt)) {
+ default:
+ break;
}
- return gsmOK;
+ return lwgsmOK;
}
/**
@@ -203,44 +209,44 @@ gsm_evt(gsm_evt_t* evt) {
* \param[in] type: Netconn connection type
* \return New netconn connection on success, `NULL` otherwise
*/
-gsm_netconn_p
-gsm_netconn_new(gsm_netconn_type_t type) {
- gsm_netconn_t* a;
+lwgsm_netconn_p
+lwgsm_netconn_new(lwgsm_netconn_type_t type) {
+ lwgsm_netconn_t* a;
static uint8_t first = 1;
/* Register only once! */
- gsm_core_lock();
+ lwgsm_core_lock();
if (first) {
first = 0;
- gsm_evt_register(gsm_evt); /* Register global event function */
+ lwgsm_evt_register(lwgsm_evt); /* Register global event function */
}
- gsm_core_unlock();
- a = gsm_mem_calloc(1, sizeof(*a)); /* Allocate memory for core object */
+ lwgsm_core_unlock();
+ a = lwgsm_mem_calloc(1, sizeof(*a)); /* Allocate memory for core object */
if (a != NULL) {
a->type = type; /* Save netconn type */
a->conn_timeout = 0; /* Default connection timeout */
- if (!gsm_sys_mbox_create(&a->mbox_receive, GSM_CFG_NETCONN_RECEIVE_QUEUE_LEN)) { /* Allocate memory for receiving message box */
- GSM_DEBUGF(GSM_CFG_DBG_NETCONN | GSM_DBG_TYPE_TRACE | GSM_DBG_LVL_DANGER,
- "[NETCONN] Cannot create receive MBOX\r\n");
+ if (!lwgsm_sys_mbox_create(&a->mbox_receive, LWGSM_CFG_NETCONN_RECEIVE_QUEUE_LEN)) {/* Allocate memory for receiving message box */
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_NETCONN | LWGSM_DBG_TYPE_TRACE | LWGSM_DBG_LVL_DANGER,
+ "[NETCONN] Cannot create receive MBOX\r\n");
goto free_ret;
}
- gsm_core_lock();
+ lwgsm_core_lock();
if (netconn_list == NULL) { /* Add new netconn to the existing list */
netconn_list = a;
} else {
a->next = netconn_list; /* Add it to beginning of the list */
netconn_list = a;
}
- gsm_core_unlock();
+ lwgsm_core_unlock();
}
return a;
free_ret:
- if (gsm_sys_mbox_isvalid(&a->mbox_receive)) {
- gsm_sys_mbox_delete(&a->mbox_receive);
- gsm_sys_mbox_invalid(&a->mbox_receive);
+ if (lwgsm_sys_mbox_isvalid(&a->mbox_receive)) {
+ lwgsm_sys_mbox_delete(&a->mbox_receive);
+ lwgsm_sys_mbox_invalid(&a->mbox_receive);
}
if (a != NULL) {
- gsm_mem_free_s((void **)&a);
+ lwgsm_mem_free_s((void**)&a);
}
return NULL;
}
@@ -248,33 +254,33 @@ gsm_netconn_new(gsm_netconn_type_t type) {
/**
* \brief Delete netconn connection
* \param[in] nc: Netconn handle
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_netconn_delete(gsm_netconn_p nc) {
- GSM_ASSERT("netconn != NULL", nc != NULL);
+lwgsmr_t
+lwgsm_netconn_delete(lwgsm_netconn_p nc) {
+ LWGSM_ASSERT("netconn != NULL", nc != NULL);
- gsm_core_lock();
+ lwgsm_core_lock();
flush_mboxes(nc, 0); /* Clear mboxes */
/* Remove netconn from linkedlist */
if (netconn_list == nc) {
netconn_list = netconn_list->next; /* Remove first from linked list */
} else if (netconn_list != NULL) {
- gsm_netconn_p tmp, prev;
+ lwgsm_netconn_p tmp, prev;
/* Find element on the list */
for (prev = netconn_list, tmp = netconn_list->next;
- tmp != NULL; prev = tmp, tmp = tmp->next) {
+ tmp != NULL; prev = tmp, tmp = tmp->next) {
if (nc == tmp) {
prev->next = tmp->next; /* Remove tmp from linked list */
break;
}
}
}
- gsm_core_unlock();
+ lwgsm_core_unlock();
- gsm_mem_free_s((void **)&nc);
- return gsmOK;
+ lwgsm_mem_free_s((void**)&nc);
+ return lwgsmOK;
}
/**
@@ -282,15 +288,15 @@ gsm_netconn_delete(gsm_netconn_p nc) {
* \param[in] nc: Netconn handle
* \param[in] host: Pointer to host, such as domain name or IP address in string format
* \param[in] port: Target port to use
- * \return \ref gsmOK if successfully connected, member of \ref gsmr_t otherwise
+ * \return \ref lwgsmOK if successfully connected, member of \ref lwgsmr_t otherwise
*/
-gsmr_t
-gsm_netconn_connect(gsm_netconn_p nc, const char* host, gsm_port_t port) {
- gsmr_t res;
+lwgsmr_t
+lwgsm_netconn_connect(lwgsm_netconn_p nc, const char* host, lwgsm_port_t port) {
+ lwgsmr_t res;
- GSM_ASSERT("nc != NULL", nc != NULL);
- GSM_ASSERT("host != NULL", host != NULL);
- GSM_ASSERT("port > 0", port > 0);
+ LWGSM_ASSERT("nc != NULL", nc != NULL);
+ LWGSM_ASSERT("host != NULL", host != NULL);
+ LWGSM_ASSERT("port > 0", port > 0);
/*
* Start a new connection as client and:
@@ -299,7 +305,7 @@ gsm_netconn_connect(gsm_netconn_p nc, const char* host, gsm_port_t port) {
* - Set netconn callback function for connection management
* - Start connection in blocking mode
*/
- res = gsm_conn_start(NULL, (gsm_conn_type_t)nc->type, host, port, nc, netconn_evt, 1);
+ res = lwgsm_conn_start(NULL, (lwgsm_conn_type_t)nc->type, host, port, nc, netconn_evt, 1);
return res;
}
@@ -309,33 +315,33 @@ gsm_netconn_connect(gsm_netconn_p nc, const char* host, gsm_port_t port) {
* \param[in] nc: Netconn handle used to write data to
* \param[in] data: Pointer to data to write
* \param[in] btw: Number of bytes to write
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_netconn_write(gsm_netconn_p nc, const void* data, size_t btw) {
+lwgsmr_t
+lwgsm_netconn_write(lwgsm_netconn_p nc, const void* data, size_t btw) {
size_t len, sent;
const uint8_t* d = data;
- gsmr_t res;
+ lwgsmr_t res;
- GSM_ASSERT("nc != NULL", nc != NULL);
- GSM_ASSERT("nc->type must be TCP or SSL", nc->type == GSM_NETCONN_TYPE_TCP || nc->type == GSM_NETCONN_TYPE_SSL);
- GSM_ASSERT("nc->conn must be active", gsm_conn_is_active(nc->conn));
+ LWGSM_ASSERT("nc != NULL", nc != NULL);
+ LWGSM_ASSERT("nc->type must be TCP or SSL", nc->type == LWGSM_NETCONN_TYPE_TCP || nc->type == LWGSM_NETCONN_TYPE_SSL);
+ LWGSM_ASSERT("nc->conn must be active", lwgsm_conn_is_active(nc->conn));
/*
* Several steps are done in write process
*
* 1. Check if buffer is set and check if there is something to write to it.
* 1. In case buffer will be full after copy, send it and free memory.
- * 2. Check how many bytes we can write directly without needed to copy
+ * 2. Check how many bytes we can write directly without need to copy
* 3. Try to allocate a new buffer and copy remaining input data to it
* 4. In case buffer allocation fails, send data directly (may affect on speed and effectivenes)
*/
/* Step 1 */
if (nc->buff.buff != NULL) { /* Is there a write buffer ready to accept more data? */
- len = GSM_MIN(nc->buff.len - nc->buff.ptr, btw); /* Get number of bytes we can write to buffer */
+ len = LWGSM_MIN(nc->buff.len - nc->buff.ptr, btw); /* Get number of bytes we can write to buffer */
if (len > 0) {
- GSM_MEMCPY(&nc->buff.buff[nc->buff.ptr], data, len);/* Copy memory to temporary write buffer */
+ LWGSM_MEMCPY(&nc->buff.buff[nc->buff.ptr], data, len); /* Copy memory to temporary write buffer */
d += len;
nc->buff.ptr += len;
btw -= len;
@@ -343,23 +349,23 @@ gsm_netconn_write(gsm_netconn_p nc, const void* data, size_t btw) {
/* Step 1.1 */
if (nc->buff.ptr == nc->buff.len) {
- res = gsm_conn_send(nc->conn, nc->buff.buff, nc->buff.len, &sent, 1);
+ res = lwgsm_conn_send(nc->conn, nc->buff.buff, nc->buff.len, &sent, 1);
- gsm_mem_free_s((void **)&nc->buff.buff);
- if (res != gsmOK) {
+ lwgsm_mem_free_s((void**)&nc->buff.buff);
+ if (res != lwgsmOK) {
return res;
}
} else {
- return gsmOK; /* Buffer is not yet full yet */
+ return lwgsmOK; /* Buffer is not yet full yet */
}
}
/* Step 2 */
- if (btw >= GSM_CFG_CONN_MAX_DATA_LEN) {
+ if (btw >= LWGSM_CFG_CONN_MAX_DATA_LEN) {
size_t rem;
- rem = btw % GSM_CFG_CONN_MAX_DATA_LEN; /* Get remaining bytes for max data length */
- res = gsm_conn_send(nc->conn, d, btw - rem, &sent, 1); /* Write data directly */
- if (res != gsmOK) {
+ rem = btw % LWGSM_CFG_CONN_MAX_DATA_LEN;/* Get remaining bytes for max data length */
+ res = lwgsm_conn_send(nc->conn, d, btw - rem, &sent, 1);/* Write data directly */
+ if (res != lwgsmOK) {
return res;
}
d += sent; /* Advance in data pointer */
@@ -367,37 +373,37 @@ gsm_netconn_write(gsm_netconn_p nc, const void* data, size_t btw) {
}
if (btw == 0) { /* Sent everything? */
- return gsmOK;
+ return lwgsmOK;
}
/* Step 3 */
if (nc->buff.buff == NULL) { /* Check if we should allocate a new buffer */
- nc->buff.buff = gsm_mem_malloc(sizeof(*nc->buff.buff) * GSM_CFG_CONN_MAX_DATA_LEN);
- nc->buff.len = GSM_CFG_CONN_MAX_DATA_LEN; /* Save buffer length */
+ nc->buff.buff = lwgsm_mem_malloc(sizeof(*nc->buff.buff) * LWGSM_CFG_CONN_MAX_DATA_LEN);
+ nc->buff.len = LWGSM_CFG_CONN_MAX_DATA_LEN; /* Save buffer length */
nc->buff.ptr = 0; /* Save buffer pointer */
}
/* Step 4 */
if (nc->buff.buff != NULL) { /* Memory available? */
- GSM_MEMCPY(&nc->buff.buff[nc->buff.ptr], d, btw); /* Copy data to buffer */
+ LWGSM_MEMCPY(&nc->buff.buff[nc->buff.ptr], d, btw); /* Copy data to buffer */
nc->buff.ptr += btw;
} else { /* Still no memory available? */
- return gsm_conn_send(nc->conn, data, btw, NULL, 1); /* Simply send directly blocking */
+ return lwgsm_conn_send(nc->conn, data, btw, NULL, 1); /* Simply send directly blocking */
}
- return gsmOK;
+ return lwgsmOK;
}
/**
* \brief Flush buffered data on netconn \e TCP/SSL connection
* \note This function may only be used on \e TCP/SSL connection
* \param[in] nc: Netconn handle to flush data
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_netconn_flush(gsm_netconn_p nc) {
- GSM_ASSERT("nc != NULL", nc != NULL);
- GSM_ASSERT("nc->type must be TCP or SSL", nc->type == GSM_NETCONN_TYPE_TCP || nc->type == GSM_NETCONN_TYPE_SSL);
- GSM_ASSERT("nc->conn must be active", gsm_conn_is_active(nc->conn));
+lwgsmr_t
+lwgsm_netconn_flush(lwgsm_netconn_p nc) {
+ LWGSM_ASSERT("nc != NULL", nc != NULL);
+ LWGSM_ASSERT("nc->type must be TCP or SSL", nc->type == LWGSM_NETCONN_TYPE_TCP || nc->type == LWGSM_NETCONN_TYPE_SSL);
+ LWGSM_ASSERT("nc->conn must be active", lwgsm_conn_is_active(nc->conn));
/*
* In case we have data in write buffer,
@@ -405,11 +411,11 @@ gsm_netconn_flush(gsm_netconn_p nc) {
*/
if (nc->buff.buff != NULL) { /* Check remaining data */
if (nc->buff.ptr > 0) { /* Do we have data in current buffer? */
- gsm_conn_send(nc->conn, nc->buff.buff, nc->buff.ptr, NULL, 1); /* Send data */
+ lwgsm_conn_send(nc->conn, nc->buff.buff, nc->buff.ptr, NULL, 1);/* Send data */
}
- gsm_mem_free_s((void **)&nc->buff.buff);
+ lwgsm_mem_free_s((void**)&nc->buff.buff);
}
- return gsmOK;
+ return lwgsmOK;
}
/**
@@ -417,15 +423,15 @@ gsm_netconn_flush(gsm_netconn_p nc) {
* \param[in] nc: Netconn handle used to send
* \param[in] data: Pointer to data to write
* \param[in] btw: Number of bytes to write
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_netconn_send(gsm_netconn_p nc, const void* data, size_t btw) {
- GSM_ASSERT("nc != NULL", nc != NULL);
- GSM_ASSERT("nc->type must be UDP", nc->type == GSM_NETCONN_TYPE_UDP);
- GSM_ASSERT("nc->conn must be active", gsm_conn_is_active(nc->conn));
+lwgsmr_t
+lwgsm_netconn_send(lwgsm_netconn_p nc, const void* data, size_t btw) {
+ LWGSM_ASSERT("nc != NULL", nc != NULL);
+ LWGSM_ASSERT("nc->type must be UDP", nc->type == LWGSM_NETCONN_TYPE_UDP);
+ LWGSM_ASSERT("nc->conn must be active", lwgsm_conn_is_active(nc->conn));
- return gsm_conn_send(nc->conn, data, btw, NULL, 1);
+ return lwgsm_conn_send(nc->conn, data, btw, NULL, 1);
}
/**
@@ -436,15 +442,15 @@ gsm_netconn_send(gsm_netconn_p nc, const void* data, size_t btw) {
* \param[in] port: Port number used to send data
* \param[in] data: Pointer to data to write
* \param[in] btw: Number of bytes to write
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_netconn_sendto(gsm_netconn_p nc, const gsm_ip_t* ip, gsm_port_t port, const void* data, size_t btw) {
- GSM_ASSERT("nc != NULL", nc != NULL);
- GSM_ASSERT("nc->type must be UDP", nc->type == GSM_NETCONN_TYPE_UDP);
- GSM_ASSERT("nc->conn must be active", gsm_conn_is_active(nc->conn));
+lwgsmr_t
+lwgsm_netconn_sendto(lwgsm_netconn_p nc, const lwgsm_ip_t* ip, lwgsm_port_t port, const void* data, size_t btw) {
+ LWGSM_ASSERT("nc != NULL", nc != NULL);
+ LWGSM_ASSERT("nc->type must be UDP", nc->type == LWGSM_NETCONN_TYPE_UDP);
+ LWGSM_ASSERT("nc->conn must be active", lwgsm_conn_is_active(nc->conn));
- return gsm_conn_sendto(nc->conn, ip, port, data, btw, NULL, 1);
+ return lwgsm_conn_sendto(nc->conn, ip, port, data, btw, NULL, 1);
}
/**
@@ -452,88 +458,88 @@ gsm_netconn_sendto(gsm_netconn_p nc, const gsm_ip_t* ip, gsm_port_t port, const
* \param[in] nc: Netconn handle used to receive from
* \param[in] pbuf: Pointer to pointer to save new receive buffer to.
* When function returns, user must check for valid pbuf value `pbuf != NULL`
- * \return \ref gsmOK when new data ready,
- * \return \ref gsmCLOSED when connection closed by remote side,
- * \return \ref gsmTIMEOUT when receive timeout occurs
- * \return Any other member of \ref gsmr_t otherwise
+ * \return \ref lwgsmOK when new data ready,
+ * \return \ref lwgsmCLOSED when connection closed by remote side,
+ * \return \ref lwgsmTIMEOUT when receive timeout occurs
+ * \return Any other member of \ref lwgsmr_t otherwise
*/
-gsmr_t
-gsm_netconn_receive(gsm_netconn_p nc, gsm_pbuf_p* pbuf) {
- GSM_ASSERT("nc != NULL", nc != NULL);
- GSM_ASSERT("pbuf != NULL", pbuf != NULL);
+lwgsmr_t
+lwgsm_netconn_receive(lwgsm_netconn_p nc, lwgsm_pbuf_p* pbuf) {
+ LWGSM_ASSERT("nc != NULL", nc != NULL);
+ LWGSM_ASSERT("pbuf != NULL", pbuf != NULL);
*pbuf = NULL;
-#if GSM_CFG_NETCONN_RECEIVE_TIMEOUT
+#if LWGSM_CFG_NETCONN_RECEIVE_TIMEOUT
/*
* Wait for new received data for up to specific timeout
* or throw error for timeout notification
*/
- if (gsm_sys_mbox_get(&nc->mbox_receive, (void **)pbuf, nc->rcv_timeout) == GSM_SYS_TIMEOUT) {
- return gsmTIMEOUT;
+ if (lwgsm_sys_mbox_get(&nc->mbox_receive, (void**)pbuf, nc->rcv_timeout) == LWGSM_SYS_TIMEOUT) {
+ return lwgsmTIMEOUT;
}
-#else /* GSM_CFG_NETCONN_RECEIVE_TIMEOUT */
+#else /* LWGSM_CFG_NETCONN_RECEIVE_TIMEOUT */
/* Forever wait for new receive packet */
- gsm_sys_mbox_get(&nc->mbox_receive, (void **)pbuf, 0);
-#endif /* !GSM_CFG_NETCONN_RECEIVE_TIMEOUT */
+ lwgsm_sys_mbox_get(&nc->mbox_receive, (void**)pbuf, 0);
+#endif /* !LWGSM_CFG_NETCONN_RECEIVE_TIMEOUT */
/* Check if connection closed */
- if ((uint8_t *)(*pbuf) == (uint8_t *)&recv_closed) {
+ if ((uint8_t*)(*pbuf) == (uint8_t*)&recv_closed) {
*pbuf = NULL; /* Reset pbuf */
- return gsmCLOSED;
+ return lwgsmCLOSED;
}
- return gsmOK; /* We have data available */
+ return lwgsmOK; /* We have data available */
}
/**
* \brief Close a netconn connection
* \param[in] nc: Netconn handle to close
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_netconn_close(gsm_netconn_p nc) {
- gsm_conn_p conn;
+lwgsmr_t
+lwgsm_netconn_close(lwgsm_netconn_p nc) {
+ lwgsm_conn_p conn;
- GSM_ASSERT("nc != NULL", nc != NULL);
- GSM_ASSERT("nc->conn != NULL", nc->conn != NULL);
- GSM_ASSERT("nc->conn must be active", gsm_conn_is_active(nc->conn));
+ LWGSM_ASSERT("nc != NULL", nc != NULL);
+ LWGSM_ASSERT("nc->conn != NULL", nc->conn != NULL);
+ LWGSM_ASSERT("nc->conn must be active", lwgsm_conn_is_active(nc->conn));
- gsm_netconn_flush(nc); /* Flush data and ignore result */
+ lwgsm_netconn_flush(nc); /* Flush data and ignore result */
conn = nc->conn;
nc->conn = NULL;
- gsm_conn_set_arg(conn, NULL); /* Reset argument */
- gsm_conn_close(conn, 1); /* Close the connection */
+ lwgsm_conn_set_arg(conn, NULL); /* Reset argument */
+ lwgsm_conn_close(conn, 1); /* Close the connection */
flush_mboxes(nc, 1); /* Flush message queues */
- return gsmOK;
+ return lwgsmOK;
}
/**
* \brief Get connection number used for netconn
* \param[in] nc: Netconn handle
- * \return `-1` on failure, connection number between `0` and \ref GSM_CFG_MAX_CONNS otherwise
+ * \return `-1` on failure, connection number between `0` and \ref LWGSM_CFG_MAX_CONNS otherwise
*/
int8_t
-gsm_netconn_getconnnum(gsm_netconn_p nc) {
+lwgsm_netconn_getconnnum(lwgsm_netconn_p nc) {
if (nc != NULL && nc->conn != NULL) {
- return gsm_conn_getnum(nc->conn);
+ return lwgsm_conn_getnum(nc->conn);
}
return -1;
}
-#if GSM_CFG_NETCONN_RECEIVE_TIMEOUT || __DOXYGEN__
+#if LWGSM_CFG_NETCONN_RECEIVE_TIMEOUT || __DOXYGEN__
/**
* \brief Set timeout value for receiving data.
*
- * When enabled, \ref gsm_netconn_receive will only block for up to
+ * When enabled, \ref lwgsm_netconn_receive will only block for up to
* \e timeout value and will return if no new data within this time
*
* \param[in] nc: Netconn handle
* \param[in] timeout: Timeout in units of milliseconds.
- * Set to `0` to disable timeout for \ref gsm_netconn_receive function
+ * Set to `0` to disable timeout for \ref lwgsm_netconn_receive function
*/
void
-gsm_netconn_set_receive_timeout(gsm_netconn_p nc, uint32_t timeout) {
+lwgsm_netconn_set_receive_timeout(lwgsm_netconn_p nc, uint32_t timeout) {
nc->rcv_timeout = timeout;
}
@@ -544,10 +550,10 @@ gsm_netconn_set_receive_timeout(gsm_netconn_p nc, uint32_t timeout) {
* If value is `0`, timeout is disabled (wait forever)
*/
uint32_t
-gsm_netconn_get_receive_timeout(gsm_netconn_p nc) {
+lwgsm_netconn_get_receive_timeout(lwgsm_netconn_p nc) {
return nc->rcv_timeout; /* Return receive timeout */
}
-#endif /* GSM_CFG_NETCONN_RECEIVE_TIMEOUT || __DOXYGEN__ */
+#endif /* LWGSM_CFG_NETCONN_RECEIVE_TIMEOUT || __DOXYGEN__ */
-#endif /* GSM_CFG_NETCONN || __DOXYGEN__ */
+#endif /* LWGSM_CFG_NETCONN || __DOXYGEN__ */
diff --git a/gsm_at_lib/src/api/gsm_network_api.c b/lwgsm/src/api/lwgsm_network_api.c
similarity index 60%
rename from gsm_at_lib/src/api/gsm_network_api.c
rename to lwgsm/src/api/lwgsm_network_api.c
index aa5cd1af..dc7d9cf7 100644
--- a/gsm_at_lib/src/api/gsm_network_api.c
+++ b/lwgsm/src/api/lwgsm_network_api.c
@@ -1,10 +1,10 @@
/**
- * \file gsm_network_api.c
+ * \file lwgsm_network_api.c
* \brief API functions for multi-thread network functions
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,16 +26,16 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#include "gsm/gsm_network_api.h"
-#include "gsm/gsm_private.h"
-#include "gsm/gsm_network.h"
+#include "lwgsm/lwgsm_network_api.h"
+#include "lwgsm/lwgsm_private.h"
+#include "lwgsm/lwgsm_network.h"
-#if GSM_CFG_NETWORK || __DOXYGEN__
+#if LWGSM_CFG_NETWORK || __DOXYGEN__
/* Network credentials used during connect operation */
static const char* network_apn;
@@ -48,40 +48,47 @@ static uint32_t network_counter;
* \param[in] apn: APN domain. Set to `NULL` if not used
* \param[in] user: APN username. Set to `NULL` if not used
* \param[in] pass: APN password. Set to `NULL` if not used
- * \return \ref espOK on success, member of \ref espr_t otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
*/
-gsmr_t
-gsm_network_set_credentials(const char* apn, const char* user, const char* pass) {
- network_apn = apn;
- network_user = user;
- network_pass = pass;
+lwgsmr_t
+lwgsm_network_set_credentials(const char* apn, const char* user, const char* pass) {
+ network_apn = apn;
+ network_user = user;
+ network_pass = pass;
- return gsmOK;
+ return lwgsmOK;
}
/**
* \brief Request manager to attach to network
* \note This function is blocking and cannot be called from event functions
- * \return \gsmOK on success (when attached), member of \ref gsmr_t otherwise
+ * \return \ref lwgsmOK on success (when attached), member of \ref lwgsmr_t otherwise
*/
-gsmr_t
-gsm_network_request_attach(void) {
- gsmr_t res = gsmOK;
+lwgsmr_t
+lwgsm_network_request_attach(void) {
+ lwgsmr_t res = lwgsmOK;
uint8_t do_conn = 0;
/* Check if we need to connect */
- gsm_core_lock();
+ lwgsm_core_lock();
if (network_counter == 0) {
- if (!gsm_network_is_attached()) {
+ if (!lwgsm_network_is_attached()) {
do_conn = 1;
}
}
- network_counter++;
- gsm_core_unlock();
+ if (!do_conn) {
+ ++network_counter;
+ }
+ lwgsm_core_unlock();
/* Connect to network */
if (do_conn) {
- res = gsm_network_attach(network_apn, network_user, network_pass, NULL, NULL, 1);
+ res = lwgsm_network_attach(network_apn, network_user, network_pass, NULL, NULL, 1);
+ if (res == lwgsmOK) {
+ lwgsm_core_lock();
+ ++network_counter;
+ lwgsm_core_unlock();
+ }
}
return res;
}
@@ -93,28 +100,34 @@ gsm_network_request_attach(void) {
* otherwise it will disable network access
*
* \note This function is blocking and cannot be called from event functions
- * \return \gsmOK on success (when attached), member of \ref gsmr_t otherwise
+ * \return \ref lwgsmOK on success (when attached), member of \ref lwgsmr_t otherwise
*/
-gsmr_t
-gsm_network_request_detach(void) {
- gsmr_t res = gsmOK;
+lwgsmr_t
+lwgsm_network_request_detach(void) {
+ lwgsmr_t res = lwgsmOK;
uint8_t do_disconn = 0;
/* Check if we need to disconnect */
- gsm_core_lock();
+ lwgsm_core_lock();
if (network_counter > 0) {
- network_counter--;
- if (network_counter == 0) {
+ if (network_counter == 1) {
do_disconn = 1;
+ } else {
+ --network_counter;
}
}
- gsm_core_unlock();
+ lwgsm_core_unlock();
/* Connect to network */
if (do_disconn) {
- res = gsm_network_detach(NULL, NULL, 1);
+ res = lwgsm_network_detach(NULL, NULL, 1);
+ if (res == lwgsmOK) {
+ lwgsm_core_lock();
+ --network_counter;
+ lwgsm_core_unlock();
+ }
}
return res;
}
-#endif /* GSM_CFG_NETWORK || __DOXYGEN__ */
+#endif /* LWGSM_CFG_NETWORK || __DOXYGEN__ */
diff --git a/gsm_at_lib/src/apps/mqtt/gsm_mqtt_client.c b/lwgsm/src/apps/mqtt/lwgsm_mqtt_client.c
similarity index 66%
rename from gsm_at_lib/src/apps/mqtt/gsm_mqtt_client.c
rename to lwgsm/src/apps/mqtt/lwgsm_mqtt_client.c
index cd71b66c..2997fb86 100644
--- a/gsm_at_lib/src/apps/mqtt/gsm_mqtt_client.c
+++ b/lwgsm/src/apps/mqtt/lwgsm_mqtt_client.c
@@ -1,10 +1,10 @@
/**
- * \file gsm_mqtt_client.c
+ * \file lwgsm_mqtt_client.c
* \brief MQTT client
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,29 +26,29 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#include "gsm/apps/gsm_mqtt_client.h"
-#include "gsm/gsm_mem.h"
-#include "gsm/gsm_pbuf.h"
+#include "lwgsm/apps/lwgsm_mqtt_client.h"
+#include "lwgsm/lwgsm_mem.h"
+#include "lwgsm/lwgsm_pbuf.h"
/**
* \brief MQTT client connection
*/
-typedef struct gsm_mqtt_client {
- gsm_conn_p conn; /*!< Active used connection for MQTT */
- const gsm_mqtt_client_info_t* info; /*!< Connection info */
- gsm_mqtt_state_t conn_state; /*!< MQTT connection state */
+typedef struct lwgsm_mqtt_client {
+ lwgsm_conn_p conn; /*!< Active used connection for MQTT */
+ const lwgsm_mqtt_client_info_t* info; /*!< Connection info */
+ lwgsm_mqtt_state_t conn_state; /*!< MQTT connection state */
uint32_t poll_time; /*!< Poll time, increased every 500ms */
- gsm_mqtt_evt_t evt; /*!< MQTT event callback */
- gsm_mqtt_evt_fn evt_fn; /*!< Event callback function */
+ lwgsm_mqtt_evt_t evt; /*!< MQTT event callback */
+ lwgsm_mqtt_evt_fn evt_fn; /*!< Event callback function */
- gsm_buff_t tx_buff; /*!< Buffer for raw output data to transmit */
+ lwgsm_buff_t tx_buff; /*!< Buffer for raw output data to transmit */
uint8_t is_sending; /*!< Flag if we are sending data currently */
uint32_t sent_total; /*!< Total number of bytes sent so far on connection */
@@ -56,7 +56,7 @@ typedef struct gsm_mqtt_client {
uint16_t last_packet_id; /*!< Packet ID used on last packet */
- gsm_mqtt_request_t requests[GSM_CFG_MQTT_MAX_REQUESTS]; /*!< List of requests */
+ lwgsm_mqtt_request_t requests[LWGSM_CFG_MQTT_MAX_REQUESTS]; /*!< List of requests */
uint8_t* rx_buff; /*!< Raw RX buffer */
size_t rx_buff_len; /*!< Length of raw RX buffer */
@@ -68,15 +68,15 @@ typedef struct gsm_mqtt_client {
uint32_t msg_curr_pos; /*!< Current buffer write pointer */
void* arg; /*!< User argument */
-} gsm_mqtt_client_t;
+} lwgsm_mqtt_client_t;
/* Tracing debug message */
-#define GSM_CFG_DBG_MQTT_TRACE (GSM_CFG_DBG_MQTT | GSM_DBG_TYPE_TRACE)
-#define GSM_CFG_DBG_MQTT_STATE (GSM_CFG_DBG_MQTT | GSM_DBG_TYPE_STATE)
-#define GSM_CFG_DBG_MQTT_TRACE_WARNING (GSM_CFG_DBG_MQTT | GSM_DBG_TYPE_TRACE | GSM_DBG_LVL_WARNING)
+#define LWGSM_CFG_DBG_MQTT_TRACE (LWGSM_CFG_DBG_MQTT | LWGSM_DBG_TYPE_TRACE)
+#define LWGSM_CFG_DBG_MQTT_STATE (LWGSM_CFG_DBG_MQTT | LWGSM_DBG_TYPE_STATE)
+#define LWGSM_CFG_DBG_MQTT_TRACE_WARNING (LWGSM_CFG_DBG_MQTT | LWGSM_DBG_TYPE_TRACE | LWGSM_DBG_LVL_WARNING)
-static gsmr_t mqtt_conn_cb(gsm_evt_t* evt);
-static void send_data(gsm_mqtt_client_p client);
+static lwgsmr_t mqtt_conn_cb(lwgsm_evt_t* evt);
+static void send_data(lwgsm_mqtt_client_p client);
/**
* \brief List of MQTT message types
@@ -112,7 +112,7 @@ typedef enum {
/* Get packet type from incoming byte */
#define MQTT_RCV_GET_PACKET_TYPE(d) ((mqtt_msg_type_t)(((d) >> 0x04) & 0x0F))
-#define MQTT_RCV_GET_PACKET_QOS(d) ((gsm_mqtt_qos_t)(((d) >> 0x01) & 0x03))
+#define MQTT_RCV_GET_PACKET_QOS(d) ((lwgsm_mqtt_qos_t)(((d) >> 0x01) & 0x03))
#define MQTT_RCV_GET_PACKET_DUP(d) (((d) >> 0x03) & 0x01)
/* Requests status */
@@ -121,11 +121,11 @@ typedef enum {
#define MQTT_REQUEST_FLAG_SUBSCRIBE 0x04 /*!< Request object has subscribe type */
#define MQTT_REQUEST_FLAG_UNSUBSCRIBE 0x08 /*!< Request object has unsubscribe type */
-#if GSM_CFG_DBG
+#if LWGSM_CFG_DBG
-static const char *
+static const char*
mqtt_msg_type_to_str(mqtt_msg_type_t msg_type) {
- static const char * strings[] = {
+ static const char* strings[] = {
"UNKNOWN",
"CONNECT", "CONNACK", "PUBLISH", "PUBACK", "PUBREC", "PUBREL",
"PUBCOMP", "SUBSCRIBE", "SUBACK", "UNSUBSCRIBE", "UNSUBACK",
@@ -134,16 +134,17 @@ mqtt_msg_type_to_str(mqtt_msg_type_t msg_type) {
return strings[(uint8_t)msg_type];
}
-#endif /* GSM_CFG_DBG */
+#endif /* LWGSM_CFG_DBG */
/**
* \brief Default event callback function
+ * \param[in] client: MQTT client
* \param[in] evt: MQTT event
*/
static void
-mqtt_evt_fn_default(gsm_mqtt_client_p client, gsm_mqtt_evt_t* evt) {
- GSM_UNUSED(client);
- GSM_UNUSED(evt);
+mqtt_evt_fn_default(lwgsm_mqtt_client_p client, lwgsm_mqtt_evt_t* evt) {
+ LWGSM_UNUSED(client);
+ LWGSM_UNUSED(evt);
}
/**
@@ -152,9 +153,8 @@ mqtt_evt_fn_default(gsm_mqtt_client_p client, gsm_mqtt_evt_t* evt) {
* \return New packet ID
*/
static uint16_t
-create_packet_id(gsm_mqtt_client_p client) {
- client->last_packet_id++;
- if (client->last_packet_id == 0) {
+create_packet_id(lwgsm_mqtt_client_p client) {
+ if (++client->last_packet_id == 0) {
client->last_packet_id = 1;
}
return client->last_packet_id;
@@ -173,13 +173,13 @@ create_packet_id(gsm_mqtt_client_p client) {
* \param[in] arg: User optional argument for identifying packets
* \return Pointer to new request ready to use or `NULL` if no available memory
*/
-static gsm_mqtt_request_t *
-request_create(gsm_mqtt_client_p client, uint16_t packet_id, void* arg) {
- gsm_mqtt_request_t* request;
+static lwgsm_mqtt_request_t*
+request_create(lwgsm_mqtt_client_p client, uint16_t packet_id, void* arg) {
+ lwgsm_mqtt_request_t* request;
uint16_t i;
/* Try to find a new request which does not have IN_USE flag set */
- for (request = NULL, i = 0; i < GSM_CFG_MQTT_MAX_REQUESTS; i++) {
+ for (request = NULL, i = 0; i < LWGSM_CFG_MQTT_MAX_REQUESTS; ++i) {
if (!(client->requests[i].status & MQTT_REQUEST_FLAG_IN_USE)) {
request = &client->requests[i]; /* We have empty request */
break;
@@ -199,9 +199,9 @@ request_create(gsm_mqtt_client_p client, uint16_t packet_id, void* arg) {
* \param[in] request: Request object to delete
*/
static void
-request_delete(gsm_mqtt_client_p client, gsm_mqtt_request_t* request) {
+request_delete(lwgsm_mqtt_client_p client, lwgsm_mqtt_request_t* request) {
request->status = 0; /* Reset status to make request unused */
- GSM_UNUSED(client);
+ LWGSM_UNUSED(client);
}
/**
@@ -210,10 +210,10 @@ request_delete(gsm_mqtt_client_p client, gsm_mqtt_request_t* request) {
* \param[in] request: Request object to delete
*/
static void
-request_set_pending(gsm_mqtt_client_p client, gsm_mqtt_request_t* request) {
- request->timeout_start_time = gsm_sys_now();/* Set timeout start time */
+request_set_pending(lwgsm_mqtt_client_p client, lwgsm_mqtt_request_t* request) {
+ request->timeout_start_time = lwgsm_sys_now(); /* Set timeout start time */
request->status |= MQTT_REQUEST_FLAG_PENDING; /* Set pending flag */
- GSM_UNUSED(client);
+ LWGSM_UNUSED(client);
}
/**
@@ -222,10 +222,10 @@ request_set_pending(gsm_mqtt_client_p client, gsm_mqtt_request_t* request) {
* \param[in] pkt_id: Packet id to get request for. Use `-1` to get first pending request
* \return Request on success, `NULL` otherwise
*/
-static gsm_mqtt_request_t *
-request_get_pending(gsm_mqtt_client_p client, int32_t pkt_id) {
+static lwgsm_mqtt_request_t*
+request_get_pending(lwgsm_mqtt_client_p client, int32_t pkt_id) {
/* Try to find a new request which does not have IN_USE flag set */
- for (size_t i = 0; i < GSM_CFG_MQTT_MAX_REQUESTS; i++) {
+ for (size_t i = 0; i < LWGSM_CFG_MQTT_MAX_REQUESTS; ++i) {
if ((client->requests[i].status & MQTT_REQUEST_FLAG_PENDING)
&& (pkt_id == -1 || client->requests[i].packet_id == (uint16_t)pkt_id)) {
return &client->requests[i];
@@ -241,21 +241,21 @@ request_get_pending(gsm_mqtt_client_p client, int32_t pkt_id) {
* \param[in] arg: User argument
*/
static void
-request_send_err_callback(gsm_mqtt_client_p client, uint8_t status, void* arg) {
+request_send_err_callback(lwgsm_mqtt_client_p client, uint8_t status, void* arg) {
if (status & MQTT_REQUEST_FLAG_SUBSCRIBE) {
- client->evt.type = GSM_MQTT_EVT_SUBSCRIBE;
+ client->evt.type = LWGSM_MQTT_EVT_SUBSCRIBE;
} else if (status & MQTT_REQUEST_FLAG_UNSUBSCRIBE) {
- client->evt.type = GSM_MQTT_EVT_UNSUBSCRIBE;
+ client->evt.type = LWGSM_MQTT_EVT_UNSUBSCRIBE;
} else {
- client->evt.type = GSM_MQTT_EVT_PUBLISH;
+ client->evt.type = LWGSM_MQTT_EVT_PUBLISH;
}
- if (client->evt.type == GSM_MQTT_EVT_PUBLISH) {
+ if (client->evt.type == LWGSM_MQTT_EVT_PUBLISH) {
client->evt.evt.publish.arg = arg;
- client->evt.evt.publish.res = gsmERR;
+ client->evt.evt.publish.res = lwgsmERR;
} else {
client->evt.evt.sub_unsub_scribed.arg = arg;
- client->evt.evt.sub_unsub_scribed.res = gsmERR;
+ client->evt.evt.sub_unsub_scribed.res = lwgsmERR;
}
client->evt_fn(client, &client->evt);
}
@@ -276,22 +276,38 @@ request_send_err_callback(gsm_mqtt_client_p client, uint8_t status, void* arg) {
* \param[in] rem_len: Remaining packet length, excluding variable length part
*/
static void
-write_fixed_header(gsm_mqtt_client_p client, mqtt_msg_type_t type, uint8_t dup, gsm_mqtt_qos_t qos, uint8_t retain, uint16_t rem_len) {
+write_fixed_header(lwgsm_mqtt_client_p client, mqtt_msg_type_t type, uint8_t dup, lwgsm_mqtt_qos_t qos, uint8_t retain, uint16_t rem_len) {
uint8_t b;
- b = GSM_U8(((GSM_U8(type)) << 0x04) | (GSM_U8(!!dup) << 0x03) | ((GSM_U8(qos) & 0x03) << 0x01) | GSM_U8(!!retain));
- gsm_buff_write(&client->tx_buff, &b, 1); /* Write start of packet parameters */
+ /*
+ * Fixed header flags according to:
+ * http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718020
+ */
+ b = LWGSM_U8(type) << 0x04;
+ switch (type) {
+ case MQTT_MSG_TYPE_PUBLISH:
+ b |= LWGSM_U8(!!dup) << 0x03 | (LWGSM_U8(qos & 0x03)) << 0x01 | LWGSM_U8(!!retain);
+ break;
+ case MQTT_MSG_TYPE_PUBREL:
+ case MQTT_MSG_TYPE_SUBSCRIBE:
+ case MQTT_MSG_TYPE_UNSUBSCRIBE:
+ b |= LWGSM_U8(LWGSM_MQTT_QOS_AT_LEAST_ONCE) << 0x01;
+ break;
+ default:
+ break;
+ }
+ lwgsm_buff_write(&client->tx_buff, &b, 1); /* Write start of packet parameters */
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_TRACE,
- "[MQTT] Writing packet type %s to output buffer\r\n", mqtt_msg_type_to_str(type));
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_TRACE,
+ "[MQTT] Writing packet type %s to output buffer\r\n", mqtt_msg_type_to_str(type));
do { /* Encode length, we must write a len byte even if 0 */
/*
* Length is encoded LSB first up to 127 (0x7F) long,
* where bit 7 indicates we have more data in queue for length parameter
*/
- b = GSM_U8((rem_len & 0x7F) | (rem_len > 0x7F ? 0x80 : 0));
- gsm_buff_write(&client->tx_buff, &b, 1);/* Write single byte */
+ b = LWGSM_U8((rem_len & 0x7F) | (rem_len > 0x7F ? 0x80 : 0));
+ lwgsm_buff_write(&client->tx_buff, &b, 1); /* Write single byte */
rem_len >>= 7; /* Go to next 127 bytes */
} while (rem_len > 0);
}
@@ -302,8 +318,8 @@ write_fixed_header(gsm_mqtt_client_p client, mqtt_msg_type_t type, uint8_t dup,
* \param[in] num: Number to write
*/
static void
-write_u8(gsm_mqtt_client_p client, uint8_t num) {
- gsm_buff_write(&client->tx_buff, &num, 1); /* Write single byte */
+write_u8(lwgsm_mqtt_client_p client, uint8_t num) {
+ lwgsm_buff_write(&client->tx_buff, &num, 1);/* Write single byte */
}
/**
@@ -312,9 +328,9 @@ write_u8(gsm_mqtt_client_p client, uint8_t num) {
* \param[in] num: Number to write
*/
static void
-write_u16(gsm_mqtt_client_p client, uint16_t num) {
- write_u8(client, GSM_U8(num >> 8)); /* Write MSB first... */
- write_u8(client, GSM_U8(num & 0xFF)); /* ...followed by LSB */
+write_u16(lwgsm_mqtt_client_p client, uint16_t num) {
+ write_u8(client, LWGSM_U8(num >> 8)); /* Write MSB first... */
+ write_u8(client, LWGSM_U8(num & 0xFF)); /* ...followed by LSB */
}
/**
@@ -324,8 +340,8 @@ write_u16(gsm_mqtt_client_p client, uint16_t num) {
* \param[in] len: Length of data to write
*/
static void
-write_data(gsm_mqtt_client_p client, const void* data, size_t len) {
- gsm_buff_write(&client->tx_buff, data, len);/* Write raw data to buffer */
+write_data(lwgsm_mqtt_client_p client, const void* data, size_t len) {
+ lwgsm_buff_write(&client->tx_buff, data, len); /* Write raw data to buffer */
}
/**
@@ -339,15 +355,15 @@ write_data(gsm_mqtt_client_p client, const void* data, size_t len) {
* \return Number of required RAW bytes or `0` if no memory available
*/
static uint16_t
-output_check_enough_memory(gsm_mqtt_client_p client, uint16_t rem_len) {
+output_check_enough_memory(lwgsm_mqtt_client_p client, uint16_t rem_len) {
uint16_t total_len = rem_len + 1; /* Remaining length + first (packet start) byte */
do { /* Calculate bytes for encoding remaining length itself */
- total_len++;
+ ++total_len;
rem_len >>= 7; /* Encoded with 7 bits per byte */
} while (rem_len > 0);
- return GSM_U16(gsm_buff_get_free(&client->tx_buff)) >= total_len ? total_len : 0;
+ return LWGSM_U16(lwgsm_buff_get_free(&client->tx_buff)) >= total_len ? total_len : 0;
}
/**
@@ -359,17 +375,17 @@ output_check_enough_memory(gsm_mqtt_client_p client, uint16_t rem_len) {
* \return `1` on success, `0` otherwise
*/
static uint8_t
-write_ack_rec_rel_resp(gsm_mqtt_client_p client, mqtt_msg_type_t msg_type, uint16_t pkt_id, gsm_mqtt_qos_t qos) {
+write_ack_rec_rel_resp(lwgsm_mqtt_client_p client, mqtt_msg_type_t msg_type, uint16_t pkt_id, lwgsm_mqtt_qos_t qos) {
if (output_check_enough_memory(client, 2)) {/* Check memory for response packet */
write_fixed_header(client, msg_type, 0, qos, 0, 2); /* Write fixed header with 2 more bytes for packet id */
write_u16(client, pkt_id); /* Write packet ID */
send_data(client); /* Flush data to output */
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_TRACE,
- "[MQTT] Response %s written to output memory\r\n", mqtt_msg_type_to_str(msg_type));
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_TRACE,
+ "[MQTT] Response %s written to output memory\r\n", mqtt_msg_type_to_str(msg_type));
return 1;
} else {
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_TRACE,
- "[MQTT] No memory to write %s packet\r\n", mqtt_msg_type_to_str(msg_type));
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_TRACE,
+ "[MQTT] No memory to write %s packet\r\n", mqtt_msg_type_to_str(msg_type));
}
return 0;
}
@@ -378,11 +394,12 @@ write_ack_rec_rel_resp(gsm_mqtt_client_p client, mqtt_msg_type_t msg_type, uint1
* \brief Write string to output buffer
* \param[in] client: MQTT client
* \param[in] str: String to write to buffer
+ * \param[in] len: Length of string
*/
static void
-write_string(gsm_mqtt_client_p client, const char* str, uint16_t len) {
+write_string(lwgsm_mqtt_client_p client, const char* str, uint16_t len) {
write_u16(client, len); /* Write string length */
- gsm_buff_write(&client->tx_buff, str, len); /* Write string to buffer */
+ lwgsm_buff_write(&client->tx_buff, str, len); /* Write string to buffer */
}
/**
@@ -390,7 +407,7 @@ write_string(gsm_mqtt_client_p client, const char* str, uint16_t len) {
* \param[in] client: MQTT client
*/
static void
-send_data(gsm_mqtt_client_p client) {
+send_data(lwgsm_mqtt_client_p client) {
size_t len;
const void* addr;
@@ -398,42 +415,42 @@ send_data(gsm_mqtt_client_p client) {
return;
}
- len = gsm_buff_get_linear_block_read_length(&client->tx_buff); /* Get length of linear memory */
- if (len > 0) { /* Anything to send? */
- gsmr_t res;
- addr = gsm_buff_get_linear_block_read_address(&client->tx_buff);/* Get address of linear memory */
- if ((res = gsm_conn_send(client->conn, addr, len, NULL, 0)) == gsmOK) {
+ len = lwgsm_buff_get_linear_block_read_length(&client->tx_buff);/* Get length of linear memory */
+ if (len > 0) { /* Anything to send? */
+ lwgsmr_t res;
+ addr = lwgsm_buff_get_linear_block_read_address(&client->tx_buff); /* Get address of linear memory */
+ if ((res = lwgsm_conn_send(client->conn, addr, len, NULL, 0)) == lwgsmOK) {
client->written_total += len; /* Increase number of bytes written to queue */
client->is_sending = 1; /* Remember active sending flag */
} else {
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_TRACE_WARNING,
- "[MQTT] Cannot send data with error: %d\r\n", (int)res);
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_TRACE_WARNING,
+ "[MQTT] Cannot send data with error: %d\r\n", (int)res);
}
} else {
- /*
+ /*
* If buffer is empty, reset it to default state (read & write pointers)
* This is to make sure everytime function needs to send data,
* it can do it in single shot rather than in 2 attempts (when read > write pointer).
* Effectively this means faster transmission of MQTT packets and lower latency.
*/
- gsm_buff_reset(&client->tx_buff);
+ lwgsm_buff_reset(&client->tx_buff);
}
}
/**
* \brief Close a MQTT connection with server
* \param[in] client: MQTT client
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-static gsmr_t
-mqtt_close(gsm_mqtt_client_p client) {
- gsmr_t res = gsmERR;
- if (client->conn_state != GSM_MQTT_CONN_DISCONNECTED
- && client->conn_state != GSM_MQTT_CONN_DISCONNECTING) {
-
- res = gsm_conn_close(client->conn, 0); /* Close the connection in non-blocking mode */
- if (res == gsmOK) {
- client->conn_state = GSM_MQTT_CONN_DISCONNECTING;
+static lwgsmr_t
+mqtt_close(lwgsm_mqtt_client_p client) {
+ lwgsmr_t res = lwgsmERR;
+ if (client->conn_state != LWGSM_MQTT_CONN_DISCONNECTED
+ && client->conn_state != LWGSM_MQTT_CONN_DISCONNECTING) {
+
+ res = lwgsm_conn_close(client->conn, 0);/* Close the connection in non-blocking mode */
+ if (res == lwgsmOK) {
+ client->conn_state = LWGSM_MQTT_CONN_DISCONNECTING;
}
}
return res;
@@ -444,17 +461,18 @@ mqtt_close(gsm_mqtt_client_p client) {
* \param[in] client: MQTT client
* \param[in] topic: MQTT topic to (un)subscribe
* \param[in] qos: Quality of service, used only on subscribe part
+ * \param[in] arg: Custom argument
* \param[in] sub: Status set to `1` on subscribe or `0` on unsubscribe
* \return `1` on success, `0` otherwise
*/
static uint8_t
-sub_unsub(gsm_mqtt_client_p client, const char* topic, gsm_mqtt_qos_t qos, void* arg, uint8_t sub) {
- gsm_mqtt_request_t* request;
+sub_unsub(lwgsm_mqtt_client_p client, const char* topic, lwgsm_mqtt_qos_t qos, void* arg, uint8_t sub) {
+ lwgsm_mqtt_request_t* request;
uint32_t rem_len;
uint16_t len_topic, pkt_id;
uint8_t ret = 0;
-
- if ((len_topic = GSM_U16(strlen(topic))) == 0) {
+
+ if ((len_topic = LWGSM_U16(strlen(topic))) == 0) {
return 0;
}
@@ -465,20 +483,20 @@ sub_unsub(gsm_mqtt_client_p client, const char* topic, gsm_mqtt_qos_t qos, void*
*/
rem_len = 2 + len_topic + 2;
if (sub) {
- rem_len++;
+ ++rem_len;
}
- gsm_core_lock();
- if (client->conn_state == GSM_MQTT_CONNECTED
+ lwgsm_core_lock();
+ if (client->conn_state == LWGSM_MQTT_CONNECTED
&& output_check_enough_memory(client, rem_len)) { /* Check if enough memory to write packet data */
pkt_id = create_packet_id(client); /* Create new packet ID */
request = request_create(client, pkt_id, arg); /* Create request for packet */
if (request != NULL) { /* Do we have a request */
- write_fixed_header(client, sub ? MQTT_MSG_TYPE_SUBSCRIBE : MQTT_MSG_TYPE_UNSUBSCRIBE, 0, (gsm_mqtt_qos_t)1, 0, rem_len);
+ write_fixed_header(client, sub ? MQTT_MSG_TYPE_SUBSCRIBE : MQTT_MSG_TYPE_UNSUBSCRIBE, 0, (lwgsm_mqtt_qos_t)1, 0, rem_len);
write_u16(client, pkt_id); /* Write packet ID */
write_string(client, topic, len_topic); /* Write topic string to packet */
if (sub) { /* Send quality of service only on subscribe */
- write_u8(client, GSM_MIN(GSM_U8(qos), GSM_U8(GSM_MQTT_QOS_EXACTLY_ONCE))); /* Write quality of service */
+ write_u8(client, LWGSM_MIN(LWGSM_U8(qos), LWGSM_U8(LWGSM_MQTT_QOS_EXACTLY_ONCE))); /* Write quality of service */
}
request->status |= sub ? MQTT_REQUEST_FLAG_SUBSCRIBE : MQTT_REQUEST_FLAG_UNSUBSCRIBE;
@@ -487,7 +505,7 @@ sub_unsub(gsm_mqtt_client_p client, const char* topic, gsm_mqtt_qos_t qos, void*
ret = 1;
}
}
- gsm_core_unlock();
+ lwgsm_core_unlock();
return ret;
}
@@ -497,45 +515,45 @@ sub_unsub(gsm_mqtt_client_p client, const char* topic, gsm_mqtt_qos_t qos, void*
* \return `1` on success, `0` otherwise
*/
static uint8_t
-mqtt_process_incoming_message(gsm_mqtt_client_p client) {
+mqtt_process_incoming_message(lwgsm_mqtt_client_p client) {
mqtt_msg_type_t msg_type;
- gsm_mqtt_qos_t qos;
+ lwgsm_mqtt_qos_t qos;
uint16_t pkt_id;
msg_type = MQTT_RCV_GET_PACKET_TYPE(client->msg_hdr_byte); /* Get packet type from message header byte */
/* Debug message */
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_STATE,
- "[MQTT] Processing packet type %s\r\n", mqtt_msg_type_to_str(msg_type));
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_STATE,
+ "[MQTT] Processing packet type %s\r\n", mqtt_msg_type_to_str(msg_type));
/* Check received packet type */
switch (msg_type) {
case MQTT_MSG_TYPE_CONNACK: {
- gsm_mqtt_conn_status_t err = (gsm_mqtt_conn_status_t)client->rx_buff[1];
- if (client->conn_state == GSM_MQTT_CONNECTING) {
- if (err == GSM_MQTT_CONN_STATUS_ACCEPTED) {
- client->conn_state = GSM_MQTT_CONNECTED;
+ lwgsm_mqtt_conn_status_t err = (lwgsm_mqtt_conn_status_t)client->rx_buff[1];
+ if (client->conn_state == LWGSM_MQTT_CONNECTING) {
+ if (err == LWGSM_MQTT_CONN_STATUS_ACCEPTED) {
+ client->conn_state = LWGSM_MQTT_CONNECTED;
}
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_TRACE,
- "[MQTT] CONNACK received with result: %d\r\n", (int)err);
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_TRACE,
+ "[MQTT] CONNACK received with result: %d\r\n", (int)err);
/* Notify user layer */
- client->evt.type = GSM_MQTT_EVT_CONNECT;
+ client->evt.type = LWGSM_MQTT_EVT_CONNECT;
client->evt.evt.connect.status = err;
client->evt_fn(client, &client->evt);
} else {
/* Protocol violation here */
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_TRACE,
- "[MQTT] Protocol violation. CONNACK received when already connected!\r\n");
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_TRACE,
+ "[MQTT] Protocol violation. CONNACK received when already connected!\r\n");
}
break;
}
case MQTT_MSG_TYPE_PUBLISH: {
uint16_t topic_len, data_len;
- uint8_t *topic, *data, dup;
+ uint8_t* topic, *data, dup;
- qos = MQTT_RCV_GET_PACKET_QOS(client->msg_hdr_byte); /* Get QoS from received packet */
- dup = MQTT_RCV_GET_PACKET_DUP(client->msg_hdr_byte); /* Get duplicate flag */
+ qos = MQTT_RCV_GET_PACKET_QOS(client->msg_hdr_byte);/* Get QoS from received packet */
+ dup = MQTT_RCV_GET_PACKET_DUP(client->msg_hdr_byte);/* Get duplicate flag */
topic_len = (client->rx_buff[0] << 8) | client->rx_buff[1];
topic = &client->rx_buff[2]; /* Start of topic */
@@ -551,9 +569,9 @@ mqtt_process_incoming_message(gsm_mqtt_client_p client) {
}
data_len = client->msg_rem_len - (data - client->rx_buff); /* Calculate length of remaining data */
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_TRACE,
- "[MQTT] Publish packet received on topic %.*s; QoS: %d; pkt_id: %d; data_len: %d\r\n",
- (int)topic_len, (const char *)topic, (int)qos, (int)pkt_id, (int)data_len);
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_TRACE,
+ "[MQTT] Publish packet received on topic %.*s; QoS: %d; pkt_id: %d; data_len: %d\r\n",
+ (int)topic_len, (const char*)topic, (int)qos, (int)pkt_id, (int)data_len);
/*
* We have to send respond to command if
@@ -564,14 +582,14 @@ mqtt_process_incoming_message(gsm_mqtt_client_p client) {
*/
if (qos > 0) { /* We have to reply on QoS > 0 */
mqtt_msg_type_t resp_msg_type = qos == 1 ? MQTT_MSG_TYPE_PUBACK : MQTT_MSG_TYPE_PUBREC;
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_TRACE, "[MQTT] Sending publish resp: %s on pkt_id: %d\r\n", \
- mqtt_msg_type_to_str(resp_msg_type), (int)pkt_id);
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_TRACE, "[MQTT] Sending publish resp: %s on pkt_id: %d\r\n", \
+ mqtt_msg_type_to_str(resp_msg_type), (int)pkt_id);
write_ack_rec_rel_resp(client, resp_msg_type, pkt_id, qos);
}
/* Notify application layer about received packet */
- client->evt.type = GSM_MQTT_EVT_PUBLISH_RECV;
+ client->evt.type = LWGSM_MQTT_EVT_PUBLISH_RECV;
client->evt.evt.publish_recv.topic = topic;
client->evt.evt.publish_recv.topic_len = topic_len;
client->evt.evt.publish_recv.payload = data;
@@ -582,9 +600,9 @@ mqtt_process_incoming_message(gsm_mqtt_client_p client) {
break;
}
case MQTT_MSG_TYPE_PINGRESP: { /* Respond to PINGREQ received */
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_TRACE, "[MQTT] Ping response received\r\n");
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_TRACE, "[MQTT] Ping response received\r\n");
- client->evt.type = GSM_MQTT_EVT_KEEP_ALIVE;
+ client->evt.type = LWGSM_MQTT_EVT_KEEP_ALIVE;
client->evt_fn(client, &client->evt);
break;
}
@@ -597,14 +615,14 @@ mqtt_process_incoming_message(gsm_mqtt_client_p client) {
pkt_id = client->rx_buff[0] << 8 | client->rx_buff[1]; /* Get packet ID */
if (msg_type == MQTT_MSG_TYPE_PUBREC) { /* Publish record received from server */
- write_ack_rec_rel_resp(client, MQTT_MSG_TYPE_PUBREL, pkt_id, (gsm_mqtt_qos_t)1); /* Send back publish release message */
+ write_ack_rec_rel_resp(client, MQTT_MSG_TYPE_PUBREL, pkt_id, (lwgsm_mqtt_qos_t)1); /* Send back publish release message */
} else if (msg_type == MQTT_MSG_TYPE_PUBREL) { /* Publish release was received */
- write_ack_rec_rel_resp(client, MQTT_MSG_TYPE_PUBCOMP, pkt_id, (gsm_mqtt_qos_t)0); /* Send back publish complete */
+ write_ack_rec_rel_resp(client, MQTT_MSG_TYPE_PUBCOMP, pkt_id, (lwgsm_mqtt_qos_t)0); /* Send back publish complete */
} else if (msg_type == MQTT_MSG_TYPE_SUBACK
- || msg_type == MQTT_MSG_TYPE_UNSUBACK
- || msg_type == MQTT_MSG_TYPE_PUBACK
- || msg_type == MQTT_MSG_TYPE_PUBCOMP) {
- gsm_mqtt_request_t* request;
+ || msg_type == MQTT_MSG_TYPE_UNSUBACK
+ || msg_type == MQTT_MSG_TYPE_PUBACK
+ || msg_type == MQTT_MSG_TYPE_PUBCOMP) {
+ lwgsm_mqtt_request_t* request;
/*
* We can enter here only if we received final acknowledge
@@ -617,27 +635,27 @@ mqtt_process_incoming_message(gsm_mqtt_client_p client) {
if (request != NULL) {
if (msg_type == MQTT_MSG_TYPE_SUBACK
|| msg_type == MQTT_MSG_TYPE_UNSUBACK) {
- client->evt.type = msg_type == MQTT_MSG_TYPE_SUBACK ? GSM_MQTT_EVT_SUBSCRIBE : GSM_MQTT_EVT_UNSUBSCRIBE;
+ client->evt.type = msg_type == MQTT_MSG_TYPE_SUBACK ? LWGSM_MQTT_EVT_SUBSCRIBE : LWGSM_MQTT_EVT_UNSUBSCRIBE;
client->evt.evt.sub_unsub_scribed.arg = request->arg;
- client->evt.evt.sub_unsub_scribed.res = client->rx_buff[2] < 3 ? gsmOK : gsmERR;
+ client->evt.evt.sub_unsub_scribed.res = client->rx_buff[2] < 3 ? lwgsmOK : lwgsmERR;
client->evt_fn(client, &client->evt);
- /*
- * Final acknowledge of packet received
- * Ack type depends on QoS level being sent to server on request
- */
+ /*
+ * Final acknowledge of packet received
+ * Ack type depends on QoS level being sent to server on request
+ */
} else if (msg_type == MQTT_MSG_TYPE_PUBCOMP
- || msg_type == MQTT_MSG_TYPE_PUBACK) {
- client->evt.type = GSM_MQTT_EVT_PUBLISH;
+ || msg_type == MQTT_MSG_TYPE_PUBACK) {
+ client->evt.type = LWGSM_MQTT_EVT_PUBLISH;
client->evt.evt.publish.arg = request->arg;
- client->evt.evt.publish.res = gsmOK;
+ client->evt.evt.publish.res = lwgsmOK;
client->evt_fn(client, &client->evt);
}
- request_delete(client, request); /* Delete request object */
+ request_delete(client, request);/* Delete request object */
} else {
/* Protocol violation at this point! */
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_TRACE,
- "[MQTT] Protocol violation. Received ACK without sent packet\r\n");
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_TRACE,
+ "[MQTT] Protocol violation. Received ACK without sent packet\r\n");
}
}
break;
@@ -655,22 +673,22 @@ mqtt_process_incoming_message(gsm_mqtt_client_p client) {
* \return `1` on success, `0` otherwise
*/
static uint8_t
-mqtt_parse_incoming(gsm_mqtt_client_p client, gsm_pbuf_p pbuf) {
- size_t idx, buff_len = 0, buff_offset = 0;
+mqtt_parse_incoming(lwgsm_mqtt_client_p client, lwgsm_pbuf_p pbuf) {
+ size_t buff_len = 0, buff_offset = 0;
uint8_t ch, *d;
do {
buff_offset += buff_len; /* Calculate new offset of buffer */
- d = gsm_pbuf_get_linear_addr(pbuf, buff_offset, &buff_len); /* Get address pointer */
+ d = lwgsm_pbuf_get_linear_addr(pbuf, buff_offset, &buff_len); /* Get address pointer */
if (d == NULL) {
break;
}
- for (idx = 0; idx < buff_len; idx++) { /* Process entire linear buffer */
+ for (size_t idx = 0; idx < buff_len; ++idx) { /* Process entire linear buffer */
ch = d[idx];
switch (client->parser_state) { /* Check parser state */
case MQTT_PARSER_STATE_INIT: { /* We are waiting for start byte and packet type */
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_STATE,
- "[MQTT] Parser init state, received first byte of packet 0x%02X\r\n", (unsigned)ch);
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_STATE,
+ "[MQTT] Parser init state, received first byte of packet 0x%02X\r\n", (unsigned)ch);
/* Save other info about message */
client->msg_hdr_byte = ch; /* Save first entry */
@@ -683,11 +701,12 @@ mqtt_parse_incoming(gsm_mqtt_client_p client, gsm_pbuf_p pbuf) {
}
case MQTT_PARSER_STATE_CALC_REM_LEN: { /* Calculate remaining length of packet */
/* Length of packet is LSB first, each consist of up to 7 bits */
- client->msg_rem_len |= (ch & 0x7F) << ((size_t)7 * (size_t)client->msg_rem_len_mult++);
+ client->msg_rem_len |= (ch & 0x7F) << ((size_t)7 * (size_t)client->msg_rem_len_mult);
+ ++client->msg_rem_len_mult;
if (!(ch & 0x80)) { /* Is this last entry? */
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_STATE,
- "[MQTT] Remaining length received: %d bytes\r\n", (int)client->msg_rem_len);
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_STATE,
+ "[MQTT] Remaining length received: %d bytes\r\n", (int)client->msg_rem_len);
if (client->msg_rem_len > 0) {
/*
@@ -726,18 +745,18 @@ mqtt_parse_incoming(gsm_mqtt_client_p client, gsm_pbuf_p pbuf) {
if (client->msg_curr_pos < client->rx_buff_len) {
client->rx_buff[client->msg_curr_pos] = ch; /* Write received character */
}
- client->msg_curr_pos++;
+ ++client->msg_curr_pos;
/* We reached end of received characters? */
if (client->msg_curr_pos == client->msg_rem_len) {
if (client->msg_curr_pos <= client->rx_buff_len) { /* Check if it was possible to write all data to rx buffer */
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_STATE,
- "[MQTT] Packet parsed and ready for processing\r\n");
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_STATE,
+ "[MQTT] Packet parsed and ready for processing\r\n");
mqtt_process_incoming_message(client); /* Process incoming packet */
} else {
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_TRACE_WARNING,
- "[MQTT] Packet too big for rx buffer. Packet discarded\r\n");
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_TRACE_WARNING,
+ "[MQTT] Packet too big for rx buffer. Packet discarded\r\n");
}
client->parser_state = MQTT_PARSER_STATE_INIT; /* Go to initial state and listen for next received packet */
}
@@ -762,7 +781,7 @@ mqtt_parse_incoming(gsm_mqtt_client_p client, gsm_pbuf_p pbuf) {
* \param[in] client: MQTT client
*/
static void
-mqtt_connected_cb(gsm_mqtt_client_p client) {
+mqtt_connected_cb(lwgsm_mqtt_client_p client) {
uint16_t rem_len, len_id, len_pass = 0, len_user = 0, len_will_topic = 0, len_will_message = 0;
uint8_t flags = 0;
@@ -776,15 +795,15 @@ mqtt_connected_cb(gsm_mqtt_client_p client) {
*/
rem_len = 10; /* Set remaining length of fixed header */
- len_id = GSM_U16(strlen(client->info->id)); /* Get cliend ID length */
+ len_id = LWGSM_U16(strlen(client->info->id)); /* Get cliend ID length */
rem_len += len_id + 2; /* Add client id length including length entries */
if (client->info->will_topic != NULL && client->info->will_message != NULL) {
flags |= MQTT_FLAG_CONNECT_WILL;
- flags |= GSM_MIN(GSM_U8(client->info->will_qos), 2) << 0x03;/* Set qos to flags */
+ flags |= LWGSM_MIN(LWGSM_U8(client->info->will_qos), 2) << 0x03;/* Set qos to flags */
- len_will_topic = GSM_U16(strlen(client->info->will_topic));
- len_will_message = GSM_U16(strlen(client->info->will_message));
+ len_will_topic = LWGSM_U16(strlen(client->info->will_topic));
+ len_will_message = LWGSM_U16(strlen(client->info->will_message));
rem_len += len_will_topic + 2; /* Add will topic parameter */
rem_len += len_will_message + 2; /* Add will message parameter */
@@ -793,14 +812,14 @@ mqtt_connected_cb(gsm_mqtt_client_p client) {
if (client->info->user != NULL) { /* Check for username */
flags |= MQTT_FLAG_CONNECT_USERNAME; /* Username is included */
- len_user = GSM_U16(strlen(client->info->user)); /* Get username length */
+ len_user = LWGSM_U16(strlen(client->info->user)); /* Get username length */
rem_len += len_user + 2; /* Add username length including length entries */
}
if (client->info->pass != NULL) { /* Check for password */
flags |= MQTT_FLAG_CONNECT_PASSWORD; /* Password is included */
- len_pass = GSM_U16(strlen(client->info->pass)); /* Get username length */
+ len_pass = LWGSM_U16(strlen(client->info->pass)); /* Get username length */
rem_len += len_pass + 2; /* Add password length including length entries */
}
@@ -809,7 +828,7 @@ mqtt_connected_cb(gsm_mqtt_client_p client) {
}
/* Write everything to output buffer */
- write_fixed_header(client, MQTT_MSG_TYPE_CONNECT, 0, (gsm_mqtt_qos_t)0, 0, rem_len);
+ write_fixed_header(client, MQTT_MSG_TYPE_CONNECT, 0, (lwgsm_mqtt_qos_t)0, 0, rem_len);
write_string(client, "MQTT", 4); /* Protocol name */
write_u8(client, 4); /* Protocol version */
write_u8(client, flags); /* Flags for CONNECT message */
@@ -829,7 +848,7 @@ mqtt_connected_cb(gsm_mqtt_client_p client) {
client->parser_state = MQTT_PARSER_STATE_INIT; /* Reset parser state */
client->poll_time = 0; /* Reset kep alive time */
- client->conn_state = GSM_MQTT_CONNECTING; /* MQTT is connecting to server */
+ client->conn_state = LWGSM_MQTT_CONNECTING; /* MQTT is connecting to server */
send_data(client); /* Flush and send the actual data */
}
@@ -841,10 +860,9 @@ mqtt_connected_cb(gsm_mqtt_client_p client) {
* \return `1` on success, `0` otherwise
*/
static uint8_t
-mqtt_data_recv_cb(gsm_mqtt_client_p client, gsm_pbuf_p pbuf) {
- client->poll_time = 0; /* Reset kep alive time */
- mqtt_parse_incoming(client, pbuf);
- gsm_conn_recved(client->conn, pbuf); /* Notify stack about received data */
+mqtt_data_recv_cb(lwgsm_mqtt_client_p client, lwgsm_pbuf_p pbuf) {
+ mqtt_parse_incoming(client, pbuf); /* We need to process incoming data */
+ lwgsm_conn_recved(client->conn, pbuf); /* Notify stack about received data */
return 1;
}
@@ -856,8 +874,8 @@ mqtt_data_recv_cb(gsm_mqtt_client_p client, gsm_pbuf_p pbuf) {
* \return `1` on success, `0` otherwise
*/
static uint8_t
-mqtt_data_sent_cb(gsm_mqtt_client_p client, size_t sent_len, uint8_t successful) {
- gsm_mqtt_request_t* request;
+mqtt_data_sent_cb(lwgsm_mqtt_client_p client, size_t sent_len, uint8_t successful) {
+ lwgsm_mqtt_request_t* request;
client->is_sending = 0; /* We are not sending anymore */
client->sent_total += sent_len;
@@ -870,13 +888,13 @@ mqtt_data_sent_cb(gsm_mqtt_client_p client, size_t sent_len, uint8_t successful)
* and clear all pending requests in closed callback function
*/
if (!successful) {
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_TRACE_WARNING,
- "[MQTT] Failed to send %d bytes. Manually closing down..\r\n", (int)sent_len);
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_TRACE_WARNING,
+ "[MQTT] Failed to send %d bytes. Manually closing down..\r\n", (int)sent_len);
mqtt_close(client);
return 0;
}
- gsm_buff_skip(&client->tx_buff, sent_len); /* Skip buffer for actual sent data */
+ lwgsm_buff_skip(&client->tx_buff, sent_len);/* Skip buffer for actual sent data */
/*
* Check pending publish requests without QoS because there is no confirmation received by server.
@@ -891,9 +909,9 @@ mqtt_data_sent_cb(gsm_mqtt_client_p client, size_t sent_len, uint8_t successful)
request_delete(client, request); /* Delete request and make space for next command */
/* Call published callback */
- client->evt.type = GSM_MQTT_EVT_PUBLISH;
+ client->evt.type = LWGSM_MQTT_EVT_PUBLISH;
client->evt.evt.publish.arg = arg;
- client->evt.evt.publish.res = gsmOK;
+ client->evt.evt.publish.res = lwgsmOK;
client->evt_fn(client, &client->evt);
} else {
break;
@@ -906,15 +924,15 @@ mqtt_data_sent_cb(gsm_mqtt_client_p client, size_t sent_len, uint8_t successful)
/**
* \brief Poll for client connection
- * Called every GSM_CFG_CONN_POLL_INTERVAL ms when MQTT client TCP connection is established
+ * Called every LWGSM_CFG_CONN_POLL_INTERVAL ms when MQTT client TCP connection is established
* \param[in] client: MQTT client
* \return `1` on success, `0` otherwise
*/
static uint8_t
-mqtt_poll_cb(gsm_mqtt_client_p client) {
- client->poll_time++;
+mqtt_poll_cb(lwgsm_mqtt_client_p client) {
+ ++client->poll_time;
- if (client->conn_state == GSM_MQTT_CONN_DISCONNECTING) {
+ if (client->conn_state == LWGSM_MQTT_CONN_DISCONNECTING) {
return 0;
}
@@ -924,18 +942,18 @@ mqtt_poll_cb(gsm_mqtt_client_p client) {
* to make sure we are still alive
*/
if (client->info->keep_alive /* Keep alive must be enabled */
- /* Poll time is in units of GSM_CFG_CONN_POLL_INTERVAL milliseconds,
+ /* Poll time is in units of LWGSM_CFG_CONN_POLL_INTERVAL milliseconds,
while keep_alive is in units of seconds */
- && (client->poll_time * GSM_CFG_CONN_POLL_INTERVAL) >= (uint32_t)(client->info->keep_alive * 1000)) {
+ && (client->poll_time * LWGSM_CFG_CONN_POLL_INTERVAL) >= (uint32_t)(client->info->keep_alive * 1000)) {
if (output_check_enough_memory(client, 0)) {/* Check if memory available in output buffer */
- write_fixed_header(client, MQTT_MSG_TYPE_PINGREQ, 0, (gsm_mqtt_qos_t)0, 0, 0); /* Write PINGREQ command to output buffer */
+ write_fixed_header(client, MQTT_MSG_TYPE_PINGREQ, 0, (lwgsm_mqtt_qos_t)0, 0, 0);/* Write PINGREQ command to output buffer */
send_data(client); /* Force send data */
client->poll_time = 0; /* Reset polling time */
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_TRACE, "[MQTT] Sending PINGREQ packet\r\n");
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_TRACE, "[MQTT] Sending PINGREQ packet\r\n");
} else {
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_TRACE_WARNING, "[MQTT] No memory to send PINGREQ packet\r\n");
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_TRACE_WARNING, "[MQTT] No memory to send PINGREQ packet\r\n");
}
}
@@ -954,17 +972,17 @@ mqtt_poll_cb(gsm_mqtt_client_p client) {
* \return `1` on success, `0` otherwise
*/
static uint8_t
-mqtt_closed_cb(gsm_mqtt_client_p client, gsmr_t res, uint8_t forced) {
- gsm_mqtt_state_t state = client->conn_state;
- gsm_mqtt_request_t* request;
+mqtt_closed_cb(lwgsm_mqtt_client_p client, lwgsmr_t res, uint8_t forced) {
+ lwgsm_mqtt_state_t state = client->conn_state;
+ lwgsm_mqtt_request_t* request;
/*
* Call user function only if connection was closed
* when we are connected or in disconnecting mode
*/
- client->conn_state = GSM_MQTT_CONN_DISCONNECTED;/* Connection is disconnected, ready to be established again */
- client->evt.evt.disconnect.is_accepted = state == GSM_MQTT_CONNECTED || state == GSM_MQTT_CONN_DISCONNECTING; /* Set connection state */
- client->evt.type = GSM_MQTT_EVT_DISCONNECT; /* Connection disconnected from server */
+ client->conn_state = LWGSM_MQTT_CONN_DISCONNECTED; /* Connection is disconnected, ready to be established again */
+ client->evt.evt.disconnect.is_accepted = state == LWGSM_MQTT_CONNECTED || state == LWGSM_MQTT_CONN_DISCONNECTING; /* Set connection state */
+ client->evt.type = LWGSM_MQTT_EVT_DISCONNECT; /* Connection disconnected from server */
client->evt_fn(client, &client->evt); /* Notify upper layer about closed connection */
client->conn = NULL; /* Reset connection handle */
@@ -976,13 +994,13 @@ mqtt_closed_cb(gsm_mqtt_client_p client, gsmr_t res, uint8_t forced) {
request_delete(client, request); /* Delete request */
request_send_err_callback(client, status, arg); /* Send error callback to user */
}
- GSM_MEMSET(client->requests, 0x00, sizeof(client->requests));
+ LWGSM_MEMSET(client->requests, 0x00, sizeof(client->requests));
client->is_sending = client->sent_total = client->written_total = 0;
client->parser_state = MQTT_PARSER_STATE_INIT;
- gsm_buff_reset(&client->tx_buff); /* Reset TX buffer */
+ lwgsm_buff_reset(&client->tx_buff); /* Reset TX buffer */
- GSM_UNUSED(forced);
+ LWGSM_UNUSED(forced);
return 1;
}
@@ -990,81 +1008,81 @@ mqtt_closed_cb(gsm_mqtt_client_p client, gsmr_t res, uint8_t forced) {
/**
* \brief Connection callback
* \param[in] evt: Callback parameters
- * \result \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \result \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-static gsmr_t
-mqtt_conn_cb(gsm_evt_t* evt) {
- gsm_conn_p conn;
- gsm_mqtt_client_p client = NULL;
+static lwgsmr_t
+mqtt_conn_cb(lwgsm_evt_t* evt) {
+ lwgsm_conn_p conn;
+ lwgsm_mqtt_client_p client = NULL;
- conn = gsm_conn_get_from_evt(evt); /* Get connection from event */
+ conn = lwgsm_conn_get_from_evt(evt); /* Get connection from event */
if (conn != NULL) {
- client = gsm_conn_get_arg(conn); /* Get client structure from connection */
+ client = lwgsm_conn_get_arg(conn); /* Get client structure from connection */
if (client == NULL) {
- gsm_conn_close(conn, 0); /* Force connection close immediatelly */
- return gsmERR;
+ lwgsm_conn_close(conn, 0); /* Force connection close immediately */
+ return lwgsmERR;
}
- } else if (evt->type != GSM_EVT_CONN_ERROR) {
- return gsmERR;
+ } else if (evt->type != LWGSM_EVT_CONN_ERROR) {
+ return lwgsmERR;
}
/* Check and process events */
- switch (gsm_evt_get_type(evt)) {
+ switch (lwgsm_evt_get_type(evt)) {
/*
* Connection error. Connection to external
* server was not successful
*/
- case GSM_EVT_CONN_ERROR: {
- gsm_mqtt_client_p client;
- client = gsm_evt_conn_error_get_arg(evt); /* Get connection argument */
+ case LWGSM_EVT_CONN_ERROR: {
+ lwgsm_mqtt_client_p client;
+ client = lwgsm_evt_conn_error_get_arg(evt); /* Get connection argument */
if (client != NULL) {
- client->conn_state = GSM_MQTT_CONN_DISCONNECTED;/* Set back to disconnected state */
+ client->conn_state = LWGSM_MQTT_CONN_DISCONNECTED; /* Set back to disconnected state */
/* Notify user upper layer */
- client->evt.type = GSM_MQTT_EVT_CONNECT;
- client->evt.evt.connect.status = GSM_MQTT_CONN_STATUS_TCP_FAILED; /* TCP connection failed */
+ client->evt.type = LWGSM_MQTT_EVT_CONNECT;
+ client->evt.evt.connect.status = LWGSM_MQTT_CONN_STATUS_TCP_FAILED; /* TCP connection failed */
client->evt_fn(client, &client->evt); /* Notify upper layer about closed connection */
}
break;
}
/* Connection active to MQTT server */
- case GSM_EVT_CONN_ACTIVE: {
+ case LWGSM_EVT_CONN_ACTIVE: {
mqtt_connected_cb(client); /* Call function to process status */
break;
}
/* A new packet of data received on MQTT client connection */
- case GSM_EVT_CONN_RECV: {
- mqtt_data_recv_cb(client, gsm_evt_conn_recv_get_buff(evt));/* Call user to process received data */
+ case LWGSM_EVT_CONN_RECV: {
+ mqtt_data_recv_cb(client, lwgsm_evt_conn_recv_get_buff(evt)); /* Call user to process received data */
break;
}
/* Data send event */
- case GSM_EVT_CONN_SEND: {
+ case LWGSM_EVT_CONN_SEND: {
/* Data sent callback */
mqtt_data_sent_cb(client,
- gsm_evt_conn_send_get_length(evt),
- gsm_evt_conn_send_get_result(evt) == gsmOK);
+ lwgsm_evt_conn_send_get_length(evt),
+ lwgsm_evt_conn_send_get_result(evt) == lwgsmOK);
break;
}
/* Periodic poll for connection */
- case GSM_EVT_CONN_POLL: {
+ case LWGSM_EVT_CONN_POLL: {
mqtt_poll_cb(client); /* Poll client */
break;
}
/* Connection closed */
- case GSM_EVT_CONN_CLOSE: {
+ case LWGSM_EVT_CONN_CLOSE: {
mqtt_closed_cb(client,
- gsm_evt_conn_close_get_result(evt) == gsmOK,
- gsm_evt_conn_close_is_forced(evt));
+ lwgsm_evt_conn_close_get_result(evt) == lwgsmOK,
+ lwgsm_evt_conn_close_is_forced(evt));
break;
}
default:
break;
}
- return gsmOK;
+ return lwgsmOK;
}
/**
@@ -1073,24 +1091,24 @@ mqtt_conn_cb(gsm_evt_t* evt) {
* \param[in] rx_buff_len: Length of raw data input buffer
* \return Pointer to new allocated MQTT client structure or `NULL` on failure
*/
-gsm_mqtt_client_t *
-gsm_mqtt_client_new(size_t tx_buff_len, size_t rx_buff_len) {
- gsm_mqtt_client_p client;
+lwgsm_mqtt_client_t*
+lwgsm_mqtt_client_new(size_t tx_buff_len, size_t rx_buff_len) {
+ lwgsm_mqtt_client_p client;
- client = gsm_mem_malloc(sizeof(*client));
+ client = lwgsm_mem_malloc(sizeof(*client));
if (client != NULL) {
- GSM_MEMSET(client, 0x00, sizeof(*client));
- client->conn_state = GSM_MQTT_CONN_DISCONNECTED;/* Set to disconnected mode */
+ LWGSM_MEMSET(client, 0x00, sizeof(*client));
+ client->conn_state = LWGSM_MQTT_CONN_DISCONNECTED; /* Set to disconnected mode */
- if (!gsm_buff_init(&client->tx_buff, tx_buff_len)) {
- gsm_mem_free_s((void **)&client);
+ if (!lwgsm_buff_init(&client->tx_buff, tx_buff_len)) {
+ lwgsm_mem_free_s((void**)&client);
}
if (client != NULL) {
client->rx_buff_len = rx_buff_len;
- client->rx_buff = gsm_mem_malloc(rx_buff_len);
+ client->rx_buff = lwgsm_mem_malloc(rx_buff_len);
if (client->rx_buff == NULL) {
- gsm_buff_free(&client->tx_buff);
- gsm_mem_free_s((void **)&client);
+ lwgsm_buff_free(&client->tx_buff);
+ lwgsm_mem_free_s((void**)&client);
}
}
}
@@ -1103,11 +1121,11 @@ gsm_mqtt_client_new(size_t tx_buff_len, size_t rx_buff_len) {
* \param[in] client: MQTT client
*/
void
-gsm_mqtt_client_delete(gsm_mqtt_client_p client) {
+lwgsm_mqtt_client_delete(lwgsm_mqtt_client_p client) {
if (client != NULL) {
- gsm_mem_free_s((void **)&client->rx_buff);
- gsm_buff_free(&client->tx_buff);
- gsm_mem_free_s((void **)&client);
+ lwgsm_mem_free_s((void**)&client->rx_buff);
+ lwgsm_buff_free(&client->tx_buff);
+ lwgsm_mem_free_s((void**)&client);
}
}
@@ -1119,30 +1137,30 @@ gsm_mqtt_client_delete(gsm_mqtt_client_p client) {
* \param[in] port: Host port number
* \param[in] evt_fn: Callback function for all events on this MQTT client
* \param[in] info: Information structure for connection
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_mqtt_client_connect(gsm_mqtt_client_p client, const char* host, gsm_port_t port,
- gsm_mqtt_evt_fn evt_fn, const gsm_mqtt_client_info_t* info) {
- gsmr_t res = gsmERR;
-
- GSM_ASSERT("client != NULL", client != NULL); /* t input parameters */
- GSM_ASSERT("host != NULL", host != NULL);
- GSM_ASSERT("port > 0", port > 0);
- GSM_ASSERT("info != NULL", info != NULL);
-
- gsm_core_lock();
- if (gsm_network_is_attached() && client->conn_state == GSM_MQTT_CONN_DISCONNECTED) {
+lwgsmr_t
+lwgsm_mqtt_client_connect(lwgsm_mqtt_client_p client, const char* host, lwgsm_port_t port,
+ lwgsm_mqtt_evt_fn evt_fn, const lwgsm_mqtt_client_info_t* info) {
+ lwgsmr_t res = lwgsmERR;
+
+ LWGSM_ASSERT("client != NULL", client != NULL); /* t input parameters */
+ LWGSM_ASSERT("host != NULL", host != NULL);
+ LWGSM_ASSERT("port > 0", port > 0);
+ LWGSM_ASSERT("info != NULL", info != NULL);
+
+ lwgsm_core_lock();
+ if (lwgsm_network_is_attached() && client->conn_state == LWGSM_MQTT_CONN_DISCONNECTED) {
client->info = info; /* Save client info parameters */
client->evt_fn = evt_fn != NULL ? evt_fn : mqtt_evt_fn_default;
/* Start a new connection in non-blocking mode */
- res = gsm_conn_start(&client->conn, GSM_CONN_TYPE_TCP, host, port, client, mqtt_conn_cb, 0);
- if (res == gsmOK) {
- client->conn_state = GSM_MQTT_CONN_CONNECTING;
+ res = lwgsm_conn_start(&client->conn, LWGSM_CONN_TYPE_TCP, host, port, client, mqtt_conn_cb, 0);
+ if (res == lwgsmOK) {
+ client->conn_state = LWGSM_MQTT_CONN_CONNECTING;
}
}
- gsm_core_unlock();
+ lwgsm_core_unlock();
return res;
}
@@ -1150,18 +1168,18 @@ gsm_mqtt_client_connect(gsm_mqtt_client_p client, const char* host, gsm_port_t p
/**
* \brief Disconnect from MQTT server
* \param[in] client: MQTT client
- * \return \ref gsmOK if request sent to queue or member of \ref gsmr_t otherwise
+ * \return \ref lwgsmOK if request sent to queue or member of \ref lwgsmr_t otherwise
*/
-gsmr_t
-gsm_mqtt_client_disconnect(gsm_mqtt_client_p client) {
- gsmr_t res = gsmERR;
+lwgsmr_t
+lwgsm_mqtt_client_disconnect(lwgsm_mqtt_client_p client) {
+ lwgsmr_t res = lwgsmERR;
- gsm_core_lock();
- if (client->conn_state != GSM_MQTT_CONN_DISCONNECTED
- && client->conn_state != GSM_MQTT_CONN_DISCONNECTING) {
+ lwgsm_core_lock();
+ if (client->conn_state != LWGSM_MQTT_CONN_DISCONNECTED
+ && client->conn_state != LWGSM_MQTT_CONN_DISCONNECTING) {
res = mqtt_close(client); /* Close client connection */
}
- gsm_core_unlock();
+ lwgsm_core_unlock();
return res;
}
@@ -1169,13 +1187,13 @@ gsm_mqtt_client_disconnect(gsm_mqtt_client_p client) {
* \brief Subscribe to MQTT topic
* \param[in] client: MQTT client
* \param[in] topic: Topic name to subscribe to
- * \param[in] qos: Quality of service. This parameter can be a value of \ref gsm_mqtt_qos_t
+ * \param[in] qos: Quality of service. This parameter can be a value of \ref lwgsm_mqtt_qos_t
* \param[in] arg: User custom argument used in callback
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_mqtt_client_subscribe(gsm_mqtt_client_p client, const char* topic, gsm_mqtt_qos_t qos, void* arg) {
- return sub_unsub(client, topic, qos, arg, 1) == 1 ? gsmOK : gsmERR; /* Subscribe to topic */
+lwgsmr_t
+lwgsm_mqtt_client_subscribe(lwgsm_mqtt_client_p client, const char* topic, lwgsm_mqtt_qos_t qos, void* arg) {
+ return sub_unsub(client, topic, qos, arg, 1) == 1 ? lwgsmOK : lwgsmERR; /* Subscribe to topic */
}
/**
@@ -1183,11 +1201,11 @@ gsm_mqtt_client_subscribe(gsm_mqtt_client_p client, const char* topic, gsm_mqtt_
* \param[in] client: MQTT client
* \param[in] topic: Topic name to unsubscribe from
* \param[in] arg: User custom argument used in callback
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_mqtt_client_unsubscribe(gsm_mqtt_client_p client, const char* topic, void* arg) {
- return sub_unsub(client, topic, (gsm_mqtt_qos_t)0, arg, 0) == 1 ? gsmOK : gsmERR; /* Unsubscribe from topic */
+lwgsmr_t
+lwgsm_mqtt_client_unsubscribe(lwgsm_mqtt_client_p client, const char* topic, void* arg) {
+ return sub_unsub(client, topic, (lwgsm_mqtt_qos_t)0, arg, 0) == 1 ? lwgsmOK : lwgsmERR; /* Unsubscribe from topic */
}
/**
@@ -1196,22 +1214,22 @@ gsm_mqtt_client_unsubscribe(gsm_mqtt_client_p client, const char* topic, void* a
* \param[in] topic: Topic to send message to
* \param[in] payload: Message data
* \param[in] payload_len: Length of payload data
- * \param[in] qos: Quality of service. This parameter can be a value of \ref gsm_mqtt_qos_t enumeration
+ * \param[in] qos: Quality of service. This parameter can be a value of \ref lwgsm_mqtt_qos_t enumeration
* \param[in] retain: Retian parameter value
* \param[in] arg: User custom argument used in callback
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_mqtt_client_publish(gsm_mqtt_client_p client, const char* topic, const void* payload,
- uint16_t payload_len, gsm_mqtt_qos_t qos, uint8_t retain, void* arg) {
- gsmr_t res = gsmOK;
- gsm_mqtt_request_t* request = NULL;
+lwgsmr_t
+lwgsm_mqtt_client_publish(lwgsm_mqtt_client_p client, const char* topic, const void* payload,
+ uint16_t payload_len, lwgsm_mqtt_qos_t qos, uint8_t retain, void* arg) {
+ lwgsmr_t res = lwgsmOK;
+ lwgsm_mqtt_request_t* request = NULL;
uint32_t rem_len, raw_len;
uint16_t len_topic, pkt_id;
- uint8_t qos_u8 = GSM_U8(qos);
+ uint8_t qos_u8 = LWGSM_U8(qos);
- if (!(len_topic = GSM_U16(strlen(topic)))) { /* Get length of topic */
- return gsmERR;
+ if (!(len_topic = LWGSM_U16(strlen(topic)))) { /* Get length of topic */
+ return lwgsmERR;
}
/*
@@ -1224,9 +1242,9 @@ gsm_mqtt_client_publish(gsm_mqtt_client_p client, const char* topic, const void*
rem_len += 2;
}
- gsm_core_lock();
- if (client->conn_state != GSM_MQTT_CONNECTED) {
- res = gsmCLOSED;
+ lwgsm_core_lock();
+ if (client->conn_state != LWGSM_MQTT_CONNECTED) {
+ res = lwgsmCLOSED;
} else if ((raw_len = output_check_enough_memory(client, rem_len)) != 0) {
pkt_id = qos_u8 > 0 ? create_packet_id(client) : 0; /* Create new packet ID */
request = request_create(client, pkt_id, arg); /* Create request for packet */
@@ -1240,7 +1258,7 @@ gsm_mqtt_client_publish(gsm_mqtt_client_p client, const char* topic, const void*
*/
request->expected_sent_len = client->written_total + raw_len;
- write_fixed_header(client, MQTT_MSG_TYPE_PUBLISH, 0, (gsm_mqtt_qos_t)GSM_MIN(qos_u8, GSM_U8(GSM_MQTT_QOS_EXACTLY_ONCE)), retain, rem_len);
+ write_fixed_header(client, MQTT_MSG_TYPE_PUBLISH, 0, (lwgsm_mqtt_qos_t)LWGSM_MIN(qos_u8, LWGSM_U8(LWGSM_MQTT_QOS_EXACTLY_ONCE)), retain, rem_len);
write_string(client, topic, len_topic); /* Write topic string to packet */
if (qos_u8) {
write_u16(client, pkt_id); /* Write packet ID */
@@ -1252,17 +1270,17 @@ gsm_mqtt_client_publish(gsm_mqtt_client_p client, const char* topic, const void*
send_data(client); /* Try to send data */
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_TRACE,
- "[MQTT] Pkt publish start. QoS: %d, pkt_id: %d\r\n", (int)qos_u8, (int)pkt_id);
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_TRACE,
+ "[MQTT] Pkt publish start. QoS: %d, pkt_id: %d\r\n", (int)qos_u8, (int)pkt_id);
} else {
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_TRACE, "[MQTT] No free request available to publish message\r\n");
- res = gsmERRMEM;
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_TRACE, "[MQTT] No free request available to publish message\r\n");
+ res = lwgsmERRMEM;
}
} else {
- GSM_DEBUGF(GSM_CFG_DBG_MQTT_TRACE, "[MQTT] Not enough memory to publish message\r\n");
- res = gsmERRMEM;
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_TRACE, "[MQTT] Not enough memory to publish message\r\n");
+ res = lwgsmERRMEM;
}
- gsm_core_unlock();
+ lwgsm_core_unlock();
return res;
}
@@ -1273,12 +1291,12 @@ gsm_mqtt_client_publish(gsm_mqtt_client_p client, const char* topic, const void*
* \return `1` on success, `0` otherwise
*/
uint8_t
-gsm_mqtt_client_is_connected(gsm_mqtt_client_p client) {
+lwgsm_mqtt_client_is_connected(lwgsm_mqtt_client_p client) {
uint8_t res;
- gsm_core_lock();
- res = GSM_U8(client->conn_state == GSM_MQTT_CONNECTED);
- gsm_core_unlock();
+ lwgsm_core_lock();
+ res = LWGSM_U8(client->conn_state == LWGSM_MQTT_CONNECTED);
+ lwgsm_core_unlock();
return res;
}
@@ -1289,10 +1307,10 @@ gsm_mqtt_client_is_connected(gsm_mqtt_client_p client) {
* \param[in] arg: User argument
*/
void
-gsm_mqtt_client_set_arg(gsm_mqtt_client_p client, void* arg) {
- gsm_core_lock();
+lwgsm_mqtt_client_set_arg(lwgsm_mqtt_client_p client, void* arg) {
+ lwgsm_core_lock();
client->arg = arg;
- gsm_core_unlock();
+ lwgsm_core_unlock();
}
/**
@@ -1300,7 +1318,7 @@ gsm_mqtt_client_set_arg(gsm_mqtt_client_p client, void* arg) {
* \param[in] client: MQTT client handle
* \return User argument
*/
-void *
-gsm_mqtt_client_get_arg(gsm_mqtt_client_p client) {
+void*
+lwgsm_mqtt_client_get_arg(lwgsm_mqtt_client_p client) {
return client->arg;
}
diff --git a/lwgsm/src/apps/mqtt/lwgsm_mqtt_client_api.c b/lwgsm/src/apps/mqtt/lwgsm_mqtt_client_api.c
new file mode 100644
index 00000000..9a8f739a
--- /dev/null
+++ b/lwgsm/src/apps/mqtt/lwgsm_mqtt_client_api.c
@@ -0,0 +1,524 @@
+/**
+ * \file lwgsm_mqtt_client_api.c
+ * \brief MQTT client API
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM - Lightweight GSM-AT library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+#include "lwgsm/apps/lwgsm_mqtt_client_api.h"
+#include "lwgsm/lwgsm_mem.h"
+
+/* Tracing debug message */
+#define LWGSM_CFG_DBG_MQTT_API_TRACE (LWGSM_CFG_DBG_MQTT_API | LWGSM_DBG_TYPE_TRACE)
+#define LWGSM_CFG_DBG_MQTT_API_STATE (LWGSM_CFG_DBG_MQTT_API | LWGSM_DBG_TYPE_STATE)
+#define LWGSM_CFG_DBG_MQTT_API_TRACE_WARNING (LWGSM_CFG_DBG_MQTT_API | LWGSM_DBG_TYPE_TRACE | LWGSM_DBG_LVL_WARNING)
+#define LWGSM_CFG_DBG_MQTT_API_TRACE_SEVERE (LWGSM_CFG_DBG_MQTT_API | LWGSM_DBG_TYPE_TRACE | LWGSM_DBG_LVL_SEVERE)
+
+/**
+ * \brief MQTT API client structure
+ */
+struct lwgsm_mqtt_client_api {
+ lwgsm_mqtt_client_p mc; /*!< MQTT client handle */
+ lwgsm_sys_mbox_t rcv_mbox; /*!< Received data mbox */
+ lwgsm_sys_sem_t sync_sem; /*!< Synchronization semaphore */
+ lwgsm_sys_mutex_t mutex; /*!< Mutex handle */
+ uint8_t release_sem; /*!< Set to `1` to release semaphore */
+ lwgsm_mqtt_conn_status_t connect_resp; /*!< Response when connecting to server */
+ lwgsmr_t sub_pub_resp; /*!< Subscribe/Unsubscribe/Publish response */
+} lwgsm_mqtt_client_api_t;
+
+/**
+ * \brief Variable used as pointer for message queue when MQTT connection is closed
+ */
+static uint8_t
+mqtt_closed = 0xFF;
+
+/**
+ * \brief Release user semaphore
+ * \param[in] client: Client handle
+ */
+static void
+release_sem(lwgsm_mqtt_client_api_p client) {
+ if (client->release_sem) {
+ client->release_sem = 0;
+ lwgsm_sys_sem_release(&client->sync_sem);
+ }
+}
+
+/**
+ * \brief MQTT event callback function
+ */
+static void
+mqtt_evt(lwgsm_mqtt_client_p client, lwgsm_mqtt_evt_t* evt) {
+ lwgsm_mqtt_client_api_p api_client = lwgsm_mqtt_client_get_arg(client);
+ if (api_client == NULL) {
+ return;
+ }
+ switch (lwgsm_mqtt_client_evt_get_type(client, evt)) {
+ case LWGSM_MQTT_EVT_CONNECT: {
+ lwgsm_mqtt_conn_status_t status = lwgsm_mqtt_client_evt_connect_get_status(client, evt);
+
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_API_TRACE,
+ "[MQTT API] Connect event with status: %d\r\n", (int)status);
+
+ api_client->connect_resp = status;
+
+ /*
+ * By MQTT 3.1.1 specification, broker must close connection
+ * if client CONNECT packet was not accepted.
+ *
+ * If client is accepted or connection did not even start,
+ * release semaphore, otherwise wait CLOSED event
+ * and release semaphore from there,
+ * to make sure we are fully ready for next connection
+ */
+ if (status == LWGSM_MQTT_CONN_STATUS_TCP_FAILED
+ || status == LWGSM_MQTT_CONN_STATUS_ACCEPTED) {
+ release_sem(api_client); /* Release semaphore */
+ }
+
+ break;
+ }
+ case LWGSM_MQTT_EVT_PUBLISH_RECV: {
+ /* Check valid receive mbox */
+ if (lwgsm_sys_mbox_isvalid(&api_client->rcv_mbox)) {
+ lwgsm_mqtt_client_api_buf_p buf;
+ size_t size, buf_size, topic_size, payload_size;
+
+ /* Get event data */
+ const char* topic = lwgsm_mqtt_client_evt_publish_recv_get_topic(client, evt);
+ size_t topic_len = lwgsm_mqtt_client_evt_publish_recv_get_topic_len(client, evt);
+ const uint8_t* payload = lwgsm_mqtt_client_evt_publish_recv_get_payload(client, evt);
+ size_t payload_len = lwgsm_mqtt_client_evt_publish_recv_get_payload_len(client, evt);
+ lwgsm_mqtt_qos_t qos = lwgsm_mqtt_client_evt_publish_recv_get_qos(client, evt);
+
+ /* Print debug message */
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_API_TRACE,
+ "[MQTT API] New publish received on topic %.*s\r\n", (int)topic_len, topic);
+
+ /* Calculate memory sizes */
+ buf_size = LWGSM_MEM_ALIGN(sizeof(*buf));
+ topic_size = LWGSM_MEM_ALIGN(sizeof(*topic) * (topic_len + 1));
+ payload_size = LWGSM_MEM_ALIGN(sizeof(*payload) * (payload_len + 1));
+
+ size = buf_size + topic_size + payload_size;
+ buf = lwgsm_mem_malloc(size);
+ if (buf != NULL) {
+ LWGSM_MEMSET(buf, 0x00, size);
+ buf->topic = (void*)((uint8_t*)buf + buf_size);
+ buf->payload = (void*)((uint8_t*)buf + buf_size + topic_size);
+ buf->topic_len = topic_len;
+ buf->payload_len = payload_len;
+ buf->qos = qos;
+
+ /* Copy content to new memory */
+ LWGSM_MEMCPY(buf->topic, topic, sizeof(*topic) * topic_len);
+ LWGSM_MEMCPY(buf->payload, payload, sizeof(*payload) * payload_len);
+
+ /* Write to receive queue */
+ if (!lwgsm_sys_mbox_putnow(&api_client->rcv_mbox, buf)) {
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_API_TRACE_WARNING,
+ "[MQTT API] Cannot put new received MQTT publish to queue\r\n");
+ lwgsm_mem_free_s((void**)&buf);
+ }
+ } else {
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_API_TRACE_WARNING,
+ "[MQTT API] Cannot allocate memory for packet buffer of size %d bytes\r\n",
+ (int)size);
+ }
+ }
+ break;
+ }
+ case LWGSM_MQTT_EVT_PUBLISH: {
+ api_client->sub_pub_resp = lwgsm_mqtt_client_evt_publish_get_result(client, evt);
+
+ /* Print debug message */
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_API_TRACE,
+ "[MQTT API] Publish event with response: %d\r\n",
+ (int)api_client->sub_pub_resp);
+
+ release_sem(api_client); /* Release semaphore */
+ break;
+ }
+ case LWGSM_MQTT_EVT_SUBSCRIBE: {
+ api_client->sub_pub_resp = lwgsm_mqtt_client_evt_subscribe_get_result(client, evt);
+
+ /* Print debug message */
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_API_TRACE,
+ "[MQTT API] Subscribe event with response: %d\r\n",
+ (int)api_client->sub_pub_resp);
+
+ release_sem(api_client); /* Release semaphore */
+ break;
+ }
+ case LWGSM_MQTT_EVT_UNSUBSCRIBE: {
+ api_client->sub_pub_resp = lwgsm_mqtt_client_evt_unsubscribe_get_result(client, evt);
+
+ /* Print debug message */
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_API_TRACE,
+ "[MQTT API] Unsubscribe event with response: %d\r\n",
+ (int)api_client->sub_pub_resp);
+
+ release_sem(api_client); /* Release semaphore */
+ break;
+ }
+ case LWGSM_MQTT_EVT_DISCONNECT: {
+ uint8_t is_accepted = lwgsm_mqtt_client_evt_disconnect_is_accepted(client, evt);
+ /* Disconnect event happened */
+ //api_client->connect_resp = MQTT_CONN_STATUS_TCP_FAILED;
+
+ /* Print debug message */
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_API_TRACE,
+ "[MQTT API] Disconnect event\r\n");
+
+ /* Write to receive mbox to wakeup receive thread */
+ if (is_accepted && lwgsm_sys_mbox_isvalid(&api_client->rcv_mbox)) {
+ lwgsm_sys_mbox_putnow(&api_client->rcv_mbox, &mqtt_closed);
+ }
+
+ release_sem(api_client); /* Release semaphore */
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+/**
+ * \brief Create new MQTT client API
+ * \param[in] tx_buff_len: Maximal TX buffer for maximal packet length
+ * \param[in] rx_buff_len: Maximal RX buffer
+ * \return Client handle on success, `NULL` otherwise
+ */
+lwgsm_mqtt_client_api_p
+lwgsm_mqtt_client_api_new(size_t tx_buff_len, size_t rx_buff_len) {
+ lwgsm_mqtt_client_api_p client;
+ size_t size;
+
+ size = LWGSM_MEM_ALIGN(sizeof(*client)); /* Get size of client itself */
+
+ /* Create client APi structure */
+ client = lwgsm_mem_calloc(1, size); /* Allocate client memory */
+ if (client != NULL) {
+ /* Create MQTT raw client structure */
+ client->mc = lwgsm_mqtt_client_new(tx_buff_len, rx_buff_len);
+ if (client->mc != NULL) {
+ /* Create receive mbox queue */
+ if (lwgsm_sys_mbox_create(&client->rcv_mbox, 5)) {
+ /* Create synchronization semaphore */
+ if (lwgsm_sys_sem_create(&client->sync_sem, 1)) {
+ /* Create mutex */
+ if (lwgsm_sys_mutex_create(&client->mutex)) {
+ lwgsm_mqtt_client_set_arg(client->mc, client); /* Set client to mqtt client argument */
+ return client;
+ } else {
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_API,
+ "[MQTT API] Cannot allocate mutex\r\n");
+ }
+ } else {
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_API,
+ "[MQTT API] Cannot allocate sync semaphore\r\n");
+ }
+ } else {
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_API,
+ "[MQTT API] Cannot allocate receive queue\r\n");
+ }
+ } else {
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_API,
+ "[MQTT API] Cannot allocate MQTT client\r\n");
+ }
+ } else {
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_API,
+ "[MQTT API] Cannot allocate memory for client\r\n");
+ }
+
+ lwgsm_mqtt_client_api_delete(client);
+ client = NULL;
+ return NULL;
+}
+
+/**
+ * \brief Delete client from memory
+ * \param[in] client: MQTT API client handle
+ */
+void
+lwgsm_mqtt_client_api_delete(lwgsm_mqtt_client_api_p client) {
+ if (client == NULL) {
+ return;
+ }
+ if (lwgsm_sys_sem_isvalid(&client->sync_sem)) {
+ lwgsm_sys_sem_delete(&client->sync_sem);
+ lwgsm_sys_sem_invalid(&client->sync_sem);
+ }
+ if (lwgsm_sys_mutex_isvalid(&client->mutex)) {
+ lwgsm_sys_mutex_delete(&client->mutex);
+ lwgsm_sys_mutex_invalid(&client->mutex);
+ }
+ if (lwgsm_sys_mbox_isvalid(&client->rcv_mbox)) {
+ void* d;
+ while (lwgsm_sys_mbox_getnow(&client->rcv_mbox, &d)) {
+ if ((uint8_t*)d != (uint8_t*)&mqtt_closed) {
+ lwgsm_mqtt_client_api_buf_free(d);
+ }
+ }
+ lwgsm_sys_mbox_delete(&client->rcv_mbox);
+ lwgsm_sys_mbox_invalid(&client->rcv_mbox);
+ }
+ if (client->mc != NULL) {
+ lwgsm_mqtt_client_delete(client->mc);
+ client->mc = NULL;
+ }
+ lwgsm_mem_free_s((void**)&client);
+}
+
+/**
+ * \brief Connect to MQTT broker
+ * \param[in] client: MQTT API client handle
+ * \param[in] host: TCP host
+ * \param[in] port: TCP port
+ * \param[in] info: MQTT client info
+ * \return \ref LWGSM_MQTT_CONN_STATUS_ACCEPTED on success, member of \ref lwgsm_mqtt_conn_status_t otherwise
+ */
+lwgsm_mqtt_conn_status_t
+lwgsm_mqtt_client_api_connect(lwgsm_mqtt_client_api_p client, const char* host,
+ lwgsm_port_t port, const lwgsm_mqtt_client_info_t* info) {
+ if (client == NULL || host == NULL
+ || !port || info == NULL) {
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_API_TRACE_WARNING,
+ "[MQTT API] Invalid parameters in function\r\n");
+ return LWGSM_MQTT_CONN_STATUS_TCP_FAILED;
+ }
+
+ lwgsm_sys_mutex_lock(&client->mutex);
+ client->connect_resp = LWGSM_MQTT_CONN_STATUS_TCP_FAILED;
+ lwgsm_sys_sem_wait(&client->sync_sem, 0);
+ client->release_sem = 1;
+ if (lwgsm_mqtt_client_connect(client->mc, host, port, mqtt_evt, info) == lwgsmOK) {
+ lwgsm_sys_sem_wait(&client->sync_sem, 0);
+ } else {
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_API_TRACE_WARNING,
+ "[MQTT API] Cannot connect to %s\r\n", host);
+ }
+ client->release_sem = 0;
+ lwgsm_sys_sem_release(&client->sync_sem);
+ lwgsm_sys_mutex_unlock(&client->mutex);
+ return client->connect_resp;
+}
+
+/**
+ * \brief Close MQTT connection
+ * \param[in] client: MQTT API client handle
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+ */
+lwgsmr_t
+lwgsm_mqtt_client_api_close(lwgsm_mqtt_client_api_p client) {
+ lwgsmr_t res = lwgsmERR;
+
+ LWGSM_ASSERT("client != NULL", client != NULL);
+
+ lwgsm_sys_mutex_lock(&client->mutex);
+ lwgsm_sys_sem_wait(&client->sync_sem, 0);
+ client->release_sem = 1;
+ if (lwgsm_mqtt_client_disconnect(client->mc) == lwgsmOK) {
+ res = lwgsmOK;
+ lwgsm_sys_sem_wait(&client->sync_sem, 0);
+ } else {
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_API_TRACE_WARNING,
+ "[MQTT API] Cannot close API connection\r\n");
+ }
+ client->release_sem = 0;
+ lwgsm_sys_sem_release(&client->sync_sem);
+ lwgsm_sys_mutex_unlock(&client->mutex);
+ return res;
+}
+
+/**
+ * \brief Subscribe to topic
+ * \param[in] client: MQTT API client handle
+ * \param[in] topic: Topic to subscribe on
+ * \param[in] qos: Quality of service. This parameter can be a value of \ref lwgsm_mqtt_qos_t
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+ */
+lwgsmr_t
+lwgsm_mqtt_client_api_subscribe(lwgsm_mqtt_client_api_p client, const char* topic,
+ lwgsm_mqtt_qos_t qos) {
+ lwgsmr_t res = lwgsmERR;
+
+ LWGSM_ASSERT("client != NULL", client != NULL);
+ LWGSM_ASSERT("topic != NULL", topic != NULL);
+
+ lwgsm_sys_mutex_lock(&client->mutex);
+ lwgsm_sys_sem_wait(&client->sync_sem, 0);
+ client->release_sem = 1;
+ if (lwgsm_mqtt_client_subscribe(client->mc, topic, qos, NULL) == lwgsmOK) {
+ lwgsm_sys_sem_wait(&client->sync_sem, 0);
+ res = client->sub_pub_resp;
+ } else {
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_API_TRACE_WARNING,
+ "[MQTT API] Cannot subscribe to topic %s\r\n", topic);
+ }
+ client->release_sem = 0;
+ lwgsm_sys_sem_release(&client->sync_sem);
+ lwgsm_sys_mutex_unlock(&client->mutex);
+
+ return res;
+}
+
+/**
+ * \brief Unsubscribe from topic
+ * \param[in] client: MQTT API client handle
+ * \param[in] topic: Topic to unsubscribe from
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+ */
+lwgsmr_t
+lwgsm_mqtt_client_api_unsubscribe(lwgsm_mqtt_client_api_p client, const char* topic) {
+ lwgsmr_t res = lwgsmERR;
+
+ LWGSM_ASSERT("client != NULL", client != NULL);
+ LWGSM_ASSERT("topic != NULL", topic != NULL);
+
+ lwgsm_sys_mutex_lock(&client->mutex);
+ lwgsm_sys_sem_wait(&client->sync_sem, 0);
+ client->release_sem = 1;
+ if (lwgsm_mqtt_client_unsubscribe(client->mc, topic, NULL) == lwgsmOK) {
+ lwgsm_sys_sem_wait(&client->sync_sem, 0);
+ res = client->sub_pub_resp;
+ } else {
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_API_TRACE_WARNING,
+ "[MQTT API] Cannot unsubscribe from topic %s\r\n", topic);
+ }
+ client->release_sem = 0;
+ lwgsm_sys_sem_release(&client->sync_sem);
+ lwgsm_sys_mutex_unlock(&client->mutex);
+
+ return res;
+}
+
+/**
+ * \brief Publish new packet to MQTT network
+ * \param[in] client: MQTT API client handle
+ * \param[in] topic: Topic to publish on
+ * \param[in] data: Data to send
+ * \param[in] btw: Number of bytes to send for data parameter
+ * \param[in] qos: Quality of service. This parameter can be a value of \ref lwgsm_mqtt_qos_t
+ * \param[in] retain: Set to `1` for retain flag, `0` otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+ */
+lwgsmr_t
+lwgsm_mqtt_client_api_publish(lwgsm_mqtt_client_api_p client, const char* topic, const void* data,
+ size_t btw, lwgsm_mqtt_qos_t qos, uint8_t retain) {
+ lwgsmr_t res = lwgsmERR;
+
+ LWGSM_ASSERT("client != NULL", client != NULL);
+ LWGSM_ASSERT("topic != NULL", topic != NULL);
+ LWGSM_ASSERT("data != NULL", data != NULL);
+ LWGSM_ASSERT("btw > 0", btw > 0);
+
+ lwgsm_sys_mutex_lock(&client->mutex);
+ lwgsm_sys_sem_wait(&client->sync_sem, 0);
+ client->release_sem = 1;
+ if (lwgsm_mqtt_client_publish(client->mc, topic, data, LWGSM_U16(btw), qos, retain, NULL) == lwgsmOK) {
+ lwgsm_sys_sem_wait(&client->sync_sem, 0);
+ res = client->sub_pub_resp;
+ } else {
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_API_TRACE_WARNING,
+ "[MQTT API] Cannot publish new packet\r\n");
+ }
+ client->release_sem = 0;
+ lwgsm_sys_sem_release(&client->sync_sem);
+ lwgsm_sys_mutex_unlock(&client->mutex);
+
+ return res;
+}
+
+/**
+ * \brief Check if client MQTT connection is active
+ * \param[in] client: MQTT API client handle
+ * \return `1` on success, `0` otherwise
+ */
+uint8_t
+lwgsm_mqtt_client_api_is_connected(lwgsm_mqtt_client_api_p client) {
+ uint8_t ret;
+
+ if (client == NULL) {
+ return 0;
+ }
+
+ lwgsm_sys_mutex_lock(&client->mutex);
+ ret = lwgsm_mqtt_client_is_connected(client->mc);
+ lwgsm_sys_mutex_unlock(&client->mutex);
+ return ret;
+}
+
+/**
+ * \brief Receive next packet in specific timeout time
+ * \note This function can be called from separate thread
+ * than the rest of API function, which allows you to
+ * handle receive data separated with custom timeout
+ * \param[in] client: MQTT API client handle
+ * \param[in] p: Pointer to output buffer
+ * \param[in] timeout: Maximal time to wait before function returns timeout
+ * \return \ref lwgsmOK on success, \ref lwgsmCLOSED if MQTT is closed, \ref lwgsmTIMEOUT on timeout
+ */
+lwgsmr_t
+lwgsm_mqtt_client_api_receive(lwgsm_mqtt_client_api_p client, lwgsm_mqtt_client_api_buf_p* p,
+ uint32_t timeout) {
+ LWGSM_ASSERT("client != NULL", client != NULL);
+ LWGSM_ASSERT("p != NULL", p != NULL);
+
+ *p = NULL;
+
+ /* Get new entry from mbox */
+ if (timeout == 0) {
+ if (!lwgsm_sys_mbox_getnow(&client->rcv_mbox, (void**)p)) {
+ return lwgsmTIMEOUT;
+ }
+ } else if (lwgsm_sys_mbox_get(&client->rcv_mbox, (void**)p, timeout) == LWGSM_SYS_TIMEOUT) {
+ return lwgsmTIMEOUT;
+ }
+
+ /* Check for MQTT closed event */
+ if ((uint8_t*)(*p) == (uint8_t*)&mqtt_closed) {
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MQTT_API_TRACE,
+ "[MQTT API] Closed event received from queue\r\n");
+
+ *p = NULL;
+ return lwgsmCLOSED;
+ }
+ return lwgsmOK;
+}
+
+/**
+ * \brief Free buffer memory after usage
+ * \param[in] p: Buffer to free
+ */
+void
+lwgsm_mqtt_client_api_buf_free(lwgsm_mqtt_client_api_buf_p p) {
+ lwgsm_mem_free_s((void**)&p);
+}
diff --git a/gsm_at_lib/src/apps/mqtt/gsm_mqtt_client_evt.c b/lwgsm/src/apps/mqtt/lwgsm_mqtt_client_evt.c
similarity index 85%
rename from gsm_at_lib/src/apps/mqtt/gsm_mqtt_client_evt.c
rename to lwgsm/src/apps/mqtt/lwgsm_mqtt_client_evt.c
index 5b48691d..824b23d5 100644
--- a/gsm_at_lib/src/apps/mqtt/gsm_mqtt_client_evt.c
+++ b/lwgsm/src/apps/mqtt/lwgsm_mqtt_client_evt.c
@@ -1,10 +1,10 @@
/**
- * \file gsm_mqtt_client_evt.c
+ * \file lwgsm_mqtt_client_evt.c
* \brief MQTT client event helper functions
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,10 +26,10 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#include "gsm/apps/gsm_mqtt_client_evt.h"
+#include "lwgsm/apps/lwgsm_mqtt_client_evt.h"
diff --git a/gsm_at_lib/src/include/gsm/apps/gsm_apps.h b/lwgsm/src/include/lwgsm/apps/lwgsm_apps.h
similarity index 81%
rename from gsm_at_lib/src/include/gsm/apps/gsm_apps.h
rename to lwgsm/src/include/lwgsm/apps/lwgsm_apps.h
index 7f00fb68..ce963a01 100644
--- a/gsm_at_lib/src/include/gsm/apps/gsm_apps.h
+++ b/lwgsm/src/include/lwgsm/apps/lwgsm_apps.h
@@ -1,10 +1,10 @@
/**
- * \file gsm_apps.h
+ * \file lwgsm_apps.h
* \brief Applications main header file
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,22 +26,22 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#ifndef GSM_HDR_APPS_H
-#define GSM_HDR_APPS_H
+#ifndef LWGSM_HDR_APPS_H
+#define LWGSM_HDR_APPS_H
+
+#include "lwgsm/lwgsm.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
-#include "gsm/gsm.h"
-
/**
- * \defgroup GSM_APPS Applications
+ * \defgroup LWGSM_APPS Applications
* \brief Applications based on GSM stack
* \{
*/
@@ -51,7 +51,7 @@ extern "C" {
*/
#ifdef __cplusplus
-};
+}
#endif /* __cplusplus */
-#endif /* GSM_HDR_APPS_H */
+#endif /* LWGSM_HDR_APPS_H */
diff --git a/gsm_at_lib/src/include/gsm/apps/gsm_mqtt_client.h b/lwgsm/src/include/lwgsm/apps/lwgsm_mqtt_client.h
similarity index 60%
rename from gsm_at_lib/src/include/gsm/apps/gsm_mqtt_client.h
rename to lwgsm/src/include/lwgsm/apps/lwgsm_mqtt_client.h
index f7f1c7b6..8b12fbe3 100644
--- a/gsm_at_lib/src/include/gsm/apps/gsm_mqtt_client.h
+++ b/lwgsm/src/include/lwgsm/apps/lwgsm_mqtt_client.h
@@ -1,10 +1,10 @@
/**
- * \file gsm_mqtt_client.h
+ * \file lwgsm_mqtt_client.h
* \brief MQTT client
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,24 +26,24 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#ifndef GSM_HDR_APP_MQTT_CLIENT_H
-#define GSM_HDR_APP_MQTT_CLIENT_H
+#ifndef LWGSM_HDR_APP_MQTT_CLIENT_H
+#define LWGSM_HDR_APP_MQTT_CLIENT_H
+
+#include "lwgsm/lwgsm.h"
+#include "lwgsm/apps/lwgsm_mqtt_client_evt.h"
#ifdef __cplusplus
extern "C" {
-#endif
-
-#include "gsm/gsm.h"
-#include "gsm/apps/gsm_mqtt_client_evt.h"
+#endif /* __cplusplus */
/**
- * \ingroup GSM_APPS
- * \defgroup GSM_APP_MQTT_CLIENT MQTT client
+ * \ingroup LWGSM_APPS
+ * \defgroup LWGSM_APP_MQTT_CLIENT MQTT client
* \brief MQTT client
* \{
*/
@@ -52,28 +52,28 @@ extern "C" {
* \brief Quality of service enumeration
*/
typedef enum {
- GSM_MQTT_QOS_AT_MOST_ONCE = 0x00, /*!< Delivery is not guaranteed to arrive, but can arrive `up to 1 time` = non-critical packets where losses are allowed */
- GSM_MQTT_QOS_AT_LEAST_ONCE = 0x01, /*!< Delivery is quaranteed `at least once`, but it may be delivered multiple times with the same content */
- GSM_MQTT_QOS_EXACTLY_ONCE = 0x02, /*!< Delivery is quaranteed `exactly once` = very critical packets such as billing informations or similar */
-} gsm_mqtt_qos_t;
+ LWGSM_MQTT_QOS_AT_MOST_ONCE = 0x00, /*!< Delivery is not guaranteed to arrive, but can arrive `up to 1 time` = non-critical packets where losses are allowed */
+ LWGSM_MQTT_QOS_AT_LEAST_ONCE = 0x01, /*!< Delivery is quaranteed `at least once`, but it may be delivered multiple times with the same content */
+ LWGSM_MQTT_QOS_EXACTLY_ONCE = 0x02, /*!< Delivery is quaranteed `exactly once` = very critical packets such as billing informations or similar */
+} lwgsm_mqtt_qos_t;
-struct gsm_mqtt_client;
+struct lwgsm_mqtt_client;
/**
- * \brief Pointer to \ref gsm_mqtt_client_t structure
+ * \brief Pointer to \ref lwgsm_mqtt_client_t structure
*/
-typedef struct gsm_mqtt_client* gsm_mqtt_client_p;
+typedef struct lwgsm_mqtt_client* lwgsm_mqtt_client_p;
/**
* \brief State of MQTT client
*/
typedef enum {
- GSM_MQTT_CONN_DISCONNECTED = 0x00, /*!< Connection with server is not established */
- GSM_MQTT_CONN_CONNECTING, /*!< Client is connecting to server */
- GSM_MQTT_CONN_DISCONNECTING, /*!< Client connection is disconnecting from server */
- GSM_MQTT_CONNECTING, /*!< MQTT client is connecting... CONNECT command has been sent to server */
- GSM_MQTT_CONNECTED, /*!< MQTT is fully connected and ready to send data on topics */
-} gsm_mqtt_state_t;
+ LWGSM_MQTT_CONN_DISCONNECTED = 0x00, /*!< Connection with server is not established */
+ LWGSM_MQTT_CONN_CONNECTING, /*!< Client is connecting to server */
+ LWGSM_MQTT_CONN_DISCONNECTING, /*!< Client connection is disconnecting from server */
+ LWGSM_MQTT_CONNECTING, /*!< MQTT client is connecting... CONNECT command has been sent to server */
+ LWGSM_MQTT_CONNECTED, /*!< MQTT is fully connected and ready to send data on topics */
+} lwgsm_mqtt_state_t;
/**
* \brief MQTT client information structure
@@ -89,8 +89,8 @@ typedef struct {
const char* will_topic; /*!< Will topic */
const char* will_message; /*!< Will message */
- gsm_mqtt_qos_t will_qos; /*!< Will topic quality of service */
-} gsm_mqtt_client_info_t;
+ lwgsm_mqtt_qos_t will_qos; /*!< Will topic quality of service */
+} lwgsm_mqtt_client_info_t;
/**
* \brief MQTT request object
@@ -104,56 +104,56 @@ typedef struct {
on connection before we can say "packet was sent". */
uint32_t timeout_start_time; /*!< Timeout start time in units of milliseconds */
-} gsm_mqtt_request_t;
+} lwgsm_mqtt_request_t;
/**
* \brief MQTT event types
*/
typedef enum {
- GSM_MQTT_EVT_CONNECT, /*!< MQTT client connect event */
- GSM_MQTT_EVT_SUBSCRIBE, /*!< MQTT client subscribed to specific topic */
- GSM_MQTT_EVT_UNSUBSCRIBE, /*!< MQTT client unsubscribed from specific topic */
- GSM_MQTT_EVT_PUBLISH, /*!< MQTT client publish message to server event.
- \note When publishing packet with quality of service \ref GSM_MQTT_QOS_AT_MOST_ONCE,
+ LWGSM_MQTT_EVT_CONNECT, /*!< MQTT client connect event */
+ LWGSM_MQTT_EVT_SUBSCRIBE, /*!< MQTT client subscribed to specific topic */
+ LWGSM_MQTT_EVT_UNSUBSCRIBE, /*!< MQTT client unsubscribed from specific topic */
+ LWGSM_MQTT_EVT_PUBLISH, /*!< MQTT client publish message to server event.
+ \note When publishing packet with quality of service \ref LWGSM_MQTT_QOS_AT_MOST_ONCE,
you may not receive event, even if packet was successfully sent,
- thus do not rely on this event for packet with `qos = GSM_MQTT_QOS_AT_MOST_ONCE` */
- GSM_MQTT_EVT_PUBLISH_RECV, /*!< MQTT client received a publish message from server */
- GSM_MQTT_EVT_DISCONNECT, /*!< MQTT client disconnected from MQTT server */
- GSM_MQTT_EVT_KEEP_ALIVE, /*!< MQTT keep-alive sent to server and reply received */
-} gsm_mqtt_evt_type_t;
+ thus do not rely on this event for packet with `qos = LWGSM_MQTT_QOS_AT_MOST_ONCE` */
+ LWGSM_MQTT_EVT_PUBLISH_RECV, /*!< MQTT client received a publish message from server */
+ LWGSM_MQTT_EVT_DISCONNECT, /*!< MQTT client disconnected from MQTT server */
+ LWGSM_MQTT_EVT_KEEP_ALIVE, /*!< MQTT keep-alive sent to server and reply received */
+} lwgsm_mqtt_evt_type_t;
/**
* \brief List of possible results from MQTT server when executing connect command
*/
typedef enum {
- GSM_MQTT_CONN_STATUS_ACCEPTED = 0x00, /*!< Connection accepted and ready to use */
- GSM_MQTT_CONN_STATUS_REFUSED_PROTOCOL_VERSION = 0x01, /*!< Connection Refused, unacceptable protocol version */
- GSM_MQTT_CONN_STATUS_REFUSED_ID = 0x02, /*!< Connection refused, identifier rejected */
- GSM_MQTT_CONN_STATUS_REFUSED_SERVER = 0x03, /*!< Connection refused, server unavailable */
- GSM_MQTT_CONN_STATUS_REFUSED_USER_PASS = 0x04, /*!< Connection refused, bad user name or password */
- GSM_MQTT_CONN_STATUS_REFUSED_NOT_AUTHORIZED = 0x05, /*!< Connection refused, not authorized */
- GSM_MQTT_CONN_STATUS_TCP_FAILED = 0x100, /*!< TCP connection to server was not successful */
-} gsm_mqtt_conn_status_t;
+ LWGSM_MQTT_CONN_STATUS_ACCEPTED = 0x00, /*!< Connection accepted and ready to use */
+ LWGSM_MQTT_CONN_STATUS_REFUSED_PROTOCOL_VERSION = 0x01, /*!< Connection Refused, unacceptable protocol version */
+ LWGSM_MQTT_CONN_STATUS_REFUSED_ID = 0x02, /*!< Connection refused, identifier rejected */
+ LWGSM_MQTT_CONN_STATUS_REFUSED_SERVER = 0x03, /*!< Connection refused, server unavailable */
+ LWGSM_MQTT_CONN_STATUS_REFUSED_USER_PASS = 0x04, /*!< Connection refused, bad user name or password */
+ LWGSM_MQTT_CONN_STATUS_REFUSED_NOT_AUTHORIZED = 0x05, /*!< Connection refused, not authorized */
+ LWGSM_MQTT_CONN_STATUS_TCP_FAILED = 0x100,/*!< TCP connection to server was not successful */
+} lwgsm_mqtt_conn_status_t;
/**
* \brief MQTT event structure for callback function
*/
typedef struct {
- gsm_mqtt_evt_type_t type; /*!< Event type */
+ lwgsm_mqtt_evt_type_t type; /*!< Event type */
union {
struct {
- gsm_mqtt_conn_status_t status; /*!< Connection status with MQTT */
+ lwgsm_mqtt_conn_status_t status; /*!< Connection status with MQTT */
} connect; /*!< Event for connecting to server */
struct {
uint8_t is_accepted; /*!< Status if client was accepted to MQTT prior disconnect event */
} disconnect; /*!< Event for disconnecting from server */
struct {
void* arg; /*!< User argument for callback function */
- gsmr_t res; /*!< Rgsmonse status */
+ lwgsmr_t res; /*!< Response status */
} sub_unsub_scribed; /*!< Event for (un)subscribe to/from topics */
struct {
void* arg; /*!< User argument for callback function */
- gsmr_t res; /*!< Rgsmonse status */
+ lwgsmr_t res; /*!< Response status */
} publish; /*!< Published event */
struct {
const uint8_t* topic; /*!< Pointer to topic identifier */
@@ -161,32 +161,32 @@ typedef struct {
const void* payload; /*!< Topic payload */
size_t payload_len; /*!< Length of topic payload */
uint8_t dup; /*!< Duplicate flag if message was sent again */
- gsm_mqtt_qos_t qos; /*!< Received packet quality of service */
+ lwgsm_mqtt_qos_t qos; /*!< Received packet quality of service */
} publish_recv; /*!< Publish received event */
} evt; /*!< Event data parameters */
-} gsm_mqtt_evt_t;
+} lwgsm_mqtt_evt_t;
/**
* \brief MQTT event callback function
* \param[in] client: MQTT client
* \param[in] evt: MQTT event with type and related data
*/
-typedef void (*gsm_mqtt_evt_fn)(gsm_mqtt_client_p client, gsm_mqtt_evt_t* evt);
+typedef void (*lwgsm_mqtt_evt_fn)(lwgsm_mqtt_client_p client, lwgsm_mqtt_evt_t* evt);
-gsm_mqtt_client_p gsm_mqtt_client_new(size_t tx_buff_len, size_t rx_buff_len);
-void gsm_mqtt_client_delete(gsm_mqtt_client_p client);
+lwgsm_mqtt_client_p lwgsm_mqtt_client_new(size_t tx_buff_len, size_t rx_buff_len);
+void lwgsm_mqtt_client_delete(lwgsm_mqtt_client_p client);
-gsmr_t gsm_mqtt_client_connect(gsm_mqtt_client_p client, const char* host, gsm_port_t port, gsm_mqtt_evt_fn evt_fn, const gsm_mqtt_client_info_t* info);
-gsmr_t gsm_mqtt_client_disconnect(gsm_mqtt_client_p client);
-uint8_t gsm_mqtt_client_is_connected(gsm_mqtt_client_p client);
+lwgsmr_t lwgsm_mqtt_client_connect(lwgsm_mqtt_client_p client, const char* host, lwgsm_port_t port, lwgsm_mqtt_evt_fn evt_fn, const lwgsm_mqtt_client_info_t* info);
+lwgsmr_t lwgsm_mqtt_client_disconnect(lwgsm_mqtt_client_p client);
+uint8_t lwgsm_mqtt_client_is_connected(lwgsm_mqtt_client_p client);
-gsmr_t gsm_mqtt_client_subscribe(gsm_mqtt_client_p client, const char* topic, gsm_mqtt_qos_t qos, void* arg);
-gsmr_t gsm_mqtt_client_unsubscribe(gsm_mqtt_client_p client, const char* topic, void* arg);
+lwgsmr_t lwgsm_mqtt_client_subscribe(lwgsm_mqtt_client_p client, const char* topic, lwgsm_mqtt_qos_t qos, void* arg);
+lwgsmr_t lwgsm_mqtt_client_unsubscribe(lwgsm_mqtt_client_p client, const char* topic, void* arg);
-gsmr_t gsm_mqtt_client_publish(gsm_mqtt_client_p client, const char* topic, const void* payload, uint16_t len, gsm_mqtt_qos_t qos, uint8_t retain, void* arg);
+lwgsmr_t lwgsm_mqtt_client_publish(lwgsm_mqtt_client_p client, const char* topic, const void* payload, uint16_t len, lwgsm_mqtt_qos_t qos, uint8_t retain, void* arg);
-void* gsm_mqtt_client_get_arg(gsm_mqtt_client_p client);
-void gsm_mqtt_client_set_arg(gsm_mqtt_client_p client, void* arg);
+void* lwgsm_mqtt_client_get_arg(lwgsm_mqtt_client_p client);
+void lwgsm_mqtt_client_set_arg(lwgsm_mqtt_client_p client, void* arg);
/**
* \}
@@ -194,6 +194,6 @@ void gsm_mqtt_client_set_arg(gsm_mqtt_client_p client, void* arg)
#ifdef __cplusplus
}
-#endif
+#endif /* __cplusplus */
-#endif /* GSM_HDR_APP_MQTT_CLIENT_H */
+#endif /* LWGSM_HDR_APP_MQTT_CLIENT_H */
diff --git a/lwgsm/src/include/lwgsm/apps/lwgsm_mqtt_client_api.h b/lwgsm/src/include/lwgsm/apps/lwgsm_mqtt_client_api.h
new file mode 100644
index 00000000..7684c9ab
--- /dev/null
+++ b/lwgsm/src/include/lwgsm/apps/lwgsm_mqtt_client_api.h
@@ -0,0 +1,96 @@
+/**
+ * \file lwgsm_mqtt_client_api.h
+ * \brief MQTT client API
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM - Lightweight GSM-AT library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+#ifndef LWGSM_HDR_APP_MQTT_CLIENT_API_H
+#define LWGSM_HDR_APP_MQTT_CLIENT_API_H
+
+#include "lwgsm/lwgsm.h"
+#include "lwgsm/apps/lwgsm_mqtt_client.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * \ingroup LWGSM_APPS
+ * \defgroup LWGSM_APP_MQTT_CLIENT_API MQTT client API
+ * \brief Sequential, single thread MQTT client API
+ * \{
+ */
+
+/**
+ * \brief MQTT API client structure
+ */
+struct lwgsm_mqtt_client_api;
+
+/**
+ * \brief MQTT API RX buffer
+ */
+typedef struct lwgsm_mqtt_client_api_buf {
+ char* topic; /*!< Topic data */
+ size_t topic_len; /*!< Topic length */
+ uint8_t* payload; /*!< Payload data */
+ size_t payload_len; /*!< Payload length */
+ lwgsm_mqtt_qos_t qos; /*!< Quality of service */
+} lwgsm_mqtt_client_api_buf_t;
+
+/**
+ * \brief Pointer to \ref lwgsm_mqtt_client_api structure
+ */
+typedef struct lwgsm_mqtt_client_api* lwgsm_mqtt_client_api_p;
+
+/**
+ * \brief Pointer to \ref lwgsm_mqtt_client_api_buf_t structure
+ */
+typedef struct lwgsm_mqtt_client_api_buf* lwgsm_mqtt_client_api_buf_p;
+
+lwgsm_mqtt_client_api_p lwgsm_mqtt_client_api_new(size_t tx_buff_len, size_t rx_buff_len);
+void lwgsm_mqtt_client_api_delete(lwgsm_mqtt_client_api_p client);
+lwgsm_mqtt_conn_status_t lwgsm_mqtt_client_api_connect(lwgsm_mqtt_client_api_p client, const char* host, lwgsm_port_t port, const lwgsm_mqtt_client_info_t* info);
+lwgsmr_t lwgsm_mqtt_client_api_close(lwgsm_mqtt_client_api_p client);
+lwgsmr_t lwgsm_mqtt_client_api_subscribe(lwgsm_mqtt_client_api_p client, const char* topic, lwgsm_mqtt_qos_t qos);
+lwgsmr_t lwgsm_mqtt_client_api_unsubscribe(lwgsm_mqtt_client_api_p client, const char* topic);
+lwgsmr_t lwgsm_mqtt_client_api_publish(lwgsm_mqtt_client_api_p client, const char* topic, const void* data, size_t btw, lwgsm_mqtt_qos_t qos, uint8_t retain);
+uint8_t lwgsm_mqtt_client_api_is_connected(lwgsm_mqtt_client_api_p client);
+lwgsmr_t lwgsm_mqtt_client_api_receive(lwgsm_mqtt_client_api_p client, lwgsm_mqtt_client_api_buf_p* p, uint32_t timeout);
+void lwgsm_mqtt_client_api_buf_free(lwgsm_mqtt_client_api_buf_p p);
+
+/**
+ * \}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LWGSM_HDR_APP_MQTT_CLIENT_H */
diff --git a/gsm_at_lib/src/include/gsm/apps/gsm_mqtt_client_evt.h b/lwgsm/src/include/lwgsm/apps/lwgsm_mqtt_client_evt.h
similarity index 52%
rename from gsm_at_lib/src/include/gsm/apps/gsm_mqtt_client_evt.h
rename to lwgsm/src/include/lwgsm/apps/lwgsm_mqtt_client_evt.h
index 7f6316ce..6d137961 100644
--- a/gsm_at_lib/src/include/gsm/apps/gsm_mqtt_client_evt.h
+++ b/lwgsm/src/include/lwgsm/apps/lwgsm_mqtt_client_evt.h
@@ -1,10 +1,10 @@
/**
- * \file gsm_mqtt_client_evt.h
+ * \file lwgsm_mqtt_client_evt.h
* \brief MQTT client event helper functions
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,23 +26,23 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#ifndef GSM_HDR_APP_MQTT_CLIENT_EVT_H
-#define GSM_HDR_APP_MQTT_CLIENT_EVT_H
+#ifndef LWGSM_HDR_APP_MQTT_CLIENT_EVT_H
+#define LWGSM_HDR_APP_MQTT_CLIENT_EVT_H
+
+#include "lwgsm/apps/lwgsm_mqtt_client.h"
#ifdef __cplusplus
extern "C" {
-#endif
-
-#include "gsm/apps/gsm_mqtt_client.h"
+#endif /* __cplusplus */
/**
- * \ingroup GSM_APP_MQTT_CLIENT
- * \defgroup GSM_APP_MQTT_CLIENT_EVT Event helper functions
+ * \ingroup LWGSM_APP_MQTT_CLIENT
+ * \defgroup LWGSM_APP_MQTT_CLIENT_EVT Event helper functions
* \brief Event helper functions
* \{
*/
@@ -51,38 +51,38 @@ extern "C" {
* \brief Get MQTT event type
* \param[in] client: MQTT client
* \param[in] evt: Event handle
- * \return MQTT Event type, value of \ref gsm_mqtt_evt_type_t enumeration
+ * \return MQTT Event type, value of \ref lwgsm_mqtt_evt_type_t enumeration
* \hideinitializer
*/
-#define gsm_mqtt_client_evt_get_type(client, evt) ((gsm_mqtt_evt_type_t)(evt)->type)
+#define lwgsm_mqtt_client_evt_get_type(client, evt) ((lwgsm_mqtt_evt_type_t)(evt)->type)
/**
- * \anchor GSM_APP_MQTT_CLIENT_EVT_CONNECT
+ * \anchor LWGSM_APP_MQTT_CLIENT_EVT_CONNECT
* \name Connect event
* \{
*
- * \note Use these functions on \ref GSM_MQTT_EVT_CONNECT event
+ * \note Use these functions on \ref LWGSM_MQTT_EVT_CONNECT event
*/
/**
* \brief Get connection status
* \param[in] client: MQTT client
* \param[in] evt: Event handle
- * \return Connection status. Member of \ref gsm_mqtt_conn_status_t
+ * \return Connection status. Member of \ref lwgsm_mqtt_conn_status_t
* \hideinitializer
*/
-#define gsm_mqtt_client_evt_connect_get_status(client, evt) ((gsm_mqtt_conn_status_t)(evt)->evt.connect.status)
+#define lwgsm_mqtt_client_evt_connect_get_status(client, evt) ((lwgsm_mqtt_conn_status_t)(evt)->evt.connect.status)
/**
* \}
*/
/**
- * \anchor GSM_APP_MQTT_CLIENT_EVT_DISCONNECT
+ * \anchor LWGSM_APP_MQTT_CLIENT_EVT_DISCONNECT
* \name Disconnect event
* \{
*
- * \note Use these functions on \ref GSM_MQTT_EVT_DISCONNECT event
+ * \note Use these functions on \ref LWGSM_MQTT_EVT_DISCONNECT event
*/
/**
@@ -92,66 +92,66 @@ extern "C" {
* \return `1` on success, `0` otherwise
* \hideinitializer
*/
-#define gsm_mqtt_client_evt_disconnect_is_accepted(client, evt) ((gsm_mqtt_conn_status_t)(evt)->evt.disconnect.is_accepted)
+#define lwgsm_mqtt_client_evt_disconnect_is_accepted(client, evt) ((lwgsm_mqtt_conn_status_t)(evt)->evt.disconnect.is_accepted)
/**
* \}
*/
/**
- * \anchor GSM_APP_MQTT_CLIENT_EVT_SUB_UNSUB
+ * \anchor LWGSM_APP_MQTT_CLIENT_EVT_SUB_UNSUB
* \name Subscribe/unsubscribe event
* \{
*
- * \note Use these functions on \ref GSM_MQTT_EVT_SUBSCRIBE or \ref GSM_MQTT_EVT_UNSUBSCRIBE events
+ * \note Use these functions on \ref LWGSM_MQTT_EVT_SUBSCRIBE or \ref LWGSM_MQTT_EVT_UNSUBSCRIBE events
*/
/**
- * \brief Get user argument used on \ref gsm_mqtt_client_subscribe
+ * \brief Get user argument used on \ref lwgsm_mqtt_client_subscribe
* \param[in] client: MQTT client
* \param[in] evt: Event handle
* \return User argument
* \hideinitializer
*/
-#define gsm_mqtt_client_evt_subscribe_get_argument(client, evt) ((void *)(evt)->evt.sub_unsub_scribed.arg)
+#define lwgsm_mqtt_client_evt_subscribe_get_argument(client, evt) ((void *)(evt)->evt.sub_unsub_scribed.arg)
/**
* \brief Get result of subscribe event
* \param[in] client: MQTT client
* \param[in] evt: Event handle
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
* \hideinitializer
*/
-#define gsm_mqtt_client_evt_subscribe_get_result(client, evt) ((gsmr_t)(evt)->evt.sub_unsub_scribed.res)
+#define lwgsm_mqtt_client_evt_subscribe_get_result(client, evt) ((lwgsmr_t)(evt)->evt.sub_unsub_scribed.res)
/**
- * \brief Get user argument used on \ref gsm_mqtt_client_unsubscribe
+ * \brief Get user argument used on \ref lwgsm_mqtt_client_unsubscribe
* \param[in] client: MQTT client
* \param[in] evt: Event handle
* \return User argument
* \hideinitializer
*/
-#define gsm_mqtt_client_evt_unsubscribe_get_argument(client, evt) ((void *)(evt)->evt.sub_unsub_scribed.arg)
+#define lwgsm_mqtt_client_evt_unsubscribe_get_argument(client, evt) ((void *)(evt)->evt.sub_unsub_scribed.arg)
/**
* \brief Get result of unsubscribe event
* \param[in] client: MQTT client
* \param[in] evt: Event handle
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
* \hideinitializer
*/
-#define gsm_mqtt_client_evt_unsubscribe_get_result(client, evt) ((gsmr_t)(evt)->evt.sub_unsub_scribed.res)
+#define lwgsm_mqtt_client_evt_unsubscribe_get_result(client, evt) ((lwgsmr_t)(evt)->evt.sub_unsub_scribed.res)
/**
* \}
*/
/**
- * \anchor GSM_APP_MQTT_CLIENT_EVT_PUBLISH_RECV
+ * \anchor LWGSM_APP_MQTT_CLIENT_EVT_PUBLISH_RECV
* \name Publish receive event
* \{
*
- * \note Use these functions on \ref GSM_MQTT_EVT_PUBLISH_RECV event
+ * \note Use these functions on \ref LWGSM_MQTT_EVT_PUBLISH_RECV event
*/
/**
@@ -161,7 +161,7 @@ extern "C" {
* \return Topic name
* \hideinitializer
*/
-#define gsm_mqtt_client_evt_publish_recv_get_topic(client, evt) ((const void *)(evt)->evt.publish_recv.topic)
+#define lwgsm_mqtt_client_evt_publish_recv_get_topic(client, evt) ((const void *)(evt)->evt.publish_recv.topic)
/**
* \brief Get topic length from received publish packet
@@ -170,7 +170,7 @@ extern "C" {
* \return Topic length
* \hideinitializer
*/
-#define gsm_mqtt_client_evt_publish_recv_get_topic_len(client, evt) (GSM_SZ((evt)->evt.publish_recv.topic_len))
+#define lwgsm_mqtt_client_evt_publish_recv_get_topic_len(client, evt) (LWGSM_SZ((evt)->evt.publish_recv.topic_len))
/**
* \brief Get payload from received publish packet
@@ -179,7 +179,7 @@ extern "C" {
* \return Packet payload
* \hideinitializer
*/
-#define gsm_mqtt_client_evt_publish_recv_get_payload(client, evt) ((const void *)(evt)->evt.publish_recv.payload)
+#define lwgsm_mqtt_client_evt_publish_recv_get_payload(client, evt) ((const void *)(evt)->evt.publish_recv.payload)
/**
* \brief Get payload length from received publish packet
@@ -188,7 +188,7 @@ extern "C" {
* \return Payload length
* \hideinitializer
*/
-#define gsm_mqtt_client_evt_publish_recv_get_payload_len(client, evt) (GSM_SZ((evt)->evt.publish_recv.payload_len))
+#define lwgsm_mqtt_client_evt_publish_recv_get_payload_len(client, evt) (LWGSM_SZ((evt)->evt.publish_recv.payload_len))
/**
* \brief Check if packet is duplicated
@@ -197,46 +197,46 @@ extern "C" {
* \return `1` if duplicated, `0` otherwise
* \hideinitializer
*/
-#define gsm_mqtt_client_evt_publish_recv_is_duplicate(client, evt) (GSM_U8((evt)->evt.publish_recv.dup))
+#define lwgsm_mqtt_client_evt_publish_recv_is_duplicate(client, evt) (LWGSM_U8((evt)->evt.publish_recv.dup))
/**
* \brief Get received quality of service
* \param[in] client: MQTT client
* \param[in] evt: Event handle
- * \return Member of \ref gsm_mqtt_qos_t enumeration
+ * \return Member of \ref lwgsm_mqtt_qos_t enumeration
* \hideinitializer
*/
-#define gsm_mqtt_client_evt_publish_recv_get_qos(client, evt) ((evt)->evt.publish_recv.qos)
+#define lwgsm_mqtt_client_evt_publish_recv_get_qos(client, evt) ((evt)->evt.publish_recv.qos)
/**
* \}
*/
/**
- * \anchor GSM_APP_MQTT_CLIENT_EVT_PUBLISH
+ * \anchor LWGSM_APP_MQTT_CLIENT_EVT_PUBLISH
* \name Publish event
* \{
*
- * \note Use these functions on \ref GSM_MQTT_EVT_PUBLISH event
+ * \note Use these functions on \ref LWGSM_MQTT_EVT_PUBLISH event
*/
/**
- * \brief Get user argument used on \ref gsm_mqtt_client_publish
+ * \brief Get user argument used on \ref lwgsm_mqtt_client_publish
* \param[in] client: MQTT client
* \param[in] evt: Event handle
* \return User argument
* \hideinitializer
*/
-#define gsm_mqtt_client_evt_publish_get_argument(client, evt) ((void *)(evt)->evt.publish.arg)
+#define lwgsm_mqtt_client_evt_publish_get_argument(client, evt) ((void *)(evt)->evt.publish.arg)
- /**
- * \brief Get result of publish event
- * \param[in] client: MQTT client
- * \param[in] evt: Event handle
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
- * \hideinitializer
- */
-#define gsm_mqtt_client_evt_publish_get_result(client, evt) ((gsmr_t)(evt)->evt.publish.res)
+/**
+* \brief Get result of publish event
+* \param[in] client: MQTT client
+* \param[in] evt: Event handle
+* \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+* \hideinitializer
+*/
+#define lwgsm_mqtt_client_evt_publish_get_result(client, evt) ((lwgsmr_t)(evt)->evt.publish.res)
/**
* \}
@@ -248,6 +248,6 @@ extern "C" {
#ifdef __cplusplus
}
-#endif
+#endif /* __cplusplus */
-#endif /* GSM_HDR_APP_MQTT_CLIENT_EVT_H */
+#endif /* LWGSM_HDR_APP_MQTT_CLIENT_EVT_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm.h b/lwgsm/src/include/lwgsm/lwgsm.h
similarity index 53%
rename from gsm_at_lib/src/include/gsm/gsm.h
rename to lwgsm/src/include/lwgsm/lwgsm.h
index fe3c225f..80775d6f 100644
--- a/gsm_at_lib/src/include/gsm/gsm.h
+++ b/lwgsm/src/include/lwgsm/lwgsm.h
@@ -1,10 +1,10 @@
/**
- * \file gsm.h
- * \brief GSM AT commands parser
+ * \file lwgsm.h
+ * \brief Lightweight GSM-AT library
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,40 +26,40 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#ifndef GSM_HDR_H
-#define GSM_HDR_H
+#ifndef LWGSM_HDR_H
+#define LWGSM_HDR_H
+
+/* Get most important include files */
+#include "lwgsm/lwgsm_includes.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
-/* Get most important include files */
-#include "gsm/gsm_includes.h"
-
/**
- * \defgroup GSM GSM-AT Lib
- * \brief GSM stack
+ * \defgroup LWGSM Lightweight GSM-AT parser library
+ * \brief Lightweight GSM-AT parser library
* \{
*/
-gsmr_t gsm_init(gsm_evt_fn evt_func, const uint32_t blocking);
-gsmr_t gsm_reset(const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-gsmr_t gsm_reset_with_delay(uint32_t delay, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_init(lwgsm_evt_fn evt_func, const uint32_t blocking);
+lwgsmr_t lwgsm_reset(const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_reset_with_delay(uint32_t delay, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-gsmr_t gsm_set_func_mode(uint8_t mode, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_set_func_mode(uint8_t mode, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-gsmr_t gsm_core_lock(void);
-gsmr_t gsm_core_unlock(void);
+lwgsmr_t lwgsm_core_lock(void);
+lwgsmr_t lwgsm_core_unlock(void);
-gsmr_t gsm_device_set_present(uint8_t present, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-uint8_t gsm_device_is_present(void);
+lwgsmr_t lwgsm_device_set_present(uint8_t present, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+uint8_t lwgsm_device_is_present(void);
-uint8_t gsm_delay(uint32_t ms);
+uint8_t lwgsm_delay(uint32_t ms);
/**
* \}
@@ -69,4 +69,4 @@ uint8_t gsm_delay(uint32_t ms);
}
#endif /* __cplusplus */
-#endif /* GSM_HDR_H */
+#endif /* LWGSM_HDR_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_buff.h b/lwgsm/src/include/lwgsm/lwgsm_buff.h
similarity index 79%
rename from gsm_at_lib/src/include/gsm/gsm_buff.h
rename to lwgsm/src/include/lwgsm/lwgsm_buff.h
index b746aadc..d67e2c94 100644
--- a/gsm_at_lib/src/include/gsm/gsm_buff.h
+++ b/lwgsm/src/include/lwgsm/lwgsm_buff.h
@@ -1,10 +1,10 @@
-/**
- * \file gsm_buff.h
+/**
+ * \file lwgsm_buff.h
* \brief Ring buffer manager
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,23 +26,23 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#ifndef GSM_HDR_BUFF_H
-#define GSM_HDR_BUFF_H
+#ifndef LWGSM_HDR_BUFF_H
+#define LWGSM_HDR_BUFF_H
+
+#include "lwgsm/lwgsm.h"
#ifdef __cplusplus
extern "C" {
-#endif
-
-#include "gsm/gsm.h"
+#endif /* __cplusplus */
/**
- * \ingroup GSM
- * \defgroup GSM_BUFF Ring buffer
+ * \ingroup LWGSM
+ * \defgroup LWGSM_BUFF Ring buffer
* \brief Generic ring buffer
* \{
*/
@@ -50,13 +50,13 @@ extern "C" {
/* --- Buffer unique part starts --- */
/**
* \brief Buffer function/typedef prefix string
- *
+ *
* It is used to change function names in zero time to easily re-use same library between applications.
- * Use `#define BUF_PREF(x) my_prefix_ ## x` to change all function names to (for example) `my_prefix_buff_init`
+ * Use `#define BUF_PREF(x) my_prefix_ ## x` to change all function names to (for example) `my_prefix_buff_init`
*
* \note Modification of this macro must be done in header and source file aswell
*/
-#define BUF_PREF(x) gsm_ ## x
+#define BUF_PREF(x) lwgsm_ ## x
/* --- Buffer unique part ends --- */
uint8_t BUF_PREF(buff_init)(BUF_PREF(buff_t)* buff, size_t size);
@@ -73,16 +73,16 @@ size_t BUF_PREF(buff_get_free)(BUF_PREF(buff_t)* buff);
size_t BUF_PREF(buff_get_full)(BUF_PREF(buff_t)* buff);
/* Read data block management */
-void * BUF_PREF(buff_get_linear_block_read_address)(BUF_PREF(buff_t)* buff);
+void* BUF_PREF(buff_get_linear_block_read_address)(BUF_PREF(buff_t)* buff);
size_t BUF_PREF(buff_get_linear_block_read_length)(BUF_PREF(buff_t)* buff);
size_t BUF_PREF(buff_skip)(BUF_PREF(buff_t)* buff, size_t len);
/* Write data block management */
-void * BUF_PREF(buff_get_linear_block_write_address)(BUF_PREF(buff_t)* buff);
+void* BUF_PREF(buff_get_linear_block_write_address)(BUF_PREF(buff_t)* buff);
size_t BUF_PREF(buff_get_linear_block_write_length)(BUF_PREF(buff_t)* buff);
size_t BUF_PREF(buff_advance)(BUF_PREF(buff_t)* buff, size_t len);
-#undef BUF_PREF /* Prefix not needed anymore */
+#undef BUF_PREF /* Prefix not needed anymore */
/**
* \}
@@ -90,6 +90,6 @@ size_t BUF_PREF(buff_advance)(BUF_PREF(buff_t)* buff, size_t len);
#ifdef __cplusplus
}
-#endif
+#endif /* __cplusplus */
-#endif /* GSM_HDR_BUFF_H */
+#endif /* LWGSM_HDR_BUFF_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_call.h b/lwgsm/src/include/lwgsm/lwgsm_call.h
similarity index 57%
rename from gsm_at_lib/src/include/gsm/gsm_call.h
rename to lwgsm/src/include/lwgsm/lwgsm_call.h
index 469c0a80..1dbb2ce7 100644
--- a/gsm_at_lib/src/include/gsm/gsm_call.h
+++ b/lwgsm/src/include/lwgsm/lwgsm_call.h
@@ -1,10 +1,10 @@
-/**
- * \file gsm_call.h
+/**
+ * \file lwgsm_call.h
* \brief Call API
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,33 +26,33 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#ifndef GSM_HDR_CALL_H
-#define GSM_HDR_CALL_H
+#ifndef LWGSM_HDR_CALL_H
+#define LWGSM_HDR_CALL_H
+
+#include "lwgsm/lwgsm.h"
#ifdef __cplusplus
extern "C" {
-#endif
-
-#include "gsm/gsm.h"
+#endif /* __cplusplus */
/**
- * \ingroup GSM
- * \defgroup GSM_CALL Call API
+ * \ingroup LWGSM
+ * \defgroup LWGSM_CALL Call API
* \brief Call manager
* \{
*/
-gsmr_t gsm_call_enable(const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-gsmr_t gsm_call_disable(const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_call_enable(const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_call_disable(const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-gsmr_t gsm_call_start(const char* number, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-gsmr_t gsm_call_answer(const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-gsmr_t gsm_call_hangup(const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_call_start(const char* number, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_call_answer(const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_call_hangup(const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
/**
* \}
@@ -60,6 +60,6 @@ gsmr_t gsm_call_hangup(const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg
#ifdef __cplusplus
}
-#endif
+#endif /* __cplusplus */
-#endif /* GSM_HDR_CALL_H */
+#endif /* LWGSM_HDR_CALL_H */
diff --git a/lwgsm/src/include/lwgsm/lwgsm_conn.h b/lwgsm/src/include/lwgsm/lwgsm_conn.h
new file mode 100644
index 00000000..891bd3f8
--- /dev/null
+++ b/lwgsm/src/include/lwgsm/lwgsm_conn.h
@@ -0,0 +1,78 @@
+/**
+ * \file lwgsm_conn.h
+ * \brief Connection API
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM - Lightweight GSM-AT library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+#ifndef LWGSM_HDR_CONN_H
+#define LWGSM_HDR_CONN_H
+
+#include "lwgsm/lwgsm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * \ingroup LWGSM
+ * \defgroup LWGSM_CONN Connection API
+ * \brief Connection API functions
+ * \{
+ */
+
+lwgsmr_t lwgsm_conn_start(lwgsm_conn_p* conn, lwgsm_conn_type_t type, const char* const host, lwgsm_port_t port, void* const arg, lwgsm_evt_fn conn_evt_fn, const uint32_t blocking);
+lwgsmr_t lwgsm_conn_close(lwgsm_conn_p conn, const uint32_t blocking);
+lwgsmr_t lwgsm_conn_send(lwgsm_conn_p conn, const void* data, size_t btw, size_t* const bw, const uint32_t blocking);
+lwgsmr_t lwgsm_conn_sendto(lwgsm_conn_p conn, const lwgsm_ip_t* const ip, lwgsm_port_t port, const void* data, size_t btw, size_t* bw, const uint32_t blocking);
+lwgsmr_t lwgsm_conn_set_arg(lwgsm_conn_p conn, void* const arg);
+void* lwgsm_conn_get_arg(lwgsm_conn_p conn);
+uint8_t lwgsm_conn_is_client(lwgsm_conn_p conn);
+uint8_t lwgsm_conn_is_active(lwgsm_conn_p conn);
+uint8_t lwgsm_conn_is_closed(lwgsm_conn_p conn);
+int8_t lwgsm_conn_getnum(lwgsm_conn_p conn);
+lwgsmr_t lwgsm_get_conns_status(const uint32_t blocking);
+lwgsm_conn_p lwgsm_conn_get_from_evt(lwgsm_evt_t* evt);
+lwgsmr_t lwgsm_conn_write(lwgsm_conn_p conn, const void* data, size_t btw, uint8_t flush, size_t* const mem_available);
+lwgsmr_t lwgsm_conn_recved(lwgsm_conn_p conn, lwgsm_pbuf_p pbuf);
+size_t lwgsm_conn_get_total_recved_count(lwgsm_conn_p conn);
+
+uint8_t lwgsm_conn_get_remote_ip(lwgsm_conn_p conn, lwgsm_ip_t* ip);
+lwgsm_port_t lwgsm_conn_get_remote_port(lwgsm_conn_p conn);
+lwgsm_port_t lwgsm_conn_get_local_port(lwgsm_conn_p conn);
+
+/**
+ * \}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LWGSM_HDR_CONN_H */
diff --git a/lwgsm/src/include/lwgsm/lwgsm_debug.h b/lwgsm/src/include/lwgsm/lwgsm_debug.h
new file mode 100644
index 00000000..23d47228
--- /dev/null
+++ b/lwgsm/src/include/lwgsm/lwgsm_debug.h
@@ -0,0 +1,130 @@
+/**
+ * \file lwgsm_debug.h
+ * \brief Debugging inside GSM stack
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM - Lightweight GSM-AT library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+#ifndef LWGSM_HDR_DEBUG_H
+#define LWGSM_HDR_DEBUG_H
+
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * \ingroup LWGSM
+ * \defgroup LWGSM_DEBUG Debugging support
+ * \brief Debugging support module to track stack
+ * \{
+ */
+
+#define LWGSM_DBG_ON 0x80 /*!< Indicates debug is enabled */
+#define LWGSM_DBG_OFF 0 /*!< Indicates debug is disabled */
+
+/**
+ * \anchor LWGSM_DBG_LVL
+ * \name Debug levels
+ * \brief List of debug levels
+ * \{
+ */
+
+#define LWGSM_DBG_LVL_ALL 0x00 /*!< Print all messages of all types */
+#define LWGSM_DBG_LVL_WARNING 0x01 /*!< Print warning and upper messages */
+#define LWGSM_DBG_LVL_DANGER 0x02 /*!< Print danger errors */
+#define LWGSM_DBG_LVL_SEVERE 0x03 /*!< Print severe problems affecting program flow */
+#define LWGSM_DBG_LVL_MASK 0x03 /*!< Mask for getting debug level */
+
+/**
+ * \}
+ */
+
+/**
+ * \anchor LWGSM_DBG_TYPE
+ * \name Debug types
+ * \brief List of possible debugging types
+ * \{
+ */
+
+#define LWGSM_DBG_TYPE_TRACE 0x40 /*!< Debug trace messages for program flow */
+#define LWGSM_DBG_TYPE_STATE 0x20 /*!< Debug state messages (such as state machines) */
+#define LWGSM_DBG_TYPE_ALL (LWGSM_DBG_TYPE_TRACE | LWGSM_DBG_TYPE_STATE) /*!< All debug types */
+
+/**
+ * \}
+ */
+
+#if LWGSM_CFG_DBG && !defined(LWGSM_CFG_DBG_OUT)
+#warning "LWGSM_CFG_DBG_OUT is not defined but debugging is enabled!"
+#endif
+
+#if (LWGSM_CFG_DBG && defined(LWGSM_CFG_DBG_OUT)) || __DOXYGEN__
+/**
+ * \brief Print message to the debug "window" if enabled
+ * \param[in] c: Condition if debug of specific type is enabled
+ * \param[in] fmt: Formatted string for debug
+ * \param[in] ...: Variable parameters for formatted string
+ */
+#define LWGSM_DEBUGF(c, fmt, ...) do {\
+ if (((c) & (LWGSM_DBG_ON)) && ((c) & (LWGSM_CFG_DBG_TYPES_ON)) && ((c) & LWGSM_DBG_LVL_MASK) >= (LWGSM_CFG_DBG_LVL_MIN)) { \
+ LWGSM_CFG_DBG_OUT(fmt, ## __VA_ARGS__); \
+ } \
+ } while (0)
+
+/**
+ * \brief Print message to the debug "window" if enabled when specific condition is met
+ * \param[in] c: Condition if debug of specific type is enabled
+ * \param[in] cond: Debug only if this condition is true
+ * \param[in] fmt: Formatted string for debug
+ * \param[in] ...: Variable parameters for formatted string
+ */
+#define LWGSM_DEBUGW(c, cond, fmt, ...) do {\
+ if (cond) { \
+ LWGSM_DEBUGF(c, fmt, ## __VA_ARGS__); \
+ } \
+ } while (0)
+#else
+#undef LWGSM_CFG_DBG
+#define LWGSM_CFG_DBG LWGSM_DBG_OFF
+#define LWGSM_DEBUGF(c, fmt, ...)
+#define LWGSM_DEBUGW(c, cond, fmt, ...)
+#endif /* (LWGSM_CFG_DBG && defined(LWGSM_CFG_DBG_OUT)) || __DOXYGEN__ */
+
+/**
+ * \}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LWGSM_HDR_DEBUG_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_device_info.h b/lwgsm/src/include/lwgsm/lwgsm_device_info.h
similarity index 57%
rename from gsm_at_lib/src/include/gsm/gsm_device_info.h
rename to lwgsm/src/include/lwgsm/lwgsm_device_info.h
index 46d617ac..759fe60b 100644
--- a/gsm_at_lib/src/include/gsm/gsm_device_info.h
+++ b/lwgsm/src/include/lwgsm/lwgsm_device_info.h
@@ -1,10 +1,10 @@
-/**
- * \file gsm_device_info.h
+/**
+ * \file lwgsm_device_info.h
* \brief Basic device information
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,31 +26,31 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#ifndef GSM_HDR_DEVICE_INFO_H
-#define GSM_HDR_DEVICE_INFO_H
+#ifndef LWGSM_HDR_DEVICE_INFO_H
+#define LWGSM_HDR_DEVICE_INFO_H
+
+#include "lwgsm/lwgsm.h"
#ifdef __cplusplus
extern "C" {
-#endif
-
-#include "gsm/gsm.h"
+#endif /* __cplusplus */
/**
- * \ingroup GSM
- * \defgroup GSM_DEVICE_INFO Device information
+ * \ingroup LWGSM
+ * \defgroup LWGSM_DEVICE_INFO Device information
* \brief Basic device information
* \{
*/
-gsmr_t gsm_device_get_manufacturer(char* manuf, size_t len, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-gsmr_t gsm_device_get_model(char* model, size_t len, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-gsmr_t gsm_device_get_revision(char* rev, size_t len, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-gsmr_t gsm_device_get_serial_number(char* serial, size_t len, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_device_get_manufacturer(char* manuf, size_t len, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_device_get_model(char* model, size_t len, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_device_get_revision(char* rev, size_t len, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_device_get_serial_number(char* serial, size_t len, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
/**
* \}
@@ -58,6 +58,6 @@ gsmr_t gsm_device_get_serial_number(char* serial, size_t len, const gsm_api
#ifdef __cplusplus
}
-#endif
+#endif /* __cplusplus */
-#endif /* GSM_HDR_DEVICE_INFO_H */
+#endif /* LWGSM_HDR_DEVICE_INFO_H */
diff --git a/lwgsm/src/include/lwgsm/lwgsm_evt.h b/lwgsm/src/include/lwgsm/lwgsm_evt.h
new file mode 100644
index 00000000..8d506824
--- /dev/null
+++ b/lwgsm/src/include/lwgsm/lwgsm_evt.h
@@ -0,0 +1,272 @@
+/**
+ * \file lwgsm_evt.h
+ * \brief Event helper functions
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM - Lightweight GSM-AT library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+#ifndef LWGSM_HDR_EVT_H
+#define LWGSM_HDR_EVT_H
+
+#include "lwgsm/lwgsm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * \ingroup LWGSM
+ * \defgroup LWGSM_EVT Events management
+ * \brief Event helper functions
+ * \{
+ */
+
+lwgsmr_t lwgsm_evt_register(lwgsm_evt_fn fn);
+lwgsmr_t lwgsm_evt_unregister(lwgsm_evt_fn fn);
+lwgsm_evt_type_t lwgsm_evt_get_type(lwgsm_evt_t* cc);
+
+/**
+ * \anchor LWGSM_EVT_RESET
+ * \name Reset event
+ * \brief Event helper functions for \ref LWGSM_EVT_RESET event
+ */
+
+lwgsmr_t lwgsm_evt_reset_get_result(lwgsm_evt_t* cc);
+
+/**
+ * \}
+ */
+
+/**
+ * \anchor LWGSM_EVT_RESTORE
+ * \name Restore event
+ * \brief Event helper functions for \ref LWGSM_EVT_RESTORE event
+ */
+
+lwgsmr_t lwgsm_evt_restore_get_result(lwgsm_evt_t* cc);
+
+/**
+ * \}
+ */
+
+/**
+ * \anchor LWGSM_EVT_NETWORK_OPERATOR_CURRENT
+ * \name Current network operator
+ * \brief Event helper functions for \ref LWGSM_EVT_NETWORK_OPERATOR_CURRENT event
+ */
+
+const lwgsm_operator_curr_t* lwgsm_evt_network_operator_get_current(lwgsm_evt_t* cc);
+
+/**
+ * \}
+ */
+
+/**
+ * \anchor LWGSM_EVT_CONN_RECV
+ * \name Connection data received
+ * \brief Event helper functions for \ref LWGSM_EVT_CONN_RECV event
+ */
+
+lwgsm_pbuf_p lwgsm_evt_conn_recv_get_buff(lwgsm_evt_t* cc);
+lwgsm_conn_p lwgsm_evt_conn_recv_get_conn(lwgsm_evt_t* cc);
+
+/**
+ * \}
+ */
+
+/**
+ * \anchor LWGSM_EVT_CONN_SEND
+ * \name Connection data send
+ * \brief Event helper functions for \ref LWGSM_EVT_CONN_SEND event
+ */
+
+lwgsm_conn_p lwgsm_evt_conn_send_get_conn(lwgsm_evt_t* cc);
+size_t lwgsm_evt_conn_send_get_length(lwgsm_evt_t* cc);
+lwgsmr_t lwgsm_evt_conn_send_get_result(lwgsm_evt_t* cc);
+
+/**
+ * \}
+ */
+
+/**
+ * \anchor LWGSM_EVT_CONN_ACTIVE
+ * \name Connection active
+ * \brief Event helper functions for \ref LWGSM_EVT_CONN_ACTIVE event
+ */
+
+lwgsm_conn_p lwgsm_evt_conn_active_get_conn(lwgsm_evt_t* cc);
+uint8_t lwgsm_evt_conn_active_is_client(lwgsm_evt_t* cc);
+
+/**
+ * \}
+ */
+
+/**
+ * \anchor LWGSM_EVT_CONN_CLOSE
+ * \name Connection close event
+ * \brief Event helper functions for \ref LWGSM_EVT_CONN_CLOSE event
+ */
+
+lwgsm_conn_p lwgsm_evt_conn_close_get_conn(lwgsm_evt_t* cc);
+uint8_t lwgsm_evt_conn_close_is_client(lwgsm_evt_t* cc);
+uint8_t lwgsm_evt_conn_close_is_forced(lwgsm_evt_t* cc);
+lwgsmr_t lwgsm_evt_conn_close_get_result(lwgsm_evt_t* cc);
+
+/**
+ * \}
+ */
+
+/**
+ * \anchor LWGSM_EVT_CONN_POLL
+ * \name Connection poll
+ * \brief Event helper functions for \ref LWGSM_EVT_CONN_POLL event
+ */
+
+lwgsm_conn_p lwgsm_evt_conn_poll_get_conn(lwgsm_evt_t* cc);
+
+/**
+ * \}
+ */
+
+/**
+ * \anchor LWGSM_EVT_CONN_ERROR
+ * \name Connection error
+ * \brief Event helper functions for \ref LWGSM_EVT_CONN_ERROR event
+ */
+
+lwgsmr_t lwgsm_evt_conn_error_get_error(lwgsm_evt_t* cc);
+lwgsm_conn_type_t lwgsm_evt_conn_error_get_type(lwgsm_evt_t* cc);
+const char* lwgsm_evt_conn_error_get_host(lwgsm_evt_t* cc);
+lwgsm_port_t lwgsm_evt_conn_error_get_port(lwgsm_evt_t* cc);
+void* lwgsm_evt_conn_error_get_arg(lwgsm_evt_t* cc);
+
+/**
+ * \}
+ */
+
+/**
+ * \anchor LWGSM_EVT_SIGNAL_STRENGTH
+ * \name Signal strength
+ * \brief Event helper functions for \ref LWGSM_EVT_CONN_RECV event
+ */
+
+int16_t lwgsm_evt_signal_strength_get_rssi(lwgsm_evt_t* cc);
+
+/**
+ * \}
+ */
+
+/**
+ * \anchor LWGSM_EVT_SMS_RECV
+ * \name SMS received
+ * \brief Event helper functions for \ref LWGSM_EVT_SMS_RECV event
+ */
+
+size_t lwgsm_evt_sms_recv_get_pos(lwgsm_evt_t* cc);
+lwgsm_mem_t lwgsm_evt_sms_recv_get_mem(lwgsm_evt_t* cc);
+
+/**
+ * \}
+ */
+
+/**
+ * \anchor LWGSM_EVT_SMS_READ
+ * \name SMS content read
+ * \brief Event helper functions for \ref LWGSM_EVT_SMS_READ event
+ */
+
+lwgsm_sms_entry_t* lwgsm_evt_sms_read_get_entry(lwgsm_evt_t* cc);
+lwgsmr_t lwgsm_evt_sms_read_get_result(lwgsm_evt_t* cc);
+
+/**
+ * \}
+ */
+
+/**
+ * \anchor LWGSM_EVT_SMS_SEND
+ * \name SMS send
+ * \brief Event helper functions for \ref LWGSM_EVT_SMS_SEND event
+ */
+
+lwgsmr_t lwgsm_evt_sms_send_get_result(lwgsm_evt_t* cc);
+size_t lwgsm_evt_sms_send_get_pos(lwgsm_evt_t* cc);
+
+/**
+ * \}
+ */
+
+/**
+ * \anchor LWGSM_EVT_SMS_DELETE
+ * \name SMS delete
+ * \brief Event helper functions for \ref LWGSM_EVT_SMS_DELETE event
+ */
+
+lwgsmr_t lwgsm_evt_sms_delete_get_result(lwgsm_evt_t* cc);
+size_t lwgsm_evt_sms_delete_get_pos(lwgsm_evt_t* cc);
+lwgsm_mem_t lwgsm_evt_sms_delete_get_mem(lwgsm_evt_t* cc);
+
+/**
+ * \}
+ */
+
+/**
+ * \anchor LWGSM_EVT_CALL_CHANGED
+ * \name Call status changed
+ * \brief Event helper functions for \ref LWGSM_EVT_CALL_CHANGED event
+ */
+
+const lwgsm_call_t* lwgsm_evt_call_changed_get_call(lwgsm_evt_t* cc);
+
+/**
+ * \}
+ */
+
+/**
+ * \anchor LWGSM_EVT_OPERATOR_SCAN
+ * \name Operator scan
+ * \brief Event helper functions for \ref LWGSM_EVT_OPERATOR_SCAN event
+ */
+
+lwgsmr_t lwgsm_evt_operator_scan_get_result(lwgsm_evt_t* cc);
+lwgsm_operator_t* lwgsm_evt_operator_scan_get_entries(lwgsm_evt_t* cc);
+size_t lwgsm_evt_operator_scan_get_length(lwgsm_evt_t* cc);
+
+/**
+ * \}
+ */
+
+/**
+ * \}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LWGSM_HDR_EVT_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_ftp.h b/lwgsm/src/include/lwgsm/lwgsm_ftp.h
similarity index 77%
rename from gsm_at_lib/src/include/gsm/gsm_ftp.h
rename to lwgsm/src/include/lwgsm/lwgsm_ftp.h
index 419a2e72..073aa922 100644
--- a/gsm_at_lib/src/include/gsm/gsm_ftp.h
+++ b/lwgsm/src/include/lwgsm/lwgsm_ftp.h
@@ -1,10 +1,10 @@
-/**
- * \file gsm_ftp.h
+/**
+ * \file lwgsm_ftp.h
* \brief FTP API
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,23 +26,23 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#ifndef GSM_HDR_FTP_H
-#define GSM_HDR_FTP_H
+#ifndef LWGSM_HDR_FTP_H
+#define LWGSM_HDR_FTP_H
+
+#include "lwgsm/lwgsm.h"
#ifdef __cplusplus
extern "C" {
-#endif
-
-#include "gsm/gsm.h"
+#endif /* __cplusplus */
/**
- * \ingroup GSM
- * \defgroup GSM_FTP File transfer protocol
+ * \ingroup LWGSM
+ * \defgroup LWGSM_FTP File transfer protocol
* \brief File Transfer Protocol (FTP) manager
*
* Currently it is under development
@@ -56,6 +56,6 @@ extern "C" {
#ifdef __cplusplus
}
-#endif
+#endif /* __cplusplus */
-#endif /* GSM_HDR_FTP_H */
+#endif /* LWGSM_HDR_FTP_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_http.h b/lwgsm/src/include/lwgsm/lwgsm_http.h
similarity index 77%
rename from gsm_at_lib/src/include/gsm/gsm_http.h
rename to lwgsm/src/include/lwgsm/lwgsm_http.h
index 8e0803e4..a42942d6 100644
--- a/gsm_at_lib/src/include/gsm/gsm_http.h
+++ b/lwgsm/src/include/lwgsm/lwgsm_http.h
@@ -1,10 +1,10 @@
-/**
- * \file gsm_http.h
+/**
+ * \file lwgsm_http.h
* \brief HTTP API
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,23 +26,23 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#ifndef GSM_HDR_HTTP_H
-#define GSM_HDR_HTTP_H
+#ifndef LWGSM_HDR_HTTP_H
+#define LWGSM_HDR_HTTP_H
+
+#include "lwgsm/lwgsm.h"
#ifdef __cplusplus
extern "C" {
-#endif
-
-#include "gsm/gsm.h"
+#endif /* __cplusplus */
/**
- * \ingroup GSM
- * \defgroup GSM_HTTP Hyper Text Transfer Protocol
+ * \ingroup LWGSM
+ * \defgroup LWGSM_HTTP Hyper Text Transfer Protocol
* \brief Hyper Text Transfer Protocol (HTTP) manager
* \{
*
@@ -56,6 +56,6 @@ extern "C" {
#ifdef __cplusplus
}
-#endif
+#endif /* __cplusplus */
-#endif /* GSM_HDR_HTTP_H */
+#endif /* LWGSM_HDR_HTTP_H */
diff --git a/lwgsm/src/include/lwgsm/lwgsm_includes.h b/lwgsm/src/include/lwgsm/lwgsm_includes.h
new file mode 100644
index 00000000..94c32a7c
--- /dev/null
+++ b/lwgsm/src/include/lwgsm/lwgsm_includes.h
@@ -0,0 +1,80 @@
+/**
+ * \file lwgsm_includes.h
+ * \brief All main includes
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM - Lightweight GSM-AT library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+#ifndef LWGSM_HDR_INCLUDES_H
+#define LWGSM_HDR_INCLUDES_H
+
+#include "lwgsm/lwgsm_opt.h"
+#include "lwgsm/lwgsm_typedefs.h"
+#include "lwgsm/lwgsm_buff.h"
+#include "lwgsm/lwgsm_input.h"
+#include "lwgsm/lwgsm_debug.h"
+#include "lwgsm/lwgsm_utils.h"
+#include "lwgsm/lwgsm_pbuf.h"
+#include "lwgsm/lwgsm_sim.h"
+#include "lwgsm/lwgsm_operator.h"
+#include "lwgsm/lwgsm_evt.h"
+#include "lwgsm/lwgsm_network.h"
+#include "lwgsm/lwgsm_device_info.h"
+#include "system/lwgsm_sys.h"
+
+#if LWGSM_CFG_SMS || __DOXYGEN__
+#include "lwgsm/lwgsm_sms.h"
+#endif /* LWGSM_CFG_SMS || __DOXYGEN__ */
+#if LWGSM_CFG_CALL || __DOXYGEN__
+#include "lwgsm/lwgsm_call.h"
+#endif /* LWGSM_CFG_CALL || __DOXYGEN__ */
+#if LWGSM_CFG_PHONEBOOK || __DOXYGEN__
+#include "lwgsm/lwgsm_phonebook.h"
+#endif /* LWGSM_CFG_PHONEBOOK || __DOXYGEN__ */
+#if LWGSM_CFG_CONN || __DOXYGEN__
+#include "lwgsm/lwgsm_conn.h"
+#endif /* LWGSM_CFG_CONN || __DOXYGEN__ */
+#if LWGSM_CFG_NETCONN || __DOXYGEN__
+#include "lwgsm/lwgsm_netconn.h"
+#endif /* LWGSM_CFG_NETCONN || __DOXYGEN__ */
+#if LWGSM_CFG_USSD || __DOXYGEN__
+#include "lwgsm/lwgsm_ussd.h"
+#endif /* LWGSM_CFG_USSD || __DOXYGEN__ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LWGSM_HDR_INCLUDES_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_input.h b/lwgsm/src/include/lwgsm/lwgsm_input.h
similarity index 75%
rename from gsm_at_lib/src/include/gsm/gsm_input.h
rename to lwgsm/src/include/lwgsm/lwgsm_input.h
index 3fa4c046..91216e56 100644
--- a/gsm_at_lib/src/include/gsm/gsm_input.h
+++ b/lwgsm/src/include/lwgsm/lwgsm_input.h
@@ -1,10 +1,10 @@
/**
- * \file gsm_input.h
+ * \file lwgsm_input.h
* \brief Initialization process
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,30 +26,30 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#ifndef GSM_HDR_INPUT_H
-#define GSM_HDR_INPUT_H
+#ifndef LWGSM_HDR_INPUT_H
+#define LWGSM_HDR_INPUT_H
+
+#include
+#include "lwgsm/lwgsm.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
-#include
-#include "gsm/gsm.h"
-
/**
- * \ingroup GSM
- * \defgroup GSM_INPUT Input processing
+ * \ingroup LWGSM
+ * \defgroup LWGSM_INPUT Input processing
* \brief Input function for received data
* \{
*/
-gsmr_t gsm_input(const void* data, size_t len);
-gsmr_t gsm_input_process(const void* data, size_t len);
+lwgsmr_t lwgsm_input(const void* data, size_t len);
+lwgsmr_t lwgsm_input_process(const void* data, size_t len);
/**
* \}
@@ -59,4 +59,4 @@ gsmr_t gsm_input_process(const void* data, size_t len);
}
#endif /* __cplusplus */
-#endif /* GSM_HDR_INPUT_H */
+#endif /* LWGSM_HDR_INPUT_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_int.h b/lwgsm/src/include/lwgsm/lwgsm_int.h
similarity index 84%
rename from gsm_at_lib/src/include/gsm/gsm_int.h
rename to lwgsm/src/include/lwgsm/lwgsm_int.h
index 29491d40..178996f1 100644
--- a/gsm_at_lib/src/include/gsm/gsm_int.h
+++ b/lwgsm/src/include/lwgsm/lwgsm_int.h
@@ -1,10 +1,10 @@
/**
- * \file gsm_int.h
+ * \file lwgsm_int.h
* \brief Internal functions
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,13 +26,13 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#ifndef GSM_HDR_INT_H
-#define GSM_HDR_INT_H
+#ifndef LWGSM_HDR_INT_H
+#define LWGSM_HDR_INT_H
#ifdef __cplusplus
extern "C" {
@@ -42,4 +42,4 @@ extern "C" {
}
#endif /* __cplusplus */
-#endif /* GSM_HDR_INT_H */
+#endif /* LWGSM_HDR_INT_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_mem.h b/lwgsm/src/include/lwgsm/lwgsm_mem.h
similarity index 68%
rename from gsm_at_lib/src/include/gsm/gsm_mem.h
rename to lwgsm/src/include/lwgsm/lwgsm_mem.h
index 2fdc97c3..5bee7c67 100644
--- a/gsm_at_lib/src/include/gsm/gsm_mem.h
+++ b/lwgsm/src/include/lwgsm/lwgsm_mem.h
@@ -1,10 +1,10 @@
-/**
- * \file gsm_mem.h
+/**
+ * \file lwgsm_mem.h
* \brief Memory manager
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,28 +26,28 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#ifndef GSM_HDR_MEM_H
-#define GSM_HDR_MEM_H
+#ifndef LWGSM_HDR_MEM_H
+#define LWGSM_HDR_MEM_H
+
+#include "lwgsm/lwgsm.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
-#include "gsm/gsm.h"
-
/**
- * \ingroup GSM
- * \defgroup GSM_MEM Memory manager
+ * \ingroup LWGSM
+ * \defgroup LWGSM_MEM Memory manager
* \brief Dynamic memory manager
* \{
*/
-#if !GSM_CFG_MEM_CUSTOM || __DOXYGEN__
+#if !LWGSM_CFG_MEM_CUSTOM || __DOXYGEN__
/**
* \brief Single memory region descriptor
@@ -55,17 +55,17 @@ extern "C" {
typedef struct {
void* start_addr; /*!< Start address of region */
size_t size; /*!< Size in units of bytes of region */
-} gsm_mem_region_t;
+} lwgsm_mem_region_t;
-uint8_t gsm_mem_assignmemory(const gsm_mem_region_t* regions, size_t size);
+uint8_t lwgsm_mem_assignmemory(const lwgsm_mem_region_t* regions, size_t size);
-#endif /* !GSM_CFG_MEM_CUSTOM || __DOXYGEN__ */
+#endif /* !LWGSM_CFG_MEM_CUSTOM || __DOXYGEN__ */
-void* gsm_mem_malloc(size_t size);
-void* gsm_mem_realloc(void* ptr, size_t size);
-void* gsm_mem_calloc(size_t num, size_t size);
-void gsm_mem_free(void* ptr);
-uint8_t gsm_mem_free_s(void** ptr);
+void* lwgsm_mem_malloc(size_t size);
+void* lwgsm_mem_realloc(void* ptr, size_t size);
+void* lwgsm_mem_calloc(size_t num, size_t size);
+void lwgsm_mem_free(void* ptr);
+uint8_t lwgsm_mem_free_s(void** ptr);
/**
@@ -76,4 +76,4 @@ uint8_t gsm_mem_free_s(void** ptr);
}
#endif /* __cplusplus */
-#endif /* GSM_HDR_MEM_H */
+#endif /* LWGSM_HDR_MEM_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_memories.h b/lwgsm/src/include/lwgsm/lwgsm_memories.h
similarity index 70%
rename from gsm_at_lib/src/include/gsm/gsm_memories.h
rename to lwgsm/src/include/lwgsm/lwgsm_memories.h
index c2219678..7e5d1393 100644
--- a/gsm_at_lib/src/include/gsm/gsm_memories.h
+++ b/lwgsm/src/include/lwgsm/lwgsm_memories.h
@@ -1,10 +1,10 @@
/**
- * \file gsm_memories.h
+ * \file lwgsm_memories.h
* \brief Supported GSM device memories
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,20 +26,20 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-GSM_DEV_MEMORY_ENTRY(SM_P, "SM_P")
-GSM_DEV_MEMORY_ENTRY(ME_P, "ME_P")
-GSM_DEV_MEMORY_ENTRY(SM, "SM")
-GSM_DEV_MEMORY_ENTRY(ME, "ME")
-GSM_DEV_MEMORY_ENTRY(MT, "MT")
-GSM_DEV_MEMORY_ENTRY(BM, "BM")
-GSM_DEV_MEMORY_ENTRY(SR, "SR")
-GSM_DEV_MEMORY_ENTRY(ON, "ON")
-GSM_DEV_MEMORY_ENTRY(FD, "FD")
+LWGSM_DEV_MEMORY_ENTRY(SM_P, "SM_P")
+LWGSM_DEV_MEMORY_ENTRY(ME_P, "ME_P")
+LWGSM_DEV_MEMORY_ENTRY(SM, "SM")
+LWGSM_DEV_MEMORY_ENTRY(ME, "ME")
+LWGSM_DEV_MEMORY_ENTRY(MT, "MT")
+LWGSM_DEV_MEMORY_ENTRY(BM, "BM")
+LWGSM_DEV_MEMORY_ENTRY(SR, "SR")
+LWGSM_DEV_MEMORY_ENTRY(ON, "ON")
+LWGSM_DEV_MEMORY_ENTRY(FD, "FD")
-#undef GSM_DEV_MEMORY_ENTRY
\ No newline at end of file
+#undef LWGSM_DEV_MEMORY_ENTRY
\ No newline at end of file
diff --git a/gsm_at_lib/src/include/gsm/gsm_models.h b/lwgsm/src/include/lwgsm/lwgsm_models.h
similarity index 76%
rename from gsm_at_lib/src/include/gsm/gsm_models.h
rename to lwgsm/src/include/lwgsm/lwgsm_models.h
index 9a6d9736..24c2953d 100644
--- a/gsm_at_lib/src/include/gsm/gsm_models.h
+++ b/lwgsm/src/include/lwgsm/lwgsm_models.h
@@ -1,10 +1,10 @@
/**
- * \file gsm_models.h
+ * \file lwgsm_models.h
* \brief Supported GSM devices
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,16 +26,16 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
/* Order: Device name; Device model identification, Is_2G, Is_LTE */
-GSM_DEVICE_MODEL_ENTRY(SIM800x, "SIM800", 1, 0)
-GSM_DEVICE_MODEL_ENTRY(SIM900x, "SIM900", 1, 0)
-//GSM_DEVICE_MODEL_ENTRY(SIM7000x, "SIM7000", 1, 0)
-//GSM_DEVICE_MODEL_ENTRY(SIM7020x, "SIM7020", 1, 0)
+LWGSM_DEVICE_MODEL_ENTRY(SIM800x, "SIM800", 1, 0)
+LWGSM_DEVICE_MODEL_ENTRY(SIM900x, "SIM900", 1, 0)
+//LWGSM_DEVICE_MODEL_ENTRY(SIM7000x, "SIM7000", 1, 0)
+//LWGSM_DEVICE_MODEL_ENTRY(SIM7020x, "SIM7020", 1, 0)
-#undef GSM_DEVICE_MODEL_ENTRY
\ No newline at end of file
+#undef LWGSM_DEVICE_MODEL_ENTRY
\ No newline at end of file
diff --git a/lwgsm/src/include/lwgsm/lwgsm_netconn.h b/lwgsm/src/include/lwgsm/lwgsm_netconn.h
new file mode 100644
index 00000000..9416dd0b
--- /dev/null
+++ b/lwgsm/src/include/lwgsm/lwgsm_netconn.h
@@ -0,0 +1,91 @@
+/**
+ * \file lwgsm_netconn.h
+ * \brief API functions for sequential calls
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM - Lightweight GSM-AT library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+#ifndef LWGSM_HDR_NETCONN_H
+#define LWGSM_HDR_NETCONN_H
+
+#include "lwgsm/lwgsm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * \ingroup LWGSM_API
+ * \defgroup LWGSM_NETCONN Network connection
+ * \brief Network connection
+ * \{
+ */
+
+struct lwgsm_netconn;
+
+/**
+ * \brief Netconn object structure
+ */
+typedef struct lwgsm_netconn* lwgsm_netconn_p;
+
+/**
+ * \brief Netconn connection type
+ */
+typedef enum {
+ LWGSM_NETCONN_TYPE_TCP = LWGSM_CONN_TYPE_TCP, /*!< TCP connection */
+ LWGSM_NETCONN_TYPE_UDP = LWGSM_CONN_TYPE_UDP, /*!< UDP connection */
+ LWGSM_NETCONN_TYPE_SSL = LWGSM_CONN_TYPE_SSL, /*!< TCP connection over SSL */
+} lwgsm_netconn_type_t;
+
+lwgsm_netconn_p lwgsm_netconn_new(lwgsm_netconn_type_t type);
+lwgsmr_t lwgsm_netconn_delete(lwgsm_netconn_p nc);
+lwgsmr_t lwgsm_netconn_connect(lwgsm_netconn_p nc, const char* host, lwgsm_port_t port);
+lwgsmr_t lwgsm_netconn_receive(lwgsm_netconn_p nc, lwgsm_pbuf_p* pbuf);
+lwgsmr_t lwgsm_netconn_close(lwgsm_netconn_p nc);
+int8_t lwgsm_netconn_getconnnum(lwgsm_netconn_p nc);
+void lwgsm_netconn_set_receive_timeout(lwgsm_netconn_p nc, uint32_t timeout);
+uint32_t lwgsm_netconn_get_receive_timeout(lwgsm_netconn_p nc);
+
+/* TCP only */
+lwgsmr_t lwgsm_netconn_write(lwgsm_netconn_p nc, const void* data, size_t btw);
+lwgsmr_t lwgsm_netconn_flush(lwgsm_netconn_p nc);
+
+/* UDP only */
+lwgsmr_t lwgsm_netconn_send(lwgsm_netconn_p nc, const void* data, size_t btw);
+lwgsmr_t lwgsm_netconn_sendto(lwgsm_netconn_p nc, const lwgsm_ip_t* ip, lwgsm_port_t port, const void* data, size_t btw);
+
+/**
+ * \}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LWGSM_HDR_NETCONN_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_network.h b/lwgsm/src/include/lwgsm/lwgsm_network.h
similarity index 57%
rename from gsm_at_lib/src/include/gsm/gsm_network.h
rename to lwgsm/src/include/lwgsm/lwgsm_network.h
index f773322b..2adfb785 100644
--- a/gsm_at_lib/src/include/gsm/gsm_network.h
+++ b/lwgsm/src/include/lwgsm/lwgsm_network.h
@@ -1,10 +1,10 @@
-/**
- * \file gsm_network.h
+/**
+ * \file lwgsm_network.h
* \brief Network API
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,37 +26,37 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#ifndef GSM_HDR_NETWORK_H
-#define GSM_HDR_NETWORK_H
+#ifndef LWGSM_HDR_NETWORK_H
+#define LWGSM_HDR_NETWORK_H
+
+#include "lwgsm/lwgsm.h"
#ifdef __cplusplus
extern "C" {
-#endif
-
-#include "gsm/gsm.h"
+#endif /* __cplusplus */
/**
- * \ingroup GSM
- * \defgroup GSM_NETWORK Network API
+ * \ingroup LWGSM
+ * \defgroup LWGSM_NETWORK Network API
* \brief Network manager
* \{
*/
/* Basic commands, always available */
-gsmr_t gsm_network_rssi(int16_t* rssi, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-gsm_network_reg_status_t gsm_network_get_reg_status(void);
+lwgsmr_t lwgsm_network_rssi(int16_t* rssi, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsm_network_reg_status_t lwgsm_network_get_reg_status(void);
/* TCP/IP related commands */
-gsmr_t gsm_network_attach(const char* apn, const char* user, const char* pass, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-gsmr_t gsm_network_detach(const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-uint8_t gsm_network_is_attached(void);
-gsmr_t gsm_network_copy_ip(gsm_ip_t* ip);
-gsmr_t gsm_network_check_status(const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_network_attach(const char* apn, const char* user, const char* pass, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_network_detach(const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+uint8_t lwgsm_network_is_attached(void);
+lwgsmr_t lwgsm_network_copy_ip(lwgsm_ip_t* ip);
+lwgsmr_t lwgsm_network_check_status(const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
/**
* \}
@@ -64,6 +64,6 @@ gsmr_t gsm_network_check_status(const gsm_api_cmd_evt_fn evt_fn, void* cons
#ifdef __cplusplus
}
-#endif
+#endif /* __cplusplus */
-#endif /* GSM_HDR_NETWORK_H */
+#endif /* LWGSM_HDR_NETWORK_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_network_api.h b/lwgsm/src/include/lwgsm/lwgsm_network_api.h
similarity index 65%
rename from gsm_at_lib/src/include/gsm/gsm_network_api.h
rename to lwgsm/src/include/lwgsm/lwgsm_network_api.h
index a794b2f5..2225b5e9 100644
--- a/gsm_at_lib/src/include/gsm/gsm_network_api.h
+++ b/lwgsm/src/include/lwgsm/lwgsm_network_api.h
@@ -1,10 +1,10 @@
/**
- * \file gsm_network_api.h
+ * \file lwgsm_network_api.h
* \brief API functions for multi-thread network functions
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,37 +26,30 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#ifndef GSM_HDR_NETWORK_API_H
-#define GSM_HDR_NETWORK_API_H
+#ifndef LWGSM_HDR_NETWORK_API_H
+#define LWGSM_HDR_NETWORK_API_H
+
+#include "lwgsm/lwgsm.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
-#include "gsm/gsm.h"
-
/**
- * \ingroup GSM_API
- * \defgroup GSM_NETWORK_API Network API
+ * \ingroup LWGSM_API
+ * \defgroup LWGSM_NETWORK_API Network API
* \brief Network API functions for multi-thread operations
* \{
- *
- * Its purpose is to control network attach status when multiple threads needs
- * to enable/disable network connection.
- *
- * Each thread asks to attach network connection and manager
- * controls when it is necessary to connect or disconnect.
- *
*/
-gsmr_t gsm_network_set_credentials(const char* apn, const char* user, const char* pass);
-gsmr_t gsm_network_request_attach(void);
-gsmr_t gsm_network_request_detach(void);
+lwgsmr_t lwgsm_network_set_credentials(const char* apn, const char* user, const char* pass);
+lwgsmr_t lwgsm_network_request_attach(void);
+lwgsmr_t lwgsm_network_request_detach(void);
/**
* \}
@@ -66,4 +59,4 @@ gsmr_t gsm_network_request_detach(void);
}
#endif /* __cplusplus */
-#endif /* GSM_HDR_NETWORK_API_H */
+#endif /* LWGSM_HDR_NETWORK_API_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_operator.h b/lwgsm/src/include/lwgsm/lwgsm_operator.h
similarity index 58%
rename from gsm_at_lib/src/include/gsm/gsm_operator.h
rename to lwgsm/src/include/lwgsm/lwgsm_operator.h
index a35451d7..0bfc0500 100644
--- a/gsm_at_lib/src/include/gsm/gsm_operator.h
+++ b/lwgsm/src/include/lwgsm/lwgsm_operator.h
@@ -1,10 +1,10 @@
-/**
- * \file gsm_operator.h
+/**
+ * \file lwgsm_operator.h
* \brief Operator API
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,31 +26,31 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#ifndef GSM_HDR_OPERATOR_H
-#define GSM_HDR_OPERATOR_H
+#ifndef LWGSM_HDR_OPERATOR_H
+#define LWGSM_HDR_OPERATOR_H
+
+#include "lwgsm/lwgsm.h"
#ifdef __cplusplus
extern "C" {
-#endif
-
-#include "gsm/gsm.h"
+#endif /* __cplusplus */
/**
- * \ingroup GSM
- * \defgroup GSM_OPERATOR Network operator API
+ * \ingroup LWGSM
+ * \defgroup LWGSM_OPERATOR Network operator API
* \brief network operator API
* \{
*/
-gsmr_t gsm_operator_get(gsm_operator_curr_t* curr, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-gsmr_t gsm_operator_set(gsm_operator_mode_t mode, gsm_operator_format_t format, const char* name, uint32_t num, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_operator_get(lwgsm_operator_curr_t* curr, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_operator_set(lwgsm_operator_mode_t mode, lwgsm_operator_format_t format, const char* name, uint32_t num, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-gsmr_t gsm_operator_scan(gsm_operator_t* ops, size_t opsl, size_t* opf, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_operator_scan(lwgsm_operator_t* ops, size_t opsl, size_t* opf, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
/**
* \}
@@ -58,6 +58,6 @@ gsmr_t gsm_operator_scan(gsm_operator_t* ops, size_t opsl, size_t* opf, con
#ifdef __cplusplus
}
-#endif
+#endif /* __cplusplus */
-#endif /* GSM_HDR_OPERATOR_H */
+#endif /* LWGSM_HDR_OPERATOR_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_config_default.h b/lwgsm/src/include/lwgsm/lwgsm_opt.h
similarity index 60%
rename from gsm_at_lib/src/include/gsm/gsm_config_default.h
rename to lwgsm/src/include/lwgsm/lwgsm_opt.h
index a4683197..4f7cb635 100644
--- a/gsm_at_lib/src/include/gsm/gsm_config_default.h
+++ b/lwgsm/src/include/lwgsm/lwgsm_opt.h
@@ -1,10 +1,10 @@
/**
- * \file gsm_config_default.h
- * \brief Default configuration for GSM-AT library
+ * \file lwgsm_opt.h
+ * \brief GSM-AT options
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,17 +26,22 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#ifndef GSM_HDR_DEFAULT_CONFIG_H
-#define GSM_HDR_DEFAULT_CONFIG_H
+#ifndef LWGSM_HDR_OPT_H
+#define LWGSM_HDR_OPT_H
+
+/* Include application options */
+#ifndef LWGSM_IGNORE_USER_OPTS
+#include "lwgsm_opts.h"
+#endif /* LWGSM_IGNORE_USER_OPTS */
/**
- * \defgroup GSM_CONFIG Configuration
- * \brief Configuration parameters
+ * \defgroup LWGSM_OPT Configuration
+ * \brief GSM-AT options
* \{
*
*/
@@ -46,40 +51,29 @@
*
* \note Value must be set to 1 in the current revision
*
- * \note Check \ref GSM_CONFIG_OS group for more configuration related to operating system
- *
- */
-#ifndef GSM_CFG_OS
-#define GSM_CFG_OS 1
-#endif
-
-/**
- * \brief Default system port implementation
- *
- * According to selected port, stack will automatically include appropriate file
+ * \note Check \ref LWGSM_OPT_OS group for more configuration related to operating system
*
- * Parameter can be a value of \ref GSM_SYS_PORTS choices
*/
-#ifndef GSM_CFG_SYS_PORT
-#define GSM_CFG_SYS_PORT GSM_SYS_PORT_CMSIS_OS
+#ifndef LWGSM_CFG_OS
+#define LWGSM_CFG_OS 1
#endif
/**
* \brief Enables `1` or disables `0` custom memory management functions
*
- * When set to `1`, \ref GSM_MEM block must be provided manually.
- * This includes implementation of functions \ref gsm_mem_malloc,
- * \ref gsm_mem_calloc, \ref gsm_mem_realloc and \ref gsm_mem_free
+ * When set to `1`, \ref LWGSM_MEM block must be provided manually.
+ * This includes implementation of functions \ref lwgsm_mem_malloc,
+ * \ref lwgsm_mem_calloc, \ref lwgsm_mem_realloc and \ref lwgsm_mem_free
*
* \note Function declaration follows standard C functions `malloc, calloc, realloc, free`.
- * Declaration is available in `gsm/gsm_mem.h` file. Include this file to final
+ * Declaration is available in `lwgsm/lwgsm_mem.h` file. Include this file to final
* implementation file
*
* \note When implementing custom memory allocation, it is necessary
* to take care of multiple threads accessing same resource for custom allocator
*/
-#ifndef GSM_CFG_MEM_CUSTOM
-#define GSM_CFG_MEM_CUSTOM 0
+#ifndef LWGSM_CFG_MEM_CUSTOM
+#define LWGSM_CFG_MEM_CUSTOM 0
#endif
/**
@@ -94,8 +88,8 @@
*
* \note This value must be power of `2`
*/
-#ifndef GSM_CFG_MEM_ALIGNMENT
-#define GSM_CFG_MEM_ALIGNMENT 4
+#ifndef LWGSM_CFG_MEM_ALIGNMENT
+#define LWGSM_CFG_MEM_ALIGNMENT 4
#endif
/**
@@ -104,16 +98,16 @@
* When enabled, `2` additional parameters are available in API functions.
* When command is executed, callback function with its parameter could be called when not set to `NULL`.
*/
-#ifndef GSM_CFG_USE_API_FUNC_EVT
-#define GSM_CFG_USE_API_FUNC_EVT 1
+#ifndef LWGSM_CFG_USE_API_FUNC_EVT
+#define LWGSM_CFG_USE_API_FUNC_EVT 1
#endif
/**
* \brief Maximal number of connections AT software can support on GSM device
*
*/
-#ifndef GSM_CFG_MAX_CONNS
-#define GSM_CFG_MAX_CONNS 6
+#ifndef LWGSM_CFG_MAX_CONNS
+#define LWGSM_CFG_MAX_CONNS 6
#endif
/**
@@ -124,8 +118,8 @@
* is not an issue, it should be set to maximal value (`1460`)
* to optimize data transfer speed performance
*/
-#ifndef GSM_CFG_CONN_MAX_DATA_LEN
-#define GSM_CFG_CONN_MAX_DATA_LEN 1460
+#ifndef LWGSM_CFG_CONN_MAX_DATA_LEN
+#define LWGSM_CFG_CONN_MAX_DATA_LEN 1460
#endif
/**
@@ -134,8 +128,8 @@
* Sometimes it may happen that `AT+SEND` command fails due to different problems.
* Trying to send the same data multiple times can raise chances we are successful.
*/
-#ifndef GSM_CFG_MAX_SEND_RETRIES
-#define GSM_CFG_MAX_SEND_RETRIES 3
+#ifndef LWGSM_CFG_MAX_SEND_RETRIES
+#define LWGSM_CFG_MAX_SEND_RETRIES 3
#endif
/**
@@ -143,8 +137,8 @@
*
* \note When GSM sends buffer buffer than maximal, multiple buffers are created
*/
-#ifndef GSM_CFG_IPD_MAX_BUFF_SIZE
-#define GSM_CFG_IPD_MAX_BUFF_SIZE 1460
+#ifndef LWGSM_CFG_IPD_MAX_BUFF_SIZE
+#define LWGSM_CFG_IPD_MAX_BUFF_SIZE 1460
#endif
/**
@@ -152,8 +146,8 @@
*
* \note Later, user may call API function to change to desired baudrate if necessary
*/
-#ifndef GSM_CFG_AT_PORT_BAUDRATE
-#define GSM_CFG_AT_PORT_BAUDRATE 115200
+#ifndef LWGSM_CFG_AT_PORT_BAUDRATE
+#define LWGSM_CFG_AT_PORT_BAUDRATE 115200
#endif
/**
@@ -165,42 +159,42 @@
* In case of DMA (CPU can work other tasks), buffer may be smaller as CPU
* will have more time to process all the incoming bytes
*
- * \note This parameter has no meaning when \ref GSM_CFG_INPUT_USE_PROCESS is enabled
+ * \note This parameter has no meaning when \ref LWGSM_CFG_INPUT_USE_PROCESS is enabled
*/
-#ifndef GSM_CFG_RCV_BUFF_SIZE
-#define GSM_CFG_RCV_BUFF_SIZE 0x400
+#ifndef LWGSM_CFG_RCV_BUFF_SIZE
+#define LWGSM_CFG_RCV_BUFF_SIZE 0x400
#endif
/**
- * \brief Enables `1` or disables `0` reset sequence after \ref gsm_init call
+ * \brief Enables `1` or disables `0` reset sequence after \ref lwgsm_init call
*
- * \note When this functionality is disabled, user must manually call \ref gsm_reset to send
+ * \note When this functionality is disabled, user must manually call \ref lwgsm_reset to send
* reset sequence to GSM device.
*/
-#ifndef GSM_CFG_RESET_ON_INIT
-#define GSM_CFG_RESET_ON_INIT 1
+#ifndef LWGSM_CFG_RESET_ON_INIT
+#define LWGSM_CFG_RESET_ON_INIT 1
#endif
/**
- * \brief Enables `1` or disables `0` reset sequence after \ref gsm_device_set_present call
+ * \brief Enables `1` or disables `0` reset sequence after \ref lwgsm_device_set_present call
*
- * \note When this functionality is disabled, user must manually call \ref gsm_reset to send
+ * \note When this functionality is disabled, user must manually call \ref lwgsm_reset to send
* reset sequence to GSM device.
*/
-#ifndef GSM_CFG_RESET_ON_DEVICE_PRESENT
-#define GSM_CFG_RESET_ON_DEVICE_PRESENT 1
+#ifndef LWGSM_CFG_RESET_ON_DEVICE_PRESENT
+#define LWGSM_CFG_RESET_ON_DEVICE_PRESENT 1
#endif
/**
* \brief Default delay (milliseconds unit) before sending first AT command on reset sequence
*/
-#ifndef GSM_CFG_RESET_DELAY_DEFAULT
-#define GSM_CFG_RESET_DELAY_DEFAULT 1000
+#ifndef LWGSM_CFG_RESET_DELAY_DEFAULT
+#define LWGSM_CFG_RESET_DELAY_DEFAULT 1000
#endif
/**
- * \defgroup GSM_CONFIG_DBG Debugging
+ * \defgroup LWGSM_OPT_DBG Debugging
* \brief Debugging configurations
* \{
*/
@@ -208,12 +202,12 @@
/**
* \brief Set global debug support.
*
- * Possible values are \ref GSM_DBG_ON or \ref GSM_DBG_OFF
+ * Possible values are \ref LWGSM_DBG_ON or \ref LWGSM_DBG_OFF
*
- * \note Set to \ref GSM_DBG_OFF to globally disable all debugs
+ * \note Set to \ref LWGSM_DBG_OFF to globally disable all debugs
*/
-#ifndef GSM_CFG_DBG
-#define GSM_CFG_DBG GSM_DBG_OFF
+#ifndef LWGSM_CFG_DBG
+#define LWGSM_CFG_DBG LWGSM_DBG_OFF
#endif
/**
@@ -221,119 +215,119 @@
*
* Called with format and optional parameters for printf style debug
*/
-#ifndef GSM_CFG_DBG_OUT
-#define GSM_CFG_DBG_OUT(fmt, ...) do { extern int printf( const char * format, ... ); printf(fmt, ## __VA_ARGS__); } while (0)
+#ifndef LWGSM_CFG_DBG_OUT
+#define LWGSM_CFG_DBG_OUT(fmt, ...) do { extern int printf( const char * format, ... ); printf(fmt, ## __VA_ARGS__); } while (0)
#endif
/**
* \brief Minimal debug level
*
- * Check \ref GSM_DBG_LVL for possible values
+ * Check \ref LWGSM_DBG_LVL for possible values
*/
-#ifndef GSM_CFG_DBG_LVL_MIN
-#define GSM_CFG_DBG_LVL_MIN GSM_DBG_LVL_ALL
+#ifndef LWGSM_CFG_DBG_LVL_MIN
+#define LWGSM_CFG_DBG_LVL_MIN LWGSM_DBG_LVL_ALL
#endif
/**
* \brief Enabled debug types
*
- * When debug is globally enabled with \ref GSM_CFG_DBG parameter,
+ * When debug is globally enabled with \ref LWGSM_CFG_DBG parameter,
* user must enable debug types such as TRACE or STATE messages.
*
- * Check \ref GSM_DBG_TYPE for possible options. Separate values with `bitwise OR` operator
+ * Check \ref LWGSM_DBG_TYPE for possible options. Separate values with `bitwise OR` operator
*/
-#ifndef GSM_CFG_DBG_TYPES_ON
-#define GSM_CFG_DBG_TYPES_ON 0
+#ifndef LWGSM_CFG_DBG_TYPES_ON
+#define LWGSM_CFG_DBG_TYPES_ON 0
#endif
/**
* \brief Set debug level for init function
*
- * Possible values are \ref GSM_DBG_ON or \ref GSM_DBG_OFF
+ * Possible values are \ref LWGSM_DBG_ON or \ref LWGSM_DBG_OFF
*/
-#ifndef GSM_CFG_DBG_INIT
-#define GSM_CFG_DBG_INIT GSM_DBG_OFF
+#ifndef LWGSM_CFG_DBG_INIT
+#define LWGSM_CFG_DBG_INIT LWGSM_DBG_OFF
#endif
/**
* \brief Set debug level for memory manager
*
- * Possible values are \ref GSM_DBG_ON or \ref GSM_DBG_OFF
+ * Possible values are \ref LWGSM_DBG_ON or \ref LWGSM_DBG_OFF
*/
-#ifndef GSM_CFG_DBG_MEM
-#define GSM_CFG_DBG_MEM GSM_DBG_OFF
+#ifndef LWGSM_CFG_DBG_MEM
+#define LWGSM_CFG_DBG_MEM LWGSM_DBG_OFF
#endif
/**
* \brief Set debug level for input module
*
- * Possible values are \ref GSM_DBG_ON or \ref GSM_DBG_OFF
+ * Possible values are \ref LWGSM_DBG_ON or \ref LWGSM_DBG_OFF
*/
-#ifndef GSM_CFG_DBG_INPUT
-#define GSM_CFG_DBG_INPUT GSM_DBG_OFF
+#ifndef LWGSM_CFG_DBG_INPUT
+#define LWGSM_CFG_DBG_INPUT LWGSM_DBG_OFF
#endif
/**
* \brief Set debug level for GSM threads
*
- * Possible values are \ref GSM_DBG_ON or \ref GSM_DBG_OFF
+ * Possible values are \ref LWGSM_DBG_ON or \ref LWGSM_DBG_OFF
*/
-#ifndef GSM_CFG_DBG_THREAD
-#define GSM_CFG_DBG_THREAD GSM_DBG_OFF
+#ifndef LWGSM_CFG_DBG_THREAD
+#define LWGSM_CFG_DBG_THREAD LWGSM_DBG_OFF
#endif
/**
* \brief Set debug level for asserting of input variables
*
- * Possible values are \ref GSM_DBG_ON or \ref GSM_DBG_OFF
+ * Possible values are \ref LWGSM_DBG_ON or \ref LWGSM_DBG_OFF
*/
-#ifndef GSM_CFG_DBG_ASSERT
-#define GSM_CFG_DBG_ASSERT GSM_DBG_OFF
+#ifndef LWGSM_CFG_DBG_ASSERT
+#define LWGSM_CFG_DBG_ASSERT LWGSM_DBG_OFF
#endif
/**
* \brief Set debug level for incoming data received from device
*
- * Possible values are \ref GSM_DBG_ON or \ref GSM_DBG_OFF
+ * Possible values are \ref LWGSM_DBG_ON or \ref LWGSM_DBG_OFF
*/
-#ifndef GSM_CFG_DBG_IPD
-#define GSM_CFG_DBG_IPD GSM_DBG_OFF
+#ifndef LWGSM_CFG_DBG_IPD
+#define LWGSM_CFG_DBG_IPD LWGSM_DBG_OFF
#endif
/**
* \brief Set debug level for packet buffer manager
*
- * Possible values are \ref GSM_DBG_ON or \ref GSM_DBG_OFF
+ * Possible values are \ref LWGSM_DBG_ON or \ref LWGSM_DBG_OFF
*/
-#ifndef GSM_CFG_DBG_PBUF
-#define GSM_CFG_DBG_PBUF GSM_DBG_OFF
+#ifndef LWGSM_CFG_DBG_PBUF
+#define LWGSM_CFG_DBG_PBUF LWGSM_DBG_OFF
#endif
/**
* \brief Set debug level for connections
*
- * Possible values are \ref GSM_DBG_ON or \ref GSM_DBG_OFF
+ * Possible values are \ref LWGSM_DBG_ON or \ref LWGSM_DBG_OFF
*/
-#ifndef GSM_CFG_DBG_CONN
-#define GSM_CFG_DBG_CONN GSM_DBG_OFF
+#ifndef LWGSM_CFG_DBG_CONN
+#define LWGSM_CFG_DBG_CONN LWGSM_DBG_OFF
#endif
/**
* \brief Set debug level for dynamic variable allocations
*
- * Possible values are \ref GSM_DBG_ON or \ref GSM_DBG_OFF
+ * Possible values are \ref LWGSM_DBG_ON or \ref LWGSM_DBG_OFF
*/
-#ifndef GSM_CFG_DBG_VAR
-#define GSM_CFG_DBG_VAR GSM_DBG_OFF
+#ifndef LWGSM_CFG_DBG_VAR
+#define LWGSM_CFG_DBG_VAR LWGSM_DBG_OFF
#endif
/**
* \brief Set debug level for netconn sequential API
*
- * Possible values are \ref GSM_DBG_ON or \ref GSM_DBG_OFF
+ * Possible values are \ref LWGSM_DBG_ON or \ref LWGSM_DBG_OFF
*/
-#ifndef GSM_CFG_DBG_NETCONN
-#define GSM_CFG_DBG_NETCONN GSM_DBG_OFF
+#ifndef LWGSM_CFG_DBG_NETCONN
+#define LWGSM_CFG_DBG_NETCONN LWGSM_DBG_OFF
#endif
/**
@@ -342,8 +336,8 @@
*
* \note This mode is useful when debugging GSM communication
*/
-#ifndef GSM_CFG_AT_ECHO
-#define GSM_CFG_AT_ECHO 0
+#ifndef LWGSM_CFG_AT_ECHO
+#define LWGSM_CFG_AT_ECHO 0
#endif
/**
@@ -351,7 +345,7 @@
*/
/**
- * \defgroup GSM_CONFIG_OS OS configuration
+ * \defgroup LWGSM_OPT_OS OS configuration
* \brief Operating system dependant configuration
* \{
*/
@@ -361,8 +355,8 @@
*
* Message queue is used for storing memory address to command data
*/
-#ifndef GSM_CFG_THREAD_PRODUCER_MBOX_SIZE
-#define GSM_CFG_THREAD_PRODUCER_MBOX_SIZE 16
+#ifndef LWGSM_CFG_THREAD_PRODUCER_MBOX_SIZE
+#define LWGSM_CFG_THREAD_PRODUCER_MBOX_SIZE 16
#endif
/**
@@ -370,8 +364,8 @@
*
* Message queue is used to notify processing thread about new received data on AT port
*/
-#ifndef GSM_CFG_THREAD_PROCESS_MBOX_SIZE
-#define GSM_CFG_THREAD_PROCESS_MBOX_SIZE 16
+#ifndef LWGSM_CFG_THREAD_PROCESS_MBOX_SIZE
+#define LWGSM_CFG_THREAD_PROCESS_MBOX_SIZE 16
#endif
/**
@@ -380,15 +374,15 @@
* When this mode is enabled, no overhead is included for copying data
* to receive buffer because bytes are processed directly.
*
- * \note This mode can only be used when \ref GSM_CFG_OS is enabled
+ * \note This mode can only be used when \ref LWGSM_CFG_OS is enabled
*
* \note When using this mode, separate thread must be dedicated only
* for reading data on AT port
*
* \note Best case for using this mode is if DMA receive is supported by host device
*/
-#ifndef GSM_CFG_INPUT_USE_PROCESS
-#define GSM_CFG_INPUT_USE_PROCESS 0
+#ifndef LWGSM_CFG_INPUT_USE_PROCESS
+#define LWGSM_CFG_INPUT_USE_PROCESS 0
#endif
/**
@@ -396,8 +390,8 @@
*
* It can be used to check if thread is alive.
*/
-#ifndef GSM_THREAD_PRODUCER_HOOK
-#define GSM_THREAD_PRODUCER_HOOK()
+#ifndef LWGSM_THREAD_PRODUCER_HOOK
+#define LWGSM_THREAD_PRODUCER_HOOK()
#endif
/**
@@ -405,8 +399,8 @@
*
* It can be used to check if thread is alive.
*/
-#ifndef GSM_THREAD_PROCESS_HOOK
-#define GSM_THREAD_PROCESS_HOOK()
+#ifndef LWGSM_THREAD_PROCESS_HOOK
+#define LWGSM_THREAD_PROCESS_HOOK()
#endif
/**
@@ -414,13 +408,13 @@
*/
/**
- * \defgroup GSM_CONFIG_MODULES Modules
+ * \defgroup LWGSM_OPT_MODULES Modules
* \brief Configuration of specific modules
* \{
*/
/**
- * \defgroup GSM_CONFIG_MODULES_NETCONN Netconn module
+ * \defgroup LWGSM_OPT_MODULES_NETCONN Netconn module
* \brief Configuration of netconn API module
* \{
*/
@@ -429,10 +423,10 @@
* \brief Enables `1` or disables `0` NETCONN sequential API support for OS systems
*
* \note To use this feature, OS support is mandatory.
- * \sa GSM_CFG_OS
+ * \sa LWGSM_CFG_OS
*/
-#ifndef GSM_CFG_NETCONN
-#define GSM_CFG_NETCONN 0
+#ifndef LWGSM_CFG_NETCONN
+#define LWGSM_CFG_NETCONN 0
#endif
/**
@@ -445,8 +439,8 @@
* \note Even if this option is enabled, user must still manually set timeout,
* by default time will be set to 0 which means no timeout.
*/
-#ifndef GSM_CFG_NETCONN_RECEIVE_TIMEOUT
-#define GSM_CFG_NETCONN_RECEIVE_TIMEOUT 1
+#ifndef LWGSM_CFG_NETCONN_RECEIVE_TIMEOUT
+#define LWGSM_CFG_NETCONN_RECEIVE_TIMEOUT 1
#endif
/**
@@ -454,8 +448,8 @@
*
* Defines number of maximal clients waiting in accept queue of server connection
*/
-#ifndef GSM_CFG_NETCONN_ACCEPT_QUEUE_LEN
-#define GSM_CFG_NETCONN_ACCEPT_QUEUE_LEN 5
+#ifndef LWGSM_CFG_NETCONN_ACCEPT_QUEUE_LEN
+#define LWGSM_CFG_NETCONN_ACCEPT_QUEUE_LEN 5
#endif
/**
@@ -463,8 +457,8 @@
*
* Defines maximal number of pbuf data packet references for receive
*/
-#ifndef GSM_CFG_NETCONN_RECEIVE_QUEUE_LEN
-#define GSM_CFG_NETCONN_RECEIVE_QUEUE_LEN 8
+#ifndef LWGSM_CFG_NETCONN_RECEIVE_QUEUE_LEN
+#define LWGSM_CFG_NETCONN_RECEIVE_QUEUE_LEN 8
#endif
/**
@@ -472,7 +466,7 @@
*/
/**
- * \defgroup GSM_CONFIG_MODULES_MQTT MQTT client module
+ * \defgroup LWGSM_OPT_MODULES_MQTT MQTT client module
* \brief Configuration of MQTT and MQTT API client modules
* \{
*/
@@ -481,26 +475,26 @@
* \brief Maximal number of open MQTT requests at a time
*
*/
-#ifndef GSM_CFG_MQTT_MAX_REQUESTS
-#define GSM_CFG_MQTT_MAX_REQUESTS 8
+#ifndef LWGSM_CFG_MQTT_MAX_REQUESTS
+#define LWGSM_CFG_MQTT_MAX_REQUESTS 8
#endif
/**
* \brief Set debug level for MQTT client module
*
- * Possible values are \ref GSM_DBG_ON or \ref GSM_DBG_OFF
+ * Possible values are \ref LWGSM_DBG_ON or \ref LWGSM_DBG_OFF
*/
-#ifndef GSM_CFG_DBG_MQTT
-#define GSM_CFG_DBG_MQTT GSM_DBG_OFF
+#ifndef LWGSM_CFG_DBG_MQTT
+#define LWGSM_CFG_DBG_MQTT LWGSM_DBG_OFF
#endif
/**
* \brief Set debug level for MQTT API client module
*
- * Possible values are \ref GSM_DBG_ON or \ref GSM_DBG_OFF
+ * Possible values are \ref LWGSM_DBG_ON or \ref LWGSM_DBG_OFF
*/
-#ifndef GSM_CFG_DBG_MQTT_API
-#define GSM_CFG_DBG_MQTT_API GSM_DBG_OFF
+#ifndef LWGSM_CFG_DBG_MQTT_API
+#define LWGSM_CFG_DBG_MQTT_API LWGSM_DBG_OFF
#endif
/**
@@ -514,8 +508,8 @@
* Network must be enabled to use all GPRS/LTE functions such
* as connection API, FTP, HTTP, etc.
*/
-#ifndef GSM_CFG_NETWORK
-#define GSM_CFG_NETWORK 0
+#ifndef LWGSM_CFG_NETWORK
+#define LWGSM_CFG_NETWORK 0
#endif
/**
@@ -524,76 +518,76 @@
* \note This may be used for data-only SIM cards where command might fail
* when trying to attach to network for data transfer
*/
-#ifndef GSM_CFG_NETWORK_IGNORE_CGACT_RESULT
-#define GSM_CFG_NETWORK_IGNORE_CGACT_RESULT 0
+#ifndef LWGSM_CFG_NETWORK_IGNORE_CGACT_RESULT
+#define LWGSM_CFG_NETWORK_IGNORE_CGACT_RESULT 0
#endif
/**
* \brief Enables `1` or disables `0` connection API.
*
- * \note \ref GSM_CFG_NETWORK must be enabled to use connection feature
+ * \note \ref LWGSM_CFG_NETWORK must be enabled to use connection feature
*/
-#ifndef GSM_CFG_CONN
-#define GSM_CFG_CONN 0
+#ifndef LWGSM_CFG_CONN
+#define LWGSM_CFG_CONN 0
#endif
/**
* \brief Enables `1` or disables `0` SMS API.
*
*/
-#ifndef GSM_CFG_SMS
-#define GSM_CFG_SMS 0
+#ifndef LWGSM_CFG_SMS
+#define LWGSM_CFG_SMS 0
#endif
/**
* \brief Enables `1` or disables `0` call API.
*
*/
-#ifndef GSM_CFG_CALL
-#define GSM_CFG_CALL 0
+#ifndef LWGSM_CFG_CALL
+#define LWGSM_CFG_CALL 0
#endif
/**
* \brief Enables `1` or disables `0` phonebook API.
*
*/
-#ifndef GSM_CFG_PHONEBOOK
-#define GSM_CFG_PHONEBOOK 0
+#ifndef LWGSM_CFG_PHONEBOOK
+#define LWGSM_CFG_PHONEBOOK 0
#endif
/**
* \brief Enables `1` or disables `0` HTTP API.
*
- * \note \ref GSM_CFG_NETWORK must be enabled to use connection feature
+ * \note \ref LWGSM_CFG_NETWORK must be enabled to use connection feature
*/
-#ifndef GSM_CFG_HTTP
-#define GSM_CFG_HTTP 0
+#ifndef LWGSM_CFG_HTTP
+#define LWGSM_CFG_HTTP 0
#endif
/**
* \brief Enables `1` or disables `0` FTP API.
*
- * \note \ref GSM_CFG_NETWORK must be enabled to use connection feature
+ * \note \ref LWGSM_CFG_NETWORK must be enabled to use connection feature
*/
-#ifndef GSM_CFG_FTP
-#define GSM_CFG_FTP 0
+#ifndef LWGSM_CFG_FTP
+#define LWGSM_CFG_FTP 0
#endif
/**
* \brief Enables `1` or disables `0` PING API.
*
- * \note \ref GSM_CFG_NETWORK must be enabled to use connection feature
+ * \note \ref LWGSM_CFG_NETWORK must be enabled to use connection feature
*/
-#ifndef GSM_CFG_PING
-#define GSM_CFG_PING 0
+#ifndef LWGSM_CFG_PING
+#define LWGSM_CFG_PING 0
#endif
/**
* \brief Enables `1` or disables `0` USSD API.
*
*/
-#ifndef GSM_CFG_USSD
-#define GSM_CFG_USSD 0
+#ifndef LWGSM_CFG_USSD
+#define LWGSM_CFG_USSD 0
#endif
/**
@@ -607,12 +601,12 @@
*
* \note Single poll interval applies for all connections
*/
-#ifndef GSM_CFG_CONN_POLL_INTERVAL
-#define GSM_CFG_CONN_POLL_INTERVAL 500
+#ifndef LWGSM_CFG_CONN_POLL_INTERVAL
+#define LWGSM_CFG_CONN_POLL_INTERVAL 500
#endif
/**
- * \defgroup GSM_CONFIG_STD_LIB Standard library
+ * \defgroup LWGSM_OPT_STD_LIB Standard library
* \brief Standard C library configuration
* \{
*
@@ -637,8 +631,8 @@ void * my_memcpy(void* dst, const void* src, size_t len);
* \param[in] len: Number of bytes to copy
* \return Destination memory start address
*/
-#ifndef GSM_MEMCPY
-#define GSM_MEMCPY(dst, src, len) memcpy(dst, src, len)
+#ifndef LWGSM_MEMCPY
+#define LWGSM_MEMCPY(dst, src, len) memcpy(dst, src, len)
#endif
/**
@@ -655,8 +649,8 @@ void * my_memset(void* dst, int b, size_t len);
* \param[in] len: Number of bytes to set
* \return Destination memory start address
*/
-#ifndef GSM_MEMSET
-#define GSM_MEMSET(dst, b, len) memset(dst, b, len)
+#ifndef LWGSM_MEMSET
+#define LWGSM_MEMSET(dst, b, len) memset(dst, b, len)
#endif
/**
@@ -669,12 +663,14 @@ void * my_memset(void* dst, int b, size_t len);
#if !__DOXYGEN__
-#if !GSM_CFG_OS
- #if GSM_CFG_INPUT_USE_PROCESS
- #error "GSM_CFG_INPUT_USE_PROCESS may only be enabled when OS is used!"
- #endif /* GSM_CFG_INPUT_USE_PROCESS */
-#endif /* !GSM_CFG_OS */
+#if !LWGSM_CFG_OS
+#if LWGSM_CFG_INPUT_USE_PROCESS
+#error "LWGSM_CFG_INPUT_USE_PROCESS may only be enabled when OS is used!"
+#endif /* LWGSM_CFG_INPUT_USE_PROCESS */
+#endif /* !LWGSM_CFG_OS */
#endif /* !__DOXYGEN__ */
-#endif /* GSM_HDR_DEFAULT_CONFIG_H */
+#include "lwgsm/lwgsm_debug.h"
+
+#endif /* LWGSM_HDR_OPT_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_config_template.h b/lwgsm/src/include/lwgsm/lwgsm_opts_template.h
similarity index 73%
rename from gsm_at_lib/src/include/gsm/gsm_config_template.h
rename to lwgsm/src/include/lwgsm/lwgsm_opts_template.h
index 20aa0d4a..cabb69bd 100644
--- a/gsm_at_lib/src/include/gsm/gsm_config_template.h
+++ b/lwgsm/src/include/lwgsm/lwgsm_opts_template.h
@@ -1,10 +1,10 @@
/**
- * \file gsm_config_template.h
+ * \file lwgsm_opts_template.h
* \brief Template config file
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,22 +26,19 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#ifndef GSM_HDR_CONFIG_H
-#define GSM_HDR_CONFIG_H
+#ifndef LWGSM_HDR_OPTS_H
+#define LWGSM_HDR_OPTS_H
-/* Rename this file to "gsm_config.h" for your application */
+/* Rename this file to "lwgsm_opts.h" for your application */
/*
- * Open "include/gsm/gsm_config_default.h" and
+ * Open "include/lwgsm/lwgsm_opt.h" and
* copy & replace here settings you want to change values
*/
-/* After user configuration, call default config to merge config together */
-#include "gsm/gsm_config_default.h"
-
-#endif /* GSM_HDR_CONFIG_H */
+#endif /* LWGSM_HDR_OPTS_H */
diff --git a/lwgsm/src/include/lwgsm/lwgsm_parser.h b/lwgsm/src/include/lwgsm/lwgsm_parser.h
new file mode 100644
index 00000000..34d99006
--- /dev/null
+++ b/lwgsm/src/include/lwgsm/lwgsm_parser.h
@@ -0,0 +1,76 @@
+/**
+ * \file lwgsm_parser.h
+ * \brief Parser of AT responses
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM - Lightweight GSM-AT library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+#ifndef LWGSM_HDR_PARSER_H
+#define LWGSM_HDR_PARSER_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* defined(__cplusplus) */
+
+#include "lwgsm/lwgsm.h"
+
+int32_t lwgsmi_parse_number(const char** str);
+uint8_t lwgsmi_parse_string(const char** src, char* dst, size_t dst_len, uint8_t trim);
+uint8_t lwgsmi_parse_ip(const char** src, lwgsm_ip_t* ip);
+uint8_t lwgsmi_parse_mac(const char** src, lwgsm_mac_t* mac);
+
+uint8_t lwgsmi_parse_cpin(const char* str, uint8_t send_evt);
+uint8_t lwgsmi_parse_creg(const char* str, uint8_t skip_first);
+uint8_t lwgsmi_parse_csq(const char* str);
+
+uint8_t lwgsmi_parse_cmgs(const char* str, size_t* num);
+uint8_t lwgsmi_parse_cmti(const char* str, uint8_t send_evt);
+uint8_t lwgsmi_parse_cmgr(const char* str);
+uint8_t lwgsmi_parse_cmgl(const char* str);
+
+uint8_t lwgsmi_parse_at_sdk_version(const char* str, uint32_t* version_out);
+
+uint8_t lwgsmi_parse_cops_scan(uint8_t ch, uint8_t reset);
+uint8_t lwgsmi_parse_cops(const char* str);
+uint8_t lwgsmi_parse_clcc(const char* str, uint8_t send_evt);
+
+uint8_t lwgsmi_parse_cpbs(const char* str, uint8_t opt);
+uint8_t lwgsmi_parse_cpms(const char* str, uint8_t opt);
+uint8_t lwgsmi_parse_cpbr(const char* str);
+uint8_t lwgsmi_parse_cpbf(const char* str);
+
+uint8_t lwgsmi_parse_cipstatus_conn(const char* str, uint8_t is_conn_line, uint8_t* continueScan);
+
+uint8_t lwgsmi_parse_ipd(const char* str);
+
+#if defined(__cplusplus)
+}
+#endif /* defined(__cplusplus) */
+
+#endif /* LWGSM_HDR_PARSER_H */
diff --git a/lwgsm/src/include/lwgsm/lwgsm_pbuf.h b/lwgsm/src/include/lwgsm/lwgsm_pbuf.h
new file mode 100644
index 00000000..55975302
--- /dev/null
+++ b/lwgsm/src/include/lwgsm/lwgsm_pbuf.h
@@ -0,0 +1,82 @@
+/**
+ * \file lwgsm_pbuf.h
+ * \brief Packet buffer manager
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM - Lightweight GSM-AT library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+#ifndef LWGSM_HDR_PBUF_H
+#define LWGSM_HDR_PBUF_H
+
+#include "lwgsm/lwgsm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * \ingroup LWGSM
+ * \defgroup LWGSM_PBUF Packet buffer
+ * \brief Packet buffer manager
+ * \{
+ */
+
+lwgsm_pbuf_p lwgsm_pbuf_new(size_t len);
+size_t lwgsm_pbuf_free(lwgsm_pbuf_p pbuf);
+void* lwgsm_pbuf_data(const lwgsm_pbuf_p pbuf);
+size_t lwgsm_pbuf_length(const lwgsm_pbuf_p pbuf, uint8_t tot);
+lwgsmr_t lwgsm_pbuf_take(lwgsm_pbuf_p pbuf, const void* data, size_t len, size_t offset);
+size_t lwgsm_pbuf_copy(lwgsm_pbuf_p pbuf, void* data, size_t len, size_t offset);
+
+lwgsmr_t lwgsm_pbuf_cat(lwgsm_pbuf_p head, const lwgsm_pbuf_p tail);
+lwgsmr_t lwgsm_pbuf_chain(lwgsm_pbuf_p head, lwgsm_pbuf_p tail);
+lwgsmr_t lwgsm_pbuf_ref(lwgsm_pbuf_p pbuf);
+
+uint8_t lwgsm_pbuf_get_at(const lwgsm_pbuf_p pbuf, size_t pos, uint8_t* el);
+size_t lwgsm_pbuf_memcmp(const lwgsm_pbuf_p pbuf, const void* data, size_t len, size_t offset);
+size_t lwgsm_pbuf_strcmp(const lwgsm_pbuf_p pbuf, const char* str, size_t offset);
+size_t lwgsm_pbuf_memfind(const lwgsm_pbuf_p pbuf, const void* data, size_t len, size_t off);
+size_t lwgsm_pbuf_strfind(const lwgsm_pbuf_p pbuf, const char* str, size_t off);
+
+uint8_t lwgsm_pbuf_advance(lwgsm_pbuf_p pbuf, int len);
+lwgsm_pbuf_p lwgsm_pbuf_skip(lwgsm_pbuf_p pbuf, size_t offset, size_t* new_offset);
+
+void* lwgsm_pbuf_get_linear_addr(const lwgsm_pbuf_p pbuf, size_t offset, size_t* new_len);
+
+void lwgsm_pbuf_set_ip(lwgsm_pbuf_p pbuf, const lwgsm_ip_t* ip, lwgsm_port_t port);
+
+/**
+ * \}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LWGSM_HDR_PBUF_H */
diff --git a/lwgsm/src/include/lwgsm/lwgsm_phonebook.h b/lwgsm/src/include/lwgsm/lwgsm_phonebook.h
new file mode 100644
index 00000000..8a0cc4f9
--- /dev/null
+++ b/lwgsm/src/include/lwgsm/lwgsm_phonebook.h
@@ -0,0 +1,68 @@
+/**
+ * \file lwgsm_phonebook.h
+ * \brief Phonebook API
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM - Lightweight GSM-AT library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+#ifndef LWGSM_HDR_PHONEBOOK_H
+#define LWGSM_HDR_PHONEBOOK_H
+
+#include "lwgsm/lwgsm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * \ingroup LWGSM
+ * \defgroup LWGSM_PHONEBOOK Phonebook API
+ * \brief Phonebook manager
+ * \{
+ */
+
+lwgsmr_t lwgsm_pb_enable(const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_pb_disable(const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+
+lwgsmr_t lwgsm_pb_add(lwgsm_mem_t mem, const char* name, const char* num, lwgsm_number_type_t type, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_pb_edit(lwgsm_mem_t mem, size_t pos, const char* name, const char* num, lwgsm_number_type_t type, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_pb_delete(lwgsm_mem_t mem, size_t pos, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_pb_read(lwgsm_mem_t mem, size_t pos, lwgsm_pb_entry_t* entry, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_pb_list(lwgsm_mem_t mem, size_t start_index, lwgsm_pb_entry_t* entries, size_t etr, size_t* er, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_pb_search(lwgsm_mem_t mem, const char* search, lwgsm_pb_entry_t* entries, size_t etr, size_t* er, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+
+/**
+ * \}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LWGSM_HDR_PHONEBOOK_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_ping.h b/lwgsm/src/include/lwgsm/lwgsm_ping.h
similarity index 77%
rename from gsm_at_lib/src/include/gsm/gsm_ping.h
rename to lwgsm/src/include/lwgsm/lwgsm_ping.h
index 4f4ea6b9..c0a7389f 100644
--- a/gsm_at_lib/src/include/gsm/gsm_ping.h
+++ b/lwgsm/src/include/lwgsm/lwgsm_ping.h
@@ -1,10 +1,10 @@
-/**
- * \file gsm_ping.h
+/**
+ * \file lwgsm_ping.h
* \brief PING API
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,23 +26,23 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#ifndef GSM_HDR_PING_H
-#define GSM_HDR_PING_H
+#ifndef LWGSM_HDR_PING_H
+#define LWGSM_HDR_PING_H
+
+#include "lwgsm/lwgsm.h"
#ifdef __cplusplus
extern "C" {
-#endif
-
-#include "gsm/gsm.h"
+#endif /* __cplusplus */
/**
- * \ingroup GSM
- * \defgroup GSM_PING PING API
+ * \ingroup LWGSM
+ * \defgroup LWGSM_PING PING API
* \brief PING manager
* \{
*/
@@ -53,6 +53,6 @@ extern "C" {
#ifdef __cplusplus
}
-#endif
+#endif /* __cplusplus */
-#endif /* GSM_HDR_PING_H */
+#endif /* LWGSM_HDR_PING_H */
diff --git a/lwgsm/src/include/lwgsm/lwgsm_private.h b/lwgsm/src/include/lwgsm/lwgsm_private.h
new file mode 100644
index 00000000..60fe00f0
--- /dev/null
+++ b/lwgsm/src/include/lwgsm/lwgsm_private.h
@@ -0,0 +1,803 @@
+/**
+ * \file lwgsm_private.h
+ * \brief Private structures and enumerations
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM - Lightweight GSM-AT library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+#ifndef LWGSM_HDR_PRIV_H
+#define LWGSM_HDR_PRIV_H
+
+#include "lwgsm/lwgsm.h"
+#include "lwgsm/lwgsm_typedefs.h"
+#include "lwgsm/lwgsm_debug.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * \addtogroup LWGSM_TYPEDEFS
+ * \{
+ */
+
+/**
+ * \brief List of possible messages
+ */
+typedef enum {
+ LWGSM_CMD_IDLE = 0, /*!< IDLE mode */
+
+ /* Basic AT commands */
+ LWGSM_CMD_RESET, /*!< Reset device */
+ LWGSM_CMD_RESET_DEVICE_FIRST_CMD, /*!< Reset device first driver specific command */
+ LWGSM_CMD_ATE0, /*!< Disable ECHO mode on AT commands */
+ LWGSM_CMD_ATE1, /*!< Enable ECHO mode on AT commands */
+ LWGSM_CMD_GSLP, /*!< Set GSM to sleep mode */
+ LWGSM_CMD_RESTORE, /*!< Restore GSM internal settings to default values */
+ LWGSM_CMD_UART,
+
+ LWGSM_CMD_CGACT_SET_0,
+ LWGSM_CMD_CGACT_SET_1,
+ LWGSM_CMD_CGATT_SET_0,
+ LWGSM_CMD_CGATT_SET_1,
+ LWGSM_CMD_NETWORK_ATTACH, /*!< Attach to a network */
+ LWGSM_CMD_NETWORK_DETACH, /*!< Detach from network */
+
+ LWGSM_CMD_CIPMUX_SET,
+ LWGSM_CMD_CIPRXGET_SET,
+ LWGSM_CMD_CSTT_SET,
+
+
+
+ /* AT commands according to the V.25TER */
+ LWGSM_CMD_CALL_ENABLE,
+ LWGSM_CMD_A, /*!< Re-issues the Last Command Given */
+ LWGSM_CMD_ATA, /*!< Answer an Incoming Call */
+ LWGSM_CMD_ATD, /*!< Mobile Originated Call to Dial A Number */
+ LWGSM_CMD_ATD_N, /*!< Originate Call to Phone Number in Current Memory: ATD */
+ LWGSM_CMD_ATD_STR, /*!< Originate Call to Phone Number in Memory Which Corresponds to Field "str": ATD>str */
+ LWGSM_CMD_ATDL, /*!< Redial Last Telephone Number Used */
+ LWGSM_CMD_ATE, /*!< Set Command Echo Mode */
+ LWGSM_CMD_ATH, /*!< Disconnect Existing */
+ LWGSM_CMD_ATI, /*!< Display Product Identification Information */
+ LWGSM_CMD_ATL, /*!< Set Monitor speaker */
+ LWGSM_CMD_ATM, /*!< Set Monitor Speaker Mode */
+ LWGSM_CMD_PPP, /*!< Switch from Data Mode or PPP Online Mode to Command Mode, "+++" originally */
+ LWGSM_CMD_ATO, /*!< Switch from Command Mode to Data Mode */
+ LWGSM_CMD_ATP, /*!< Select Pulse Dialing */
+ LWGSM_CMD_ATQ, /*!< Set Result Code Presentation Mode */
+ LWGSM_CMD_ATS0, /*!< Set Number of Rings before Automatically Answering the Call */
+ LWGSM_CMD_ATS3, /*!< Set Command Line Termination Character */
+ LWGSM_CMD_ATS4, /*!< Set Response Formatting Character */
+ LWGSM_CMD_ATS5, /*!< Set Command Line Editing Character */
+ LWGSM_CMD_ATS6, /*!< Pause Before Blind */
+ LWGSM_CMD_ATS7, /*!< Set Number of Seconds to Wait for Connection Completion */
+ LWGSM_CMD_ATS8, /*!< Set Number of Seconds to Wait for Comma Dial Modifier Encountered in Dial String of D Command */
+ LWGSM_CMD_ATS10, /*!< Set Disconnect Delay after Indicating the Absence of Data Carrier */
+ LWGSM_CMD_ATT, /*!< Select Tone Dialing */
+ LWGSM_CMD_ATV, /*!< TA Response Format */
+ LWGSM_CMD_ATX, /*!< Set CONNECT Result Code Format and Monitor Call Progress */
+ LWGSM_CMD_ATZ, /*!< Reset Default Configuration */
+ LWGSM_CMD_AT_C, /*!< Set DCD Function Mode, AT&C */
+ LWGSM_CMD_AT_D, /*!< Set DTR Function, AT&D */
+ LWGSM_CMD_AT_F, /*!< Factory Defined Configuration, AT&F */
+ LWGSM_CMD_AT_V, /*!< Display Current Configuration, AT&V */
+ LWGSM_CMD_AT_W, /*!< Store Active Profile, AT&W */
+ LWGSM_CMD_GCAP, /*!< Request Complete TA Capabilities List */
+ LWGSM_CMD_GMI, /*!< Request Manufacturer Identification */
+ LWGSM_CMD_GMM, /*!< Request TA Model Identification */
+ LWGSM_CMD_GMR, /*!< Request TA Revision Identification of Software Release */
+ LWGSM_CMD_GOI, /*!< Request Global Object Identification */
+ LWGSM_CMD_GSN, /*!< Request TA Serial Number Identification (IMEI) */
+ LWGSM_CMD_ICF, /*!< Set TE-TA Control Character Framing */
+ LWGSM_CMD_IFC, /*!< Set TE-TA Local Data Flow Control */
+ LWGSM_CMD_IPR, /*!< Set TE-TA Fixed Local Rate */
+ LWGSM_CMD_HVOIC, /*!< Disconnect Voice Call Only */
+
+ /* AT commands according to 3GPP TS 27.007 */
+ LWGSM_CMD_COPS_SET, /*!< Set operator */
+ LWGSM_CMD_COPS_GET, /*!< Get current operator */
+ LWGSM_CMD_COPS_GET_OPT, /*!< Get a list of available operators */
+ LWGSM_CMD_CPAS, /*!< Phone Activity Status */
+ LWGSM_CMD_CGMI_GET, /*!< Request Manufacturer Identification */
+ LWGSM_CMD_CGMM_GET, /*!< Request Model Identification */
+ LWGSM_CMD_CGMR_GET, /*!< Request TA Revision Identification of Software Release */
+ LWGSM_CMD_CGSN_GET, /*!< Request Product Serial Number Identification (Identical with +GSN) */
+
+ LWGSM_CMD_CLCC_SET, /*!< List Current Calls of ME */
+ LWGSM_CMD_CLCK, /*!< Facility Lock */
+
+ LWGSM_CMD_CACM, /*!< Accumulated Call Meter (ACM) Reset or Query */
+ LWGSM_CMD_CAMM, /*!< Accumulated Call Meter Maximum (ACM max) Set or Query */
+ LWGSM_CMD_CAOC, /*!< Advice of Charge */
+ LWGSM_CMD_CBST, /*!< Select Bearer Service Type */
+ LWGSM_CMD_CCFC, /*!< Call Forwarding Number and Conditions Control */
+ LWGSM_CMD_CCWA, /*!< Call Waiting Control */
+ LWGSM_CMD_CEER, /*!< Extended Error Report */
+ LWGSM_CMD_CSCS, /*!< Select TE Character Set */
+ LWGSM_CMD_CSTA, /*!< Select Type of Address */
+ LWGSM_CMD_CHLD, /*!< Call Hold and Multiparty */
+ LWGSM_CMD_CIMI, /*!< Request International Mobile Subscriber Identity */
+ LWGSM_CMD_CLIP, /*!< Calling Line Identification Presentation */
+ LWGSM_CMD_CLIR, /*!< Calling Line Identification Restriction */
+ LWGSM_CMD_CMEE_SET, /*!< Report Mobile Equipment Error */
+ LWGSM_CMD_COLP, /*!< Connected Line Identification Presentation */
+
+ LWGSM_CMD_PHONEBOOK_ENABLE,
+ LWGSM_CMD_CPBF, /*!< Find Phonebook Entries */
+ LWGSM_CMD_CPBR, /*!< Read Current Phonebook Entries */
+ LWGSM_CMD_CPBS_SET, /*!< Select Phonebook Memory Storage */
+ LWGSM_CMD_CPBS_GET, /*!< Get current Phonebook Memory Storage */
+ LWGSM_CMD_CPBS_GET_OPT, /*!< Get available Phonebook Memory Storages */
+ LWGSM_CMD_CPBW_SET, /*!< Write Phonebook Entry */
+ LWGSM_CMD_CPBW_GET_OPT, /*!< Get options for write Phonebook Entry */
+
+ LWGSM_CMD_SIM_PROCESS_BASIC_CMDS, /*!< Command setup, executed when SIM is in READY state */
+ LWGSM_CMD_CPIN_SET, /*!< Enter PIN */
+ LWGSM_CMD_CPIN_GET, /*!< Read current SIM status */
+ LWGSM_CMD_CPIN_ADD, /*!< Add new PIN to SIM if pin is not set */
+ LWGSM_CMD_CPIN_CHANGE, /*!< Change already active SIM */
+ LWGSM_CMD_CPIN_REMOVE, /*!< Remove current PIN */
+ LWGSM_CMD_CPUK_SET, /*!< Enter PUK and set new PIN */
+
+ LWGSM_CMD_CSQ_GET, /*!< Signal Quality Report */
+ LWGSM_CMD_CFUN_SET, /*!< Set Phone Functionality */
+ LWGSM_CMD_CFUN_GET, /*!< Get Phone Functionality */
+ LWGSM_CMD_CREG_SET, /*!< Network Registration set output */
+ LWGSM_CMD_CREG_GET, /*!< Get current network registration status */
+ LWGSM_CMD_CBC, /*!< Battery Charge */
+ LWGSM_CMD_CNUM, /*!< Subscriber Number */
+
+ LWGSM_CMD_CPWD, /*!< Change Password */
+ LWGSM_CMD_CR, /*!< Service Reporting Control */
+ LWGSM_CMD_CRC, /*!< Set Cellular Result Codes for Incoming Call Indication */
+ LWGSM_CMD_CRLP, /*!< Select Radio Link Protocol Parameters */
+ LWGSM_CMD_CRSM, /*!< Restricted SIM Access */
+ LWGSM_CMD_VTD, /*!< Tone Duration */
+ LWGSM_CMD_VTS, /*!< DTMF and Tone Generation */
+ LWGSM_CMD_CMUX, /*!< Multiplexer Control */
+ LWGSM_CMD_CPOL, /*!< Preferred Operator List */
+ LWGSM_CMD_COPN, /*!< Read Operator Names */
+ LWGSM_CMD_CCLK, /*!< Clock */
+ LWGSM_CMD_CSIM, /*!< Generic SIM Access */
+ LWGSM_CMD_CALM, /*!< Alert Sound Mode */
+ LWGSM_CMD_CALS, /*!< Alert Sound Select */
+ LWGSM_CMD_CRSL, /*!< Ringer Sound Level */
+ LWGSM_CMD_CLVL, /*!< Loud Speaker Volume Level */
+ LWGSM_CMD_CMUT, /*!< Mute Control */
+ LWGSM_CMD_CPUC, /*!< Price Per Unit and Currency Table */
+ LWGSM_CMD_CCWE, /*!< Call Meter Maximum Event */
+ LWGSM_CMD_CUSD_SET, /*!< Unstructured Supplementary Service Data, Set command */
+ LWGSM_CMD_CUSD_GET, /*!< Unstructured Supplementary Service Data, Get command */
+ LWGSM_CMD_CUSD, /*!< Unstructured Supplementary Service Data, Execute command */
+ LWGSM_CMD_CSSN, /*!< Supplementary Services Notification */
+
+ LWGSM_CMD_CIPMUX, /*!< Start Up Multi-IP Connection */
+ LWGSM_CMD_CIPSTART, /*!< Start Up TCP or UDP Connection */
+ LWGSM_CMD_CIPSEND, /*!< Send Data Through TCP or UDP Connection */
+ LWGSM_CMD_CIPQSEND, /*!< Select Data Transmitting Mode */
+ LWGSM_CMD_CIPACK, /*!< Query Previous Connection Data Transmitting State */
+ LWGSM_CMD_CIPCLOSE, /*!< Close TCP or UDP Connection */
+ LWGSM_CMD_CIPSHUT, /*!< Deactivate GPRS PDP Context */
+ LWGSM_CMD_CLPORT, /*!< Set Local Port */
+ LWGSM_CMD_CSTT, /*!< Start Task and Set APN, username, password */
+ LWGSM_CMD_CIICR, /*!< Bring Up Wireless Connection with GPRS or CSD */
+ LWGSM_CMD_CIFSR, /*!< Get Local IP Address */
+ LWGSM_CMD_CIPSTATUS, /*!< Query Current Connection Status */
+ LWGSM_CMD_CDNSCFG, /*!< Configure Domain Name Server */
+ LWGSM_CMD_CDNSGIP, /*!< Query the IP Address of Given Domain Name */
+ LWGSM_CMD_CIPHEAD, /*!< Add an IP Head at the Beginning of a Package Received */
+ LWGSM_CMD_CIPATS, /*!< Set Auto Sending Timer */
+ LWGSM_CMD_CIPSPRT, /*!< Set Prompt of greater than sign When Module Sends Data */
+ LWGSM_CMD_CIPSERVER, /*!< Configure Module as Server */
+ LWGSM_CMD_CIPCSGP, /*!< Set CSD or GPRS for Connection Mode */
+ LWGSM_CMD_CIPSRIP, /*!< Show Remote IP Address and Port When Received Data */
+ LWGSM_CMD_CIPDPDP, /*!< Set Whether to Check State of GPRS Network Timing */
+ LWGSM_CMD_CIPMODE, /*!< Select TCPIP Application Mode */
+ LWGSM_CMD_CIPCCFG, /*!< Configure Transparent Transfer Mode */
+ LWGSM_CMD_CIPSHOWTP, /*!< Display Transfer Protocol in IP Head When Received Data */
+ LWGSM_CMD_CIPUDPMODE, /*!< UDP Extended Mode */
+ LWGSM_CMD_CIPRXGET, /*!< Get Data from Network Manually */
+ LWGSM_CMD_CIPSCONT, /*!< Save TCPIP Application Context */
+ LWGSM_CMD_CIPRDTIMER, /*!< Set Remote Delay Timer */
+ LWGSM_CMD_CIPSGTXT, /*!< Select GPRS PDP context */
+ LWGSM_CMD_CIPTKA, /*!< Set TCP Keepalive Parameters */
+ LWGSM_CMD_CIPSSL, /*!< Connection SSL function */
+
+ LWGSM_CMD_SMS_ENABLE,
+ LWGSM_CMD_CMGD, /*!< Delete SMS Message */
+ LWGSM_CMD_CMGF, /*!< Select SMS Message Format */
+ LWGSM_CMD_CMGL, /*!< List SMS Messages from Preferred Store */
+ LWGSM_CMD_CMGR, /*!< Read SMS Message */
+ LWGSM_CMD_CMGS, /*!< Send SMS Message */
+ LWGSM_CMD_CMGW, /*!< Write SMS Message to Memory */
+ LWGSM_CMD_CMSS, /*!< Send SMS Message from Storage */
+ LWGSM_CMD_CMGDA, /*!< MASS SMS delete */
+ LWGSM_CMD_CNMI, /*!< New SMS Message Indications */
+ LWGSM_CMD_CPMS_SET, /*!< Set preferred SMS Message Storage */
+ LWGSM_CMD_CPMS_GET, /*!< Get preferred SMS Message Storage */
+ LWGSM_CMD_CPMS_GET_OPT, /*!< Get optional SMS message storages */
+ LWGSM_CMD_CRES, /*!< Restore SMS Settings */
+ LWGSM_CMD_CSAS, /*!< Save SMS Settings */
+ LWGSM_CMD_CSCA, /*!< SMS Service Center Address */
+ LWGSM_CMD_CSCB, /*!< Select Cell Broadcast SMS Messages */
+ LWGSM_CMD_CSDH, /*!< Show SMS Text Mode Parameters */
+ LWGSM_CMD_CSMP, /*!< Set SMS Text Mode Parameters */
+ LWGSM_CMD_CSMS, /*!< Select Message Service */
+
+ LWGSM_CMD_END, /*!< Last CMD entry */
+} lwgsm_cmd_t;
+
+/**
+ * \brief Connection structure
+ */
+typedef struct lwgsm_conn {
+ lwgsm_conn_type_t type; /*!< Connection type */
+ uint8_t num; /*!< Connection number */
+ lwgsm_ip_t remote_ip; /*!< Remote IP address */
+ lwgsm_port_t remote_port; /*!< Remote port number */
+ lwgsm_port_t local_port; /*!< Local IP address */
+ lwgsm_evt_fn evt_func; /*!< Callback function for connection */
+ void* arg; /*!< User custom argument */
+
+ uint8_t val_id; /*!< Validation ID number. It is increased each time a new connection is established.
+ It protects sending data to wrong connection in case we have data in send queue,
+ and connection was closed and active again in between. */
+
+ lwgsm_linbuff_t buff; /*!< Linear buffer structure */
+
+ size_t total_recved; /*!< Total number of bytes received */
+
+ union {
+ struct {
+ uint8_t active: 1; /*!< Status whether connection is active */
+ uint8_t client: 1; /*!< Status whether connection is in client mode */
+ uint8_t data_received: 1; /*!< Status whether first data were received on connection */
+ uint8_t in_closing: 1; /*!< Status if connection is in closing mode.
+ When in closing mode, ignore any possible received data from function */
+ uint8_t bearer: 1; /*!< Bearer used. Can be `1` or `0` */
+ } f; /*!< Connection flags */
+ } status; /*!< Connection status union with flag bits */
+} lwgsm_conn_t;
+
+/**
+ * \ingroup LWGSM_PBUF
+ * \brief Packet buffer structure
+ */
+typedef struct lwgsm_pbuf {
+ struct lwgsm_pbuf* next; /*!< Next pbuf in chain list */
+ size_t tot_len; /*!< Total length of pbuf chain */
+ size_t len; /*!< Length of payload */
+ size_t ref; /*!< Number of references to this structure */
+ uint8_t* payload; /*!< Pointer to payload memory */
+ lwgsm_ip_t ip; /*!< Remote address for received IPD data */
+ lwgsm_port_t port; /*!< Remote port for received IPD data */
+} lwgsm_pbuf_t;
+
+/**
+ * \brief Incoming network data read structure
+ */
+typedef struct {
+ uint8_t read; /*!< Set to 1 when we should process input data as connection data */
+ size_t tot_len; /*!< Total length of packet */
+ size_t rem_len; /*!< Remaining bytes to read in current +IPD statement */
+ lwgsm_conn_p conn; /*!< Pointer to connection for network data */
+
+ size_t buff_ptr; /*!< Buffer pointer to save data to.
+ When set to `NULL` while `read = 1`, reading should ignore incoming data */
+ lwgsm_pbuf_p buff; /*!< Pointer to data buffer used for receiving data */
+} lwgsm_ipd_t;
+
+/**
+ * \brief Connection result on connect command
+ */
+typedef enum {
+ LWGSM_CONN_CONNECT_UNKNOWN, /*!< No valid result */
+ LWGSM_CONN_CONNECT_OK, /*!< Connected OK */
+ LWGSM_CONN_CONNECT_ERROR, /*!< Error on connection */
+ LWGSM_CONN_CONNECT_ALREADY, /*!< Already connected */
+} lwgsm_conn_connect_res_t;
+
+/**
+ * \brief Message queue structure to share between threads
+ */
+typedef struct lwgsm_msg {
+ lwgsm_cmd_t cmd_def; /*!< Default message type received from queue */
+ lwgsm_cmd_t cmd; /*!< Since some commands can have different subcommands, sub command is used here */
+ uint8_t i; /*!< Variable to indicate order number of subcommands */
+ lwgsm_sys_sem_t sem; /*!< Semaphore for the message */
+ uint8_t is_blocking; /*!< Status if command is blocking */
+ uint32_t block_time; /*!< Maximal blocking time in units of milliseconds. Use 0 to for non-blocking call */
+ lwgsmr_t res; /*!< Result of message operation */
+ lwgsmr_t (*fn)(struct lwgsm_msg*); /*!< Processing callback function to process packet */
+
+#if LWGSM_CFG_USE_API_FUNC_EVT
+ lwgsm_api_cmd_evt_fn evt_fn; /*!< Command callback API function */
+ void* evt_arg; /*!< Command callback API callback parameter */
+#endif /* LWGSM_CFG_USE_API_FUNC_EVT */
+
+ union {
+ struct {
+ uint32_t delay; /*!< Delay to use before sending first reset AT command */
+ } reset; /*!< Reset device */
+ struct {
+ uint32_t baudrate; /*!< Baudrate for AT port */
+ } uart; /*!< UART configuration */
+
+ struct {
+ uint8_t mode; /*!< Functionality mode */
+ } cfun; /*!< Set phone functionality */
+
+ struct {
+ const char* pin; /*!< Pin code to write */
+ } cpin_enter; /*!< Enter pin code */
+ struct {
+ const char* pin; /*!< New pin code */
+ } cpin_add; /*!< Add pin code if previously wasn't set */
+ struct {
+ const char* current_pin; /*!< Current pin code */
+ const char* new_pin; /*!< New pin code */
+ } cpin_change; /*!< Change current pin code */
+ struct {
+ const char* pin; /*!< Current pin code */
+ } cpin_remove; /*!< Remove PIN code */
+ struct {
+ const char* puk; /*!< PUK code */
+ const char* pin; /*!< New PIN code */
+ } cpuk_enter; /*!< Enter PUK and new PIN */
+ struct {
+ size_t cnum_tries; /*!< Number of tries */
+ } sim_info; /*!< Get information for SIM card */
+
+ struct {
+ char* str; /*!< Pointer to output string array */
+ size_t len; /*!< Length of output string array including trailing zero memory */
+ } device_info; /*!< All kind of device info, serial number, model, manufacturer, revision */
+
+ struct {
+ int16_t* rssi; /*!< Pointer to RSSI variable */
+ } csq; /*!< Signal strength */
+ struct {
+ uint8_t read; /*!< Flag indicating we can read the COPS actual data */
+ lwgsm_operator_t* ops; /*!< Pointer to operators array */
+ size_t opsl; /*!< Length of operators array */
+ size_t opsi; /*!< Current operator index array */
+ size_t* opf; /*!< Pointer to number of operators found */
+ } cops_scan; /*!< Scan operators */
+ struct {
+ lwgsm_operator_curr_t* curr; /*!< Pointer to output current operator */
+ } cops_get; /*!< Get current operator info */
+ struct {
+ lwgsm_operator_mode_t mode; /*!< COPS mode */
+ lwgsm_operator_format_t format; /*!< Operator format to print */
+ const char* name; /*!< Short or long name, according to format */
+ uint32_t num; /*!< Number in case format is number */
+ } cops_set; /*!< Set operator settings */
+
+#if LWGSM_CFG_CONN || __DOXYGEN__
+ /* Connection based commands */
+ struct {
+ lwgsm_conn_t** conn; /*!< Pointer to pointer to save connection used */
+ const char* host; /*!< Host to use for connection */
+ lwgsm_port_t port; /*!< Remote port used for connection */
+ lwgsm_conn_type_t type; /*!< Connection type */
+ void* arg; /*!< Connection custom argument */
+ lwgsm_evt_fn evt_func; /*!< Callback function to use on connection */
+ uint8_t num; /*!< Connection number used for start */
+ lwgsm_conn_connect_res_t conn_res; /*!< Connection result status */
+ } conn_start; /*!< Structure for starting new connection */
+ struct {
+ lwgsm_conn_t* conn; /*!< Pointer to connection to close */
+ uint8_t val_id; /*!< Connection current validation ID when command was sent to queue */
+ } conn_close; /*!< Close connection */
+ struct {
+ lwgsm_conn_t* conn; /*!< Pointer to connection to send data */
+ size_t btw; /*!< Number of remaining bytes to write */
+ size_t ptr; /*!< Current write pointer for data */
+ const uint8_t* data; /*!< Data to send */
+ size_t sent; /*!< Number of bytes sent in last packet */
+ size_t sent_all; /*!< Number of bytes sent all together */
+ uint8_t tries; /*!< Number of tries used for last packet */
+ uint8_t wait_send_ok_err; /*!< Set to 1 when we wait for SEND OK or SEND ERROR */
+ const lwgsm_ip_t* remote_ip; /*!< Remote IP address for UDP connection */
+ lwgsm_port_t remote_port; /*!< Remote port address for UDP connection */
+ uint8_t fau; /*!< Free after use flag to free memory after data are sent (or not) */
+ size_t* bw; /*!< Number of bytes written so far */
+ uint8_t val_id; /*!< Connection current validation ID when command was sent to queue */
+ } conn_send; /*!< Structure to send data on connection */
+#endif /* LWGSM_CFG_CONN || __DOXYGEN__ */
+#if LWGSM_CFG_SMS || __DOXYGEN__
+ struct {
+ const char* num; /*!< Phone number */
+ const char* text; /*!< SMS content to send */
+ uint8_t format; /*!< SMS format, `0 = PDU`, `1 = text` */
+ size_t pos; /*!< Set on +CMGS response if command is OK */
+ } sms_send; /*!< Send SMS */
+ struct {
+ lwgsm_mem_t mem; /*!< Memory to read from */
+ size_t pos; /*!< SMS position in memory */
+ lwgsm_sms_entry_t* entry; /*!< Pointer to entry to write info */
+ uint8_t update; /*!< Update SMS status after read operation */
+ uint8_t format; /*!< SMS format, `0 = PDU`, `1 = text` */
+ uint8_t read; /*!< Read the data flag */
+ } sms_read; /*!< Read single SMS */
+ struct {
+ lwgsm_mem_t mem; /*!< Memory to delete from */
+ size_t pos; /*!< SMS position in memory */
+ } sms_delete; /*!< Delete SMS message */
+ struct {
+ lwgsm_sms_status_t status; /*!< SMS status to delete */
+ } sms_delete_all; /*!< Mass delete SMS messages */
+ struct {
+ lwgsm_mem_t mem; /*!< Memory to use for read */
+ lwgsm_sms_status_t status; /*!< SMS entries status */
+ lwgsm_sms_entry_t* entries; /*!< Pointer to entries */
+ size_t etr; /*!< Entries to read (array length) */
+ size_t ei; /*!< Current entry index in array */
+ size_t* er; /*!< Final entries read pointer for user */
+ uint8_t update; /*!< Update SMS status after read operation */
+ uint8_t format; /*!< SMS format, `0 = PDU`, `1 = text` */
+ uint8_t read; /*!< Read the data flag */
+ } sms_list; /*!< List SMS messages */
+ struct {
+ lwgsm_mem_t mem[3]; /*!< Array of memories */
+ } sms_memory; /*!< Set preferred memories */
+#endif /* LWGSM_CFG_SMS || __DOXYGEN__ */
+#if LWGSM_CFG_CALL || __DOXYGEN__
+ struct {
+ const char* number; /*!< Phone number to dial */
+ } call_start; /*!< Start a new call */
+#endif /* LWGSM_CFG_CALL || __DOXYGEN__ */
+#if LWGSM_CFG_PHONEBOOK || __DOXYGEN__
+ struct {
+ lwgsm_mem_t mem; /*!< Memory to use */
+ size_t pos; /*!< Memory position. Set to 0 to use new one or SIZE_T MAX to delete entry */
+ const char* name; /*!< Entry name */
+ const char* num; /*!< Entry number */
+ lwgsm_number_type_t type; /*!< Entry phone number type */
+ uint8_t del; /*!< Flag indicates delete */
+ } pb_write; /*!< Write/Edit/Delete entry */
+ struct {
+ lwgsm_mem_t mem; /*!< Memory to use */
+ size_t start_index; /*!< Start index in phonebook to read */
+ lwgsm_pb_entry_t* entries; /*!< Pointer to entries array */
+ size_t etr; /*!< NUmber of entries to read */
+ size_t ei; /*!< Current entry index */
+ size_t* er; /*!< Final entries read pointer for user */
+ } pb_list; /*!< List phonebook entries */
+ struct {
+ lwgsm_mem_t mem; /*!< Memory to use */
+ lwgsm_pb_entry_t* entries; /*!< Pointer to entries array */
+ size_t etr; /*!< NUmber of entries to read */
+ size_t ei; /*!< Current entry index */
+ size_t* er; /*!< Final entries read pointer for user */
+ const char* search; /*!< Search string */
+ } pb_search; /*!< Search phonebook entries */
+#endif /* LWGSM_CFG_PHONEBOOK || __DOXYGEN__ */
+ struct {
+ const char* code; /*!< Code to send */
+ char* resp; /*!< Response array */
+ size_t resp_len; /*!< Length of response array */
+ uint8_t read; /*!< Flag indicating we can read the COPS actual data */
+ size_t resp_write_ptr; /*!< Write pointer for response */
+ uint8_t quote_det; /*!< Information if quote has been detected */
+ } ussd; /*!< Execute USSD command */
+#if LWGSM_CFG_NETWORK || __DOXYGEN__
+ struct {
+ const char* apn; /*!< APN address */
+ const char* user; /*!< APN username */
+ const char* pass; /*!< APN password */
+ } network_attach; /*!< Settings for network attach */
+#endif /* LWGSM_CFG_NETWORK || __DOXYGEN__ */
+ } msg; /*!< Group of different possible message contents */
+} lwgsm_msg_t;
+
+/**
+ * \brief IP and MAC structure with netmask and gateway addresses
+ */
+typedef struct {
+ lwgsm_ip_t ip; /*!< IP address */
+ lwgsm_ip_t gw; /*!< Gateway address */
+ lwgsm_ip_t nm; /*!< Netmask address */
+ lwgsm_mac_t mac; /*!< MAC address */
+} lwgsm_ip_mac_t;
+
+/**
+ * \brief Link connection active info
+ */
+typedef struct {
+ uint8_t failed; /*!< Status if connection successful */
+ uint8_t num; /*!< Connection number */
+ uint8_t is_server; /*!< Status if connection is client or server */
+ lwgsm_conn_type_t type; /*!< Connection type */
+ lwgsm_ip_t remote_ip; /*!< Remote IP address */
+ lwgsm_port_t remote_port; /*!< Remote port */
+ lwgsm_port_t local_port; /*!< Local port number */
+} lwgsm_link_conn_t;
+
+/**
+ * \brief Callback function linked list prototype
+ */
+typedef struct lwgsm_evt_func {
+ struct lwgsm_evt_func* next; /*!< Next function in the list */
+ lwgsm_evt_fn fn; /*!< Function pointer itself */
+} lwgsm_evt_func_t;
+
+/**
+ * \ingroup LWGSM_SMS
+ * \brief SMS memory information
+ */
+typedef struct {
+ uint32_t mem_available; /*!< Bit field of available memories */
+ lwgsm_mem_t current; /*!< Current memory choice */
+ size_t total; /*!< Size of memory in units of entries */
+ size_t used; /*!< Number of used entries */
+} lwgsm_sms_mem_t;
+
+/**
+ * \ingroup LWGSM_SMS
+ * \brief SMS structure
+ */
+typedef struct {
+ uint8_t ready; /*!< Flag indicating feature ready by device */
+ uint8_t enabled; /*!< Flag indicating feature enabled */
+
+ lwgsm_sms_mem_t mem[3]; /*!< 3 memory info for operation,receive,sent storage */
+} lwgsm_sms_t;
+
+/**
+ * \ingroup LWGSM_SMS
+ * \brief SMS memory information
+ */
+typedef struct {
+ uint32_t mem_available; /*!< Bit field of available memories */
+ lwgsm_mem_t current; /*!< Current memory choice */
+ size_t total; /*!< Size of memory in units of entries */
+ size_t used; /*!< Number of used entries */
+} lwgsm_pb_mem_t;
+
+/**
+ * \ingroup LWGSM_PB
+ * \brief Phonebook structure
+ */
+typedef struct {
+ uint8_t ready; /*!< Flag indicating feature ready by device */
+ uint8_t enabled; /*!< Flag indicating feature enabled */
+
+ lwgsm_pb_mem_t mem; /*!< Memory information */
+} lwgsm_pb_t;
+
+/**
+ * \brief SIM structure
+ */
+typedef struct {
+ lwgsm_sim_state_t state; /*!< Current SIM status */
+} lwgsm_sim_t;
+
+/**
+ * \brief Network info
+ */
+typedef struct {
+ lwgsm_network_reg_status_t status; /*!< Network registration status */
+ lwgsm_operator_curr_t curr_operator; /*!< Current operator information */
+
+ uint8_t is_attached; /*!< Flag indicating device is attached and PDP context is active */
+ lwgsm_ip_t ip_addr; /*!< Device IP address when network PDP context is enabled */
+} lwgsm_network_t;
+
+/**
+ * \brief GSM modules structure
+ */
+typedef struct {
+ /* Device identification */
+ char model_manufacturer[20]; /*!< Device manufacturer */
+ char model_number[20]; /*!< Device model number */
+ char model_serial_number[20];/*!< Device serial number */
+ char model_revision[20]; /*!< Device revision */
+ lwgsm_device_model_t model; /*!< Device model */
+
+ /* Network&operator specific */
+ lwgsm_sim_t sim; /*!< SIM data */
+ lwgsm_network_t network; /*!< Network status */
+ int16_t rssi; /*!< RSSI signal strength. `0` = invalid, `-53 % -113` = valid */
+
+ /* Device specific */
+#if LWGSM_CFG_CONN || __DOXYGEN__
+ uint8_t active_conns_cur_parse_num; /*!< Current connection number used for parsing */
+
+ lwgsm_conn_t conns[LWGSM_CFG_MAX_CONNS]; /*!< Array of all connection structures */
+ lwgsm_ipd_t ipd; /*!< Connection incoming data structure */
+ uint8_t conn_val_id; /*!< Validation ID increased each time device connects to network */
+#endif /* LWGSM_CFG_CONNS || __DOXYGEN__ */
+#if LWGSM_CFG_SMS || __DOXYGEN__
+ lwgsm_sms_t sms; /*!< SMS information */
+#endif /* LWGSM_CFG_SMS || __DOXYGEN__ */
+#if LWGSM_CFG_PHONEBOOK || __DOXYGEN__
+ lwgsm_pb_t pb; /*!< Phonebook information */
+#endif /* LWGSM_CFG_PHONEBOOK || __DOXYGEN__ */
+#if LWGSM_CFG_CALL || __DOXYGEN__
+ lwgsm_call_t call; /*!< Call information */
+#endif /* LWGSM_CFG_CALL || __DOXYGEN__ */
+} lwgsm_modules_t;
+
+/**
+ * \brief GSM global structure
+ */
+typedef struct {
+ size_t locked_cnt; /*!< Counter how many times (recursive) stack is currently locked */
+
+ lwgsm_sys_sem_t sem_sync; /*!< Synchronization semaphore between threads */
+ lwgsm_sys_mbox_t mbox_producer; /*!< Producer message queue handle */
+ lwgsm_sys_mbox_t mbox_process; /*!< Consumer message queue handle */
+ lwgsm_sys_thread_t thread_produce; /*!< Producer thread handle */
+ lwgsm_sys_thread_t thread_process; /*!< Processing thread handle */
+#if !LWGSM_CFG_INPUT_USE_PROCESS || __DOXYGEN__
+ lwgsm_buff_t buff; /*!< Input processing buffer */
+#endif /* !LWGSM_CFG_INPUT_USE_PROCESS || __DOXYGEN__ */
+ lwgsm_ll_t ll; /*!< Low level functions */
+
+ lwgsm_msg_t* msg; /*!< Pointer to current user message being executed */
+
+ lwgsm_evt_t evt; /*!< Callback processing structure */
+ lwgsm_evt_func_t* evt_func; /*!< Callback function linked list */
+
+ lwgsm_modules_t m; /*!< All modules. When resetting, reset structure */
+
+ union {
+ struct {
+ uint8_t initialized: 1; /*!< Flag indicating GSM library is initialized */
+ uint8_t dev_present: 1; /*!< Flag indicating GSM device is present */
+ } f; /*!< Flags structure */
+ } status; /*!< Status structure */
+} lwgsm_t;
+
+/**
+ * \brief Memory mapping structure between string and value in app
+ */
+typedef struct {
+ lwgsm_mem_t mem; /*!< Mem indication */
+ const char* mem_str; /*!< Memory string */
+} lwgsm_dev_mem_map_t;
+
+/**
+ * \brief Device models map between model and other information
+ */
+typedef struct {
+ lwgsm_device_model_t model; /*!< Device model */
+ const char* id_str; /*!< Model string identification */
+ uint8_t is_2g; /*!< Status if modem is 2G */
+ uint8_t is_lte; /*!< Status if modem is LTE */
+} lwgsm_dev_model_map_t;
+
+/**
+ * \ingroup LWGSM_UNICODE
+ * \brief Unicode support structure
+ */
+typedef struct {
+ uint8_t ch[4]; /*!< UTF-8 max characters */
+ uint8_t t; /*!< Total expected length in UTF-8 sequence */
+ uint8_t r; /*!< Remaining bytes in UTF-8 sequence */
+ lwgsmr_t res; /*!< Current result of processing */
+} lwgsm_unicode_t;
+
+/**
+ * \}
+ */
+
+#if !__DOXYGEN__
+
+/**
+ * \ingroup LWGSM
+ * \defgroup LWGSM_PRIVATE Internal functions
+ * \brief Functions, structures and enumerations
+ * \{
+ */
+
+extern lwgsm_t lwgsm;
+
+extern const lwgsm_dev_mem_map_t lwgsm_dev_mem_map[];
+extern const size_t lwgsm_dev_mem_map_size;
+
+extern const lwgsm_dev_model_map_t lwgsm_dev_model_map[];
+extern const size_t lwgsm_dev_model_map_size;
+
+#define CMD_IS_CUR(c) (lwgsm.msg != NULL && lwgsm.msg->cmd == (c))
+#define CMD_IS_DEF(c) (lwgsm.msg != NULL && lwgsm.msg->cmd_def == (c))
+#define CMD_GET_CUR() ((lwgsm_cmd_t)(((lwgsm.msg != NULL) ? lwgsm.msg->cmd : LWGSM_CMD_IDLE)))
+#define CMD_GET_DEF() ((lwgsm_cmd_t)(((lwgsm.msg != NULL) ? lwgsm.msg->cmd_def : LWGSM_CMD_IDLE)))
+
+#define CRLF "\r\n"
+#define CRLF_LEN 2
+
+#define LWGSM_MSG_VAR_DEFINE(name) lwgsm_msg_t* name
+#define LWGSM_MSG_VAR_ALLOC(name, blocking) do {\
+ (name) = lwgsm_mem_malloc(sizeof(*(name))); \
+ LWGSM_DEBUGW(LWGSM_CFG_DBG_VAR | LWGSM_DBG_TYPE_TRACE, (name) != NULL, "[MSG VAR] Allocated %d bytes at %p\r\n", sizeof(*(name)), (name)); \
+ LWGSM_DEBUGW(LWGSM_CFG_DBG_VAR | LWGSM_DBG_TYPE_TRACE, (name) == NULL, "[MSG VAR] Error allocating %d bytes\r\n", sizeof(*(name))); \
+ if ((name) == NULL) { \
+ return lwgsmERRMEM; \
+ } \
+ LWGSM_MEMSET((name), 0x00, sizeof(*(name))); \
+ (name)->is_blocking = LWGSM_U8((blocking) > 0); \
+ } while (0)
+#define LWGSM_MSG_VAR_REF(name) (*(name))
+#define LWGSM_MSG_VAR_FREE(name) do {\
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_VAR | LWGSM_DBG_TYPE_TRACE, "[MSG VAR] Free memory: %p\r\n", (name)); \
+ if (lwgsm_sys_sem_isvalid(&((name)->sem))) { \
+ lwgsm_sys_sem_delete(&((name)->sem)); \
+ lwgsm_sys_sem_invalid(&((name)->sem)); \
+ } \
+ lwgsm_mem_free_s((void **)&(name)); \
+ } while (0)
+#if LWGSM_CFG_USE_API_FUNC_EVT
+#define LWGSM_MSG_VAR_SET_EVT(name, e_fn, e_arg) do {\
+ (name)->evt_fn = (e_fn); \
+ (name)->evt_arg = (e_arg); \
+ } while (0)
+#else /* LWGSM_CFG_USE_API_FUNC_EVT */
+#define LWGSM_MSG_VAR_SET_EVT(name, e_fn, e_arg) do { LWGSM_UNUSED(e_fn); LWGSM_UNUSED(e_arg); } while (0)
+#endif /* !LWGSM_CFG_USE_API_FUNC_EVT */
+
+#define LWGSM_CHARISNUM(x) ((x) >= '0' && (x) <= '9')
+#define LWGSM_CHARTONUM(x) ((x) - '0')
+#define LWGSM_CHARISHEXNUM(x) (((x) >= '0' && (x) <= '9') || ((x) >= 'a' && (x) <= 'f') || ((x) >= 'A' && (x) <= 'F'))
+#define LWGSM_CHARHEXTONUM(x) (((x) >= '0' && (x) <= '9') ? ((x) - '0') : (((x) >= 'a' && (x) <= 'f') ? ((x) - 'a' + 10) : (((x) >= 'A' && (x) <= 'F') ? ((x) - 'A' + 10) : 0)))
+#define LWGSM_ISVALIDASCII(x) (((x) >= 32 && (x) <= 126) || (x) == '\r' || (x) == '\n')
+
+#define LWGSM_PORT2NUM(port) ((uint32_t)(port))
+
+const char* lwgsmi_dbg_msg_to_string(lwgsm_cmd_t cmd);
+lwgsmr_t lwgsmi_process(const void* data, size_t len);
+lwgsmr_t lwgsmi_process_buffer(void);
+lwgsmr_t lwgsmi_initiate_cmd(lwgsm_msg_t* msg);
+uint8_t lwgsmi_is_valid_conn_ptr(lwgsm_conn_p conn);
+lwgsmr_t lwgsmi_send_cb(lwgsm_evt_type_t type);
+lwgsmr_t lwgsmi_send_conn_cb(lwgsm_conn_t* conn, lwgsm_evt_fn cb);
+void lwgsmi_conn_init(void);
+lwgsmr_t lwgsmi_send_msg_to_producer_mbox(lwgsm_msg_t* msg, lwgsmr_t (*process_fn)(lwgsm_msg_t*), uint32_t max_block_time);
+uint32_t lwgsmi_get_from_mbox_with_timeout_checks(lwgsm_sys_mbox_t* b, void** m, uint32_t timeout);
+uint8_t lwgsmi_conn_closed_process(uint8_t conn_num, uint8_t forced);
+void lwgsmi_conn_start_timeout(lwgsm_conn_p conn);
+
+lwgsmr_t lwgsmi_get_sim_info(const uint32_t blocking);
+
+void lwgsmi_reset_everything(uint8_t forced);
+void lwgsmi_process_events_for_timeout_or_error(lwgsm_msg_t* msg, lwgsmr_t err);
+
+/**
+ * \}
+ */
+
+#endif /* !__DOXYGEN__ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LWGSM_HDR_PRIV_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_sim.h b/lwgsm/src/include/lwgsm/lwgsm_sim.h
similarity index 53%
rename from gsm_at_lib/src/include/gsm/gsm_sim.h
rename to lwgsm/src/include/lwgsm/lwgsm_sim.h
index 901a74cd..d1f66eef 100644
--- a/gsm_at_lib/src/include/gsm/gsm_sim.h
+++ b/lwgsm/src/include/lwgsm/lwgsm_sim.h
@@ -1,10 +1,10 @@
-/**
- * \file gsm_sim.h
+/**
+ * \file lwgsm_sim.h
* \brief SIM API
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,33 +26,33 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#ifndef GSM_HDR_SIM_H
-#define GSM_HDR_SIM_H
+#ifndef LWGSM_HDR_SIM_H
+#define LWGSM_HDR_SIM_H
+
+#include "lwgsm/lwgsm.h"
#ifdef __cplusplus
extern "C" {
-#endif
-
-#include "gsm/gsm.h"
+#endif /* __cplusplus */
/**
- * \ingroup GSM
- * \defgroup GSM_SIM SIM API
+ * \ingroup LWGSM
+ * \defgroup LWGSM_SIM SIM API
* \brief SIM card manager
* \{
*/
-gsm_sim_state_t gsm_sim_get_current_state(void);
-gsmr_t gsm_sim_pin_enter(const char* pin, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-gsmr_t gsm_sim_pin_add(const char* pin, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-gsmr_t gsm_sim_pin_remove(const char* pin, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-gsmr_t gsm_sim_pin_change(const char* pin, const char* new_pin, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
-gsmr_t gsm_sim_puk_enter(const char* puk, const char* new_pin, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsm_sim_state_t lwgsm_sim_get_current_state(void);
+lwgsmr_t lwgsm_sim_pin_enter(const char* pin, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_sim_pin_add(const char* pin, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_sim_pin_remove(const char* pin, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_sim_pin_change(const char* pin, const char* new_pin, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_sim_puk_enter(const char* puk, const char* new_pin, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
/**
* \}
@@ -60,6 +60,6 @@ gsmr_t gsm_sim_puk_enter(const char* puk, const char* new_pin, const gsm_ap
#ifdef __cplusplus
}
-#endif
+#endif /* __cplusplus */
-#endif /* GSM_HDR_SIM_H */
+#endif /* LWGSM_HDR_SIM_H */
diff --git a/lwgsm/src/include/lwgsm/lwgsm_sms.h b/lwgsm/src/include/lwgsm/lwgsm_sms.h
new file mode 100644
index 00000000..292f4bd0
--- /dev/null
+++ b/lwgsm/src/include/lwgsm/lwgsm_sms.h
@@ -0,0 +1,69 @@
+/**
+ * \file lwgsm_sms.h
+ * \brief SMS API
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM - Lightweight GSM-AT library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+#ifndef LWGSM_HDR_SMS_H
+#define LWGSM_HDR_SMS_H
+
+#include "lwgsm/lwgsm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * \ingroup LWGSM
+ * \defgroup LWGSM_SMS SMS API
+ * \brief SMS manager
+ * \{
+ */
+
+lwgsmr_t lwgsm_sms_enable(const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_sms_disable(const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+
+lwgsmr_t lwgsm_sms_send(const char* num, const char* text, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_sms_read(lwgsm_mem_t mem, size_t pos, lwgsm_sms_entry_t* entry, uint8_t update, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_sms_delete(lwgsm_mem_t mem, size_t pos, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_sms_delete_all(lwgsm_sms_status_t status, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_sms_list(lwgsm_mem_t mem, lwgsm_sms_status_t stat, lwgsm_sms_entry_t* entries, size_t etr, size_t* er, uint8_t update, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg,
+ const uint32_t blocking);
+lwgsmr_t lwgsm_sms_set_preferred_storage(lwgsm_mem_t mem1, lwgsm_mem_t mem2, lwgsm_mem_t mem3, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+
+/**
+ * \}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LWGSM_HDR_SMS_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_threads.h b/lwgsm/src/include/lwgsm/lwgsm_threads.h
similarity index 78%
rename from gsm_at_lib/src/include/gsm/gsm_threads.h
rename to lwgsm/src/include/lwgsm/lwgsm_threads.h
index f11f59a4..2cd1ff18 100644
--- a/gsm_at_lib/src/include/gsm/gsm_threads.h
+++ b/lwgsm/src/include/lwgsm/lwgsm_threads.h
@@ -1,10 +1,10 @@
/**
- * \file gsm_threads.h
+ * \file lwgsm_threads.h
* \brief OS threads implementations
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,25 +26,25 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#ifndef GSM_HDR_THREADS_H
-#define GSM_HDR_THREADS_H
+#ifndef LWGSM_HDR_THREADS_H
+#define LWGSM_HDR_THREADS_H
+
+#include "lwgsm/lwgsm.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
-#include "gsm/gsm.h"
-
-void gsm_thread_produce(void* const arg);
-void gsm_thread_process(void* const arg);
+void lwgsm_thread_produce(void* const arg);
+void lwgsm_thread_process(void* const arg);
#ifdef __cplusplus
}
#endif /* __cplusplus */
-#endif /* GSM_HDR_THREADS_H */
+#endif /* LWGSM_HDR_THREADS_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_timeout.h b/lwgsm/src/include/lwgsm/lwgsm_timeout.h
similarity index 70%
rename from gsm_at_lib/src/include/gsm/gsm_timeout.h
rename to lwgsm/src/include/lwgsm/lwgsm_timeout.h
index 2405d18b..26020e88 100644
--- a/gsm_at_lib/src/include/gsm/gsm_timeout.h
+++ b/lwgsm/src/include/lwgsm/lwgsm_timeout.h
@@ -1,10 +1,10 @@
-/**
- * \file gsm_timeout.h
+/**
+ * \file lwgsm_timeout.h
* \brief Timeout manager
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,29 +26,29 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#ifndef GSM_HDR_TIMEOUT_H
-#define GSM_HDR_TIMEOUT_H
+#ifndef LWGSM_HDR_TIMEOUT_H
+#define LWGSM_HDR_TIMEOUT_H
+
+#include "lwgsm/lwgsm.h"
#ifdef __cplusplus
extern "C" {
-#endif
-
-#include "gsm/gsm.h"
+#endif /* __cplusplus */
/**
- * \ingroup GSM
- * \defgroup GSM_TIMEOUT Timeout manager
+ * \ingroup LWGSM
+ * \defgroup LWGSM_TIMEOUT Timeout manager
* \brief Timeout manager
* \{
*/
-gsmr_t gsm_timeout_add(uint32_t time, gsm_timeout_fn fn, void* arg);
-gsmr_t gsm_timeout_remove(gsm_timeout_fn fn);
+lwgsmr_t lwgsm_timeout_add(uint32_t time, lwgsm_timeout_fn fn, void* arg);
+lwgsmr_t lwgsm_timeout_remove(lwgsm_timeout_fn fn);
/**
* \}
@@ -56,6 +56,6 @@ gsmr_t gsm_timeout_remove(gsm_timeout_fn fn);
#ifdef __cplusplus
}
-#endif
+#endif /* __cplusplus */
-#endif /* GSM_HDR_TIMEOUT_H */
+#endif /* LWGSM_HDR_TIMEOUT_H */
diff --git a/lwgsm/src/include/lwgsm/lwgsm_typedefs.h b/lwgsm/src/include/lwgsm/lwgsm_typedefs.h
new file mode 100644
index 00000000..da2bf637
--- /dev/null
+++ b/lwgsm/src/include/lwgsm/lwgsm_typedefs.h
@@ -0,0 +1,635 @@
+/**
+ * \file lwgsm_typedefs.h
+ * \brief List of structures and enumerations for public usage
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM - Lightweight GSM-AT library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+#ifndef LWGSM_HDR_DEFS_H
+#define LWGSM_HDR_DEFS_H
+
+#include
+#include
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * \ingroup LWGSM
+ * \defgroup LWGSM_TYPEDEFS Structures and enumerations
+ * \brief List of core structures and enumerations
+ * \{
+ */
+
+/**
+ * \}
+ */
+
+/**
+ * \ingroup LWGSM_TYPEDEFS
+ * \brief Result enumeration used across application functions
+ */
+typedef enum {
+ lwgsmOK = 0, /*!< Function returned OK */
+ lwgsmOKIGNOREMORE, /*!< Function succedded, should continue as \ref lwgsmOK
+ but ignore sending more data.
+ This result is possible on connection data receive callback */
+ lwgsmERR, /*!< Generic error */
+ lwgsmPARERR, /*!< Wrong parameters on function call */
+ lwgsmERRMEM, /*!< Memory error occurred */
+ lwgsmTIMEOUT, /*!< Timeout occurred on command */
+ lwgsmCONT, /*!< There is still some command to be processed in current command */
+ lwgsmCLOSED, /*!< Connection just closed */
+ lwgsmINPROG, /*!< Operation is in progress */
+
+ lwgsmERRNOTENABLED, /*!< Feature not enabled error */
+ lwgsmERRNOIP, /*!< Station does not have IP address */
+ lwgsmERRNOFREECONN, /*!< There is no free connection available to start */
+ lwgsmERRCONNTIMEOUT, /*!< Timeout received when connection to access point */
+ lwgsmERRPASS, /*!< Invalid password for access point */
+ lwgsmERRNOAP, /*!< No access point found with specific SSID and MAC address */
+ lwgsmERRCONNFAIL, /*!< Connection failed to access point */
+ lwgsmERRWIFINOTCONNECTED, /*!< Wifi not connected to access point */
+ lwgsmERRNODEVICE, /*!< Device is not present */
+ lwgsmERRBLOCKING, /*!< Blocking mode command is not allowed */
+} lwgsmr_t;
+
+/**
+ * \ingroup LWGSM_TYPEDEFS
+ * \brief GSM device model type
+ */
+typedef enum {
+#define LWGSM_DEVICE_MODEL_ENTRY(name, str_id, is_2g, is_lte) LWGSM_DEVICE_MODEL_ ## name,
+#include "lwgsm/lwgsm_models.h"
+ LWGSM_DEVICE_MODEL_END, /*!< End of device model */
+ LWGSM_DEVICE_MODEL_UNKNOWN, /*!< Unknown device model */
+} lwgsm_device_model_t;
+
+/**
+ * \ingroup LWGSM_SIM
+ * \brief SIM state
+ */
+typedef enum {
+ LWGSM_SIM_STATE_NOT_INSERTED, /*!< SIM is not inserted in socket */
+ LWGSM_SIM_STATE_READY, /*!< SIM is ready for operations */
+ LWGSM_SIM_STATE_NOT_READY, /*!< SIM is not ready for any operation */
+ LWGSM_SIM_STATE_PIN, /*!< SIM is waiting for SIM to be given */
+ LWGSM_SIM_STATE_PUK, /*!< SIM is waiting for PUT to be given */
+ LWGSM_SIM_STATE_PH_PIN,
+ LWGSM_SIM_STATE_PH_PUK,
+} lwgsm_sim_state_t;
+
+/**
+ * \ingroup LWGSM_TYPEDEFS
+ * \brief IP structure
+ */
+typedef struct {
+ uint8_t ip[4]; /*!< IPv4 address */
+} lwgsm_ip_t;
+
+/**
+ * \ingroup LWGSM_TYPEDEFS
+ * \brief Port variable
+ */
+typedef uint16_t lwgsm_port_t;
+
+/**
+ * \ingroup LWGSM_TYPEDEFS
+ * \brief MAC address
+ */
+typedef struct {
+ uint8_t mac[6]; /*!< MAC address */
+} lwgsm_mac_t;
+
+/**
+ * \ingroup LWGSM_TYPEDEFS
+ * \brief Date and time structure
+ */
+typedef struct {
+ uint8_t date; /*!< Day in a month, from `1` to up to `31` */
+ uint8_t month; /*!< Month in a year, from `1` to `12` */
+ uint16_t year; /*!< Year */
+ uint8_t day; /*!< Day in a week, from `1` to `7`, 0 = invalid */
+ uint8_t hours; /*!< Hours in a day, from `0` to `23` */
+ uint8_t minutes; /*!< Minutes in a hour, from `0` to `59` */
+ uint8_t seconds; /*!< Seconds in a minute, from `0` to `59` */
+} lwgsm_datetime_t;
+
+/**
+ * \ingroup LWGSM_CONN
+ * \brief List of possible connection types
+ */
+typedef enum {
+ LWGSM_CONN_TYPE_TCP, /*!< Connection type is TCP */
+ LWGSM_CONN_TYPE_UDP, /*!< Connection type is UDP */
+ LWGSM_CONN_TYPE_SSL, /*!< Connection type is TCP over SSL */
+} lwgsm_conn_type_t;
+
+/**
+ * \ingroup LWGSM_TYPEDEFS
+ * \brief Available device memories
+ */
+typedef enum {
+#define LWGSM_DEV_MEMORY_ENTRY(name, str_code) LWGSM_MEM_ ## name,
+#include "lwgsm/lwgsm_memories.h"
+ LWGSM_MEM_END, /*!< End of memory list */
+ LWGSM_MEM_CURRENT, /*!< Use current memory for read/delete operation */
+ LWGSM_MEM_UNKNOWN = 0x1F, /*!< Unknown memory */
+} lwgsm_mem_t;
+
+/**
+ * \ingroup LWGSM_TYPEDEFS
+ * \brief GSM number type
+ */
+typedef enum {
+ LWGSM_NUMBER_TYPE_NATIONAL = 129, /*!< Number is national */
+ LWGSM_NUMBER_TYPE_INTERNATIONAL = 145, /*!< Number is international */
+} lwgsm_number_type_t;
+
+/**
+ * \ingroup LWGSM_SMS
+ * \brief SMS status in current memory
+ */
+typedef enum {
+ LWGSM_SMS_STATUS_ALL, /*!< Process all SMS, used for mass delete or SMS list */
+ LWGSM_SMS_STATUS_READ, /*!< SMS status is read */
+ LWGSM_SMS_STATUS_UNREAD, /*!< SMS status is unread */
+ LWGSM_SMS_STATUS_SENT, /*!< SMS status is sent */
+ LWGSM_SMS_STATUS_UNSENT, /*!< SMS status is unsent */
+ LWGSM_SMS_STATUS_INBOX, /*!< SMS status, used only for mass delete operation */
+} lwgsm_sms_status_t;
+
+/**
+ * \ingroup LWGSM_SMS
+ * \brief SMS entry structure
+ */
+typedef struct {
+ lwgsm_mem_t mem; /*!< Memory storage */
+ size_t pos; /*!< Memory position */
+ lwgsm_datetime_t datetime; /*!< Date and time */
+ lwgsm_sms_status_t status; /*!< Message status */
+ char number[26]; /*!< Phone number */
+ char name[20]; /*!< Name in phonebook if exists */
+ char data[161]; /*!< Data memory */
+ size_t length; /*!< Length of SMS data */
+} lwgsm_sms_entry_t;
+
+/**
+ * \ingroup LWGSM_PB
+ * \brief Phonebook entry structure
+ */
+typedef struct {
+ lwgsm_mem_t mem; /*!< Memory position */
+ size_t pos; /*!< Position in memory */
+ char name[20]; /*!< Name of phonebook entry */
+ char number[26]; /*!< Phone number */
+ lwgsm_number_type_t type; /*!< Phone number type */
+} lwgsm_pb_entry_t;
+
+/**
+ * \ingroup LWGSM_OPERATOR
+ * \brief Operator status value
+ */
+typedef enum {
+ LWGSM_OPERATOR_STATUS_UNKNOWN = 0x00, /*!< Unknown operator */
+ LWGSM_OPERATOR_STATUS_AVAILABLE, /*!< Operator is available */
+ LWGSM_OPERATOR_STATUS_CURRENT, /*!< Operator is currently active */
+ LWGSM_OPERATOR_STATUS_FORBIDDEN /*!< Operator is forbidden */
+} lwgsm_operator_status_t;
+
+/**
+ * \ingroup LWGSM_OPERATOR
+ * \brief Operator selection mode
+ */
+typedef enum {
+ LWGSM_OPERATOR_MODE_AUTO = 0x00, /*!< Operator automatic mode */
+ LWGSM_OPERATOR_MODE_MANUAL = 0x01, /*!< Operator manual mode */
+ LWGSM_OPERATOR_MODE_DEREGISTER = 0x02, /*!< Operator deregistered from network */
+ LWGSM_OPERATOR_MODE_MANUAL_AUTO = 0x04, /*!< Operator manual mode first. If fails, auto mode enabled */
+} lwgsm_operator_mode_t;
+
+/**
+ * \ingroup LWGSM_OPERATOR
+ * \brief Operator data format
+ */
+typedef enum {
+ LWGSM_OPERATOR_FORMAT_LONG_NAME = 0x00, /*!< COPS command returned long name */
+ LWGSM_OPERATOR_FORMAT_SHORT_NAME, /*!< COPS command returned short name */
+ LWGSM_OPERATOR_FORMAT_NUMBER, /*!< COPS command returned number */
+ LWGSM_OPERATOR_FORMAT_INVALID /*!< Unknown format */
+} lwgsm_operator_format_t;
+
+/**
+ * \ingroup LWGSM_OPERATOR
+ * \brief Operator details for scan
+ */
+typedef struct {
+ lwgsm_operator_status_t stat; /*!< Operator status */
+ char long_name[20]; /*!< Operator long name */
+ char short_name[20]; /*!< Operator short name */
+ uint32_t num; /*!< Operator numeric value */
+} lwgsm_operator_t;
+
+/**
+ * \ingroup LWGSM_OPERATOR
+ * \brief Current operator info
+ */
+typedef struct {
+ lwgsm_operator_mode_t mode; /*!< Operator mode */
+ lwgsm_operator_format_t format; /*!< Data format */
+ union {
+ char long_name[20]; /*!< Long name format */
+ char short_name[20]; /*!< Short name format */
+ uint32_t num; /*!< Number format */
+ } data; /*!< Operator data union */
+} lwgsm_operator_curr_t;
+
+/**
+ * \ingroup LWGSM_NETWORK
+ * \brief Network Registration status
+ */
+typedef enum {
+ LWGSM_NETWORK_REG_STATUS_SIM_ERR = 0x00, /*!< SIM card error */
+ LWGSM_NETWORK_REG_STATUS_CONNECTED = 0x01, /*!< Device is connected to network */
+ LWGSM_NETWORK_REG_STATUS_SEARCHING = 0x02, /*!< Network search is in progress */
+ LWGSM_NETWORK_REG_STATUS_DENIED = 0x03, /*!< Registration denied */
+ LWGSM_NETWORK_REG_STATUS_CONNECTED_ROAMING = 0x05, /*!< Device is connected and is roaming */
+ LWGSM_NETWORK_REG_STATUS_CONNECTED_SMS_ONLY = 0x06, /*!< Device is connected to home network in SMS-only mode */
+ LWGSM_NETWORK_REG_STATUS_CONNECTED_ROAMING_SMS_ONLY = 0x07 /*!< Device is roaming in SMS-only mode */
+} lwgsm_network_reg_status_t;
+
+/**
+ * \ingroup LWGSM_CALL
+ * \brief List of call directions
+ */
+typedef enum {
+ LWGSM_CALL_DIR_MO = 0x00, /*!< Mobile Originated, outgoing call */
+ LWGSM_CALL_DIR_MT, /*!< Mobile Terminated, incoming call */
+} lwgsm_call_dir_t;
+
+/**
+ * \ingroup LWGSM_CALL
+ * \brief List of call states
+ */
+typedef enum {
+ LWGSM_CALL_STATE_ACTIVE = 0x00, /*!< Call is active */
+ LWGSM_CALL_STATE_HELD, /*!< Call is held */
+ LWGSM_CALL_STATE_DIALING, /*!< Call is dialing */
+ LWGSM_CALL_STATE_ALERTING, /*!< Call is alerting */
+ LWGSM_CALL_STATE_INCOMING, /*!< Call is incoming */
+ LWGSM_CALL_STATE_WAITING, /*!< Call is waiting */
+ LWGSM_CALL_STATE_DISCONNECT, /*!< Call disconnected, call finished */
+} lwgsm_call_state_t;
+
+/**
+ * \ingroup LWGSM_CALL
+ * \brief List of call types
+ */
+typedef enum {
+ LWGSM_CALL_TYPE_VOICE = 0x00, /*!< Voice call */
+ LWGSM_CALL_TYPE_DATA, /*!< Data call */
+ LWGSM_CALL_TYPE_FAX, /*!< Fax call */
+} lwgsm_call_type_t;
+
+/**
+ * \ingroup LWGSM_CALL
+ * \brief Call information
+ * \note Data received on `+CLCC` info
+ */
+typedef struct {
+ uint8_t ready; /*!< Flag indicating feature ready by device */
+ uint8_t enabled; /*!< Flag indicating feature enabled */
+
+ uint8_t id; /*!< Call identification number, 0-7 */
+ lwgsm_call_dir_t dir; /*!< Call direction */
+ lwgsm_call_state_t state; /*!< Call state */
+ lwgsm_call_type_t type; /*!< Call type */
+ char number[20]; /*!< Phone number */
+ char is_multipart; /*!< Multipart status */
+ uint8_t addr_type; /*!< Address type */
+ char name[20]; /*!< Phone book name if exists for current number */
+} lwgsm_call_t;
+
+/* Forward declarations */
+struct lwgsm_evt;
+struct lwgsm_conn;
+struct lwgsm_pbuf;
+
+/**
+ * \ingroup LWGSM_CONN
+ * \brief Pointer to \ref lwgsm_conn_t structure
+ */
+typedef struct lwgsm_conn* lwgsm_conn_p;
+
+/**
+ * \ingroup LWGSM_PBUF
+ * \brief Pointer to \ref lwgsm_pbuf_t structure
+ */
+typedef struct lwgsm_pbuf* lwgsm_pbuf_p;
+
+/**
+ * \ingroup LWGSM_EVT
+ * \brief Event function prototype
+ * \param[in] evt: Callback event data
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+ */
+typedef lwgsmr_t (*lwgsm_evt_fn)(struct lwgsm_evt* evt);
+
+/**
+ * \ingroup LWGSM_EVT
+ * \brief List of possible callback types received to user
+ */
+typedef enum lwgsm_cb_type_t {
+ LWGSM_EVT_INIT_FINISH, /*!< Initialization has been finished at this point */
+
+ LWGSM_EVT_RESET, /*!< Device reset operation finished */
+ LWGSM_EVT_RESTORE, /*!< Device restore operation finished */
+
+ LWGSM_EVT_CMD_TIMEOUT, /*!< Timeout on command.
+ When application receives this event,
+ it may reset system as there was (maybe) a problem in device */
+
+ LWGSM_EVT_DEVICE_PRESENT, /*!< Notification when device present status changes */
+ LWGSM_EVT_DEVICE_IDENTIFIED, /*!< Device identified event */
+
+ LWGSM_EVT_SIGNAL_STRENGTH, /*!< Signal strength event */
+
+ LWGSM_EVT_SIM_STATE_CHANGED, /*!< SIM card state changed */
+
+ LWGSM_EVT_OPERATOR_SCAN, /*!< Operator scan finished event */
+
+ LWGSM_EVT_NETWORK_OPERATOR_CURRENT, /*!< Current operator event */
+ LWGSM_EVT_NETWORK_REG_CHANGED, /*!< Network registration changed.
+ Available even when \ref LWGSM_CFG_NETWORK is disabled */
+#if LWGSM_CFG_NETWORK || __DOXYGEN__
+ LWGSM_EVT_NETWORK_ATTACHED, /*!< Attached to network, PDP context active and ready for TCP/IP application */
+ LWGSM_EVT_NETWORK_DETACHED, /*!< Detached from network, PDP context not active anymore */
+#endif /* LWGSM_CFG_NETWORK || __DOXYGEN__ */
+
+#if LWGSM_CFG_CONN || __DOXYGEN__
+ LWGSM_EVT_CONN_RECV, /*!< Connection data received */
+ LWGSM_EVT_CONN_SEND, /*!< Connection data send */
+ LWGSM_EVT_CONN_ACTIVE, /*!< Connection just became active */
+ LWGSM_EVT_CONN_ERROR, /*!< Client connection start was not successful */
+ LWGSM_EVT_CONN_CLOSE, /*!< Connection close event. Check status if successful */
+ LWGSM_EVT_CONN_POLL, /*!< Poll for connection if there are any changes */
+#endif /* LWGSM_CFG_CONN || __DOXYGEN__ */
+
+#if LWGSM_CFG_SMS || __DOXYGEN__
+ LWGSM_EVT_SMS_ENABLE, /*!< SMS enable event */
+ LWGSM_EVT_SMS_READY, /*!< SMS ready event */
+ LWGSM_EVT_SMS_SEND, /*!< SMS send event */
+ LWGSM_EVT_SMS_RECV, /*!< SMS received */
+ LWGSM_EVT_SMS_READ, /*!< SMS read */
+ LWGSM_EVT_SMS_DELETE, /*!< SMS delete */
+ LWGSM_EVT_SMS_LIST, /*!< SMS list */
+#endif /* LWGSM_CFG_SMS || __DOXYGEN__ */
+#if LWGSM_CFG_CALL || __DOXYGEN__
+ LWGSM_EVT_CALL_ENABLE, /*!< Call enable event */
+ LWGSM_EVT_CALL_READY, /*!< Call ready event */
+ LWGSM_EVT_CALL_CHANGED, /*!< Call info changed, `+CLCK` statement received */
+ LWGSM_EVT_CALL_RING, /*!< Call is ringing event */
+ LWGSM_EVT_CALL_BUSY, /*!< Call is busy */
+ LWGSM_EVT_CALL_NO_CARRIER, /*!< No carrier to make a call */
+#endif /* LWGSM_CFG_CALL || __DOXYGEN__ */
+#if LWGSM_CFG_PHONEBOOK || __DOXYGEN__
+ LWGSM_EVT_PB_ENABLE, /*!< Phonebook enable event */
+ LWGSM_EVT_PB_LIST, /*!< Phonebook list event */
+ LWGSM_EVT_PB_SEARCH, /*!< Phonebook search event */
+#endif /* LWGSM_CFG_PHONEBOOK || __DOXYGEN__ */
+} lwgsm_evt_type_t;
+
+/**
+ * \ingroup LWGSM_EVT
+ * \brief Global callback structure to pass as parameter to callback function
+ */
+typedef struct lwgsm_evt {
+ lwgsm_evt_type_t type; /*!< Callback type */
+ union {
+ struct {
+ lwgsmr_t res; /*!< Reset operation result */
+ } reset; /*!< Reset sequence finish. Use with \ref LWGSM_EVT_RESET event */
+ struct {
+ lwgsmr_t res; /*!< Restore operation result */
+ } restore; /*!< Restore sequence finish. Use with \ref LWGSM_EVT_RESTORE event */
+
+ struct {
+ lwgsm_sim_state_t state; /*!< SIM state */
+ } cpin; /*!< CPIN event */
+ struct {
+ const lwgsm_operator_curr_t* operator_current; /*!< Current operator info */
+ } operator_current; /*!< Current operator event. Use with \ref LWGSM_EVT_NETWORK_OPERATOR_CURRENT event */
+ struct {
+ lwgsm_operator_t* ops; /*!< Pointer to operators */
+ size_t opf; /*!< Number of operators found */
+ lwgsmr_t res; /*!< Scan operation result */
+ } operator_scan; /*!< Operator scan event. Use with \ref LWGSM_EVT_OPERATOR_SCAN event */
+
+ struct {
+ int16_t rssi; /*!< Strength in units of dBm */
+ } rssi; /*!< Signal strength event. Use with \ref LWGSM_EVT_SIGNAL_STRENGTH event */
+
+#if LWGSM_CFG_CONN || __DOXYGEN__
+ struct {
+ lwgsm_conn_p conn; /*!< Connection where data were received */
+ lwgsm_pbuf_p buff; /*!< Pointer to received data */
+ } conn_data_recv; /*!< Network data received. Use with \ref LWGSM_EVT_CONN_RECV event */
+ struct {
+ lwgsm_conn_p conn; /*!< Connection where data were sent */
+ size_t sent; /*!< Number of bytes sent on connection */
+ lwgsmr_t res; /*!< Send data result */
+ } conn_data_send; /*!< Data successfully sent. Use with \ref LWGSM_EVT_CONN_SEND event */
+ struct {
+ const char* host; /*!< Host to use for connection */
+ lwgsm_port_t port; /*!< Remote port used for connection */
+ lwgsm_conn_type_t type; /*!< Connection type */
+ void* arg; /*!< Connection argument used on connection */
+ lwgsmr_t err; /*!< Error value */
+ } conn_error; /*!< Client connection start error. Use with \ref LWGSM_EVT_CONN_ERROR event */
+ struct {
+ lwgsm_conn_p conn; /*!< Pointer to connection */
+ uint8_t client; /*!< Set to `1` if connection is/was client mode */
+ uint8_t forced; /*!< Set to `1` if connection action was forced */
+ lwgsmr_t res; /*!< Result of close event. Set to \ref lwgsmOK on success. */
+ } conn_active_close; /*!< Process active and closed statuses at the same time. Use with \ref LWGSM_EVT_CONN_ACTIVE or \ref LWGSM_EVT_CONN_CLOSE events */
+ struct {
+ lwgsm_conn_p conn; /*!< Set connection pointer */
+ } conn_poll; /*!< Polling active connection to check for timeouts. Use with \ref LWGSM_EVT_CONN_POLL event */
+#endif /* LWGSM_CFG_CONN || __DOXYGEN__ */
+
+#if LWGSM_CFG_SMS || __DOXYGEN__
+ struct {
+ lwgsmr_t status; /*!< Enable status */
+ } sms_enable; /*!< SMS enable event. Use with \ref LWGSM_EVT_SMS_ENABLE event */
+ struct {
+ size_t pos; /*!< Position in memory */
+ lwgsmr_t res; /*!< SMS send result information */
+ } sms_send; /*!< SMS sent info. Use with \ref LWGSM_EVT_SMS_SEND event */
+ struct {
+ lwgsm_mem_t mem; /*!< Memory of received message */
+ size_t pos; /*!< Received position in memory for sent SMS */
+ } sms_recv; /*!< SMS received info. Use with \ref LWGSM_EVT_SMS_RECV event */
+ struct {
+ lwgsm_sms_entry_t* entry; /*!< SMS entry */
+ lwgsmr_t res; /*!< SMS read result information */
+ } sms_read; /*!< SMS read. Use with \ref LWGSM_EVT_SMS_READ event */
+ struct {
+ lwgsm_mem_t mem; /*!< Memory of deleted message */
+ size_t pos; /*!< Deleted position in memory for sent SMS */
+ lwgsmr_t res; /*!< Operation success */
+ } sms_delete; /*!< SMS delete. Use with \ref LWGSM_EVT_SMS_DELETE event */
+ struct {
+ lwgsm_mem_t mem; /*!< Memory used for scan */
+ lwgsm_sms_entry_t* entries; /*!< Pointer to entries */
+ size_t size; /*!< Number of valid entries */
+ lwgsmr_t res; /*!< Result on command */
+ } sms_list; /*!< SMS list. Use with \ref LWGSM_EVT_SMS_LIST event */
+#endif /* LWGSM_CFG_SMS || __DOXYGEN__ */
+#if LWGSM_CFG_CALL || __DOXYGEN__
+ struct {
+ lwgsmr_t res; /*!< Enable status */
+ } call_enable; /*!< Call enable event. Use with \ref LWGSM_EVT_CALL_ENABLE event */
+ struct {
+ const lwgsm_call_t* call; /*!< Call information */
+ } call_changed; /*!< Call changed info. Use with \ref LWGSM_EVT_CALL_CHANGED event */
+#endif /* LWGSM_CFG_CALL || __DOXYGEN__ */
+#if LWGSM_CFG_PHONEBOOK || __DOXYGEN__
+ struct {
+ lwgsmr_t res; /*!< Enable status */
+ } pb_enable; /*!< Phonebook enable event. Use with \ref LWGSM_EVT_PB_ENABLE event */
+ struct {
+ lwgsm_mem_t mem; /*!< Memory used for scan */
+ lwgsm_pb_entry_t* entries; /*!< Pointer to entries */
+ size_t size; /*!< Number of valid entries */
+ lwgsmr_t res; /*!< Operation success */
+ } pb_list; /*!< Phonebok list. Use with \ref LWGSM_EVT_PB_LIST event */
+ struct {
+ const char* search; /*!< Search string */
+ lwgsm_mem_t mem; /*!< Memory used for scan */
+ lwgsm_pb_entry_t* entries; /*!< Pointer to entries */
+ size_t size; /*!< Number of valid entries */
+ lwgsmr_t res; /*!< Operation success */
+ } pb_search; /*!< Phonebok search list. Use with \ref LWGSM_EVT_PB_SEARCH event */
+#endif /* LWGSM_CFG_PHONEBOOK || __DOXYGEN__ */
+ } evt; /*!< Callback event union */
+} lwgsm_evt_t;
+
+#define LWGSM_SIZET_MAX ((size_t)(-1)) /*!< Maximal value of size_t variable type */
+
+/**
+ * \ingroup LWGSM_LL
+ * \brief Function prototype for AT output data
+ * \param[in] data: Pointer to data to send. This parameter can be set to `NULL`
+ * \param[in] len: Number of bytes to send. This parameter can be set to `0`
+ * to indicate that internal buffer can be flushed to stream.
+ * This is implementation defined and feature might be ignored
+ * \return Number of bytes sent
+ */
+typedef size_t (*lwgsm_ll_send_fn)(const void* data, size_t len);
+
+/**
+ * \ingroup LWGSM_LL
+ * \brief Function prototype for hardware reset of GSM device
+ * \param[in] state: State indicating reset. When set to `1`, reset must be active (usually pin active low),
+ * or set to `0` when reset is cleared
+ * \return `1` on successful action, `0` otherwise
+ */
+typedef uint8_t (*lwgsm_ll_reset_fn)(uint8_t state);
+
+/**
+ * \ingroup LWGSM_LL
+ * \brief Low level user specific functions
+ */
+typedef struct {
+ lwgsm_ll_send_fn send_fn; /*!< Callback function to transmit data */
+ lwgsm_ll_reset_fn reset_fn; /*!< Reset callback function */
+ struct {
+ uint32_t baudrate; /*!< UART baudrate value */
+ } uart; /*!< UART communication parameters */
+} lwgsm_ll_t;
+
+/**
+ * \ingroup LWGSM_TIMEOUT
+ * \brief Timeout callback function prototype
+ * \param[in] arg: Custom user argument
+ */
+typedef void (*lwgsm_timeout_fn)(void* arg);
+
+/**
+ * \ingroup LWGSM_TIMEOUT
+ * \brief Timeout structure
+ */
+typedef struct lwgsm_timeout {
+ struct lwgsm_timeout* next; /*!< Pointer to next timeout entry */
+ uint32_t time; /*!< Time difference from previous entry */
+ void* arg; /*!< Argument to pass to callback function */
+ lwgsm_timeout_fn fn; /*!< Callback function for timeout */
+} lwgsm_timeout_t;
+
+/**
+ * \ingroup LWGSM_BUFF
+ * \brief Buffer structure
+ */
+typedef struct {
+ uint8_t* buff; /*!< Pointer to buffer data.
+ Buffer is considered initialized when `buff != NULL` */
+ size_t size; /*!< Size of buffer data.
+ Size of actual buffer is `1` byte less than this value */
+ size_t r; /*!< Next read pointer.
+ Buffer is considered empty when `r == w` and full when `w == r - 1` */
+ size_t w; /*!< Next write pointer.
+ Buffer is considered empty when `r == w` and full when `w == r - 1` */
+} lwgsm_buff_t;
+
+/**
+ * \ingroup LWGSM_TYPEDEFS
+ * \brief Linear buffer structure
+ */
+typedef struct {
+ uint8_t* buff; /*!< Pointer to buffer data array */
+ size_t len; /*!< Length of buffer array */
+ size_t ptr; /*!< Current buffer pointer */
+} lwgsm_linbuff_t;
+
+/**
+ * \ingroup LWGSM_TYPEDEFS
+ * \brief Function declaration for API function command event callback function
+ * \param[in] res: Operation result, member of \ref lwgsmr_t enumeration
+ * \param[in] arg: Custom user argument
+ */
+typedef void (*lwgsm_api_cmd_evt_fn)(lwgsmr_t res, void* arg);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LWGSM_HDR_DEFS_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_unicode.h b/lwgsm/src/include/lwgsm/lwgsm_unicode.h
similarity index 73%
rename from gsm_at_lib/src/include/gsm/gsm_unicode.h
rename to lwgsm/src/include/lwgsm/lwgsm_unicode.h
index 0a84ab70..2ab6d667 100644
--- a/gsm_at_lib/src/include/gsm/gsm_unicode.h
+++ b/lwgsm/src/include/lwgsm/lwgsm_unicode.h
@@ -1,10 +1,10 @@
-/**
- * \file gsm_unicode.h
+/**
+ * \file lwgsm_unicode.h
* \brief Unicode support
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,28 +26,28 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#ifndef GSM_HDR_UNICODE_H
-#define GSM_HDR_UNICODE_H
+#ifndef LWGSM_HDR_UNICODE_H
+#define LWGSM_HDR_UNICODE_H
+
+#include "lwgsm/lwgsm.h"
#ifdef __cplusplus
extern "C" {
-#endif
-
-#include "gsm/gsm.h"
+#endif /* __cplusplus */
/**
- * \ingroup GSM
- * \defgroup GSM_UNICODE Unicode manager
+ * \ingroup LWGSM
+ * \defgroup LWGSM_UNICODE Unicode manager
* \brief Unicode support manager
* \{
*/
-gsmr_t gsmi_unicode_decode(gsm_unicode_t* uni, uint8_t ch);
+lwgsmr_t lwgsmi_unicode_decode(lwgsm_unicode_t* uni, uint8_t ch);
/**
* \}
@@ -55,6 +55,6 @@ gsmr_t gsmi_unicode_decode(gsm_unicode_t* uni, uint8_t ch);
#ifdef __cplusplus
}
-#endif
+#endif /* __cplusplus */
-#endif /* GSM_HDR_UNICODE_H */
+#endif /* LWGSM_HDR_UNICODE_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_ussd.h b/lwgsm/src/include/lwgsm/lwgsm_ussd.h
similarity index 70%
rename from gsm_at_lib/src/include/gsm/gsm_ussd.h
rename to lwgsm/src/include/lwgsm/lwgsm_ussd.h
index 4ffd947c..26236d05 100644
--- a/gsm_at_lib/src/include/gsm/gsm_ussd.h
+++ b/lwgsm/src/include/lwgsm/lwgsm_ussd.h
@@ -1,10 +1,10 @@
-/**
- * \file gsm_ussd.h
+/**
+ * \file lwgsm_ussd.h
* \brief Unstructured Supplementary Service Data
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,28 +26,28 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#ifndef GSM_HDR_USSD_H
-#define GSM_HDR_USSD_H
+#ifndef LWGSM_HDR_USSD_H
+#define LWGSM_HDR_USSD_H
+
+#include "lwgsm/lwgsm.h"
#ifdef __cplusplus
extern "C" {
-#endif
-
-#include "gsm/gsm.h"
+#endif /* __cplusplus */
/**
- * \ingroup GSM
- * \defgroup GSM_USSD Unstructured Supplementary Service Data
+ * \ingroup LWGSM
+ * \defgroup LWGSM_USSD Unstructured Supplementary Service Data
* \brief Unstructured Supplementary Service Data
* \{
*/
-gsmr_t gsm_ussd_run(const char* code, char* resp, size_t resp_len, const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
+lwgsmr_t lwgsm_ussd_run(const char* code, char* resp, size_t resp_len, const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking);
/**
* \}
@@ -55,6 +55,6 @@ gsmr_t gsm_ussd_run(const char* code, char* resp, size_t resp_len, const gsm_ap
#ifdef __cplusplus
}
-#endif
+#endif /* __cplusplus */
-#endif /* GSM_HDR_HTTP_H */
+#endif /* LWGSM_HDR_HTTP_H */
diff --git a/gsm_at_lib/src/include/gsm/gsm_utils.h b/lwgsm/src/include/lwgsm/lwgsm_utils.h
similarity index 69%
rename from gsm_at_lib/src/include/gsm/gsm_utils.h
rename to lwgsm/src/include/lwgsm/lwgsm_utils.h
index 3c103b3d..eb850077 100644
--- a/gsm_at_lib/src/include/gsm/gsm_utils.h
+++ b/lwgsm/src/include/lwgsm/lwgsm_utils.h
@@ -1,10 +1,10 @@
/**
- * \file gsm_utils.h
+ * \file lwgsm_utils.h
* \brief Utilities
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,47 +26,47 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#ifndef GSM_HDR_UTILS_H
-#define GSM_HDR_UTILS_H
+#ifndef LWGSM_HDR_UTILS_H
+#define LWGSM_HDR_UTILS_H
+
+#include "lwgsm/lwgsm.h"
#ifdef __cplusplus
extern "C" {
-#endif
-
-#include "gsm/gsm.h"
+#endif /* __cplusplus */
/**
- * \ingroup GSM
- * \defgroup GSM_UTILS Utilities
+ * \ingroup LWGSM
+ * \defgroup LWGSM_UTILS Utilities
* \brief Utilities
* \{
*/
/**
* \brief Assert an input parameter if in valid range
- * \note Since this is a macro, it may only be used on a functions where return status is of type \ref gsmr_t enumeration
+ * \note Since this is a macro, it may only be used on a functions where return status is of type \ref lwgsmr_t enumeration
* \param[in] msg: message to print to debug if test fails
* \param[in] c: Condition to test
*/
-#define GSM_ASSERT(msg, c) do { \
- if (!(c)) { \
- GSM_DEBUGF(GSM_CFG_DBG_ASSERT, "Wrong parameters on file %s and line %d: %s\r\n", __FILE__, (int)__LINE__, msg);\
- return gsmPARERR; \
- } \
-} while (0)
+#define LWGSM_ASSERT(msg, c) do { \
+ if (!(c)) { \
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_ASSERT, "Wrong parameters on file %s and line %d: %s\r\n", __FILE__, (int)__LINE__, msg);\
+ return lwgsmPARERR; \
+ } \
+ } while (0)
/**
- * \brief Align `x` value to specific number of bytes, provided by \ref GSM_CFG_MEM_ALIGNMENT configuration
+ * \brief Align `x` value to specific number of bytes, provided by \ref LWGSM_CFG_MEM_ALIGNMENT configuration
* \param[in] x: Input value to align
* \return Input value aligned to specific number of bytes
* \hideinitializer
*/
-#define GSM_MEM_ALIGN(x) ((x + (GSM_CFG_MEM_ALIGNMENT - 1)) & ~(GSM_CFG_MEM_ALIGNMENT - 1))
+#define LWGSM_MEM_ALIGN(x) ((x + (LWGSM_CFG_MEM_ALIGNMENT - 1)) & ~(LWGSM_CFG_MEM_ALIGNMENT - 1))
/**
* \brief Get minimal value between `x` and `y` inputs
@@ -75,7 +75,7 @@ extern "C" {
* \return Minimal value between `x` and `y` parameters
* \hideinitializer
*/
-#define GSM_MIN(x, y) ((x) < (y) ? (x) : (y))
+#define LWGSM_MIN(x, y) ((x) < (y) ? (x) : (y))
/**
* \brief Get maximal value between `x` and `y` inputs
@@ -84,7 +84,7 @@ extern "C" {
* \return Maximal value between `x` and `y` parameters
* \hideinitializer
*/
-#define GSM_MAX(x, y) ((x) > (y) ? (x) : (y))
+#define LWGSM_MAX(x, y) ((x) > (y) ? (x) : (y))
/**
* \brief Get size of statically declared array
@@ -92,7 +92,7 @@ extern "C" {
* \return Number of array elements
* \hideinitializer
*/
-#define GSM_ARRAYSIZE(x) (sizeof(x) / sizeof((x)[0]))
+#define LWGSM_ARRAYSIZE(x) (sizeof(x) / sizeof((x)[0]))
/**
* \brief Unused argument in a function call
@@ -101,56 +101,56 @@ extern "C" {
* \param[in] x: Variable which is not used
* \hideinitializer
*/
-#define GSM_UNUSED(x) ((void)(x))
+#define LWGSM_UNUSED(x) ((void)(x))
/**
* \brief Get input value casted to `unsigned 32-bit` value
* \param[in] x: Input value
* \hideinitializer
*/
-#define GSM_U32(x) ((uint32_t)(x))
+#define LWGSM_U32(x) ((uint32_t)(x))
/**
* \brief Get input value casted to `unsigned 16-bit` value
* \param[in] x: Input value
* \hideinitializer
*/
-#define GSM_U16(x) ((uint16_t)(x))
+#define LWGSM_U16(x) ((uint16_t)(x))
/**
* \brief Get input value casted to `unsigned 8-bit` value
* \param[in] x: Input value
* \hideinitializer
*/
-#define GSM_U8(x) ((uint8_t)(x))
+#define LWGSM_U8(x) ((uint8_t)(x))
/**
* \brief Get input value casted to `signed 32-bit` value
* \param[in] x: Input value
* \hideinitializer
*/
-#define GSM_I32(x) ((int32_t)(x))
+#define LWGSM_I32(x) ((int32_t)(x))
/**
* \brief Get input value casted to `signed 16-bit` value
* \param[in] x: Input value
* \hideinitializer
*/
-#define GSM_I16(x) ((int16_t)(x))
+#define LWGSM_I16(x) ((int16_t)(x))
/**
* \brief Get input value casted to `signed 8-bit` value
* \param[in] x: Input value
* \hideinitializer
*/
-#define GSM_I8(x) ((int8_t)(x))
+#define LWGSM_I8(x) ((int8_t)(x))
/**
* \brief Get input value casted to `size_t` value
* \param[in] x: Input value
* \hideinitializer
*/
-#define GSM_SZ(x) ((size_t)(x))
+#define LWGSM_SZ(x) ((size_t)(x))
/**
* \brief Convert `unsigned 32-bit` number to string
@@ -159,7 +159,7 @@ extern "C" {
* \return Pointer to output variable
* \hideinitializer
*/
-#define gsm_u32_to_str(num, out) gsm_u32_to_gen_str(GSM_U32(num), (out), 0, 0)
+#define lwgsm_u32_to_str(num, out) lwgsm_u32_to_gen_str(LWGSM_U32(num), (out), 0, 0)
/**
* \brief Convert `unsigned 32-bit` number to HEX string
@@ -170,7 +170,7 @@ extern "C" {
* \return Pointer to output variable
* \hideinitializer
*/
-#define gsm_u32_to_hex_str(num, out, w) gsm_u32_to_gen_str(GSM_U32(num), (out), 1, (w))
+#define lwgsm_u32_to_hex_str(num, out, w) lwgsm_u32_to_gen_str(LWGSM_U32(num), (out), 1, (w))
/**
* \brief Convert `signed 32-bit` number to string
@@ -179,7 +179,7 @@ extern "C" {
* \return Pointer to output variable
* \hideinitializer
*/
-#define gsm_i32_to_str(num, out) gsm_i32_to_gen_str(GSM_I32(num), (out))
+#define lwgsm_i32_to_str(num, out) lwgsm_i32_to_gen_str(LWGSM_I32(num), (out))
/**
* \brief Convert `unsigned 16-bit` number to string
@@ -188,7 +188,7 @@ extern "C" {
* \return Pointer to output variable
* \hideinitializer
*/
-#define gsm_u16_to_str(num, out) gsm_u32_to_gen_str(GSM_U32(GSM_U16(num)), (out), 0, 0)
+#define lwgsm_u16_to_str(num, out) lwgsm_u32_to_gen_str(LWGSM_U32(LWGSM_U16(num)), (out), 0, 0)
/**
* \brief Convert `unsigned 16-bit` number to HEX string
@@ -199,7 +199,7 @@ extern "C" {
* \return Pointer to output variable
* \hideinitializer
*/
-#define gsm_u16_to_hex_str(num, out, w) gsm_u32_to_gen_str(GSM_U32(GSM_U16(num)), (out), 1, (w))
+#define lwgsm_u16_to_hex_str(num, out, w) lwgsm_u32_to_gen_str(LWGSM_U32(LWGSM_U16(num)), (out), 1, (w))
/**
* \brief Convert `signed 16-bit` number to string
@@ -208,7 +208,7 @@ extern "C" {
* \return Pointer to output variable
* \hideinitializer
*/
-#define gsm_i16_to_str(num, out) gsm_i32_to_gen_str(GSM_I32(GSM_I16(num)), (out))
+#define lwgsm_i16_to_str(num, out) lwgsm_i32_to_gen_str(LWGSM_I32(LWGSM_I16(num)), (out))
/**
* \brief Convert `unsigned 8-bit` number to string
@@ -217,7 +217,7 @@ extern "C" {
* \return Pointer to output variable
* \hideinitializer
*/
-#define gsm_u8_to_str(num, out) gsm_u32_to_gen_str(GSM_U32(GSM_U8(num)), (out), 0, 0)
+#define lwgsm_u8_to_str(num, out) lwgsm_u32_to_gen_str(LWGSM_U32(LWGSM_U8(num)), (out), 0, 0)
/**
* \brief Convert `unsigned 16-bit` number to HEX string
@@ -228,7 +228,7 @@ extern "C" {
* \return Pointer to output variable
* \hideinitializer
*/
-#define gsm_u8_to_hex_str(num, out, w) gsm_u32_to_gen_str(GSM_U32(GSM_U8(num)), (out), 1, (w))
+#define lwgsm_u8_to_hex_str(num, out, w) lwgsm_u32_to_gen_str(LWGSM_U32(LWGSM_U8(num)), (out), 1, (w))
/**
* \brief Convert `signed 8-bit` number to string
@@ -237,10 +237,10 @@ extern "C" {
* \return Pointer to output variable
* \hideinitializer
*/
-#define gsm_i8_to_str(num, out) gsm_i32_to_gen_str(GSM_I32(GSM_I8(num)), (out))
+#define lwgsm_i8_to_str(num, out) lwgsm_i32_to_gen_str(LWGSM_I32(LWGSM_I8(num)), (out))
-char * gsm_u32_to_gen_str(uint32_t num, char* out, uint8_t is_hex, uint8_t padding);
-char * gsm_i32_to_gen_str(int32_t num, char* out);
+char* lwgsm_u32_to_gen_str(uint32_t num, char* out, uint8_t is_hex, uint8_t padding);
+char* lwgsm_i32_to_gen_str(int32_t num, char* out);
/**
* \}
@@ -248,6 +248,6 @@ char * gsm_i32_to_gen_str(int32_t num, char* out);
#ifdef __cplusplus
}
-#endif
+#endif /* __cplusplus */
-#endif /* GSM_HDR_UTILITIES_H */
+#endif /* LWGSM_HDR_UTILITIES_H */
diff --git a/gsm_at_lib/src/include/system/gsm_ll.h b/lwgsm/src/include/system/lwgsm_ll.h
similarity index 78%
rename from gsm_at_lib/src/include/system/gsm_ll.h
rename to lwgsm/src/include/system/lwgsm_ll.h
index 793f966e..2a14c2c9 100644
--- a/gsm_at_lib/src/include/system/gsm_ll.h
+++ b/lwgsm/src/include/system/lwgsm_ll.h
@@ -1,10 +1,10 @@
/**
- * \file gsm_ll.h
+ * \file lwgsm_ll.h
* \brief Low-level communication implementation
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,29 +26,28 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#ifndef GSM_HDR_LL_H
-#define GSM_HDR_LL_H
+#ifndef LWGSM_HDR_LL_H
+#define LWGSM_HDR_LL_H
+
+#include "lwgsm/lwgsm.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
-#include "gsm/gsm.h"
-
/**
- * \ingroup GSM_PORT
- * \defgroup GSM_LL Low-level functions
+ * \defgroup LWGSM_LL Low-level functions
* \brief Low-level communication functions
* \{
*/
-gsmr_t gsm_ll_init(gsm_ll_t* ll);
-gsmr_t gsm_ll_deinit(gsm_ll_t* ll);
+lwgsmr_t lwgsm_ll_init(lwgsm_ll_t* ll);
+lwgsmr_t lwgsm_ll_deinit(lwgsm_ll_t* ll);
/**
* \}
@@ -58,4 +57,4 @@ gsmr_t gsm_ll_deinit(gsm_ll_t* ll);
}
#endif /* __cplusplus */
-#endif /* GSM_HDR_LL_H */
+#endif /* LWGSM_HDR_LL_H */
diff --git a/lwgsm/src/include/system/lwgsm_sys.h b/lwgsm/src/include/system/lwgsm_sys.h
new file mode 100644
index 00000000..11ad52ad
--- /dev/null
+++ b/lwgsm/src/include/system/lwgsm_sys.h
@@ -0,0 +1,144 @@
+/**
+ * \file lwgsm_sys.h
+ * \brief Main system include file which decides later include file
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM - Lightweight GSM-AT library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+#ifndef LWGSM_HDR_MAIN_SYS_H
+#define LWGSM_HDR_MAIN_SYS_H
+
+#include
+#include "lwgsm/lwgsm_opt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * \defgroup LWGSM_SYS System functions
+ * \brief System based function for OS management, timings, etc
+ * \{
+ */
+
+/**
+ * \brief Thread function prototype
+ */
+typedef void (*lwgsm_sys_thread_fn)(void*);
+
+/* Include system port file from portable folder */
+#include "lwgsm_sys_port.h"
+
+/**
+ * \anchor LWGSM_SYS_CORE
+ * \name Main
+ */
+
+uint8_t lwgsm_sys_init(void);
+uint32_t lwgsm_sys_now(void);
+
+uint8_t lwgsm_sys_protect(void);
+uint8_t lwgsm_sys_unprotect(void);
+
+/**
+ * \}
+ */
+
+/**
+ * \anchor LWGSM_SYS_MUTEX
+ * \name Mutex
+ */
+
+uint8_t lwgsm_sys_mutex_create(lwgsm_sys_mutex_t* p);
+uint8_t lwgsm_sys_mutex_delete(lwgsm_sys_mutex_t* p);
+uint8_t lwgsm_sys_mutex_lock(lwgsm_sys_mutex_t* p);
+uint8_t lwgsm_sys_mutex_unlock(lwgsm_sys_mutex_t* p);
+uint8_t lwgsm_sys_mutex_isvalid(lwgsm_sys_mutex_t* p);
+uint8_t lwgsm_sys_mutex_invalid(lwgsm_sys_mutex_t* p);
+
+/**
+ * \}
+ */
+
+/**
+ * \anchor LWGSM_SYS_SEM
+ * \name Semaphores
+ */
+
+uint8_t lwgsm_sys_sem_create(lwgsm_sys_sem_t* p, uint8_t cnt);
+uint8_t lwgsm_sys_sem_delete(lwgsm_sys_sem_t* p);
+uint32_t lwgsm_sys_sem_wait(lwgsm_sys_sem_t* p, uint32_t timeout);
+uint8_t lwgsm_sys_sem_release(lwgsm_sys_sem_t* p);
+uint8_t lwgsm_sys_sem_isvalid(lwgsm_sys_sem_t* p);
+uint8_t lwgsm_sys_sem_invalid(lwgsm_sys_sem_t* p);
+
+/**
+ * \}
+ */
+
+/**
+ * \anchor LWGSM_SYS_MBOX
+ * \name Message queues
+ */
+
+uint8_t lwgsm_sys_mbox_create(lwgsm_sys_mbox_t* b, size_t size);
+uint8_t lwgsm_sys_mbox_delete(lwgsm_sys_mbox_t* b);
+uint32_t lwgsm_sys_mbox_put(lwgsm_sys_mbox_t* b, void* m);
+uint32_t lwgsm_sys_mbox_get(lwgsm_sys_mbox_t* b, void** m, uint32_t timeout);
+uint8_t lwgsm_sys_mbox_putnow(lwgsm_sys_mbox_t* b, void* m);
+uint8_t lwgsm_sys_mbox_getnow(lwgsm_sys_mbox_t* b, void** m);
+uint8_t lwgsm_sys_mbox_isvalid(lwgsm_sys_mbox_t* b);
+uint8_t lwgsm_sys_mbox_invalid(lwgsm_sys_mbox_t* b);
+
+/**
+ * \}
+ */
+
+/**
+ * \anchor LWGSM_SYS_THREAD
+ * \name Threads
+ */
+
+uint8_t lwgsm_sys_thread_create(lwgsm_sys_thread_t* t, const char* name, lwgsm_sys_thread_fn thread_func, void* const arg, size_t stack_size, lwgsm_sys_thread_prio_t prio);
+uint8_t lwgsm_sys_thread_terminate(lwgsm_sys_thread_t* t);
+uint8_t lwgsm_sys_thread_yield(void);
+
+/**
+ * \}
+ */
+
+/**
+ * \}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LWGSM_HDR_MAIN_LL_H */
diff --git a/gsm_at_lib/src/include/system/gsm_sys_cmsis_os.h b/lwgsm/src/include/system/port/cmsis_os/lwgsm_sys_port.h
similarity index 55%
rename from gsm_at_lib/src/include/system/gsm_sys_cmsis_os.h
rename to lwgsm/src/include/system/port/cmsis_os/lwgsm_sys_port.h
index 4a3aeccc..3c773989 100644
--- a/gsm_at_lib/src/include/system/gsm_sys_cmsis_os.h
+++ b/lwgsm/src/include/system/port/cmsis_os/lwgsm_sys_port.h
@@ -1,10 +1,10 @@
-/**
- * \file gsm_sys_cmsis_os.h
- * \brief CMSIS-OS based system file
+/**
+ * \file lwgsm_sys_port.h
+ * \brief System dependent functions for CMSIS-OS based operating system
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,43 +26,42 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#ifndef GSM_HDR_SYSTEM_CMSIS_OS_H
-#define GSM_HDR_SYSTEM_CMSIS_OS_H
+#ifndef LWGSM_HDR_SYSTEM_PORT_H
+#define LWGSM_HDR_SYSTEM_PORT_H
+
+#include
+#include
+#include "lwgsm/lwgsm_opt.h"
+#include "cmsis_os.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
-#include
-#include
+#if LWGSM_CFG_OS && !__DOXYGEN__
-#include "gsm_config.h"
-#include "gsm_sys.h"
-
-#if GSM_CFG_OS && !__DOXYGEN__
-#include "cmsis_os.h"
+typedef osMutexId_t lwgsm_sys_mutex_t;
+typedef osSemaphoreId_t lwgsm_sys_sem_t;
+typedef osMessageQueueId_t lwgsm_sys_mbox_t;
+typedef osThreadId_t lwgsm_sys_thread_t;
+typedef osPriority_t lwgsm_sys_thread_prio_t;
-typedef osMutexId gsm_sys_mutex_t;
-typedef osSemaphoreId gsm_sys_sem_t;
-typedef osMessageQId gsm_sys_mbox_t;
-typedef osThreadId gsm_sys_thread_t;
-typedef osPriority gsm_sys_thread_prio_t;
-#define GSM_SYS_MBOX_NULL (gsm_sys_mbox_t)0
-#define GSM_SYS_SEM_NULL (gsm_sys_sem_t)0
-#define GSM_SYS_MUTEX_NULL (gsm_sys_mutex_t)0
-#define GSM_SYS_TIMEOUT ((uint32_t)osWaitForever)
-#define GSM_SYS_THREAD_PRIO (osPriorityNormal)
-#define GSM_SYS_THREAD_SS (512)
+#define LWGSM_SYS_MUTEX_NULL ((lwgsm_sys_mutex_t)0)
+#define LWGSM_SYS_SEM_NULL ((lwgsm_sys_sem_t)0)
+#define LWGSM_SYS_MBOX_NULL ((lwgsm_sys_mbox_t)0)
+#define LWGSM_SYS_TIMEOUT ((uint32_t)osWaitForever)
+#define LWGSM_SYS_THREAD_PRIO (osPriorityNormal)
+#define LWGSM_SYS_THREAD_SS (512)
-#endif /* GSM_CFG_OS && !__DOXYGEN__ */
+#endif /* LWGSM_CFG_OS && !__DOXYGEN__ */
#ifdef __cplusplus
-};
+}
#endif /* __cplusplus */
-#endif /* GSM_HDR_SYSTEM_CMSIS_OS_H */
+#endif /* LWGSM_HDR_SYSTEM_PORT_H */
diff --git a/lwgsm/src/include/system/port/template/lwgsm_sys_port.h b/lwgsm/src/include/system/port/template/lwgsm_sys_port.h
new file mode 100644
index 00000000..75c41f14
--- /dev/null
+++ b/lwgsm/src/include/system/port/template/lwgsm_sys_port.h
@@ -0,0 +1,143 @@
+/**
+ * \file lwgsm_sys_port.h
+ * \brief Template file for system functions
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM - Lightweight GSM-AT library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+#ifndef LWGSM_HDR_SYSTEM_PORT_H
+#define LWGSM_HDR_SYSTEM_PORT_H
+
+#include
+#include
+#include "lwgsm/lwgsm_opt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * \addtogroup LWGSM_SYS
+ * \{
+ */
+
+#if LWGSM_CFG_OS || __DOXYGEN__
+
+/* Include any OS specific features */
+#include "cmsis_os.h"
+
+/**
+ * \brief System mutex type
+ *
+ * It is used by middleware as base type of mutex.
+ */
+typedef osMutexId_t lwgsm_sys_mutex_t;
+
+/**
+ * \brief System semaphore type
+ *
+ * It is used by middleware as base type of mutex.
+ */
+typedef osSemaphoreId_t lwgsm_sys_sem_t;
+
+/**
+ * \brief System message queue type
+ *
+ * It is used by middleware as base type of mutex.
+ */
+typedef osMessageQueueId_t lwgsm_sys_mbox_t;
+
+/**
+ * \brief System thread ID type
+ */
+typedef osThreadId_t lwgsm_sys_thread_t;
+
+/**
+ * \brief System thread priority type
+ *
+ * It is used as priority type for system function,
+ * to start new threads by middleware.
+ */
+typedef osPriority lwgsm_sys_thread_prio_t;
+
+/**
+ * \brief Mutex invalid value
+ *
+ * Value assigned to \ref lwgsm_sys_mutex_t type when it is not valid.
+ */
+#define LWGSM_SYS_MUTEX_NULL ((lwgsm_sys_mutex_t)0)
+
+/**
+ * \brief Semaphore invalid value
+ *
+ * Value assigned to \ref lwgsm_sys_sem_t type when it is not valid.
+ */
+#define LWGSM_SYS_SEM_NULL ((lwgsm_sys_sem_t)0)
+
+/**
+ * \brief Message box invalid value
+ *
+ * Value assigned to \ref lwgsm_sys_mbox_t type when it is not valid.
+ */
+#define LWGSM_SYS_MBOX_NULL ((lwgsm_sys_mbox_t)0)
+
+/**
+ * \brief OS timeout value
+ *
+ * Value returned by operating system functions (mutex wait, sem wait, mbox wait)
+ * when it returns timeout and does not give valid value to application
+ */
+#define LWGSM_SYS_TIMEOUT ((uint32_t)osWaitForever)
+
+/**
+ * \brief Default thread priority value used by middleware to start built-in threads
+ *
+ * Threads can well operate with normal (default) priority and do not require
+ * any special feature in terms of priority for prioer operation.
+ */
+#define LWGSM_SYS_THREAD_PRIO (osPriorityNormal)
+
+/**
+ * \brief Stack size in units of bytes for system threads
+ *
+ * It is used as default stack size for all built-in threads.
+ */
+#define LWGSM_SYS_THREAD_SS (1024)
+
+#endif /* LWGSM_CFG_OS || __DOXYGEN__ */
+
+/**
+ * \}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LWGSM_HDR_SYSTEM_PORT_H */
diff --git a/gsm_at_lib/src/include/system/gsm_sys_win32.h b/lwgsm/src/include/system/port/win32/lwgsm_sys_port.h
similarity index 59%
rename from gsm_at_lib/src/include/system/gsm_sys_win32.h
rename to lwgsm/src/include/system/port/win32/lwgsm_sys_port.h
index 1a837fdf..8276f751 100644
--- a/gsm_at_lib/src/include/system/gsm_sys_win32.h
+++ b/lwgsm/src/include/system/port/win32/lwgsm_sys_port.h
@@ -1,10 +1,10 @@
-/**
- * \file gsm_sys_win32.h
+/**
+ * \file lwgsm_sys_port.h
* \brief WIN32 based system file implementation
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,42 +26,42 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#ifndef GSM_HDR_SYSTEM_WIN32_H
-#define GSM_HDR_SYSTEM_WIN32_H
+#ifndef LWGSM_HDR_SYSTEM_PORT_H
+#define LWGSM_HDR_SYSTEM_PORT_H
+
+#include
+#include
+#include "lwgsm/lwgsm_opt.h"
+#include "windows.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
-#include
-#include
-
-#include "gsm_config.h"
-#include "windows.h"
+#if LWGSM_CFG_OS && !__DOXYGEN__
-#if GSM_CFG_OS && !__DOXYGEN__
+typedef HANDLE lwgsm_sys_mutex_t;
+typedef HANDLE lwgsm_sys_sem_t;
+typedef HANDLE lwgsm_sys_mbox_t;
+typedef HANDLE lwgsm_sys_thread_t;
+typedef int lwgsm_sys_thread_prio_t;
-typedef HANDLE gsm_sys_mutex_t;
-typedef HANDLE gsm_sys_sem_t;
-typedef HANDLE gsm_sys_mbox_t;
-typedef HANDLE gsm_sys_thread_t;
-typedef int gsm_sys_thread_prio_t;
-#define GSM_SYS_MBOX_NULL (HANDLE)0
-#define GSM_SYS_SEM_NULL (HANDLE)0
-#define GSM_SYS_MUTEX_NULL (HANDLE)0
-#define GSM_SYS_TIMEOUT (INFINITE)
-#define GSM_SYS_THREAD_PRIO (0)
-#define GSM_SYS_THREAD_SS (4096)
+#define LWGSM_SYS_MUTEX_NULL ((HANDLE)0)
+#define LWGSM_SYS_SEM_NULL ((HANDLE)0)
+#define LWGSM_SYS_MBOX_NULL ((HANDLE)0)
+#define LWGSM_SYS_TIMEOUT (INFINITE)
+#define LWGSM_SYS_THREAD_PRIO (0)
+#define LWGSM_SYS_THREAD_SS (4096)
-#endif /* GSM_CFG_OS && !__DOXYGEN__ */
+#endif /* LWGSM_CFG_OS && !__DOXYGEN__ */
#ifdef __cplusplus
-};
+}
#endif /* __cplusplus */
-#endif /* GSM_HDR_SYSTEM_WIN32_H */
+#endif /* LWGSM_HDR_SYSTEM_PORT_H */
diff --git a/lwgsm/src/lwgsm/lwgsm.c b/lwgsm/src/lwgsm/lwgsm.c
new file mode 100644
index 00000000..3213be33
--- /dev/null
+++ b/lwgsm/src/lwgsm/lwgsm.c
@@ -0,0 +1,334 @@
+/**
+ * \file lwgsm.c
+ * \brief Main GSM core file
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM - Lightweight GSM-AT library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+#include "lwgsm/lwgsm_private.h"
+#include "lwgsm/lwgsm_mem.h"
+#include "lwgsm/lwgsm_threads.h"
+#include "system/lwgsm_ll.h"
+
+#if LWGSM_CFG_OS != 1
+#error LWGSM_CFG_OS must be set to 1!
+#endif
+
+static lwgsmr_t def_callback(lwgsm_evt_t* cb);
+static lwgsm_evt_func_t def_evt_link;
+
+lwgsm_t lwgsm;
+
+/**
+ * \brief Default callback function for events
+ * \param[in] evt: Pointer to callback data structure
+ * \return Member of \ref lwgsmr_t enumeration
+ */
+static lwgsmr_t
+def_callback(lwgsm_evt_t* evt) {
+ LWGSM_UNUSED(evt);
+ return lwgsmOK;
+}
+
+/**
+ * \brief Init and prepare GSM stack for device operation
+ * \note Function must be called from operating system thread context.
+ * It creates necessary threads and waits them to start, thus running operating system is important.
+ * - When \ref LWGSM_CFG_RESET_ON_INIT is enabled, reset sequence will be sent to device
+ * otherwise manual call to \ref lwgsm_reset is required to setup device
+ *
+ * \param[in] evt_func: Global event callback function for all major events
+ * \param[in] blocking: Status whether command should be blocking or not.
+ * Used when \ref LWGSM_CFG_RESET_ON_INIT is enabled.
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
+ */
+lwgsmr_t
+lwgsm_init(lwgsm_evt_fn evt_func, const uint32_t blocking) {
+ lwgsmr_t res = lwgsmOK;
+
+ lwgsm.status.f.initialized = 0; /* Clear possible init flag */
+
+ def_evt_link.fn = evt_func != NULL ? evt_func : def_callback;
+ lwgsm.evt_func = &def_evt_link; /* Set callback function */
+
+ if (!lwgsm_sys_init()) { /* Init low-level system */
+ goto cleanup;
+ }
+
+ if (!lwgsm_sys_sem_create(&lwgsm.sem_sync, 1)) {/* Create sync semaphore between threads */
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_INIT | LWGSM_DBG_LVL_SEVERE | LWGSM_DBG_TYPE_TRACE,
+ "[CORE] Cannot allocate sync semaphore!\r\n");
+ goto cleanup;
+ }
+
+ /* Create message queues */
+ if (!lwgsm_sys_mbox_create(&lwgsm.mbox_producer, LWGSM_CFG_THREAD_PRODUCER_MBOX_SIZE)) {
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_INIT | LWGSM_DBG_LVL_SEVERE | LWGSM_DBG_TYPE_TRACE,
+ "[CORE] Cannot allocate producer mbox queue!\r\n");
+ goto cleanup;
+ }
+ if (!lwgsm_sys_mbox_create(&lwgsm.mbox_process, LWGSM_CFG_THREAD_PROCESS_MBOX_SIZE)) {
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_INIT | LWGSM_DBG_LVL_SEVERE | LWGSM_DBG_TYPE_TRACE,
+ "[CORE] Cannot allocate process mbox queue!\r\n");
+ goto cleanup;
+ }
+
+ /* Create threads */
+ lwgsm_sys_sem_wait(&lwgsm.sem_sync, 0);
+ if (!lwgsm_sys_thread_create(&lwgsm.thread_produce, "lwgsm_produce", lwgsm_thread_produce, &lwgsm.sem_sync, LWGSM_SYS_THREAD_SS, LWGSM_SYS_THREAD_PRIO)) {
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_INIT | LWGSM_DBG_LVL_SEVERE | LWGSM_DBG_TYPE_TRACE,
+ "[CORE] Cannot create producing thread!\r\n");
+ lwgsm_sys_sem_release(&lwgsm.sem_sync); /* Release semaphore and return */
+ goto cleanup;
+ }
+ lwgsm_sys_sem_wait(&lwgsm.sem_sync, 0); /* Wait semaphore, should be unlocked in produce thread */
+ if (!lwgsm_sys_thread_create(&lwgsm.thread_process, "lwgsm_process", lwgsm_thread_process, &lwgsm.sem_sync, LWGSM_SYS_THREAD_SS, LWGSM_SYS_THREAD_PRIO)) {
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_INIT | LWGSM_DBG_LVL_SEVERE | LWGSM_DBG_TYPE_TRACE,
+ "[CORE] Cannot create processing thread!\r\n");
+ lwgsm_sys_thread_terminate(&lwgsm.thread_produce); /* Delete produce thread */
+ lwgsm_sys_sem_release(&lwgsm.sem_sync); /* Release semaphore and return */
+ goto cleanup;
+ }
+ lwgsm_sys_sem_wait(&lwgsm.sem_sync, 0); /* Wait semaphore, should be unlocked in produce thread */
+ lwgsm_sys_sem_release(&lwgsm.sem_sync); /* Release semaphore manually */
+
+ lwgsm_core_lock();
+ lwgsm.ll.uart.baudrate = LWGSM_CFG_AT_PORT_BAUDRATE;
+ lwgsm_ll_init(&lwgsm.ll); /* Init low-level communication */
+
+#if !LWGSM_CFG_INPUT_USE_PROCESS
+ lwgsm_buff_init(&lwgsm.buff, LWGSM_CFG_RCV_BUFF_SIZE); /* Init buffer for input data */
+#endif /* !LWGSM_CFG_INPUT_USE_PROCESS */
+
+ lwgsm.status.f.initialized = 1; /* We are initialized now */
+ lwgsm.status.f.dev_present = 1; /* We assume device is present at this point */
+
+ lwgsmi_send_cb(LWGSM_EVT_INIT_FINISH); /* Call user callback function */
+
+ /*
+ * Call reset command and call default
+ * AT commands to prepare basic setup for device
+ */
+#if LWGSM_CFG_RESET_ON_INIT
+ if (lwgsm.status.f.dev_present) {
+ lwgsm_core_unlock();
+ res = lwgsm_reset_with_delay(LWGSM_CFG_RESET_DELAY_DEFAULT, NULL, NULL, blocking); /* Send reset sequence with delay */
+ lwgsm_core_lock();
+ }
+#else /* LWGSM_CFG_RESET_ON_INIT */
+ LWGSM_UNUSED(blocking);
+#endif /* !LWGSM_CFG_RESET_ON_INIT */
+ lwgsm_core_unlock();
+
+ return res;
+
+cleanup:
+ if (lwgsm_sys_mbox_isvalid(&lwgsm.mbox_producer)) {
+ lwgsm_sys_mbox_delete(&lwgsm.mbox_producer);
+ lwgsm_sys_mbox_invalid(&lwgsm.mbox_producer);
+ }
+ if (lwgsm_sys_mbox_isvalid(&lwgsm.mbox_process)) {
+ lwgsm_sys_mbox_delete(&lwgsm.mbox_process);
+ lwgsm_sys_mbox_invalid(&lwgsm.mbox_process);
+ }
+ if (lwgsm_sys_sem_isvalid(&lwgsm.sem_sync)) {
+ lwgsm_sys_sem_delete(&lwgsm.sem_sync);
+ lwgsm_sys_sem_invalid(&lwgsm.sem_sync);
+ }
+ return lwgsmERRMEM;
+}
+
+/**
+ * \brief Execute reset and send default commands
+ * \param[in] evt_fn: Callback function called when command is finished. Set to `NULL` when not used
+ * \param[in] evt_arg: Custom argument for event callback function
+ * \param[in] blocking: Status whether command should be blocking or not
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
+ */
+lwgsmr_t
+lwgsm_reset(const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ return lwgsm_reset_with_delay(0, evt_fn, evt_arg, blocking);
+}
+
+/**
+ * \brief Execute reset and send default commands with delay
+ * \param[in] delay: Number of milliseconds to wait before initiating first command to device
+ * \param[in] evt_fn: Callback function called when command is finished. Set to `NULL` when not used
+ * \param[in] evt_arg: Custom argument for event callback function
+ * \param[in] blocking: Status whether command should be blocking or not
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
+ */
+lwgsmr_t
+lwgsm_reset_with_delay(uint32_t delay,
+ const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
+
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_RESET;
+ LWGSM_MSG_VAR_REF(msg).msg.reset.delay = delay;
+
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 60000);
+}
+
+/**
+ * \brief Lock stack from multi-thread access, enable atomic access to core
+ *
+ * If lock was `0` prior function call, lock is enabled and increased
+ *
+ * \note Function may be called multiple times to increase locks.
+ * Application must take care to call \ref lwgsm_core_unlock
+ * the same amount of time to make sure lock gets back to `0`
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
+ */
+lwgsmr_t
+lwgsm_core_lock(void) {
+ lwgsm_sys_protect();
+ ++lwgsm.locked_cnt;
+ return lwgsmOK;
+}
+
+/**
+ * \brief Unlock stack for multi-thread access
+ *
+ * Used in conjunction with \ref lwgsm_core_lock function
+ *
+ * If lock was non-zero before function call, lock is decreased.
+ * When `lock == 0`, protection is disabled and other threads may access to core
+ *
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
+ */
+lwgsmr_t
+lwgsm_core_unlock(void) {
+ --lwgsm.locked_cnt;
+ lwgsm_sys_unprotect();
+ return lwgsmOK;
+}
+
+/**
+ * \brief Delay for amount of milliseconds
+ *
+ * Delay is based on operating system semaphores.
+ * It locks semaphore and waits for timeout in `ms` time.
+ * Based on operating system, thread may be put to \e blocked list during delay and may improve execution speed
+ *
+ * \param[in] ms: Milliseconds to delay
+ * \return `1` on success, `0` otherwise
+ */
+uint8_t
+lwgsm_delay(uint32_t ms) {
+ lwgsm_sys_sem_t sem;
+ if (ms == 0) {
+ return 1;
+ }
+ if (lwgsm_sys_sem_create(&sem, 0)) {
+ lwgsm_sys_sem_wait(&sem, ms);
+ lwgsm_sys_sem_release(&sem);
+ lwgsm_sys_sem_delete(&sem);
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * \brief Set modem function mode
+ * \note Use this function to set modem to normal or low-power mode
+ * \param[in] mode: Mode status. Set to `1` for full functionality or `0` for low-power mode (no functionality)
+ * \param[in] evt_fn: Callback function called when command is finished. Set to `NULL` when not used
+ * \param[in] evt_arg: Custom argument for event callback function
+ * \param[in] blocking: Status whether command should be blocking or not
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
+ */
+lwgsmr_t
+lwgsm_set_func_mode(uint8_t mode,
+ const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
+
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_CFUN_SET;
+ LWGSM_MSG_VAR_REF(msg).msg.cfun.mode = mode;
+
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 60000);
+}
+
+/**
+ * \brief Notify stack if device is present or not
+ *
+ * Use this function to notify stack that device is not physically connected
+ * and not ready to communicate with host device
+ *
+ * \param[in] present: Flag indicating device is present
+ * \param[in] evt_fn: Callback function called when command is finished. Set to `NULL` when not used
+ * \param[in] evt_arg: Custom argument for event callback function
+ * \param[in] blocking: Status whether command should be blocking or not
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
+ */
+lwgsmr_t
+lwgsm_device_set_present(uint8_t present,
+ const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ lwgsmr_t res = lwgsmOK;
+ lwgsm_core_lock();
+ present = present ? 1 : 0;
+ if (present != lwgsm.status.f.dev_present) {
+ lwgsm.status.f.dev_present = present;
+
+ if (!lwgsm.status.f.dev_present) {
+ /* Manually reset stack to default device state */
+ lwgsmi_reset_everything(1);
+ } else {
+#if LWGSM_CFG_RESET_ON_DEVICE_PRESENT
+ lwgsm_core_unlock();
+ res = lwgsm_reset_with_delay(LWGSM_CFG_RESET_DELAY_DEFAULT, evt_fn, evt_arg, blocking); /* Reset with delay */
+ lwgsm_core_lock();
+#endif /* LWGSM_CFG_RESET_ON_DEVICE_PRESENT */
+ }
+ lwgsmi_send_cb(LWGSM_EVT_DEVICE_PRESENT); /* Send present event */
+ }
+ lwgsm_core_unlock();
+
+ LWGSM_UNUSED(evt_fn);
+ LWGSM_UNUSED(evt_arg);
+ LWGSM_UNUSED(blocking);
+
+ return res;
+}
+
+/**
+ * \brief Check if device is present
+ * \return `1` on success, `0` otherwise
+ */
+uint8_t
+lwgsm_device_is_present(void) {
+ uint8_t res;
+ lwgsm_core_lock();
+ res = lwgsm.status.f.dev_present;
+ lwgsm_core_unlock();
+ return res;
+}
diff --git a/gsm_at_lib/src/gsm/gsm_buff.c b/lwgsm/src/lwgsm/lwgsm_buff.c
similarity index 94%
rename from gsm_at_lib/src/gsm/gsm_buff.c
rename to lwgsm/src/lwgsm/lwgsm_buff.c
index 8c530c34..4a93604d 100644
--- a/gsm_at_lib/src/gsm/gsm_buff.c
+++ b/lwgsm/src/lwgsm/lwgsm_buff.c
@@ -1,10 +1,10 @@
-/**
- * \file gsm_buff.c
+/**
+ * \file lwgsm_buff.c
* \brief Ring buffer manager
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,23 +26,23 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#include "gsm/gsm_private.h"
-#include "gsm/gsm_buff.h"
-#include "gsm/gsm_mem.h"
+#include "lwgsm/lwgsm_private.h"
+#include "lwgsm/lwgsm_buff.h"
+#include "lwgsm/lwgsm_mem.h"
/* --- Buffer unique part starts --- */
/* Prefix for all buffer functions and typedefs */
-#define BUF_PREF(x) gsm_ ## x
+#define BUF_PREF(x) lwgsm_ ## x
/* --- Buffer unique part ends --- */
/* Buffer utility macros */
-#define BUF_MEMSET GSM_MEMSET
-#define BUF_MEMCPY GSM_MEMCPY
+#define BUF_MEMSET LWGSM_MEMSET
+#define BUF_MEMCPY LWGSM_MEMCPY
#define BUF_IS_VALID(b) ((b) != NULL && (b)->buff != NULL && (b)->size > 0)
#define BUF_MIN(x, y) ((x) < (y) ? (x) : (y))
#define BUF_MAX(x, y) ((x) > (y) ? (x) : (y))
@@ -61,7 +61,7 @@ BUF_PREF(buff_init)(BUF_PREF(buff_t)* buff, size_t size) {
BUF_MEMSET(buff, 0, sizeof(*buff));
buff->size = size; /* Set default values */
- buff->buff = gsm_mem_malloc(sizeof(*buff->buff) * size);/* Allocate memory for buffer */
+ buff->buff = lwgsm_mem_malloc(sizeof(*buff->buff) * size); /* Allocate memory for buffer */
if (buff->buff == NULL) { /* Check allocation */
return 0;
@@ -76,7 +76,7 @@ BUF_PREF(buff_init)(BUF_PREF(buff_t)* buff, size_t size) {
void
BUF_PREF(buff_free)(BUF_PREF(buff_t)* buff) {
if (BUF_IS_VALID(buff)) {
- gsm_mem_free_s((void **)&buff->buff);
+ lwgsm_mem_free_s((void**)&buff->buff);
}
}
@@ -114,7 +114,7 @@ BUF_PREF(buff_write)(BUF_PREF(buff_t)* buff, const void* data, size_t btw) {
/* Step 2: Write data to beginning of buffer (overflow part) */
if (btw > 0) {
- BUF_MEMCPY(buff->buff, (void *)&d[tocopy], btw);
+ BUF_MEMCPY(buff->buff, (void*)&d[tocopy], btw);
buff->w = btw;
}
@@ -135,7 +135,7 @@ BUF_PREF(buff_write)(BUF_PREF(buff_t)* buff, const void* data, size_t btw) {
size_t
BUF_PREF(buff_read)(BUF_PREF(buff_t)* buff, void* data, size_t btr) {
size_t tocopy, full;
- uint8_t *d = data;
+ uint8_t* d = data;
if (!BUF_IS_VALID(buff) || btr == 0) {
return 0;
@@ -178,12 +178,12 @@ BUF_PREF(buff_read)(BUF_PREF(buff_t)* buff, void* data, size_t btr) {
size_t
BUF_PREF(buff_peek)(BUF_PREF(buff_t)* buff, size_t skip_count, void* data, size_t btp) {
size_t full, tocopy, r;
- uint8_t *d = data;
+ uint8_t* d = data;
if (!BUF_IS_VALID(buff) || btp == 0) {
return 0;
}
-
+
r = buff->r;
/* Calculate maximum number of bytes available to read */
@@ -288,7 +288,7 @@ BUF_PREF(buff_reset)(BUF_PREF(buff_t)* buff) {
* \param[in] buff: Buffer handle
* \return Linear buffer start address
*/
-void *
+void*
BUF_PREF(buff_get_linear_block_read_address)(BUF_PREF(buff_t)* buff) {
if (!BUF_IS_VALID(buff)) {
return NULL;
@@ -351,7 +351,7 @@ BUF_PREF(buff_skip)(BUF_PREF(buff_t)* buff, size_t len) {
* \param[in] buff: Buffer handle
* \return Linear buffer start address
*/
-void *
+void*
BUF_PREF(buff_get_linear_block_write_address)(BUF_PREF(buff_t)* buff) {
if (!BUF_IS_VALID(buff)) {
return NULL;
@@ -379,7 +379,7 @@ BUF_PREF(buff_get_linear_block_write_length)(BUF_PREF(buff_t)* buff) {
len = buff->size - w;
/*
* When read pointer is 0,
- * maximal length is one less as if too many bytes
+ * maximal length is one less as if too many bytes
* are written, buffer would be considered empty again (r == w)
*/
if (r == 0) {
@@ -388,7 +388,7 @@ BUF_PREF(buff_get_linear_block_write_length)(BUF_PREF(buff_t)* buff) {
* - If r is not 0, statement does not get called
* - buff->size cannot be 0 and if r is 0, len is greater 0
*/
- len--;
+ --len;
}
} else {
len = r - w - 1;
diff --git a/gsm_at_lib/src/gsm/gsm_call.c b/lwgsm/src/lwgsm/lwgsm_call.c
similarity index 50%
rename from gsm_at_lib/src/gsm/gsm_call.c
rename to lwgsm/src/lwgsm/lwgsm_call.c
index 145905f5..49ca440d 100644
--- a/gsm_at_lib/src/gsm/gsm_call.c
+++ b/lwgsm/src/lwgsm/lwgsm_call.c
@@ -1,10 +1,10 @@
-/**
- * \file gsm_call.c
+/**
+ * \file lwgsm_call.c
* \brief Call API functions
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,44 +26,44 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#include "gsm/gsm_private.h"
-#include "gsm/gsm_call.h"
-#include "gsm/gsm_mem.h"
+#include "lwgsm/lwgsm_private.h"
+#include "lwgsm/lwgsm_call.h"
+#include "lwgsm/lwgsm_mem.h"
-#if GSM_CFG_CALL || __DOXYGEN__
+#if LWGSM_CFG_CALL || __DOXYGEN__
#if !__DOXYGEN__
-#define CHECK_ENABLED() if (!(check_enabled() == gsmOK)) { return gsmERRNOTENABLED; }
+#define CHECK_ENABLED() if (!(check_enabled() == lwgsmOK)) { return lwgsmERRNOTENABLED; }
#endif /* !__DOXYGEN__ */
/**
* \brief Check if sms is enabled
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
*/
-static gsmr_t
+static lwgsmr_t
check_enabled(void) {
- gsmr_t res;
- gsm_core_lock();
- res = gsm.m.call.enabled ? gsmOK : gsmERR;
- gsm_core_unlock();
+ lwgsmr_t res;
+ lwgsm_core_lock();
+ res = lwgsm.m.call.enabled ? lwgsmOK : lwgsmERR;
+ lwgsm_core_unlock();
return res;
}
/**
* \brief Check if call is available
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-static gsmr_t
+static lwgsmr_t
check_ready(void) {
- gsmr_t res;
- gsm_core_lock();
- res = gsm.m.call.ready ? gsmOK : gsmERR;
- gsm_core_unlock();
+ lwgsmr_t res;
+ lwgsm_core_lock();
+ res = lwgsm.m.call.ready ? lwgsmOK : lwgsmERR;
+ lwgsm_core_unlock();
return res;
}
@@ -72,18 +72,18 @@ check_ready(void) {
* \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
* \param[in] evt_arg: Custom argument for event callback function
* \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
*/
-gsmr_t
-gsm_call_enable(const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
+lwgsmr_t
+lwgsm_call_enable(const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_CALL_ENABLE;
- GSM_MSG_VAR_REF(msg).cmd = GSM_CMD_CLCC_SET;
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_CALL_ENABLE;
+ LWGSM_MSG_VAR_REF(msg).cmd = LWGSM_CMD_CLCC_SET;
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 60000);
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 60000);
}
/**
@@ -91,17 +91,17 @@ gsm_call_enable(const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint
* \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
* \param[in] evt_arg: Custom argument for event callback function
* \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
*/
-gsmr_t
-gsm_call_disable(const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- gsm_core_lock();
- gsm.m.call.enabled = 0;
+lwgsmr_t
+lwgsm_call_disable(const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ lwgsm_core_lock();
+ lwgsm.m.call.enabled = 0;
if (evt_fn != NULL) {
- evt_fn(gsmOK, evt_arg);
+ evt_fn(lwgsmOK, evt_arg);
}
- gsm_core_unlock();
- return gsmOK;
+ lwgsm_core_unlock();
+ return lwgsmOK;
}
/**
@@ -110,23 +110,23 @@ gsm_call_disable(const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uin
* \param[in] evt_arg: Custom argument for event callback function
* \param[in] number: Phone number to call, including country code starting with `+` sign
* \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_call_start(const char* number,
- const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
+lwgsmr_t
+lwgsm_call_start(const char* number,
+ const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
- GSM_ASSERT("number != NULL", number != NULL);
+ LWGSM_ASSERT("number != NULL", number != NULL);
CHECK_ENABLED(); /* Check if enabled */
- GSM_ASSERT("check_ready == gsmOK", check_ready() == gsmOK);
+ LWGSM_ASSERT("check_ready == lwgsmOK", check_ready() == lwgsmOK);
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_ATD;
- GSM_MSG_VAR_REF(msg).msg.call_start.number = number;
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_ATD;
+ LWGSM_MSG_VAR_REF(msg).msg.call_start.number = number;
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 10000);
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 10000);
}
/**
@@ -134,19 +134,19 @@ gsm_call_start(const char* number,
* \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
* \param[in] evt_arg: Custom argument for event callback function
* \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_call_answer(const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
+lwgsmr_t
+lwgsm_call_answer(const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
CHECK_ENABLED();
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_ATA;
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_ATA;
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 10000);
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 10000);
}
/**
@@ -154,19 +154,19 @@ gsm_call_answer(const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint
* \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
* \param[in] evt_arg: Custom argument for event callback function
* \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_call_hangup(const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
+lwgsmr_t
+lwgsm_call_hangup(const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
CHECK_ENABLED();
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_ATH;
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_ATH;
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 10000);
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 10000);
}
-#endif /* GSM_CFG_CALL || __DOXYGEN__ */
+#endif /* LWGSM_CFG_CALL || __DOXYGEN__ */
diff --git a/gsm_at_lib/src/gsm/gsm_conn.c b/lwgsm/src/lwgsm/lwgsm_conn.c
similarity index 54%
rename from gsm_at_lib/src/gsm/gsm_conn.c
rename to lwgsm/src/lwgsm/lwgsm_conn.c
index ef68e07e..1376ccc0 100644
--- a/gsm_at_lib/src/gsm/gsm_conn.c
+++ b/lwgsm/src/lwgsm/lwgsm_conn.c
@@ -1,10 +1,10 @@
/**
- * \file gsm_conn.c
+ * \file lwgsm_conn.c
* \brief Connection API
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,33 +26,33 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#include "gsm/gsm_private.h"
-#include "gsm/gsm_conn.h"
-#include "gsm/gsm_mem.h"
-#include "gsm/gsm_timeout.h"
+#include "lwgsm/lwgsm_private.h"
+#include "lwgsm/lwgsm_conn.h"
+#include "lwgsm/lwgsm_mem.h"
+#include "lwgsm/lwgsm_timeout.h"
-#if GSM_CFG_CONN || __DOXYGEN__
+#if LWGSM_CFG_CONN || __DOXYGEN__
/**
* \brief Check if connection is closed or in closing state
* \param[in] conn: Connection handle
*/
#define CONN_CHECK_CLOSED_IN_CLOSING(conn) do { \
- gsmr_t r = gsmOK; \
- gsm_core_lock(); \
- if (conn->status.f.in_closing || !conn->status.f.active) { \
- r = gsmCLOSED; \
- } \
- gsm_core_unlock(); \
- if (r != gsmOK) { \
- return r; \
- } \
-} while (0)
+ lwgsmr_t r = lwgsmOK; \
+ lwgsm_core_lock(); \
+ if (conn->status.f.in_closing || !conn->status.f.active) { \
+ r = lwgsmCLOSED; \
+ } \
+ lwgsm_core_unlock(); \
+ if (r != lwgsmOK) { \
+ return r; \
+ } \
+ } while (0)
/**
* \brief Timeout callback for connection
@@ -60,16 +60,16 @@
*/
static void
conn_timeout_cb(void* arg) {
- gsm_conn_p conn = arg; /* Argument is actual connection */
+ lwgsm_conn_p conn = arg; /* Argument is actual connection */
if (conn->status.f.active) { /* Handle only active connections */
- gsm.evt.type = GSM_EVT_CONN_POLL; /* Poll connection event */
- gsm.evt.evt.conn_poll.conn = conn; /* Set connection pointer */
- gsmi_send_conn_cb(conn, NULL); /* Send connection callback */
+ lwgsm.evt.type = LWGSM_EVT_CONN_POLL; /* Poll connection event */
+ lwgsm.evt.evt.conn_poll.conn = conn; /* Set connection pointer */
+ lwgsmi_send_conn_cb(conn, NULL); /* Send connection callback */
- gsmi_conn_start_timeout(conn); /* Schedule new timeout */
- GSM_DEBUGF(GSM_CFG_DBG_CONN | GSM_DBG_TYPE_TRACE,
- "[CONN] Poll event: %p\r\n", conn);
+ lwgsmi_conn_start_timeout(conn); /* Schedule new timeout */
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_CONN | LWGSM_DBG_TYPE_TRACE,
+ "[CONN] Poll event: %p\r\n", conn);
}
}
@@ -78,8 +78,8 @@ conn_timeout_cb(void* arg) {
* \param[in] conn: Connection handle as user argument
*/
void
-gsmi_conn_start_timeout(gsm_conn_p conn) {
- gsm_timeout_add(GSM_CFG_CONN_POLL_INTERVAL, conn_timeout_cb, conn); /* Add connection timeout */
+lwgsmi_conn_start_timeout(lwgsm_conn_p conn) {
+ lwgsm_timeout_add(LWGSM_CFG_CONN_POLL_INTERVAL, conn_timeout_cb, conn); /* Add connection timeout */
}
/**
@@ -88,11 +88,11 @@ gsmi_conn_start_timeout(gsm_conn_p conn) {
* \return Connection current validation ID
*/
uint8_t
-gsmi_conn_get_val_id(gsm_conn_p conn) {
+lwgsmi_conn_get_val_id(lwgsm_conn_p conn) {
uint8_t val_id;
- gsm_core_lock();
+ lwgsm_core_lock();
val_id = conn->val_id;
- gsm_core_unlock();
+ lwgsm_core_unlock();
return val_id;
}
@@ -108,16 +108,16 @@ gsmi_conn_get_val_id(gsm_conn_p conn) {
* \param[out] bw: Pointer to output variable to save number of sent data when successfully sent
* \param[in] fau: "Free After Use" flag. Set to `1` if stack should free the memory after data sent
* \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-static gsmr_t
-conn_send(gsm_conn_p conn, const gsm_ip_t* const ip, gsm_port_t port, const void* data,
- size_t btw, size_t* const bw, uint8_t fau, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
+static lwgsmr_t
+conn_send(lwgsm_conn_p conn, const lwgsm_ip_t* const ip, lwgsm_port_t port, const void* data,
+ size_t btw, size_t* const bw, uint8_t fau, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
- GSM_ASSERT("conn != NULL", conn != NULL);
- GSM_ASSERT("data != NULL", data != NULL);
- GSM_ASSERT("btw > 0", btw > 0);
+ LWGSM_ASSERT("conn != NULL", conn != NULL);
+ LWGSM_ASSERT("data != NULL", data != NULL);
+ LWGSM_ASSERT("btw > 0", btw > 0);
if (bw != NULL) {
*bw = 0;
@@ -125,30 +125,30 @@ conn_send(gsm_conn_p conn, const gsm_ip_t* const ip, gsm_port_t port, const void
CONN_CHECK_CLOSED_IN_CLOSING(conn); /* Check if we can continue */
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_CIPSEND;
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_CIPSEND;
- GSM_MSG_VAR_REF(msg).msg.conn_send.conn = conn;
- GSM_MSG_VAR_REF(msg).msg.conn_send.data = data;
- GSM_MSG_VAR_REF(msg).msg.conn_send.btw = btw;
- GSM_MSG_VAR_REF(msg).msg.conn_send.bw = bw;
- GSM_MSG_VAR_REF(msg).msg.conn_send.remote_ip = ip;
- GSM_MSG_VAR_REF(msg).msg.conn_send.remote_port = port;
- GSM_MSG_VAR_REF(msg).msg.conn_send.fau = fau;
- GSM_MSG_VAR_REF(msg).msg.conn_send.val_id = gsmi_conn_get_val_id(conn);
+ LWGSM_MSG_VAR_REF(msg).msg.conn_send.conn = conn;
+ LWGSM_MSG_VAR_REF(msg).msg.conn_send.data = data;
+ LWGSM_MSG_VAR_REF(msg).msg.conn_send.btw = btw;
+ LWGSM_MSG_VAR_REF(msg).msg.conn_send.bw = bw;
+ LWGSM_MSG_VAR_REF(msg).msg.conn_send.remote_ip = ip;
+ LWGSM_MSG_VAR_REF(msg).msg.conn_send.remote_port = port;
+ LWGSM_MSG_VAR_REF(msg).msg.conn_send.fau = fau;
+ LWGSM_MSG_VAR_REF(msg).msg.conn_send.val_id = lwgsmi_conn_get_val_id(conn);
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 60000);
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 60000);
}
/**
* \brief Flush buffer on connection
* \param[in] conn: Connection to flush buffer on
- * \return \ref gsmOK if data flushed and put to queue, member of \ref gsmr_t otherwise
+ * \return \ref lwgsmOK if data flushed and put to queue, member of \ref lwgsmr_t otherwise
*/
-static gsmr_t
-flush_buff(gsm_conn_p conn) {
- gsmr_t res = gsmOK;
- gsm_core_lock();
+static lwgsmr_t
+flush_buff(lwgsm_conn_p conn) {
+ lwgsmr_t res = lwgsmOK;
+ lwgsm_core_lock();
if (conn != NULL && conn->buff.buff != NULL) { /* Do we have something ready? */
/*
* If there is nothing to write or if write was not successful,
@@ -157,16 +157,16 @@ flush_buff(gsm_conn_p conn) {
if (conn->buff.ptr > 0) { /* Anything to send at the moment? */
res = conn_send(conn, NULL, 0, conn->buff.buff, conn->buff.ptr, NULL, 1, 0);
} else {
- res = gsmERR;
+ res = lwgsmERR;
}
- if (res != gsmOK) {
- GSM_DEBUGF(GSM_CFG_DBG_CONN | GSM_DBG_TYPE_TRACE,
- "[CONN] Free write buffer: %p\r\n", (void *)conn->buff.buff);
- gsm_mem_free_s((void **)&conn->buff.buff);
+ if (res != lwgsmOK) {
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_CONN | LWGSM_DBG_TYPE_TRACE,
+ "[CONN] Free write buffer: %p\r\n", (void*)conn->buff.buff);
+ lwgsm_mem_free_s((void**)&conn->buff.buff);
}
conn->buff.buff = NULL;
}
- gsm_core_unlock();
+ lwgsm_core_unlock();
return res;
}
@@ -174,73 +174,73 @@ flush_buff(gsm_conn_p conn) {
* \brief Initialize connection module
*/
void
-gsmi_conn_init(void) {
+lwgsmi_conn_init(void) {
}
/**
* \brief Start a new connection of specific type
* \param[out] conn: Pointer to connection handle to set new connection reference in case of successful connection
- * \param[in] type: Connection type. This parameter can be a value of \ref gsm_conn_type_t enumeration
+ * \param[in] type: Connection type. This parameter can be a value of \ref lwgsm_conn_type_t enumeration
* \param[in] host: Connection host. In case of IP, write it as string, ex. "192.168.1.1"
* \param[in] port: Connection port
* \param[in] arg: Pointer to user argument passed to connection if successfully connected
* \param[in] conn_evt_fn: Callback function for this connection
* \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_conn_start(gsm_conn_p* conn, gsm_conn_type_t type, const char* const host, gsm_port_t port,
- void* const arg, gsm_evt_fn conn_evt_fn, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
-
- GSM_ASSERT("host != NULL", host != NULL);
- GSM_ASSERT("port > 0", port > 0);
- GSM_ASSERT("conn_evt_fn != NULL", conn_evt_fn != NULL);
-
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_CIPSTART;
- GSM_MSG_VAR_REF(msg).cmd = GSM_CMD_CIPSTATUS;
- GSM_MSG_VAR_REF(msg).msg.conn_start.num = GSM_CFG_MAX_CONNS;/* Set maximal value as invalid number */
- GSM_MSG_VAR_REF(msg).msg.conn_start.conn = conn;
- GSM_MSG_VAR_REF(msg).msg.conn_start.type = type;
- GSM_MSG_VAR_REF(msg).msg.conn_start.host = host;
- GSM_MSG_VAR_REF(msg).msg.conn_start.port = port;
- GSM_MSG_VAR_REF(msg).msg.conn_start.evt_func = conn_evt_fn;
- GSM_MSG_VAR_REF(msg).msg.conn_start.arg = arg;
-
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 60000);
+lwgsmr_t
+lwgsm_conn_start(lwgsm_conn_p* conn, lwgsm_conn_type_t type, const char* const host, lwgsm_port_t port,
+ void* const arg, lwgsm_evt_fn conn_evt_fn, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
+
+ LWGSM_ASSERT("host != NULL", host != NULL);
+ LWGSM_ASSERT("port > 0", port > 0);
+ LWGSM_ASSERT("conn_evt_fn != NULL", conn_evt_fn != NULL);
+
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_CIPSTART;
+ LWGSM_MSG_VAR_REF(msg).cmd = LWGSM_CMD_CIPSTATUS;
+ LWGSM_MSG_VAR_REF(msg).msg.conn_start.num = LWGSM_CFG_MAX_CONNS;/* Set maximal value as invalid number */
+ LWGSM_MSG_VAR_REF(msg).msg.conn_start.conn = conn;
+ LWGSM_MSG_VAR_REF(msg).msg.conn_start.type = type;
+ LWGSM_MSG_VAR_REF(msg).msg.conn_start.host = host;
+ LWGSM_MSG_VAR_REF(msg).msg.conn_start.port = port;
+ LWGSM_MSG_VAR_REF(msg).msg.conn_start.evt_func = conn_evt_fn;
+ LWGSM_MSG_VAR_REF(msg).msg.conn_start.arg = arg;
+
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 60000);
}
/**
* \brief Close specific or all connections
* \param[in] conn: Connection handle to close. Set to NULL if you want to close all connections.
* \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_conn_close(gsm_conn_p conn, const uint32_t blocking) {
- gsmr_t res = gsmOK;
- GSM_MSG_VAR_DEFINE(msg);
+lwgsmr_t
+lwgsm_conn_close(lwgsm_conn_p conn, const uint32_t blocking) {
+ lwgsmr_t res = lwgsmOK;
+ LWGSM_MSG_VAR_DEFINE(msg);
- GSM_ASSERT("conn != NULL", conn != NULL);
+ LWGSM_ASSERT("conn != NULL", conn != NULL);
CONN_CHECK_CLOSED_IN_CLOSING(conn); /* Check if we can continue */
/* Proceed with close event at this point! */
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_CIPCLOSE;
- GSM_MSG_VAR_REF(msg).msg.conn_close.conn = conn;
- GSM_MSG_VAR_REF(msg).msg.conn_close.val_id = gsmi_conn_get_val_id(conn);
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_CIPCLOSE;
+ LWGSM_MSG_VAR_REF(msg).msg.conn_close.conn = conn;
+ LWGSM_MSG_VAR_REF(msg).msg.conn_close.val_id = lwgsmi_conn_get_val_id(conn);
flush_buff(conn); /* First flush buffer */
- res = gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 1000);
- if (res == gsmOK && !blocking) { /* Function succedded in non-blocking mode */
- gsm_core_lock();
- GSM_DEBUGF(GSM_CFG_DBG_CONN | GSM_DBG_TYPE_TRACE,
- "[CONN] Connection %d set to closing state\r\n", (int)conn->num);
+ res = lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 1000);
+ if (res == lwgsmOK && !blocking) { /* Function succedded in non-blocking mode */
+ lwgsm_core_lock();
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_CONN | LWGSM_DBG_TYPE_TRACE,
+ "[CONN] Connection %d set to closing state\r\n", (int)conn->num);
conn->status.f.in_closing = 1; /* Connection is in closing mode but not yet closed */
- gsm_core_unlock();
+ lwgsm_core_unlock();
}
return res;
}
@@ -255,12 +255,12 @@ gsm_conn_close(gsm_conn_p conn, const uint32_t blocking) {
* \param[in] btw: Number of bytes to send
* \param[out] bw: Pointer to output variable to save number of sent data when successfully sent
* \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_conn_sendto(gsm_conn_p conn, const gsm_ip_t* const ip, gsm_port_t port, const void* data,
+lwgsmr_t
+lwgsm_conn_sendto(lwgsm_conn_p conn, const lwgsm_ip_t* const ip, lwgsm_port_t port, const void* data,
size_t btw, size_t* bw, const uint32_t blocking) {
- GSM_ASSERT("conn != NULL", conn != NULL);
+ LWGSM_ASSERT("conn != NULL", conn != NULL);
flush_buff(conn); /* Flush currently written memory if exists */
return conn_send(conn, ip, port, data, btw, bw, 0, blocking);
@@ -272,32 +272,32 @@ gsm_conn_sendto(gsm_conn_p conn, const gsm_ip_t* const ip, gsm_port_t port, cons
* \param[in] data: Data to send
* \param[in] btw: Number of bytes to send
* \param[out] bw: Pointer to output variable to save number of sent data when successfully sent.
- * Parameter value might not be accurate if you combine \ref gsm_conn_write and \ref gsm_conn_send functions
+ * Parameter value might not be accurate if you combine \ref lwgsm_conn_write and \ref lwgsm_conn_send functions
* \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_conn_send(gsm_conn_p conn, const void* data, size_t btw, size_t* const bw,
- const uint32_t blocking) {
- gsmr_t res;
+lwgsmr_t
+lwgsm_conn_send(lwgsm_conn_p conn, const void* data, size_t btw, size_t* const bw,
+ const uint32_t blocking) {
+ lwgsmr_t res;
const uint8_t* d = data;
- GSM_ASSERT("conn != NULL", conn != NULL);
- GSM_ASSERT("data != NULL", data != NULL);
- GSM_ASSERT("btw > 0", btw > 0);
+ LWGSM_ASSERT("conn != NULL", conn != NULL);
+ LWGSM_ASSERT("data != NULL", data != NULL);
+ LWGSM_ASSERT("btw > 0", btw > 0);
- gsm_core_lock();
+ lwgsm_core_lock();
if (conn->buff.buff != NULL) { /* Check if memory available */
size_t to_copy;
- to_copy = GSM_MIN(btw, conn->buff.len - conn->buff.ptr);
+ to_copy = LWGSM_MIN(btw, conn->buff.len - conn->buff.ptr);
if (to_copy > 0) {
- GSM_MEMCPY(&conn->buff.buff[conn->buff.ptr], d, to_copy);
+ LWGSM_MEMCPY(&conn->buff.buff[conn->buff.ptr], d, to_copy);
conn->buff.ptr += to_copy;
d += to_copy;
btw -= to_copy;
}
}
- gsm_core_unlock();
+ lwgsm_core_unlock();
res = flush_buff(conn); /* Flush currently written memory if exists */
if (btw > 0) { /* Check for remaining data */
res = conn_send(conn, NULL, 0, d, btw, bw, 0, blocking);
@@ -317,69 +317,69 @@ gsm_conn_send(gsm_conn_p conn, const void* data, size_t btw, size_t* const bw,
*
* \param[in] conn: Connection handle
* \param[in] pbuf: Packet buffer received on connection
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_conn_recved(gsm_conn_p conn, gsm_pbuf_p pbuf) {
-#if GSM_CFG_CONN_MANUAL_TCP_RECEIVE
+lwgsmr_t
+lwgsm_conn_recved(lwgsm_conn_p conn, lwgsm_pbuf_p pbuf) {
+#if LWGSM_CFG_CONN_MANUAL_TCP_RECEIVE
size_t len;
- len = gsm_pbuf_length(pbuf, 1); /* Get length of pbuf */
+ len = lwgsm_pbuf_length(pbuf, 1); /* Get length of pbuf */
if (conn->tcp_available_data > len) {
conn->tcp_available_data -= len; /* Decrease for available length */
if (conn->tcp_available_data > 0) {
/* Start new manual receive here... */
}
}
-#else /* GSM_CFG_CONN_MANUAL_TCP_RECEIVE */
- GSM_UNUSED(conn);
- GSM_UNUSED(pbuf);
-#endif /* !GSM_CFG_CONN_MANUAL_TCP_RECEIVE */
- return gsmOK;
+#else /* LWGSM_CFG_CONN_MANUAL_TCP_RECEIVE */
+ LWGSM_UNUSED(conn);
+ LWGSM_UNUSED(pbuf);
+#endif /* !LWGSM_CFG_CONN_MANUAL_TCP_RECEIVE */
+ return lwgsmOK;
}
/**
* \brief Set argument variable for connection
* \param[in] conn: Connection handle to set argument
* \param[in] arg: Pointer to argument
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
- * \sa gsm_conn_get_arg
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
+ * \sa lwgsm_conn_get_arg
*/
-gsmr_t
-gsm_conn_set_arg(gsm_conn_p conn, void* const arg) {
- gsm_core_lock();
+lwgsmr_t
+lwgsm_conn_set_arg(lwgsm_conn_p conn, void* const arg) {
+ lwgsm_core_lock();
conn->arg = arg; /* Set argument for connection */
- gsm_core_unlock();
- return gsmOK;
+ lwgsm_core_unlock();
+ return lwgsmOK;
}
/**
* \brief Get user defined connection argument
* \param[in] conn: Connection handle to get argument
* \return User argument
- * \sa gsm_conn_set_arg
+ * \sa lwgsm_conn_set_arg
*/
-void *
-gsm_conn_get_arg(gsm_conn_p conn) {
+void*
+lwgsm_conn_get_arg(lwgsm_conn_p conn) {
void* arg;
- gsm_core_lock();
+ lwgsm_core_lock();
arg = conn->arg; /* Set argument for connection */
- gsm_core_unlock();
+ lwgsm_core_unlock();
return arg;
}
/**
* \brief Gets connections status
* \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_get_conns_status(const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
+lwgsmr_t
+lwgsm_get_conns_status(const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_CIPSTATUS;
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_CIPSTATUS;
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 1000);
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 1000);
}
/**
@@ -388,12 +388,12 @@ gsm_get_conns_status(const uint32_t blocking) {
* \return `1` on success, `0` otherwise
*/
uint8_t
-gsm_conn_is_client(gsm_conn_p conn) {
+lwgsm_conn_is_client(lwgsm_conn_p conn) {
uint8_t res = 0;
- if (conn != NULL && gsmi_is_valid_conn_ptr(conn)) {
- gsm_core_lock();
+ if (conn != NULL && lwgsmi_is_valid_conn_ptr(conn)) {
+ lwgsm_core_lock();
res = conn->status.f.active && conn->status.f.client;
- gsm_core_unlock();
+ lwgsm_core_unlock();
}
return res;
}
@@ -404,12 +404,12 @@ gsm_conn_is_client(gsm_conn_p conn) {
* \return `1` on success, `0` otherwise
*/
uint8_t
-gsm_conn_is_active(gsm_conn_p conn) {
+lwgsm_conn_is_active(lwgsm_conn_p conn) {
uint8_t res = 0;
- if (conn != NULL && gsmi_is_valid_conn_ptr(conn)) {
- gsm_core_lock();
+ if (conn != NULL && lwgsmi_is_valid_conn_ptr(conn)) {
+ lwgsm_core_lock();
res = conn->status.f.active;
- gsm_core_unlock();
+ lwgsm_core_unlock();
}
return res;
}
@@ -420,12 +420,12 @@ gsm_conn_is_active(gsm_conn_p conn) {
* \return `1` on success, `0` otherwise
*/
uint8_t
-gsm_conn_is_closed(gsm_conn_p conn) {
+lwgsm_conn_is_closed(lwgsm_conn_p conn) {
uint8_t res = 0;
- if (conn != NULL && gsmi_is_valid_conn_ptr(conn)) {
- gsm_core_lock();
+ if (conn != NULL && lwgsmi_is_valid_conn_ptr(conn)) {
+ lwgsm_core_lock();
res = !conn->status.f.active;
- gsm_core_unlock();
+ lwgsm_core_unlock();
}
return res;
}
@@ -436,9 +436,9 @@ gsm_conn_is_closed(gsm_conn_p conn) {
* \return Connection number in case of success or -1 on failure
*/
int8_t
-gsm_conn_getnum(gsm_conn_p conn) {
+lwgsm_conn_getnum(lwgsm_conn_p conn) {
int8_t res = -1;
- if (conn != NULL && gsmi_is_valid_conn_ptr(conn)) {
+ if (conn != NULL && lwgsmi_is_valid_conn_ptr(conn)) {
/* Protection not needed as every connection has always the same number */
res = conn->num; /* Get number */
}
@@ -450,15 +450,21 @@ gsm_conn_getnum(gsm_conn_p conn) {
* \param[in] evt: Event which happened for connection
* \return Connection pointer on success, `NULL` otherwise
*/
-gsm_conn_p
-gsm_conn_get_from_evt(gsm_evt_t* evt) {
+lwgsm_conn_p
+lwgsm_conn_get_from_evt(lwgsm_evt_t* evt) {
switch (evt->type) {
- case GSM_EVT_CONN_ACTIVE: return gsm_evt_conn_active_get_conn(evt);
- case GSM_EVT_CONN_CLOSE: return gsm_evt_conn_close_get_conn(evt);
- case GSM_EVT_CONN_RECV: return gsm_evt_conn_recv_get_conn(evt);
- case GSM_EVT_CONN_SEND: return gsm_evt_conn_send_get_conn(evt);
- case GSM_EVT_CONN_POLL: return gsm_evt_conn_poll_get_conn(evt);
- default: return NULL;
+ case LWGSM_EVT_CONN_ACTIVE:
+ return lwgsm_evt_conn_active_get_conn(evt);
+ case LWGSM_EVT_CONN_CLOSE:
+ return lwgsm_evt_conn_close_get_conn(evt);
+ case LWGSM_EVT_CONN_RECV:
+ return lwgsm_evt_conn_recv_get_conn(evt);
+ case LWGSM_EVT_CONN_SEND:
+ return lwgsm_evt_conn_send_get_conn(evt);
+ case LWGSM_EVT_CONN_POLL:
+ return lwgsm_evt_conn_poll_get_conn(evt);
+ default:
+ return NULL;
}
}
@@ -468,20 +474,20 @@ gsm_conn_get_from_evt(gsm_evt_t* evt) {
* \param[in] conn: Connection to write
* \param[in] data: Data to copy to write buffer
* \param[in] btw: Number of bytes to write
- * \param[in] flush: Flush flag. Set to `1` if you want to send data immediatelly after copying
+ * \param[in] flush: Flush flag. Set to `1` if you want to send data immediately after copying
* \param[out] mem_available: Available memory size available in current write buffer.
* When the buffer length is reached, current one is sent and a new one is automatically created.
- * If function returns \ref gsmOK and `*mem_available = 0`, there was a problem
+ * If function returns \ref lwgsmOK and `*mem_available = 0`, there was a problem
* allocating a new buffer for next operation
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_conn_write(gsm_conn_p conn, const void* data, size_t btw, uint8_t flush, size_t* const mem_available) {
+lwgsmr_t
+lwgsm_conn_write(lwgsm_conn_p conn, const void* data, size_t btw, uint8_t flush, size_t* const mem_available) {
size_t len;
const uint8_t* d = data;
- GSM_ASSERT("conn != NULL", conn != NULL);
+ LWGSM_ASSERT("conn != NULL", conn != NULL);
/*
* Steps during write process:
@@ -498,8 +504,8 @@ gsm_conn_write(gsm_conn_p conn, const void* data, size_t btw, uint8_t flush, siz
/* Step 1 */
if (conn->buff.buff != NULL) {
- len = GSM_MIN(conn->buff.len - conn->buff.ptr, btw);
- GSM_MEMCPY(&conn->buff.buff[conn->buff.ptr], d, len);
+ len = LWGSM_MIN(conn->buff.len - conn->buff.ptr, btw);
+ LWGSM_MEMCPY(&conn->buff.buff[conn->buff.ptr], d, len);
d += len;
btw -= len;
@@ -508,52 +514,52 @@ gsm_conn_write(gsm_conn_p conn, const void* data, size_t btw, uint8_t flush, siz
/* Step 1.1 */
if (conn->buff.ptr == conn->buff.len || flush) {
/* Try to send to processing queue in non-blocking way */
- if (conn_send(conn, NULL, 0, conn->buff.buff, conn->buff.ptr, NULL, 1, 0) != gsmOK) {
- GSM_DEBUGF(GSM_CFG_DBG_CONN | GSM_DBG_TYPE_TRACE,
- "[CONN] Free write buffer: %p\r\n", conn->buff.buff);
- gsm_mem_free_s((void **)&conn->buff.buff);
+ if (conn_send(conn, NULL, 0, conn->buff.buff, conn->buff.ptr, NULL, 1, 0) != lwgsmOK) {
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_CONN | LWGSM_DBG_TYPE_TRACE,
+ "[CONN] Free write buffer: %p\r\n", conn->buff.buff);
+ lwgsm_mem_free_s((void**)&conn->buff.buff);
}
conn->buff.buff = NULL;
}
}
/* Step 2 */
- while (btw >= GSM_CFG_CONN_MAX_DATA_LEN) {
+ while (btw >= LWGSM_CFG_CONN_MAX_DATA_LEN) {
uint8_t* buff;
- buff = gsm_mem_malloc(sizeof(*buff) * GSM_CFG_CONN_MAX_DATA_LEN);
+ buff = lwgsm_mem_malloc(sizeof(*buff) * LWGSM_CFG_CONN_MAX_DATA_LEN);
if (buff != NULL) {
- GSM_MEMCPY(buff, d, GSM_CFG_CONN_MAX_DATA_LEN); /* Copy data to buffer */
- if (conn_send(conn, NULL, 0, buff, GSM_CFG_CONN_MAX_DATA_LEN, NULL, 1, 0) != gsmOK) {
- GSM_DEBUGF(GSM_CFG_DBG_CONN | GSM_DBG_TYPE_TRACE,
- "[CONN] Free write buffer: %p\r\n", (void *)buff);
- gsm_mem_free_s((void **)&buff);
- return gsmERRMEM;
+ LWGSM_MEMCPY(buff, d, LWGSM_CFG_CONN_MAX_DATA_LEN); /* Copy data to buffer */
+ if (conn_send(conn, NULL, 0, buff, LWGSM_CFG_CONN_MAX_DATA_LEN, NULL, 1, 0) != lwgsmOK) {
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_CONN | LWGSM_DBG_TYPE_TRACE,
+ "[CONN] Free write buffer: %p\r\n", (void*)buff);
+ lwgsm_mem_free_s((void**)&buff);
+ return lwgsmERRMEM;
}
} else {
- return gsmERRMEM;
+ return lwgsmERRMEM;
}
- btw -= GSM_CFG_CONN_MAX_DATA_LEN; /* Decrease remaining length */
- d += GSM_CFG_CONN_MAX_DATA_LEN; /* Advance data pointer */
+ btw -= LWGSM_CFG_CONN_MAX_DATA_LEN; /* Decrease remaining length */
+ d += LWGSM_CFG_CONN_MAX_DATA_LEN; /* Advance data pointer */
}
/* Step 3 */
if (conn->buff.buff == NULL) {
- conn->buff.buff = gsm_mem_malloc(sizeof(*conn->buff.buff) * GSM_CFG_CONN_MAX_DATA_LEN);
- conn->buff.len = GSM_CFG_CONN_MAX_DATA_LEN;
+ conn->buff.buff = lwgsm_mem_malloc(sizeof(*conn->buff.buff) * LWGSM_CFG_CONN_MAX_DATA_LEN);
+ conn->buff.len = LWGSM_CFG_CONN_MAX_DATA_LEN;
conn->buff.ptr = 0;
- GSM_DEBUGW(GSM_CFG_DBG_CONN | GSM_DBG_TYPE_TRACE, conn->buff.buff != NULL,
- "[CONN] New write buffer allocated, addr = %p\r\n", conn->buff.buff);
- GSM_DEBUGW(GSM_CFG_DBG_CONN | GSM_DBG_TYPE_TRACE, conn->buff.buff == NULL,
- "[CONN] Cannot allocate new write buffer\r\n");
+ LWGSM_DEBUGW(LWGSM_CFG_DBG_CONN | LWGSM_DBG_TYPE_TRACE, conn->buff.buff != NULL,
+ "[CONN] New write buffer allocated, addr = %p\r\n", conn->buff.buff);
+ LWGSM_DEBUGW(LWGSM_CFG_DBG_CONN | LWGSM_DBG_TYPE_TRACE, conn->buff.buff == NULL,
+ "[CONN] Cannot allocate new write buffer\r\n");
}
if (btw > 0) {
if (conn->buff.buff != NULL) {
- GSM_MEMCPY(conn->buff.buff, d, btw); /* Copy data to memory */
+ LWGSM_MEMCPY(conn->buff.buff, d, btw); /* Copy data to memory */
conn->buff.ptr = btw;
} else {
- return gsmERRMEM;
+ return lwgsmERRMEM;
}
}
@@ -570,7 +576,7 @@ gsm_conn_write(gsm_conn_p conn, const void* data, size_t btw, uint8_t flush, siz
*mem_available = 0;
}
}
- return gsmOK;
+ return lwgsmOK;
}
/**
@@ -579,14 +585,14 @@ gsm_conn_write(gsm_conn_p conn, const void* data, size_t btw, uint8_t flush, siz
* \return Count of received bytes on connection
*/
size_t
-gsm_conn_get_total_recved_count(gsm_conn_p conn) {
+lwgsm_conn_get_total_recved_count(lwgsm_conn_p conn) {
size_t tot;
- GSM_ASSERT("conn != NULL", conn != NULL);
+ LWGSM_ASSERT("conn != NULL", conn != NULL);
- gsm_core_lock();
+ lwgsm_core_lock();
tot = conn->total_recved; /* Get total received bytes */
- gsm_core_unlock();
+ lwgsm_core_unlock();
return tot;
}
@@ -598,11 +604,11 @@ gsm_conn_get_total_recved_count(gsm_conn_p conn) {
* \return `1` on success, `0` otherwise
*/
uint8_t
-gsm_conn_get_remote_ip(gsm_conn_p conn, gsm_ip_t* ip) {
+lwgsm_conn_get_remote_ip(lwgsm_conn_p conn, lwgsm_ip_t* ip) {
if (conn != NULL && ip != NULL) {
- gsm_core_lock();
- GSM_MEMCPY(ip, &conn->remote_ip, sizeof(*ip)); /* Copy data */
- gsm_core_unlock();
+ lwgsm_core_lock();
+ LWGSM_MEMCPY(ip, &conn->remote_ip, sizeof(*ip));/* Copy data */
+ lwgsm_core_unlock();
return 1;
}
return 0;
@@ -613,13 +619,13 @@ gsm_conn_get_remote_ip(gsm_conn_p conn, gsm_ip_t* ip) {
* \param[in] conn: Connection handle
* \return Port number on success, `0` otherwise
*/
-gsm_port_t
-gsm_conn_get_remote_port(gsm_conn_p conn) {
- gsm_port_t port = 0;
+lwgsm_port_t
+lwgsm_conn_get_remote_port(lwgsm_conn_p conn) {
+ lwgsm_port_t port = 0;
if (conn != NULL) {
- gsm_core_lock();
+ lwgsm_core_lock();
port = conn->remote_port;
- gsm_core_unlock();
+ lwgsm_core_unlock();
}
return port;
}
@@ -629,15 +635,15 @@ gsm_conn_get_remote_port(gsm_conn_p conn) {
* \param[in] conn: Connection handle
* \return Port number on success, `0` otherwise
*/
-gsm_port_t
-gsm_conn_get_local_port(gsm_conn_p conn) {
- gsm_port_t port = 0;
+lwgsm_port_t
+lwgsm_conn_get_local_port(lwgsm_conn_p conn) {
+ lwgsm_port_t port = 0;
if (conn != NULL) {
- gsm_core_lock();
+ lwgsm_core_lock();
port = conn->local_port;
- gsm_core_unlock();
+ lwgsm_core_unlock();
}
return port;
}
-#endif /* GSM_CFG_CONN || __DOXYGEN__ */
+#endif /* LWGSM_CFG_CONN || __DOXYGEN__ */
diff --git a/gsm_at_lib/src/gsm/gsm_debug.c b/lwgsm/src/lwgsm/lwgsm_debug.c
similarity index 77%
rename from gsm_at_lib/src/gsm/gsm_debug.c
rename to lwgsm/src/lwgsm/lwgsm_debug.c
index 9be1c0c1..54d22bfd 100644
--- a/gsm_at_lib/src/gsm/gsm_debug.c
+++ b/lwgsm/src/lwgsm/lwgsm_debug.c
@@ -1,10 +1,10 @@
-/**
- * \file gsm_debug.c
+/**
+ * \file lwgsm_debug.c
* \brief Debugging inside GSM stack
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,19 +26,19 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#include "gsm/gsm_private.h"
-#include "gsm/gsm_debug.h"
-#include "gsm/gsm.h"
+#include "lwgsm/lwgsm_private.h"
+#include "lwgsm/lwgsm_debug.h"
+#include "lwgsm/lwgsm.h"
-#if GSM_CFG_DBG || __DOXYGEN__
+#if LWGSM_CFG_DBG || __DOXYGEN__
-const char *
-gsmi_dbg_msg_to_string(gsm_cmd_t cmd) {
+const char*
+lwgsmi_dbg_msg_to_string(lwgsm_cmd_t cmd) {
static char tmp_arr[100];
if (cmd) {
sprintf(tmp_arr, "%d", (int)cmd);
@@ -47,4 +47,4 @@ gsmi_dbg_msg_to_string(gsm_cmd_t cmd) {
return "";
}
-#endif /* GSM_CFG_DBG || __DOXYGEN__ */
+#endif /* LWGSM_CFG_DBG || __DOXYGEN__ */
diff --git a/gsm_at_lib/src/gsm/gsm_device_info.c b/lwgsm/src/lwgsm/lwgsm_device_info.c
similarity index 50%
rename from gsm_at_lib/src/gsm/gsm_device_info.c
rename to lwgsm/src/lwgsm/lwgsm_device_info.c
index 98d72cbc..81bf18b6 100644
--- a/gsm_at_lib/src/gsm/gsm_device_info.c
+++ b/lwgsm/src/lwgsm/lwgsm_device_info.c
@@ -1,10 +1,10 @@
-/**
- * \file gsm_device_info.c
+/**
+ * \file lwgsm_device_info.c
* \brief Basic device information
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,14 +26,14 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#include "gsm/gsm_private.h"
-#include "gsm/gsm_device_info.h"
-#include "gsm/gsm_mem.h"
+#include "lwgsm/lwgsm_private.h"
+#include "lwgsm/lwgsm_device_info.h"
+#include "lwgsm/lwgsm_mem.h"
/**
* \brief Get device manufacturer
@@ -42,23 +42,23 @@
* \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
* \param[in] evt_arg: Custom argument for event callback function
* \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_device_get_manufacturer(char* manuf, size_t len, const gsm_api_cmd_evt_fn evt_fn,
+lwgsmr_t
+lwgsm_device_get_manufacturer(char* manuf, size_t len, const lwgsm_api_cmd_evt_fn evt_fn,
void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
+ LWGSM_MSG_VAR_DEFINE(msg);
- GSM_ASSERT("manuf != NULL", manuf != NULL);
- GSM_ASSERT("len > 0", len > 0);
+ LWGSM_ASSERT("manuf != NULL", manuf != NULL);
+ LWGSM_ASSERT("len > 0", len > 0);
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_CGMI_GET;
- GSM_MSG_VAR_REF(msg).msg.device_info.str = manuf;
- GSM_MSG_VAR_REF(msg).msg.device_info.len = len;
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_CGMI_GET;
+ LWGSM_MSG_VAR_REF(msg).msg.device_info.str = manuf;
+ LWGSM_MSG_VAR_REF(msg).msg.device_info.len = len;
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 10000);
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 10000);
}
/**
@@ -68,23 +68,23 @@ gsm_device_get_manufacturer(char* manuf, size_t len, const gsm_api_cmd_evt_fn ev
* \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
* \param[in] evt_arg: Custom argument for event callback function
* \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_device_get_model(char* model, size_t len, const gsm_api_cmd_evt_fn evt_fn,
- void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
+lwgsmr_t
+lwgsm_device_get_model(char* model, size_t len, const lwgsm_api_cmd_evt_fn evt_fn,
+ void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
- GSM_ASSERT("model != NULL", model != NULL);
- GSM_ASSERT("len > 0", len > 0);
+ LWGSM_ASSERT("model != NULL", model != NULL);
+ LWGSM_ASSERT("len > 0", len > 0);
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_CGMM_GET;
- GSM_MSG_VAR_REF(msg).msg.device_info.str = model;
- GSM_MSG_VAR_REF(msg).msg.device_info.len = len;
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_CGMM_GET;
+ LWGSM_MSG_VAR_REF(msg).msg.device_info.str = model;
+ LWGSM_MSG_VAR_REF(msg).msg.device_info.len = len;
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 10000);
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 10000);
}
/**
@@ -94,23 +94,23 @@ gsm_device_get_model(char* model, size_t len, const gsm_api_cmd_evt_fn evt_fn,
* \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
* \param[in] evt_arg: Custom argument for event callback function
* \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_device_get_revision(char* rev, size_t len, const gsm_api_cmd_evt_fn evt_fn,
- void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
+lwgsmr_t
+lwgsm_device_get_revision(char* rev, size_t len, const lwgsm_api_cmd_evt_fn evt_fn,
+ void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
- GSM_ASSERT("rev != NULL", rev != NULL);
- GSM_ASSERT("len > 0", len > 0);
+ LWGSM_ASSERT("rev != NULL", rev != NULL);
+ LWGSM_ASSERT("len > 0", len > 0);
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_CGMR_GET;
- GSM_MSG_VAR_REF(msg).msg.device_info.str = rev;
- GSM_MSG_VAR_REF(msg).msg.device_info.len = len;
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_CGMR_GET;
+ LWGSM_MSG_VAR_REF(msg).msg.device_info.str = rev;
+ LWGSM_MSG_VAR_REF(msg).msg.device_info.len = len;
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 10000);
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 10000);
}
/**
@@ -120,21 +120,21 @@ gsm_device_get_revision(char* rev, size_t len, const gsm_api_cmd_evt_fn evt_fn,
* \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
* \param[in] evt_arg: Custom argument for event callback function
* \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_device_get_serial_number(char* serial, size_t len, const gsm_api_cmd_evt_fn evt_fn,
- void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
+lwgsmr_t
+lwgsm_device_get_serial_number(char* serial, size_t len, const lwgsm_api_cmd_evt_fn evt_fn,
+ void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
- GSM_ASSERT("serial != NULL", serial != NULL);
- GSM_ASSERT("len > 0", len > 0);
+ LWGSM_ASSERT("serial != NULL", serial != NULL);
+ LWGSM_ASSERT("len > 0", len > 0);
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_CGSN_GET;
- GSM_MSG_VAR_REF(msg).msg.device_info.str = serial;
- GSM_MSG_VAR_REF(msg).msg.device_info.len = len;
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_CGSN_GET;
+ LWGSM_MSG_VAR_REF(msg).msg.device_info.str = serial;
+ LWGSM_MSG_VAR_REF(msg).msg.device_info.len = len;
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 10000);
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 10000);
}
diff --git a/gsm_at_lib/src/gsm/gsm_evt.c b/lwgsm/src/lwgsm/lwgsm_evt.c
similarity index 62%
rename from gsm_at_lib/src/gsm/gsm_evt.c
rename to lwgsm/src/lwgsm/lwgsm_evt.c
index d1ea3208..dc0ba507 100644
--- a/gsm_at_lib/src/gsm/gsm_evt.c
+++ b/lwgsm/src/lwgsm/lwgsm_evt.c
@@ -1,10 +1,10 @@
-/**
- * \file gsm_evt.c
+/**
+ * \file lwgsm_evt.c
* \brief Event helper functions
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,108 +26,108 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#include "gsm/gsm_private.h"
-#include "gsm/gsm_evt.h"
-#include "gsm/gsm_mem.h"
+#include "lwgsm/lwgsm_private.h"
+#include "lwgsm/lwgsm_evt.h"
+#include "lwgsm/lwgsm_mem.h"
/**
* \brief Register callback function for global (non-connection based) events
* \param[in] fn: Callback function to call on specific event
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_evt_register(gsm_evt_fn fn) {
- gsmr_t res = gsmOK;
- gsm_evt_func_t* func, *newFunc;
+lwgsmr_t
+lwgsm_evt_register(lwgsm_evt_fn fn) {
+ lwgsmr_t res = lwgsmOK;
+ lwgsm_evt_func_t* func, *new_func;
- GSM_ASSERT("fn != NULL", fn != NULL);
+ LWGSM_ASSERT("fn != NULL", fn != NULL);
- gsm_core_lock();
+ lwgsm_core_lock();
/* Check if function already exists on list */
- for (func = gsm.evt_func; func != NULL; func = func->next) {
+ for (func = lwgsm.evt_func; func != NULL; func = func->next) {
if (func->fn == fn) {
- res = gsmERR;
+ res = lwgsmERR;
break;
}
}
- if (res == gsmOK) {
- newFunc = gsm_mem_malloc(sizeof(*newFunc));
- if (newFunc != NULL) {
- GSM_MEMSET(newFunc, 0x00, sizeof(*newFunc));
- newFunc->fn = fn; /* Set function pointer */
- for (func = gsm.evt_func; func != NULL && func->next != NULL; func = func->next) {}
+ if (res == lwgsmOK) {
+ new_func = lwgsm_mem_malloc(sizeof(*new_func));
+ if (new_func != NULL) {
+ LWGSM_MEMSET(new_func, 0x00, sizeof(*new_func));
+ new_func->fn = fn; /* Set function pointer */
+ for (func = lwgsm.evt_func; func != NULL && func->next != NULL; func = func->next) {}
if (func != NULL) {
- func->next = newFunc; /* Set new function as next */
- res = gsmOK;
+ func->next = new_func; /* Set new function as next */
+ res = lwgsmOK;
} else {
- gsm_mem_free_s((void**)& newFunc);
- res = gsmERRMEM;
+ lwgsm_mem_free_s((void**)&new_func);
+ res = lwgsmERRMEM;
}
} else {
- res = gsmERRMEM;
+ res = lwgsmERRMEM;
}
}
- gsm_core_unlock();
+ lwgsm_core_unlock();
return res;
}
/**
* \brief Unregister callback function for global (non-connection based) events
- * \note Function must be first registered using \ref gsm_evt_register
+ * \note Function must be first registered using \ref lwgsm_evt_register
* \param[in] fn: Callback function to remove from event list
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_evt_unregister(gsm_evt_fn fn) {
- gsm_evt_func_t* func, *prev;
- GSM_ASSERT("fn != NULL", fn != NULL);
+lwgsmr_t
+lwgsm_evt_unregister(lwgsm_evt_fn fn) {
+ lwgsm_evt_func_t* func, *prev;
+ LWGSM_ASSERT("fn != NULL", fn != NULL);
- gsm_core_lock();
- for (prev = gsm.evt_func, func = gsm.evt_func->next; func != NULL; prev = func, func = func->next) {
+ lwgsm_core_lock();
+ for (prev = lwgsm.evt_func, func = lwgsm.evt_func->next; func != NULL; prev = func, func = func->next) {
if (func->fn == fn) {
prev->next = func->next;
- gsm_mem_free_s((void **)&func);
+ lwgsm_mem_free_s((void**)&func);
break;
}
}
- gsm_core_unlock();
- return gsmOK;
+ lwgsm_core_unlock();
+ return lwgsmOK;
}
/**
* \brief Get event type
* \param[in] cc: Event handle
- * \return Event type. Member of \ref gsm_evt_type_t enumeration
+ * \return Event type. Member of \ref lwgsm_evt_type_t enumeration
*/
-gsm_evt_type_t
-gsm_evt_get_type(gsm_evt_t* cc) {
+lwgsm_evt_type_t
+lwgsm_evt_get_type(lwgsm_evt_t* cc) {
return cc->type;
}
/**
* \brief Get reset sequence operation status
* \param[in] cc: Event data
- * \return Member of \ref gsmr_t enumeration
+ * \return Member of \ref lwgsmr_t enumeration
*/
-gsmr_t
-gsm_evt_reset_get_result(gsm_evt_t* cc) {
+lwgsmr_t
+lwgsm_evt_reset_get_result(lwgsm_evt_t* cc) {
return cc->evt.reset.res;
}
/**
* \brief Get restore sequence operation status
* \param[in] cc: Event data
- * \return Member of \ref gsmr_t enumeration
+ * \return Member of \ref lwgsmr_t enumeration
*/
-gsmr_t
-gsm_evt_restore_get_result(gsm_evt_t* cc) {
+lwgsmr_t
+lwgsm_evt_restore_get_result(lwgsm_evt_t* cc) {
return cc->evt.restore.res;
}
@@ -136,18 +136,18 @@ gsm_evt_restore_get_result(gsm_evt_t* cc) {
* \param[in] cc: Event data
* \return Current operator handle
*/
-const gsm_operator_curr_t *
-gsm_evt_network_operator_get_current(gsm_evt_t* cc) {
+const lwgsm_operator_curr_t*
+lwgsm_evt_network_operator_get_current(lwgsm_evt_t* cc) {
return cc->evt.operator_current.operator_current;
}
/**
* \brief Get operator scan operation status
* \param[in] cc: Event data
- * \return Member of \ref gsmr_t enumeration
+ * \return Member of \ref lwgsmr_t enumeration
*/
-gsmr_t
-gsm_evt_operator_scan_get_result(gsm_evt_t* cc) {
+lwgsmr_t
+lwgsm_evt_operator_scan_get_result(lwgsm_evt_t* cc) {
return cc->evt.operator_scan.res;
}
@@ -156,8 +156,8 @@ gsm_evt_operator_scan_get_result(gsm_evt_t* cc) {
* \param[in] cc: Event data
* \return Pointer to array of operator entries
*/
-gsm_operator_t *
-gsm_evt_operator_scan_get_entries(gsm_evt_t* cc) {
+lwgsm_operator_t*
+lwgsm_evt_operator_scan_get_entries(lwgsm_evt_t* cc) {
return cc->evt.operator_scan.ops;
}
@@ -167,7 +167,7 @@ gsm_evt_operator_scan_get_entries(gsm_evt_t* cc) {
* \return Number of operators scanned
*/
size_t
-gsm_evt_operator_scan_get_length(gsm_evt_t* cc) {
+lwgsm_evt_operator_scan_get_length(lwgsm_evt_t* cc) {
return cc->evt.operator_scan.opf;
}
@@ -177,19 +177,19 @@ gsm_evt_operator_scan_get_length(gsm_evt_t* cc) {
* \return RSSI value in units of dBm
*/
int16_t
-gsm_evt_signal_strength_get_rssi(gsm_evt_t* cc) {
+lwgsm_evt_signal_strength_get_rssi(lwgsm_evt_t* cc) {
return cc->evt.rssi.rssi;
}
-#if GSM_CFG_CONN || __DOXYGEN__
+#if LWGSM_CFG_CONN || __DOXYGEN__
/**
* \brief Get buffer from received data
* \param[in] cc: Event handle
* \return Buffer handle
*/
-gsm_pbuf_p
-gsm_evt_conn_recv_get_buff(gsm_evt_t* cc) {
+lwgsm_pbuf_p
+lwgsm_evt_conn_recv_get_buff(lwgsm_evt_t* cc) {
return cc->evt.conn_data_recv.buff;
}
@@ -198,8 +198,8 @@ gsm_evt_conn_recv_get_buff(gsm_evt_t* cc) {
* \param[in] cc: Event handle
* \return Connection handle
*/
-gsm_conn_p
-gsm_evt_conn_recv_get_conn(gsm_evt_t* cc) {
+lwgsm_conn_p
+lwgsm_evt_conn_recv_get_conn(lwgsm_evt_t* cc) {
return cc->evt.conn_data_recv.conn;
}
@@ -208,8 +208,8 @@ gsm_evt_conn_recv_get_conn(gsm_evt_t* cc) {
* \param[in] cc: Event handle
* \return Connection handle
*/
-gsm_conn_p
-gsm_evt_conn_send_get_conn(gsm_evt_t* cc) {
+lwgsm_conn_p
+lwgsm_evt_conn_send_get_conn(lwgsm_evt_t* cc) {
return cc->evt.conn_data_send.conn;
}
@@ -219,17 +219,17 @@ gsm_evt_conn_send_get_conn(gsm_evt_t* cc) {
* \return Number of bytes sent
*/
size_t
-gsm_evt_conn_send_get_length(gsm_evt_t* cc) {
+lwgsm_evt_conn_send_get_length(lwgsm_evt_t* cc) {
return cc->evt.conn_data_send.sent;
}
/**
* \brief Check if connection send was successful
* \param[in] cc: Event handle
- * \return Member of \ref gsmr_t enumeration
+ * \return Member of \ref lwgsmr_t enumeration
*/
-gsmr_t
-gsm_evt_conn_send_get_result(gsm_evt_t* cc) {
+lwgsmr_t
+lwgsm_evt_conn_send_get_result(lwgsm_evt_t* cc) {
return cc->evt.conn_data_send.res;
}
@@ -238,8 +238,8 @@ gsm_evt_conn_send_get_result(gsm_evt_t* cc) {
* \param[in] cc: Event handle
* \return Connection handle
*/
-gsm_conn_p
-gsm_evt_conn_active_get_conn(gsm_evt_t* cc) {
+lwgsm_conn_p
+lwgsm_evt_conn_active_get_conn(lwgsm_evt_t* cc) {
return cc->evt.conn_active_close.conn;
}
@@ -249,8 +249,8 @@ gsm_evt_conn_active_get_conn(gsm_evt_t* cc) {
* \return `1` if client, `0` otherwise
*/
uint8_t
-gsm_evt_conn_active_is_client(gsm_evt_t* cc) {
- return GSM_U8(cc->evt.conn_active_close.client > 0);
+lwgsm_evt_conn_active_is_client(lwgsm_evt_t* cc) {
+ return LWGSM_U8(cc->evt.conn_active_close.client > 0);
}
/**
@@ -258,8 +258,8 @@ gsm_evt_conn_active_is_client(gsm_evt_t* cc) {
* \param[in] cc: Event handle
* \return Connection handle
*/
-gsm_conn_p
-gsm_evt_conn_close_get_conn(gsm_evt_t* cc) {
+lwgsm_conn_p
+lwgsm_evt_conn_close_get_conn(lwgsm_evt_t* cc) {
return cc->evt.conn_active_close.conn;
}
@@ -269,7 +269,7 @@ gsm_evt_conn_close_get_conn(gsm_evt_t* cc) {
* \return `1` if client, `0` otherwise
*/
uint8_t
-gsm_evt_conn_close_is_client(gsm_evt_t* cc) {
+lwgsm_evt_conn_close_is_client(lwgsm_evt_t* cc) {
return cc->evt.conn_active_close.client;
}
@@ -279,17 +279,17 @@ gsm_evt_conn_close_is_client(gsm_evt_t* cc) {
* \return `1` if forced, `0` otherwise
*/
uint8_t
-gsm_evt_conn_close_is_forced(gsm_evt_t* cc) {
+lwgsm_evt_conn_close_is_forced(lwgsm_evt_t* cc) {
return cc->evt.conn_active_close.forced;
}
/**
* \brief Get connection close event result
* \param[in] cc: Event handle
- * \return Member of \ref gsmr_t enumeration
+ * \return Member of \ref lwgsmr_t enumeration
*/
-gsmr_t
-gsm_evt_conn_close_get_result(gsm_evt_t* cc) {
+lwgsmr_t
+lwgsm_evt_conn_close_get_result(lwgsm_evt_t* cc) {
return cc->evt.conn_active_close.res;
}
@@ -298,28 +298,28 @@ gsm_evt_conn_close_get_result(gsm_evt_t* cc) {
* \param[in] cc: Event handle
* \return Connection handle
*/
-gsm_conn_p
-gsm_evt_conn_poll_get_conn(gsm_evt_t* cc) {
+lwgsm_conn_p
+lwgsm_evt_conn_poll_get_conn(lwgsm_evt_t* cc) {
return cc->evt.conn_poll.conn;
}
/**
* \brief Get connection error type
* \param[in] cc: Event handle
- * \return Member of \ref gsmr_t enumeration
+ * \return Member of \ref lwgsmr_t enumeration
*/
-gsmr_t
-gsm_evt_conn_error_get_error(gsm_evt_t* cc) {
+lwgsmr_t
+lwgsm_evt_conn_error_get_error(lwgsm_evt_t* cc) {
return cc->evt.conn_error.err;
}
/**
* \brief Get connection type
* \param[in] cc: Event handle
- * \return Member of \ref gsmr_t enumeration
+ * \return Member of \ref lwgsmr_t enumeration
*/
-gsm_conn_type_t
-gsm_evt_conn_error_get_type(gsm_evt_t* cc) {
+lwgsm_conn_type_t
+lwgsm_evt_conn_error_get_type(lwgsm_evt_t* cc) {
return cc->evt.conn_error.type;
}
@@ -328,8 +328,8 @@ gsm_evt_conn_error_get_type(gsm_evt_t* cc) {
* \param[in] cc: Event handle
* \return Host name for connection
*/
-const char *
-gsm_evt_conn_error_get_host(gsm_evt_t* cc) {
+const char*
+lwgsm_evt_conn_error_get_host(lwgsm_evt_t* cc) {
return cc->evt.conn_error.host;
}
@@ -338,8 +338,8 @@ gsm_evt_conn_error_get_host(gsm_evt_t* cc) {
* \param[in] cc: Event handle
* \return Host port number
*/
-gsm_port_t
-gsm_evt_conn_error_get_port(gsm_evt_t* cc) {
+lwgsm_port_t
+lwgsm_evt_conn_error_get_port(lwgsm_evt_t* cc) {
return cc->evt.conn_error.port;
}
@@ -348,14 +348,14 @@ gsm_evt_conn_error_get_port(gsm_evt_t* cc) {
* \param[in] cc: Event handle
* \return User argument
*/
-void *
-gsm_evt_conn_error_get_arg(gsm_evt_t* cc) {
+void*
+lwgsm_evt_conn_error_get_arg(lwgsm_evt_t* cc) {
return cc->evt.conn_error.arg;
}
-#endif /* GSM_CFG_CONN || __DOXYGEN__ */
+#endif /* LWGSM_CFG_CONN || __DOXYGEN__ */
-#if GSM_CFG_SMS || __DOXYGEN__
+#if LWGSM_CFG_SMS || __DOXYGEN__
/**
* \brief Get SMS position in memory which has been saved on receive
@@ -363,7 +363,7 @@ gsm_evt_conn_error_get_arg(gsm_evt_t* cc) {
* \return SMS position in memory
*/
size_t
-gsm_evt_sms_recv_get_pos(gsm_evt_t* cc) {
+lwgsm_evt_sms_recv_get_pos(lwgsm_evt_t* cc) {
return cc->evt.sms_recv.pos;
}
@@ -372,8 +372,8 @@ gsm_evt_sms_recv_get_pos(gsm_evt_t* cc) {
* \param[in] cc: Event handle
* \return SMS memory location
*/
-gsm_mem_t
-gsm_evt_sms_recv_get_mem(gsm_evt_t* cc) {
+lwgsm_mem_t
+lwgsm_evt_sms_recv_get_mem(lwgsm_evt_t* cc) {
return cc->evt.sms_recv.mem;
}
@@ -382,8 +382,8 @@ gsm_evt_sms_recv_get_mem(gsm_evt_t* cc) {
* \param[in] cc: Event handle
* \return SMS entry
*/
-gsm_sms_entry_t *
-gsm_evt_sms_read_get_entry(gsm_evt_t* cc) {
+lwgsm_sms_entry_t*
+lwgsm_evt_sms_read_get_entry(lwgsm_evt_t* cc) {
return cc->evt.sms_read.entry;
}
@@ -392,18 +392,18 @@ gsm_evt_sms_read_get_entry(gsm_evt_t* cc) {
* \param[in] cc: Event handle
* \return SMS entry
*/
-gsmr_t
-gsm_evt_sms_read_get_result(gsm_evt_t* cc) {
+lwgsmr_t
+lwgsm_evt_sms_read_get_result(lwgsm_evt_t* cc) {
return cc->evt.sms_read.res;
}
/**
* \brief Get SMS send result status
* \param[in] cc: Event handle
- * \return Member of \ref gsmr_t enumeration
+ * \return Member of \ref lwgsmr_t enumeration
*/
-gsmr_t
-gsm_evt_sms_send_get_result(gsm_evt_t* cc) {
+lwgsmr_t
+lwgsm_evt_sms_send_get_result(lwgsm_evt_t* cc) {
return cc->evt.sms_send.res;
}
@@ -414,17 +414,17 @@ gsm_evt_sms_send_get_result(gsm_evt_t* cc) {
* \return Position in memory
*/
size_t
-gsm_evt_sms_send_get_pos(gsm_evt_t* cc) {
+lwgsm_evt_sms_send_get_pos(lwgsm_evt_t* cc) {
return cc->evt.sms_send.pos;
}
/**
* \brief Get SMS delete result status
* \param[in] cc: Event handle
- * \return Member of \ref gsmr_t enumeration
+ * \return Member of \ref lwgsmr_t enumeration
*/
-gsmr_t
-gsm_evt_sms_delete_get_result(gsm_evt_t* cc) {
+lwgsmr_t
+lwgsm_evt_sms_delete_get_result(lwgsm_evt_t* cc) {
return cc->evt.sms_delete.res;
}
@@ -434,7 +434,7 @@ gsm_evt_sms_delete_get_result(gsm_evt_t* cc) {
* \return Deleted position in memory
*/
size_t
-gsm_evt_sms_delete_get_pos(gsm_evt_t* cc) {
+lwgsm_evt_sms_delete_get_pos(lwgsm_evt_t* cc) {
return cc->evt.sms_delete.pos;
}
@@ -443,23 +443,23 @@ gsm_evt_sms_delete_get_pos(gsm_evt_t* cc) {
* \param[in] cc: Event handle
* \return SMS memory for delete operation
*/
-gsm_mem_t
-gsm_evt_sms_delete_get_mem(gsm_evt_t* cc) {
+lwgsm_mem_t
+lwgsm_evt_sms_delete_get_mem(lwgsm_evt_t* cc) {
return cc->evt.sms_delete.mem;
}
-#endif /* GSM_CFG_SMS || __DOXYGEN__ */
+#endif /* LWGSM_CFG_SMS || __DOXYGEN__ */
-#if GSM_CFG_CALL || __DOXYGEN__
+#if LWGSM_CFG_CALL || __DOXYGEN__
/**
* \brief Get call information from changed event
* \param[in] cc: Event handle
* \return Position in memory
*/
-const gsm_call_t *
-gsm_evt_call_changed_get_call(gsm_evt_t* cc) {
- return gsm.evt.evt.call_changed.call;
+const lwgsm_call_t*
+lwgsm_evt_call_changed_get_call(lwgsm_evt_t* cc) {
+ return lwgsm.evt.evt.call_changed.call;
}
-#endif /* GSM_CFG_CALL || __DOXYGEN__ */
+#endif /* LWGSM_CFG_CALL || __DOXYGEN__ */
diff --git a/gsm_at_lib/src/gsm/gsm_ftp.c b/lwgsm/src/lwgsm/lwgsm_ftp.c
similarity index 78%
rename from gsm_at_lib/src/gsm/gsm_ftp.c
rename to lwgsm/src/lwgsm/lwgsm_ftp.c
index 8998cb4e..a8450ce4 100644
--- a/gsm_at_lib/src/gsm/gsm_ftp.c
+++ b/lwgsm/src/lwgsm/lwgsm_ftp.c
@@ -1,10 +1,10 @@
-/**
- * \file gsm_ftp.c
+/**
+ * \file lwgsm_ftp.c
* \brief FTP API
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,15 +26,15 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#include "gsm/gsm_private.h"
-#include "gsm/gsm_ftp.h"
-#include "gsm/gsm_mem.h"
+#include "lwgsm/lwgsm_private.h"
+#include "lwgsm/lwgsm_ftp.h"
+#include "lwgsm/lwgsm_mem.h"
-#if GSM_CFG_FTP || __DOXYGEN__
+#if LWGSM_CFG_FTP || __DOXYGEN__
-#endif /* GSM_CFG_FTP || __DOXYGEN__ */
+#endif /* LWGSM_CFG_FTP || __DOXYGEN__ */
diff --git a/gsm_at_lib/src/gsm/gsm_http.c b/lwgsm/src/lwgsm/lwgsm_http.c
similarity index 78%
rename from gsm_at_lib/src/gsm/gsm_http.c
rename to lwgsm/src/lwgsm/lwgsm_http.c
index 2b845612..5a1db9d8 100644
--- a/gsm_at_lib/src/gsm/gsm_http.c
+++ b/lwgsm/src/lwgsm/lwgsm_http.c
@@ -1,10 +1,10 @@
-/**
- * \file gsm_http.c
+/**
+ * \file lwgsm_http.c
* \brief HTTP API
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,15 +26,15 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#include "gsm/gsm_private.h"
-#include "gsm/gsm_http.h"
-#include "gsm/gsm_mem.h"
+#include "lwgsm/lwgsm_private.h"
+#include "lwgsm/lwgsm_http.h"
+#include "lwgsm/lwgsm_mem.h"
-#if GSM_CFG_HTTP || __DOXYGEN__
+#if LWGSM_CFG_HTTP || __DOXYGEN__
-#endif /* GSM_CFG_HTTP || __DOXYGEN__ */
+#endif /* LWGSM_CFG_HTTP || __DOXYGEN__ */
diff --git a/gsm_at_lib/src/gsm/gsm_input.c b/lwgsm/src/lwgsm/lwgsm_input.c
similarity index 52%
rename from gsm_at_lib/src/gsm/gsm_input.c
rename to lwgsm/src/lwgsm/lwgsm_input.c
index 38dac471..8c82b7ef 100644
--- a/gsm_at_lib/src/gsm/gsm_input.c
+++ b/lwgsm/src/lwgsm/lwgsm_input.c
@@ -1,10 +1,10 @@
/**
- * \file gsm_input.c
+ * \file lwgsm_input.c
* \brief Wrapper for passing input data to stack
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,70 +26,70 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#include "gsm/gsm_private.h"
-#include "gsm/gsm.h"
-#include "gsm/gsm_input.h"
-#include "gsm/gsm_buff.h"
+#include "lwgsm/lwgsm_private.h"
+#include "lwgsm/lwgsm.h"
+#include "lwgsm/lwgsm_input.h"
+#include "lwgsm/lwgsm_buff.h"
-static uint32_t gsm_recv_total_len;
-static uint32_t gsm_recv_calls;
+static uint32_t lwgsm_recv_total_len;
+static uint32_t lwgsm_recv_calls;
-#if !GSM_CFG_INPUT_USE_PROCESS || __DOXYGEN__
+#if !LWGSM_CFG_INPUT_USE_PROCESS || __DOXYGEN__
/**
* \brief Write data to input buffer
- * \note \ref GSM_CFG_INPUT_USE_PROCESS must be disabled to use this function
+ * \note \ref LWGSM_CFG_INPUT_USE_PROCESS must be disabled to use this function
* \param[in] data: Pointer to data to write
* \param[in] len: Number of data elements in units of bytes
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_input(const void* data, size_t len) {
- if (!gsm.status.f.initialized || gsm.buff.buff == NULL) {
- return gsmERR;
+lwgsmr_t
+lwgsm_input(const void* data, size_t len) {
+ if (!lwgsm.status.f.initialized || lwgsm.buff.buff == NULL) {
+ return lwgsmERR;
}
- gsm_buff_write(&gsm.buff, data, len); /* Write data to buffer */
- gsm_sys_mbox_putnow(&gsm.mbox_process, NULL); /* Write empty box, don't care if write fails */
- gsm_recv_total_len += len; /* Update total number of received bytes */
- gsm_recv_calls++; /* Update number of calls */
- return gsmOK;
+ lwgsm_buff_write(&lwgsm.buff, data, len); /* Write data to buffer */
+ lwgsm_sys_mbox_putnow(&lwgsm.mbox_process, NULL); /* Write empty box, don't care if write fails */
+ lwgsm_recv_total_len += len; /* Update total number of received bytes */
+ ++lwgsm_recv_calls; /* Update number of calls */
+ return lwgsmOK;
}
-#endif /* !GSM_CFG_INPUT_USE_PROCESS || __DOXYGEN__ */
+#endif /* !LWGSM_CFG_INPUT_USE_PROCESS || __DOXYGEN__ */
-#if GSM_CFG_INPUT_USE_PROCESS || __DOXYGEN__
+#if LWGSM_CFG_INPUT_USE_PROCESS || __DOXYGEN__
/**
* \brief Process input data directly without writing it to input buffer
* \note This function may only be used when in OS mode,
* where single thread is dedicated for input read of AT receive
*
- * \note \ref GSM_CFG_INPUT_USE_PROCESS must be enabled to use this function
+ * \note \ref LWGSM_CFG_INPUT_USE_PROCESS must be enabled to use this function
*
* \param[in] data: Pointer to received data to be processed
* \param[in] len: Length of data to process in units of bytes
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_input_process(const void* data, size_t len) {
- gsmr_t res;
+lwgsmr_t
+lwgsm_input_process(const void* data, size_t len) {
+ lwgsmr_t res;
- if (!gsm.status.f.initialized) {
- return gsmERR;
+ if (!lwgsm.status.f.initialized) {
+ return lwgsmERR;
}
- gsm_recv_total_len += len; /* Update total number of received bytes */
- gsm_recv_calls++; /* Update number of calls */
+ lwgsm_recv_total_len += len; /* Update total number of received bytes */
+ ++lwgsm_recv_calls; /* Update number of calls */
- gsm_core_lock();
- res = gsmi_process(data, len); /* Process input data */
- gsm_core_unlock();
+ lwgsm_core_lock();
+ res = lwgsmi_process(data, len); /* Process input data */
+ lwgsm_core_unlock();
return res;
}
-#endif /* GSM_CFG_INPUT_USE_PROCESS || __DOXYGEN__ */
+#endif /* LWGSM_CFG_INPUT_USE_PROCESS || __DOXYGEN__ */
diff --git a/lwgsm/src/lwgsm/lwgsm_int.c b/lwgsm/src/lwgsm/lwgsm_int.c
new file mode 100644
index 00000000..e9b782a5
--- /dev/null
+++ b/lwgsm/src/lwgsm/lwgsm_int.c
@@ -0,0 +1,2391 @@
+/**
+ * \file lwgsm_int.c
+ * \brief Internal functions
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM - Lightweight GSM-AT library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+#include "lwgsm/lwgsm_private.h"
+#include "lwgsm/lwgsm.h"
+#include "lwgsm/lwgsm_int.h"
+#include "lwgsm/lwgsm_mem.h"
+#include "lwgsm/lwgsm_parser.h"
+#include "lwgsm/lwgsm_unicode.h"
+#include "system/lwgsm_ll.h"
+
+#if !__DOXYGEN__
+/**
+ * \brief Receive character structure to handle full line terminated with `\n` character
+ */
+typedef struct {
+ char data[128]; /*!< Received characters */
+ size_t len; /*!< Length of valid characters */
+} lwgsm_recv_t;
+
+/* Receive character macros */
+#define RECV_ADD(ch) do { if (recv_buff.len < (sizeof(recv_buff.data)) - 1) { recv_buff.data[recv_buff.len++] = ch; recv_buff.data[recv_buff.len] = 0; } } while (0)
+#define RECV_RESET() do { recv_buff.len = 0; recv_buff.data[0] = 0; } while (0)
+#define RECV_LEN() ((size_t)recv_buff.len)
+#define RECV_IDX(index) recv_buff.data[index]
+
+/* Send data over AT port */
+#define AT_PORT_SEND_STR(str) lwgsm.ll.send_fn((const void *)(str), (size_t)strlen(str))
+#define AT_PORT_SEND_CONST_STR(str) lwgsm.ll.send_fn((const void *)(str), (size_t)(sizeof(str) - 1))
+#define AT_PORT_SEND_CHR(ch) lwgsm.ll.send_fn((const void *)(ch), (size_t)1)
+#define AT_PORT_SEND_FLUSH() lwgsm.ll.send_fn(NULL, 0)
+#define AT_PORT_SEND(d, l) lwgsm.ll.send_fn((const void *)(d), (size_t)(l))
+#define AT_PORT_SEND_WITH_FLUSH(d, l) do { AT_PORT_SEND((d), (l)); AT_PORT_SEND_FLUSH(); } while (0)
+
+/* Beginning and end of every AT command */
+#define AT_PORT_SEND_BEGIN_AT() do { AT_PORT_SEND_CONST_STR("AT"); } while (0)
+#define AT_PORT_SEND_END_AT() do { AT_PORT_SEND(CRLF, CRLF_LEN); AT_PORT_SEND(NULL, 0); } while (0)
+
+/* Send special characters over AT port with condition */
+#define AT_PORT_SEND_QUOTE_COND(q) do { if ((q)) { AT_PORT_SEND_CONST_STR("\""); } } while (0)
+#define AT_PORT_SEND_COMMA_COND(c) do { if ((c)) { AT_PORT_SEND_CONST_STR(","); } } while (0)
+#define AT_PORT_SEND_EQUAL_COND(e) do { if ((e)) { AT_PORT_SEND_CONST_STR("="); } } while (0)
+
+/* Send special characters */
+#define AT_PORT_SEND_CTRL_Z() AT_PORT_SEND_STR("\x1A")
+#define AT_PORT_SEND_ESC() AT_PORT_SEND_STR("\x1B")
+#endif /* !__DOXYGEN__ */
+
+static lwgsm_recv_t recv_buff;
+static lwgsmr_t lwgsmi_process_sub_cmd(lwgsm_msg_t* msg, uint8_t* is_ok, uint16_t* is_error);
+
+/**
+ * \brief Memory mapping
+ */
+const lwgsm_dev_mem_map_t
+lwgsm_dev_mem_map[] = {
+#define LWGSM_DEV_MEMORY_ENTRY(name, str_code) { LWGSM_MEM_ ## name, str_code },
+#include "lwgsm/lwgsm_memories.h"
+};
+
+/**
+ * \brief Size of device memory mapping array
+ */
+const size_t
+lwgsm_dev_mem_map_size = LWGSM_ARRAYSIZE(lwgsm_dev_mem_map);
+
+/**
+ * \brief List of supported devices
+ */
+const lwgsm_dev_model_map_t
+lwgsm_dev_model_map[] = {
+#define LWGSM_DEVICE_MODEL_ENTRY(name, str_id, is_2g, is_lte) { LWGSM_DEVICE_MODEL_ ## name, str_id, is_2g, is_lte },
+#include "lwgsm/lwgsm_models.h"
+};
+
+/**
+ * \brief Size of device models mapping array
+ */
+const size_t
+lwgsm_dev_model_map_size = LWGSM_ARRAYSIZE(lwgsm_dev_model_map);
+
+/**
+ * \brief Free connection send data memory
+ * \param[in] m: Send data message type
+ */
+#define CONN_SEND_DATA_FREE(m) do { \
+ if ((m) != NULL && (m)->msg.conn_send.fau) { \
+ (m)->msg.conn_send.fau = 0; \
+ if ((m)->msg.conn_send.data != NULL) { \
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_CONN | LWGSM_DBG_TYPE_TRACE, \
+ "[CONN] Free write buffer fau: %p\r\n", (void *)(m)->msg.conn_send.data); \
+ lwgsm_mem_free_s((void **)&((m)->msg.conn_send.data)); \
+ } \
+ } \
+ } while (0)
+
+/**
+ * \brief Send connection callback for "data send"
+ * \param[in] m: Command message
+ * \param[in] err: Error of type \ref lwgsmr_t
+ */
+#define CONN_SEND_DATA_SEND_EVT(m, err) do { \
+ CONN_SEND_DATA_FREE(m); \
+ lwgsm.evt.type = LWGSM_EVT_CONN_SEND; \
+ lwgsm.evt.evt.conn_data_send.res = err; \
+ lwgsm.evt.evt.conn_data_send.conn = (m)->msg.conn_send.conn; \
+ lwgsm.evt.evt.conn_data_send.sent = (m)->msg.conn_send.sent_all; \
+ lwgsmi_send_conn_cb((m)->msg.conn_send.conn, NULL); \
+ } while (0)
+
+/**
+ * \brief Send reset sequence event
+ * \param[in] m: Command message
+ * \param[in] err: Error of type \ref lwgsmr_t
+ */
+#define RESET_SEND_EVT(m, err) do { \
+ lwgsm.evt.evt.reset.res = err; \
+ lwgsmi_send_cb(LWGSM_EVT_RESET); \
+ } while (0)
+
+/**
+ * \brief Send restore sequence event
+ * \param[in] m: Connection send message
+ * \param[in] err: Error of type \ref lwgsmr_t
+ */
+#define RESTORE_SEND_EVT(m, err) do { \
+ lwgsm.evt.evt.restore.res = err; \
+ lwgsmi_send_cb(LWGSM_EVT_RESTORE); \
+ } while (0)
+
+/**
+ * \brief Send operator scan sequence event
+ * \param[in] m: Command message
+ * \param[in] err: Error of type \ref lwgsmr_t
+ */
+#define OPERATOR_SCAN_SEND_EVT(m, err) do { \
+ lwgsm.evt.evt.operator_scan.res = err; \
+ lwgsm.evt.evt.operator_scan.ops = (m)->msg.cops_scan.ops; \
+ lwgsm.evt.evt.operator_scan.opf = *(m)->msg.cops_scan.opf;\
+ lwgsmi_send_cb(LWGSM_EVT_OPERATOR_SCAN); \
+ } while (0)
+
+/**
+* \brief Send SMS delete operation event
+* \param[in] m: SMS delete message
+* \param[in] err: Error of type \ref lwgsmr_t
+*/
+#define SMS_SEND_DELETE_EVT(m, err) do { \
+ lwgsm.evt.evt.sms_delete.res = err; \
+ lwgsm.evt.evt.sms_delete.mem = (m)->msg.sms_delete.mem; \
+ lwgsm.evt.evt.sms_delete.pos = (m)->msg.sms_delete.pos; \
+ lwgsmi_send_cb(LWGSM_EVT_SMS_DELETE); \
+ } while (0)
+
+/**
+ * \brief Send SMS read operation event
+ * \param[in] m: SMS read message
+ * \param[in] err: Error of type \ref lwgsmr_t
+ */
+#define SMS_SEND_READ_EVT(m, err) do { \
+ lwgsm.evt.evt.sms_read.res = err; \
+ lwgsm.evt.evt.sms_read.entry = (m)->msg.sms_read.entry; \
+ lwgsmi_send_cb(LWGSM_EVT_SMS_READ); \
+ } while (0)
+
+/**
+ * \brief Send SMS read operation event
+ * \param[in] mm: SMS list message
+ * \param[in] err: Error of type \ref lwgsmr_t
+ */
+#define SMS_SEND_LIST_EVT(mm, err) do { \
+ lwgsm.evt.evt.sms_list.mem = lwgsm.m.sms.mem[0].current;\
+ lwgsm.evt.evt.sms_list.entries = (mm)->msg.sms_list.entries; \
+ lwgsm.evt.evt.sms_list.size = (mm)->msg.sms_list.ei; \
+ lwgsm.evt.evt.sms_list.res = err; \
+ lwgsmi_send_cb(LWGSM_EVT_SMS_LIST); \
+ } while (0)
+
+/**
+ * \brief Send SMS send operation event
+ * \param[in] m: SMS send message
+ * \param[in] err: Error of type \ref lwgsmr_t
+ */
+#define SMS_SEND_SEND_EVT(m, err) do { \
+ lwgsm.evt.evt.sms_send.pos = (m)->msg.sms_send.pos; \
+ lwgsm.evt.evt.sms_send.res = err; \
+ lwgsmi_send_cb(LWGSM_EVT_SMS_SEND); \
+ } while (0)
+
+/**
+ * \brief Get SIM info when SIM is ready
+ * \param[in] blocking: Blocking command
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+ */
+lwgsmr_t
+lwgsmi_get_sim_info(const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
+
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_SIM_PROCESS_BASIC_CMDS;
+ LWGSM_MSG_VAR_REF(msg).cmd = LWGSM_CMD_CNUM;
+
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 60000);
+}
+
+/**
+ * \brief Send IP or MAC address to AT port
+ * \param[in] d: Pointer to IP or MAC address
+ * \param[in] is_ip: Set to `1` when sending IP, `0` when MAC
+ * \param[in] q: Set to `1` to include start and ending quotes
+ * \param[in] c: Set to `1` to include comma before string
+ */
+void
+lwgsmi_send_ip_mac(const void* d, uint8_t is_ip, uint8_t q, uint8_t c) {
+ uint8_t ch;
+ char str[4];
+ const lwgsm_mac_t* mac = d;
+ const lwgsm_ip_t* ip = d;
+
+ AT_PORT_SEND_COMMA_COND(c); /* Send comma */
+ if (d == NULL) {
+ return;
+ }
+ AT_PORT_SEND_QUOTE_COND(q); /* Send quote */
+ ch = is_ip ? '.' : ':'; /* Get delimiter character */
+ for (uint8_t i = 0; i < (is_ip ? 4 : 6); ++i) { /* Process byte by byte */
+ if (is_ip) { /* In case of IP ... */
+ lwgsm_u8_to_str(ip->ip[i], str); /* ... go to decimal format ... */
+ } else { /* ... in case of MAC ... */
+ lwgsm_u8_to_hex_str(mac->mac[i], str, 2); /* ... go to HEX format */
+ }
+ AT_PORT_SEND_STR(str); /* Send str */
+ if (i < (is_ip ? 4 : 6) - 1) { /* Check end if characters */
+ AT_PORT_SEND_CHR(&ch); /* Send character */
+ }
+ }
+ AT_PORT_SEND_QUOTE_COND(q); /* Send quote */
+}
+
+/**
+ * \brief Send string to AT port, either plain or escaped
+ * \param[in] str: Pointer to input string to string
+ * \param[in] e: Value to indicate string send format, escaped (`1`) or plain (`0`)
+ * \param[in] q: Value to indicate starting and ending quotes, enabled (`1`) or disabled (`0`)
+ * \param[in] c: Set to `1` to include comma before string
+ */
+void
+lwgsmi_send_string(const char* str, uint8_t e, uint8_t q, uint8_t c) {
+ char special = '\\';
+
+ AT_PORT_SEND_COMMA_COND(c); /* Send comma */
+ AT_PORT_SEND_QUOTE_COND(q); /* Send quote */
+ if (str != NULL) {
+ if (e) { /* Do we have to escape string? */
+ while (*str) { /* Go through string */
+ if (*str == ',' || *str == '"' || *str == '\\') { /* Check for special character */
+ AT_PORT_SEND_CHR(&special); /* Send special character */
+ }
+ AT_PORT_SEND_CHR(str); /* Send character */
+ ++str;
+ }
+ } else {
+ AT_PORT_SEND_STR(str); /* Send plain string */
+ }
+ }
+ AT_PORT_SEND_QUOTE_COND(q); /* Send quote */
+}
+
+/**
+ * \brief Send number (decimal) to AT port
+ * \param[in] num: Number to send to AT port
+ * \param[in] q: Value to indicate starting and ending quotes, enabled (`1`) or disabled (`0`)
+ * \param[in] c: Set to `1` to include comma before string
+ */
+void
+lwgsmi_send_number(uint32_t num, uint8_t q, uint8_t c) {
+ char str[11];
+
+ lwgsm_u32_to_str(num, str); /* Convert digit to decimal string */
+
+ AT_PORT_SEND_COMMA_COND(c); /* Send comma */
+ AT_PORT_SEND_QUOTE_COND(q); /* Send quote */
+ AT_PORT_SEND_STR(str); /* Send string with number */
+ AT_PORT_SEND_QUOTE_COND(q); /* Send quote */
+}
+
+/**
+ * \brief Send port number to AT port
+ * \param[in] port: Port number to send
+ * \param[in] q: Value to indicate starting and ending quotes, enabled (`1`) or disabled (`0`)
+ * \param[in] c: Set to `1` to include comma before string
+ */
+void
+lwgsmi_send_port(lwgsm_port_t port, uint8_t q, uint8_t c) {
+ char str[6];
+
+ lwgsm_u16_to_str(LWGSM_PORT2NUM(port), str);/* Convert digit to decimal string */
+
+ AT_PORT_SEND_COMMA_COND(c); /* Send comma */
+ AT_PORT_SEND_QUOTE_COND(q); /* Send quote */
+ AT_PORT_SEND_STR(str); /* Send string with number */
+ AT_PORT_SEND_QUOTE_COND(q); /* Send quote */
+}
+
+/**
+ * \brief Send signed number to AT port
+ * \param[in] num: Number to send to AT port
+ * \param[in] q: Value to indicate starting and ending quotes, enabled (`1`) or disabled (`0`)
+ * \param[in] c: Set to `1` to include comma before string
+ */
+void
+lwgsmi_send_signed_number(int32_t num, uint8_t q, uint8_t c) {
+ char str[11];
+
+ lwgsm_i32_to_str(num, str); /* Convert digit to decimal string */
+
+ AT_PORT_SEND_COMMA_COND(c); /* Send comma */
+ AT_PORT_SEND_QUOTE_COND(q); /* Send quote */
+ AT_PORT_SEND_STR(str); /* Send string with number */
+ AT_PORT_SEND_QUOTE_COND(q); /* Send quote */
+}
+
+/**
+ * \brief Send memory string to device
+ * \param[in] mem: Memory index to send
+ * \param[in] q: Value to indicate starting and ending quotes, enabled (`1`) or disabled (`0`)
+ * \param[in] c: Set to `1` to include comma before string
+ */
+void
+lwgsmi_send_dev_memory(lwgsm_mem_t mem, uint8_t q, uint8_t c) {
+ if (mem < LWGSM_MEM_END) { /* Check valid range */
+ lwgsmi_send_string(lwgsm_dev_mem_map[LWGSM_SZ(mem)].mem_str, 0, q, c);
+ }
+}
+
+#if LWGSM_CFG_SMS || __DOXYGEN__
+
+/**
+ * \brief Send SMS status text
+ * \param[in] status: SMS status
+ * \param[in] q: Value to indicate starting and ending quotes, enabled (`1`) or disabled (`0`)
+ * \param[in] c: Set to `1` to include comma before string
+ */
+void
+lwgsmi_send_sms_stat(lwgsm_sms_status_t status, uint8_t q, uint8_t c) {
+ const char* t;
+ switch (status) {
+ case LWGSM_SMS_STATUS_UNREAD:
+ t = "REC UNREAD";
+ break;
+ case LWGSM_SMS_STATUS_READ:
+ t = "REC READ";
+ break;
+ case LWGSM_SMS_STATUS_UNSENT:
+ t = "STO UNSENT";
+ break;
+ case LWGSM_SMS_STATUS_SENT:
+ t = "STO SENT";
+ break;
+ case LWGSM_SMS_STATUS_ALL:
+ default:
+ t = "ALL";
+ break;
+ }
+ lwgsmi_send_string(t, 0, q, c);
+}
+
+#endif /* LWGSM_CFG_SMS */
+
+#if LWGSM_CFG_CONN || __DOXYGEN__
+
+/**
+ * \brief Reset all connections
+ * \note Used to notify upper layer stack to close everything and reset the memory if necessary
+ * \param[in] forced: Flag indicating reset was forced by user
+ */
+static void
+reset_connections(uint8_t forced) {
+ lwgsm.evt.type = LWGSM_EVT_CONN_CLOSE;
+ lwgsm.evt.evt.conn_active_close.forced = forced;
+ lwgsm.evt.evt.conn_active_close.res = lwgsmOK;
+
+ for (size_t i = 0; i < LWGSM_CFG_MAX_CONNS; ++i) { /* Check all connections */
+ if (lwgsm.m.conns[i].status.f.active) {
+ lwgsm.m.conns[i].status.f.active = 0;
+
+ lwgsm.evt.evt.conn_active_close.conn = &lwgsm.m.conns[i];
+ lwgsm.evt.evt.conn_active_close.client = lwgsm.m.conns[i].status.f.client;
+ lwgsmi_send_conn_cb(&lwgsm.m.conns[i], NULL); /* Send callback function */
+ }
+ }
+}
+
+#endif /* LWGSM_CFG_CONN || __DOXYGEN__ */
+
+/**
+ * \brief Reset everything after reset was detected
+ * \param[in] forced: Set to `1` if reset forced by user
+ */
+void
+lwgsmi_reset_everything(uint8_t forced) {
+ /**
+ * \todo: Put stack to default state:
+ * - Close all the connection in memory
+ * - Clear entire data memory
+ * - Reset GSM structure
+ */
+
+#if LWGSM_CFG_CONN
+ /* Manually close all connections in memory */
+ reset_connections(forced);
+
+ /* Check if IPD active */
+ if (lwgsm.m.ipd.buff != NULL) {
+ lwgsm_pbuf_free(lwgsm.m.ipd.buff);
+ lwgsm.m.ipd.buff = NULL;
+ }
+#endif /* LWGSM_CFG_CONN */
+
+#if LWGSM_CFG_NETWORK
+ /* Notify app about detached network PDP context */
+ if (lwgsm.m.network.is_attached) {
+ lwgsm.m.network.is_attached = 0;
+ lwgsmi_send_cb(LWGSM_EVT_NETWORK_DETACHED);
+ }
+#endif /* LWGSM_CFG_NETWORK */
+
+ /* Invalid GSM modules */
+ LWGSM_MEMSET(&lwgsm.m, 0x00, sizeof(lwgsm.m));
+
+ /* Manually set states */
+ lwgsm.m.sim.state = (lwgsm_sim_state_t) -1;
+ lwgsm.m.model = LWGSM_DEVICE_MODEL_UNKNOWN;
+}
+
+/**
+ * \brief Process callback function to user with specific type
+ * \param[in] type: Callback event type
+ * \return Member of \ref lwgsmr_t enumeration
+ */
+lwgsmr_t
+lwgsmi_send_cb(lwgsm_evt_type_t type) {
+ lwgsm.evt.type = type; /* Set callback type to process */
+
+ /* Call callback function for all registered functions */
+ for (lwgsm_evt_func_t* link = lwgsm.evt_func; link != NULL; link = link->next) {
+ link->fn(&lwgsm.evt);
+ }
+ return lwgsmOK;
+}
+
+#if LWGSM_CFG_CONN || __DOXYGEN__
+
+/**
+ * \brief Process connection callback
+ * \note Before calling function, callback structure must be prepared
+ * \param[in] conn: Pointer to connection to use as callback
+ * \param[in] evt: Event callback function for connection
+ * \return Member of \ref lwgsmr_t enumeration
+ */
+lwgsmr_t
+lwgsmi_send_conn_cb(lwgsm_conn_t* conn, lwgsm_evt_fn evt) {
+ if (conn->status.f.in_closing && lwgsm.evt.type != LWGSM_EVT_CONN_CLOSE) { /* Do not continue if in closing mode */
+ /* return lwgsmOK; */
+ }
+
+ if (evt != NULL) { /* Try with user connection */
+ return evt(&lwgsm.evt); /* Call temporary function */
+ } else if (conn != NULL && conn->evt_func != NULL) {/* Connection custom callback? */
+ return conn->evt_func(&lwgsm.evt); /* Process callback function */
+ } else if (conn == NULL) {
+ return lwgsmOK;
+ }
+
+ /*
+ * On normal API operation,
+ * we should never enter to this part of code
+ */
+
+ /*
+ * If connection doesn't have callback function
+ * automatically close the connection?
+ *
+ * Since function call is non-blocking,
+ * it will set active connection to closing mode
+ * and further callback events should not be executed anymore
+ */
+ return lwgsm_conn_close(conn, 0);
+}
+
+/**
+ * \brief Process and send data from device buffer
+ * \return Member of \ref lwgsmr_t enumeration
+ */
+static lwgsmr_t
+lwgsmi_tcpip_process_send_data(void) {
+ lwgsm_conn_t* c = lwgsm.msg->msg.conn_send.conn;
+ if (!lwgsm_conn_is_active(c) || /* Is the connection already closed? */
+ lwgsm.msg->msg.conn_send.val_id != c->val_id/* Did validation ID change after we set parameter? */
+ ) {
+ /* Send event to user about failed send event */
+ CONN_SEND_DATA_SEND_EVT(lwgsm.msg, lwgsmCLOSED);
+ return lwgsmERR;
+ }
+ lwgsm.msg->msg.conn_send.sent = LWGSM_MIN(lwgsm.msg->msg.conn_send.btw, LWGSM_CFG_CONN_MAX_DATA_LEN);
+
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CIPSEND=");
+ lwgsmi_send_number(LWGSM_U32(c->num), 0, 0);/* Send connection number */
+ lwgsmi_send_number(LWGSM_U32(lwgsm.msg->msg.conn_send.sent), 0, 1); /* Send length number */
+
+ /* On UDP connections, IP address and port may be selected */
+ if (c->type == LWGSM_CONN_TYPE_UDP) {
+ if (lwgsm.msg->msg.conn_send.remote_ip != NULL && lwgsm.msg->msg.conn_send.remote_port) {
+ lwgsmi_send_ip_mac(lwgsm.msg->msg.conn_send.remote_ip, 1, 1, 1);/* Send IP address including quotes */
+ lwgsmi_send_port(lwgsm.msg->msg.conn_send.remote_port, 0, 1); /* Send length number */
+ }
+ }
+ AT_PORT_SEND_END_AT();
+ return lwgsmOK;
+}
+
+/**
+ * \brief Process data sent and send remaining
+ * \param[in] sent: Status whether data were sent or not,
+ * info received from GSM with "SEND OK" or "SEND FAIL"
+ * \return `1` in case we should stop sending or `0` if we still have data to process
+ */
+static uint8_t
+lwgsmi_tcpip_process_data_sent(uint8_t sent) {
+ if (sent) { /* Data were successfully sent */
+ lwgsm.msg->msg.conn_send.sent_all += lwgsm.msg->msg.conn_send.sent;
+ lwgsm.msg->msg.conn_send.btw -= lwgsm.msg->msg.conn_send.sent;
+ lwgsm.msg->msg.conn_send.ptr += lwgsm.msg->msg.conn_send.sent;
+ if (lwgsm.msg->msg.conn_send.bw != NULL) {
+ *lwgsm.msg->msg.conn_send.bw += lwgsm.msg->msg.conn_send.sent;
+ }
+ lwgsm.msg->msg.conn_send.tries = 0;
+ } else { /* We were not successful */
+ ++lwgsm.msg->msg.conn_send.tries; /* Increase number of tries */
+ if (lwgsm.msg->msg.conn_send.tries == LWGSM_CFG_MAX_SEND_RETRIES) { /* In case we reached max number of retransmissions */
+ return 1; /* Return 1 and indicate error */
+ }
+ }
+ if (lwgsm.msg->msg.conn_send.btw > 0) { /* Do we still have data to send? */
+ if (lwgsmi_tcpip_process_send_data() != lwgsmOK) { /* Check if we can continue */
+ return 1; /* Finish at this point */
+ }
+ return 0; /* We still have data to send */
+ }
+ return 1; /* Everything was sent, we can stop execution */
+}
+
+/**
+ * \brief Process CIPSEND response
+ * \param[in] rcv: Received data
+ * \param[in,out] is_ok: Pointer to current ok status
+ * \param[in,out] is_error: Pointer to current error status
+ */
+void
+lwgsmi_process_cipsend_response(lwgsm_recv_t* rcv, uint8_t* is_ok, uint16_t* is_error) {
+ if (lwgsm.msg->msg.conn_send.wait_send_ok_err) {
+ if (LWGSM_CHARISNUM(rcv->data[0]) && rcv->data[1] == ',') {
+ uint8_t num = LWGSM_CHARTONUM(rcv->data[0]);
+ if (!strncmp(&rcv->data[3], "SEND OK" CRLF, 7 + CRLF_LEN)) {
+ lwgsm.msg->msg.conn_send.wait_send_ok_err = 0;
+ *is_ok = lwgsmi_tcpip_process_data_sent(1); /* Process as data were sent */
+ if (*is_ok && lwgsm.msg->msg.conn_send.conn->status.f.active) {
+ CONN_SEND_DATA_SEND_EVT(lwgsm.msg, lwgsmOK);
+ }
+ } else if (!strncmp(&rcv->data[3], "SEND FAIL" CRLF, 9 + CRLF_LEN)) {
+ lwgsm.msg->msg.conn_send.wait_send_ok_err = 0;
+ *is_error = lwgsmi_tcpip_process_data_sent(0); /* Data were not sent due to SEND FAIL or command didn't even start */
+ if (*is_error && lwgsm.msg->msg.conn_send.conn->status.f.active) {
+ CONN_SEND_DATA_SEND_EVT(lwgsm.msg, lwgsmERR);
+ }
+ }
+ LWGSM_UNUSED(num);
+ }
+ /* Check for an error or if connection closed in the meantime */
+ } else if (*is_error) {
+ CONN_SEND_DATA_SEND_EVT(lwgsm.msg, lwgsmERR);
+ }
+}
+
+/**
+ * \brief Send error event to application layer
+ * \param[in] msg: Message from user with connection start
+ * \param[in] error: Error type
+ */
+static void
+lwgsmi_send_conn_error_cb(lwgsm_msg_t* msg, lwgsmr_t error) {
+ lwgsm.evt.type = LWGSM_EVT_CONN_ERROR; /* Connection error */
+ lwgsm.evt.evt.conn_error.host = lwgsm.msg->msg.conn_start.host;
+ lwgsm.evt.evt.conn_error.port = lwgsm.msg->msg.conn_start.port;
+ lwgsm.evt.evt.conn_error.type = lwgsm.msg->msg.conn_start.type;
+ lwgsm.evt.evt.conn_error.arg = lwgsm.msg->msg.conn_start.arg;
+ lwgsm.evt.evt.conn_error.err = error;
+
+ /* Call callback specified by user on connection startup */
+ lwgsm.msg->msg.conn_start.evt_func(&lwgsm.evt);
+ LWGSM_UNUSED(msg);
+}
+
+/**
+ * \brief Checks if connection pointer has valid address
+ * \param[in] conn: Address to check if valid connection ptr
+ * \return 1 on success, 0 otherwise
+ */
+uint8_t
+lwgsmi_is_valid_conn_ptr(lwgsm_conn_p conn) {
+ uint8_t i = 0;
+ for (i = 0; i < LWGSM_ARRAYSIZE(lwgsm.m.conns); ++i) {
+ if (conn == &lwgsm.m.conns[i]) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/**
+ * \brief Connection close event detected, process with callback to user
+ * \param[in] conn_num: Connection number
+ * \param[in] forced: Set to `1` if close forced by command, `0` otherwise
+ * \return `1` on success, `0` otherwise
+ */
+uint8_t
+lwgsmi_conn_closed_process(uint8_t conn_num, uint8_t forced) {
+ lwgsm_conn_t* conn = &lwgsm.m.conns[conn_num];
+
+ conn->status.f.active = 0;
+
+ /* Check if write buffer is set */
+ if (conn->buff.buff != NULL) {
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_CONN | LWGSM_DBG_TYPE_TRACE,
+ "[CONN] Free write buffer: %p\r\n", conn->buff.buff);
+ lwgsm_mem_free_s((void**)&conn->buff.buff);
+ }
+
+ /* Send event */
+ lwgsm.evt.type = LWGSM_EVT_CONN_CLOSE;
+ lwgsm.evt.evt.conn_active_close.conn = conn;
+ lwgsm.evt.evt.conn_active_close.forced = forced;
+ lwgsm.evt.evt.conn_active_close.res = lwgsmOK;
+ lwgsm.evt.evt.conn_active_close.client = conn->status.f.client;
+ lwgsmi_send_conn_cb(conn, NULL);
+
+ return 1;
+}
+
+#endif /* LWGSM_CFG_CONN || __DOXYGEN__ */
+
+/**
+ * \brief Process received string from GSM
+ * \param[in] rcv: Pointer to \ref lwgsm_recv_t structure with input string
+ */
+static void
+lwgsmi_parse_received(lwgsm_recv_t* rcv) {
+ uint8_t is_ok = 0;
+ uint16_t is_error = 0;
+
+ /* Try to remove non-parsable strings */
+ if (rcv->len == 2 && rcv->data[0] == '\r' && rcv->data[1] == '\n') {
+ return;
+ }
+
+ /* Check OK response */
+ is_ok = rcv->len == (2 + CRLF_LEN) && !strcmp(rcv->data, "OK" CRLF);/* Check if received string is OK */
+ if (!is_ok) { /* Check for SHUT OK string */
+ is_ok = rcv->len == (7 + CRLF_LEN) && !strcmp(rcv->data, "SEND OK" CRLF);
+ }
+
+ /* Check error response */
+ if (!is_ok) { /* If still not ok, check if error? */
+ is_error = rcv->data[0] == '+' && !strncmp(rcv->data, "+CME ERROR", 10);/* First check +CME coded errors */
+ if (!is_error) { /* Check basic error aswell */
+ is_error = rcv->data[0] == '+' && !strncmp(rcv->data, "+CMS ERROR", 10);/* First check +CME coded errors */
+ if (!is_error) {
+ is_error = !strcmp(rcv->data, "ERROR" CRLF) || !strcmp(rcv->data, "FAIL" CRLF);
+ }
+ }
+ }
+
+ /* Scan received strings which start with '+' */
+ if (rcv->data[0] == '+') {
+ if (!strncmp(rcv->data, "+CSQ", 4)) {
+ lwgsmi_parse_csq(rcv->data); /* Parse +CSQ response */
+#if LWGSM_CFG_NETWORK
+ } else if (!strncmp(rcv->data, "+PDP: DEACT", 11)) {
+ /* PDP has been deactivated */
+ lwgsm_network_check_status(NULL, NULL, 0); /* Update status */
+#endif /* LWGSM_CFG_NETWORK */
+#if LWGSM_CFG_CONN
+ } else if (!strncmp(rcv->data, "+RECEIVE", 8)) {
+ lwgsmi_parse_ipd(rcv->data); /* Parse IPD */
+#endif /* LWGSM_CFG_CONN */
+ } else if (!strncmp(rcv->data, "+CREG", 5)) { /* Check for +CREG indication */
+ lwgsmi_parse_creg(rcv->data, LWGSM_U8(CMD_IS_CUR(LWGSM_CMD_CREG_GET))); /* Parse +CREG response */
+ } else if (!strncmp(rcv->data, "+CPIN", 5)) { /* Check for +CPIN indication for SIM */
+ lwgsmi_parse_cpin(rcv->data, 1 /* !CMD_IS_DEF(LWGSM_CMD_CPIN_SET) */); /* Parse +CPIN response */
+ } else if (CMD_IS_CUR(LWGSM_CMD_COPS_GET) && !strncmp(rcv->data, "+COPS", 5)) {
+ lwgsmi_parse_cops(rcv->data); /* Parse current +COPS */
+#if LWGSM_CFG_SMS
+ } else if (CMD_IS_CUR(LWGSM_CMD_CMGS) && !strncmp(rcv->data, "+CMGS", 5)) {
+ lwgsmi_parse_cmgs(rcv->data, &lwgsm.msg->msg.sms_send.pos); /* Parse +CMGS response */
+ } else if (CMD_IS_CUR(LWGSM_CMD_CMGR) && !strncmp(rcv->data, "+CMGR", 5)) {
+ if (lwgsmi_parse_cmgr(rcv->data)) { /* Parse +CMGR response */
+ lwgsm.msg->msg.sms_read.read = 2; /* Set read flag and process the data */
+ } else {
+ lwgsm.msg->msg.sms_read.read = 1; /* Read but ignore data */
+ }
+ } else if (CMD_IS_CUR(LWGSM_CMD_CMGL) && !strncmp(rcv->data, "+CMGL", 5)) {
+ if (lwgsmi_parse_cmgl(rcv->data)) { /* Parse +CMGL response */
+ lwgsm.msg->msg.sms_list.read = 2; /* Set read flag and process the data */
+ } else {
+ lwgsm.msg->msg.sms_list.read = 1; /* Read but ignore data */
+ }
+ } else if (!strncmp(rcv->data, "+CMTI", 5)) {
+ lwgsmi_parse_cmti(rcv->data, 1); /* Parse +CMTI response with received SMS */
+ } else if (CMD_IS_CUR(LWGSM_CMD_CPMS_GET_OPT) && !strncmp(rcv->data, "+CPMS", 5)) {
+ lwgsmi_parse_cpms(rcv->data, 0); /* Parse +CPMS with SMS memories info */
+ } else if (CMD_IS_CUR(LWGSM_CMD_CPMS_GET) && !strncmp(rcv->data, "+CPMS", 5)) {
+ lwgsmi_parse_cpms(rcv->data, 1); /* Parse +CPMS with SMS memories info */
+ } else if (CMD_IS_CUR(LWGSM_CMD_CPMS_SET) && !strncmp(rcv->data, "+CPMS", 5)) {
+ lwgsmi_parse_cpms(rcv->data, 2); /* Parse +CPMS with SMS memories info */
+#endif /* LWGSM_CFG_SMS */
+#if LWGSM_CFG_CALL
+ } else if (!strncmp(rcv->data, "+CLCC", 5)) {
+ lwgsmi_parse_clcc(rcv->data, 1); /* Parse +CLCC response with call info change */
+#endif /* LWGSM_CFG_CALL */
+#if LWGSM_CFG_PHONEBOOK
+ } else if (CMD_IS_CUR(LWGSM_CMD_CPBS_GET_OPT) && !strncmp(rcv->data, "+CPBS", 5)) {
+ lwgsmi_parse_cpbs(rcv->data, 0); /* Parse +CPBS response */
+ } else if (CMD_IS_CUR(LWGSM_CMD_CPBS_GET) && !strncmp(rcv->data, "+CPBS", 5)) {
+ lwgsmi_parse_cpbs(rcv->data, 1); /* Parse +CPBS response */
+ } else if (CMD_IS_CUR(LWGSM_CMD_CPBS_SET) && !strncmp(rcv->data, "+CPBS", 5)) {
+ lwgsmi_parse_cpbs(rcv->data, 2); /* Parse +CPBS response */
+ } else if (CMD_IS_CUR(LWGSM_CMD_CPBR) && !strncmp(rcv->data, "+CPBR", 5)) {
+ lwgsmi_parse_cpbr(rcv->data); /* Parse +CPBR statement */
+ } else if (CMD_IS_CUR(LWGSM_CMD_CPBF) && !strncmp(rcv->data, "+CPBF", 5)) {
+ lwgsmi_parse_cpbf(rcv->data); /* Parse +CPBR statement */
+#endif /* LWGSM_CFG_PHONEBOOK */
+ }
+
+ /* Messages not starting with '+' sign */
+ } else {
+ if (rcv->data[0] == 'S' && !strncmp(rcv->data, "SHUT OK" CRLF, 7 + CRLF_LEN)) {
+ is_ok = 1;
+#if LWGSM_CFG_CONN
+ } else if (LWGSM_CHARISNUM(rcv->data[0]) && rcv->data[1] == ',' && rcv->data[2] == ' '
+ && (!strncmp(&rcv->data[3], "CLOSE OK" CRLF, 8 + CRLF_LEN) || !strncmp(&rcv->data[3], "CLOSED" CRLF, 6 + CRLF_LEN))) {
+ uint8_t forced = 0, num;
+
+ num = LWGSM_CHARTONUM(rcv->data[0]);/* Get connection number */
+ if (CMD_IS_CUR(LWGSM_CMD_CIPCLOSE) && lwgsm.msg->msg.conn_close.conn->num == num) {
+ forced = 1;
+ is_ok = 1; /* If forced and connection is closed, command is OK */
+ }
+
+ /* Manually stop send command? */
+ if (CMD_IS_CUR(LWGSM_CMD_CIPSEND) && lwgsm.msg->msg.conn_send.conn->num == num) {
+ /*
+ * If active command is CIPSEND and CLOSED event received,
+ * manually set error and process usual "ERROR" event on senddata
+ */
+ is_error = 1; /* This is an error in response */
+ lwgsmi_process_cipsend_response(rcv, &is_ok, &is_error);
+ }
+ lwgsmi_conn_closed_process(num, forced);/* Connection closed, process */
+#endif /* LWGSM_CFG_CONN */
+#if LWGSM_CFG_CALL
+ } else if (rcv->data[0] == 'C' && !strncmp(rcv->data, "Call Ready" CRLF, 10 + CRLF_LEN)) {
+ lwgsm.m.call.ready = 1;
+ lwgsmi_send_cb(LWGSM_EVT_CALL_READY); /* Send CALL ready event */
+ } else if (rcv->data[0] == 'R' && !strncmp(rcv->data, "RING" CRLF, 4 + CRLF_LEN)) {
+ lwgsmi_send_cb(LWGSM_EVT_CALL_RING);/* Send call ring */
+ } else if (rcv->data[0] == 'N' && !strncmp(rcv->data, "NO CARRIER" CRLF, 10 + CRLF_LEN)) {
+ lwgsmi_send_cb(LWGSM_EVT_CALL_NO_CARRIER); /* Send call no carrier event */
+ } else if (rcv->data[0] == 'B' && !strncmp(rcv->data, "BUSY" CRLF, 4 + CRLF_LEN)) {
+ lwgsmi_send_cb(LWGSM_EVT_CALL_BUSY);/* Send call busy message */
+#endif /* LWGSM_CFG_CALL */
+#if LWGSM_CFG_SMS
+ } else if (rcv->data[0] == 'S' && !strncmp(rcv->data, "SMS Ready" CRLF, 9 + CRLF_LEN)) {
+ lwgsm.m.sms.ready = 1; /* SMS ready flag */
+ lwgsmi_send_cb(LWGSM_EVT_SMS_READY);/* Send SMS ready event */
+#endif /* LWGSM_CFG_SMS */
+ } else if ((CMD_IS_CUR(LWGSM_CMD_CGMI_GET) || CMD_IS_CUR(LWGSM_CMD_CGMM_GET) || CMD_IS_CUR(LWGSM_CMD_CGSN_GET) || CMD_IS_CUR(LWGSM_CMD_CGMR_GET))
+ && !is_ok && !is_error && strncmp(rcv->data, "AT+", 3)) {
+ const char* tmp = rcv->data;
+ size_t tocopy;
+ if (CMD_IS_CUR(LWGSM_CMD_CGMI_GET)) { /* Check device manufacturer */
+ lwgsmi_parse_string(&tmp, lwgsm.m.model_manufacturer, sizeof(lwgsm.m.model_manufacturer), 1);
+ if (CMD_IS_DEF(LWGSM_CMD_CGMI_GET)) {
+ tocopy = LWGSM_MIN(sizeof(lwgsm.m.model_manufacturer), lwgsm.msg->msg.device_info.len);
+ LWGSM_MEMCPY(lwgsm.msg->msg.device_info.str, lwgsm.m.model_manufacturer, tocopy);
+ lwgsm.msg->msg.device_info.str[tocopy - 1] = 0;
+ }
+ } else if (CMD_IS_CUR(LWGSM_CMD_CGMM_GET)) {/* Check device model number */
+ lwgsmi_parse_string(&tmp, lwgsm.m.model_number, sizeof(lwgsm.m.model_number), 1);
+ if (CMD_IS_DEF(LWGSM_CMD_CGMM_GET)) {
+ tocopy = LWGSM_MIN(sizeof(lwgsm.m.model_number), lwgsm.msg->msg.device_info.len);
+ LWGSM_MEMCPY(lwgsm.msg->msg.device_info.str, lwgsm.m.model_number, tocopy);
+ lwgsm.msg->msg.device_info.str[tocopy - 1] = 0;
+ }
+ for (size_t i = 0; i < lwgsm_dev_model_map_size; ++i) {
+ if (strstr(lwgsm.m.model_number, lwgsm_dev_model_map[i].id_str) != NULL) {
+ lwgsm.m.model = lwgsm_dev_model_map[i].model;
+ break;
+ }
+ }
+ } else if (CMD_IS_CUR(LWGSM_CMD_CGSN_GET)) {/* Check device serial number */
+ lwgsmi_parse_string(&tmp, lwgsm.m.model_serial_number, sizeof(lwgsm.m.model_serial_number), 1);
+ if (CMD_IS_DEF(LWGSM_CMD_CGSN_GET)) {
+ tocopy = LWGSM_MIN(sizeof(lwgsm.m.model_serial_number), lwgsm.msg->msg.device_info.len);
+ LWGSM_MEMCPY(lwgsm.msg->msg.device_info.str, lwgsm.m.model_serial_number, tocopy);
+ lwgsm.msg->msg.device_info.str[tocopy - 1] = 0;
+ }
+ } else if (CMD_IS_CUR(LWGSM_CMD_CGMR_GET)) {/* Check device revision */
+ if (!strncmp(tmp, "Revision:", 9)) {
+ tmp += 9;
+ }
+ lwgsmi_parse_string(&tmp, lwgsm.m.model_revision, sizeof(lwgsm.m.model_revision), 1);
+ if (CMD_IS_DEF(LWGSM_CMD_CGMR_GET)) {
+ tocopy = LWGSM_MIN(sizeof(lwgsm.m.model_revision), lwgsm.msg->msg.device_info.len);
+ LWGSM_MEMCPY(lwgsm.msg->msg.device_info.str, lwgsm.m.model_revision, tocopy);
+ lwgsm.msg->msg.device_info.str[tocopy - 1] = 0;
+ }
+ }
+ } else if (CMD_IS_CUR(LWGSM_CMD_CIFSR) && LWGSM_CHARISNUM(rcv->data[0])) {
+ const char* tmp = rcv->data;
+ lwgsmi_parse_ip(&tmp, &lwgsm.m.network.ip_addr);/* Parse IP address */
+
+ is_ok = 1; /* Manually set OK flag as we don't expect OK in CIFSR command */
+ }
+ }
+
+ /* Check general responses for active commands */
+ if (lwgsm.msg != NULL) {
+ if (0) {
+#if LWGSM_CFG_SMS
+ } else if (CMD_IS_CUR(LWGSM_CMD_CMGS) && is_ok) {
+ /* At this point we have to wait for "> " to send data */
+#endif /* LWGSM_CFG_SMS */
+#if LWGSM_CFG_CONN
+ } else if (CMD_IS_CUR(LWGSM_CMD_CIPSTATUS)) {
+ /* For CIPSTATUS, OK is returned before important data */
+ if (is_ok) {
+ is_ok = 0;
+ }
+ /* Check if connection data received */
+ if (rcv->len > 3) {
+ uint8_t continueScan, processed = 0;
+ if (rcv->data[0] == 'C' && rcv->data[1] == ':' && rcv->data[2] == ' ') {
+ processed = 1;
+ lwgsmi_parse_cipstatus_conn(rcv->data, 1, &continueScan);
+
+ if (lwgsm.m.active_conns_cur_parse_num == (LWGSM_CFG_MAX_CONNS - 1)) {
+ is_ok = 1;
+ }
+ } else if (!strncmp(rcv->data, "STATE:", 6)) {
+ processed = 1;
+ lwgsmi_parse_cipstatus_conn(rcv->data, 0, &continueScan);
+ }
+
+ /* Check if we shall stop processing at this stage */
+ if (processed && !continueScan) {
+ is_ok = 1;
+ }
+ }
+ } else if (CMD_IS_CUR(LWGSM_CMD_CIPSTART)) {
+ /* For CIPSTART, OK is returned before important data */
+ if (is_ok) {
+ is_ok = 0;
+ }
+
+ /* Wait here for CONNECT status before we cancel connection */
+ if (LWGSM_CHARISNUM(rcv->data[0])
+ && rcv->data[1] == ',' && rcv->data[2] == ' ') {
+ uint8_t num = LWGSM_CHARTONUM(rcv->data[0]);
+ if (num < LWGSM_CFG_MAX_CONNS) {
+ uint8_t id;
+ lwgsm_conn_t* conn = &lwgsm.m.conns[num]; /* Get connection handle */
+
+ if (!strncmp(&rcv->data[3], "CONNECT OK" CRLF, 10 + CRLF_LEN)) {
+ id = conn->val_id;
+ LWGSM_MEMSET(conn, 0x00, sizeof(*conn));/* Reset connection parameters */
+ conn->num = num;
+ conn->status.f.active = 1;
+ conn->val_id = ++id; /* Set new validation ID */
+
+ /* Set connection parameters */
+ conn->status.f.client = 1;
+ conn->evt_func = lwgsm.msg->msg.conn_start.evt_func;
+ conn->arg = lwgsm.msg->msg.conn_start.arg;
+
+ /* Set status */
+ lwgsm.msg->msg.conn_start.conn_res = LWGSM_CONN_CONNECT_OK;
+ is_ok = 1;
+ } else if (!strncmp(&rcv->data[3], "CONNECT FAIL" CRLF, 12 + CRLF_LEN)) {
+ lwgsm.msg->msg.conn_start.conn_res = LWGSM_CONN_CONNECT_ERROR;
+ is_error = 1;
+ } else if (!strncmp(&rcv->data[3], "ALREADY CONNECT" CRLF, 15 + CRLF_LEN)) {
+ lwgsm.msg->msg.conn_start.conn_res = LWGSM_CONN_CONNECT_ALREADY;
+ is_error = 1;
+ }
+ }
+ }
+ } else if (CMD_IS_CUR(LWGSM_CMD_CIPSEND)) {
+ if (is_ok) {
+ is_ok = 0;
+ }
+ lwgsmi_process_cipsend_response(rcv, &is_ok, &is_error);
+#endif /* LWGSM_CFG_CONN */
+#if LWGSM_CFG_USSD
+ } else if (CMD_IS_CUR(LWGSM_CMD_CUSD)) {
+ /* OK is returned before +CUSD */
+ /* Command is not finished yet, unless it was an ERROR */
+ if (is_ok) {
+ is_ok = 0;
+ }
+
+ /* Check for manual CUSTOM OK message */
+ if (!strcmp(rcv->data, "CUSTOM_OK\r\n")) {
+ is_ok = 1;
+ }
+#endif /* LWGSM_CFG_USSD */
+ }
+ }
+
+ /*
+ * In case of any of these events, simply release semaphore
+ * and proceed with next command
+ */
+ if (is_ok || is_error) {
+ lwgsmr_t res = lwgsmOK;
+ if (lwgsm.msg != NULL) { /* Do we have active message? */
+ res = lwgsmi_process_sub_cmd(lwgsm.msg, &is_ok, &is_error);
+ if (res != lwgsmCONT) { /* Shall we continue with next subcommand under this one? */
+ if (is_ok) { /* Check OK status */
+ res = lwgsm.msg->res = lwgsmOK;
+ } else { /* Or error status */
+ res = lwgsm.msg->res = res; /* Set the error status */
+ }
+ } else {
+ ++lwgsm.msg->i; /* Number of continue calls */
+ }
+
+ /*
+ * When the command is finished,
+ * release synchronization semaphore
+ * from user thread and start with next command
+ */
+ if (res != lwgsmCONT) { /* Do we have to continue to wait for command? */
+ lwgsm_sys_sem_release(&lwgsm.sem_sync); /* Release semaphore */
+ }
+ }
+ }
+}
+
+#if !LWGSM_CFG_INPUT_USE_PROCESS || __DOXYGEN__
+/**
+ * \brief Process data from input buffer
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
+ */
+lwgsmr_t
+lwgsmi_process_buffer(void) {
+ void* data;
+ size_t len;
+
+ do {
+ /*
+ * Get length of linear memory in buffer
+ * we can process directly as memory
+ */
+ len = lwgsm_buff_get_linear_block_read_length(&lwgsm.buff);
+ if (len > 0) {
+ /*
+ * Get memory address of first element
+ * in linear block of data to process
+ */
+ data = lwgsm_buff_get_linear_block_read_address(&lwgsm.buff);
+
+ /* Process actual received data */
+ lwgsmi_process(data, len);
+
+ /*
+ * Once data is processed, simply skip
+ * the buffer memory and start over
+ */
+ lwgsm_buff_skip(&lwgsm.buff, len);
+ }
+ } while (len);
+ return lwgsmOK;
+}
+#endif /* !LWGSM_CFG_INPUT_USE_PROCESS || __DOXYGEN__ */
+
+/**
+ * \brief Process input data received from GSM device
+ * \param[in] data: Pointer to data to process
+ * \param[in] data_len: Length of data to process in units of bytes
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
+ */
+lwgsmr_t
+lwgsmi_process(const void* data, size_t data_len) {
+ uint8_t ch;
+ const uint8_t* d = data;
+ size_t d_len = data_len;
+ static uint8_t ch_prev1, ch_prev2;
+ static lwgsm_unicode_t unicode;
+
+ /* Check status if device is available */
+ if (!lwgsm.status.f.dev_present) {
+ return lwgsmERRNODEVICE;
+ }
+
+ while (d_len > 0) { /* Read entire set of characters from buffer */
+ ch = *d; /* Get next character */
+ ++d; /* Go to next character, must be here as it is used later on */
+ --d_len; /* Decrease remaining length, must be here as it is decreased later too */
+
+ if (0) {
+#if LWGSM_CFG_CONN
+ } else if (lwgsm.m.ipd.read) { /* Read connection data */
+ size_t len;
+
+ if (lwgsm.m.ipd.buff != NULL) { /* Do we have active buffer? */
+ lwgsm.m.ipd.buff->payload[lwgsm.m.ipd.buff_ptr] = ch; /* Save data character */
+ }
+ ++lwgsm.m.ipd.buff_ptr;
+ --lwgsm.m.ipd.rem_len;
+
+ /* Try to read more data directly from buffer */
+ len = LWGSM_MIN(d_len, LWGSM_MIN(lwgsm.m.ipd.rem_len, lwgsm.m.ipd.buff != NULL ? (lwgsm.m.ipd.buff->len - lwgsm.m.ipd.buff_ptr) : lwgsm.m.ipd.rem_len));
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_IPD | LWGSM_DBG_TYPE_TRACE,
+ "[IPD] New length to read: %d bytes\r\n", (int)len);
+ if (len > 0) {
+ if (lwgsm.m.ipd.buff != NULL) { /* Is buffer valid? */
+ LWGSM_MEMCPY(&lwgsm.m.ipd.buff->payload[lwgsm.m.ipd.buff_ptr], d, len);
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_IPD | LWGSM_DBG_TYPE_TRACE,
+ "[IPD] Bytes read: %d\r\n", (int)len);
+ } else { /* Simply skip the data in buffer */
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_IPD | LWGSM_DBG_TYPE_TRACE,
+ "[IPD] Bytes skipped: %d\r\n", (int)len);
+ }
+ d_len -= len; /* Decrease effective length */
+ d += len; /* Skip remaining length */
+ lwgsm.m.ipd.buff_ptr += len; /* Forward buffer pointer */
+ lwgsm.m.ipd.rem_len -= len; /* Decrease remaining length */
+ }
+
+ /* Did we reach end of buffer or no more data? */
+ if (lwgsm.m.ipd.rem_len == 0 || (lwgsm.m.ipd.buff != NULL && lwgsm.m.ipd.buff_ptr == lwgsm.m.ipd.buff->len)) {
+ lwgsmr_t res = lwgsmOK;
+
+ /* Call user callback function with received data */
+ if (lwgsm.m.ipd.buff != NULL) { /* Do we have valid buffer? */
+ lwgsm.m.ipd.conn->total_recved += lwgsm.m.ipd.buff->tot_len;/* Increase number of bytes received */
+
+ /*
+ * Send data buffer to upper layer
+ *
+ * From this moment, user is responsible for packet
+ * buffer and must free it manually
+ */
+ lwgsm.evt.type = LWGSM_EVT_CONN_RECV;
+ lwgsm.evt.evt.conn_data_recv.buff = lwgsm.m.ipd.buff;
+ lwgsm.evt.evt.conn_data_recv.conn = lwgsm.m.ipd.conn;
+ res = lwgsmi_send_conn_cb(lwgsm.m.ipd.conn, NULL);
+
+ lwgsm_pbuf_free(lwgsm.m.ipd.buff); /* Free packet buffer at this point */
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_IPD | LWGSM_DBG_TYPE_TRACE,
+ "[IPD] Free packet buffer\r\n");
+ if (res == lwgsmOKIGNOREMORE) { /* We should ignore more data */
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_IPD | LWGSM_DBG_TYPE_TRACE,
+ "[IPD] Ignoring more data from this IPD if available\r\n");
+ lwgsm.m.ipd.buff = NULL;/* Set to NULL to ignore more data if possibly available */
+ }
+
+ /*
+ * Create new data packet if case if:
+ *
+ * - Previous one was successful and more data to read and
+ * - Connection is not in closing state
+ */
+ if (lwgsm.m.ipd.buff != NULL && lwgsm.m.ipd.rem_len > 0 && !lwgsm.m.ipd.conn->status.f.in_closing) {
+ size_t new_len = LWGSM_MIN(lwgsm.m.ipd.rem_len, LWGSM_CFG_IPD_MAX_BUFF_SIZE); /* Calculate new buffer length */
+
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_IPD | LWGSM_DBG_TYPE_TRACE,
+ "[IPD] Allocating new packet buffer of size: %d bytes\r\n", (int)new_len);
+ lwgsm.m.ipd.buff = lwgsm_pbuf_new(new_len); /* Allocate new packet buffer */
+
+ LWGSM_DEBUGW(LWGSM_CFG_DBG_IPD | LWGSM_DBG_TYPE_TRACE | LWGSM_DBG_LVL_WARNING,
+ lwgsm.m.ipd.buff == NULL, "[IPD] Buffer allocation failed for %d bytes\r\n", (int)new_len);
+ } else {
+ lwgsm.m.ipd.buff = NULL;/* Reset it */
+ }
+ }
+ if (lwgsm.m.ipd.rem_len == 0) { /* Check if we read everything */
+ lwgsm.m.ipd.buff = NULL; /* Reset buffer pointer */
+ lwgsm.m.ipd.read = 0; /* Stop reading data */
+ }
+ lwgsm.m.ipd.buff_ptr = 0; /* Reset input buffer pointer */
+ }
+#endif /* LWGSM_CFG_CONN */
+ /*
+ * Check if operators scan command is active
+ * and if we are ready to read the incoming data
+ */
+ } else if (CMD_IS_CUR(LWGSM_CMD_COPS_GET_OPT) && lwgsm.msg->msg.cops_scan.read) {
+ if (ch == '\n') {
+ lwgsm.msg->msg.cops_scan.read = 0;
+ } else {
+ lwgsmi_parse_cops_scan(ch, 0); /* Parse character by character */
+ }
+#if LWGSM_CFG_SMS
+ } else if (CMD_IS_CUR(LWGSM_CMD_CMGR) && lwgsm.msg->msg.sms_read.read) {
+ lwgsm_sms_entry_t* e = lwgsm.msg->msg.sms_read.entry;
+ if (lwgsm.msg->msg.sms_read.read == 2) {/* Read only if set to 2 */
+ if (e != NULL) { /* Check if valid entry */
+ if (e->length < (sizeof(e->data) - 1)) {
+ e->data[e->length++] = ch;
+ }
+ } else {
+ lwgsm.msg->msg.sms_read.read = 1; /* Read but ignore data */
+ }
+ }
+ if (ch == '\n' && ch_prev1 == '\r') {
+ if (lwgsm.msg->msg.sms_read.read == 2) {
+
+ }
+ lwgsm.msg->msg.sms_read.read = 0;
+ }
+ } else if (CMD_IS_CUR(LWGSM_CMD_CMGL) && lwgsm.msg->msg.sms_list.read) {
+ if (lwgsm.msg->msg.sms_list.read == 2) {
+ lwgsm_sms_entry_t* e = &lwgsm.msg->msg.sms_list.entries[lwgsm.msg->msg.sms_list.ei];
+ if (e->length < (sizeof(e->data) - 1)) {
+ e->data[e->length++] = ch;
+ }
+ }
+ if (ch == '\n' && ch_prev1 == '\r') {
+ if (lwgsm.msg->msg.sms_list.read == 2) {
+ ++lwgsm.msg->msg.sms_list.ei; /* Go to next entry */
+ if (lwgsm.msg->msg.sms_list.er != NULL) { /* Check and update user variable */
+ *lwgsm.msg->msg.sms_list.er = lwgsm.msg->msg.sms_list.ei;
+ }
+ }
+ lwgsm.msg->msg.sms_list.read = 0;
+ }
+#endif /* LWGSM_CFG_SMS */
+#if LWGSM_CFG_USSD
+ } else if (CMD_IS_CUR(LWGSM_CMD_CUSD) && lwgsm.msg->msg.ussd.read) {
+ if (ch == '"') {
+ lwgsm.msg->msg.ussd.resp[lwgsm.msg->msg.ussd.resp_write_ptr] = 0;
+ lwgsm.msg->msg.ussd.quote_det = !lwgsm.msg->msg.ussd.quote_det;
+ } else if (lwgsm.msg->msg.ussd.quote_det) {
+ if (lwgsm.msg->msg.ussd.resp_write_ptr < lwgsm.msg->msg.ussd.resp_len) {
+ lwgsm.msg->msg.ussd.resp[lwgsm.msg->msg.ussd.resp_write_ptr++] = ch;
+ lwgsm.msg->msg.ussd.resp[lwgsm.msg->msg.ussd.resp_write_ptr] = 0;
+ }
+ } else if (ch == '\n' && ch_prev1 == '\r') {
+ /* End of reading, command finished! */
+ /* Return OK at this point! */
+ strcpy(recv_buff.data, "CUSTOM_OK\r\n");
+ recv_buff.len = strlen(recv_buff.data);
+ lwgsmi_parse_received(&recv_buff);
+ }
+#endif /* LWGSM_CFG_USSD */
+ /*
+ * We are in command mode where we have to process byte by byte
+ * Simply check for ASCII and unicode format and process data accordingly
+ */
+ } else {
+ lwgsmr_t res = lwgsmERR;
+ if (LWGSM_ISVALIDASCII(ch)) { /* Manually check if valid ASCII character */
+ res = lwgsmOK;
+ unicode.t = 1; /* Manually set total to 1 */
+ unicode.r = 0; /* Reset remaining bytes */
+ } else if (ch >= 0x80) { /* Process only if more than ASCII can hold */
+ res = lwgsmi_unicode_decode(&unicode, ch); /* Try to decode unicode format */
+ }
+
+ if (res == lwgsmERR) { /* In case of an ERROR */
+ unicode.r = 0;
+ }
+ if (res == lwgsmOK) { /* Can we process the character(s) */
+ if (unicode.t == 1) { /* Totally 1 character? */
+ switch (ch) {
+ case '\n':
+ RECV_ADD(ch); /* Add character to input buffer */
+ lwgsmi_parse_received(&recv_buff); /* Parse received string */
+ RECV_RESET(); /* Reset received string */
+ break;
+ default:
+ RECV_ADD(ch); /* Any ASCII valid character */
+ break;
+ }
+
+#if LWGSM_CFG_CONN
+ /* Check if we have to read data */
+ if (ch == '\n' && lwgsm.m.ipd.read) {
+ size_t len;
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_IPD | LWGSM_DBG_TYPE_TRACE,
+ "[IPD] Data on connection %d with total size %d byte(s)\r\n",
+ (int)lwgsm.m.ipd.conn->num, (int)lwgsm.m.ipd.tot_len);
+
+ len = LWGSM_MIN(lwgsm.m.ipd.rem_len, LWGSM_CFG_IPD_MAX_BUFF_SIZE);
+
+ /*
+ * Read received data in case of:
+ *
+ * - Connection is active and
+ * - Connection is not in closing mode
+ */
+ if (lwgsm.m.ipd.conn->status.f.active && !lwgsm.m.ipd.conn->status.f.in_closing) {
+ lwgsm.m.ipd.buff = lwgsm_pbuf_new(len); /* Allocate new packet buffer */
+ LWGSM_DEBUGW(LWGSM_CFG_DBG_IPD | LWGSM_DBG_TYPE_TRACE | LWGSM_DBG_LVL_WARNING, lwgsm.m.ipd.buff == NULL,
+ "[IPD] Buffer allocation failed for %d byte(s)\r\n", (int)len);
+ } else {
+ lwgsm.m.ipd.buff = NULL;/* Ignore reading on closed connection */
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_IPD | LWGSM_DBG_TYPE_TRACE,
+ "[IPD] Connection %d closed or in closing, skipping %d byte(s)\r\n",
+ (int)lwgsm.m.ipd.conn->num, (int)len);
+ }
+ lwgsm.m.ipd.conn->status.f.data_received = 1; /* We have first received data */
+
+ lwgsm.m.ipd.buff_ptr = 0; /* Reset buffer write pointer */
+ }
+#endif /* LWGSM_CFG_CONN */
+
+ /*
+ * Do we have a special sequence "> "?
+ *
+ * Check if any command active which may expect that kind of response
+ */
+ if (ch_prev2 == '\n' && ch_prev1 == '>' && ch == ' ') {
+ if (0) {
+#if LWGSM_CFG_CONN
+ } else if (CMD_IS_CUR(LWGSM_CMD_CIPSEND)) {
+ RECV_RESET(); /* Reset received object */
+
+ /* Now actually send the data prepared before */
+ AT_PORT_SEND_WITH_FLUSH(&lwgsm.msg->msg.conn_send.data[lwgsm.msg->msg.conn_send.ptr], lwgsm.msg->msg.conn_send.sent);
+ lwgsm.msg->msg.conn_send.wait_send_ok_err = 1; /* Now we are waiting for "SEND OK" or "SEND ERROR" */
+#endif /* LWGSM_CFG_CONN */
+#if LWGSM_CFG_SMS
+ } else if (CMD_IS_CUR(LWGSM_CMD_CMGS)) {/* Send SMS? */
+ AT_PORT_SEND(lwgsm.msg->msg.sms_send.text, strlen(lwgsm.msg->msg.sms_send.text));
+ AT_PORT_SEND_CTRL_Z();
+ AT_PORT_SEND_FLUSH();
+#endif /* LWGSM_CFG_SMS */
+ }
+ } else if (CMD_IS_CUR(LWGSM_CMD_COPS_GET_OPT)) {
+ if (RECV_LEN() > 5 && !strncmp(recv_buff.data, "+COPS:", 6)) {
+ RECV_RESET(); /* Reset incoming buffer */
+ lwgsmi_parse_cops_scan(0, 1); /* Reset parser state */
+ lwgsm.msg->msg.cops_scan.read = 1; /* Start reading incoming bytes */
+ }
+#if LWGSM_CFG_USSD
+ } else if (CMD_IS_CUR(LWGSM_CMD_CUSD)) {
+ if (RECV_LEN() > 5 && !strncmp(recv_buff.data, "+CUSD:", 6)) {
+ RECV_RESET(); /* Reset incoming buffer */
+ lwgsm.msg->msg.ussd.read = 1; /* Start reading incoming bytes */
+ }
+#endif /* LWGSM_CFG_USSD */
+ }
+ } else { /* We have sequence of unicode characters */
+ /*
+ * Unicode sequence characters are not "meta" characters
+ * so it is safe to just add them to receive array without checking
+ * what are the actual values
+ */
+ for (uint8_t i = 0; i < unicode.t; ++i) {
+ RECV_ADD(unicode.ch[i]);/* Add character to receive array */
+ }
+ }
+ } else if (res != lwgsmINPROG) { /* Not in progress? */
+ RECV_RESET(); /* Invalid character in sequence */
+ }
+ }
+
+ ch_prev2 = ch_prev1; /* Save previous character as previous previous */
+ ch_prev1 = ch; /* Set current as previous */
+ }
+ return lwgsmOK;
+}
+
+/* Temporary macros, only available for inside lwgsmi_process_sub_cmd function */
+/* Set new command, but first check for error on previous */
+#define SET_NEW_CMD_CHECK_ERROR(new_cmd) do { \
+ if (!*(is_error)) { \
+ n_cmd = (new_cmd); \
+ } \
+ } while (0)
+
+/* Set new command, ignore result of previous */
+#define SET_NEW_CMD(new_cmd) do { \
+ n_cmd = (new_cmd); \
+ } while (0)
+
+/**
+ * \brief Process current command with known execution status and start another if necessary
+ * \param[in] msg: Pointer to current message
+ * \param[in] is_ok: pointer to status whether last command result was OK
+ * \param[in] is_error: Pointer to status whether last command result was ERROR
+ * \return \ref lwgsmCONT if you sent more data and we need to process more data, \ref lwgsmOK on success, or \ref lwgsmERR on error
+ */
+static lwgsmr_t
+lwgsmi_process_sub_cmd(lwgsm_msg_t* msg, uint8_t* is_ok, uint16_t* is_error) {
+ lwgsm_cmd_t n_cmd = LWGSM_CMD_IDLE;
+ if (CMD_IS_DEF(LWGSM_CMD_RESET)) {
+ switch (CMD_GET_CUR()) { /* Check current command */
+ case LWGSM_CMD_RESET: {
+ lwgsmi_reset_everything(1); /* Reset everything */
+ SET_NEW_CMD(LWGSM_CFG_AT_ECHO ? LWGSM_CMD_ATE1 : LWGSM_CMD_ATE0); /* Set ECHO mode */
+ lwgsm_delay(5000); /* Delay for some time before we can continue after reset */
+ break;
+ }
+ case LWGSM_CMD_ATE0:
+ case LWGSM_CMD_ATE1:
+ SET_NEW_CMD(LWGSM_CMD_CFUN_SET);
+ break; /* Set full functionality */
+ case LWGSM_CMD_CFUN_SET:
+ SET_NEW_CMD(LWGSM_CMD_CMEE_SET);
+ break; /* Set detailed error reporting */
+ case LWGSM_CMD_CMEE_SET:
+ SET_NEW_CMD(LWGSM_CMD_CGMI_GET);
+ break; /* Get manufacturer */
+ case LWGSM_CMD_CGMI_GET:
+ SET_NEW_CMD(LWGSM_CMD_CGMM_GET);
+ break; /* Get model */
+ case LWGSM_CMD_CGMM_GET:
+ SET_NEW_CMD(LWGSM_CMD_CGSN_GET);
+ break; /* Get product serial number */
+ case LWGSM_CMD_CGSN_GET:
+ SET_NEW_CMD(LWGSM_CMD_CGMR_GET);
+ break; /* Get product revision */
+ case LWGSM_CMD_CGMR_GET: {
+ /*
+ * At this point we have modem info.
+ * It is now time to send info to user
+ * to select between device drivers
+ */
+ lwgsmi_send_cb(LWGSM_EVT_DEVICE_IDENTIFIED);
+
+ SET_NEW_CMD(LWGSM_CMD_CREG_SET);/* Enable unsolicited code for CREG */
+ break;
+ }
+ case LWGSM_CMD_CREG_SET:
+ SET_NEW_CMD(LWGSM_CMD_CLCC_SET);
+ break; /* Set call state */
+ case LWGSM_CMD_CLCC_SET:
+ SET_NEW_CMD(LWGSM_CMD_CPIN_GET);
+ break; /* Get SIM state */
+ case LWGSM_CMD_CPIN_GET:
+ break;
+ default:
+ break;
+ }
+
+ /* Send event */
+ if (n_cmd == LWGSM_CMD_IDLE) {
+ RESET_SEND_EVT(msg, lwgsmOK);
+ }
+ } else if (CMD_IS_DEF(LWGSM_CMD_COPS_GET)) {
+ if (CMD_IS_CUR(LWGSM_CMD_COPS_GET)) {
+ lwgsm.evt.evt.operator_current.operator_current = &lwgsm.m.network.curr_operator;
+ lwgsmi_send_cb(LWGSM_EVT_NETWORK_OPERATOR_CURRENT);
+ }
+ } else if (CMD_IS_DEF(LWGSM_CMD_COPS_GET_OPT)) {
+ if (CMD_IS_CUR(LWGSM_CMD_COPS_GET_OPT)) {
+ OPERATOR_SCAN_SEND_EVT(lwgsm.msg, *is_ok ? lwgsmOK : lwgsmERR);
+ }
+ } else if (CMD_IS_DEF(LWGSM_CMD_SIM_PROCESS_BASIC_CMDS)) {
+ if (CMD_IS_CUR(LWGSM_CMD_CNUM)) {
+ /* Get own phone number */
+ if (!*is_ok) {
+ /* Sometimes SIM is not ready just after PIN entered */
+ if (msg->msg.sim_info.cnum_tries < 5) {
+ ++msg->msg.sim_info.cnum_tries;
+ SET_NEW_CMD(LWGSM_CMD_CNUM);
+ lwgsm_delay(1000);
+ }
+ }
+ }
+ } else if (CMD_IS_DEF(LWGSM_CMD_CPIN_SET)) {/* Set PIN code */
+ switch (CMD_GET_CUR()) {
+ case LWGSM_CMD_CPIN_GET: { /* Get own phone number */
+ if (*is_ok && lwgsm.m.sim.state == LWGSM_SIM_STATE_PIN) {
+ SET_NEW_CMD(LWGSM_CMD_CPIN_SET);/* Set command to write PIN */
+ } else if (lwgsm.m.sim.state != LWGSM_SIM_STATE_READY) {
+ *is_ok = 0;
+ *is_error = 1;
+ }
+ break;
+ }
+ case LWGSM_CMD_CPIN_SET: { /* Set CPIN */
+ if (*is_ok) {
+ lwgsm_delay(5000); /* Make delay to make sure SIM is ready */
+ }
+ break;
+ }
+ default:
+ break;
+ }
+#if LWGSM_CFG_SMS
+ } else if (CMD_IS_DEF(LWGSM_CMD_SMS_ENABLE)) {
+ switch (CMD_GET_CUR()) {
+ case LWGSM_CMD_CPMS_GET_OPT:
+ SET_NEW_CMD(LWGSM_CMD_CPMS_GET);
+ break;
+ case LWGSM_CMD_CPMS_GET:
+ break;
+ default:
+ break;
+ }
+ if (!*is_ok || n_cmd == LWGSM_CMD_IDLE) { /* Stop execution on any command */
+ SET_NEW_CMD(LWGSM_CMD_IDLE);
+ lwgsm.m.sms.enabled = n_cmd == LWGSM_CMD_IDLE; /* Set enabled status */
+ lwgsm.evt.evt.sms_enable.status = lwgsm.m.sms.enabled ? lwgsmOK : lwgsmERR;
+ lwgsmi_send_cb(LWGSM_EVT_SMS_ENABLE); /* Send to user */
+ }
+ } else if (CMD_IS_DEF(LWGSM_CMD_CMGS)) { /* Send SMS default command */
+ if (CMD_IS_CUR(LWGSM_CMD_CMGF) && *is_ok) { /* Set message format current command */
+ SET_NEW_CMD(LWGSM_CMD_CMGS); /* Now send actual message */
+ }
+
+ /* Send event on finish */
+ if (n_cmd == LWGSM_CMD_IDLE) {
+ SMS_SEND_SEND_EVT(lwgsm.msg, *is_ok ? lwgsmOK : lwgsmERR);
+ }
+ } else if (CMD_IS_DEF(LWGSM_CMD_CMGR)) { /* Read SMS message */
+ if (CMD_IS_CUR(LWGSM_CMD_CPMS_GET) && *is_ok) {
+ SET_NEW_CMD(LWGSM_CMD_CPMS_SET); /* Set memory */
+ } else if (CMD_IS_CUR(LWGSM_CMD_CPMS_SET) && *is_ok) {
+ SET_NEW_CMD(LWGSM_CMD_CMGF); /* Set text mode */
+ } else if (CMD_IS_CUR(LWGSM_CMD_CMGF) && *is_ok) { /* Set message format current command*/
+ SET_NEW_CMD(LWGSM_CMD_CMGR); /* Start message read */
+ } else if (CMD_IS_CUR(LWGSM_CMD_CMGR) && *is_ok) {
+ msg->msg.sms_read.mem = lwgsm.m.sms.mem[0].current; /* Set current memory */
+ }
+
+ /* Send event on finish */
+ if (n_cmd == LWGSM_CMD_IDLE) {
+ SMS_SEND_READ_EVT(lwgsm.msg, *is_ok ? lwgsmOK : lwgsmERR);
+ }
+ } else if (CMD_IS_DEF(LWGSM_CMD_CMGD)) { /* Delete SMS message*/
+ if (CMD_IS_CUR(LWGSM_CMD_CPMS_GET) && *is_ok) {
+ SET_NEW_CMD(LWGSM_CMD_CPMS_SET); /* Set memory */
+ } else if (CMD_IS_CUR(LWGSM_CMD_CPMS_SET) && *is_ok) {
+ SET_NEW_CMD(LWGSM_CMD_CMGD); /* Delete message */
+ }
+
+ /* Send event on finish */
+ if (n_cmd == LWGSM_CMD_IDLE) {
+ SMS_SEND_DELETE_EVT(msg, *is_ok ? lwgsmOK : lwgsmERR);
+ }
+ } else if (CMD_IS_DEF(LWGSM_CMD_CMGDA)) {
+ if (CMD_IS_CUR(LWGSM_CMD_CMGF) && *is_ok) {
+ SET_NEW_CMD(LWGSM_CMD_CMGDA); /* Mass storage */
+ }
+ } else if (CMD_IS_DEF(LWGSM_CMD_CMGL)) { /* List SMS messages */
+ if (CMD_IS_CUR(LWGSM_CMD_CPMS_GET) && *is_ok) {
+ SET_NEW_CMD(LWGSM_CMD_CPMS_SET); /* Set memory */
+ } else if (CMD_IS_CUR(LWGSM_CMD_CPMS_SET) && *is_ok) {
+ SET_NEW_CMD(LWGSM_CMD_CMGF); /* Set text format */
+ } else if (CMD_IS_CUR(LWGSM_CMD_CMGF) && *is_ok) {
+ SET_NEW_CMD(LWGSM_CMD_CMGL); /* List messages */
+ }
+
+ /* Send event on finish */
+ if (n_cmd == LWGSM_CMD_IDLE) {
+ SMS_SEND_LIST_EVT(msg, *is_ok ? lwgsmOK : lwgsmERR);
+ }
+ } else if (CMD_IS_DEF(LWGSM_CMD_CPMS_SET)) {/* Set preferred memory */
+ if (CMD_IS_CUR(LWGSM_CMD_CPMS_GET) && *is_ok) {
+ SET_NEW_CMD(LWGSM_CMD_CPMS_SET); /* Now set the command */
+ }
+#endif /* LWGSM_CFG_SMS */
+#if LWGSM_CFG_CALL
+ } else if (CMD_IS_DEF(LWGSM_CMD_CALL_ENABLE)) {
+ lwgsm.m.call.enabled = *is_ok; /* Set enabled status */
+ lwgsm.evt.evt.call_enable.res = lwgsm.m.call.enabled ? lwgsmOK : lwgsmERR;
+ lwgsmi_send_cb(LWGSM_EVT_CALL_ENABLE); /* Send to user */
+#endif /* LWGSM_CFG_CALL */
+#if LWGSM_CFG_PHONEBOOK
+ } else if (CMD_IS_DEF(LWGSM_CMD_PHONEBOOK_ENABLE)) {
+ lwgsm.m.pb.enabled = *is_ok; /* Set enabled status */
+ lwgsm.evt.evt.pb_enable.res = lwgsm.m.pb.enabled ? lwgsmOK : lwgsmERR;
+ lwgsmi_send_cb(LWGSM_EVT_PB_ENABLE); /* Send to user */
+ } else if (CMD_IS_DEF(LWGSM_CMD_CPBW_SET)) {/* Write phonebook entry */
+ if (CMD_IS_CUR(LWGSM_CMD_CPBS_GET) && *is_ok) { /* Get current memory */
+ SET_NEW_CMD(LWGSM_CMD_CPBS_SET); /* Set current memory */
+ } else if (CMD_IS_CUR(LWGSM_CMD_CPBS_SET) && *is_ok) {
+ SET_NEW_CMD(LWGSM_CMD_CPBW_SET); /* Write entry to phonebook */
+ }
+ } else if (CMD_IS_DEF(LWGSM_CMD_CPBR)) {
+ if (CMD_IS_CUR(LWGSM_CMD_CPBS_GET) && *is_ok) { /* Get current memory */
+ SET_NEW_CMD(LWGSM_CMD_CPBS_SET); /* Set current memory */
+ } else if (CMD_IS_CUR(LWGSM_CMD_CPBS_SET) && *is_ok) {
+ SET_NEW_CMD(LWGSM_CMD_CPBR); /* Read entries */
+ } else if (CMD_IS_CUR(LWGSM_CMD_CPBR)) {
+ lwgsm.evt.evt.pb_list.mem = lwgsm.m.pb.mem.current;
+ lwgsm.evt.evt.pb_list.entries = lwgsm.msg->msg.pb_list.entries;
+ lwgsm.evt.evt.pb_list.size = lwgsm.msg->msg.pb_list.ei;
+ lwgsm.evt.evt.pb_list.res = *is_ok ? lwgsmOK : lwgsmERR;
+ lwgsmi_send_cb(LWGSM_EVT_PB_LIST);
+ }
+ } else if (CMD_IS_DEF(LWGSM_CMD_CPBF)) {
+ if (CMD_IS_CUR(LWGSM_CMD_CPBS_GET) && *is_ok) { /* Get current memory */
+ SET_NEW_CMD(LWGSM_CMD_CPBS_SET); /* Set current memory */
+ } else if (CMD_IS_CUR(LWGSM_CMD_CPBS_SET) && *is_ok) {
+ SET_NEW_CMD(LWGSM_CMD_CPBF); /* Read entries */
+ } else if (CMD_IS_CUR(LWGSM_CMD_CPBF)) {
+ lwgsm.evt.evt.pb_search.mem = lwgsm.m.pb.mem.current;
+ lwgsm.evt.evt.pb_search.search = lwgsm.msg->msg.pb_search.search;
+ lwgsm.evt.evt.pb_search.entries = lwgsm.msg->msg.pb_search.entries;
+ lwgsm.evt.evt.pb_search.size = lwgsm.msg->msg.pb_search.ei;
+ lwgsm.evt.evt.pb_search.res = *is_ok ? lwgsmOK : lwgsmERR;
+ lwgsmi_send_cb(LWGSM_EVT_PB_SEARCH);
+ }
+#endif /* LWGSM_CFG_PHONEBOOK */
+#if LWGSM_CFG_NETWORK
+ }
+ if (CMD_IS_DEF(LWGSM_CMD_NETWORK_ATTACH)) {
+ switch (msg->i) {
+ case 0:
+ SET_NEW_CMD_CHECK_ERROR(LWGSM_CMD_CGACT_SET_0);
+ break;
+ case 1:
+ SET_NEW_CMD(LWGSM_CMD_CGACT_SET_1);
+ break;
+#if LWGSM_CFG_NETWORK_IGNORE_CGACT_RESULT
+ case 2:
+ SET_NEW_CMD(LWGSM_CMD_CGATT_SET_0);
+ break;
+#else /* LWGSM_CFG_NETWORK_IGNORE_CGACT_RESULT */
+ case 2:
+ SET_NEW_CMD_CHECK_ERROR(LWGSM_CMD_CGATT_SET_0);
+ break;
+#endif /* !LWGSM_CFG_NETWORK_IGNORE_CGACT_RESULT */
+ case 3:
+ SET_NEW_CMD(LWGSM_CMD_CGATT_SET_1);
+ break;
+ case 4:
+ SET_NEW_CMD_CHECK_ERROR(LWGSM_CMD_CIPSHUT);
+ break;
+ case 5:
+ SET_NEW_CMD_CHECK_ERROR(LWGSM_CMD_CIPMUX_SET);
+ break;
+ case 6:
+ SET_NEW_CMD_CHECK_ERROR(LWGSM_CMD_CIPRXGET_SET);
+ break;
+ case 7:
+ SET_NEW_CMD_CHECK_ERROR(LWGSM_CMD_CSTT_SET);
+ break;
+ case 8:
+ SET_NEW_CMD_CHECK_ERROR(LWGSM_CMD_CIICR);
+ break;
+ case 9:
+ SET_NEW_CMD_CHECK_ERROR(LWGSM_CMD_CIFSR);
+ break;
+ case 10:
+ SET_NEW_CMD(LWGSM_CMD_CIPSTATUS);
+ break;
+ default:
+ break;
+ }
+ } else if (CMD_IS_DEF(LWGSM_CMD_NETWORK_DETACH)) {
+ switch (msg->i) {
+ case 0:
+ SET_NEW_CMD(LWGSM_CMD_CGATT_SET_0);
+ break;
+ case 1:
+ SET_NEW_CMD(LWGSM_CMD_CGACT_SET_0);
+ break;
+#if LWGSM_CFG_CONN
+ case 2:
+ SET_NEW_CMD(LWGSM_CMD_CIPSTATUS);
+ break;
+#endif /* LWGSM_CFG_CONN */
+ default:
+ break;
+ }
+ if (!n_cmd) {
+ *is_ok = 1;
+ }
+#endif /* LWGSM_CFG_NETWORK */
+#if LWGSM_CFG_CONN
+ } else if (CMD_IS_DEF(LWGSM_CMD_CIPSTART)) {
+ if (!msg->i && CMD_IS_CUR(LWGSM_CMD_CIPSTATUS)) { /* Was the current command status info? */
+ if (*is_ok) {
+ SET_NEW_CMD(LWGSM_CMD_CIPSSL); /* Set SSL */
+ }
+ } else if (msg->i == 1 && CMD_IS_CUR(LWGSM_CMD_CIPSSL)) {
+ SET_NEW_CMD(LWGSM_CMD_CIPSTART); /* Now actually start connection */
+ } else if (msg->i == 2 && CMD_IS_CUR(LWGSM_CMD_CIPSTART)) {
+ SET_NEW_CMD(LWGSM_CMD_CIPSTATUS); /* Go to status mode */
+ if (*is_error) {
+ msg->msg.conn_start.conn_res = LWGSM_CONN_CONNECT_ERROR;
+ }
+ } else if (msg->i == 3 && CMD_IS_CUR(LWGSM_CMD_CIPSTATUS)) {
+ /* After second CIP status, define what to do next */
+ switch (msg->msg.conn_start.conn_res) {
+ case LWGSM_CONN_CONNECT_OK: { /* Successfully connected */
+ lwgsm_conn_t* conn = &lwgsm.m.conns[msg->msg.conn_start.num]; /* Get connection number */
+
+ lwgsm.evt.type = LWGSM_EVT_CONN_ACTIVE; /* Connection just active */
+ lwgsm.evt.evt.conn_active_close.client = 1;
+ lwgsm.evt.evt.conn_active_close.conn = conn;
+ lwgsm.evt.evt.conn_active_close.forced = 1;
+ lwgsmi_send_conn_cb(conn, NULL);
+ lwgsmi_conn_start_timeout(conn);/* Start connection timeout timer */
+ break;
+ }
+ case LWGSM_CONN_CONNECT_ERROR: {/* Connection error */
+ lwgsmi_send_conn_error_cb(msg, lwgsmERRCONNFAIL);
+ *is_error = 1; /* Manually set error */
+ *is_ok = 0; /* Reset success */
+ break;
+ }
+ default: {
+ /* Do nothing as of now */
+ break;
+ }
+ }
+ }
+ } else if (CMD_IS_DEF(LWGSM_CMD_CIPCLOSE)) {
+ /*
+ * It is unclear in which state connection is when ERROR is received on close command.
+ * Stack checks if connection is closed before it allows and sends close command,
+ * however it was detected that no automatic close event has been received from device
+ * and AT+CIPCLOSE returned ERROR.
+ *
+ * Is it device firmware bug?
+ */
+ if (CMD_IS_CUR(LWGSM_CMD_CIPCLOSE) && *is_error) {
+ /* Notify upper layer about failed close event */
+ lwgsm.evt.type = LWGSM_EVT_CONN_CLOSE;
+ lwgsm.evt.evt.conn_active_close.conn = msg->msg.conn_close.conn;
+ lwgsm.evt.evt.conn_active_close.forced = 1;
+ lwgsm.evt.evt.conn_active_close.res = lwgsmERR;
+ lwgsm.evt.evt.conn_active_close.client = msg->msg.conn_close.conn->status.f.active && msg->msg.conn_close.conn->status.f.client;
+ lwgsmi_send_conn_cb(msg->msg.conn_close.conn, NULL);
+ }
+#endif /* LWGSM_CFG_CONN */
+#if LWGSM_CFG_USSD
+ } else if (CMD_IS_DEF(LWGSM_CMD_CUSD)) {
+ if (CMD_IS_CUR(LWGSM_CMD_CUSD_GET)) {
+ if (*is_ok) {
+ SET_NEW_CMD(LWGSM_CMD_CUSD); /* Run next command */
+ }
+ }
+ /* The rest is handled in one layer above */
+#endif /* LWGSM_CFG_USSD */
+ }
+
+ /* Check if new command was set for execution */
+ if (n_cmd != LWGSM_CMD_IDLE) {
+ lwgsmr_t res;
+ msg->cmd = n_cmd;
+ if ((res = msg->fn(msg)) == lwgsmOK) {
+ return lwgsmCONT;
+ } else {
+ *is_ok = 0;
+ *is_error = 1;
+ return res;
+ }
+ } else {
+ msg->cmd = LWGSM_CMD_IDLE;
+ }
+ return *is_ok ? lwgsmOK : lwgsmERR;
+}
+
+/**
+ * \brief Function to initialize every AT command
+ * \note Never call this function directly. Set as initialization function for command and use `msg->fn(msg)`
+ * \param[in] msg: Pointer to \ref lwgsm_msg_t with data
+ * \return Member of \ref lwgsmr_t enumeration
+ */
+lwgsmr_t
+lwgsmi_initiate_cmd(lwgsm_msg_t* msg) {
+ switch (CMD_GET_CUR()) { /* Check current message we want to send over AT */
+ case LWGSM_CMD_RESET: { /* Reset modem with AT commands */
+ /* Try with hardware reset */
+ if (lwgsm.ll.reset_fn != NULL && lwgsm.ll.reset_fn(1)) {
+ lwgsm_delay(2);
+ lwgsm.ll.reset_fn(0);
+ lwgsm_delay(500);
+ }
+
+ /* Send manual AT command */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CFUN=1,1");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_RESET_DEVICE_FIRST_CMD: {/* First command for device driver specific reset */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_ATE0:
+ case LWGSM_CMD_ATE1: {
+ AT_PORT_SEND_BEGIN_AT();
+ if (CMD_IS_CUR(LWGSM_CMD_ATE0)) {
+ AT_PORT_SEND_CONST_STR("E0");
+ } else {
+ AT_PORT_SEND_CONST_STR("E1");
+ }
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CMEE_SET: { /* Enable detailed error messages */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CMEE=1");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CLCC_SET: { /* Enable detailed call info */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CLCC=1");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CGMI_GET: { /* Get manufacturer */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CGMI");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CGMM_GET: { /* Get model */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CGMM");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CGSN_GET: { /* Get serial number */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CGSN");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CGMR_GET: { /* Get revision */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CGMR");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CREG_SET: { /* Enable +CREG message */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CREG=1");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CREG_GET: { /* Get network registration status */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CREG?");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CFUN_SET: {
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CFUN=");
+ /**
+ * \todo: If CFUN command forced, check value
+ */
+ if (CMD_IS_DEF(LWGSM_CMD_RESET)
+ || (CMD_IS_DEF(LWGSM_CMD_CFUN_SET) && msg->msg.cfun.mode)) {
+ AT_PORT_SEND_CONST_STR("1");
+ } else {
+ AT_PORT_SEND_CONST_STR("0");
+ }
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CPIN_GET: { /* Read current SIM status */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CPIN?");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CPIN_SET: { /* Set SIM pin code */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CPIN=");
+ lwgsmi_send_string(msg->msg.cpin_enter.pin, 0, 1, 0);
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CPIN_ADD: { /* Add new pin code */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CLCK=\"SC\",1,");
+ lwgsmi_send_string(msg->msg.cpin_add.pin, 0, 1, 0);
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CPIN_CHANGE: { /* Change already active SIM */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CPWD=\"SC\"");
+ lwgsmi_send_string(msg->msg.cpin_change.current_pin, 0, 1, 1);
+ lwgsmi_send_string(msg->msg.cpin_change.new_pin, 0, 1, 1);
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CPIN_REMOVE: { /* Remove current PIN */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CLCK=\"SC\",0,");
+ lwgsmi_send_string(msg->msg.cpin_remove.pin, 0, 1, 0);
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CPUK_SET: { /* Enter PUK and set new PIN */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CPIN=");
+ lwgsmi_send_string(msg->msg.cpuk_enter.puk, 0, 1, 0);
+ lwgsmi_send_string(msg->msg.cpuk_enter.pin, 0, 1, 1);
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_COPS_SET: { /* Set current operator */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+COPS=");
+ lwgsmi_send_number(LWGSM_U32(msg->msg.cops_set.mode), 0, 0);
+ if (msg->msg.cops_set.mode != LWGSM_OPERATOR_MODE_AUTO) {
+ lwgsmi_send_number(LWGSM_U32(msg->msg.cops_set.format), 0, 1);
+ switch (msg->msg.cops_set.format) {
+ case LWGSM_OPERATOR_FORMAT_LONG_NAME:
+ case LWGSM_OPERATOR_FORMAT_SHORT_NAME:
+ lwgsmi_send_string(msg->msg.cops_set.name, 1, 1, 1);
+ break;
+ default:
+ lwgsmi_send_number(LWGSM_U32(msg->msg.cops_set.num), 0, 1);
+ }
+ }
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_COPS_GET: { /* Get current operator */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+COPS?");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_COPS_GET_OPT: { /* Get list of available operators */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+COPS=?");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CSQ_GET: { /* Get signal strength */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CSQ");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CNUM: { /* Get SIM number */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CNUM");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CIPSHUT: { /* Shut down network connection and put to reset state */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CIPSHUT");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+#if LWGSM_CFG_CONN
+ case LWGSM_CMD_CIPMUX: { /* Enable multiple connections */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CIPMUX=1");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CIPHEAD: { /* Enable information on receive data about connection and length */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CIPHEAD=1");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CIPSRIP: {
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CIPSRIP=1");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CIPSSL: { /* Set SSL configuration */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CIPSSL=");
+ lwgsmi_send_number((msg->msg.conn_start.type == LWGSM_CONN_TYPE_SSL) ? 1 : 0, 0, 0);
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CIPSTART: { /* Start a new connection */
+ lwgsm_conn_t* c = NULL;
+
+ /* Do we have network connection? */
+ /* Check if we are connected to network */
+
+ msg->msg.conn_start.num = 0; /* Start with max value = invalidated */
+ for (int16_t i = LWGSM_CFG_MAX_CONNS - 1; i >= 0; --i) {/* Find available connection */
+ if (!lwgsm.m.conns[i].status.f.active) {
+ c = &lwgsm.m.conns[i];
+ c->num = LWGSM_U8(i);
+ msg->msg.conn_start.num = LWGSM_U8(i); /* Set connection number for message structure */
+ break;
+ }
+ }
+ if (c == NULL) {
+ lwgsmi_send_conn_error_cb(msg, lwgsmERRNOFREECONN);
+ return lwgsmERRNOFREECONN; /* We don't have available connection */
+ }
+
+ if (msg->msg.conn_start.conn != NULL) { /* Is user interested about connection info? */
+ *msg->msg.conn_start.conn = c; /* Save connection for user */
+ }
+
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CIPSTART=");
+ lwgsmi_send_number(LWGSM_U32(c->num), 0, 0);
+ if (msg->msg.conn_start.type == LWGSM_CONN_TYPE_TCP) {
+ lwgsmi_send_string("TCP", 0, 1, 1);
+ } else if (msg->msg.conn_start.type == LWGSM_CONN_TYPE_UDP) {
+ lwgsmi_send_string("UDP", 0, 1, 1);
+ }
+ lwgsmi_send_string(msg->msg.conn_start.host, 0, 1, 1);
+ lwgsmi_send_port(msg->msg.conn_start.port, 0, 1);
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CIPCLOSE: { /* Close the connection */
+ lwgsm_conn_p c = msg->msg.conn_close.conn;
+ if (c != NULL &&
+ /* Is connection already closed or command for this connection is not valid anymore? */
+ (!lwgsm_conn_is_active(c) || c->val_id != msg->msg.conn_close.val_id)) {
+ return lwgsmERR;
+ }
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CIPCLOSE=");
+ lwgsmi_send_number(LWGSM_U32(msg->msg.conn_close.conn ? msg->msg.conn_close.conn->num : LWGSM_CFG_MAX_CONNS), 0, 0);
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CIPSEND: { /* Send data to connection */
+ return lwgsmi_tcpip_process_send_data();/* Process send data */
+ }
+ case LWGSM_CMD_CIPSTATUS: { /* Get status of device and all connections */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CIPSTATUS");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+#endif /* LWGSM_CFG_CONN */
+#if LWGSM_CFG_SMS
+ case LWGSM_CMD_CMGF: { /* Select SMS message format */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CMGF=");
+ if (CMD_IS_DEF(LWGSM_CMD_CMGS)) {
+ lwgsmi_send_number(LWGSM_U32(!!msg->msg.sms_send.format), 0, 0);
+ } else if (CMD_IS_DEF(LWGSM_CMD_CMGR)) {
+ lwgsmi_send_number(LWGSM_U32(!!msg->msg.sms_read.format), 0, 0);
+ } else if (CMD_IS_DEF(LWGSM_CMD_CMGL)) {
+ lwgsmi_send_number(LWGSM_U32(!!msg->msg.sms_list.format), 0, 0);
+ } else {
+ /* Used for all other operations like delete all messages, etc */
+ AT_PORT_SEND_CONST_STR("1");
+ }
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CMGS: { /* Send SMS */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CMGS=");
+ lwgsmi_send_string(msg->msg.sms_send.num, 0, 1, 0);
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CMGR: { /* Read message */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CMGR=");
+ lwgsmi_send_number(LWGSM_U32(msg->msg.sms_read.pos), 0, 0);
+ lwgsmi_send_number(LWGSM_U32(!msg->msg.sms_read.update), 0, 1);
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CMGD: { /* Delete SMS message */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CMGD=");
+ lwgsmi_send_number(LWGSM_U32(msg->msg.sms_delete.pos), 0, 0);
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CMGDA: { /* Mass delete SMS messages */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CMGDA=");
+ switch (msg->msg.sms_delete_all.status) {
+ case LWGSM_SMS_STATUS_READ:
+ lwgsmi_send_string("DEL READ", 0, 1, 0);
+ break;
+ case LWGSM_SMS_STATUS_UNREAD:
+ lwgsmi_send_string("DEL UNREAD", 0, 1, 0);
+ break;
+ case LWGSM_SMS_STATUS_SENT:
+ lwgsmi_send_string("DEL SENT", 0, 1, 0);
+ break;
+ case LWGSM_SMS_STATUS_UNSENT:
+ lwgsmi_send_string("DEL UNSENT", 0, 1, 0);
+ break;
+ case LWGSM_SMS_STATUS_INBOX:
+ lwgsmi_send_string("DEL INBOX", 0, 1, 0);
+ break;
+ case LWGSM_SMS_STATUS_ALL:
+ lwgsmi_send_string("DEL ALL", 0, 1, 0);
+ break;
+ default:
+ break;
+ }
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+
+ case LWGSM_CMD_CMGL: { /* Delete SMS message */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CMGL=");
+ lwgsmi_send_sms_stat(msg->msg.sms_list.status, 1, 0);
+ lwgsmi_send_number(LWGSM_U32(!msg->msg.sms_list.update), 0, 1);
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CPMS_GET_OPT: { /* Get available SMS storages */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CPMS=?");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CPMS_GET: { /* Get current SMS storage info */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CPMS?");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CPMS_SET: { /* Set active SMS storage(s) */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CPMS=");
+ if (CMD_IS_DEF(LWGSM_CMD_CMGR)) { /* Read SMS original command? */
+ lwgsmi_send_dev_memory(msg->msg.sms_read.mem == LWGSM_MEM_CURRENT ? lwgsm.m.sms.mem[0].current : msg->msg.sms_read.mem, 1, 0);
+ } else if (CMD_IS_DEF(LWGSM_CMD_CMGD)) {/* Delete SMS original command? */
+ lwgsmi_send_dev_memory(msg->msg.sms_delete.mem == LWGSM_MEM_CURRENT ? lwgsm.m.sms.mem[0].current : msg->msg.sms_delete.mem, 1, 0);
+ } else if (CMD_IS_DEF(LWGSM_CMD_CMGL)) {/* List SMS original command? */
+ lwgsmi_send_dev_memory(msg->msg.sms_list.mem == LWGSM_MEM_CURRENT ? lwgsm.m.sms.mem[0].current : msg->msg.sms_list.mem, 1, 0);
+ } else if (CMD_IS_DEF(LWGSM_CMD_CPMS_SET)) {/* Do we want to set memory for read/delete,sent/write,receive? */
+ for (size_t i = 0; i < 3; ++i) {/* Write 3 memories */
+ lwgsmi_send_dev_memory(msg->msg.sms_memory.mem[i] == LWGSM_MEM_CURRENT ? lwgsm.m.sms.mem[i].current : msg->msg.sms_memory.mem[i], 1, !!i);
+ }
+ }
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+#endif /* LWGSM_CFG_SMS */
+#if LWGSM_CFG_CALL
+ case LWGSM_CMD_ATD: { /* Start new call */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("D");
+ lwgsmi_send_string(msg->msg.call_start.number, 0, 0, 0);
+ AT_PORT_SEND_CONST_STR(";");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_ATA: { /* Answer phone call */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("A");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_ATH: { /* Disconnect existing connection (hang-up phone call) */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("H");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+#endif /* LWGSM_CFG_CALL */
+#if LWGSM_CFG_PHONEBOOK
+ case LWGSM_CMD_CPBS_GET_OPT: { /* Get available phonebook storages */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CPBS=?");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CPBS_GET: { /* Get current memory info */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CPBS?");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CPBS_SET: { /* Get current memory info */
+ lwgsm_mem_t mem;
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CPBS=");
+ switch (CMD_GET_DEF()) {
+ case LWGSM_CMD_CPBW_SET:
+ mem = msg->msg.pb_write.mem;
+ break;
+ case LWGSM_CMD_CPBR:
+ mem = msg->msg.pb_list.mem;
+ break;
+ case LWGSM_CMD_CPBF:
+ mem = msg->msg.pb_search.mem;
+ break;
+ default:
+ break;
+ }
+ lwgsmi_send_dev_memory(mem == LWGSM_MEM_CURRENT ? lwgsm.m.pb.mem.current : mem, 1, 0);
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CPBW_SET: { /* Write/Delete new/old entry */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CPBW=");
+ if (msg->msg.pb_write.pos > 0) { /* Write number if more than 0 */
+ lwgsmi_send_number(LWGSM_U32(msg->msg.pb_write.pos), 0, 0);
+ }
+ if (!msg->msg.pb_write.del) {
+ lwgsmi_send_string(msg->msg.pb_write.num, 0, 1, 1);
+ lwgsmi_send_number(LWGSM_U32(msg->msg.pb_write.type), 0, 1);
+ lwgsmi_send_string(msg->msg.pb_write.name, 0, 1, 1);
+ }
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CPBR: { /* Read entires */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CPBR=");
+ lwgsmi_send_number(LWGSM_U32(msg->msg.pb_list.start_index), 0, 0);
+ lwgsmi_send_number(LWGSM_U32(msg->msg.pb_list.etr), 0, 1);
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CPBF: { /* Find entires */
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CPBF=");
+ lwgsmi_send_string(msg->msg.pb_search.search, 1, 1, 0);
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+#endif /* LWGSM_CFG_PHONEBOOK */
+#if LWGSM_CFG_NETWORK
+ case LWGSM_CMD_NETWORK_ATTACH:
+ case LWGSM_CMD_CGACT_SET_0: {
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CGACT=0");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CGACT_SET_1: {
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CGACT=1");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_NETWORK_DETACH:
+ case LWGSM_CMD_CGATT_SET_0: {
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CGATT=0");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CGATT_SET_1: {
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CGATT=1");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CIPMUX_SET: {
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CIPMUX=1");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CIPRXGET_SET: {
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CIPRXGET=0");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CSTT_SET: {
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CSTT=");
+ lwgsmi_send_string(msg->msg.network_attach.apn, 1, 1, 0);
+ lwgsmi_send_string(msg->msg.network_attach.user, 1, 1, 1);
+ lwgsmi_send_string(msg->msg.network_attach.pass, 1, 1, 1);
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CIICR: {
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CIICR");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CIFSR: {
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CIFSR");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+#endif /* LWGSM_CFG_NETWORK */
+#if LWGSM_CFG_USSD
+ case LWGSM_CMD_CUSD_GET: {
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CUSD?");
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+ case LWGSM_CMD_CUSD: {
+ AT_PORT_SEND_BEGIN_AT();
+ AT_PORT_SEND_CONST_STR("+CUSD=1,");
+ lwgsmi_send_string(msg->msg.ussd.code, 1, 1, 0);
+ AT_PORT_SEND_END_AT();
+ break;
+ }
+#endif /* LWGSM_CFG_USSD */
+ default:
+ return lwgsmERR; /* Invalid command */
+ }
+ return lwgsmOK; /* Valid command */
+}
+
+/**
+ * \brief Send message from API function to producer queue for further processing
+ * \param[in] msg: New message to process
+ * \param[in] process_fn: callback function used to process message
+ * \param[in] max_block_time: Maximal time command can block in units of milliseconds
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
+ */
+lwgsmr_t
+lwgsmi_send_msg_to_producer_mbox(lwgsm_msg_t* msg, lwgsmr_t (*process_fn)(lwgsm_msg_t*), uint32_t max_block_time) {
+ lwgsmr_t res = msg->res = lwgsmOK;
+
+ /* Check here if stack is even enabled or shall we disable new command entry? */
+ lwgsm_core_lock();
+ /* If locked more than 1 time, means we were called from callback or internally */
+ if (lwgsm.locked_cnt > 1 && msg->is_blocking) {
+ res = lwgsmERRBLOCKING; /* Blocking mode not allowed */
+ }
+ /* Check if device present */
+ if (res == lwgsmOK && !lwgsm.status.f.dev_present) {
+ res = lwgsmERRNODEVICE; /* No device connected */
+ }
+ lwgsm_core_unlock();
+ if (res != lwgsmOK) {
+ LWGSM_MSG_VAR_FREE(msg); /* Free memory and return */
+ return res;
+ }
+
+ if (msg->is_blocking) { /* In case message is blocking */
+ if (!lwgsm_sys_sem_create(&msg->sem, 0)) { /* Create semaphore and lock it immediately */
+ LWGSM_MSG_VAR_FREE(msg); /* Release memory and return */
+ return lwgsmERRMEM;
+ }
+ }
+ if (!msg->cmd) { /* Set start command if not set by user */
+ msg->cmd = msg->cmd_def; /* Set it as default */
+ }
+ msg->block_time = max_block_time; /* Set blocking status if necessary */
+ msg->fn = process_fn; /* Save processing function to be called as callback */
+ if (msg->is_blocking) {
+ lwgsm_sys_mbox_put(&lwgsm.mbox_producer, msg); /* Write message to producer queue and wait forever */
+ } else {
+ if (!lwgsm_sys_mbox_putnow(&lwgsm.mbox_producer, msg)) {/* Write message to producer queue immediately */
+ LWGSM_MSG_VAR_FREE(msg); /* Release message */
+ return lwgsmERRMEM;
+ }
+ }
+ if (res == lwgsmOK && msg->is_blocking) { /* In case we have blocking request */
+ uint32_t time;
+ time = lwgsm_sys_sem_wait(&msg->sem, 0);/* Wait forever for semaphore */
+ if (time == LWGSM_SYS_TIMEOUT) { /* If semaphore was not accessed within given time */
+ res = lwgsmTIMEOUT; /* Semaphore not released in time */
+ } else {
+ res = msg->res; /* Set response status from message response */
+ }
+ LWGSM_MSG_VAR_FREE(msg); /* Release message */
+ }
+ return res;
+}
+
+/**
+ * \brief Process events in case of timeout on command or invalid message (if device is not present)
+ *
+ * Function is called from processing thread:
+ *
+ * - On command timeout error
+ * - If command was sent to queue and before processed, device present status changed
+ *
+ * \param[in] msg: Current message
+ * \param[in] err: Error message to send
+ */
+void
+lwgsmi_process_events_for_timeout_or_error(lwgsm_msg_t* msg, lwgsmr_t err) {
+ switch (msg->cmd_def) {
+ case LWGSM_CMD_RESET: {
+ /* Reset command error */
+ RESET_SEND_EVT(msg, err);
+ break;
+ }
+
+ case LWGSM_CMD_RESTORE: {
+ /* Restore command error */
+ RESTORE_SEND_EVT(msg, err);
+ break;
+ }
+
+ case LWGSM_CMD_COPS_GET_OPT: {
+ /* Operator scan command error */
+ OPERATOR_SCAN_SEND_EVT(msg, err);
+ break;
+ }
+
+#if LWGSM_CFG_CONN
+ case LWGSM_CMD_CIPSTART: {
+ /* Start connection error */
+ lwgsmi_send_conn_error_cb(msg, err);
+ break;
+ }
+
+ case LWGSM_CMD_CIPSEND: {
+ /* Send data error event */
+ CONN_SEND_DATA_SEND_EVT(msg, err);
+ break;
+ }
+#endif /* LWGSM_CFG_CONN */
+
+#if LWGSM_CFG_SMS
+ case LWGSM_CMD_CMGS: {
+ /* Send error event */
+ SMS_SEND_SEND_EVT(msg, err);
+ break;
+ }
+
+ case LWGSM_CMD_CMGR: {
+ /* Read error event */
+ SMS_SEND_READ_EVT(msg, err);
+ break;
+ }
+
+ case LWGSM_CMD_CMGL: {
+ /* List error event */
+ SMS_SEND_LIST_EVT(msg, err);
+ break;
+ }
+
+ case LWGSM_CMD_CMGD: {
+ /* Delete error event */
+ SMS_SEND_DELETE_EVT(msg, err);
+ break;
+ }
+#endif /* LWGSM_CFG_SMS */
+
+ default:
+ break;
+ }
+}
diff --git a/gsm_at_lib/src/gsm/gsm_mem.c b/lwgsm/src/lwgsm/lwgsm_mem.c
similarity index 71%
rename from gsm_at_lib/src/gsm/gsm_mem.c
rename to lwgsm/src/lwgsm/lwgsm_mem.c
index 291af57d..8502dc27 100644
--- a/gsm_at_lib/src/gsm/gsm_mem.c
+++ b/lwgsm/src/lwgsm/lwgsm_mem.c
@@ -1,10 +1,10 @@
/**
- * \file gsm_mem.c
+ * \file lwgsm_mem.c
* \brief Memory manager
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,16 +26,16 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#include "gsm/gsm_private.h"
-#include "gsm/gsm_mem.h"
#include
+#include "lwgsm/lwgsm_private.h"
+#include "lwgsm/lwgsm_mem.h"
-#if !GSM_CFG_MEM_CUSTOM || __DOXYGEN__
+#if !LWGSM_CFG_MEM_CUSTOM || __DOXYGEN__
#if !__DOXYGEN__
typedef struct mem_block {
@@ -47,9 +47,9 @@ typedef struct mem_block {
/**
* \brief Memory alignment bits and absolute number
*/
-#define MEM_ALIGN_BITS GSM_SZ(GSM_CFG_MEM_ALIGNMENT - 1)
-#define MEM_ALIGN_NUM GSM_SZ(GSM_CFG_MEM_ALIGNMENT)
-#define MEM_ALIGN(x) GSM_MEM_ALIGN(x)
+#define MEM_ALIGN_BITS LWGSM_SZ(LWGSM_CFG_MEM_ALIGNMENT - 1)
+#define MEM_ALIGN_NUM LWGSM_SZ(LWGSM_CFG_MEM_ALIGNMENT)
+#define MEM_ALIGN(x) LWGSM_MEM_ALIGN(x)
#define MEMBLOCK_METASIZE MEM_ALIGN(sizeof(mem_block_t))
@@ -73,19 +73,24 @@ mem_insertfreeblock(mem_block_t* nb) {
/* Find block position to insert new block between */
for (ptr = &start_block; ptr != NULL && ptr->next < nb; ptr = ptr->next) {}
+ /* Check hard error on wrongly used memory */
+ if (ptr == NULL) {
+ return;
+ }
+
/*
* If the new inserted block and block before create a one big block (contiguous)
* then try to merge them together
*/
- addr = (void *)ptr;
- if ((uint8_t *)(addr + ptr->size) == (uint8_t *)nb) {
+ addr = (void*)ptr;
+ if ((uint8_t*)(addr + ptr->size) == (uint8_t*)nb) {
ptr->size += nb->size; /* Expand size of block before new inserted */
nb = ptr; /* Set new block pointer to block before (expanded block) */
}
/* Check if new block and its size is the same address as next free block newBlock points to */
- addr = (void *)nb;
- if ((uint8_t *)(addr + nb->size) == (uint8_t *)ptr->next) {
+ addr = (void*)nb;
+ if ((uint8_t*)(addr + nb->size) == (uint8_t*)ptr->next) {
if (ptr->next == end_block) { /* Does it points to the end? */
nb->next = end_block; /* Set end block pointer */
} else {
@@ -114,39 +119,38 @@ mem_insertfreeblock(mem_block_t* nb) {
* \param[in] len: Number of regions to assign
*/
static uint8_t
-mem_assignmem(const gsm_mem_region_t* regions, size_t len) {
+mem_assignmem(const lwgsm_mem_region_t* regions, size_t len) {
uint8_t* mem_start_addr;
size_t mem_size;
- mem_block_t *first_block, *prev_end_block = NULL;
+ mem_block_t* first_block, *prev_end_block = NULL;
if (end_block != NULL) { /* Regions already defined */
return 0;
}
/* Check if region address are linear and rising */
- mem_start_addr = (uint8_t *)0;
- for (size_t i = 0; i < len; i++) {
- if (mem_start_addr >= (uint8_t *)regions[i].start_addr) { /* Check if previous greater than current */
+ mem_start_addr = (uint8_t*)0;
+ for (size_t i = 0; i < len; ++i) {
+ if (mem_start_addr >= (uint8_t*)regions[i].start_addr) {/* Check if previous greater than current */
return 0; /* Return as invalid and failed */
}
- mem_start_addr = (uint8_t *)regions[i].start_addr; /* Save as previous address */
+ mem_start_addr = (uint8_t*)regions[i].start_addr; /* Save as previous address */
}
- while (len--) {
+ for (; len > 0; --len, ++regions) {
/* Check minimum region size */
mem_size = regions->size;
if (mem_size < (MEM_ALIGN_NUM + MEMBLOCK_METASIZE)) {
- regions++;
continue;
}
/*
* Get start address and check memory alignment
* if necessary, decrease memory region size
*/
- mem_start_addr = (uint8_t *)regions->start_addr;/* Actual heap memory address */
- if (GSM_SZ(mem_start_addr) & MEM_ALIGN_BITS) { /* Check alignment boundary */
- mem_start_addr += MEM_ALIGN_NUM - (GSM_SZ(mem_start_addr) & MEM_ALIGN_BITS);
- mem_size -= mem_start_addr - (uint8_t *)regions->start_addr;
+ mem_start_addr = (uint8_t*)regions->start_addr; /* Actual heap memory address */
+ if (LWGSM_SZ(mem_start_addr) & MEM_ALIGN_BITS) {/* Check alignment boundary */
+ mem_start_addr += MEM_ALIGN_NUM - (LWGSM_SZ(mem_start_addr) & MEM_ALIGN_BITS);
+ mem_size -= mem_start_addr - (uint8_t*)regions->start_addr;
}
/* Check memory size alignment if match */
@@ -162,7 +166,7 @@ mem_assignmem(const gsm_mem_region_t* regions, size_t len) {
* Set Start block only if end block is not yet defined = first run
*/
if (end_block == NULL) {
- start_block.next = (mem_block_t *)mem_start_addr;
+ start_block.next = (mem_block_t*)mem_start_addr;
start_block.size = 0;
}
@@ -172,7 +176,7 @@ mem_assignmem(const gsm_mem_region_t* regions, size_t len) {
* Set pointer to end of free memory - block region memory
* Calculate new end block in region
*/
- end_block = (mem_block_t *)((uint8_t *)mem_start_addr + mem_size - MEMBLOCK_METASIZE);
+ end_block = (mem_block_t*)((uint8_t*)mem_start_addr + mem_size - MEMBLOCK_METASIZE);
end_block->next = NULL; /* No more free blocks after end is reached */
end_block->size = 0; /* Empty block */
@@ -180,8 +184,8 @@ mem_assignmem(const gsm_mem_region_t* regions, size_t len) {
* Initialize start of region memory
* Create first block in region
*/
- first_block = (mem_block_t *)mem_start_addr;
- first_block->size = mem_size - MEMBLOCK_METASIZE; /* Exclude end block in chain */
+ first_block = (mem_block_t*)mem_start_addr;
+ first_block->size = mem_size - MEMBLOCK_METASIZE; /* Exclude end block in chain */
first_block->next = end_block; /* Last block is next free in chain */
/*
@@ -196,8 +200,6 @@ mem_assignmem(const gsm_mem_region_t* regions, size_t len) {
/* Set number of free bytes available to allocate in region */
mem_available_bytes += first_block->size;
-
- regions++; /* Go to next region */
}
return 1; /* Regions set as expected */
@@ -208,9 +210,9 @@ mem_assignmem(const gsm_mem_region_t* regions, size_t len) {
* \param[in] size: Number of bytes to allocate
* \return Memory address on success, `NULL` otherwise
*/
-static void *
+static void*
mem_alloc(size_t size) {
- mem_block_t *prev, *curr, *next;
+ mem_block_t* prev, *curr, *next;
void* retval = NULL;
if (end_block == NULL) { /* If end block is not yet defined */
@@ -245,16 +247,16 @@ mem_alloc(size_t size) {
* Feature may be very risky later because of fragmentation
*/
if (curr != end_block) { /* We found empty block of enough memory available */
- retval = (void *)((uint8_t *)prev->next + MEMBLOCK_METASIZE); /* Set return value */
- prev->next = curr->next; /* Since block is now allocated, remove it from free chain */
+ retval = (void*)((uint8_t*)prev->next + MEMBLOCK_METASIZE); /* Set return value */
+ prev->next = curr->next; /* Since block is now allocated, remove it from free chain */
/*
* If found free block is much bigger than required,
* then split big block by 2 blocks (one used, second available)
* There should be available memory for at least 2 metadata block size = 8 bytes of useful memory
*/
- if ((curr->size - size) > (2 * MEMBLOCK_METASIZE)) { /* There is more available memory then required = split memory to one free block */
- next = (mem_block_t *)(((uint8_t *)curr) + size); /* Create next memory block which is still free */
+ if ((curr->size - size) > (2 * MEMBLOCK_METASIZE)) {/* There is more available memory then required = split memory to one free block */
+ next = (mem_block_t*)(((uint8_t*)curr) + size); /* Create next memory block which is still free */
next->size = curr->size - size; /* Set new block size for remaining of before and used */
curr->size = size; /* Set block size for used block */
@@ -276,8 +278,8 @@ mem_alloc(size_t size) {
/**
* \brief Free memory
- * \param[in] ptr: Pointer to memory previously returned using \ref gsm_mem_malloc,
- * \ref gsm_mem_calloc or \ref gsm_mem_realloc functions
+ * \param[in] ptr: Pointer to memory previously returned using \ref lwgsm_mem_malloc,
+ * \ref lwgsm_mem_calloc or \ref lwgsm_mem_realloc functions
*/
static void
mem_free(void* ptr) {
@@ -306,16 +308,17 @@ mem_free(void* ptr) {
/**
* \brief Allocate memory of specific size
- * \param[in] size: Number of bytes to allocate
+ * \param[in] num: Number of elements to allocate
+ * \param[in] size: Size of element in units of bytes
* \return Memory address on success, `NULL` otherwise
*/
-static void *
+static void*
mem_calloc(size_t num, size_t size) {
void* ptr;
size_t tot_len = num * size;
if ((ptr = mem_alloc(tot_len)) != NULL) { /* Try to allocate memory */
- GSM_MEMSET(ptr, 0x00, tot_len); /* Reset entire memory */
+ LWGSM_MEMSET(ptr, 0x00, tot_len); /* Reset entire memory */
}
return ptr;
}
@@ -323,12 +326,12 @@ mem_calloc(size_t num, size_t size) {
/**
* \brief Reallocate memory to specific size
* \note After new memory is allocated, content of old one is copied to new memory
- * \param[in] ptr: Pointer to current allocated memory to resize, returned using
- * \ref gsm_mem_malloc, \ref gsm_mem_calloc or \ref gsm_mem_realloc functions
+ * \param[in] ptr: Pointer to current allocated memory to resize, returned using
+ * \ref lwgsm_mem_malloc, \ref lwgsm_mem_calloc or \ref lwgsm_mem_realloc functions
* \param[in] size: Number of bytes to allocate on new memory
* \return Memory address on success, `NULL` otherwise
*/
-static void *
+static void*
mem_realloc(void* ptr, size_t size) {
void* new_ptr;
size_t old_size;
@@ -337,10 +340,10 @@ mem_realloc(void* ptr, size_t size) {
return mem_alloc(size); /* Only allocate memory */
}
- old_size = MEM_BLOCK_USER_SIZE(ptr); /* Get size of old pointer */
+ old_size = MEM_BLOCK_USER_SIZE(ptr); /* Get size of old pointer */
new_ptr = mem_alloc(size); /* Try to allocate new memory block */
if (new_ptr != NULL) {
- GSM_MEMCPY(new_ptr, ptr, GSM_MIN(size, old_size)); /* Copy old data to new array */
+ LWGSM_MEMCPY(new_ptr, ptr, LWGSM_MIN(size, old_size)); /* Copy old data to new array */
mem_free(ptr); /* Free old pointer */
}
return new_ptr;
@@ -350,39 +353,39 @@ mem_realloc(void* ptr, size_t size) {
* \brief Allocate memory of specific size
* \param[in] size: Number of bytes to allocate
* \return Memory address on success, `NULL` otherwise
- * \note Function is not available when \ref GSM_CFG_MEM_CUSTOM is `1` and must be implemented by user
+ * \note Function is not available when \ref LWGSM_CFG_MEM_CUSTOM is `1` and must be implemented by user
*/
-void *
-gsm_mem_malloc(size_t size) {
+void*
+lwgsm_mem_malloc(size_t size) {
void* ptr;
- gsm_core_lock();
+ lwgsm_core_lock();
ptr = mem_calloc(1, size); /* Allocate memory and return pointer */
- gsm_core_unlock();
- GSM_DEBUGW(GSM_CFG_DBG_MEM | GSM_DBG_TYPE_TRACE, ptr == NULL,
- "[MEM] Allocation failed: %d bytes\r\n", (int)size);
- GSM_DEBUGW(GSM_CFG_DBG_MEM | GSM_DBG_TYPE_TRACE, ptr != NULL,
- "[MEM] Allocation OK: %d bytes, addr: %p\r\n", (int)size, ptr);
+ lwgsm_core_unlock();
+ LWGSM_DEBUGW(LWGSM_CFG_DBG_MEM | LWGSM_DBG_TYPE_TRACE, ptr == NULL,
+ "[MEM] Allocation failed: %d bytes\r\n", (int)size);
+ LWGSM_DEBUGW(LWGSM_CFG_DBG_MEM | LWGSM_DBG_TYPE_TRACE, ptr != NULL,
+ "[MEM] Allocation OK: %d bytes, addr: %p\r\n", (int)size, ptr);
return ptr;
}
/**
* \brief Reallocate memory to specific size
* \note After new memory is allocated, content of old one is copied to new memory
- * \param[in] ptr: Pointer to current allocated memory to resize, returned using \ref gsm_mem_malloc,
- * \ref gsm_mem_calloc or \ref gsm_mem_realloc functions
+ * \param[in] ptr: Pointer to current allocated memory to resize, returned using \ref lwgsm_mem_malloc,
+ * \ref lwgsm_mem_calloc or \ref lwgsm_mem_realloc functions
* \param[in] size: Number of bytes to allocate on new memory
* \return Memory address on success, `NULL` otherwise
- * \note Function is not available when \ref GSM_CFG_MEM_CUSTOM is `1` and must be implemented by user
+ * \note Function is not available when \ref LWGSM_CFG_MEM_CUSTOM is `1` and must be implemented by user
*/
-void *
-gsm_mem_realloc(void* ptr, size_t size) {
- gsm_core_lock();
+void*
+lwgsm_mem_realloc(void* ptr, size_t size) {
+ lwgsm_core_lock();
ptr = mem_realloc(ptr, size); /* Reallocate and return pointer */
- gsm_core_unlock();
- GSM_DEBUGW(GSM_CFG_DBG_MEM | GSM_DBG_TYPE_TRACE, ptr == NULL,
- "[MEM] Reallocation failed: %d bytes\r\n", (int)size);
- GSM_DEBUGW(GSM_CFG_DBG_MEM | GSM_DBG_TYPE_TRACE, ptr != NULL,
- "[MEM] Reallocation OK: %d bytes, addr: %p\r\n", (int)size, ptr);
+ lwgsm_core_unlock();
+ LWGSM_DEBUGW(LWGSM_CFG_DBG_MEM | LWGSM_DBG_TYPE_TRACE, ptr == NULL,
+ "[MEM] Reallocation failed: %d bytes\r\n", (int)size);
+ LWGSM_DEBUGW(LWGSM_CFG_DBG_MEM | LWGSM_DBG_TYPE_TRACE, ptr != NULL,
+ "[MEM] Reallocation OK: %d bytes, addr: %p\r\n", (int)size, ptr);
return ptr;
}
@@ -391,38 +394,38 @@ gsm_mem_realloc(void* ptr, size_t size) {
* \param[in] num: Number of elements to allocate
* \param[in] size: Size of each element
* \return Memory address on success, `NULL` otherwise
- * \note Function is not available when \ref GSM_CFG_MEM_CUSTOM is `1` and must be implemented by user
+ * \note Function is not available when \ref LWGSM_CFG_MEM_CUSTOM is `1` and must be implemented by user
*/
-void *
-gsm_mem_calloc(size_t num, size_t size) {
+void*
+lwgsm_mem_calloc(size_t num, size_t size) {
void* ptr;
- gsm_core_lock();
- ptr = mem_calloc(num, size); /* Allocate memory and clear it to 0. Then return pointer */
- gsm_core_unlock();
- GSM_DEBUGW(GSM_CFG_DBG_MEM | GSM_DBG_TYPE_TRACE, ptr == NULL,
- "[MEM] Callocation failed: %d bytes\r\n", (int)size * (int)num);
- GSM_DEBUGW(GSM_CFG_DBG_MEM | GSM_DBG_TYPE_TRACE, ptr != NULL,
- "[MEM] Callocation OK: %d bytes, addr: %p\r\n", (int)size * (int)num, ptr);
+ lwgsm_core_lock();
+ ptr = mem_calloc(num, size); /* Allocate memory and clear it to 0. Then return pointer */
+ lwgsm_core_unlock();
+ LWGSM_DEBUGW(LWGSM_CFG_DBG_MEM | LWGSM_DBG_TYPE_TRACE, ptr == NULL,
+ "[MEM] Callocation failed: %d bytes\r\n", (int)size * (int)num);
+ LWGSM_DEBUGW(LWGSM_CFG_DBG_MEM | LWGSM_DBG_TYPE_TRACE, ptr != NULL,
+ "[MEM] Callocation OK: %d bytes, addr: %p\r\n", (int)size * (int)num, ptr);
return ptr;
}
/**
* \brief Free memory
- * \param[in] ptr: Pointer to memory previously returned using \ref gsm_mem_malloc,
- * \ref gsm_mem_calloc or \ref gsm_mem_realloc functions
- * \note Function is not available when \ref GSM_CFG_MEM_CUSTOM is `1` and must be implemented by user
+ * \param[in] ptr: Pointer to memory previously returned using \ref lwgsm_mem_malloc,
+ * \ref lwgsm_mem_calloc or \ref lwgsm_mem_realloc functions
+ * \note Function is not available when \ref LWGSM_CFG_MEM_CUSTOM is `1` and must be implemented by user
*/
void
-gsm_mem_free(void* ptr) {
+lwgsm_mem_free(void* ptr) {
if (ptr == NULL) {
return;
}
- GSM_DEBUGF(GSM_CFG_DBG_MEM | GSM_DBG_TYPE_TRACE,
- "[MEM] Free size: %d, address: %p\r\n",
- (int)MEM_BLOCK_USER_SIZE(ptr), ptr);
- gsm_core_lock();
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_MEM | LWGSM_DBG_TYPE_TRACE,
+ "[MEM] Free size: %d, address: %p\r\n",
+ (int)MEM_BLOCK_USER_SIZE(ptr), ptr);
+ lwgsm_core_lock();
mem_free(ptr);
- gsm_core_unlock();
+ lwgsm_core_unlock();
}
/**
@@ -431,16 +434,16 @@ gsm_mem_free(void* ptr) {
* \param[in] regions: Pointer to list of regions to use for allocations
* \param[in] len: Number of regions to use
* \return `1` on success, `0` otherwise
- * \note Function is not available when \ref GSM_CFG_MEM_CUSTOM is `1`
+ * \note Function is not available when \ref LWGSM_CFG_MEM_CUSTOM is `1`
*/
uint8_t
-gsm_mem_assignmemory(const gsm_mem_region_t* regions, size_t len) {
+lwgsm_mem_assignmemory(const lwgsm_mem_region_t* regions, size_t len) {
uint8_t ret;
ret = mem_assignmem(regions, len); /* Assign memory */
return ret;
}
-#endif /* !GSM_CFG_MEM_CUSTOM || __DOXYGEN__ */
+#endif /* !LWGSM_CFG_MEM_CUSTOM || __DOXYGEN__ */
/**
* \brief Free memory in safe way by invalidating pointer after freeing
@@ -448,9 +451,9 @@ gsm_mem_assignmemory(const gsm_mem_region_t* regions, size_t len) {
* \return `1` on success, `0` otherwise
*/
uint8_t
-gsm_mem_free_s(void** ptr) {
+lwgsm_mem_free_s(void** ptr) {
if (ptr != NULL && *ptr != NULL) {
- gsm_mem_free(*ptr);
+ lwgsm_mem_free(*ptr);
*ptr = NULL;
return 1;
}
diff --git a/lwgsm/src/lwgsm/lwgsm_network.c b/lwgsm/src/lwgsm/lwgsm_network.c
new file mode 100644
index 00000000..8ef59340
--- /dev/null
+++ b/lwgsm/src/lwgsm/lwgsm_network.c
@@ -0,0 +1,170 @@
+/**
+ * \file lwgsm_network.c
+ * \brief Network API
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM - Lightweight GSM-AT library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+#include "lwgsm/lwgsm_private.h"
+#include "lwgsm/lwgsm_network.h"
+#include "lwgsm/lwgsm_mem.h"
+
+#if LWGSM_CFG_NETWORK || __DOXYGEN__
+
+/**
+ * \brief Attach to network and active PDP context
+ * \param[in] apn: APN name
+ * \param[in] user: User name to attach. Set to `NULL` if not used
+ * \param[in] pass: User password to attach. Set to `NULL` if not used
+ * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
+ * \param[in] evt_arg: Custom argument for event callback function
+ * \param[in] blocking: Status whether command should be blocking or not
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
+ */
+lwgsmr_t
+lwgsm_network_attach(const char* apn, const char* user, const char* pass,
+ const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
+
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_NETWORK_ATTACH;
+#if LWGSM_CFG_CONN
+ LWGSM_MSG_VAR_REF(msg).cmd = LWGSM_CMD_CIPSTATUS;
+#endif /* LWGSM_CFG_CONN */
+ LWGSM_MSG_VAR_REF(msg).msg.network_attach.apn = apn;
+ LWGSM_MSG_VAR_REF(msg).msg.network_attach.user = user;
+ LWGSM_MSG_VAR_REF(msg).msg.network_attach.pass = pass;
+
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 200000);
+}
+
+/**
+ * \brief Detach from network
+ * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
+ * \param[in] evt_arg: Custom argument for event callback function
+ * \param[in] blocking: Status whether command should be blocking or not
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
+ */
+lwgsmr_t
+lwgsm_network_detach(const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
+
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_NETWORK_DETACH;
+#if LWGSM_CFG_CONN
+ /* LWGSM_MSG_VAR_REF(msg).cmd = LWGSM_CMD_CIPSTATUS; */
+#endif /* LWGSM_CFG_CONN */
+
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 60000);
+}
+
+/**
+ * \brief Check network PDP status
+ * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
+ * \param[in] evt_arg: Custom argument for event callback function
+ * \param[in] blocking: Status whether command should be blocking or not
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
+ */
+lwgsmr_t
+lwgsm_network_check_status(const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
+
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_CIPSTATUS;
+
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 60000);
+}
+
+/**
+ * \brief Copy IP address from internal value to user variable
+ * \param[out] ip: Pointer to output IP variable
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
+ */
+lwgsmr_t
+lwgsm_network_copy_ip(lwgsm_ip_t* ip) {
+ if (lwgsm_network_is_attached()) {
+ lwgsm_core_lock();
+ LWGSM_MEMCPY(ip, &lwgsm.m.network.ip_addr, sizeof(*ip));
+ lwgsm_core_unlock();
+ return lwgsmOK;
+ }
+ return lwgsmERR;
+}
+
+/**
+ * \brief Check if device is attached to network and PDP context is active
+ * \return `1` on success, `0` otherwise
+ */
+uint8_t
+lwgsm_network_is_attached(void) {
+ uint8_t res;
+ lwgsm_core_lock();
+ res = LWGSM_U8(lwgsm.m.network.is_attached);
+ lwgsm_core_unlock();
+ return res;
+}
+
+#endif /* LWGSM_CFG_NETWORK || __DOXYGEN__ */
+
+/**
+ * \brief Read RSSI signal from network operator
+ * \param[out] rssi: RSSI output variable. When set to `0`, RSSI is not valid
+ * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
+ * \param[in] evt_arg: Custom argument for event callback function
+ * \param[in] blocking: Status whether command should be blocking or not
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
+ */
+lwgsmr_t
+lwgsm_network_rssi(int16_t* rssi,
+ const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
+
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_CSQ_GET;
+ LWGSM_MSG_VAR_REF(msg).msg.csq.rssi = rssi;
+
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 120000);
+}
+
+/**
+ * \brief Get network registration status
+ * \return Member of \ref lwgsm_network_reg_status_t enumeration
+ */
+lwgsm_network_reg_status_t
+lwgsm_network_get_reg_status(void) {
+ lwgsm_network_reg_status_t ret;
+ lwgsm_core_lock();
+ ret = lwgsm.m.network.status;
+ lwgsm_core_unlock();
+ return ret;
+}
diff --git a/gsm_at_lib/src/gsm/gsm_operator.c b/lwgsm/src/lwgsm/lwgsm_operator.c
similarity index 52%
rename from gsm_at_lib/src/gsm/gsm_operator.c
rename to lwgsm/src/lwgsm/lwgsm_operator.c
index ae0c4424..7e06669a 100644
--- a/gsm_at_lib/src/gsm/gsm_operator.c
+++ b/lwgsm/src/lwgsm/lwgsm_operator.c
@@ -1,10 +1,10 @@
-/**
- * \file gsm_operator.c
+/**
+ * \file lwgsm_operator.c
* \brief Operator API functions
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,14 +26,14 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#include "gsm/gsm_private.h"
-#include "gsm/gsm_operator.h"
-#include "gsm/gsm_mem.h"
+#include "lwgsm/lwgsm_private.h"
+#include "lwgsm/lwgsm_operator.h"
+#include "lwgsm/lwgsm_mem.h"
/**
* \brief Get current operator
@@ -41,54 +41,54 @@
* \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
* \param[in] evt_arg: Custom argument for event callback function
* \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_operator_get(gsm_operator_curr_t* curr,
- const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
+lwgsmr_t
+lwgsm_operator_get(lwgsm_operator_curr_t* curr,
+ const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_COPS_GET;
- GSM_MSG_VAR_REF(msg).msg.cops_get.curr = curr;
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_COPS_GET;
+ LWGSM_MSG_VAR_REF(msg).msg.cops_get.curr = curr;
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 2000);
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 2000);
}
/**
* \brief Set current operator
- * \param[in] mode: Operator mode. This parameter can be a value of \ref gsm_operator_mode_t enumeration
- * \param[in] format: Operator data format. This parameter can be a value of \ref gsm_operator_format_t enumeration
+ * \param[in] mode: Operator mode. This parameter can be a value of \ref lwgsm_operator_mode_t enumeration
+ * \param[in] format: Operator data format. This parameter can be a value of \ref lwgsm_operator_format_t enumeration
* \param[in] name: Operator name. This parameter must be valid according to `format` parameter
* \param[in] num: Operator number. This parameter must be valid according to `format` parameter
* \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
* \param[in] evt_arg: Custom argument for event callback function
* \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_operator_set(gsm_operator_mode_t mode, gsm_operator_format_t format, const char* name, uint32_t num,
- const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
+lwgsmr_t
+lwgsm_operator_set(lwgsm_operator_mode_t mode, lwgsm_operator_format_t format, const char* name, uint32_t num,
+ const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
- if (mode != GSM_OPERATOR_MODE_AUTO) { /* Check parameters only if non-auto mode */
- GSM_ASSERT("format < GSM_OPERATOR_FORMAT_INVALID", format < GSM_OPERATOR_FORMAT_INVALID);
- if (format != GSM_OPERATOR_FORMAT_NUMBER) {
- GSM_ASSERT("name != NULL", name != NULL);
+ if (mode != LWGSM_OPERATOR_MODE_AUTO) { /* Check parameters only if non-auto mode */
+ LWGSM_ASSERT("format < LWGSM_OPERATOR_FORMAT_INVALID", format < LWGSM_OPERATOR_FORMAT_INVALID);
+ if (format != LWGSM_OPERATOR_FORMAT_NUMBER) {
+ LWGSM_ASSERT("name != NULL", name != NULL);
}
}
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_COPS_SET;
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_COPS_SET;
- GSM_MSG_VAR_REF(msg).msg.cops_set.mode = mode;
- GSM_MSG_VAR_REF(msg).msg.cops_set.format = format;
- GSM_MSG_VAR_REF(msg).msg.cops_set.name = name;
- GSM_MSG_VAR_REF(msg).msg.cops_set.num = num;
+ LWGSM_MSG_VAR_REF(msg).msg.cops_set.mode = mode;
+ LWGSM_MSG_VAR_REF(msg).msg.cops_set.format = format;
+ LWGSM_MSG_VAR_REF(msg).msg.cops_set.name = name;
+ LWGSM_MSG_VAR_REF(msg).msg.cops_set.num = num;
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 2000);
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 2000);
}
/**
@@ -99,23 +99,23 @@ gsm_operator_set(gsm_operator_mode_t mode, gsm_operator_format_t format, const c
* \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
* \param[in] evt_arg: Custom argument for event callback function
* \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_operator_scan(gsm_operator_t* ops, size_t opsl, size_t* opf,
- const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
+lwgsmr_t
+lwgsm_operator_scan(lwgsm_operator_t* ops, size_t opsl, size_t* opf,
+ const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
if (opf != NULL) {
*opf = 0;
}
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_COPS_GET_OPT;
- GSM_MSG_VAR_REF(msg).msg.cops_scan.ops = ops;
- GSM_MSG_VAR_REF(msg).msg.cops_scan.opsl = opsl;
- GSM_MSG_VAR_REF(msg).msg.cops_scan.opf = opf;
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_COPS_GET_OPT;
+ LWGSM_MSG_VAR_REF(msg).msg.cops_scan.ops = ops;
+ LWGSM_MSG_VAR_REF(msg).msg.cops_scan.opsl = opsl;
+ LWGSM_MSG_VAR_REF(msg).msg.cops_scan.opf = opf;
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 120000);
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 120000);
}
diff --git a/gsm_at_lib/src/gsm/gsm_parser.c b/lwgsm/src/lwgsm/lwgsm_parser.c
similarity index 54%
rename from gsm_at_lib/src/gsm/gsm_parser.c
rename to lwgsm/src/lwgsm/lwgsm_parser.c
index a2938bae..198153a9 100644
--- a/gsm_at_lib/src/gsm/gsm_parser.c
+++ b/lwgsm/src/lwgsm/lwgsm_parser.c
@@ -1,10 +1,10 @@
/**
- * \file gsm_parser.c
+ * \file lwgsm_parser.c
* \brief Parse incoming data from AT port
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,55 +26,55 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#include "gsm/gsm_private.h"
-#include "gsm/gsm_parser.h"
-#include "gsm/gsm_mem.h"
+#include "lwgsm/lwgsm_private.h"
+#include "lwgsm/lwgsm_parser.h"
+#include "lwgsm/lwgsm_mem.h"
/**
* \brief Parse number from string
* \note Input string pointer is changed and number is skipped
- * \param[in] Pointer to pointer to string to parse
+ * \param[in,out] str: Pointer to pointer to string to parse
* \return Parsed number
*/
int32_t
-gsmi_parse_number(const char** str) {
+lwgsmi_parse_number(const char** str) {
int32_t val = 0;
uint8_t minus = 0;
const char* p = *str; /* */
if (*p == '"') { /* Skip leading quotes */
- p++;
+ ++p;
}
if (*p == ',') { /* Skip leading comma */
- p++;
+ ++p;
}
if (*p == '"') { /* Skip leading quotes */
- p++;
+ ++p;
}
if (*p == '/') { /* Skip '/' character, used in datetime */
- p++;
+ ++p;
}
if (*p == ':') { /* Skip ':' character, used in datetime */
- p++;
+ ++p;
}
if (*p == '+') { /* Skip '+' character, used in datetime */
- p++;
+ ++p;
}
if (*p == '-') { /* Check negative number */
minus = 1;
- p++;
+ ++p;
}
- while (GSM_CHARISNUM(*p)) { /* Parse until character is valid number */
- val = val * 10 + GSM_CHARTONUM(*p);
- p++;
+ while (LWGSM_CHARISNUM(*p)) { /* Parse until character is valid number */
+ val = val * 10 + LWGSM_CHARTONUM(*p);
+ ++p;
}
if (*p == '"') { /* Skip trailling quotes */
- p++;
+ ++p;
}
*str = p; /* Save new pointer with new offset */
@@ -84,29 +84,29 @@ gsmi_parse_number(const char** str) {
/**
* \brief Parse number from string as hex
* \note Input string pointer is changed and number is skipped
- * \param[in] Pointer to pointer to string to parse
+ * \param[in,out] str: Pointer to pointer to string to parse
* \return Parsed number
*/
uint32_t
-gsmi_parse_hexnumber(const char** str) {
+lwgsmi_parse_hexnumber(const char** str) {
int32_t val = 0;
const char* p = *str; /* */
if (*p == '"') { /* Skip leading quotes */
- p++;
+ ++p;
}
if (*p == ',') { /* Skip leading comma */
- p++;
+ ++p;
}
if (*p == '"') { /* Skip leading quotes */
- p++;
+ ++p;
}
- while (GSM_CHARISHEXNUM(*p)) { /* Parse until character is valid number */
- val = val * 16 + GSM_CHARHEXTONUM(*p);
- p++;
+ while (LWGSM_CHARISHEXNUM(*p)) { /* Parse until character is valid number */
+ val = val * 16 + LWGSM_CHARHEXTONUM(*p);
+ ++p;
}
if (*p == ',') { /* Go to next entry if possible */
- p++;
+ ++p;
}
*str = p; /* Save new pointer with new offset */
return val;
@@ -124,34 +124,35 @@ gsmi_parse_hexnumber(const char** str) {
* \return `1` on success, `0` otherwise
*/
uint8_t
-gsmi_parse_string(const char** src, char* dst, size_t dst_len, uint8_t trim) {
+lwgsmi_parse_string(const char** src, char* dst, size_t dst_len, uint8_t trim) {
const char* p = *src;
size_t i;
if (*p == ',') {
- p++;
+ ++p;
}
if (*p == '"') {
- p++;
+ ++p;
}
i = 0;
if (dst_len > 0) {
- dst_len--;
+ --dst_len;
}
while (*p) {
- if (*p == '"' && (p[1] == ',' || p[1] == '\r' || p[1] == '\n')) {
- p++;
+ if ((*p == '"' && (p[1] == ',' || p[1] == '\r' || p[1] == '\n'))
+ || (*p == '\r' || *p == '\n')) {
+ ++p;
break;
}
if (dst != NULL) {
if (i < dst_len) {
*dst++ = *p;
- i++;
+ ++i;
} else if (!trim) {
break;
}
}
- p++;
+ ++p;
}
if (dst != NULL) {
*dst = 0;
@@ -165,37 +166,40 @@ gsmi_parse_string(const char** src, char* dst, size_t dst_len, uint8_t trim) {
* \param[in] src: Pointer to pointer to input string
*/
void
-gsmi_check_and_trim(const char** src) {
+lwgsmi_check_and_trim(const char** src) {
const char* t = *src;
if (*t != '"' && *t != '\r' && *t != ',') { /* Check if trim required */
- gsmi_parse_string(src, NULL, 0, 1); /* Trim to the end */
+ lwgsmi_parse_string(src, NULL, 0, 1); /* Trim to the end */
}
}
/**
* \brief Parse string as IP address
* \param[in,out] src: Pointer to pointer to string to parse from
- * \param[in] dst: Destination pointer
+ * \param[out] ip: Pointer to IP memory
* \return `1 on success, 0 otherwise
*/
uint8_t
-gsmi_parse_ip(const char** src, gsm_ip_t* ip) {
+lwgsmi_parse_ip(const char** src, lwgsm_ip_t* ip) {
const char* p = *src;
if (*p == ',') {
- p++;
+ ++p;
}
if (*p == '"') {
- p++;
+ ++p;
}
- if (GSM_CHARISNUM(*p)) {
- ip->ip[0] = gsmi_parse_number(&p); p++;
- ip->ip[1] = gsmi_parse_number(&p); p++;
- ip->ip[2] = gsmi_parse_number(&p); p++;
- ip->ip[3] = gsmi_parse_number(&p);
+ if (LWGSM_CHARISNUM(*p)) {
+ ip->ip[0] = lwgsmi_parse_number(&p);
+ ++p;
+ ip->ip[1] = lwgsmi_parse_number(&p);
+ ++p;
+ ip->ip[2] = lwgsmi_parse_number(&p);
+ ++p;
+ ip->ip[3] = lwgsmi_parse_number(&p);
}
if (*p == '"') {
- p++;
+ ++p;
}
*src = p; /* Set new pointer */
@@ -205,27 +209,32 @@ gsmi_parse_ip(const char** src, gsm_ip_t* ip) {
/**
* \brief Parse string as MAC address
* \param[in,out] src: Pointer to pointer to string to parse from
- * \param[in] dst: Destination pointer
+ * \param[out] mac: Pointer to MAC memory
* \return 1 on success, 0 otherwise
*/
uint8_t
-gsmi_parse_mac(const char** src, gsm_mac_t* mac) {
+lwgsmi_parse_mac(const char** src, lwgsm_mac_t* mac) {
const char* p = *src;
if (*p == '"') {
- p++;
- }
- mac->mac[0] = gsmi_parse_hexnumber(&p); p++;
- mac->mac[1] = gsmi_parse_hexnumber(&p); p++;
- mac->mac[2] = gsmi_parse_hexnumber(&p); p++;
- mac->mac[3] = gsmi_parse_hexnumber(&p); p++;
- mac->mac[4] = gsmi_parse_hexnumber(&p); p++;
- mac->mac[5] = gsmi_parse_hexnumber(&p);
+ ++p;
+ }
+ mac->mac[0] = lwgsmi_parse_hexnumber(&p);
+ ++p;
+ mac->mac[1] = lwgsmi_parse_hexnumber(&p);
+ ++p;
+ mac->mac[2] = lwgsmi_parse_hexnumber(&p);
+ ++p;
+ mac->mac[3] = lwgsmi_parse_hexnumber(&p);
+ ++p;
+ mac->mac[4] = lwgsmi_parse_hexnumber(&p);
+ ++p;
+ mac->mac[5] = lwgsmi_parse_hexnumber(&p);
if (*p == '"') {
- p++;
+ ++p;
}
if (*p == ',') {
- p++;
+ ++p;
}
*src = p;
return 1;
@@ -236,34 +245,34 @@ gsmi_parse_mac(const char** src, gsm_mac_t* mac) {
* \param[in,out] src: Pointer to pointer to string to parse from
* \return Parsed memory
*/
-gsm_mem_t
-gsmi_parse_memory(const char** src) {
+lwgsm_mem_t
+lwgsmi_parse_memory(const char** src) {
size_t i, sl;
- gsm_mem_t mem = GSM_MEM_UNKNOWN;
+ lwgsm_mem_t mem = LWGSM_MEM_UNKNOWN;
const char* s = *src;
if (*s == ',') {
- s++;
+ ++s;
}
if (*s == '"') {
- s++;
+ ++s;
}
/* Scan all memories available for modem */
- for (i = 0; i < gsm_dev_mem_map_size; i++) {
- sl = strlen(gsm_dev_mem_map[i].mem_str);
- if (!strncmp(s, gsm_dev_mem_map[i].mem_str, sl)) {
- mem = gsm_dev_mem_map[i].mem;
+ for (i = 0; i < lwgsm_dev_mem_map_size; ++i) {
+ sl = strlen(lwgsm_dev_mem_map[i].mem_str);
+ if (!strncmp(s, lwgsm_dev_mem_map[i].mem_str, sl)) {
+ mem = lwgsm_dev_mem_map[i].mem;
s += sl;
break;
}
}
- if (mem == GSM_MEM_UNKNOWN) {
- gsmi_parse_string(&s, NULL, 0, 1); /* Skip string */
+ if (mem == LWGSM_MEM_UNKNOWN) {
+ lwgsmi_parse_string(&s, NULL, 0, 1); /* Skip string */
}
if (*s == '"') {
- s++;
+ ++s;
}
*src = s;
return mem;
@@ -277,23 +286,23 @@ gsmi_parse_memory(const char** src) {
* \return 1 on success, 0 otherwise
*/
uint8_t
-gsmi_parse_memories_string(const char** src, uint32_t* mem_dst) {
+lwgsmi_parse_memories_string(const char** src, uint32_t* mem_dst) {
const char* str = *src;
- gsm_mem_t mem;
+ lwgsm_mem_t mem;
*mem_dst = 0;
if (*str == ',') {
- str++;
+ ++str;
}
if (*str == '(') {
- str++;
+ ++str;
}
do {
- mem = gsmi_parse_memory(&str); /* Parse memory string */
- *mem_dst |= GSM_U32(1 << GSM_U32(mem)); /* Set as bit field */
+ mem = lwgsmi_parse_memory(&str); /* Parse memory string */
+ *mem_dst |= LWGSM_U32(1 << LWGSM_U32(mem)); /* Set as bit field */
} while (*str && *str != ')');
if (*str == ')') {
- str++;
+ ++str;
}
*src = str;
return 1;
@@ -301,37 +310,38 @@ gsmi_parse_memories_string(const char** src, uint32_t* mem_dst) {
/**
* \brief Parse received +CREG message
- * \param[in] str: Input string
+ * \param[in] str: Input string to parse from
+ * \param[in] skip_first: Set to `1` to skip first number
* \return 1 on success, 0 otherwise
*/
uint8_t
-gsmi_parse_creg(const char* str, uint8_t skip_first) {
+lwgsmi_parse_creg(const char* str, uint8_t skip_first) {
if (*str == '+') {
str += 7;
}
if (skip_first) {
- gsmi_parse_number(&str);
+ lwgsmi_parse_number(&str);
}
- gsm.m.network.status = (gsm_network_reg_status_t)gsmi_parse_number(&str);
+ lwgsm.m.network.status = (lwgsm_network_reg_status_t)lwgsmi_parse_number(&str);
/*
* In case we are connected to network,
* scan for current network info
*/
- if (gsm.m.network.status == GSM_NETWORK_REG_STATUS_CONNECTED ||
- gsm.m.network.status == GSM_NETWORK_REG_STATUS_CONNECTED_ROAMING) {
+ if (lwgsm.m.network.status == LWGSM_NETWORK_REG_STATUS_CONNECTED ||
+ lwgsm.m.network.status == LWGSM_NETWORK_REG_STATUS_CONNECTED_ROAMING) {
/* Try to get operator */
/* Notify user in case we are not able to add new command to queue */
- gsm_operator_get(&gsm.m.network.curr_operator, NULL, NULL, 0);
-#if GSM_CFG_NETWORK
- } else if (gsm_network_is_attached()) {
- gsm_network_check_status(NULL, NULL, 0); /* Do the update */
-#endif /* GSM_CFG_NETWORK */
+ lwgsm_operator_get(&lwgsm.m.network.curr_operator, NULL, NULL, 0);
+#if LWGSM_CFG_NETWORK
+ } else if (lwgsm_network_is_attached()) {
+ lwgsm_network_check_status(NULL, NULL, 0); /* Do the update */
+#endif /* LWGSM_CFG_NETWORK */
}
/* Send callback event */
- gsmi_send_cb(GSM_EVT_NETWORK_REG_CHANGED);
+ lwgsmi_send_cb(LWGSM_EVT_NETWORK_REG_CHANGED);
return 1;
}
@@ -342,27 +352,27 @@ gsmi_parse_creg(const char* str, uint8_t skip_first) {
* \return 1 on success, 0 otherwise
*/
uint8_t
-gsmi_parse_csq(const char* str) {
+lwgsmi_parse_csq(const char* str) {
int16_t rssi;
if (*str == '+') {
str += 6;
}
- rssi = gsmi_parse_number(&str);
+ rssi = lwgsmi_parse_number(&str);
if (rssi < 32) {
rssi = -(113 - (rssi * 2));
} else {
rssi = 0;
}
- gsm.m.rssi = rssi; /* Save RSSI to global variable */
- if (gsm.msg->cmd_def == GSM_CMD_CSQ_GET &&
- gsm.msg->msg.csq.rssi != NULL) {
- *gsm.msg->msg.csq.rssi = rssi; /* Save to user variable */
+ lwgsm.m.rssi = rssi; /* Save RSSI to global variable */
+ if (lwgsm.msg->cmd_def == LWGSM_CMD_CSQ_GET &&
+ lwgsm.msg->msg.csq.rssi != NULL) {
+ *lwgsm.msg->msg.csq.rssi = rssi; /* Save to user variable */
}
/* Report CSQ status */
- gsm.evt.evt.rssi.rssi = rssi;
- gsmi_send_cb(GSM_EVT_SIGNAL_STRENGTH); /* RSSI event type */
+ lwgsm.evt.evt.rssi.rssi = rssi;
+ lwgsmi_send_cb(LWGSM_EVT_SIGNAL_STRENGTH); /* RSSI event type */
return 1;
}
@@ -374,39 +384,39 @@ gsmi_parse_csq(const char* str) {
* \return 1 on success, 0 otherwise
*/
uint8_t
-gsmi_parse_cpin(const char* str, uint8_t send_evt) {
- gsm_sim_state_t state;
+lwgsmi_parse_cpin(const char* str, uint8_t send_evt) {
+ lwgsm_sim_state_t state;
if (*str == '+') {
str += 7;
}
if (!strncmp(str, "READY", 5)) {
- state = GSM_SIM_STATE_READY;
+ state = LWGSM_SIM_STATE_READY;
} else if (!strncmp(str, "NOT READY", 9)) {
- state = GSM_SIM_STATE_NOT_READY;
+ state = LWGSM_SIM_STATE_NOT_READY;
} else if (!strncmp(str, "NOT INSERTED", 14)) {
- state = GSM_SIM_STATE_NOT_INSERTED;
+ state = LWGSM_SIM_STATE_NOT_INSERTED;
} else if (!strncmp(str, "SIM PIN", 7)) {
- state = GSM_SIM_STATE_PIN;
+ state = LWGSM_SIM_STATE_PIN;
} else if (!strncmp(str, "SIM PUK", 7)) {
- state = GSM_SIM_STATE_PUK;
+ state = LWGSM_SIM_STATE_PUK;
} else {
- state = GSM_SIM_STATE_NOT_READY;
+ state = LWGSM_SIM_STATE_NOT_READY;
}
/* React only on change */
- if (state != gsm.m.sim.state) {
- gsm.m.sim.state = state;
+ if (state != lwgsm.m.sim.state) {
+ lwgsm.m.sim.state = state;
/*
* In case SIM is ready,
* start with basic info about SIM
*/
- if (gsm.m.sim.state == GSM_SIM_STATE_READY) {
- gsmi_get_sim_info(0);
+ if (lwgsm.m.sim.state == LWGSM_SIM_STATE_READY) {
+ lwgsmi_get_sim_info(0);
}
if (send_evt) {
- gsm.evt.evt.cpin.state = gsm.m.sim.state;
- gsmi_send_cb(GSM_EVT_SIM_STATE_CHANGED);
+ lwgsm.evt.evt.cpin.state = lwgsm.m.sim.state;
+ lwgsmi_send_cb(LWGSM_EVT_SIM_STATE_CHANGED);
}
}
return 1;
@@ -418,35 +428,36 @@ gsmi_parse_cpin(const char* str, uint8_t send_evt) {
* \return 1 on success, 0 otherwise
*/
uint8_t
-gsmi_parse_cops(const char* str) {
+lwgsmi_parse_cops(const char* str) {
if (*str == '+') {
str += 7;
}
- gsm.m.network.curr_operator.mode = (gsm_operator_mode_t)gsmi_parse_number(&str);
+ lwgsm.m.network.curr_operator.mode = (lwgsm_operator_mode_t)lwgsmi_parse_number(&str);
if (*str != '\r') {
- gsm.m.network.curr_operator.format = (gsm_operator_format_t)gsmi_parse_number(&str);
+ lwgsm.m.network.curr_operator.format = (lwgsm_operator_format_t)lwgsmi_parse_number(&str);
if (*str != '\r') {
- switch (gsm.m.network.curr_operator.format) {
- case GSM_OPERATOR_FORMAT_LONG_NAME:
- gsmi_parse_string(&str, gsm.m.network.curr_operator.data.long_name, sizeof(gsm.m.network.curr_operator.data.long_name), 1);
+ switch (lwgsm.m.network.curr_operator.format) {
+ case LWGSM_OPERATOR_FORMAT_LONG_NAME:
+ lwgsmi_parse_string(&str, lwgsm.m.network.curr_operator.data.long_name, sizeof(lwgsm.m.network.curr_operator.data.long_name), 1);
+ break;
+ case LWGSM_OPERATOR_FORMAT_SHORT_NAME:
+ lwgsmi_parse_string(&str, lwgsm.m.network.curr_operator.data.short_name, sizeof(lwgsm.m.network.curr_operator.data.short_name), 1);
break;
- case GSM_OPERATOR_FORMAT_SHORT_NAME:
- gsmi_parse_string(&str, gsm.m.network.curr_operator.data.short_name, sizeof(gsm.m.network.curr_operator.data.short_name), 1);
+ case LWGSM_OPERATOR_FORMAT_NUMBER:
+ lwgsm.m.network.curr_operator.data.num = LWGSM_U32(lwgsmi_parse_number(&str));
break;
- case GSM_OPERATOR_FORMAT_NUMBER:
- gsm.m.network.curr_operator.data.num = GSM_U32(gsmi_parse_number(&str));
+ default:
break;
- default: break;
}
}
} else {
- gsm.m.network.curr_operator.format = GSM_OPERATOR_FORMAT_INVALID;
+ lwgsm.m.network.curr_operator.format = LWGSM_OPERATOR_FORMAT_INVALID;
}
- if (CMD_IS_DEF(GSM_CMD_COPS_GET) &&
- gsm.msg->msg.cops_get.curr != NULL) { /* Check and copy to user variable */
- GSM_MEMCPY(gsm.msg->msg.cops_get.curr, &gsm.m.network.curr_operator, sizeof(*gsm.msg->msg.cops_get.curr));
+ if (CMD_IS_DEF(LWGSM_CMD_COPS_GET) &&
+ lwgsm.msg->msg.cops_get.curr != NULL) { /* Check and copy to user variable */
+ LWGSM_MEMCPY(lwgsm.msg->msg.cops_get.curr, &lwgsm.m.network.curr_operator, sizeof(*lwgsm.msg->msg.cops_get.curr));
}
return 1;
}
@@ -459,19 +470,19 @@ gsmi_parse_cops(const char* str) {
* \return 1 on success, 0 otherwise
*/
uint8_t
-gsmi_parse_cops_scan(uint8_t ch, uint8_t reset) {
+lwgsmi_parse_cops_scan(uint8_t ch, uint8_t reset) {
static union {
struct {
- uint8_t bo:1; /*!< Bracket open flag (Bracket Open) */
- uint8_t ccd:1; /*!< 2 consecutive commas detected in a row (Comma Comma Detected) */
- uint8_t tn:2; /*!< Term number in response, 2 bits for 4 diff values */
+ uint8_t bo: 1; /*!< Bracket open flag (Bracket Open) */
+ uint8_t ccd: 1; /*!< 2 consecutive commas detected in a row (Comma Comma Detected) */
+ uint8_t tn: 2; /*!< Term number in response, 2 bits for 4 diff values */
uint8_t tp; /*!< Current term character position */
uint8_t ch_prev; /*!< Previous character */
} f;
} u;
if (reset) { /* Check for reset status */
- GSM_MEMSET(&u, 0x00, sizeof(u)); /* Reset everything */
+ LWGSM_MEMSET(&u, 0x00, sizeof(u)); /* Reset everything */
u.f.ch_prev = 0;
return 1;
}
@@ -485,7 +496,7 @@ gsmi_parse_cops_scan(uint8_t ch, uint8_t reset) {
}
if (u.f.ccd || /* Ignore data after 2 commas in a row */
- gsm.msg->msg.cops_scan.opsi >= gsm.msg->msg.cops_scan.opsl) { /* or if array is full */
+ lwgsm.msg->msg.cops_scan.opsi >= lwgsm.msg->msg.cops_scan.opsl) { /* or if array is full */
return 1;
}
@@ -494,39 +505,40 @@ gsmi_parse_cops_scan(uint8_t ch, uint8_t reset) {
u.f.bo = 0; /* Clear bracket open flag */
u.f.tn = 0; /* Go to next term */
u.f.tp = 0; /* Go to beginning of next term */
- gsm.msg->msg.cops_scan.opsi++; /* Increase index */
- if (gsm.msg->msg.cops_scan.opf != NULL) {
- *gsm.msg->msg.cops_scan.opf = gsm.msg->msg.cops_scan.opsi;
+ ++lwgsm.msg->msg.cops_scan.opsi; /* Increase index */
+ if (lwgsm.msg->msg.cops_scan.opf != NULL) {
+ *lwgsm.msg->msg.cops_scan.opf = lwgsm.msg->msg.cops_scan.opsi;
}
} else if (ch == ',') {
- u.f.tn++; /* Go to next term */
+ ++u.f.tn; /* Go to next term */
u.f.tp = 0; /* Go to beginning of next term */
} else if (ch != '"') { /* We have valid data */
- size_t i = gsm.msg->msg.cops_scan.opsi;
+ size_t i = lwgsm.msg->msg.cops_scan.opsi;
switch (u.f.tn) {
case 0: { /* Parse status info */
- gsm.msg->msg.cops_scan.ops[i].stat = (gsm_operator_status_t)(10 * (size_t)gsm.msg->msg.cops_scan.ops[i].stat + (ch - '0'));
+ lwgsm.msg->msg.cops_scan.ops[i].stat = (lwgsm_operator_status_t)(10 * (size_t)lwgsm.msg->msg.cops_scan.ops[i].stat + (ch - '0'));
break;
}
case 1: { /*!< Parse long name */
- if (u.f.tp < sizeof(gsm.msg->msg.cops_scan.ops[i].long_name) - 1) {
- gsm.msg->msg.cops_scan.ops[i].long_name[u.f.tp++] = ch;
- gsm.msg->msg.cops_scan.ops[i].long_name[u.f.tp] = 0;
+ if (u.f.tp < sizeof(lwgsm.msg->msg.cops_scan.ops[i].long_name) - 1) {
+ lwgsm.msg->msg.cops_scan.ops[i].long_name[u.f.tp] = ch;
+ lwgsm.msg->msg.cops_scan.ops[i].long_name[++u.f.tp] = 0;
}
break;
}
case 2: { /*!< Parse short name */
- if (u.f.tp < sizeof(gsm.msg->msg.cops_scan.ops[i].short_name) - 1) {
- gsm.msg->msg.cops_scan.ops[i].short_name[u.f.tp++] = ch;
- gsm.msg->msg.cops_scan.ops[i].short_name[u.f.tp] = 0;
+ if (u.f.tp < sizeof(lwgsm.msg->msg.cops_scan.ops[i].short_name) - 1) {
+ lwgsm.msg->msg.cops_scan.ops[i].short_name[u.f.tp] = ch;
+ lwgsm.msg->msg.cops_scan.ops[i].short_name[++u.f.tp] = 0;
}
break;
}
case 3: { /*!< Parse number */
- gsm.msg->msg.cops_scan.ops[i].num = (10 * gsm.msg->msg.cops_scan.ops[i].num) + (ch - '0');
+ lwgsm.msg->msg.cops_scan.ops[i].num = (10 * lwgsm.msg->msg.cops_scan.ops[i].num) + (ch - '0');
break;
}
- default: break;
+ default:
+ break;
}
}
} else {
@@ -547,19 +559,19 @@ gsmi_parse_cops_scan(uint8_t ch, uint8_t reset) {
* \return 1 on success, 0 otherwise
*/
uint8_t
-gsmi_parse_datetime(const char** src, gsm_datetime_t* dt) {
- dt->date = gsmi_parse_number(src);
- dt->month = gsmi_parse_number(src);
- dt->year = GSM_U16(2000) + gsmi_parse_number(src);
- dt->hours = gsmi_parse_number(src);
- dt->minutes = gsmi_parse_number(src);
- dt->seconds = gsmi_parse_number(src);
-
- gsmi_check_and_trim(src); /* Trim text to the end */
+lwgsmi_parse_datetime(const char** src, lwgsm_datetime_t* dt) {
+ dt->date = lwgsmi_parse_number(src);
+ dt->month = lwgsmi_parse_number(src);
+ dt->year = LWGSM_U16(2000) + lwgsmi_parse_number(src);
+ dt->hours = lwgsmi_parse_number(src);
+ dt->minutes = lwgsmi_parse_number(src);
+ dt->seconds = lwgsmi_parse_number(src);
+
+ lwgsmi_check_and_trim(src); /* Trim text to the end */
return 1;
}
-#if GSM_CFG_CALL || __DOXYGEN__
+#if LWGSM_CFG_CALL || __DOXYGEN__
/**
* \brief Parse received +CLCC with call status info
@@ -568,30 +580,30 @@ gsmi_parse_datetime(const char** src, gsm_datetime_t* dt) {
* \return 1 on success, 0 otherwise
*/
uint8_t
-gsmi_parse_clcc(const char* str, uint8_t send_evt) {
+lwgsmi_parse_clcc(const char* str, uint8_t send_evt) {
if (*str == '+') {
str += 7;
}
- gsm.m.call.id = gsmi_parse_number(&str);
- gsm.m.call.dir = (gsm_call_dir_t)gsmi_parse_number(&str);
- gsm.m.call.state = (gsm_call_state_t)gsmi_parse_number(&str);
- gsm.m.call.type = (gsm_call_type_t)gsmi_parse_number(&str);
- gsm.m.call.is_multipart = (gsm_call_type_t)gsmi_parse_number(&str);
- gsmi_parse_string(&str, gsm.m.call.number, sizeof(gsm.m.call.number), 1);
- gsm.m.call.addr_type = gsmi_parse_number(&str);
- gsmi_parse_string(&str, gsm.m.call.name, sizeof(gsm.m.call.name), 1);
+ lwgsm.m.call.id = lwgsmi_parse_number(&str);
+ lwgsm.m.call.dir = (lwgsm_call_dir_t)lwgsmi_parse_number(&str);
+ lwgsm.m.call.state = (lwgsm_call_state_t)lwgsmi_parse_number(&str);
+ lwgsm.m.call.type = (lwgsm_call_type_t)lwgsmi_parse_number(&str);
+ lwgsm.m.call.is_multipart = (lwgsm_call_type_t)lwgsmi_parse_number(&str);
+ lwgsmi_parse_string(&str, lwgsm.m.call.number, sizeof(lwgsm.m.call.number), 1);
+ lwgsm.m.call.addr_type = lwgsmi_parse_number(&str);
+ lwgsmi_parse_string(&str, lwgsm.m.call.name, sizeof(lwgsm.m.call.name), 1);
if (send_evt) {
- gsm.evt.evt.call_changed.call = &gsm.m.call;
- gsmi_send_cb(GSM_EVT_CALL_CHANGED);
+ lwgsm.evt.evt.call_changed.call = &lwgsm.m.call;
+ lwgsmi_send_cb(LWGSM_EVT_CALL_CHANGED);
}
return 1;
}
-#endif /* GSM_CFG_CALL || __DOXYGEN__ */
+#endif /* LWGSM_CFG_CALL || __DOXYGEN__ */
-#if GSM_CFG_SMS || __DOXYGEN__
+#if LWGSM_CFG_SMS || __DOXYGEN__
/**
* \brief Parse string and check for type of SMS state
@@ -600,23 +612,23 @@ gsmi_parse_clcc(const char* str, uint8_t send_evt) {
* \return 1 on success, 0 otherwise
*/
uint8_t
-gsmi_parse_sms_status(const char** src, gsm_sms_status_t* stat) {
- gsm_sms_status_t s;
+lwgsmi_parse_sms_status(const char** src, lwgsm_sms_status_t* stat) {
+ lwgsm_sms_status_t s;
char t[11];
- gsmi_parse_string(src, t, sizeof(t), 1); /* Parse string and advance */
+ lwgsmi_parse_string(src, t, sizeof(t), 1); /* Parse string and advance */
if (!strcmp(t, "REC UNREAD")) {
- s = GSM_SMS_STATUS_UNREAD;
+ s = LWGSM_SMS_STATUS_UNREAD;
} else if (!strcmp(t, "REC READ")) {
- s = GSM_SMS_STATUS_READ;
+ s = LWGSM_SMS_STATUS_READ;
} else if (!strcmp(t, "STO UNSENT")) {
- s = GSM_SMS_STATUS_UNSENT;
+ s = LWGSM_SMS_STATUS_UNSENT;
} else if (!strcmp(t, "REC SENT")) {
- s = GSM_SMS_STATUS_SENT;
+ s = LWGSM_SMS_STATUS_SENT;
} else {
- s = GSM_SMS_STATUS_ALL; /* Error! */
+ s = LWGSM_SMS_STATUS_ALL; /* Error! */
}
- if (s != GSM_SMS_STATUS_ALL) {
+ if (s != LWGSM_SMS_STATUS_ALL) {
*stat = s;
return 1;
}
@@ -630,13 +642,13 @@ gsmi_parse_sms_status(const char** src, gsm_sms_status_t* stat) {
* \return `1` on success, `0` otherwise
*/
uint8_t
-gsmi_parse_cmgs(const char* str, size_t* num) {
+lwgsmi_parse_cmgs(const char* str, size_t* num) {
if (*str == '+') {
str += 7;
}
if (num != NULL) {
- *num = (size_t)gsmi_parse_number(&str);
+ *num = (size_t)lwgsmi_parse_number(&str);
}
return 1;
}
@@ -648,18 +660,18 @@ gsmi_parse_cmgs(const char* str, size_t* num) {
* \return 1 on success, 0 otherwise
*/
uint8_t
-gsmi_parse_cmgr(const char* str) {
- gsm_sms_entry_t* e;
+lwgsmi_parse_cmgr(const char* str) {
+ lwgsm_sms_entry_t* e;
if (*str == '+') {
str += 7;
}
- e = gsm.msg->msg.sms_read.entry;
+ e = lwgsm.msg->msg.sms_read.entry;
e->length = 0;
- gsmi_parse_sms_status(&str, &e->status);
- gsmi_parse_string(&str, e->number, sizeof(e->number), 1);
- gsmi_parse_string(&str, e->name, sizeof(e->name), 1);
- gsmi_parse_datetime(&str, &e->datetime);
+ lwgsmi_parse_sms_status(&str, &e->status);
+ lwgsmi_parse_string(&str, e->number, sizeof(e->number), 1);
+ lwgsmi_parse_string(&str, e->name, sizeof(e->name), 1);
+ lwgsmi_parse_datetime(&str, &e->datetime);
return 1;
}
@@ -671,11 +683,11 @@ gsmi_parse_cmgr(const char* str) {
* \return 1 on success, 0 otherwise
*/
uint8_t
-gsmi_parse_cmgl(const char* str) {
- gsm_sms_entry_t* e;
+lwgsmi_parse_cmgl(const char* str) {
+ lwgsm_sms_entry_t* e;
- if (!CMD_IS_DEF(GSM_CMD_CMGL) ||
- gsm.msg->msg.sms_list.ei >= gsm.msg->msg.sms_list.etr) {
+ if (!CMD_IS_DEF(LWGSM_CMD_CMGL) ||
+ lwgsm.msg->msg.sms_list.ei >= lwgsm.msg->msg.sms_list.etr) {
return 0;
}
@@ -683,14 +695,14 @@ gsmi_parse_cmgl(const char* str) {
str += 7;
}
- e = &gsm.msg->msg.sms_list.entries[gsm.msg->msg.sms_list.ei];
+ e = &lwgsm.msg->msg.sms_list.entries[lwgsm.msg->msg.sms_list.ei];
e->length = 0;
- e->mem = gsm.msg->msg.sms_list.mem; /* Manually set memory */
- e->pos = GSM_SZ(gsmi_parse_number(&str)); /* Scan position */
- gsmi_parse_sms_status(&str, &e->status);
- gsmi_parse_string(&str, e->number, sizeof(e->number), 1);
- gsmi_parse_string(&str, e->name, sizeof(e->name), 1);
- gsmi_parse_datetime(&str, &e->datetime);
+ e->mem = lwgsm.msg->msg.sms_list.mem; /* Manually set memory */
+ e->pos = LWGSM_SZ(lwgsmi_parse_number(&str)); /* Scan position */
+ lwgsmi_parse_sms_status(&str, &e->status);
+ lwgsmi_parse_string(&str, e->number, sizeof(e->number), 1);
+ lwgsmi_parse_string(&str, e->name, sizeof(e->name), 1);
+ lwgsmi_parse_datetime(&str, &e->datetime);
return 1;
}
@@ -702,16 +714,16 @@ gsmi_parse_cmgl(const char* str) {
* \return 1 on success, 0 otherwise
*/
uint8_t
-gsmi_parse_cmti(const char* str, uint8_t send_evt) {
+lwgsmi_parse_cmti(const char* str, uint8_t send_evt) {
if (*str == '+') {
str += 7;
}
- gsm.evt.evt.sms_recv.mem = gsmi_parse_memory(&str); /* Parse memory string */
- gsm.evt.evt.sms_recv.pos = gsmi_parse_number(&str); /* Parse number */
+ lwgsm.evt.evt.sms_recv.mem = lwgsmi_parse_memory(&str); /* Parse memory string */
+ lwgsm.evt.evt.sms_recv.pos = lwgsmi_parse_number(&str); /* Parse number */
if (send_evt) {
- gsmi_send_cb(GSM_EVT_SMS_RECV);
+ lwgsmi_send_cb(LWGSM_EVT_SMS_RECV);
}
return 1;
}
@@ -723,43 +735,44 @@ gsmi_parse_cmti(const char* str, uint8_t send_evt) {
* \return 1 on success, 0 otherwise
*/
uint8_t
-gsmi_parse_cpms(const char* str, uint8_t opt) {
+lwgsmi_parse_cpms(const char* str, uint8_t opt) {
uint8_t i;
if (*str == '+') {
str += 7;
}
switch (opt) { /* Check expected input string */
case 0: { /* Get list of CPMS options: +CPMS: (("","","",..),("....")("...")) */
- for (i = 0; i < 3; i++) { /* 3 different memories for "operation","receive","sent" */
- if (!gsmi_parse_memories_string(&str, &gsm.m.sms.mem[i].mem_available)) {
+ for (i = 0; i < 3; ++i) { /* 3 different memories for "operation","receive","sent" */
+ if (!lwgsmi_parse_memories_string(&str, &lwgsm.m.sms.mem[i].mem_available)) {
return 0;
}
}
break;
}
case 1: { /* Received statement of current info: +CPMS: "ME",10,20,"SE",2,20,"... */
- for (i = 0; i < 3; i++) { /* 3 memories expected */
- gsm.m.sms.mem[i].current = gsmi_parse_memory(&str); /* Parse memory string and save it as current */
- gsm.m.sms.mem[i].used = gsmi_parse_number(&str);/* Get used memory size */
- gsm.m.sms.mem[i].total = gsmi_parse_number(&str); /* Get total memory size */
+ for (i = 0; i < 3; ++i) { /* 3 memories expected */
+ lwgsm.m.sms.mem[i].current = lwgsmi_parse_memory(&str); /* Parse memory string and save it as current */
+ lwgsm.m.sms.mem[i].used = lwgsmi_parse_number(&str);/* Get used memory size */
+ lwgsm.m.sms.mem[i].total = lwgsmi_parse_number(&str); /* Get total memory size */
}
break;
}
case 2: { /* Received statement of set info: +CPMS: 10,20,2,20 */
- for (i = 0; i < 3; i++) { /* 3 memories expected */
- gsm.m.sms.mem[i].used = gsmi_parse_number(&str);/* Get used memory size */
- gsm.m.sms.mem[i].total = gsmi_parse_number(&str); /* Get total memory size */
+ for (i = 0; i < 3; ++i) { /* 3 memories expected */
+ lwgsm.m.sms.mem[i].used = lwgsmi_parse_number(&str);/* Get used memory size */
+ lwgsm.m.sms.mem[i].total = lwgsmi_parse_number(&str); /* Get total memory size */
}
break;
}
- default: break;
+ default:
+ break;
}
return 1;
}
-#endif /* GSM_CFG_SMS || __DOXYGEN__ */
+#endif /* LWGSM_CFG_SMS || __DOXYGEN__ */
-#if GSM_CFG_PHONEBOOK || __DOXYGEN__
+#if LWGSM_CFG_PHONEBOOK || __DOXYGEN__
/**
* \brief Parse +CPBS statement
@@ -768,23 +781,23 @@ gsmi_parse_cpms(const char* str, uint8_t opt) {
* \return 1 on success, 0 otherwise
*/
uint8_t
-gsmi_parse_cpbs(const char* str, uint8_t opt) {
+lwgsmi_parse_cpbs(const char* str, uint8_t opt) {
if (*str == '+') {
str += 7;
}
switch (opt) { /* Check expected input string */
case 0: { /* Get list of CPBS options: ("M1","M2","M3",...) */
- return gsmi_parse_memories_string(&str, &gsm.m.pb.mem.mem_available);
+ return lwgsmi_parse_memories_string(&str, &lwgsm.m.pb.mem.mem_available);
}
case 1: { /* Received statement of current info: +CPBS: "ME",10,20 */
- gsm.m.pb.mem.current = gsmi_parse_memory(&str); /* Parse memory string and save it as current */
- gsm.m.pb.mem.used = gsmi_parse_number(&str);/* Get used memory size */
- gsm.m.pb.mem.total = gsmi_parse_number(&str); /* Get total memory size */
+ lwgsm.m.pb.mem.current = lwgsmi_parse_memory(&str); /* Parse memory string and save it as current */
+ lwgsm.m.pb.mem.used = lwgsmi_parse_number(&str);/* Get used memory size */
+ lwgsm.m.pb.mem.total = lwgsmi_parse_number(&str); /* Get total memory size */
break;
}
case 2: { /* Received statement of set info: +CPBS: 10,20 */
- gsm.m.pb.mem.used = gsmi_parse_number(&str);/* Get used memory size */
- gsm.m.pb.mem.total = gsmi_parse_number(&str); /* Get total memory size */
+ lwgsm.m.pb.mem.used = lwgsmi_parse_number(&str);/* Get used memory size */
+ lwgsm.m.pb.mem.total = lwgsmi_parse_number(&str); /* Get total memory size */
break;
}
}
@@ -797,11 +810,11 @@ gsmi_parse_cpbs(const char* str, uint8_t opt) {
* \return 1 on success, 0 otherwise
*/
uint8_t
-gsmi_parse_cpbr(const char* str) {
- gsm_pb_entry_t* e;
+lwgsmi_parse_cpbr(const char* str) {
+ lwgsm_pb_entry_t* e;
- if (!CMD_IS_DEF(GSM_CMD_CPBR) ||
- gsm.msg->msg.pb_list.ei >= gsm.msg->msg.pb_list.etr) {
+ if (!CMD_IS_DEF(LWGSM_CMD_CPBR) ||
+ lwgsm.msg->msg.pb_list.ei >= lwgsm.msg->msg.pb_list.etr) {
return 0;
}
@@ -809,15 +822,15 @@ gsmi_parse_cpbr(const char* str) {
str += 7;
}
- e = &gsm.msg->msg.pb_list.entries[gsm.msg->msg.pb_list.ei];
- e->pos = GSM_SZ(gsmi_parse_number(&str));
- gsmi_parse_string(&str, e->name, sizeof(e->name), 1);
- e->type = (gsm_number_type_t)gsmi_parse_number(&str);
- gsmi_parse_string(&str, e->number, sizeof(e->number), 1);
+ e = &lwgsm.msg->msg.pb_list.entries[lwgsm.msg->msg.pb_list.ei];
+ e->pos = LWGSM_SZ(lwgsmi_parse_number(&str));
+ lwgsmi_parse_string(&str, e->name, sizeof(e->name), 1);
+ e->type = (lwgsm_number_type_t)lwgsmi_parse_number(&str);
+ lwgsmi_parse_string(&str, e->number, sizeof(e->number), 1);
- gsm.msg->msg.pb_list.ei++;
- if (gsm.msg->msg.pb_list.er != NULL) {
- *gsm.msg->msg.pb_list.er = gsm.msg->msg.pb_list.ei;
+ ++lwgsm.msg->msg.pb_list.ei;
+ if (lwgsm.msg->msg.pb_list.er != NULL) {
+ *lwgsm.msg->msg.pb_list.er = lwgsm.msg->msg.pb_list.ei;
}
return 1;
}
@@ -828,11 +841,11 @@ gsmi_parse_cpbr(const char* str) {
* \return 1 on success, 0 otherwise
*/
uint8_t
-gsmi_parse_cpbf(const char* str) {
- gsm_pb_entry_t* e;
+lwgsmi_parse_cpbf(const char* str) {
+ lwgsm_pb_entry_t* e;
- if (!CMD_IS_DEF(GSM_CMD_CPBF) ||
- gsm.msg->msg.pb_search.ei >= gsm.msg->msg.pb_search.etr) {
+ if (!CMD_IS_DEF(LWGSM_CMD_CPBF) ||
+ lwgsm.msg->msg.pb_search.ei >= lwgsm.msg->msg.pb_search.etr) {
return 0;
}
@@ -840,22 +853,22 @@ gsmi_parse_cpbf(const char* str) {
str += 7;
}
- e = &gsm.msg->msg.pb_search.entries[gsm.msg->msg.pb_search.ei];
- e->pos = GSM_SZ(gsmi_parse_number(&str));
- gsmi_parse_string(&str, e->name, sizeof(e->name), 1);
- e->type = (gsm_number_type_t)gsmi_parse_number(&str);
- gsmi_parse_string(&str, e->number, sizeof(e->number), 1);
+ e = &lwgsm.msg->msg.pb_search.entries[lwgsm.msg->msg.pb_search.ei];
+ e->pos = LWGSM_SZ(lwgsmi_parse_number(&str));
+ lwgsmi_parse_string(&str, e->name, sizeof(e->name), 1);
+ e->type = (lwgsm_number_type_t)lwgsmi_parse_number(&str);
+ lwgsmi_parse_string(&str, e->number, sizeof(e->number), 1);
- gsm.msg->msg.pb_search.ei++;
- if (gsm.msg->msg.pb_search.er != NULL) {
- *gsm.msg->msg.pb_search.er = gsm.msg->msg.pb_search.ei;
+ ++lwgsm.msg->msg.pb_search.ei;
+ if (lwgsm.msg->msg.pb_search.er != NULL) {
+ *lwgsm.msg->msg.pb_search.er = lwgsm.msg->msg.pb_search.ei;
}
return 1;
}
-#endif /* GSM_CFG_PHONEBOOK || __DOXYGEN__ */
+#endif /* LWGSM_CFG_PHONEBOOK || __DOXYGEN__ */
-#if GSM_CFG_CONN
+#if LWGSM_CFG_CONN
/**
* \brief Parse connection info line from CIPSTATUS command
@@ -865,9 +878,9 @@ gsmi_parse_cpbf(const char* str) {
* \return `1` on success, `0` otherwise
*/
uint8_t
-gsmi_parse_cipstatus_conn(const char* str, uint8_t is_conn_line, uint8_t* continueScan) {
+lwgsmi_parse_cipstatus_conn(const char* str, uint8_t is_conn_line, uint8_t* continueScan) {
uint8_t num;
- gsm_conn_t* conn;
+ lwgsm_conn_t* conn;
char s_tmp[16];
uint8_t tmp_pdp_state;
@@ -886,34 +899,34 @@ gsmi_parse_cipstatus_conn(const char* str, uint8_t is_conn_line, uint8_t* contin
}
/* Check if we have to update status for application */
- if (gsm.m.network.is_attached != tmp_pdp_state) {
- gsm.m.network.is_attached = tmp_pdp_state;
+ if (lwgsm.m.network.is_attached != tmp_pdp_state) {
+ lwgsm.m.network.is_attached = tmp_pdp_state;
/* Notify upper layer */
- gsmi_send_cb(gsm.m.network.is_attached ? GSM_EVT_NETWORK_ATTACHED : GSM_EVT_NETWORK_DETACHED);
+ lwgsmi_send_cb(lwgsm.m.network.is_attached ? LWGSM_EVT_NETWORK_ATTACHED : LWGSM_EVT_NETWORK_DETACHED);
}
return 1;
}
/* Parse connection line */
- num = GSM_U8(gsmi_parse_number(&str));
- conn = &gsm.m.conns[num];
+ num = LWGSM_U8(lwgsmi_parse_number(&str));
+ conn = &lwgsm.m.conns[num];
- conn->status.f.bearer = GSM_U8(gsmi_parse_number(&str));
- gsmi_parse_string(&str, s_tmp, sizeof(s_tmp), 1); /* Parse TCP/UPD */
+ conn->status.f.bearer = LWGSM_U8(lwgsmi_parse_number(&str));
+ lwgsmi_parse_string(&str, s_tmp, sizeof(s_tmp), 1); /* Parse TCP/UPD */
if (strlen(s_tmp)) {
if (!strcmp(s_tmp, "TCP")) {
- conn->type = GSM_CONN_TYPE_TCP;
+ conn->type = LWGSM_CONN_TYPE_TCP;
} else if (!strcmp(s_tmp, "UDP")) {
- conn->type = GSM_CONN_TYPE_UDP;
+ conn->type = LWGSM_CONN_TYPE_UDP;
}
}
- gsmi_parse_ip(&str, &conn->remote_ip);
- conn->remote_port = gsmi_parse_number(&str);
+ lwgsmi_parse_ip(&str, &conn->remote_ip);
+ conn->remote_port = lwgsmi_parse_number(&str);
/* Get connection status */
- gsmi_parse_string(&str, s_tmp, sizeof(s_tmp), 1);
+ lwgsmi_parse_string(&str, s_tmp, sizeof(s_tmp), 1);
/* TODO: Implement all connection states */
if (!strcmp(s_tmp, "INITIAL")) {
@@ -928,12 +941,12 @@ gsmi_parse_cipstatus_conn(const char* str, uint8_t is_conn_line, uint8_t* contin
} else if (!strcmp(s_tmp, "CLOSED")) { /* Connection closed */
if (conn->status.f.active) { /* Check if connection is not */
- gsmi_conn_closed_process(conn->num, 0); /* Process closed event */
+ lwgsmi_conn_closed_process(conn->num, 0); /* Process closed event */
}
}
/* Save last parsed connection */
- gsm.m.active_conns_cur_parse_num = num;
+ lwgsm.m.active_conns_cur_parse_num = num;
return 1;
}
@@ -944,13 +957,13 @@ gsmi_parse_cipstatus_conn(const char* str, uint8_t is_conn_line, uint8_t* contin
* \return `1` on success, `0` otherwise
*/
uint8_t
-gsmi_parse_ipd(const char* str) {
+lwgsmi_parse_ipd(const char* str) {
uint8_t conn;
size_t len;
- gsm_conn_p c;
+ lwgsm_conn_p c;
if (*str == '+') {
- str++;
+ ++str;
if (*str == 'R') {
str += 8; /* Advance for RECEIVE */
} else {
@@ -958,20 +971,20 @@ gsmi_parse_ipd(const char* str) {
}
}
- conn = gsmi_parse_number(&str); /* Parse number for connection number */
- len = gsmi_parse_number(&str); /* Parse number for number of bytes to read */
+ conn = lwgsmi_parse_number(&str); /* Parse number for connection number */
+ len = lwgsmi_parse_number(&str); /* Parse number for number of bytes to read */
- c = conn < GSM_CFG_MAX_CONNS ? &gsm.m.conns[conn] : NULL; /* Get connection handle */
+ c = conn < LWGSM_CFG_MAX_CONNS ? &lwgsm.m.conns[conn] : NULL; /* Get connection handle */
if (c == NULL) { /* Invalid connection number */
return 0;
}
- gsm.m.ipd.read = 1; /* Start reading network data */
- gsm.m.ipd.tot_len = len; /* Total number of bytes in this received packet */
- gsm.m.ipd.rem_len = len; /* Number of remaining bytes to read */
- gsm.m.ipd.conn = c; /* Pointer to connection we have data for */
+ lwgsm.m.ipd.read = 1; /* Start reading network data */
+ lwgsm.m.ipd.tot_len = len; /* Total number of bytes in this received packet */
+ lwgsm.m.ipd.rem_len = len; /* Number of remaining bytes to read */
+ lwgsm.m.ipd.conn = c; /* Pointer to connection we have data for */
return 1;
}
-#endif /* GSM_CFG_CONN */
+#endif /* LWGSM_CFG_CONN */
diff --git a/gsm_at_lib/src/gsm/gsm_pbuf.c b/lwgsm/src/lwgsm/lwgsm_pbuf.c
similarity index 69%
rename from gsm_at_lib/src/gsm/gsm_pbuf.c
rename to lwgsm/src/lwgsm/lwgsm_pbuf.c
index 79b0782d..79367b21 100644
--- a/gsm_at_lib/src/gsm/gsm_pbuf.c
+++ b/lwgsm/src/lwgsm/lwgsm_pbuf.c
@@ -1,10 +1,10 @@
/**
- * \file gsm_pbuf.c
+ * \file lwgsm_pbuf.c
* \brief Packet buffer manager
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,17 +26,17 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#include "gsm/gsm_private.h"
-#include "gsm/gsm_pbuf.h"
-#include "gsm/gsm_mem.h"
+#include "lwgsm/lwgsm_private.h"
+#include "lwgsm/lwgsm_pbuf.h"
+#include "lwgsm/lwgsm_mem.h"
/* Set size of pbuf structure */
-#define SIZEOF_PBUF_STRUCT GSM_MEM_ALIGN(sizeof(gsm_pbuf_t))
+#define SIZEOF_PBUF_STRUCT LWGSM_MEM_ALIGN(sizeof(lwgsm_pbuf_t))
#define SET_NEW_LEN(v, len) do { if ((v) != NULL) { *(v) = (len); } } while (0)
/**
@@ -46,8 +46,8 @@
* \param[out] new_off: New offset on new returned pbuf
* \return New pbuf where offset was found, `NULL` if offset too big for pbuf chain
*/
-static gsm_pbuf_p
-pbuf_skip(gsm_pbuf_p p, size_t off, size_t* new_off) {
+static lwgsm_pbuf_p
+pbuf_skip(lwgsm_pbuf_p p, size_t off, size_t* new_off) {
if (p == NULL || p->tot_len < off) { /* Check valid parameters */
SET_NEW_LEN(new_off, 0); /* Set output value */
return NULL;
@@ -67,20 +67,20 @@ pbuf_skip(gsm_pbuf_p p, size_t off, size_t* new_off) {
* \param[in] len: Length of payload memory to allocate
* \return Pointer to allocated memory, `NULL` otherwise
*/
-gsm_pbuf_p
-gsm_pbuf_new(size_t len) {
- gsm_pbuf_p p;
-
- p = gsm_mem_malloc(SIZEOF_PBUF_STRUCT + sizeof(*p->payload) * len);
- GSM_DEBUGW(GSM_CFG_DBG_PBUF | GSM_DBG_TYPE_TRACE, p == NULL,
- "[PBUF] Failed to allocate %d bytes\r\n", (int)len);
- GSM_DEBUGW(GSM_CFG_DBG_PBUF | GSM_DBG_TYPE_TRACE, p != NULL,
- "[PBUF] Allocated %d bytes on %p\r\n", (int)len, p);
+lwgsm_pbuf_p
+lwgsm_pbuf_new(size_t len) {
+ lwgsm_pbuf_p p;
+
+ p = lwgsm_mem_malloc(SIZEOF_PBUF_STRUCT + sizeof(*p->payload) * len);
+ LWGSM_DEBUGW(LWGSM_CFG_DBG_PBUF | LWGSM_DBG_TYPE_TRACE, p == NULL,
+ "[PBUF] Failed to allocate %d bytes\r\n", (int)len);
+ LWGSM_DEBUGW(LWGSM_CFG_DBG_PBUF | LWGSM_DBG_TYPE_TRACE, p != NULL,
+ "[PBUF] Allocated %d bytes on %p\r\n", (int)len, p);
if (p != NULL) {
p->next = NULL; /* No next element in chain */
p->tot_len = len; /* Set total length of pbuf chain */
p->len = len; /* Set payload length */
- p->payload = (void *)(((char *)p) + SIZEOF_PBUF_STRUCT);/* Set pointer to payload data */
+ p->payload = (void*)(((char*)p) + SIZEOF_PBUF_STRUCT); /* Set pointer to payload data */
p->ref = 1; /* Single reference is used on this pbuf */
}
return p;
@@ -92,11 +92,11 @@ gsm_pbuf_new(size_t len) {
* \return Number of freed pbufs from head
*/
size_t
-gsm_pbuf_free(gsm_pbuf_p pbuf) {
- gsm_pbuf_p p, pn;
+lwgsm_pbuf_free(lwgsm_pbuf_p pbuf) {
+ lwgsm_pbuf_p p, pn;
size_t ref, cnt;
- GSM_ASSERT("pbuf != NULL", pbuf != NULL);
+ LWGSM_ASSERT("pbuf != NULL", pbuf != NULL);
/*
* Free all pbufs until first ->ref > 1 is reached
@@ -104,16 +104,16 @@ gsm_pbuf_free(gsm_pbuf_p pbuf) {
*/
cnt = 0;
for (p = pbuf; p != NULL;) {
- gsm_core_lock();
+ lwgsm_core_lock();
ref = --p->ref; /* Decrease current value and save it */
- gsm_core_unlock();
+ lwgsm_core_unlock();
if (ref == 0) { /* Did we reach 0 and are ready to free it? */
- GSM_DEBUGF(GSM_CFG_DBG_PBUF | GSM_DBG_TYPE_TRACE,
- "[PBUF] Deallocating %p with len/tot_len: %d/%d\r\n", p, (int)p->len, (int)p->tot_len);
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_PBUF | LWGSM_DBG_TYPE_TRACE,
+ "[PBUF] Deallocating %p with len/tot_len: %d/%d\r\n", p, (int)p->len, (int)p->tot_len);
pn = p->next; /* Save next entry */
- gsm_mem_free_s((void **)&p); /* Free memory for pbuf */
+ lwgsm_mem_free_s((void**)&p); /* Free memory for pbuf */
p = pn; /* Restore with next entry */
- cnt++; /* Increase number of freed pbufs */
+ ++cnt; /* Increase number of freed pbufs */
} else {
break;
}
@@ -124,18 +124,18 @@ gsm_pbuf_free(gsm_pbuf_p pbuf) {
/**
* \brief Concatenate `2` packet buffers together to one big packet
* \note After `tail` pbuf has been added to `head` pbuf chain,
- * it must not be referenced by user anymore as it is now completelly controlled by `head` pbuf.
- * In simple words, when user calls this function, it should not call \ref gsm_pbuf_free function anymore,
+ * it must not be referenced by user anymore as it is now completely controlled by `head` pbuf.
+ * In simple words, when user calls this function, it should not call \ref lwgsm_pbuf_free function anymore,
* as it might make memory undefined for `head` pbuf.
* \param[in] head: Head packet buffer to append new pbuf to
* \param[in] tail: Tail packet buffer to append to head pbuf
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
- * \sa gsm_pbuf_chain
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
+ * \sa lwgsm_pbuf_chain
*/
-gsmr_t
-gsm_pbuf_cat(gsm_pbuf_p head, const gsm_pbuf_p tail) {
- GSM_ASSERT("head != NULL", head != NULL);
- GSM_ASSERT("tail != NULL", tail != NULL);
+lwgsmr_t
+lwgsm_pbuf_cat(lwgsm_pbuf_p head, const lwgsm_pbuf_p tail) {
+ LWGSM_ASSERT("head != NULL", head != NULL);
+ LWGSM_ASSERT("tail != NULL", tail != NULL);
/*
* For all pbuf packets in head,
@@ -147,30 +147,30 @@ gsm_pbuf_cat(gsm_pbuf_p head, const gsm_pbuf_p tail) {
head->tot_len += tail->tot_len; /* Increase total length of last packet in chain */
head->next = tail; /* Set next packet buffer as next one */
- return gsmOK;
+ return lwgsmOK;
}
/**
- * \brief Chain 2 pbufs together. Similar to \ref gsm_pbuf_cat
+ * \brief Chain 2 pbufs together. Similar to \ref lwgsm_pbuf_cat
* but now new reference is done from head pbuf to tail pbuf.
- * \note After this function call, user must call \ref gsm_pbuf_free to remove
- * its reference to tail pbuf and allow control to head pbuf: gsm_pbuf_free(tail)
+ * \note After this function call, user must call \ref lwgsm_pbuf_free to remove
+ * its reference to tail pbuf and allow control to head pbuf: `lwgsm_pbuf_free(tail)`
* \param[in] head: Head packet buffer to append new pbuf to
* \param[in] tail: Tail packet buffer to append to head pbuf
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
- * \sa gsm_pbuf_cat
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
+ * \sa lwgsm_pbuf_cat
*/
-gsmr_t
-gsm_pbuf_chain(gsm_pbuf_p head, gsm_pbuf_p tail) {
- gsmr_t res;
+lwgsmr_t
+lwgsm_pbuf_chain(lwgsm_pbuf_p head, lwgsm_pbuf_p tail) {
+ lwgsmr_t res;
/*
* To prevent issues with multi-thread access,
* first reference pbuf and increase counter
*/
- gsm_pbuf_ref(tail); /* Reference tail pbuf by head pbuf now */
- if ((res = gsm_pbuf_cat(head, tail)) != gsmOK) { /* Did we contencate them together successfully? */
- gsm_pbuf_free(tail); /* Call free to decrease reference counter */
+ lwgsm_pbuf_ref(tail); /* Reference tail pbuf by head pbuf now */
+ if ((res = lwgsm_pbuf_cat(head, tail)) != lwgsmOK) {/* Did we concatenate them together successfully? */
+ lwgsm_pbuf_free(tail); /* Call free to decrease reference counter */
}
return res;
}
@@ -178,14 +178,15 @@ gsm_pbuf_chain(gsm_pbuf_p head, gsm_pbuf_p tail) {
/**
* \brief Unchain first pbuf from list and return second one
*
- * `tot_len` and `len` fields are adjusted to reflect new values and reference counter is as is
+ * `tot_len` and `len` fields are adjusted to reflect new values and reference counter is `as is`
+ *
* \note After unchain, user must take care of both pbufs (`head` and `new returned one`)
* \param[in] head: First pbuf in chain to remove from chain
* \return Next pbuf after `head`
*/
-gsm_pbuf_p
-gsm_pbuf_unchain(gsm_pbuf_p head) {
- gsm_pbuf_p r = NULL;
+lwgsm_pbuf_p
+lwgsm_pbuf_unchain(lwgsm_pbuf_p head) {
+ lwgsm_pbuf_p r = NULL;
if (head != NULL && head->next != NULL) { /* Check for valid pbuf */
r = head->next; /* Set return value as next pbuf */
@@ -198,14 +199,14 @@ gsm_pbuf_unchain(gsm_pbuf_p head) {
/**
* \brief Increment reference count on pbuf
* \param[in] pbuf: pbuf to increase reference
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_pbuf_ref(gsm_pbuf_p pbuf) {
- GSM_ASSERT("pbuf != NULL", pbuf != NULL);
+lwgsmr_t
+lwgsm_pbuf_ref(lwgsm_pbuf_p pbuf) {
+ LWGSM_ASSERT("pbuf != NULL", pbuf != NULL);
- pbuf->ref++; /* Increase reference count for pbuf */
- return gsmOK;
+ ++pbuf->ref; /* Increase reference count for pbuf */
+ return lwgsmOK;
}
/**
@@ -214,34 +215,34 @@ gsm_pbuf_ref(gsm_pbuf_p pbuf) {
* \param[in] data: Input data to copy to pbuf memory
* \param[in] len: Length of input data to copy
* \param[in] offset: Start offset in pbuf where to start copying
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_pbuf_take(gsm_pbuf_p pbuf, const void* data, size_t len, size_t offset) {
+lwgsmr_t
+lwgsm_pbuf_take(lwgsm_pbuf_p pbuf, const void* data, size_t len, size_t offset) {
const uint8_t* d = data;
size_t copy_len;
- GSM_ASSERT("pbuf != NULL", pbuf != NULL);
- GSM_ASSERT("data != NULL", data != NULL);
- GSM_ASSERT("len > 0", len > 0);
- GSM_ASSERT("pbuf->tot_len >= len", pbuf->tot_len >= len);
+ LWGSM_ASSERT("pbuf != NULL", pbuf != NULL);
+ LWGSM_ASSERT("data != NULL", data != NULL);
+ LWGSM_ASSERT("len > 0", len > 0);
+ LWGSM_ASSERT("pbuf->tot_len >= len", pbuf->tot_len >= len);
/* Skip if necessary and check if we are in valid range */
if (offset > 0) {
- pbuf = pbuf_skip(pbuf, offset, &offset); /* Offset and check for new length */
+ pbuf = pbuf_skip(pbuf, offset, &offset);/* Offset and check for new length */
if (pbuf == NULL) {
- return gsmERR;
+ return lwgsmERR;
}
}
if (pbuf->tot_len < (len + offset)) {
- return gsmPARERR;
+ return lwgsmPARERR;
}
/* First only copy in case we have some offset from first pbuf */
if (offset > 0) {
- copy_len = GSM_MIN(pbuf->len - offset, len); /* Get length to copy to current pbuf */
- GSM_MEMCPY(pbuf->payload + offset, d, copy_len);/* Copy to memory with offset */
+ copy_len = LWGSM_MIN(pbuf->len - offset, len); /* Get length to copy to current pbuf */
+ LWGSM_MEMCPY(pbuf->payload + offset, d, copy_len); /* Copy to memory with offset */
len -= copy_len; /* Decrease remaining bytes to copy */
d += copy_len; /* Increase data pointer */
pbuf = pbuf->next; /* Go to next pbuf */
@@ -249,12 +250,12 @@ gsm_pbuf_take(gsm_pbuf_p pbuf, const void* data, size_t len, size_t offset) {
/* Copy user memory to sequence of pbufs */
for (; len; pbuf = pbuf->next) {
- copy_len = GSM_MIN(len, pbuf->len); /* Get copy length */
- GSM_MEMCPY(pbuf->payload, d, copy_len); /* Copy memory to pbuf payload */
+ copy_len = LWGSM_MIN(len, pbuf->len); /* Get copy length */
+ LWGSM_MEMCPY(pbuf->payload, d, copy_len); /* Copy memory to pbuf payload */
len -= copy_len; /* Decrease number of remaining bytes to send */
d += copy_len; /* Increase data pointer */
}
- return gsmOK;
+ return lwgsmOK;
}
/**
@@ -266,7 +267,7 @@ gsm_pbuf_take(gsm_pbuf_p pbuf, const void* data, size_t len, size_t offset) {
* \return Number of bytes copied
*/
size_t
-gsm_pbuf_copy(gsm_pbuf_p pbuf, void* data, size_t len, size_t offset) {
+lwgsm_pbuf_copy(lwgsm_pbuf_p pbuf, void* data, size_t len, size_t offset) {
size_t tot, tc;
uint8_t* d = data;
@@ -291,8 +292,8 @@ gsm_pbuf_copy(gsm_pbuf_p pbuf, void* data, size_t len, size_t offset) {
*/
tot = 0;
for (; pbuf != NULL && len; pbuf = pbuf->next) {
- tc = GSM_MIN(pbuf->len - offset, len); /* Get length of data to copy */
- GSM_MEMCPY(d, pbuf->payload + offset, tc); /* Copy data from pbuf */
+ tc = LWGSM_MIN(pbuf->len - offset, len);/* Get length of data to copy */
+ LWGSM_MEMCPY(d, pbuf->payload + offset, tc);/* Copy data from pbuf */
d += tc;
len -= tc;
tot += tc;
@@ -309,8 +310,8 @@ gsm_pbuf_copy(gsm_pbuf_p pbuf, void* data, size_t len, size_t offset) {
* \return `1` on success, `0` otherwise
*/
uint8_t
-gsm_pbuf_get_at(const gsm_pbuf_p pbuf, size_t pos, uint8_t* el) {
- gsm_pbuf_p p;
+lwgsm_pbuf_get_at(const lwgsm_pbuf_p pbuf, size_t pos, uint8_t* el) {
+ lwgsm_pbuf_p p;
if (pbuf != NULL) {
p = pbuf_skip(pbuf, pos, &pos); /* Skip pbufs to desired position and get new offset from new pbuf */
@@ -328,23 +329,23 @@ gsm_pbuf_get_at(const gsm_pbuf_p pbuf, size_t pos, uint8_t* el) {
* \param[in] needle: Data memory used as needle
* \param[in] len: Length of needle memory
* \param[in] off: Starting offset in pbuf memory
- * \return `GSM_SIZET_MAX` if no match or position where in pbuf we have a match
- * \sa gsm_pbuf_strfind
+ * \return `LWGSM_SIZET_MAX` if no match or position where in pbuf we have a match
+ * \sa lwgsm_pbuf_strfind
*/
size_t
-gsm_pbuf_memfind(const gsm_pbuf_p pbuf, const void* needle, size_t len, size_t off) {
+lwgsm_pbuf_memfind(const lwgsm_pbuf_p pbuf, const void* needle, size_t len, size_t off) {
if (pbuf != NULL && needle != NULL && pbuf->tot_len >= (len + off)) { /* Check if valid entries */
/*
* Try entire buffer element by element
* and in case we have a match, report it
*/
- for (size_t i = off; i <= pbuf->tot_len - len; i++) {
- if (!gsm_pbuf_memcmp(pbuf, needle, len, i)) { /* Check if identical */
+ for (size_t i = off; i <= pbuf->tot_len - len; ++i) {
+ if (!lwgsm_pbuf_memcmp(pbuf, needle, len, i)) { /* Check if identical */
return i; /* We have a match! */
}
}
}
- return GSM_SIZET_MAX; /* Return maximal value of size_t variable to indicate error */
+ return LWGSM_SIZET_MAX; /* Return maximal value of size_t variable to indicate error */
}
/**
@@ -352,12 +353,12 @@ gsm_pbuf_memfind(const gsm_pbuf_p pbuf, const void* needle, size_t len, size_t o
* \param[in] pbuf: Pbuf used as haystack
* \param[in] str: String to search for in pbuf
* \param[in] off: Starting offset in pbuf memory
- * \return `GSM_SIZET_MAX` if no match or position where in pbuf we have a match
- * \sa gsm_pbuf_memfind
+ * \return `LWGSM_SIZET_MAX` if no match or position where in pbuf we have a match
+ * \sa lwgsm_pbuf_memfind
*/
size_t
-gsm_pbuf_strfind(const gsm_pbuf_p pbuf, const char* str, size_t off) {
- return gsm_pbuf_memfind(pbuf, str, strlen(str), off);
+lwgsm_pbuf_strfind(const lwgsm_pbuf_p pbuf, const char* str, size_t off) {
+ return lwgsm_pbuf_memfind(pbuf, str, strlen(str), off);
}
/**
@@ -367,18 +368,18 @@ gsm_pbuf_strfind(const gsm_pbuf_p pbuf, const char* str, size_t off) {
* \param[in] data: Actual data to compare with
* \param[in] len: Length of input data in units of bytes
* \param[in] offset: Start offset to use when comparing data
- * \return `0` if equal, `GSM_SIZET_MAX` if memory/offset too big or anything between if not equal
- * \sa gsm_pbuf_strcmp
+ * \return `0` if equal, `LWGSM_SIZET_MAX` if memory/offset too big or anything between if not equal
+ * \sa lwgsm_pbuf_strcmp
*/
size_t
-gsm_pbuf_memcmp(const gsm_pbuf_p pbuf, const void* data, size_t len, size_t offset) {
- gsm_pbuf_p p;
+lwgsm_pbuf_memcmp(const lwgsm_pbuf_p pbuf, const void* data, size_t len, size_t offset) {
+ lwgsm_pbuf_p p;
uint8_t el;
const uint8_t* d = data;
- if (pbuf == NULL || data == NULL || len == 0 || /* Input parameters check */
- pbuf->tot_len < (offset + len)) { /* Check of valid ranges */
- return GSM_SIZET_MAX; /* Invalid check here */
+ if (pbuf == NULL || data == NULL || len == 0/* Input parameters check */
+ || pbuf->tot_len < (offset + len)) { /* Check of valid ranges */
+ return LWGSM_SIZET_MAX; /* Invalid check here */
}
/*
@@ -395,8 +396,8 @@ gsm_pbuf_memcmp(const gsm_pbuf_p pbuf, const void* data, size_t len, size_t offs
*
* Use byte by byte read function to inspect bytes separatelly
*/
- for (size_t i = 0; i < len; i++) {
- if (!gsm_pbuf_get_at(p, offset + i, &el) || el != d[i]) { /* Get value from pbuf at specific offset */
+ for (size_t i = 0; i < len; ++i) {
+ if (!lwgsm_pbuf_get_at(p, offset + i, &el) || el != d[i]) { /* Get value from pbuf at specific offset */
return offset + 1; /* Return value from offset where it failed */
}
}
@@ -409,12 +410,12 @@ gsm_pbuf_memcmp(const gsm_pbuf_p pbuf, const void* data, size_t len, size_t offs
* \param[in] pbuf: Pbuf used to compare with data memory
* \param[in] str: String to be compared with pbuf
* \param[in] offset: Start memory offset in pbuf
- * \return `0` if equal, `GSM_SIZET_MAX` if memory/offset too big or anything between if not equal
- * \sa gsm_pbuf_memcmp
+ * \return `0` if equal, `LWGSM_SIZET_MAX` if memory/offset too big or anything between if not equal
+ * \sa lwgsm_pbuf_memcmp
*/
size_t
-gsm_pbuf_strcmp(const gsm_pbuf_p pbuf, const char* str, size_t offset) {
- return gsm_pbuf_memcmp(pbuf, str, strlen(str), offset);
+lwgsm_pbuf_strcmp(const lwgsm_pbuf_p pbuf, const char* str, size_t offset) {
+ return lwgsm_pbuf_memcmp(pbuf, str, strlen(str), offset);
}
/**
@@ -426,9 +427,9 @@ gsm_pbuf_strcmp(const gsm_pbuf_p pbuf, const char* str, size_t offset) {
* \param[out] new_len: Length of memory returned by function
* \return Pointer to memory on success, `NULL` otherwise
*/
-void *
-gsm_pbuf_get_linear_addr(const gsm_pbuf_p pbuf, size_t offset, size_t* new_len) {
- gsm_pbuf_p p = pbuf;
+void*
+lwgsm_pbuf_get_linear_addr(const lwgsm_pbuf_p pbuf, size_t offset, size_t* new_len) {
+ lwgsm_pbuf_p p = pbuf;
if (pbuf == NULL || pbuf->tot_len < offset) { /* Check input parameters */
SET_NEW_LEN(new_len, 0);
@@ -451,8 +452,8 @@ gsm_pbuf_get_linear_addr(const gsm_pbuf_p pbuf, size_t offset, size_t* new_len)
* \param[in] pbuf: Packet buffer
* \return Pointer to data buffer on success, `NULL` otherwise
*/
-void *
-gsm_pbuf_data(const gsm_pbuf_p pbuf) {
+void*
+lwgsm_pbuf_data(const lwgsm_pbuf_p pbuf) {
return pbuf != NULL ? pbuf->payload : NULL;
}
@@ -463,7 +464,7 @@ gsm_pbuf_data(const gsm_pbuf_p pbuf) {
* \return Length of data in units of bytes
*/
size_t
-gsm_pbuf_length(const gsm_pbuf_p pbuf, uint8_t tot) {
+lwgsm_pbuf_length(const lwgsm_pbuf_p pbuf, uint8_t tot) {
return pbuf != NULL ? (tot ? pbuf->tot_len : pbuf->len) : 0;
}
@@ -474,9 +475,9 @@ gsm_pbuf_length(const gsm_pbuf_p pbuf, uint8_t tot) {
* \param[in] port: Port number to assign to packet buffer
*/
void
-gsm_pbuf_set_ip(gsm_pbuf_p pbuf, const gsm_ip_t* ip, gsm_port_t port) {
+lwgsm_pbuf_set_ip(lwgsm_pbuf_p pbuf, const lwgsm_ip_t* ip, lwgsm_port_t port) {
if (pbuf != NULL && ip != NULL) {
- GSM_MEMCPY(&pbuf->ip, ip, sizeof(*ip));
+ LWGSM_MEMCPY(&pbuf->ip, ip, sizeof(*ip));
pbuf->port = port;
}
}
@@ -494,7 +495,7 @@ gsm_pbuf_set_ip(gsm_pbuf_p pbuf, const gsm_ip_t* ip, gsm_port_t port) {
* \return `1` on success, `0` otherwise
*/
uint8_t
-gsm_pbuf_advance(gsm_pbuf_p pbuf, int len) {
+lwgsm_pbuf_advance(lwgsm_pbuf_p pbuf, int len) {
uint8_t process = 0;
if (pbuf == NULL || len == 0) {
return 0;
@@ -505,7 +506,7 @@ gsm_pbuf_advance(gsm_pbuf_p pbuf, int len) {
}
} else {
/* Is current payload + new len still higher than pbuf structure? */
- if (((uint8_t *)pbuf + SIZEOF_PBUF_STRUCT) < (pbuf->payload + len)) {
+ if (((uint8_t*)pbuf + SIZEOF_PBUF_STRUCT) < (pbuf->payload + len)) {
process = 1;
}
}
@@ -525,8 +526,8 @@ gsm_pbuf_advance(gsm_pbuf_p pbuf, int len) {
* \param[out] new_offset: Pointer to output variable to save new offset in returned pbuf
* \return New pbuf on success, `NULL` otherwise
*/
-gsm_pbuf_p
-gsm_pbuf_skip(gsm_pbuf_p pbuf, size_t offset, size_t* new_offset) {
+lwgsm_pbuf_p
+lwgsm_pbuf_skip(lwgsm_pbuf_p pbuf, size_t offset, size_t* new_offset) {
return pbuf_skip(pbuf, offset, new_offset); /* Skip pbufs with internal function */
}
@@ -536,19 +537,19 @@ gsm_pbuf_skip(gsm_pbuf_p pbuf, size_t offset, size_t* new_offset) {
* \param[in] seq: Set to `1` to dump all `pbufs` in linked list or `0` to dump first one only
*/
void
-gsm_pbuf_dump(gsm_pbuf_p p, uint8_t seq) {
+lwgsm_pbuf_dump(lwgsm_pbuf_p p, uint8_t seq) {
if (p != NULL) {
- GSM_DEBUGF(GSM_CFG_DBG_PBUF | GSM_DBG_TYPE_TRACE,
- "[PBUF] Dump start: %p\r\n", p);
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_PBUF | LWGSM_DBG_TYPE_TRACE,
+ "[PBUF] Dump start: %p\r\n", p);
for (; p != NULL; p = p->next) {
- GSM_DEBUGF(GSM_CFG_DBG_PBUF | GSM_DBG_TYPE_TRACE,
- "[PBUF] Dump %p; ref: %d; len: %d; tot_len: %d, next: %p\r\n",
- p, (int)p->ref, (int)p->len, (int)p->tot_len, p->next);
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_PBUF | LWGSM_DBG_TYPE_TRACE,
+ "[PBUF] Dump %p; ref: %d; len: %d; tot_len: %d, next: %p\r\n",
+ p, (int)p->ref, (int)p->len, (int)p->tot_len, p->next);
if (!seq) {
break;
}
}
- GSM_DEBUGF(GSM_CFG_DBG_PBUF | GSM_DBG_TYPE_TRACE,
- "[PBUF] Dump end\r\n");
+ LWGSM_DEBUGF(LWGSM_CFG_DBG_PBUF | LWGSM_DBG_TYPE_TRACE,
+ "[PBUF] Dump end\r\n");
}
}
diff --git a/lwgsm/src/lwgsm/lwgsm_phonebook.c b/lwgsm/src/lwgsm/lwgsm_phonebook.c
new file mode 100644
index 00000000..c811fed8
--- /dev/null
+++ b/lwgsm/src/lwgsm/lwgsm_phonebook.c
@@ -0,0 +1,334 @@
+/**
+ * \file lwgsm_phonebook.c
+ * \brief Phonebook API
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM - Lightweight GSM-AT library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+#include "lwgsm/lwgsm_private.h"
+#include "lwgsm/lwgsm_phonebook.h"
+#include "lwgsm/lwgsm_mem.h"
+
+#if LWGSM_CFG_PHONEBOOK || __DOXYGEN__
+
+#if !__DOXYGEN__
+#define CHECK_ENABLED() if (!(check_enabled() == lwgsmOK)) { return lwgsmERRNOTENABLED; }
+#endif /* !__DOXYGEN__ */
+
+/**
+ * \brief Check if phonebook is enabled
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+ */
+static lwgsmr_t
+check_enabled(void) {
+ lwgsmr_t res;
+ lwgsm_core_lock();
+ res = lwgsm.m.pb.enabled ? lwgsmOK : lwgsmERR;
+ lwgsm_core_unlock();
+ return res;
+}
+
+/**
+ * \brief Check if input memory is available in modem
+ * \param[in] mem: Memory to test
+ * \param[in] can_curr: Flag indicates if \ref LWGSM_MEM_CURRENT option can be used
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+ */
+static lwgsmr_t
+check_mem(lwgsm_mem_t mem, uint8_t can_curr) {
+ lwgsmr_t res = lwgsmERRMEM;
+ lwgsm_core_lock();
+ if ((mem < LWGSM_MEM_END && lwgsm.m.pb.mem.mem_available & (1 << (uint32_t)mem)) ||
+ (can_curr && mem == LWGSM_MEM_CURRENT)) {
+ res = lwgsmOK;
+ }
+ lwgsm_core_unlock();
+ return res;
+}
+
+/**
+ * \brief Enable phonebook functionality
+ * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
+ * \param[in] evt_arg: Custom argument for event callback function
+ * \param[in] blocking: Status whether command should be blocking or not
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+ */
+lwgsmr_t
+lwgsm_pb_enable(const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
+
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_PHONEBOOK_ENABLE;
+ LWGSM_MSG_VAR_REF(msg).cmd = LWGSM_CMD_CPBS_GET_OPT;
+
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 60000);
+}
+
+/**
+ * \brief Disable phonebook functionality
+ * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
+ * \param[in] evt_arg: Custom argument for event callback function
+ * \param[in] blocking: Status whether command should be blocking or not
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+ */
+lwgsmr_t
+lwgsm_pb_disable(const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ lwgsm_core_lock();
+ lwgsm.m.pb.enabled = 0;
+ if (evt_fn != NULL) {
+ evt_fn(lwgsmOK, evt_arg);
+ }
+ lwgsm_core_unlock();
+ return lwgsmOK;
+}
+
+/**
+ * \brief Add new phonebook entry to desired memory
+ * \param[in] mem: Memory to use to save entry. Use \ref LWGSM_MEM_CURRENT to use current memory
+ * \param[in] name: Entry name
+ * \param[in] num: Entry phone number
+ * \param[in] type: Entry phone number type
+ * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
+ * \param[in] evt_arg: Custom argument for event callback function
+ * \param[in] blocking: Status whether command should be blocking or not
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+ */
+lwgsmr_t
+lwgsm_pb_add(lwgsm_mem_t mem, const char* name, const char* num, lwgsm_number_type_t type,
+ const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
+
+ LWGSM_ASSERT("name != NULL", name != NULL);
+ LWGSM_ASSERT("num != NULL", num != NULL);
+ CHECK_ENABLED(); /* Check if enabled */
+ LWGSM_ASSERT("check_mem() == lwgsmOK", check_mem(mem, 1) == lwgsmOK);
+
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_CPBW_SET;
+ if (mem == LWGSM_MEM_CURRENT) { /* Should be always false */
+ LWGSM_MSG_VAR_REF(msg).cmd = LWGSM_CMD_CPBS_GET;/* First get memory */
+ } else {
+ LWGSM_MSG_VAR_REF(msg).cmd = LWGSM_CMD_CPBS_SET;/* First set memory */
+ }
+
+ LWGSM_MSG_VAR_REF(msg).msg.pb_write.pos = 0;
+ LWGSM_MSG_VAR_REF(msg).msg.pb_write.mem = mem;
+ LWGSM_MSG_VAR_REF(msg).msg.pb_write.name = name;
+ LWGSM_MSG_VAR_REF(msg).msg.pb_write.num = num;
+ LWGSM_MSG_VAR_REF(msg).msg.pb_write.type = type;
+
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 60000);
+}
+
+/**
+ * \brief Read single phonebook entry
+ * \param[in] mem: Memory to use to save entry. Use \ref LWGSM_MEM_CURRENT to use current memory
+ * \param[in] pos: Entry position in memory to read
+ * \param[out] entry: Pointer to entry variable to save data
+ * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
+ * \param[in] evt_arg: Custom argument for event callback function
+ * \param[in] blocking: Status whether command should be blocking or not
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+ */
+lwgsmr_t
+lwgsm_pb_read(lwgsm_mem_t mem, size_t pos, lwgsm_pb_entry_t* entry,
+ const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ return lwgsm_pb_list(mem, pos, entry, 1, NULL, evt_fn, evt_arg, blocking);
+}
+
+/**
+ * \brief Edit or overwrite phonebook entry at desired memory and position
+ * \param[in] mem: Memory to use to save entry. Use \ref LWGSM_MEM_CURRENT to use current memory
+ * \param[in] pos: Entry position in memory to edit
+ * \param[in] name: New entry name
+ * \param[in] num: New entry phone number
+ * \param[in] type: New entry phone number type
+ * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
+ * \param[in] evt_arg: Custom argument for event callback function
+ * \param[in] blocking: Status whether command should be blocking or not
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+ */
+lwgsmr_t
+lwgsm_pb_edit(lwgsm_mem_t mem, size_t pos, const char* name, const char* num, lwgsm_number_type_t type,
+ const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
+
+ LWGSM_ASSERT("name != NULL", name != NULL);
+ LWGSM_ASSERT("num != NULL", num != NULL);
+ CHECK_ENABLED(); /* Check if enabled */
+ LWGSM_ASSERT("check_mem() == mem", check_mem(mem, 1) == lwgsmOK);
+
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_CPBW_SET;
+ if (mem == LWGSM_MEM_CURRENT) { /* Should be always false */
+ LWGSM_MSG_VAR_REF(msg).cmd = LWGSM_CMD_CPBS_GET;/* First get memory */
+ } else {
+ LWGSM_MSG_VAR_REF(msg).cmd = LWGSM_CMD_CPBS_SET;/* First set memory */
+ }
+
+ LWGSM_MSG_VAR_REF(msg).msg.pb_write.pos = pos;
+ LWGSM_MSG_VAR_REF(msg).msg.pb_write.mem = mem;
+ LWGSM_MSG_VAR_REF(msg).msg.pb_write.name = name;
+ LWGSM_MSG_VAR_REF(msg).msg.pb_write.num = num;
+ LWGSM_MSG_VAR_REF(msg).msg.pb_write.type = type;
+
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 60000);
+}
+
+/**
+ * \brief Delete phonebook entry at desired memory and position
+ * \param[in] mem: Memory to use to save entry. Use \ref LWGSM_MEM_CURRENT to use current memory
+ * \param[in] pos: Entry position in memory to delete
+ * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
+ * \param[in] evt_arg: Custom argument for event callback function
+ * \param[in] blocking: Status whether command should be blocking or not
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+ */
+lwgsmr_t
+lwgsm_pb_delete(lwgsm_mem_t mem, size_t pos,
+ const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
+
+ LWGSM_ASSERT("pos > 0", pos > 0);
+ CHECK_ENABLED(); /* Check if enabled */
+ LWGSM_ASSERT("check_mem() == lwgsmOK", check_mem(mem, 1) == lwgsmOK);
+
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_CPBW_SET;
+ if (mem == LWGSM_MEM_CURRENT) { /* Should be always false */
+ LWGSM_MSG_VAR_REF(msg).cmd = LWGSM_CMD_CPBS_GET;/* First get memory */
+ } else {
+ LWGSM_MSG_VAR_REF(msg).cmd = LWGSM_CMD_CPBS_SET;/* First set memory */
+ }
+
+ LWGSM_MSG_VAR_REF(msg).msg.pb_write.mem = mem;
+ LWGSM_MSG_VAR_REF(msg).msg.pb_write.pos = pos;
+ LWGSM_MSG_VAR_REF(msg).msg.pb_write.del = 1;
+
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 60000);
+}
+
+/**
+ * \brief List entires from specific memory
+ * \param[in] mem: Memory to use to save entry. Use \ref LWGSM_MEM_CURRENT to use current memory
+ * \param[in] start_index: Start position in memory to list
+ * \param[out] entries: Pointer to array to save entries
+ * \param[in] etr: Number of entries to read
+ * \param[out] er: Pointer to output variable to save entries listed
+ * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
+ * \param[in] evt_arg: Custom argument for event callback function
+ * \param[in] blocking: Status whether command should be blocking or not
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+ */
+lwgsmr_t
+lwgsm_pb_list(lwgsm_mem_t mem, size_t start_index, lwgsm_pb_entry_t* entries, size_t etr, size_t* er,
+ const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
+
+ LWGSM_ASSERT("start_index", start_index);
+ LWGSM_ASSERT("entries != NULL", entries != NULL);
+ LWGSM_ASSERT("etr > 0", etr > 0);
+ CHECK_ENABLED();
+ LWGSM_ASSERT("check_mem() == lwgsmOK", check_mem(mem, 1) == lwgsmOK);
+
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+
+ if (er != NULL) {
+ *er = 0;
+ }
+ LWGSM_MEMSET(entries, 0x00, sizeof(*entries) * etr);/* Reset data structure */
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_CPBR;
+ if (mem == LWGSM_MEM_CURRENT) { /* Should be always false */
+ LWGSM_MSG_VAR_REF(msg).cmd = LWGSM_CMD_CPBS_GET;/* First get memory */
+ } else {
+ LWGSM_MSG_VAR_REF(msg).cmd = LWGSM_CMD_CPBS_SET;/* First set memory */
+ }
+
+ LWGSM_MSG_VAR_REF(msg).msg.pb_list.mem = mem;
+ LWGSM_MSG_VAR_REF(msg).msg.pb_list.start_index = start_index;
+ LWGSM_MSG_VAR_REF(msg).msg.pb_list.entries = entries;
+ LWGSM_MSG_VAR_REF(msg).msg.pb_list.etr = etr;
+ LWGSM_MSG_VAR_REF(msg).msg.pb_list.er = er;
+
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 60000);
+}
+
+/**
+ * \brief Search for entires with specific name from specific memory
+ * \note Search works by entry name only. Phone number search is not available
+ * \param[in] mem: Memory to use to save entry. Use \ref LWGSM_MEM_CURRENT to use current memory
+ * \param[in] search: String to search for
+ * \param[out] entries: Pointer to array to save entries
+ * \param[in] etr: Number of entries to read
+ * \param[out] er: Pointer to output variable to save entries found
+ * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
+ * \param[in] evt_arg: Custom argument for event callback function
+ * \param[in] blocking: Status whether command should be blocking or not
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+ */
+lwgsmr_t
+lwgsm_pb_search(lwgsm_mem_t mem, const char* search, lwgsm_pb_entry_t* entries, size_t etr, size_t* er,
+ const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
+
+ LWGSM_ASSERT("search != NULL", search != NULL);
+ LWGSM_ASSERT("entries != NULL", entries != NULL);
+ LWGSM_ASSERT("etr > 0", etr > 0);
+ CHECK_ENABLED(); /* Check if enabled */
+ LWGSM_ASSERT("check_mem() == mem", check_mem(mem, 1) == lwgsmOK);
+
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+
+ if (er != NULL) {
+ *er = 0;
+ }
+ LWGSM_MEMSET(entries, 0x00, sizeof(*entries) * etr);/* Reset data structure */
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_CPBF;
+ if (mem == LWGSM_MEM_CURRENT) { /* Should be always false */
+ LWGSM_MSG_VAR_REF(msg).cmd = LWGSM_CMD_CPBS_GET;/* First get memory */
+ } else {
+ LWGSM_MSG_VAR_REF(msg).cmd = LWGSM_CMD_CPBS_SET;/* First set memory */
+ }
+
+ LWGSM_MSG_VAR_REF(msg).msg.pb_search.mem = mem;
+ LWGSM_MSG_VAR_REF(msg).msg.pb_search.search = search;
+ LWGSM_MSG_VAR_REF(msg).msg.pb_search.entries = entries;
+ LWGSM_MSG_VAR_REF(msg).msg.pb_search.etr = etr;
+ LWGSM_MSG_VAR_REF(msg).msg.pb_search.er = er;
+
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 60000);
+}
+
+#endif /* LWGSM_CFG_PHONEBOOK || __DOXYGEN__ */
diff --git a/gsm_at_lib/src/gsm/gsm_ping.c b/lwgsm/src/lwgsm/lwgsm_ping.c
similarity index 78%
rename from gsm_at_lib/src/gsm/gsm_ping.c
rename to lwgsm/src/lwgsm/lwgsm_ping.c
index 9a81f328..f95c0f4b 100644
--- a/gsm_at_lib/src/gsm/gsm_ping.c
+++ b/lwgsm/src/lwgsm/lwgsm_ping.c
@@ -1,10 +1,10 @@
-/**
- * \file gsm_ping.c
+/**
+ * \file lwgsm_ping.c
* \brief PING API
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,15 +26,15 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#include "gsm/gsm_private.h"
-#include "gsm/gsm_ping.h"
-#include "gsm/gsm_mem.h"
+#include "lwgsm/lwgsm_private.h"
+#include "lwgsm/lwgsm_ping.h"
+#include "lwgsm/lwgsm_mem.h"
-#if GSM_CFG_PING || __DOXYGEN__
+#if LWGSM_CFG_PING || __DOXYGEN__
-#endif /* GSM_CFG_PING || __DOXYGEN__ */
+#endif /* LWGSM_CFG_PING || __DOXYGEN__ */
diff --git a/lwgsm/src/lwgsm/lwgsm_sim.c b/lwgsm/src/lwgsm/lwgsm_sim.c
new file mode 100644
index 00000000..a8712b48
--- /dev/null
+++ b/lwgsm/src/lwgsm/lwgsm_sim.c
@@ -0,0 +1,174 @@
+/**
+ * \file lwgsm_sim.c
+ * \brief SIM API
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM - Lightweight GSM-AT library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+#include "lwgsm/lwgsm_private.h"
+#include "lwgsm/lwgsm_sim.h"
+#include "lwgsm/lwgsm_mem.h"
+
+/**
+ * \brief Get current cached SIM state from stack
+ * \note Information is always valid, starting after successful device reset using \ref lwgsm_reset function call
+ * \return Member of \ref lwgsm_sim_state_t enumeration
+ */
+lwgsm_sim_state_t
+lwgsm_sim_get_current_state(void) {
+ lwgsm_sim_state_t state;
+ lwgsm_core_lock();
+ state = lwgsm.m.sim.state;
+ lwgsm_core_unlock();
+ return state;
+}
+
+/**
+ * \brief Enter pin code to unlock SIM
+ * \param[in] pin: Pin code in string format
+ * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
+ * \param[in] evt_arg: Custom argument for event callback function
+ * \param[in] blocking: Status whether command should be blocking or not
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
+ */
+lwgsmr_t
+lwgsm_sim_pin_enter(const char* pin,
+ const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
+
+ LWGSM_ASSERT("pin != NULL", pin != NULL);
+
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_CPIN_SET;
+ LWGSM_MSG_VAR_REF(msg).cmd = LWGSM_CMD_CPIN_GET;
+ LWGSM_MSG_VAR_REF(msg).msg.cpin_enter.pin = pin;
+
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 30000);
+}
+
+/**
+ * \brief Add pin number to open SIM card
+ * \note Use this function only if your SIM card doesn't have PIN code.
+ * If you wish to change current pin, use \ref lwgsm_sim_pin_change instead
+ * \param[in] pin: Current SIM pin code
+ * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
+ * \param[in] evt_arg: Custom argument for event callback function
+ * \param[in] blocking: Status whether command should be blocking or not
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
+ */
+lwgsmr_t
+lwgsm_sim_pin_add(const char* pin,
+ const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
+
+ LWGSM_ASSERT("pin != NULL", pin != NULL);
+
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_CPIN_ADD;
+ LWGSM_MSG_VAR_REF(msg).msg.cpin_add.pin = pin;
+
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 10000);
+}
+
+/**
+ * \brief Change current pin code
+ * \param[in] pin: Current pin code
+ * \param[in] new_pin: New pin code
+ * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
+ * \param[in] evt_arg: Custom argument for event callback function
+ * \param[in] blocking: Status whether command should be blocking or not
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
+ */
+lwgsmr_t
+lwgsm_sim_pin_change(const char* pin, const char* new_pin,
+ const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
+
+ LWGSM_ASSERT("pin != NULL", pin != NULL);
+ LWGSM_ASSERT("new_pin != NULL", new_pin != NULL);
+
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_CPIN_CHANGE;
+ LWGSM_MSG_VAR_REF(msg).msg.cpin_change.current_pin = pin;
+ LWGSM_MSG_VAR_REF(msg).msg.cpin_change.new_pin = new_pin;
+
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 10000);
+}
+
+/**
+ * \brief Remove pin code from SIM
+ * \param[in] pin: Current pin code
+ * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
+ * \param[in] evt_arg: Custom argument for event callback function
+ * \param[in] blocking: Status whether command should be blocking or not
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
+ */
+lwgsmr_t
+lwgsm_sim_pin_remove(const char* pin,
+ const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
+
+ LWGSM_ASSERT("pin != NULL", pin != NULL);
+
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_CPIN_REMOVE;
+ LWGSM_MSG_VAR_REF(msg).msg.cpin_remove.pin = pin;
+
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 10000);
+}
+
+/**
+ * \brief Enter PUK code and new PIN to unlock SIM card
+ * \param[in] puk: PUK code associated with SIM card
+ * \param[in] new_pin: New PIN code to use
+ * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
+ * \param[in] evt_arg: Custom argument for event callback function
+ * \param[in] blocking: Status whether command should be blocking or not
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
+ */
+lwgsmr_t
+lwgsm_sim_puk_enter(const char* puk, const char* new_pin,
+ const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
+
+ LWGSM_ASSERT("puk != NULL", puk != NULL);
+ LWGSM_ASSERT("new_pin != NULL", new_pin != NULL);
+
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_CPUK_SET;
+ LWGSM_MSG_VAR_REF(msg).msg.cpuk_enter.puk = puk;
+ LWGSM_MSG_VAR_REF(msg).msg.cpuk_enter.pin = new_pin;
+
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 10000);
+}
diff --git a/lwgsm/src/lwgsm/lwgsm_sms.c b/lwgsm/src/lwgsm/lwgsm_sms.c
new file mode 100644
index 00000000..41016ee5
--- /dev/null
+++ b/lwgsm/src/lwgsm/lwgsm_sms.c
@@ -0,0 +1,346 @@
+/**
+ * \file lwgsm_sms.c
+ * \brief SMS API
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM - Lightweight GSM-AT library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+#include "lwgsm/lwgsm_private.h"
+#include "lwgsm/lwgsm_sms.h"
+#include "lwgsm/lwgsm_mem.h"
+
+#if LWGSM_CFG_SMS || __DOXYGEN__
+
+#define LWGSM_SMS_OPERATION_IDX 0 /*!< Operation index for memory array (read, delete, list) */
+#define LWGSM_SMS_SEND_IDX 1 /*!< Send index for memory array */
+#define LWGSM_SMS_RECEIVE_IDX 2 /*!< Receive index for memory array */
+
+#if !__DOXYGEN__
+#define CHECK_ENABLED() if (!(check_enabled() == lwgsmOK)) { return lwgsmERRNOTENABLED; }
+#define CHECK_READY() if (!(check_ready() == lwgsmOK)) { return lwgsmERR; }
+#endif /* !__DOXYGEN__ */
+
+/**
+ * \brief Check if sms is enabled
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+ */
+static lwgsmr_t
+check_enabled(void) {
+ lwgsmr_t res;
+ lwgsm_core_lock();
+ res = lwgsm.m.sms.enabled ? lwgsmOK : lwgsmERR;
+ lwgsm_core_unlock();
+ return res;
+}
+
+/**
+ * \brief Check if SMS is available
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
+ */
+static lwgsmr_t
+check_ready(void) {
+ lwgsmr_t res;
+ lwgsm_core_lock();
+ res = lwgsm.m.sms.ready ? lwgsmOK : lwgsmERR;
+ lwgsm_core_unlock();
+ return res;
+}
+
+/**
+ * \brief Check if input memory is available in modem
+ * \param[in] mem: Memory to test
+ * \param[in] can_curr: Flag indicates if \ref LWGSM_MEM_CURRENT option can be used
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+ */
+static lwgsmr_t
+check_sms_mem(lwgsm_mem_t mem, uint8_t can_curr) {
+ lwgsmr_t res = lwgsmERRMEM;
+ lwgsm_core_lock();
+ if ((mem < LWGSM_MEM_END && lwgsm.m.sms.mem[LWGSM_SMS_OPERATION_IDX].mem_available & (1 << (uint32_t)mem)) ||
+ (can_curr && mem == LWGSM_MEM_CURRENT)) {
+ res = lwgsmOK;
+ }
+ lwgsm_core_unlock();
+ return res;
+}
+
+/**
+ * \brief Enable SMS functionality
+ * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
+ * \param[in] evt_arg: Custom argument for event callback function
+ * \param[in] blocking: Status whether command should be blocking or not
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+ */
+lwgsmr_t
+lwgsm_sms_enable(const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
+
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_SMS_ENABLE;
+ LWGSM_MSG_VAR_REF(msg).cmd = LWGSM_CMD_CPMS_GET_OPT;
+
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 60000);
+}
+
+/**
+ * \brief Disable SMS functionality
+ * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
+ * \param[in] evt_arg: Custom argument for event callback function
+ * \param[in] blocking: Status whether command should be blocking or not
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+ */
+lwgsmr_t
+lwgsm_sms_disable(const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ lwgsm_core_lock();
+ lwgsm.m.sms.enabled = 0;
+ if (evt_fn != NULL) {
+ evt_fn(lwgsmOK, evt_arg);
+ }
+ lwgsm_core_unlock();
+ LWGSM_UNUSED(blocking);
+ return lwgsmOK;
+}
+
+/**
+ * \brief Send SMS text to phone number
+ * \param[in] num: String number
+ * \param[in] text: Text to send. Maximal `160` characters
+ * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
+ * \param[in] evt_arg: Custom argument for event callback function
+ * \param[in] blocking: Status whether command should be blocking or not
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+ */
+lwgsmr_t
+lwgsm_sms_send(const char* num, const char* text,
+ const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
+
+ LWGSM_ASSERT("num != NULL && num[0] > 0", num != NULL && num[0] > 0);
+ LWGSM_ASSERT("text != NULL && text[0] > 0 && strlen(text) <= 160", text != NULL && text[0] > 0 && strlen(text) <= 160);
+ CHECK_ENABLED(); /* Check if enabled */
+ CHECK_READY(); /* Check if ready */
+
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_CMGS;
+ LWGSM_MSG_VAR_REF(msg).cmd = LWGSM_CMD_CMGF;
+ LWGSM_MSG_VAR_REF(msg).msg.sms_send.num = num;
+ LWGSM_MSG_VAR_REF(msg).msg.sms_send.text = text;
+ LWGSM_MSG_VAR_REF(msg).msg.sms_send.format = 1; /* Send as plain text */
+
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 60000);
+}
+
+/**
+ * \brief Read SMS entry at specific memory and position
+ * \param[in] mem: Memory used to read message from
+ * \param[in] pos: Position number in memory to read
+ * \param[out] entry: Pointer to SMS entry structure to fill data to
+ * \param[in] update: Flag indicates update. Set to `1` to change `UNREAD` messages to `READ` or `0` to leave as is
+ * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
+ * \param[in] evt_arg: Custom argument for event callback function
+ * \param[in] blocking: Status whether command should be blocking or not
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+ */
+lwgsmr_t
+lwgsm_sms_read(lwgsm_mem_t mem, size_t pos, lwgsm_sms_entry_t* entry, uint8_t update,
+ const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
+
+ LWGSM_ASSERT("entry != NULL", entry != NULL);
+ CHECK_ENABLED(); /* Check if enabled */
+ CHECK_READY(); /* Check if ready */
+ LWGSM_ASSERT("check_sms_mem() == lwgsmOK", check_sms_mem(mem, 1) == lwgsmOK);
+
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+
+ LWGSM_MEMSET(entry, 0x00, sizeof(*entry)); /* Reset data structure */
+
+ entry->mem = mem; /* Set memory */
+ entry->pos = pos; /* Set device position */
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_CMGR;
+ if (mem == LWGSM_MEM_CURRENT) { /* Should be always false */
+ LWGSM_MSG_VAR_REF(msg).cmd = LWGSM_CMD_CPMS_GET;/* First get memory */
+ } else {
+ LWGSM_MSG_VAR_REF(msg).cmd = LWGSM_CMD_CPMS_SET;/* First set memory */
+ }
+ LWGSM_MSG_VAR_REF(msg).msg.sms_read.mem = mem;
+ LWGSM_MSG_VAR_REF(msg).msg.sms_read.pos = pos;
+ LWGSM_MSG_VAR_REF(msg).msg.sms_read.entry = entry;
+ LWGSM_MSG_VAR_REF(msg).msg.sms_read.update = update;
+ LWGSM_MSG_VAR_REF(msg).msg.sms_read.format = 1; /* Send as plain text */
+
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 60000);
+}
+
+/**
+ * \brief Delete SMS entry at specific memory and position
+ * \param[in] mem: Memory used to read message from
+ * \param[in] pos: Position number in memory to read
+ * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
+ * \param[in] evt_arg: Custom argument for event callback function
+ * \param[in] blocking: Status whether command should be blocking or not
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+ */
+lwgsmr_t
+lwgsm_sms_delete(lwgsm_mem_t mem, size_t pos,
+ const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
+
+ CHECK_ENABLED(); /* Check if enabled */
+ CHECK_READY(); /* Check if ready */
+ LWGSM_ASSERT("check_sms_mem() == lwgsmOK", check_sms_mem(mem, 1) == lwgsmOK);
+
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_CMGD;
+ if (mem == LWGSM_MEM_CURRENT) { /* Should be always false */
+ LWGSM_MSG_VAR_REF(msg).cmd = LWGSM_CMD_CPMS_GET;/* First get memory */
+ } else {
+ LWGSM_MSG_VAR_REF(msg).cmd = LWGSM_CMD_CPMS_SET;/* First set memory */
+ }
+ LWGSM_MSG_VAR_REF(msg).msg.sms_delete.mem = mem;
+ LWGSM_MSG_VAR_REF(msg).msg.sms_delete.pos = pos;
+
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 1000);
+}
+
+/**
+ * \brief Delete all SMS entries with specific status
+ * \param[in] status: SMS status. This parameter can be one of all possible types in \ref lwgsm_sms_status_t enumeration
+ * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
+ * \param[in] evt_arg: Custom argument for event callback function
+ * \param[in] blocking: Status whether command should be blocking or not
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+ */
+lwgsmr_t
+lwgsm_sms_delete_all(lwgsm_sms_status_t status,
+ const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
+
+ CHECK_ENABLED(); /* Check if enabled */
+ CHECK_READY(); /* Check if ready */
+
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_CMGDA;
+ LWGSM_MSG_VAR_REF(msg).cmd = LWGSM_CMD_CMGF;/* By default format = 1 */
+ LWGSM_MSG_VAR_REF(msg).msg.sms_delete_all.status = status;
+
+ /* This command may take a while */
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 60000);
+}
+
+/**
+ * \brief List SMS from SMS memory
+ * \param[in] mem: Memory to read entries from. Use \ref LWGSM_MEM_CURRENT to read from current memory
+ * \param[in] stat: SMS status to read, either `read`, `unread`, `sent`, `unsent` or `all`
+ * \param[out] entries: Pointer to array to save SMS entries
+ * \param[in] etr: Number of entries to read
+ * \param[out] er: Pointer to output variable to save number of entries in array
+ * \param[in] update: Flag indicates update. Set to `1` to change `UNREAD` messages to `READ` or `0` to leave as is
+ * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
+ * \param[in] evt_arg: Custom argument for event callback function
+ * \param[in] blocking: Status whether command should be blocking or not
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+ */
+lwgsmr_t
+lwgsm_sms_list(lwgsm_mem_t mem, lwgsm_sms_status_t stat, lwgsm_sms_entry_t* entries, size_t etr, size_t* er, uint8_t update,
+ const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
+
+ LWGSM_ASSERT("entires != NULL", entries != NULL);
+ LWGSM_ASSERT("etr > 0", etr > 0);
+ CHECK_ENABLED(); /* Check if enabled */
+ CHECK_READY(); /* Check if ready */
+ LWGSM_ASSERT("check_sms_mem() == lwgsmOK", check_sms_mem(mem, 1) == lwgsmOK);
+
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+
+ if (er != NULL) {
+ *er = 0;
+ }
+ LWGSM_MEMSET(entries, 0x00, sizeof(*entries) * etr);/* Reset data structure */
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_CMGL;
+ if (mem == LWGSM_MEM_CURRENT) { /* Should be always false */
+ LWGSM_MSG_VAR_REF(msg).cmd = LWGSM_CMD_CPMS_GET;/* First get memory */
+ } else {
+ LWGSM_MSG_VAR_REF(msg).cmd = LWGSM_CMD_CPMS_SET;/* First set memory */
+ }
+ LWGSM_MSG_VAR_REF(msg).msg.sms_list.mem = mem;
+ LWGSM_MSG_VAR_REF(msg).msg.sms_list.status = stat;
+ LWGSM_MSG_VAR_REF(msg).msg.sms_list.entries = entries;
+ LWGSM_MSG_VAR_REF(msg).msg.sms_list.etr = etr;
+ LWGSM_MSG_VAR_REF(msg).msg.sms_list.er = er;
+ LWGSM_MSG_VAR_REF(msg).msg.sms_list.update = update;
+ LWGSM_MSG_VAR_REF(msg).msg.sms_list.format = 1; /* Send as plain text */
+
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 60000);
+}
+
+/**
+ * \brief Set preferred storage for SMS
+ * \param[in] mem1: Preferred memory for read/delete SMS operations. Use \ref LWGSM_MEM_CURRENT to keep it as is
+ * \param[in] mem2: Preferred memory for sent/write SMS operations. Use \ref LWGSM_MEM_CURRENT to keep it as is
+ * \param[in] mem3: Preferred memory for received SMS entries. Use \ref LWGSM_MEM_CURRENT to keep it as is
+ * \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
+ * \param[in] evt_arg: Custom argument for event callback function
+ * \param[in] blocking: Status whether command should be blocking or not
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+ */
+lwgsmr_t
+lwgsm_sms_set_preferred_storage(lwgsm_mem_t mem1, lwgsm_mem_t mem2, lwgsm_mem_t mem3,
+ const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
+
+ CHECK_ENABLED(); /* Check if enabled */
+ CHECK_READY(); /* Check if ready */
+ LWGSM_ASSERT("check_sms_mem(1) == lwgsmOK", check_sms_mem(mem1, 1) == lwgsmOK);
+ LWGSM_ASSERT("check_sms_mem(2) == lwgsmOK", check_sms_mem(mem2, 1) == lwgsmOK);
+ LWGSM_ASSERT("check_sms_mem(3) == lwgsmOK", check_sms_mem(mem3, 1) == lwgsmOK);
+
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_CPMS_SET;
+
+ /* In case any of memories is set to current, read current status first from device */
+ if (mem1 == LWGSM_MEM_CURRENT || mem2 == LWGSM_MEM_CURRENT || mem3 == LWGSM_MEM_CURRENT) {
+ LWGSM_MSG_VAR_REF(msg).cmd = LWGSM_CMD_CPMS_GET;
+ }
+ LWGSM_MSG_VAR_REF(msg).msg.sms_memory.mem[0] = mem1;
+ LWGSM_MSG_VAR_REF(msg).msg.sms_memory.mem[1] = mem2;
+ LWGSM_MSG_VAR_REF(msg).msg.sms_memory.mem[2] = mem3;
+
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 60000);
+}
+
+#endif /* LWGSM_CFG_SMS || __DOXYGEN__ */
diff --git a/gsm_at_lib/src/gsm/gsm_threads.c b/lwgsm/src/lwgsm/lwgsm_threads.c
similarity index 55%
rename from gsm_at_lib/src/gsm/gsm_threads.c
rename to lwgsm/src/lwgsm/lwgsm_threads.c
index d421c5f3..41d7eaeb 100644
--- a/gsm_at_lib/src/gsm/gsm_threads.c
+++ b/lwgsm/src/lwgsm/lwgsm_threads.c
@@ -1,10 +1,10 @@
/**
- * \file gsm_threads.c
+ * \file lwgsm_threads.c
* \brief OS threads implementations
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,47 +26,47 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#include "gsm/gsm_private.h"
-#include "gsm/gsm_threads.h"
-#include "gsm/gsm_parser.h"
-#include "gsm/gsm_int.h"
-#include "gsm/gsm_timeout.h"
-#include "gsm/gsm.h"
-#include "gsm/gsm_mem.h"
-#include "system/gsm_sys.h"
+#include "lwgsm/lwgsm_private.h"
+#include "lwgsm/lwgsm_threads.h"
+#include "lwgsm/lwgsm_parser.h"
+#include "lwgsm/lwgsm_int.h"
+#include "lwgsm/lwgsm_timeout.h"
+#include "lwgsm/lwgsm.h"
+#include "lwgsm/lwgsm_mem.h"
+#include "system/lwgsm_sys.h"
/**
* \brief User thread to process input packets from API functions
* \param[in] arg: User argument. Semaphore to release when thread starts
*/
void
-gsm_thread_produce(void* const arg) {
- gsm_sys_sem_t* sem = arg;
- gsm_t* e = &gsm;
- gsm_msg_t* msg;
- gsmr_t res;
+lwgsm_thread_produce(void* const arg) {
+ lwgsm_sys_sem_t* sem = arg;
+ lwgsm_t* e = &lwgsm;
+ lwgsm_msg_t* msg;
+ lwgsmr_t res;
uint32_t time;
/* Thread is running, unlock semaphore */
- if (gsm_sys_sem_isvalid(sem)) {
- gsm_sys_sem_release(sem); /* Release semaphore */
+ if (lwgsm_sys_sem_isvalid(sem)) {
+ lwgsm_sys_sem_release(sem); /* Release semaphore */
}
- gsm_core_lock();
+ lwgsm_core_lock();
while (1) {
- gsm_core_unlock();
+ lwgsm_core_unlock();
do {
- time = gsm_sys_mbox_get(&e->mbox_producer, (void **)&msg, 0); /* Get message from queue */
- } while (time == GSM_SYS_TIMEOUT || msg == NULL);
- GSM_THREAD_PRODUCER_HOOK(); /* Execute producer thread hook */
- gsm_core_lock();
+ time = lwgsm_sys_mbox_get(&e->mbox_producer, (void**)&msg, 0); /* Get message from queue */
+ } while (time == LWGSM_SYS_TIMEOUT || msg == NULL);
+ LWGSM_THREAD_PRODUCER_HOOK(); /* Execute producer thread hook */
+ lwgsm_core_lock();
- res = gsmOK; /* Start with OK */
+ res = lwgsmOK; /* Start with OK */
e->msg = msg; /* Set message handle */
/*
@@ -75,53 +75,53 @@ gsm_thread_produce(void* const arg) {
* if device present flag changes
*/
if (!e->status.f.dev_present) {
- res = gsmERRNODEVICE;
+ res = lwgsmERRNODEVICE;
}
/* For reset message, we can have delay! */
- if (res == gsmOK && msg->cmd_def == GSM_CMD_RESET) {
+ if (res == lwgsmOK && msg->cmd_def == LWGSM_CMD_RESET) {
if (msg->msg.reset.delay > 0) {
- gsm_delay(msg->msg.reset.delay);
+ lwgsm_delay(msg->msg.reset.delay);
}
- gsmi_reset_everything(1); /* Reset stack before trying to reset */
+ lwgsmi_reset_everything(1); /* Reset stack before trying to reset */
}
/*
* Try to call function to process this message
* Usually it should be function to transmit data to AT port
*/
- if (res == gsmOK && msg->fn != NULL) { /* Check for callback processing function */
- /*
- * Obtain semaphore
+ if (res == lwgsmOK && msg->fn != NULL) {/* Check for callback processing function */
+ /*
+ * Obtain semaphore
* This code should not block at any point.
- * If it blocks, severe problems occurred and program should
+ * If it blocks, severe problems occurred and program should
* immediate terminate
*/
- gsm_core_unlock();
- gsm_sys_sem_wait(&e->sem_sync, 0); /* First call */
- gsm_core_lock();
+ lwgsm_core_unlock();
+ lwgsm_sys_sem_wait(&e->sem_sync, 0);/* First call */
+ lwgsm_core_lock();
res = msg->fn(msg); /* Process this message, check if command started at least */
- time = ~GSM_SYS_TIMEOUT; /* Reset time */
- if (res == gsmOK) { /* We have valid data and data were sent */
- gsm_core_unlock();
- time = gsm_sys_sem_wait(&e->sem_sync, msg->block_time); /* Second call; Wait for synchronization semaphore from processing thread or timeout */
- gsm_core_lock();
- if (time == GSM_SYS_TIMEOUT) { /* Sync timeout occurred? */
- res = gsmTIMEOUT; /* Timeout on command */
+ time = ~LWGSM_SYS_TIMEOUT; /* Reset time */
+ if (res == lwgsmOK) { /* We have valid data and data were sent */
+ lwgsm_core_unlock();
+ time = lwgsm_sys_sem_wait(&e->sem_sync, msg->block_time); /* Second call; Wait for synchronization semaphore from processing thread or timeout */
+ lwgsm_core_lock();
+ if (time == LWGSM_SYS_TIMEOUT) {/* Sync timeout occurred? */
+ res = lwgsmTIMEOUT; /* Timeout on command */
}
}
/* Notify application on command timeout */
- if (res == gsmTIMEOUT) {
- gsmi_send_cb(GSM_EVT_CMD_TIMEOUT);
+ if (res == lwgsmTIMEOUT) {
+ lwgsmi_send_cb(LWGSM_EVT_CMD_TIMEOUT);
}
- GSM_DEBUGW(GSM_CFG_DBG_THREAD | GSM_DBG_TYPE_TRACE | GSM_DBG_LVL_SEVERE,
- res == gsmTIMEOUT,
- "[THREAD] Timeout in produce thread waiting for command to finish in process thread\r\n");
- GSM_DEBUGW(GSM_CFG_DBG_THREAD | GSM_DBG_TYPE_TRACE | GSM_DBG_LVL_SEVERE,
- res != gsmOK && res != gsmTIMEOUT,
- "[THREAD] Could not start execution for command %d\r\n", (int)msg->cmd);
+ LWGSM_DEBUGW(LWGSM_CFG_DBG_THREAD | LWGSM_DBG_TYPE_TRACE | LWGSM_DBG_LVL_SEVERE,
+ res == lwgsmTIMEOUT,
+ "[THREAD] Timeout in produce thread waiting for command to finish in process thread\r\n");
+ LWGSM_DEBUGW(LWGSM_CFG_DBG_THREAD | LWGSM_DBG_TYPE_TRACE | LWGSM_DBG_LVL_SEVERE,
+ res != lwgsmOK && res != lwgsmTIMEOUT,
+ "[THREAD] Could not start execution for command %d\r\n", (int)msg->cmd);
/*
* Manually release semaphore in all cases:
@@ -139,25 +139,25 @@ gsm_thread_produce(void* const arg) {
* it would not be possible to start a new command after,
* because semaphore would be still locked
*/
- gsm_sys_sem_release(&e->sem_sync);
+ lwgsm_sys_sem_release(&e->sem_sync);
} else {
- if (res == gsmOK) {
- res = gsmERR; /* Simply set error message */
+ if (res == lwgsmOK) {
+ res = lwgsmERR; /* Simply set error message */
}
}
- if (res != gsmOK) {
+ if (res != lwgsmOK) {
/* Process global callbacks */
- gsmi_process_events_for_timeout_or_error(msg, res);
+ lwgsmi_process_events_for_timeout_or_error(msg, res);
msg->res = res; /* Save response */
}
-#if GSM_CFG_USE_API_FUNC_EVT
+#if LWGSM_CFG_USE_API_FUNC_EVT
/* Send event function to user */
if (msg->evt_fn != NULL) {
msg->evt_fn(msg->res, msg->evt_arg);/* Send event with user argument */
}
-#endif /* GSM_CFG_USE_API_FUNC_EVT */
+#endif /* LWGSM_CFG_USE_API_FUNC_EVT */
/*
* In case message is blocking,
@@ -165,9 +165,9 @@ gsm_thread_produce(void* const arg) {
* otherwise directly free memory of message structure
*/
if (msg->is_blocking) {
- gsm_sys_sem_release(&msg->sem);
+ lwgsm_sys_sem_release(&msg->sem);
} else {
- GSM_MSG_VAR_FREE(msg);
+ LWGSM_MSG_VAR_FREE(msg);
}
e->msg = NULL;
}
@@ -180,33 +180,33 @@ gsm_thread_produce(void* const arg) {
* in correct time order as it is never blocked by user command
*
* \param[in] arg: User argument. Semaphore to release when thread starts
- * \sa GSM_CFG_INPUT_USE_PROCESS
+ * \sa LWGSM_CFG_INPUT_USE_PROCESS
*/
void
-gsm_thread_process(void* const arg) {
- gsm_sys_sem_t* sem = arg;
- gsm_t* e = &gsm;
- gsm_msg_t* msg;
+lwgsm_thread_process(void* const arg) {
+ lwgsm_sys_sem_t* sem = arg;
+ lwgsm_t* e = &lwgsm;
+ lwgsm_msg_t* msg;
uint32_t time;
/* Thread is running, unlock semaphore */
- if (gsm_sys_sem_isvalid(sem)) {
- gsm_sys_sem_release(sem); /* Release semaphore */
+ if (lwgsm_sys_sem_isvalid(sem)) {
+ lwgsm_sys_sem_release(sem); /* Release semaphore */
}
-#if !GSM_CFG_INPUT_USE_PROCESS
- gsm_core_lock();
+#if !LWGSM_CFG_INPUT_USE_PROCESS
+ lwgsm_core_lock();
while (1) {
- gsm_core_unlock();
- time = gsmi_get_from_mbox_with_timeout_checks(&e->mbox_process, (void **)&msg, 10);
- GSM_THREAD_PROCESS_HOOK(); /* Execute process thread hook */
- gsm_core_lock();
+ lwgsm_core_unlock();
+ time = lwgsmi_get_from_mbox_with_timeout_checks(&e->mbox_process, (void**)&msg, 10);
+ LWGSM_THREAD_PROCESS_HOOK(); /* Execute process thread hook */
+ lwgsm_core_lock();
- if (time == GSM_SYS_TIMEOUT || msg == NULL) {
- GSM_UNUSED(time); /* Unused variable */
+ if (time == LWGSM_SYS_TIMEOUT || msg == NULL) {
+ LWGSM_UNUSED(time); /* Unused variable */
}
- gsmi_process_buffer(); /* Process input data */
-#else /* GSM_CFG_INPUT_USE_PROCESS */
+ lwgsmi_process_buffer(); /* Process input data */
+#else /* LWGSM_CFG_INPUT_USE_PROCESS */
while (1) {
/*
* Check for next timeout event only here
@@ -214,9 +214,9 @@ gsm_thread_process(void* const arg) {
* If there are no timeouts to process, we can wait unlimited time.
* In case new timeout occurs, thread will wake up by writing new element to mbox process queue
*/
- time = gsmi_get_from_mbox_with_timeout_checks(&e->mbox_process, (void **)&msg, 0);
- GSM_THREAD_PROCESS_HOOK(); /* Execute process thread hook */
- GSM_UNUSED(time);
-#endif /* !GSM_CFG_INPUT_USE_PROCESS */
+ time = lwgsmi_get_from_mbox_with_timeout_checks(&e->mbox_process, (void**)&msg, 0);
+ LWGSM_THREAD_PROCESS_HOOK(); /* Execute process thread hook */
+ LWGSM_UNUSED(time);
+#endif /* !LWGSM_CFG_INPUT_USE_PROCESS */
}
}
diff --git a/gsm_at_lib/src/gsm/gsm_timeout.c b/lwgsm/src/lwgsm/lwgsm_timeout.c
similarity index 75%
rename from gsm_at_lib/src/gsm/gsm_timeout.c
rename to lwgsm/src/lwgsm/lwgsm_timeout.c
index da13f2e2..b3cedc2c 100644
--- a/gsm_at_lib/src/gsm/gsm_timeout.c
+++ b/lwgsm/src/lwgsm/lwgsm_timeout.c
@@ -1,10 +1,10 @@
-/**
- * \file gsm_timeout.c
+/**
+ * \file lwgsm_timeout.c
* \brief Timeout manager
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,16 +26,16 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#include "gsm/gsm_private.h"
-#include "gsm/gsm_timeout.h"
-#include "gsm/gsm_mem.h"
+#include "lwgsm/lwgsm_private.h"
+#include "lwgsm/lwgsm_timeout.h"
+#include "lwgsm/lwgsm_mem.h"
-static gsm_timeout_t* first_timeout;
+static lwgsm_timeout_t* first_timeout;
static uint32_t last_timeout_time;
/**
@@ -48,9 +48,9 @@ get_next_timeout_diff(void) {
if (first_timeout == NULL) {
return 0xFFFFFFFF;
}
- diff = gsm_sys_now() - last_timeout_time; /* Get difference between current time and last process time */
+ diff = lwgsm_sys_now() - last_timeout_time; /* Get difference between current time and last process time */
if (diff >= first_timeout->time) { /* Are we over already? */
- return 0; /* We have to immediatelly process this timeout */
+ return 0; /* We have to immediately process this timeout */
}
return first_timeout->time - diff; /* Return remaining time for sleep */
}
@@ -62,7 +62,7 @@ static void
process_next_timeout(void) {
uint32_t time;
- time = gsm_sys_now();
+ time = lwgsm_sys_now();
/*
* Before calling timeout callback, update variable
@@ -72,7 +72,7 @@ process_next_timeout(void) {
last_timeout_time = time; /* Reset variable when we were last processed */
if (first_timeout != NULL) {
- gsm_timeout_t* to = first_timeout;
+ lwgsm_timeout_t* to = first_timeout;
/*
* Before calling callback remove current timeout from list
@@ -81,7 +81,7 @@ process_next_timeout(void) {
*/
first_timeout = first_timeout->next; /* Set next timeout on a list as first timeout */
to->fn(to->arg); /* Call user callback function */
- gsm_mem_free_s((void **)&to);
+ lwgsm_mem_free_s((void**)&to);
}
}
@@ -93,17 +93,17 @@ process_next_timeout(void) {
* \return Time in milliseconds required for next message
*/
uint32_t
-gsmi_get_from_mbox_with_timeout_checks(gsm_sys_mbox_t* b, void** m, uint32_t timeout) {
+lwgsmi_get_from_mbox_with_timeout_checks(lwgsm_sys_mbox_t* b, void** m, uint32_t timeout) {
uint32_t wait_time;
do {
if (first_timeout == NULL) { /* We have no timeouts ready? */
- return gsm_sys_mbox_get(b, m, timeout); /* Get entry from message queue */
+ return lwgsm_sys_mbox_get(b, m, timeout); /* Get entry from message queue */
}
wait_time = get_next_timeout_diff(); /* Get time to wait for next timeout execution */
- if (wait_time == 0 || gsm_sys_mbox_get(b, m, wait_time) == GSM_SYS_TIMEOUT) {
- gsm_core_lock();
+ if (wait_time == 0 || lwgsm_sys_mbox_get(b, m, wait_time) == LWGSM_SYS_TIMEOUT) {
+ lwgsm_core_lock();
process_next_timeout(); /* Process with next timeout */
- gsm_core_unlock();
+ lwgsm_core_unlock();
}
break;
} while (1);
@@ -115,31 +115,30 @@ gsmi_get_from_mbox_with_timeout_checks(gsm_sys_mbox_t* b, void** m, uint32_t tim
* \param[in] time: Time in units of milliseconds for timeout execution
* \param[in] fn: Callback function to call when timeout expires
* \param[in] arg: Pointer to user specific argument to call when timeout callback function is executed
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_timeout_add(uint32_t time, gsm_timeout_fn fn, void* arg) {
- gsm_timeout_t* to;
- uint32_t now, diff = 0;
+lwgsmr_t
+lwgsm_timeout_add(uint32_t time, lwgsm_timeout_fn fn, void* arg) {
+ lwgsm_timeout_t* to;
+ uint32_t now;
- GSM_ASSERT("fn != NULL", fn != NULL);
+ LWGSM_ASSERT("fn != NULL", fn != NULL);
- to = gsm_mem_calloc(1, sizeof(*to)); /* Allocate memory for timeout structure */
+ to = lwgsm_mem_calloc(1, sizeof(*to)); /* Allocate memory for timeout structure */
if (to == NULL) {
- return gsmERR;
+ return lwgsmERR;
}
- gsm_core_lock();
- now = gsm_sys_now(); /* Get current time */
+ lwgsm_core_lock();
+ now = lwgsm_sys_now(); /* Get current time */
if (first_timeout != NULL) {
- diff = now - last_timeout_time; /* Get difference between current and last processed time */
+ /*
+ * Since we want timeout value to start from NOW,
+ * we have to add time when we last processed our timeouts
+ */
+ time += now - last_timeout_time; /* Add difference between now and last processed time */
}
-
- /*
- * Since we want timeout value to start from NOW,
- * we have to add time when we last processed our timeouts
- */
- to->time = time + diff;
+ to->time = time;
to->arg = arg;
to->fn = fn;
@@ -161,7 +160,7 @@ gsm_timeout_add(uint32_t time, gsm_timeout_fn fn, void* arg) {
to->next = first_timeout; /* Set first timeout as next of new one */
first_timeout = to; /* Set new timeout as first */
} else { /* Go somewhere in between current list */
- for (gsm_timeout_t* t = first_timeout; t != NULL; t = t->next) {
+ for (lwgsm_timeout_t* t = first_timeout; t != NULL; t = t->next) {
to->time -= t->time; /* Decrease new timeout time by time in a linked list */
/*
* Enter between 2 entries on a list in case:
@@ -182,23 +181,23 @@ gsm_timeout_add(uint32_t time, gsm_timeout_fn fn, void* arg) {
}
}
}
- gsm_core_unlock();
- gsm_sys_mbox_putnow(&gsm.mbox_process, NULL); /* Insert dummy value to wakeup process thread */
- return gsmOK;
+ lwgsm_core_unlock();
+ lwgsm_sys_mbox_putnow(&lwgsm.mbox_process, NULL); /* Insert dummy value to wakeup process thread */
+ return lwgsmOK;
}
/**
* \brief Remove callback from timeout list
* \param[in] fn: Callback function to identify timeout to remove
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_timeout_remove(gsm_timeout_fn fn) {
+lwgsmr_t
+lwgsm_timeout_remove(lwgsm_timeout_fn fn) {
uint8_t success = 0;
- gsm_core_lock();
- for (gsm_timeout_t* t = first_timeout, *t_prev = NULL; t != NULL;
- t_prev = t, t = t->next) { /* Check all entries */
+ lwgsm_core_lock();
+ for (lwgsm_timeout_t* t = first_timeout, *t_prev = NULL; t != NULL;
+ t_prev = t, t = t->next) { /* Check all entries */
if (t->fn == fn) { /* Do we have a match from callback point of view? */
/*
@@ -221,11 +220,11 @@ gsm_timeout_remove(gsm_timeout_fn fn) {
} else {
first_timeout = t->next;
}
- gsm_mem_free_s((void **)&t);
+ lwgsm_mem_free_s((void**)&t);
success = 1;
break;
}
}
- gsm_core_unlock();
- return success ? gsmOK : gsmERR;
+ lwgsm_core_unlock();
+ return success ? lwgsmOK : lwgsmERR;
}
diff --git a/gsm_at_lib/src/gsm/gsm_unicode.c b/lwgsm/src/lwgsm/lwgsm_unicode.c
similarity index 73%
rename from gsm_at_lib/src/gsm/gsm_unicode.c
rename to lwgsm/src/lwgsm/lwgsm_unicode.c
index b928cf39..3f12b2df 100644
--- a/gsm_at_lib/src/gsm/gsm_unicode.c
+++ b/lwgsm/src/lwgsm/lwgsm_unicode.c
@@ -1,10 +1,10 @@
-/**
- * \file gsm_unicode.c
+/**
+ * \file lwgsm_unicode.c
* \brief Unicode support
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,31 +26,31 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#include "gsm/gsm_private.h"
-#include "gsm/gsm_unicode.h"
+#include "lwgsm/lwgsm_private.h"
+#include "lwgsm/lwgsm_unicode.h"
/**
* \brief Decode single character for unicode (UTF-8 only) format
* \param[in,out] s: Pointer to unicode decode control structure
* \param[in] c: UTF-8 character sequence to test for device
- * \retval gsmOK: Function succedded, there is a valid UTF-8 sequence
- * \retval gsmINPROG: Function continues well but expects some more data to finish sequence
- * \retval gsmERR: Error in UTF-8 sequence
+ * \retval lwgsmOK: Function succedded, there is a valid UTF-8 sequence
+ * \retval lwgsmINPROG: Function continues well but expects some more data to finish sequence
+ * \retval lwgsmERR: Error in UTF-8 sequence
*/
-gsmr_t
-gsmi_unicode_decode(gsm_unicode_t* s, uint8_t c) {
+lwgsmr_t
+lwgsmi_unicode_decode(lwgsm_unicode_t* s, uint8_t c) {
if (s->r == 0) { /* Are we expecting a first character? */
s->t = 0; /* Reset sequence */
s->ch[0] = c; /* Save current character */
if (c < 0x80) { /* One byte only in UTF-8 representation */
s->r = 0; /* Remaining bytes */
s->t = 1;
- return gsmOK; /* Return OK */
+ return lwgsmOK; /* Return OK */
}
if ((c & 0xE0) == 0xC0) { /* 1 additional byte in a row = 110x xxxx */
s->r = 1;
@@ -59,17 +59,17 @@ gsmi_unicode_decode(gsm_unicode_t* s, uint8_t c) {
} else if ((c & 0xF8) == 0xF0) { /* 3 additional bytes in a row = 1111 0xxx */
s->r = 3;
} else {
- return gsmERR; /* Error parsing unicode byte */
+ return lwgsmERR; /* Error parsing unicode byte */
}
s->t = s->r + 1; /* Number of bytes is 1 byte more than remaining in sequence */
- return gsmINPROG; /* Return in progress status */
+ return lwgsmINPROG; /* Return in progress status */
} else if ((c & 0xC0) == 0x80) { /* Next character in sequence */
- s->r--; /* Decrease character */
+ --s->r; /* Decrease character */
s->ch[s->t - s->r - 1] = c; /* Save character to array */
if (s->r == 0) { /* Did we finish? */
- return gsmOK; /* Return OK, we are ready to proceed */
+ return lwgsmOK; /* Return OK, we are ready to proceed */
}
- return gsmINPROG; /* Still in progress */
+ return lwgsmINPROG; /* Still in progress */
}
- return gsmERR; /* An error, unknown UTF-8 character entered */
+ return lwgsmERR; /* An error, unknown UTF-8 character entered */
}
diff --git a/gsm_at_lib/src/gsm/gsm_ussd.c b/lwgsm/src/lwgsm/lwgsm_ussd.c
similarity index 58%
rename from gsm_at_lib/src/gsm/gsm_ussd.c
rename to lwgsm/src/lwgsm/lwgsm_ussd.c
index 2113d23d..8ce9afd9 100644
--- a/gsm_at_lib/src/gsm/gsm_ussd.c
+++ b/lwgsm/src/lwgsm/lwgsm_ussd.c
@@ -1,10 +1,10 @@
-/**
- * \file gsm_ussd.c
+/**
+ * \file lwgsm_ussd.c
* \brief Unstructured Supplementary Service Data
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,16 +26,16 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#include "gsm/gsm_private.h"
-#include "gsm/gsm_ussd.h"
-#include "gsm/gsm_mem.h"
+#include "lwgsm/lwgsm_private.h"
+#include "lwgsm/lwgsm_ussd.h"
+#include "lwgsm/lwgsm_mem.h"
-#if GSM_CFG_USSD || __DOXYGEN__
+#if LWGSM_CFG_USSD || __DOXYGEN__
/**
* \brief Run USSD command, such as `*123#` to get balance on SIM card
@@ -45,26 +45,26 @@
* \param[in] evt_fn: Callback function called when command has finished. Set to `NULL` when not used
* \param[in] evt_arg: Custom argument for event callback function
* \param[in] blocking: Status whether command should be blocking or not
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_ussd_run(const char* code, char* resp, size_t resp_len,
- const gsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
- GSM_MSG_VAR_DEFINE(msg);
+lwgsmr_t
+lwgsm_ussd_run(const char* code, char* resp, size_t resp_len,
+ const lwgsm_api_cmd_evt_fn evt_fn, void* const evt_arg, const uint32_t blocking) {
+ LWGSM_MSG_VAR_DEFINE(msg);
- GSM_ASSERT("code != NULL && strlen(code) > 0", code != NULL && strlen(code) > 0);
- GSM_ASSERT("resp != NULL", resp != NULL);
- GSM_ASSERT("resp_len != NULL", resp_len > 0);
+ LWGSM_ASSERT("code != NULL && strlen(code) > 0", code != NULL && strlen(code) > 0);
+ LWGSM_ASSERT("resp != NULL", resp != NULL);
+ LWGSM_ASSERT("resp_len != NULL", resp_len > 0);
- GSM_MSG_VAR_ALLOC(msg, blocking);
- GSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
- GSM_MSG_VAR_REF(msg).cmd_def = GSM_CMD_CUSD;
- GSM_MSG_VAR_REF(msg).cmd = GSM_CMD_CUSD_GET;
- GSM_MSG_VAR_REF(msg).msg.ussd.code = code;
- GSM_MSG_VAR_REF(msg).msg.ussd.resp = resp;
- GSM_MSG_VAR_REF(msg).msg.ussd.resp_len = resp_len;
+ LWGSM_MSG_VAR_ALLOC(msg, blocking);
+ LWGSM_MSG_VAR_SET_EVT(msg, evt_fn, evt_arg);
+ LWGSM_MSG_VAR_REF(msg).cmd_def = LWGSM_CMD_CUSD;
+ LWGSM_MSG_VAR_REF(msg).cmd = LWGSM_CMD_CUSD_GET;
+ LWGSM_MSG_VAR_REF(msg).msg.ussd.code = code;
+ LWGSM_MSG_VAR_REF(msg).msg.ussd.resp = resp;
+ LWGSM_MSG_VAR_REF(msg).msg.ussd.resp_len = resp_len;
- return gsmi_send_msg_to_producer_mbox(&GSM_MSG_VAR_REF(msg), gsmi_initiate_cmd, 10000);
+ return lwgsmi_send_msg_to_producer_mbox(&LWGSM_MSG_VAR_REF(msg), lwgsmi_initiate_cmd, 10000);
}
-#endif /* GSM_CFG_USSD || __DOXYGEN__ */
+#endif /* LWGSM_CFG_USSD || __DOXYGEN__ */
diff --git a/gsm_at_lib/src/gsm/gsm_utils.c b/lwgsm/src/lwgsm/lwgsm_utils.c
similarity index 83%
rename from gsm_at_lib/src/gsm/gsm_utils.c
rename to lwgsm/src/lwgsm/lwgsm_utils.c
index 24207e83..24921d48 100644
--- a/gsm_at_lib/src/gsm/gsm_utils.c
+++ b/lwgsm/src/lwgsm/lwgsm_utils.c
@@ -1,10 +1,10 @@
/**
- * \file gsm_utils.c
+ * \file lwgsm_utils.c
* \brief Utilities
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,14 +26,14 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#include "gsm/gsm_private.h"
-#include "gsm/gsm_utils.h"
#include
+#include "lwgsm/lwgsm_private.h"
+#include "lwgsm/lwgsm_utils.h"
/**
* \brief Convert `unsigned 32-bit` number to string
@@ -45,8 +45,8 @@
* This parameter is valid only when formatting hex numbers
* \return Pointer to output variable
*/
-char *
-gsm_u32_to_gen_str(uint32_t num, char* out, uint8_t is_hex, uint8_t width) {
+char*
+lwgsm_u32_to_gen_str(uint32_t num, char* out, uint8_t is_hex, uint8_t width) {
char* tmp = out;
uint8_t i, y;
@@ -54,7 +54,7 @@ gsm_u32_to_gen_str(uint32_t num, char* out, uint8_t is_hex, uint8_t width) {
i = 0;
tmp[0] = '0';
if (num == 0) {
- i++;
+ ++i;
} else {
if (is_hex) {
uint8_t mod;
@@ -66,20 +66,20 @@ gsm_u32_to_gen_str(uint32_t num, char* out, uint8_t is_hex, uint8_t width) {
tmp[i] = mod - 10 + 'A';
}
num >>= 4;
- i++;
+ ++i;
}
} else {
while (num > 0) {
tmp[i] = (num % 10) + '0';
num /= 10;
- i++;
+ ++i;
}
}
}
if (is_hex) {
while (i < width) {
tmp[i] = '0';
- i++;
+ ++i;
}
}
tmp[i] = 0;
@@ -90,7 +90,7 @@ gsm_u32_to_gen_str(uint32_t num, char* out, uint8_t is_hex, uint8_t width) {
char t = out[i - y - 1];
out[i - y - 1] = tmp[y];
tmp[y] = t;
- y++;
+ ++y;
}
out[i] = 0;
return out;
@@ -102,12 +102,12 @@ gsm_u32_to_gen_str(uint32_t num, char* out, uint8_t is_hex, uint8_t width) {
* \param[out] out: Output variable to save string
* \return Pointer to output variable
*/
-char *
-gsm_i32_to_gen_str(int32_t num, char* out) {
+char*
+lwgsm_i32_to_gen_str(int32_t num, char* out) {
if (num < 0) {
*out++ = '-';
- return gsm_u32_to_gen_str(GSM_U32(-num), out, 0, 0) - 1;
+ return lwgsm_u32_to_gen_str(LWGSM_U32(-num), out, 0, 0) - 1;
} else {
- return gsm_u32_to_gen_str(GSM_U32(num), out, 0, 0);
+ return lwgsm_u32_to_gen_str(LWGSM_U32(num), out, 0, 0);
}
}
diff --git a/lwgsm/src/system/lwgsm_ll_stm32.c b/lwgsm/src/system/lwgsm_ll_stm32.c
new file mode 100644
index 00000000..77989288
--- /dev/null
+++ b/lwgsm/src/system/lwgsm_ll_stm32.c
@@ -0,0 +1,375 @@
+/**
+ * \file lwgsm_ll_stm32.c
+ * \brief Generic STM32 driver, included in various STM32 driver variants
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM - Lightweight GSM-AT library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+
+/*
+ * How it works
+ *
+ * On first call to \ref lwgsm_ll_init, new thread is created and processed in usart_ll_thread function.
+ * USART is configured in RX DMA mode and any incoming bytes are processed inside thread function.
+ * DMA and USART implement interrupt handlers to notify main thread about new data ready to send to upper layer.
+ *
+ * More about UART + RX DMA: https://github.com/MaJerle/stm32-usart-dma-rx-tx
+ *
+ * \ref LWGSM_CFG_INPUT_USE_PROCESS must be enabled in `lwgsm_config.h` to use this driver.
+ */
+#include "lwgsm/lwgsm.h"
+#include "lwgsm/lwgsm_mem.h"
+#include "lwgsm/lwgsm_input.h"
+#include "system/lwgsm_ll.h"
+
+#if !__DOXYGEN__
+
+#if !LWGSM_CFG_INPUT_USE_PROCESS
+#error "LWGSM_CFG_INPUT_USE_PROCESS must be enabled in `lwgsm_config.h` to use this driver."
+#endif /* LWGSM_CFG_INPUT_USE_PROCESS */
+
+#if !defined(LWGSM_USART_DMA_RX_BUFF_SIZE)
+#define LWGSM_USART_DMA_RX_BUFF_SIZE 0x1000
+#endif /* !defined(LWGSM_USART_DMA_RX_BUFF_SIZE) */
+
+#if !defined(LWGSM_MEM_SIZE)
+#define LWGSM_MEM_SIZE 0x1000
+#endif /* !defined(LWGSM_MEM_SIZE) */
+
+#if !defined(LWGSM_USART_RDR_NAME)
+#define LWGSM_USART_RDR_NAME RDR
+#endif /* !defined(LWGSM_USART_RDR_NAME) */
+
+/* USART memory */
+static uint8_t usart_mem[LWGSM_USART_DMA_RX_BUFF_SIZE];
+static uint8_t is_running, initialized;
+static size_t old_pos;
+
+/* USART thread */
+static void usart_ll_thread(void* arg);
+static osThreadId_t usart_ll_thread_id;
+
+/* Message queue */
+static osMessageQueueId_t usart_ll_mbox_id;
+
+/**
+ * \brief USART data processing
+ */
+static void
+usart_ll_thread(void* arg) {
+ size_t pos;
+
+ LWGSM_UNUSED(arg);
+
+ while (1) {
+ void* d;
+ /* Wait for the event message from DMA or USART */
+ osMessageQueueGet(usart_ll_mbox_id, &d, NULL, osWaitForever);
+
+ /* Read data */
+#if defined(LWGSM_USART_DMA_RX_STREAM)
+ pos = sizeof(usart_mem) - LL_DMA_GetDataLength(LWGSM_USART_DMA, LWGSM_USART_DMA_RX_STREAM);
+#else
+ pos = sizeof(usart_mem) - LL_DMA_GetDataLength(LWGSM_USART_DMA, LWGSM_USART_DMA_RX_CH);
+#endif /* defined(LWGSM_USART_DMA_RX_STREAM) */
+ if (pos != old_pos && is_running) {
+ if (pos > old_pos) {
+ lwgsm_input_process(&usart_mem[old_pos], pos - old_pos);
+ } else {
+ lwgsm_input_process(&usart_mem[old_pos], sizeof(usart_mem) - old_pos);
+ if (pos > 0) {
+ lwgsm_input_process(&usart_mem[0], pos);
+ }
+ }
+ old_pos = pos;
+ if (old_pos == sizeof(usart_mem)) {
+ old_pos = 0;
+ }
+ }
+ }
+}
+
+/**
+ * \brief Configure UART using DMA for receive in double buffer mode and IDLE line detection
+ */
+static void
+configure_uart(uint32_t baudrate) {
+ static LL_USART_InitTypeDef usart_init;
+ static LL_DMA_InitTypeDef dma_init;
+ LL_GPIO_InitTypeDef gpio_init;
+
+ if (!initialized) {
+ /* Enable peripheral clocks */
+ LWGSM_USART_CLK;
+ LWGSM_USART_DMA_CLK;
+ LWGSM_USART_TX_PORT_CLK;
+ LWGSM_USART_RX_PORT_CLK;
+
+#if defined(LWGSM_RESET_PIN)
+ LWGSM_RESET_PORT_CLK;
+#endif /* defined(LWGSM_RESET_PIN) */
+
+ /* Global pin configuration */
+ LL_GPIO_StructInit(&gpio_init);
+ gpio_init.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
+ gpio_init.Pull = LL_GPIO_PULL_UP;
+ gpio_init.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
+ gpio_init.Mode = LL_GPIO_MODE_OUTPUT;
+
+#if defined(LWGSM_RESET_PIN)
+ /* Configure RESET pin */
+ gpio_init.Pin = LWGSM_RESET_PIN;
+ LL_GPIO_Init(LWGSM_RESET_PORT, &gpio_init);
+#endif /* defined(LWGSM_RESET_PIN) */
+
+ /* Configure USART pins */
+ gpio_init.Mode = LL_GPIO_MODE_ALTERNATE;
+
+ /* TX PIN */
+ gpio_init.Alternate = LWGSM_USART_TX_PIN_AF;
+ gpio_init.Pin = LWGSM_USART_TX_PIN;
+ LL_GPIO_Init(LWGSM_USART_TX_PORT, &gpio_init);
+
+ /* RX PIN */
+ gpio_init.Alternate = LWGSM_USART_RX_PIN_AF;
+ gpio_init.Pin = LWGSM_USART_RX_PIN;
+ LL_GPIO_Init(LWGSM_USART_RX_PORT, &gpio_init);
+
+ /* Configure UART */
+ LL_USART_DeInit(LWGSM_USART);
+ LL_USART_StructInit(&usart_init);
+ usart_init.BaudRate = baudrate;
+ usart_init.DataWidth = LL_USART_DATAWIDTH_8B;
+ usart_init.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
+ usart_init.OverSampling = LL_USART_OVERSAMPLING_16;
+ usart_init.Parity = LL_USART_PARITY_NONE;
+ usart_init.StopBits = LL_USART_STOPBITS_1;
+ usart_init.TransferDirection = LL_USART_DIRECTION_TX_RX;
+ LL_USART_Init(LWGSM_USART, &usart_init);
+
+ /* Enable USART interrupts and DMA request */
+ LL_USART_EnableIT_IDLE(LWGSM_USART);
+ LL_USART_EnableIT_PE(LWGSM_USART);
+ LL_USART_EnableIT_ERROR(LWGSM_USART);
+ LL_USART_EnableDMAReq_RX(LWGSM_USART);
+
+ /* Enable USART interrupts */
+ NVIC_SetPriority(LWGSM_USART_IRQ, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0x07, 0x00));
+ NVIC_EnableIRQ(LWGSM_USART_IRQ);
+
+ /* Configure DMA */
+ is_running = 0;
+#if defined(LWGSM_USART_DMA_RX_STREAM)
+ LL_DMA_DeInit(LWGSM_USART_DMA, LWGSM_USART_DMA_RX_STREAM);
+ dma_init.Channel = LWGSM_USART_DMA_RX_CH;
+#else
+ LL_DMA_DeInit(LWGSM_USART_DMA, LWGSM_USART_DMA_RX_CH);
+ dma_init.PeriphRequest = LWGSM_USART_DMA_RX_REQ_NUM;
+#endif /* defined(LWGSM_USART_DMA_RX_STREAM) */
+ dma_init.PeriphOrM2MSrcAddress = (uint32_t)&LWGSM_USART->LWGSM_USART_RDR_NAME;
+ dma_init.MemoryOrM2MDstAddress = (uint32_t)usart_mem;
+ dma_init.Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
+ dma_init.Mode = LL_DMA_MODE_CIRCULAR;
+ dma_init.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT;
+ dma_init.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT;
+ dma_init.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_BYTE;
+ dma_init.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_BYTE;
+ dma_init.NbData = sizeof(usart_mem);
+ dma_init.Priority = LL_DMA_PRIORITY_MEDIUM;
+#if defined(LWGSM_USART_DMA_RX_STREAM)
+ LL_DMA_Init(LWGSM_USART_DMA, LWGSM_USART_DMA_RX_STREAM, &dma_init);
+#else
+ LL_DMA_Init(LWGSM_USART_DMA, LWGSM_USART_DMA_RX_CH, &dma_init);
+#endif /* defined(LWGSM_USART_DMA_RX_STREAM) */
+
+ /* Enable DMA interrupts */
+#if defined(LWGSM_USART_DMA_RX_STREAM)
+ LL_DMA_EnableIT_HT(LWGSM_USART_DMA, LWGSM_USART_DMA_RX_STREAM);
+ LL_DMA_EnableIT_TC(LWGSM_USART_DMA, LWGSM_USART_DMA_RX_STREAM);
+ LL_DMA_EnableIT_TE(LWGSM_USART_DMA, LWGSM_USART_DMA_RX_STREAM);
+ LL_DMA_EnableIT_FE(LWGSM_USART_DMA, LWGSM_USART_DMA_RX_STREAM);
+ LL_DMA_EnableIT_DME(LWGSM_USART_DMA, LWGSM_USART_DMA_RX_STREAM);
+#else
+ LL_DMA_EnableIT_HT(LWGSM_USART_DMA, LWGSM_USART_DMA_RX_CH);
+ LL_DMA_EnableIT_TC(LWGSM_USART_DMA, LWGSM_USART_DMA_RX_CH);
+ LL_DMA_EnableIT_TE(LWGSM_USART_DMA, LWGSM_USART_DMA_RX_CH);
+#endif /* defined(LWGSM_USART_DMA_RX_STREAM) */
+
+ /* Enable DMA interrupts */
+ NVIC_SetPriority(LWGSM_USART_DMA_RX_IRQ, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0x07, 0x00));
+ NVIC_EnableIRQ(LWGSM_USART_DMA_RX_IRQ);
+
+ old_pos = 0;
+ is_running = 1;
+
+ /* Start DMA and USART */
+#if defined(LWGSM_USART_DMA_RX_STREAM)
+ LL_DMA_EnableStream(LWGSM_USART_DMA, LWGSM_USART_DMA_RX_STREAM);
+#else
+ LL_DMA_EnableChannel(LWGSM_USART_DMA, LWGSM_USART_DMA_RX_CH);
+#endif /* defined(LWGSM_USART_DMA_RX_STREAM) */
+ LL_USART_Enable(LWGSM_USART);
+ } else {
+ osDelay(10);
+ LL_USART_Disable(LWGSM_USART);
+ usart_init.BaudRate = baudrate;
+ LL_USART_Init(LWGSM_USART, &usart_init);
+ LL_USART_Enable(LWGSM_USART);
+ }
+
+ /* Create mbox and start thread */
+ if (usart_ll_mbox_id == NULL) {
+ usart_ll_mbox_id = osMessageQueueNew(10, sizeof(void*), NULL);
+ }
+ if (usart_ll_thread_id == NULL) {
+ const osThreadAttr_t attr = {
+ .stack_size = 1024
+ };
+ usart_ll_thread_id = osThreadNew(usart_ll_thread, usart_ll_mbox_id, &attr);
+ }
+}
+
+#if defined(LWGSM_RESET_PIN)
+/**
+ * \brief Hardware reset callback
+ */
+static uint8_t
+reset_device(uint8_t state) {
+ if (state) { /* Activate reset line */
+ LL_GPIO_ResetOutputPin(LWGSM_RESET_PORT, LWGSM_RESET_PIN);
+ } else {
+ LL_GPIO_SetOutputPin(LWGSM_RESET_PORT, LWGSM_RESET_PIN);
+ }
+ return 1;
+}
+#endif /* defined(LWGSM_RESET_PIN) */
+
+/**
+ * \brief Send data to GSM device
+ * \param[in] data: Pointer to data to send
+ * \param[in] len: Number of bytes to send
+ * \return Number of bytes sent
+ */
+static size_t
+send_data(const void* data, size_t len) {
+ const uint8_t* d = data;
+
+ for (size_t i = 0; i < len; ++i, ++d) {
+ LL_USART_TransmitData8(LWGSM_USART, *d);
+ while (!LL_USART_IsActiveFlag_TXE(LWGSM_USART)) {}
+ }
+ return len;
+}
+
+/**
+ * \brief Callback function called from initialization process
+ * \note This function may be called multiple times if AT baudrate is changed from application
+ * \param[in,out] ll: Pointer to \ref lwgsm_ll_t structure to fill data for communication functions
+ * \param[in] baudrate: Baudrate to use on AT port
+ * \return Member of \ref lwgsmr_t enumeration
+ */
+lwgsmr_t
+lwgsm_ll_init(lwgsm_ll_t* ll) {
+#if !LWGSM_CFG_MEM_CUSTOM
+ static uint8_t memory[LWGSM_MEM_SIZE];
+ lwgsm_mem_region_t mem_regions[] = {
+ { memory, sizeof(memory) }
+ };
+
+ if (!initialized) {
+ lwgsm_mem_assignmemory(mem_regions, LWGSM_ARRAYSIZE(mem_regions)); /* Assign memory for allocations */
+ }
+#endif /* !LWGSM_CFG_MEM_CUSTOM */
+
+ if (!initialized) {
+ ll->send_fn = send_data; /* Set callback function to send data */
+#if defined(LWGSM_RESET_PIN)
+ ll->reset_fn = reset_device; /* Set callback for hardware reset */
+#endif /* defined(LWGSM_RESET_PIN) */
+ }
+
+ configure_uart(ll->uart.baudrate); /* Initialize UART for communication */
+ initialized = 1;
+ return lwgsmOK;
+}
+
+/**
+ * \brief Callback function to de-init low-level communication part
+ * \param[in,out] ll: Pointer to \ref lwgsm_ll_t structure to fill data for communication functions
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
+ */
+lwgsmr_t
+lwgsm_ll_deinit(lwgsm_ll_t* ll) {
+ if (usart_ll_mbox_id != NULL) {
+ osMessageQueueId_t tmp = usart_ll_mbox_id;
+ usart_ll_mbox_id = NULL;
+ osMessageQueueDelete(tmp);
+ }
+ if (usart_ll_thread_id != NULL) {
+ osThreadId_t tmp = usart_ll_thread_id;
+ usart_ll_thread_id = NULL;
+ osThreadTerminate(tmp);
+ }
+ initialized = 0;
+ LWGSM_UNUSED(ll);
+ return lwgsmOK;
+}
+
+/**
+ * \brief UART global interrupt handler
+ */
+void
+LWGSM_USART_IRQHANDLER(void) {
+ LL_USART_ClearFlag_IDLE(LWGSM_USART);
+ LL_USART_ClearFlag_PE(LWGSM_USART);
+ LL_USART_ClearFlag_FE(LWGSM_USART);
+ LL_USART_ClearFlag_ORE(LWGSM_USART);
+ LL_USART_ClearFlag_NE(LWGSM_USART);
+
+ if (usart_ll_mbox_id != NULL) {
+ void* d = (void*)1;
+ osMessageQueuePut(usart_ll_mbox_id, &d, 0, 0);
+ }
+}
+
+/**
+ * \brief UART DMA stream/channel handler
+ */
+void
+LWGSM_USART_DMA_RX_IRQHANDLER(void) {
+ LWGSM_USART_DMA_RX_CLEAR_TC;
+ LWGSM_USART_DMA_RX_CLEAR_HT;
+
+ if (usart_ll_mbox_id != NULL) {
+ void* d = (void*)1;
+ osMessageQueuePut(usart_ll_mbox_id, &d, 0, 0);
+ }
+}
+
+#endif /* !__DOXYGEN__ */
diff --git a/lwgsm/src/system/lwgsm_ll_stm32f429zi_nucleo.c b/lwgsm/src/system/lwgsm_ll_stm32f429zi_nucleo.c
new file mode 100644
index 00000000..e644d8b7
--- /dev/null
+++ b/lwgsm/src/system/lwgsm_ll_stm32f429zi_nucleo.c
@@ -0,0 +1,101 @@
+/**
+ * \file lwgsm_ll_stm32f429zi_nucleo.c
+ * \brief Low-level communication with GSM device for STM32F429ZI-Nucleo using DMA
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM - Lightweight GSM-AT library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+
+/*
+ * Default UART configuration is:
+ *
+ * UART: USART6
+ * STM32 TX (GSM RX): GPIOC, GPIO_PIN_6
+ * STM32 RX (GSM TX): GPIOC, GPIO_PIN_7
+ * RESET: GPIOC, GPIO_PIN_5
+ *
+ * USART_DMA: DMA2
+ * USART_DMA_STREAM: DMA_STREAM_1
+ * USART_DMA_CHANNEL: DMA_CHANNEL_5
+ */
+#include "lwgsm/lwgsm.h"
+#include "lwgsm/lwgsm_mem.h"
+#include "lwgsm/lwgsm_input.h"
+#include "system/lwgsm_ll.h"
+
+#if !__DOXYGEN__
+
+#include "stm32f4xx_ll_bus.h"
+#include "stm32f4xx_ll_usart.h"
+#include "stm32f4xx_ll_gpio.h"
+#include "stm32f4xx_ll_dma.h"
+#include "stm32f4xx_ll_rcc.h"
+
+/* USART */
+#define LWGSM_USART USART6
+#define LWGSM_USART_CLK LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART6)
+#define LWGSM_USART_IRQ USART6_IRQn
+#define LWGSM_USART_IRQHANDLER USART6_IRQHandler
+#define LWGSM_USART_RDR_NAME DR
+
+/* DMA settings */
+#define LWGSM_USART_DMA DMA2
+#define LWGSM_USART_DMA_CLK LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA2)
+#define LWGSM_USART_DMA_RX_STREAM LL_DMA_STREAM_1
+#define LWGSM_USART_DMA_RX_CH LL_DMA_CHANNEL_5
+#define LWGSM_USART_DMA_RX_IRQ DMA2_Stream1_IRQn
+#define LWGSM_USART_DMA_RX_IRQHANDLER DMA2_Stream1_IRQHandler
+
+/* DMA flags management */
+#define LWGSM_USART_DMA_RX_IS_TC LL_DMA_IsActiveFlag_TC1(LWGSM_USART_DMA)
+#define LWGSM_USART_DMA_RX_IS_HT LL_DMA_IsActiveFlag_HT1(LWGSM_USART_DMA)
+#define LWGSM_USART_DMA_RX_CLEAR_TC LL_DMA_ClearFlag_TC1(LWGSM_USART_DMA)
+#define LWGSM_USART_DMA_RX_CLEAR_HT LL_DMA_ClearFlag_HT1(LWGSM_USART_DMA)
+
+/* USART TX PIN */
+#define LWGSM_USART_TX_PORT_CLK LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOC)
+#define LWGSM_USART_TX_PORT GPIOC
+#define LWGSM_USART_TX_PIN LL_GPIO_PIN_6
+#define LWGSM_USART_TX_PIN_AF LL_GPIO_AF_8
+
+/* USART RX PIN */
+#define LWGSM_USART_RX_PORT_CLK LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOC)
+#define LWGSM_USART_RX_PORT GPIOC
+#define LWGSM_USART_RX_PIN LL_GPIO_PIN_7
+#define LWGSM_USART_RX_PIN_AF LL_GPIO_AF_8
+
+/* RESET PIN */
+#define LWGSM_RESET_PORT_CLK LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOC)
+#define LWGSM_RESET_PORT GPIOC
+#define LWGSM_RESET_PIN LL_GPIO_PIN_5
+
+/* Include STM32 generic driver */
+#include "../system/lwgsm_ll_stm32.c"
+
+#endif /* !__DOXYGEN__ */
diff --git a/gsm_at_lib/src/system/gsm_ll_template.c b/lwgsm/src/system/lwgsm_ll_template.c
similarity index 72%
rename from gsm_at_lib/src/system/gsm_ll_template.c
rename to lwgsm/src/system/lwgsm_ll_template.c
index 1c2a959b..c5d96f23 100644
--- a/gsm_at_lib/src/system/gsm_ll_template.c
+++ b/lwgsm/src/system/lwgsm_ll_template.c
@@ -1,10 +1,10 @@
/**
- * \file gsm_ll_template.c
+ * \file lwgsm_ll_template.c
* \brief Low-level communication with GSM device template
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,15 +26,15 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#include "system/gsm_ll.h"
-#include "gsm/gsm.h"
-#include "gsm/gsm_mem.h"
-#include "gsm/gsm_input.h"
+#include "system/lwgsm_ll.h"
+#include "lwgsm/lwgsm.h"
+#include "lwgsm/lwgsm_mem.h"
+#include "lwgsm/lwgsm_input.h"
static uint8_t initialized = 0;
@@ -45,7 +45,7 @@ static uint8_t initialized = 0;
* \return Number of bytes sent
*/
static size_t
-send_data(const void* data, uint16_t size_t) {
+send_data(const void* data, size_t len) {
/* Implement send function here */
@@ -59,14 +59,14 @@ send_data(const void* data, uint16_t size_t) {
* It is important that every configuration except AT baudrate is configured only once!
*
* \note This function may be called from different threads in GSM stack when using OS.
- * When \ref GSM_CFG_INPUT_USE_PROCESS is set to 1, this function may be called from user UART thread.
+ * When \ref LWGSM_CFG_INPUT_USE_PROCESS is set to 1, this function may be called from user UART thread.
*
- * \param[in,out] ll: Pointer to \ref gsm_ll_t structure to fill data for communication functions
- * \return gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \param[in,out] ll: Pointer to \ref lwgsm_ll_t structure to fill data for communication functions
+ * \return lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_ll_init(gsm_ll_t* ll) {
-#if !GSM_CFG_MEM_CUSTOM
+lwgsmr_t
+lwgsm_ll_init(lwgsm_ll_t* ll) {
+#if !LWGSM_CFG_MEM_CUSTOM
/* Step 1: Configure memory for dynamic allocations */
static uint8_t memory[0x10000]; /* Create memory for dynamic allocations with specific size */
@@ -75,13 +75,13 @@ gsm_ll_init(gsm_ll_t* ll) {
* If device has internal/external memory available,
* multiple memories may be used
*/
- gsm_mem_region_t mem_regions[] = {
+ lwgsm_mem_region_t mem_regions[] = {
{ memory, sizeof(memory) }
};
if (!initialized) {
- gsm_mem_assignmemory(mem_regions, GSM_ARRAYSIZE(mem_regions)); /* Assign memory for allocations to GSM library */
+ lwgsm_mem_assignmemory(mem_regions, LWGSM_ARRAYSIZE(mem_regions)); /* Assign memory for allocations to GSM library */
}
-#endif /* !GSM_CFG_MEM_CUSTOM */
+#endif /* !LWGSM_CFG_MEM_CUSTOM */
/* Step 2: Set AT port send function to use when we have data to transmit */
if (!initialized) {
@@ -91,16 +91,16 @@ gsm_ll_init(gsm_ll_t* ll) {
/* Step 3: Configure AT port to be able to send/receive data to/from GSM device */
configure_uart(ll->uart.baudrate); /* Initialize UART for communication */
initialized = 1;
- return gsmOK;
+ return lwgsmOK;
}
/**
* \brief Callback function to de-init low-level communication part
- * \param[in,out] ll: Pointer to \ref gsm_ll_t structure to fill data for communication functions
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \param[in,out] ll: Pointer to \ref lwgsm_ll_t structure to fill data for communication functions
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_ll_deinit(gsm_ll_t* ll) {
+lwgsmr_t
+lwgsm_ll_deinit(lwgsm_ll_t* ll) {
initialized = 0; /* Clear initialized flag */
- return gsmOK;
+ return lwgsmOK;
}
diff --git a/gsm_at_lib/src/system/gsm_ll_win32.c b/lwgsm/src/system/lwgsm_ll_win32.c
similarity index 75%
rename from gsm_at_lib/src/system/gsm_ll_win32.c
rename to lwgsm/src/system/lwgsm_ll_win32.c
index 7a1f2b32..7f39aa47 100644
--- a/gsm_at_lib/src/system/gsm_ll_win32.c
+++ b/lwgsm/src/system/lwgsm_ll_win32.c
@@ -1,10 +1,10 @@
/**
- * \file gsm_ll_win32.c
+ * \file lwgsm_ll_win32.c
* \brief Low-level communication with GSM device for WIN32
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,25 +26,24 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#include "system/gsm_ll.h"
-#include "gsm/gsm.h"
-#include "gsm/gsm_mem.h"
-#include "gsm/gsm_input.h"
+#include "system/lwgsm_ll.h"
+#include "lwgsm/lwgsm.h"
+#include "lwgsm/lwgsm_mem.h"
+#include "lwgsm/lwgsm_input.h"
#if !__DOXYGEN__
static uint8_t initialized = 0;
+static HANDLE thread_handle;
+static volatile HANDLE com_port; /*!< COM port handle */
+static uint8_t data_buffer[0x1000]; /*!< Received data array */
-DWORD thread_id;
-HANDLE thread_handle;
static void uart_thread(void* param);
-volatile HANDLE com_port; /*!< COM port handle */
-uint8_t data_buffer[0x1000]; /*!< Received data array */
/**
* \brief Send data to GSM device, function called from GSM stack when we have data to send
@@ -56,17 +55,17 @@ static size_t
send_data(const void* data, size_t len) {
DWORD written;
if (com_port != NULL) {
-#if !GSM_CFG_AT_ECHO
+#if !LWGSM_CFG_AT_ECHO
const uint8_t* d = data;
HANDLE hConsole;
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, FOREGROUND_RED);
- for (DWORD i = 0; i < len; i++) {
+ for (DWORD i = 0; i < len; ++i) {
printf("%c", d[i]);
}
SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
-#endif /* !GSM_CFG_AT_ECHO */
+#endif /* !LWGSM_CFG_AT_ECHO */
/* Write data to AT port */
WriteFile(com_port, data, len, &written, NULL);
@@ -92,21 +91,22 @@ configure_uart(uint32_t baudrate) {
if (!initialized) {
static const LPCWSTR com_ports[] = {
L"\\\\.\\COM23",
+ L"\\\\.\\COM12",
L"\\\\.\\COM9",
L"\\\\.\\COM8",
L"\\\\.\\COM4"
};
- for (size_t i = 0; i < sizeof(com_ports) / sizeof(com_ports[0]); i++) {
+ for (size_t i = 0; i < sizeof(com_ports) / sizeof(com_ports[0]); ++i) {
com_port = CreateFile(com_ports[i],
- GENERIC_READ | GENERIC_WRITE,
- 0,
- 0,
- OPEN_EXISTING,
- 0,
- NULL
- );
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ 0,
+ OPEN_EXISTING,
+ 0,
+ NULL
+ );
if (GetCommState(com_port, &dcb)) {
- printf("COM PORT %s opened!\r\n", (const char *)com_ports[i]);
+ printf("COM PORT %s opened!\r\n", (const char*)com_ports[i]);
break;
}
}
@@ -125,7 +125,7 @@ configure_uart(uint32_t baudrate) {
printf("Cannot set COM PORT info\r\n");
}
if (GetCommTimeouts(com_port, &timeouts)) {
- /* Set timeout to return immediatelly from ReadFile function */
+ /* Set timeout to return immediately from ReadFile function */
timeouts.ReadIntervalTimeout = MAXDWORD;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.ReadTotalTimeoutMultiplier = 0;
@@ -152,13 +152,13 @@ configure_uart(uint32_t baudrate) {
static void
uart_thread(void* param) {
DWORD bytes_read;
- gsm_sys_sem_t sem;
+ lwgsm_sys_sem_t sem;
FILE* file = NULL;
- gsm_sys_sem_create(&sem, 0); /* Create semaphore for delay functions */
+ lwgsm_sys_sem_create(&sem, 0); /* Create semaphore for delay functions */
while (com_port == NULL) {
- gsm_sys_sem_wait(&sem, 1); /* Add some delay with yield */
+ lwgsm_sys_sem_wait(&sem, 1); /* Add some delay with yield */
}
fopen_s(&file, "log_file.txt", "w+"); /* Open debug file in write mode */
@@ -173,17 +173,17 @@ uart_thread(void* param) {
HANDLE hConsole;
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, FOREGROUND_GREEN);
- for (DWORD i = 0; i < bytes_read; i++) {
+ for (DWORD i = 0; i < bytes_read; ++i) {
printf("%c", data_buffer[i]);
}
SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
/* Send received data to input processing module */
-#if GSM_CFG_INPUT_USE_PROCESS
- gsm_input_process(data_buffer, (size_t)bytes_read);
-#else /* GSM_CFG_INPUT_USE_PROCESS */
- gsm_input(data_buffer, (size_t)bytes_read);
-#endif /* !GSM_CFG_INPUT_USE_PROCESS */
+#if LWGSM_CFG_INPUT_USE_PROCESS
+ lwgsm_input_process(data_buffer, (size_t)bytes_read);
+#else /* LWGSM_CFG_INPUT_USE_PROCESS */
+ lwgsm_input(data_buffer, (size_t)bytes_read);
+#endif /* !LWGSM_CFG_INPUT_USE_PROCESS */
/* Write received data to output debug file */
if (file != NULL) {
@@ -194,7 +194,7 @@ uart_thread(void* param) {
} while (bytes_read == (DWORD)sizeof(data_buffer));
/* Implement delay to allow other tasks processing */
- gsm_sys_sem_wait(&sem, 1);
+ lwgsm_sys_sem_wait(&sem, 1);
}
}
@@ -205,14 +205,14 @@ uart_thread(void* param) {
* It is important that every configuration except AT baudrate is configured only once!
*
* \note This function may be called from different threads in GSM stack when using OS.
- * When \ref GSM_CFG_INPUT_USE_PROCESS is set to 1, this function may be called from user UART thread.
+ * When \ref LWGSM_CFG_INPUT_USE_PROCESS is set to 1, this function may be called from user UART thread.
*
- * \param[in,out] ll: Pointer to \ref gsm_ll_t structure to fill data for communication functions
- * \return \ref gsmOK on success, member of \ref gsmr_t enumeration otherwise
+ * \param[in,out] ll: Pointer to \ref lwgsm_ll_t structure to fill data for communication functions
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
-gsmr_t
-gsm_ll_init(gsm_ll_t* ll) {
-#if !GSM_CFG_MEM_CUSTOM
+lwgsmr_t
+lwgsm_ll_init(lwgsm_ll_t* ll) {
+#if !LWGSM_CFG_MEM_CUSTOM
/* Step 1: Configure memory for dynamic allocations */
static uint8_t memory[0x10000]; /* Create memory for dynamic allocations with specific size */
@@ -221,13 +221,13 @@ gsm_ll_init(gsm_ll_t* ll) {
* If device has internal/external memory available,
* multiple memories may be used
*/
- gsm_mem_region_t mem_regions[] = {
+ lwgsm_mem_region_t mem_regions[] = {
{ memory, sizeof(memory) }
};
if (!initialized) {
- gsm_mem_assignmemory(mem_regions, GSM_ARRAYSIZE(mem_regions)); /* Assign memory for allocations to GSM library */
+ lwgsm_mem_assignmemory(mem_regions, LWGSM_ARRAYSIZE(mem_regions)); /* Assign memory for allocations to GSM library */
}
-#endif /* !GSM_CFG_MEM_CUSTOM */
+#endif /* !LWGSM_CFG_MEM_CUSTOM */
/* Step 2: Set AT port send function to use when we have data to transmit */
if (!initialized) {
@@ -237,7 +237,7 @@ gsm_ll_init(gsm_ll_t* ll) {
/* Step 3: Configure AT port to be able to send/receive data to/from GSM device */
configure_uart(ll->uart.baudrate); /* Initialize UART for communication */
initialized = 1;
- return gsmOK;
+ return lwgsmOK;
}
#endif /* !__DOXYGEN__ */
diff --git a/gsm_at_lib/src/system/gsm_mem_lwmem.c b/lwgsm/src/system/lwgsm_mem_lwmem.c
similarity index 75%
rename from gsm_at_lib/src/system/gsm_mem_lwmem.c
rename to lwgsm/src/system/lwgsm_mem_lwmem.c
index e6b76d15..cdcbd0ce 100644
--- a/gsm_at_lib/src/system/gsm_mem_lwmem.c
+++ b/lwgsm/src/system/lwgsm_mem_lwmem.c
@@ -1,10 +1,10 @@
/**
- * \file gsm_mem_lwmem.c
+ * \file lwgsm_mem_lwmem.c
* \brief Dynamic memory manager implemented with LwMEM
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,16 +26,16 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#include "gsm/gsm.h"
+#include "lwgsm/lwgsm.h"
-/* See gsm_mem.c file for function documentation on parameters and return values */
+/* See lwgsm_mem.c file for function documentation on parameters and return values */
-#if GSM_CFG_MEM_CUSTOM && !__DOXYGEN__
+#if LWGSM_CFG_MEM_CUSTOM && !__DOXYGEN__
/*
* Before this driver can be used, user must:
@@ -46,24 +46,24 @@
#include "lwmem/lwmem.h"
-void *
-gsm_mem_malloc(size_t size) {
+void*
+lwgsm_mem_malloc(size_t size) {
return lwmem_malloc(size);
}
-void *
-gsm_mem_realloc(void* ptr, size_t size) {
+void*
+lwgsm_mem_realloc(void* ptr, size_t size) {
return lwmem_realloc(ptr, size);
}
-void *
-gsm_mem_calloc(size_t num, size_t size) {
+void*
+lwgsm_mem_calloc(size_t num, size_t size) {
return lwmem_calloc(num, size);
}
void
-gsm_mem_free(void* ptr) {
+lwgsm_mem_free(void* ptr) {
lwmem_free(ptr);
}
-#endif /* GSM_CFG_MEM_CUSTOM && !__DOXYGEN__ */
\ No newline at end of file
+#endif /* LWGSM_CFG_MEM_CUSTOM && !__DOXYGEN__ */
\ No newline at end of file
diff --git a/lwgsm/src/system/lwgsm_sys_cmsis_os.c b/lwgsm/src/system/lwgsm_sys_cmsis_os.c
new file mode 100644
index 00000000..623d2467
--- /dev/null
+++ b/lwgsm/src/system/lwgsm_sys_cmsis_os.c
@@ -0,0 +1,209 @@
+/**
+ * \file lwgsm_sys_cmsis_os.c
+ * \brief System dependent functions for CMSIS-OS based operating system
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * This file is part of LwGSM - Lightweight GSM-AT library.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+#include "system/lwgsm_sys.h"
+#include "cmsis_os.h"
+
+#if !__DOXYGEN__
+
+static osMutexId_t sys_mutex;
+
+uint8_t
+lwgsm_sys_init(void) {
+ lwgsm_sys_mutex_create(&sys_mutex);
+ return 1;
+}
+
+uint32_t
+lwgsm_sys_now(void) {
+ return osKernelSysTick();
+}
+
+uint8_t
+lwgsm_sys_protect(void) {
+ lwgsm_sys_mutex_lock(&sys_mutex);
+ return 1;
+}
+
+uint8_t
+lwgsm_sys_unprotect(void) {
+ lwgsm_sys_mutex_unlock(&sys_mutex);
+ return 1;
+}
+
+uint8_t
+lwgsm_sys_mutex_create(lwgsm_sys_mutex_t* p) {
+ const osMutexAttr_t attr = {
+ .attr_bits = osMutexRecursive
+ };
+ *p = osMutexNew(&attr);
+ return *p != NULL;
+}
+
+uint8_t
+lwgsm_sys_mutex_delete(lwgsm_sys_mutex_t* p) {
+ return osMutexDelete(*p) == osOK;
+}
+
+uint8_t
+lwgsm_sys_mutex_lock(lwgsm_sys_mutex_t* p) {
+ return osMutexAcquire(*p, osWaitForever) == osOK;
+}
+
+uint8_t
+lwgsm_sys_mutex_unlock(lwgsm_sys_mutex_t* p) {
+ return osMutexRelease(*p) == osOK;
+}
+
+uint8_t
+lwgsm_sys_mutex_isvalid(lwgsm_sys_mutex_t* p) {
+ return p != NULL && *p != NULL;
+}
+
+uint8_t
+lwgsm_sys_mutex_invalid(lwgsm_sys_mutex_t* p) {
+ *p = LWGSM_SYS_MUTEX_NULL;
+ return 1;
+}
+
+uint8_t
+lwgsm_sys_sem_create(lwgsm_sys_sem_t* p, uint8_t cnt) {
+ return (*p = osSemaphoreNew(1, cnt > 0 ? 1 : 0, NULL)) != NULL;
+}
+
+uint8_t
+lwgsm_sys_sem_delete(lwgsm_sys_sem_t* p) {
+ return osSemaphoreDelete(*p) == osOK;
+}
+
+uint32_t
+lwgsm_sys_sem_wait(lwgsm_sys_sem_t* p, uint32_t timeout) {
+ uint32_t tick = osKernelSysTick();
+ return (osSemaphoreAcquire(*p, timeout == 0 ? osWaitForever : timeout) == osOK) ? (osKernelSysTick() - tick) : LWGSM_SYS_TIMEOUT;
+}
+
+uint8_t
+lwgsm_sys_sem_release(lwgsm_sys_sem_t* p) {
+ return osSemaphoreRelease(*p) == osOK;
+}
+
+uint8_t
+lwgsm_sys_sem_isvalid(lwgsm_sys_sem_t* p) {
+ return p != NULL && *p != NULL;
+}
+
+uint8_t
+lwgsm_sys_sem_invalid(lwgsm_sys_sem_t* p) {
+ *p = LWGSM_SYS_SEM_NULL;
+ return 1;
+}
+
+uint8_t
+lwgsm_sys_mbox_create(lwgsm_sys_mbox_t* b, size_t size) {
+ return (*b = osMessageQueueNew(size, sizeof(void*), NULL)) != NULL;
+}
+
+uint8_t
+lwgsm_sys_mbox_delete(lwgsm_sys_mbox_t* b) {
+ if (osMessageQueueGetCount(*b) > 0) {
+ return 0;
+ }
+ return osMessageQueueDelete(*b) == osOK;
+}
+
+uint32_t
+lwgsm_sys_mbox_put(lwgsm_sys_mbox_t* b, void* m) {
+ uint32_t tick = osKernelSysTick();
+ return osMessageQueuePut(*b, &m, 0, osWaitForever) == osOK ? (osKernelSysTick() - tick) : LWGSM_SYS_TIMEOUT;
+}
+
+uint32_t
+lwgsm_sys_mbox_get(lwgsm_sys_mbox_t* b, void** m, uint32_t timeout) {
+ uint32_t tick = osKernelSysTick();
+ return osMessageQueueGet(*b, m, NULL, timeout == 0 ? osWaitForever : timeout) == osOK ? (osKernelSysTick() - tick) : LWGSM_SYS_TIMEOUT;
+}
+
+uint8_t
+lwgsm_sys_mbox_putnow(lwgsm_sys_mbox_t* b, void* m) {
+ return osMessageQueuePut(*b, &m, 0, 0) == osOK;
+}
+
+uint8_t
+lwgsm_sys_mbox_getnow(lwgsm_sys_mbox_t* b, void** m) {
+ return osMessageQueueGet(*b, m, NULL, 0) == osOK;
+}
+
+uint8_t
+lwgsm_sys_mbox_isvalid(lwgsm_sys_mbox_t* b) {
+ return b != NULL && *b != NULL;
+}
+
+uint8_t
+lwgsm_sys_mbox_invalid(lwgsm_sys_mbox_t* b) {
+ *b = LWGSM_SYS_MBOX_NULL;
+ return 1;
+}
+
+uint8_t
+lwgsm_sys_thread_create(lwgsm_sys_thread_t* t, const char* name, lwgsm_sys_thread_fn thread_func, void* const arg, size_t stack_size, lwgsm_sys_thread_prio_t prio) {
+ lwgsm_sys_thread_t id;
+ const osThreadAttr_t thread_attr = {
+ .name = (char*)name,
+ .priority = (osPriority)prio,
+ .stack_size = stack_size > 0 ? stack_size : LWGSM_SYS_THREAD_SS
+ };
+
+ id = osThreadNew(thread_func, arg, &thread_attr);
+ if (t != NULL) {
+ *t = id;
+ }
+ return id != NULL;
+}
+
+uint8_t
+lwgsm_sys_thread_terminate(lwgsm_sys_thread_t* t) {
+ if (t != NULL) {
+ osThreadTerminate(*t);
+ } else {
+ osThreadExit();
+ }
+ return 1;
+}
+
+uint8_t
+lwgsm_sys_thread_yield(void) {
+ osThreadYield();
+ return 1;
+}
+
+#endif /* !__DOXYGEN__ */
diff --git a/lwgsm/src/system/lwgsm_sys_template.c b/lwgsm/src/system/lwgsm_sys_template.c
new file mode 100644
index 00000000..e2d07b65
--- /dev/null
+++ b/lwgsm/src/system/lwgsm_sys_template.c
@@ -0,0 +1,388 @@
+/**
+ * \file lwgsm_sys_template.c
+ * \brief System dependant functions
+ */
+
+/*
+ * Copyright (c) 2020 Tilen MAJERLE
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Tilen MAJERLE
+ * Version: v0.1.0
+ */
+#include "system/lwgsm_sys.h"
+#include "cmsis_os.h"
+
+static osMutexId sys_mutex;
+
+/**
+ * \brief Init system dependant parameters
+ *
+ * After this function is called,
+ * all other system functions must be fully ready.
+ *
+ * \return `1` on success, `0` otherwise
+ */
+uint8_t
+lwgsm_sys_init(void) {
+ lwgsm_sys_mutex_create(&sys_mutex);
+ return 1;
+}
+
+/**
+ * \brief Get current time in units of milliseconds
+ * \return Current time in units of milliseconds
+ */
+uint32_t
+lwgsm_sys_now(void) {
+ return osKernelSysTick();
+}
+
+/**
+ * \brief Protect middleware core
+ *
+ * Stack protection must support recursive mode.
+ * This function may be called multiple times,
+ * even if access has been granted before.
+ *
+ * \note Most operating systems support recursive mutexes.
+ * \return `1` on success, `0` otherwise
+ */
+uint8_t
+lwgsm_sys_protect(void) {
+ lwgsm_sys_mutex_lock(&sys_mutex);
+ return 1;
+}
+
+/**
+ * \brief Unprotect middleware core
+ *
+ * This function must follow number of calls of \ref lwgsm_sys_protect
+ * and unlock access only when counter reached back zero.
+ *
+ * \note Most operating systems support recursive mutexes.
+ * \return `1` on success, `0` otherwise
+ */
+uint8_t
+lwgsm_sys_unprotect(void) {
+ lwgsm_sys_mutex_unlock(&sys_mutex);
+ return 1;
+}
+
+/**
+ * \brief Create new recursive mutex
+ * \note Recursive mutex has to be created as it may be locked multiple times before unlocked
+ * \param[out] p: Pointer to mutex structure to allocate
+ * \return `1` on success, `0` otherwise
+ */
+uint8_t
+lwgsm_sys_mutex_create(lwgsm_sys_mutex_t* p) {
+ osMutexDef(MUT);
+ *p = osRecursiveMutexCreate(osMutex(MUT));
+ return *p != NULL;
+}
+
+/**
+ * \brief Delete recursive mutex from system
+ * \param[in] p: Pointer to mutex structure
+ * \return `1` on success, `0` otherwise
+ */
+uint8_t
+lwgsm_sys_mutex_delete(lwgsm_sys_mutex_t* p) {
+ return osMutexDelete(*p) == osOK;
+}
+
+/**
+ * \brief Lock recursive mutex, wait forever to lock
+ * \param[in] p: Pointer to mutex structure
+ * \return `1` on success, `0` otherwise
+ */
+uint8_t
+lwgsm_sys_mutex_lock(lwgsm_sys_mutex_t* p) {
+ return osRecursiveMutexWait(*p, osWaitForever) == osOK;
+}
+
+/**
+ * \brief Unlock recursive mutex
+ * \param[in] p: Pointer to mutex structure
+ * \return `1` on success, `0` otherwise
+ */
+uint8_t
+lwgsm_sys_mutex_unlock(lwgsm_sys_mutex_t* p) {
+ return osRecursiveMutexRelease(*p) == osOK;
+}
+
+/**
+ * \brief Check if mutex structure is valid system
+ * \param[in] p: Pointer to mutex structure
+ * \return `1` on success, `0` otherwise
+ */
+uint8_t
+lwgsm_sys_mutex_isvalid(lwgsm_sys_mutex_t* p) {
+ return p != NULL && *p != NULL;
+}
+
+/**
+ * \brief Set recursive mutex structure as invalid
+ * \param[in] p: Pointer to mutex structure
+ * \return `1` on success, `0` otherwise
+ */
+uint8_t
+lwgsm_sys_mutex_invalid(lwgsm_sys_mutex_t* p) {
+ *p = LWGSM_SYS_MUTEX_NULL;
+ return 1;
+}
+
+/**
+ * \brief Create a new binary semaphore and set initial state
+ * \note Semaphore may only have `1` token available
+ * \param[out] p: Pointer to semaphore structure to fill with result
+ * \param[in] cnt: Count indicating default semaphore state:
+ * `0`: Take semaphore token immediately
+ * `1`: Keep token available
+ * \return `1` on success, `0` otherwise
+ */
+uint8_t
+lwgsm_sys_sem_create(lwgsm_sys_sem_t* p, uint8_t cnt) {
+ osSemaphoreDef(SEM);
+ *p = osSemaphoreCreate(osSemaphore(SEM), 1);
+
+ if (*p != NULL && !cnt) {
+ osSemaphoreWait(*p, 0);
+ }
+ return *p != NULL;
+}
+
+/**
+ * \brief Delete binary semaphore
+ * \param[in] p: Pointer to semaphore structure
+ * \return `1` on success, `0` otherwise
+ */
+uint8_t
+lwgsm_sys_sem_delete(lwgsm_sys_sem_t* p) {
+ return osSemaphoreDelete(*p) == osOK;
+}
+
+/**
+ * \brief Wait for semaphore to be available
+ * \param[in] p: Pointer to semaphore structure
+ * \param[in] timeout: Timeout to wait in milliseconds. When `0` is applied, wait forever
+ * \return Number of milliseconds waited for semaphore to become available or
+ * \ref LWGSM_SYS_TIMEOUT if not available within given time
+ */
+uint32_t
+lwgsm_sys_sem_wait(lwgsm_sys_sem_t* p, uint32_t timeout) {
+ uint32_t tick = osKernelSysTick();
+ return (osSemaphoreWait(*p, !timeout ? osWaitForever : timeout) == osOK) ? (osKernelSysTick() - tick) : LWGSM_SYS_TIMEOUT;
+}
+
+/**
+ * \brief Release semaphore
+ * \param[in] p: Pointer to semaphore structure
+ * \return `1` on success, `0` otherwise
+ */
+uint8_t
+lwgsm_sys_sem_release(lwgsm_sys_sem_t* p) {
+ return osSemaphoreRelease(*p) == osOK;
+}
+
+/**
+ * \brief Check if semaphore is valid
+ * \param[in] p: Pointer to semaphore structure
+ * \return `1` on success, `0` otherwise
+ */
+uint8_t
+lwgsm_sys_sem_isvalid(lwgsm_sys_sem_t* p) {
+ return p != NULL && *p != NULL;
+}
+
+/**
+ * \brief Invalid semaphore
+ * \param[in] p: Pointer to semaphore structure
+ * \return `1` on success, `0` otherwise
+ */
+uint8_t
+lwgsm_sys_sem_invalid(lwgsm_sys_sem_t* p) {
+ *p = LWGSM_SYS_SEM_NULL;
+ return 1;
+}
+
+/**
+ * \brief Create a new message queue with entry type of `void *`
+ * \param[out] b: Pointer to message queue structure
+ * \param[in] size: Number of entries for message queue to hold
+ * \return `1` on success, `0` otherwise
+ */
+uint8_t
+lwgsm_sys_mbox_create(lwgsm_sys_mbox_t* b, size_t size) {
+ osMessageQDef(MBOX, size, void*);
+ *b = osMessageCreate(osMessageQ(MBOX), NULL);
+ return *b != NULL;
+}
+
+/**
+ * \brief Delete message queue
+ * \param[in] b: Pointer to message queue structure
+ * \return `1` on success, `0` otherwise
+ */
+uint8_t
+lwgsm_sys_mbox_delete(lwgsm_sys_mbox_t* b) {
+ if (osMessageWaiting(*b)) {
+ return 0;
+ }
+ return osMessageDelete(*b) == osOK;
+}
+
+/**
+ * \brief Put a new entry to message queue and wait until memory available
+ * \param[in] b: Pointer to message queue structure
+ * \param[in] m: Pointer to entry to insert to message queue
+ * \return Time in units of milliseconds needed to put a message to queue
+ */
+uint32_t
+lwgsm_sys_mbox_put(lwgsm_sys_mbox_t* b, void* m) {
+ uint32_t tick = osKernelSysTick();
+ return osMessagePut(*b, (uint32_t)m, osWaitForever) == osOK ? (osKernelSysTick() - tick) : LWGSM_SYS_TIMEOUT;
+}
+
+/**
+ * \brief Get a new entry from message queue with timeout
+ * \param[in] b: Pointer to message queue structure
+ * \param[in] m: Pointer to pointer to result to save value from message queue to
+ * \param[in] timeout: Maximal timeout to wait for new message. When `0` is applied, wait for unlimited time
+ * \return Time in units of milliseconds needed to put a message to queue
+ * or \ref LWGSM_SYS_TIMEOUT if it was not successful
+ */
+uint32_t
+lwgsm_sys_mbox_get(lwgsm_sys_mbox_t* b, void** m, uint32_t timeout) {
+ osEvent evt;
+ uint32_t time = osKernelSysTick();
+
+ evt = osMessageGet(*b, !timeout ? osWaitForever : timeout);
+ if (evt.status == osEventMessage) {
+ *m = evt.value.p;
+ return osKernelSysTick() - time;
+ }
+ return LWGSM_SYS_TIMEOUT;
+}
+
+/**
+ * \brief Put a new entry to message queue without timeout (now or fail)
+ * \param[in] b: Pointer to message queue structure
+ * \param[in] m: Pointer to message to save to queue
+ * \return `1` on success, `0` otherwise
+ */
+uint8_t
+lwgsm_sys_mbox_putnow(lwgsm_sys_mbox_t* b, void* m) {
+ return osMessagePut(*b, (uint32_t)m, 0) == osOK;
+}
+
+/**
+ * \brief Get an entry from message queue immediately
+ * \param[in] b: Pointer to message queue structure
+ * \param[in] m: Pointer to pointer to result to save value from message queue to
+ * \return `1` on success, `0` otherwise
+ */
+uint8_t
+lwgsm_sys_mbox_getnow(lwgsm_sys_mbox_t* b, void** m) {
+ osEvent evt;
+
+ evt = osMessageGet(*b, 0);
+ if (evt.status == osEventMessage) {
+ *m = evt.value.p;
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * \brief Check if message queue is valid
+ * \param[in] b: Pointer to message queue structure
+ * \return `1` on success, `0` otherwise
+ */
+uint8_t
+lwgsm_sys_mbox_isvalid(lwgsm_sys_mbox_t* b) {
+ return b != NULL && *b != NULL;
+}
+
+/**
+ * \brief Invalid message queue
+ * \param[in] b: Pointer to message queue structure
+ * \return `1` on success, `0` otherwise
+ */
+uint8_t
+lwgsm_sys_mbox_invalid(lwgsm_sys_mbox_t* b) {
+ *b = LWGSM_SYS_MBOX_NULL;
+ return 1;
+}
+
+/**
+ * \brief Create a new thread
+ * \param[out] t: Pointer to thread identifier if create was successful.
+ * It may be set to `NULL`
+ * \param[in] name: Name of a new thread
+ * \param[in] thread_func: Thread function to use as thread body
+ * \param[in] arg: Thread function argument
+ * \param[in] stack_size: Size of thread stack in uints of bytes. If set to 0, reserve default stack size
+ * \param[in] prio: Thread priority
+ * \return `1` on success, `0` otherwise
+ */
+uint8_t
+lwgsm_sys_thread_create(lwgsm_sys_thread_t* t, const char* name, lwgsm_sys_thread_fn thread_func,
+ void* const arg, size_t stack_size, lwgsm_sys_thread_prio_t prio) {
+ const osThreadDef_t thread_def = {
+ (char*)name,
+ (os_pthread)thread_func,
+ (osPriority)prio,
+ 0,
+ stack_size > 0 ? stack_size : LWGSM_SYS_THREAD_SS
+ };
+ lwgsm_sys_thread_t id;
+
+ id = osThreadCreate(&thread_def, arg);
+ if (t != NULL) {
+ *t = id;
+ }
+ return id != NULL;
+}
+
+/**
+ * \brief Terminate thread (shut it down and remove)
+ * \param[in] t: Pointer to thread handle to terminate.
+ * If set to `NULL`, terminate current thread (thread from where function is called)
+ * \return `1` on success, `0` otherwise
+ */
+uint8_t
+lwgsm_sys_thread_terminate(lwgsm_sys_thread_t* t) {
+ osThreadTerminate(t != NULL ? *t : NULL);
+ return 1;
+}
+
+/**
+ * \brief Yield current thread
+ * \return `1` on success, `0` otherwise
+ */
+uint8_t
+lwgsm_sys_thread_yield(void) {
+ osThreadYield();
+ return 1;
+}
diff --git a/gsm_at_lib/src/system/gsm_sys_win32.c b/lwgsm/src/system/lwgsm_sys_win32.c
similarity index 55%
rename from gsm_at_lib/src/system/gsm_sys_win32.c
rename to lwgsm/src/system/lwgsm_sys_win32.c
index 5018825f..7ba0d5ce 100644
--- a/gsm_at_lib/src/system/gsm_sys_win32.c
+++ b/lwgsm/src/system/lwgsm_sys_win32.c
@@ -1,10 +1,10 @@
-/**
- * \file gsm_sys_win32.c
+/**
+ * \file lwgsm_sys_win32.c
* \brief System dependant functions for WIN32
*/
/*
- * Copyright (c) 2019 Tilen MAJERLE
+ * Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,14 +26,14 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * This file is part of GSM-AT library.
+ * This file is part of LwGSM - Lightweight GSM-AT library.
*
* Author: Tilen MAJERLE
- * Version: v0.6.0
+ * Version: v0.1.0
*/
-#include "system/gsm_sys.h"
#include
#include
+#include "system/lwgsm_sys.h"
#if !__DOXYGEN__
@@ -41,15 +41,15 @@
* \brief Custom message queue implementation for WIN32
*/
typedef struct {
- gsm_sys_sem_t sem_not_empty; /*!< Semaphore indicates not empty */
- gsm_sys_sem_t sem_not_full; /*!< Semaphore indicates not full */
- gsm_sys_sem_t sem; /*!< Semaphore to lock access */
+ lwgsm_sys_sem_t sem_not_empty; /*!< Semaphore indicates not empty */
+ lwgsm_sys_sem_t sem_not_full; /*!< Semaphore indicates not full */
+ lwgsm_sys_sem_t sem; /*!< Semaphore to lock access */
size_t in, out, size;
void* entries[1];
} win32_mbox_t;
static LARGE_INTEGER freq, sys_start_time;
-static gsm_sys_mutex_t sys_mutex; /* Mutex ID for main protection */
+static lwgsm_sys_mutex_t sys_mutex; /* Mutex ID for main protection */
static uint8_t
mbox_is_full(win32_mbox_t* m) {
@@ -79,44 +79,44 @@ osKernelSysTick(void) {
}
uint8_t
-gsm_sys_init(void) {
+lwgsm_sys_init(void) {
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&sys_start_time);
- gsm_sys_mutex_create(&sys_mutex);
+ lwgsm_sys_mutex_create(&sys_mutex);
return 1;
}
uint32_t
-gsm_sys_now(void) {
+lwgsm_sys_now(void) {
return osKernelSysTick();
}
uint8_t
-gsm_sys_protect(void) {
- gsm_sys_mutex_lock(&sys_mutex);
+lwgsm_sys_protect(void) {
+ lwgsm_sys_mutex_lock(&sys_mutex);
return 1;
}
uint8_t
-gsm_sys_unprotect(void) {
- gsm_sys_mutex_unlock(&sys_mutex);
+lwgsm_sys_unprotect(void) {
+ lwgsm_sys_mutex_unlock(&sys_mutex);
return 1;
}
uint8_t
-gsm_sys_mutex_create(gsm_sys_mutex_t* p) {
+lwgsm_sys_mutex_create(lwgsm_sys_mutex_t* p) {
*p = CreateMutex(NULL, FALSE, NULL);
return *p != NULL;
}
uint8_t
-gsm_sys_mutex_delete(gsm_sys_mutex_t* p) {
+lwgsm_sys_mutex_delete(lwgsm_sys_mutex_t* p) {
return CloseHandle(*p);
}
uint8_t
-gsm_sys_mutex_lock(gsm_sys_mutex_t* p) {
+lwgsm_sys_mutex_lock(lwgsm_sys_mutex_t* p) {
DWORD ret;
ret = WaitForSingleObject(*p, INFINITE);
if (ret != WAIT_OBJECT_0) {
@@ -126,23 +126,23 @@ gsm_sys_mutex_lock(gsm_sys_mutex_t* p) {
}
uint8_t
-gsm_sys_mutex_unlock(gsm_sys_mutex_t* p) {
- return (uint8_t)ReleaseMutex(*p);
+lwgsm_sys_mutex_unlock(lwgsm_sys_mutex_t* p) {
+ return (uint8_t)ReleaseMutex(*p);
}
uint8_t
-gsm_sys_mutex_isvalid(gsm_sys_mutex_t* p) {
+lwgsm_sys_mutex_isvalid(lwgsm_sys_mutex_t* p) {
return p != NULL && *p != NULL;
}
uint8_t
-gsm_sys_mutex_invalid(gsm_sys_mutex_t* p) {
- *p = GSM_SYS_MUTEX_NULL;
+lwgsm_sys_mutex_invalid(lwgsm_sys_mutex_t* p) {
+ *p = LWGSM_SYS_MUTEX_NULL;
return 1;
}
uint8_t
-gsm_sys_sem_create(gsm_sys_sem_t* p, uint8_t cnt) {
+lwgsm_sys_sem_create(lwgsm_sys_sem_t* p, uint8_t cnt) {
HANDLE h;
h = CreateSemaphore(NULL, !!cnt, 1, NULL);
*p = h;
@@ -150,15 +150,15 @@ gsm_sys_sem_create(gsm_sys_sem_t* p, uint8_t cnt) {
}
uint8_t
-gsm_sys_sem_delete(gsm_sys_sem_t* p) {
+lwgsm_sys_sem_delete(lwgsm_sys_sem_t* p) {
return CloseHandle(*p);
}
uint32_t
-gsm_sys_sem_wait(gsm_sys_sem_t* p, uint32_t timeout) {
+lwgsm_sys_sem_wait(lwgsm_sys_sem_t* p, uint32_t timeout) {
DWORD ret;
uint32_t tick = osKernelSysTick();
-
+
if (timeout == 0) {
ret = WaitForSingleObject(*p, INFINITE);
return 1;
@@ -167,61 +167,61 @@ gsm_sys_sem_wait(gsm_sys_sem_t* p, uint32_t timeout) {
if (ret == WAIT_OBJECT_0) {
return 1;
} else {
- return GSM_SYS_TIMEOUT;
+ return LWGSM_SYS_TIMEOUT;
}
}
}
uint8_t
-gsm_sys_sem_release(gsm_sys_sem_t* p) {
+lwgsm_sys_sem_release(lwgsm_sys_sem_t* p) {
return ReleaseSemaphore(*p, 1, NULL);
}
uint8_t
-gsm_sys_sem_isvalid(gsm_sys_sem_t* p) {
+lwgsm_sys_sem_isvalid(lwgsm_sys_sem_t* p) {
return p != NULL && *p != NULL;
}
uint8_t
-gsm_sys_sem_invalid(gsm_sys_sem_t* p) {
- *p = GSM_SYS_SEM_NULL;
+lwgsm_sys_sem_invalid(lwgsm_sys_sem_t* p) {
+ *p = LWGSM_SYS_SEM_NULL;
return 1;
}
uint8_t
-gsm_sys_mbox_create(gsm_sys_mbox_t* b, size_t size) {
+lwgsm_sys_mbox_create(lwgsm_sys_mbox_t* b, size_t size) {
win32_mbox_t* mbox;
*b = NULL;
- mbox = malloc(sizeof(*mbox) + size * sizeof(void *));
+ mbox = malloc(sizeof(*mbox) + size * sizeof(void*));
if (mbox != NULL) {
memset(mbox, 0x00, sizeof(*mbox));
mbox->size = size + 1; /* Set it to 1 more as cyclic buffer has only one less than size */
- gsm_sys_sem_create(&mbox->sem, 1);
- gsm_sys_sem_create(&mbox->sem_not_empty, 0);
- gsm_sys_sem_create(&mbox->sem_not_full, 0);
+ lwgsm_sys_sem_create(&mbox->sem, 1);
+ lwgsm_sys_sem_create(&mbox->sem_not_empty, 0);
+ lwgsm_sys_sem_create(&mbox->sem_not_full, 0);
*b = mbox;
}
return *b != NULL;
}
uint8_t
-gsm_sys_mbox_delete(gsm_sys_mbox_t* b) {
+lwgsm_sys_mbox_delete(lwgsm_sys_mbox_t* b) {
win32_mbox_t* mbox = *b;
- gsm_sys_sem_delete(&mbox->sem);
- gsm_sys_sem_delete(&mbox->sem_not_full);
- gsm_sys_sem_delete(&mbox->sem_not_empty);
+ lwgsm_sys_sem_delete(&mbox->sem);
+ lwgsm_sys_sem_delete(&mbox->sem_not_full);
+ lwgsm_sys_sem_delete(&mbox->sem_not_empty);
free(mbox);
return 1;
}
uint32_t
-gsm_sys_mbox_put(gsm_sys_mbox_t* b, void* m) {
+lwgsm_sys_mbox_put(lwgsm_sys_mbox_t* b, void* m) {
win32_mbox_t* mbox = *b;
uint32_t time = osKernelSysTick(); /* Get start time */
- gsm_sys_sem_wait(&mbox->sem, 0); /* Wait for access */
+ lwgsm_sys_sem_wait(&mbox->sem, 0); /* Wait for access */
/*
* Since function is blocking until ready to write something to queue,
@@ -229,120 +229,99 @@ gsm_sys_mbox_put(gsm_sys_mbox_t* b, void* m) {
* to process the queue before we can write new value.
*/
while (mbox_is_full(mbox)) {
- gsm_sys_sem_release(&mbox->sem); /* Release semaphore */
- gsm_sys_sem_wait(&mbox->sem_not_full, 0); /* Wait for semaphore indicating not full */
- gsm_sys_sem_wait(&mbox->sem, 0); /* Wait availability again */
+ lwgsm_sys_sem_release(&mbox->sem); /* Release semaphore */
+ lwgsm_sys_sem_wait(&mbox->sem_not_full, 0); /* Wait for semaphore indicating not full */
+ lwgsm_sys_sem_wait(&mbox->sem, 0); /* Wait availability again */
}
mbox->entries[mbox->in] = m;
- if (mbox->in == mbox->out) { /* Was the previous state empty? */
- gsm_sys_sem_release(&mbox->sem_not_empty); /* Signal non-empty state */
- }
if (++mbox->in >= mbox->size) {
mbox->in = 0;
}
- gsm_sys_sem_release(&mbox->sem); /* Release access for other threads */
+ lwgsm_sys_sem_release(&mbox->sem_not_empty);/* Signal non-empty state */
+ lwgsm_sys_sem_release(&mbox->sem); /* Release access for other threads */
return osKernelSysTick() - time;
}
uint32_t
-gsm_sys_mbox_get(gsm_sys_mbox_t* b, void** m, uint32_t timeout) {
+lwgsm_sys_mbox_get(lwgsm_sys_mbox_t* b, void** m, uint32_t timeout) {
win32_mbox_t* mbox = *b;
- uint32_t time = osKernelSysTick(); /* Get current time */
- uint32_t spent_time;
+ uint32_t time;
+
+ time = osKernelSysTick();
/* Get exclusive access to message queue */
- if ((spent_time = gsm_sys_sem_wait(&mbox->sem, timeout)) == GSM_SYS_TIMEOUT) {
- return spent_time;
+ if (lwgsm_sys_sem_wait(&mbox->sem, timeout) == LWGSM_SYS_TIMEOUT) {
+ return LWGSM_SYS_TIMEOUT;
}
-
- /* Make sure we have something to read from queue. */
while (mbox_is_empty(mbox)) {
- gsm_sys_sem_release(&mbox->sem); /* Release semaphore and allow other threads to write something */
- /*
- * Timeout = 0 means unlimited time
- * Wait either unlimited time or for specific timeout
- */
- if (timeout == 0) {
- gsm_sys_sem_wait(&mbox->sem_not_empty, 0);
- } else {
- spent_time = gsm_sys_sem_wait(&mbox->sem_not_empty, timeout);
- if (spent_time == GSM_SYS_TIMEOUT) {
- return spent_time;
- }
+ lwgsm_sys_sem_release(&mbox->sem);
+ if (lwgsm_sys_sem_wait(&mbox->sem_not_empty, timeout) == LWGSM_SYS_TIMEOUT) {
+ return LWGSM_SYS_TIMEOUT;
}
- spent_time = gsm_sys_sem_wait(&mbox->sem, timeout); /* Wait again for exclusive access */
+ lwgsm_sys_sem_wait(&mbox->sem, timeout);
}
-
- /*
- * At this point, semaphore is not empty and
- * we have exclusive access to content
- */
*m = mbox->entries[mbox->out];
if (++mbox->out >= mbox->size) {
mbox->out = 0;
}
-
- /* Release it only if waiting for it */
- gsm_sys_sem_release(&mbox->sem_not_full); /* Release semaphore as it is not full */
- gsm_sys_sem_release(&mbox->sem); /* Release exclusive access to mbox */
+ lwgsm_sys_sem_release(&mbox->sem_not_full);
+ lwgsm_sys_sem_release(&mbox->sem);
return osKernelSysTick() - time;
}
uint8_t
-gsm_sys_mbox_putnow(gsm_sys_mbox_t* b, void* m) {
+lwgsm_sys_mbox_putnow(lwgsm_sys_mbox_t* b, void* m) {
win32_mbox_t* mbox = *b;
- gsm_sys_sem_wait(&mbox->sem, 0);
+ lwgsm_sys_sem_wait(&mbox->sem, 0);
if (mbox_is_full(mbox)) {
- gsm_sys_sem_release(&mbox->sem);
+ lwgsm_sys_sem_release(&mbox->sem);
return 0;
}
mbox->entries[mbox->in] = m;
if (mbox->in == mbox->out) {
- gsm_sys_sem_release(&mbox->sem_not_empty);
+ lwgsm_sys_sem_release(&mbox->sem_not_empty);
}
- mbox->in++;
- if (mbox->in >= mbox->size) {
+ if (++mbox->in >= mbox->size) {
mbox->in = 0;
}
- gsm_sys_sem_release(&mbox->sem);
+ lwgsm_sys_sem_release(&mbox->sem);
return 1;
}
uint8_t
-gsm_sys_mbox_getnow(gsm_sys_mbox_t* b, void** m) {
+lwgsm_sys_mbox_getnow(lwgsm_sys_mbox_t* b, void** m) {
win32_mbox_t* mbox = *b;
- gsm_sys_sem_wait(&mbox->sem, 0); /* Wait exclusive access */
+ lwgsm_sys_sem_wait(&mbox->sem, 0); /* Wait exclusive access */
if (mbox->in == mbox->out) {
- gsm_sys_sem_release(&mbox->sem); /* Release access */
+ lwgsm_sys_sem_release(&mbox->sem); /* Release access */
return 0;
}
*m = mbox->entries[mbox->out];
- mbox->out++;
- if (mbox->out >= mbox->size) {
+ if (++mbox->out >= mbox->size) {
mbox->out = 0;
}
- gsm_sys_sem_release(&mbox->sem_not_full); /* Queue not full anymore */
- gsm_sys_sem_release(&mbox->sem); /* Release semaphore */
+ lwgsm_sys_sem_release(&mbox->sem_not_full); /* Queue not full anymore */
+ lwgsm_sys_sem_release(&mbox->sem); /* Release semaphore */
return 1;
}
uint8_t
-gsm_sys_mbox_isvalid(gsm_sys_mbox_t* b) {
+lwgsm_sys_mbox_isvalid(lwgsm_sys_mbox_t* b) {
return b != NULL && *b != NULL; /* Return status if message box is valid */
}
uint8_t
-gsm_sys_mbox_invalid(gsm_sys_mbox_t* b) {
- *b = GSM_SYS_MBOX_NULL; /* Invalidate message box */
+lwgsm_sys_mbox_invalid(lwgsm_sys_mbox_t* b) {
+ *b = LWGSM_SYS_MBOX_NULL; /* Invalidate message box */
return 1;
}
uint8_t
-gsm_sys_thread_create(gsm_sys_thread_t* t, const char* name, gsm_sys_thread_fn thread_func, void* const arg, size_t stack_size, gsm_sys_thread_prio_t prio) {
+lwgsm_sys_thread_create(lwgsm_sys_thread_t* t, const char* name, lwgsm_sys_thread_fn thread_func, void* const arg, size_t stack_size, lwgsm_sys_thread_prio_t prio) {
HANDLE h;
DWORD id;
h = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)thread_func, arg, 0, &id);
@@ -353,7 +332,7 @@ gsm_sys_thread_create(gsm_sys_thread_t* t, const char* name, gsm_sys_thread_fn t
}
uint8_t
-gsm_sys_thread_terminate(gsm_sys_thread_t* t) {
+lwgsm_sys_thread_terminate(lwgsm_sys_thread_t* t) {
HANDLE h = NULL;
if (t == NULL) { /* Shall we terminate ourself? */
@@ -362,13 +341,13 @@ gsm_sys_thread_terminate(gsm_sys_thread_t* t) {
h = *t;
}
TerminateThread(h, 0);
- return 1;
+ return 1;
}
uint8_t
-gsm_sys_thread_yield(void) {
+lwgsm_sys_thread_yield(void) {
/* Not implemented */
- return 1;
+ return 1;
}
#endif /* !__DOXYGEN__ */
diff --git a/snippets/call.c b/snippets/call.c
new file mode 100644
index 00000000..8203c7de
--- /dev/null
+++ b/snippets/call.c
@@ -0,0 +1,61 @@
+/*
+ * Receive call and answer to it example
+ */
+#include "call.h"
+#include "lwgsm/lwgsm.h"
+
+#if !LWGSM_CFG_CALL
+#error "CALL must be enabled to run this example"
+#endif /* !LWGSM_CFG_CALL */
+
+static lwgsmr_t call_evt_func(lwgsm_evt_t* evt);
+
+/**
+ * \brief Start CALL example
+ */
+void
+call_start(void) {
+ /* Add custom callback */
+ lwgsm_evt_register(call_evt_func);
+
+ /* Enable calls */
+ if (lwgsm_call_enable(NULL, NULL, 1) == lwgsmOK) {
+ printf("Calls enabled. You may take your phone and call GSM device number.\r\n");
+ } else {
+ printf("Could not enable call functionality!\r\n");
+ }
+}
+
+/**
+ * \brief Event function for calls
+ * \param[in] evt: GSM event
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+ */
+static lwgsmr_t
+call_evt_func(lwgsm_evt_t* evt) {
+ switch (lwgsm_evt_get_type(evt)) {
+ case LWGSM_EVT_CALL_CHANGED: {
+ const lwgsm_call_t* call = lwgsm_evt_call_changed_get_call(evt);
+ if (call->state == LWGSM_CALL_STATE_ACTIVE) {
+ printf("Call is active!\r\n");
+
+ /* In case of mobile originated direction */
+ if (call->dir == LWGSM_CALL_DIR_MO) {
+ lwgsm_call_hangup(NULL, NULL, 0); /* Manually hangup call */
+ }
+ } else if (call->state == LWGSM_CALL_STATE_INCOMING) {
+ printf("Incoming call received! Phone number: %s\r\n", call->number);
+ lwgsm_call_answer(NULL, NULL, 0); /* Answer to a call */
+ } else if (call->state == LWGSM_CALL_STATE_DIALING) {
+ printf("Call is dialing!\r\n");
+ } else if (call->state == LWGSM_CALL_STATE_DISCONNECT) {
+ printf("Call ended!\r\n");
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ return lwgsmOK;
+}
diff --git a/snippets/call_sms.c b/snippets/call_sms.c
new file mode 100644
index 00000000..e424ba74
--- /dev/null
+++ b/snippets/call_sms.c
@@ -0,0 +1,119 @@
+/*
+ * SMS send and receive basic event based example
+ *
+ * Waits for received SMS and then replies with
+ */
+#include "call_sms.h"
+#include "lwgsm/lwgsm.h"
+
+#if !LWGSM_CFG_SMS || !LWGSM_CFG_CALL
+#error "SMS & CALL must be enabled to run this example"
+#endif /* !LWGSM_CFG_SMS || !LWGSM_CFG_CALL */
+
+static lwgsmr_t call_sms_evt_func(lwgsm_evt_t* evt);
+
+/**
+ * \brief SMS entry
+ */
+static lwgsm_sms_entry_t
+sms_entry;
+
+/**
+ * \brief Start CALL & SMS combined example
+ */
+void
+call_sms_start(void) {
+ /* Add custom callback */
+ lwgsm_evt_register(call_sms_evt_func);
+
+ /* First enable SMS functionality */
+ if (lwgsm_sms_enable(NULL, NULL, 1) == lwgsmOK) {
+ printf("SMS enabled. Send new SMS from your phone to device.\r\n");
+ } else {
+ printf("Cannot enable SMS functionality!\r\n");
+ }
+
+ /* Then enable call functionality */
+ if (lwgsm_call_enable(NULL, NULL, 1) == lwgsmOK) {
+ printf("Call enabled. You may now take your phone and call modem\r\n");
+ } else {
+ printf("Cannot enable call functionality!\r\n");
+ }
+
+ /* Now send SMS from phone to device */
+ printf("Start by sending SMS message or call device...\r\n");
+}
+
+/**
+ * \brief Event function for received SMS or calls
+ * \param[in] evt: GSM event
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+ */
+static lwgsmr_t
+call_sms_evt_func(lwgsm_evt_t* evt) {
+ switch (lwgsm_evt_get_type(evt)) {
+ case LWGSM_EVT_SMS_READY: { /* SMS is ready notification from device */
+ printf("SIM device SMS service is ready!\r\n");
+ break;
+ }
+ case LWGSM_EVT_SMS_RECV: { /* New SMS received indicator */
+ lwgsmr_t res;
+
+ printf("New SMS received!\r\n"); /* Notify user */
+
+ /* Try to read SMS */
+ res = lwgsm_sms_read(lwgsm_evt_sms_recv_get_mem(evt), lwgsm_evt_sms_recv_get_pos(evt), &sms_entry, 1, NULL, NULL, 0);
+ if (res == lwgsmOK) {
+ printf("SMS read in progress!\r\n");
+ } else {
+ printf("Cannot start SMS read procedure!\r\n");
+ }
+ break;
+ }
+ case LWGSM_EVT_SMS_READ: { /* SMS read event */
+ lwgsm_sms_entry_t* entry = lwgsm_evt_sms_read_get_entry(evt);
+ if (lwgsm_evt_sms_read_get_result(evt) == lwgsmOK && entry != NULL) {
+ /* Print SMS data */
+ printf("SMS read. From: %s, content: %s\r\n",
+ entry->number, entry->data
+ );
+
+ /* Try to send SMS back */
+ if (lwgsm_sms_send(entry->number, entry->data, NULL, NULL, 0) == lwgsmOK) {
+ printf("SMS send in progress!\r\n");
+ } else {
+ printf("Cannot start SMS send procedure!\r\n");
+ }
+
+ /* Delete SMS from device memory */
+ lwgsm_sms_delete(entry->mem, entry->pos, NULL, NULL, 0);
+ }
+ break;
+ }
+ case LWGSM_EVT_SMS_SEND: { /* SMS send event */
+ if (lwgsm_evt_sms_send_get_result(evt) == lwgsmOK) {
+ printf("SMS has been successfully sent!\r\n");
+ } else {
+ printf("SMS has not been sent successfully!\r\n");
+ }
+ break;
+ }
+
+ case LWGSM_EVT_CALL_READY: { /* Call is ready notification from device */
+ printf("SIM device Call service is ready!\r\n");
+ break;
+ }
+ case LWGSM_EVT_CALL_CHANGED: {
+ const lwgsm_call_t* call = lwgsm_evt_call_changed_get_call(evt);
+ if (call->state == LWGSM_CALL_STATE_INCOMING) { /* On incoming call */
+ lwgsm_call_hangup(NULL, NULL, 0); /* Hangup call */
+ lwgsm_sms_send(call->number, "Cannot answer call. Please send SMS\r\n", NULL, NULL, 0);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ return lwgsmOK;
+}
diff --git a/snippets/client.c b/snippets/client.c
new file mode 100644
index 00000000..28aaf8d3
--- /dev/null
+++ b/snippets/client.c
@@ -0,0 +1,100 @@
+#include "client.h"
+#include "lwgsm/lwgsm.h"
+#include "lwgsm/lwgsm_network_api.h"
+
+/* Host parameter */
+#define CONN_HOST "example.com"
+#define CONN_PORT 80
+
+static lwgsmr_t conn_callback_func(lwgsm_evt_t* evt);
+
+/**
+ * \brief Request data for connection
+ */
+static const
+uint8_t req_data[] = ""
+ "GET / HTTP/1.1\r\n"
+ "Host: " CONN_HOST "\r\n"
+ "Connection: close\r\n"
+ "\r\n";
+
+/**
+ * \brief Start a new connection(s) as client
+ */
+void
+client_connect(void) {
+ lwgsmr_t res;
+
+ /* Attach to GSM network */
+ lwgsm_network_request_attach();
+
+ /* Start a new connection as client in non-blocking mode */
+ if ((res = lwgsm_conn_start(NULL, LWGSM_CONN_TYPE_TCP, "example.com", 80, NULL, conn_callback_func, 0)) == lwgsmOK) {
+ printf("Connection to " CONN_HOST " started...\r\n");
+ } else {
+ printf("Cannot start connection to " CONN_HOST "!\r\n");
+ }
+}
+
+/**
+ * \brief Event callback function for connection-only
+ * \param[in] evt: Event information with data
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+ */
+static lwgsmr_t
+conn_callback_func(lwgsm_evt_t* evt) {
+ lwgsm_conn_p conn;
+ lwgsmr_t res;
+ uint8_t conn_num;
+
+ conn = lwgsm_conn_get_from_evt(evt); /* Get connection handle from event */
+ if (conn == NULL) {
+ return lwgsmERR;
+ }
+ conn_num = lwgsm_conn_getnum(conn); /* Get connection number for identification */
+ switch (lwgsm_evt_get_type(evt)) {
+ case LWGSM_EVT_CONN_ACTIVE: { /* Connection just active */
+ printf("Connection %d active!\r\n", (int)conn_num);
+ res = lwgsm_conn_send(conn, req_data, sizeof(req_data) - 1, NULL, 0); /* Start sending data in non-blocking mode */
+ if (res == lwgsmOK) {
+ printf("Sending request data to server...\r\n");
+ } else {
+ printf("Cannot send request data to server. Closing connection manually...\r\n");
+ lwgsm_conn_close(conn, 0); /* Close the connection */
+ }
+ break;
+ }
+ case LWGSM_EVT_CONN_CLOSE: { /* Connection closed */
+ if (lwgsm_evt_conn_close_is_forced(evt)) {
+ printf("Connection %d closed by client!\r\n", (int)conn_num);
+ } else {
+ printf("Connection %d closed by remote side!\r\n", (int)conn_num);
+ }
+ break;
+ }
+ case LWGSM_EVT_CONN_SEND: { /* Data send event */
+ lwgsmr_t res = lwgsm_evt_conn_send_get_result(evt);
+ if (res == lwgsmOK) {
+ printf("Data sent successfully on connection %d...waiting to receive data from remote side...\r\n", (int)conn_num);
+ } else {
+ printf("Error while sending data on connection %d!\r\n", (int)conn_num);
+ }
+ break;
+ }
+ case LWGSM_EVT_CONN_RECV: { /* Data received from remote side */
+ lwgsm_pbuf_p pbuf = lwgsm_evt_conn_recv_get_buff(evt);
+ lwgsm_conn_recved(conn, pbuf); /* Notify stack about received pbuf */
+ printf("Received %d bytes on connection %d..\r\n", (int)lwgsm_pbuf_length(pbuf, 1), (int)conn_num);
+ break;
+ }
+ case LWGSM_EVT_CONN_ERROR: { /* Error connecting to server */
+ const char* host = lwgsm_evt_conn_error_get_host(evt);
+ lwgsm_port_t port = lwgsm_evt_conn_error_get_port(evt);
+ printf("Error connecting to %s:%d\r\n", host, (int)port);
+ break;
+ }
+ default:
+ break;
+ }
+ return lwgsmOK;
+}
diff --git a/snippets/device_info.c b/snippets/device_info.c
new file mode 100644
index 00000000..47376be9
--- /dev/null
+++ b/snippets/device_info.c
@@ -0,0 +1,33 @@
+/*
+ * Read device information
+ */
+#include "lwgsm/lwgsm.h"
+
+/**
+ * \brief Device info string array
+ */
+static char dev_str[20];
+
+/**
+ * \brief Start SMS send receive procedure
+ */
+void
+read_device_info(void) {
+ /* Read information */
+
+ /* Read device manufacturer */
+ lwgsm_device_get_manufacturer(dev_str, sizeof(dev_str), NULL, NULL, 1);
+ printf("Manuf: %s\r\n", dev_str);
+
+ /* Read device model */
+ lwgsm_device_get_model(dev_str, sizeof(dev_str), NULL, NULL, 1);
+ printf("Model: %s\r\n", dev_str);
+
+ /* Read device serial number */
+ lwgsm_device_get_serial_number(dev_str, sizeof(dev_str), NULL, NULL, 1);
+ printf("Serial: %s\r\n", dev_str);
+
+ /* Read device revision */
+ lwgsm_device_get_revision(dev_str, sizeof(dev_str), NULL, NULL, 1);
+ printf("Revision: %s\r\n", dev_str);
+}
diff --git a/snippets/include/call.h b/snippets/include/call.h
new file mode 100644
index 00000000..51456513
--- /dev/null
+++ b/snippets/include/call.h
@@ -0,0 +1,14 @@
+#ifndef SNIPPET_HDR_CALL_H
+#define SNIPPET_HDR_CALL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+void call_start(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SNIPPET_HDR_CALL_H */
diff --git a/snippets/include/call_sms.h b/snippets/include/call_sms.h
new file mode 100644
index 00000000..2ff99aba
--- /dev/null
+++ b/snippets/include/call_sms.h
@@ -0,0 +1,14 @@
+#ifndef SNIPPET_HDR_CALL_SMS_H
+#define SNIPPET_HDR_CALL_SMS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+void call_sms_start(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SNIPPET_HDR_CALL_SMS_H */
diff --git a/snippets/include/client.h b/snippets/include/client.h
new file mode 100644
index 00000000..eb1d40ff
--- /dev/null
+++ b/snippets/include/client.h
@@ -0,0 +1,14 @@
+#ifndef SNIPPET_HDR_CLIENT_H
+#define SNIPPET_HDR_CLIENT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+void client_connect(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SNIPPET_HDR_CLIENT_H */
diff --git a/snippets/include/device_info.h b/snippets/include/device_info.h
new file mode 100644
index 00000000..0bf1de1d
--- /dev/null
+++ b/snippets/include/device_info.h
@@ -0,0 +1,14 @@
+#ifndef SNIPPET_HDR_DEVICE_INFO_H
+#define SNIPPET_HDR_DEVICE_INFO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+void read_device_info(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SNIPPET_HDR_DEVICE_INFO_H */
diff --git a/snippets/include/mqtt_client_api.h b/snippets/include/mqtt_client_api.h
index 16d6e679..efacd6a8 100644
--- a/snippets/include/mqtt_client_api.h
+++ b/snippets/include/mqtt_client_api.h
@@ -1,14 +1,14 @@
-#ifndef __MQTT_CLIENT_API_H
-#define __MQTT_CLIENT_API_H
+#ifndef SNIPPET_HDR_MQTT_CLIENT_API_H
+#define SNIPPET_HDR_MQTT_CLIENT_API_H
#ifdef __cplusplus
extern "C" {
-#endif
+#endif /* __cplusplus */
void mqtt_client_api_thread(void const* arg);
#ifdef __cplusplus
}
-#endif
+#endif /* __cplusplus */
-#endif
+#endif /* SNIPPET_HDR_MQTT_CLIENT_API_H */
diff --git a/snippets/include/netconn_client.h b/snippets/include/netconn_client.h
index f07e5402..a6e9d7d5 100644
--- a/snippets/include/netconn_client.h
+++ b/snippets/include/netconn_client.h
@@ -1,14 +1,14 @@
-#ifndef __NETCONN_CLIENT_H
-#define __NETCONN_CLIENT_H
+#ifndef SNIPPET_HDR_NETCONN_CLIENT_H
+#define SNIPPET_HDR_NETCONN_CLIENT_H
#ifdef __cplusplus
extern "C" {
-#endif
+#endif /* __cplusplus */
void netconn_client_thread(void const* arg);
#ifdef __cplusplus
}
-#endif
+#endif /* __cplusplus */
-#endif
+#endif /* SNIPPET_HDR_NETCONN_CLIENT_H */
diff --git a/snippets/include/network_apn_settings.h b/snippets/include/network_apn_settings.h
index 781e3282..26e35723 100644
--- a/snippets/include/network_apn_settings.h
+++ b/snippets/include/network_apn_settings.h
@@ -1,9 +1,11 @@
-#ifndef __NETWORK_APN_SETTINGS_H
-#define __NETWORK_APN_SETTINGS_H
+#ifndef SNIPPET_HDR_NETWORK_APN_SETTINGS_H
+#define SNIPPET_HDR_NETWORK_APN_SETTINGS_H
+
+#include "lwgsm/lwgsm_network_api.h"
#ifdef __cplusplus
extern "C" {
-#endif
+#endif /* __cplusplus */
/* APN settings to attach to network */
#define NETWORK_APN "internet"
@@ -12,6 +14,6 @@ extern "C" {
#ifdef __cplusplus
}
-#endif
+#endif /* __cplusplus */
-#endif
+#endif /* SNIPPET_HDR_NETWORK_APN_SETTINGS_H */
diff --git a/snippets/include/network_utils.h b/snippets/include/network_utils.h
index a90f20ba..b567a939 100644
--- a/snippets/include/network_utils.h
+++ b/snippets/include/network_utils.h
@@ -1,19 +1,19 @@
-#ifndef __NETWORK_UTILS_H
-#define __NETWORK_UTILS_H
+#ifndef SNIPPET_HDR_NETWORK_UTILS_H
+#define SNIPPET_HDR_NETWORK_UTILS_H
+
+#include
+#include "lwgsm/lwgsm.h"
#ifdef __cplusplus
extern "C" {
-#endif
-
-#include
-#include "gsm/gsm.h"
+#endif /* __cplusplus */
-void network_utils_process_reg_change(gsm_evt_t* evt);
-void network_utils_process_curr_operator(gsm_evt_t* evt);
-void network_utils_process_rssi(gsm_evt_t* evt);
+void network_utils_process_reg_change(lwgsm_evt_t* evt);
+void network_utils_process_curr_operator(lwgsm_evt_t* evt);
+void network_utils_process_rssi(lwgsm_evt_t* evt);
#ifdef __cplusplus
}
-#endif
+#endif /* __cplusplus */
-#endif
+#endif /* SNIPPET_HDR_NETWORK_UTILS_H */
diff --git a/snippets/include/sim_manager.h b/snippets/include/sim_manager.h
index 5f9b283b..3a3596ed 100644
--- a/snippets/include/sim_manager.h
+++ b/snippets/include/sim_manager.h
@@ -1,16 +1,16 @@
-#ifndef __SIM_MANAGER_H
-#define __SIM_MANAGER_H
+#ifndef SNIPPET_HDR_SIM_MANAGER_H
+#define SNIPPET_HDR_SIM_MANAGER_H
+
+#include
#ifdef __cplusplus
extern "C" {
-#endif
-
-#include
+#endif /* __cplusplus */
uint8_t configure_sim_card(void);
#ifdef __cplusplus
}
-#endif
+#endif /* __cplusplus */
-#endif
+#endif /* SNIPPET_HDR_SIM_MANAGER_H */
diff --git a/snippets/include/sms_send_receive.h b/snippets/include/sms_send_receive.h
index 0af5e0bb..09fea5f4 100644
--- a/snippets/include/sms_send_receive.h
+++ b/snippets/include/sms_send_receive.h
@@ -1,14 +1,14 @@
-#ifndef __SMS_SEND_RECEIVE_H
-#define __SMS_SEND_RECEIVE_H
+#ifndef SNIPPET_HDR_SMS_SEND_RECEIVE_H
+#define SNIPPET_HDR_SMS_SEND_RECEIVE_H
#ifdef __cplusplus
extern "C" {
-#endif
+#endif /* __cplusplus */
-void sms_send_receive_thread(void const* arg);
+void sms_send_receive_start(void);
#ifdef __cplusplus
}
-#endif
+#endif /* __cplusplus */
-#endif
+#endif /* SNIPPET_HDR_SMS_SEND_RECEIVE_H */
diff --git a/snippets/include/sms_send_receive_thread.h b/snippets/include/sms_send_receive_thread.h
new file mode 100644
index 00000000..4bbfd7b6
--- /dev/null
+++ b/snippets/include/sms_send_receive_thread.h
@@ -0,0 +1,14 @@
+#ifndef SNIPPET_HDR_SMS_SEND_RECEIVE_THREAD_H
+#define SNIPPET_HDR_SMS_SEND_RECEIVE_THREAD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+void sms_send_receive_thread(void const* arg);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SNIPPET_HDR_SMS_SEND_RECEIVE_THREAD_H */
diff --git a/snippets/mqtt_client_api.c b/snippets/mqtt_client_api.c
index 40bdb1d5..a303c362 100644
--- a/snippets/mqtt_client_api.c
+++ b/snippets/mqtt_client_api.c
@@ -4,21 +4,21 @@
* Once device is connected to network,
* it will try to connect to mosquitto test server and start the MQTT.
*
- * If successfully connected, it will publish data to "gsm_mqtt_topic" topic every x seconds.
+ * If successfully connected, it will publish data to "lwgsm_mqtt_topic" topic every x seconds.
*
* To check if data are sent, you can use mqtt-spy PC software to inspect
* test.mosquitto.org server and subscribe to publishing topic
*/
-#include "gsm/apps/gsm_mqtt_client_api.h"
+#include "lwgsm/apps/lwgsm_mqtt_client_api.h"
#include "mqtt_client_api.h"
-#include "gsm/gsm_mem.h"
-#include "gsm/gsm_network_api.h"
+#include "lwgsm/lwgsm_mem.h"
+#include "lwgsm/lwgsm_network_api.h"
/**
* \brief Connection information for MQTT CONNECT packet
*/
-static const gsm_mqtt_client_info_t
+static const lwgsm_mqtt_client_info_t
mqtt_client_info = {
.keep_alive = 10,
@@ -52,19 +52,19 @@ generate_random(char* str) {
*/
void
mqtt_client_api_thread(void const* arg) {
- gsm_mqtt_client_api_p client;
- gsm_mqtt_conn_status_t conn_status;
- gsm_mqtt_client_api_buf_p buf;
- gsmr_t res;
+ lwgsm_mqtt_client_api_p client;
+ lwgsm_mqtt_conn_status_t conn_status;
+ lwgsm_mqtt_client_api_buf_p buf;
+ lwgsmr_t res;
char random_str[10];
/* Request network attach */
- while (gsm_network_request_attach() != gsmOK) {
- gsm_delay(1000);
+ while (lwgsm_network_request_attach() != lwgsmOK) {
+ lwgsm_delay(1000);
}
/* Create new MQTT API */
- client = gsm_mqtt_client_api_new(256, 128);
+ client = lwgsm_mqtt_client_api_new(256, 128);
if (client == NULL) {
goto terminate;
}
@@ -74,19 +74,19 @@ mqtt_client_api_thread(void const* arg) {
printf("Joining MQTT server\r\n");
/* Try to join */
- conn_status = gsm_mqtt_client_api_connect(client, "mqtt.mydevices.com", 1883, &mqtt_client_info);
- if (conn_status == GSM_MQTT_CONN_STATUS_ACCEPTED) {
+ conn_status = lwgsm_mqtt_client_api_connect(client, "mqtt.mydevices.com", 1883, &mqtt_client_info);
+ if (conn_status == LWGSM_MQTT_CONN_STATUS_ACCEPTED) {
printf("Connected and accepted!\r\n");
printf("Client is ready to subscribe and publish to new messages\r\n");
} else {
printf("Connect API response: %d\r\n", (int)conn_status);
- gsm_delay(5000);
+ lwgsm_delay(5000);
continue;
}
/* Subscribe to topics */
sprintf(mqtt_topic_str, "v1/%s/things/%s/cmd/#", mqtt_client_info.user, mqtt_client_info.id);
- if (gsm_mqtt_client_api_subscribe(client, mqtt_topic_str, GSM_MQTT_QOS_AT_LEAST_ONCE) == gsmOK) {
+ if (lwgsm_mqtt_client_api_subscribe(client, mqtt_topic_str, LWGSM_MQTT_QOS_AT_LEAST_ONCE) == lwgsmOK) {
printf("Subscribed to topic\r\n");
} else {
printf("Problem subscribing to topic!\r\n");
@@ -94,32 +94,32 @@ mqtt_client_api_thread(void const* arg) {
while (1) {
/* Receive MQTT packet with 1000ms timeout */
- res = gsm_mqtt_client_api_receive(client, &buf, 5000);
- if (res == gsmOK) {
+ res = lwgsm_mqtt_client_api_receive(client, &buf, 5000);
+ if (res == lwgsmOK) {
if (buf != NULL) {
printf("Publish received!\r\n");
printf("Topic: %s, payload: %s\r\n", buf->topic, buf->payload);
- gsm_mqtt_client_api_buf_free(buf);
+ lwgsm_mqtt_client_api_buf_free(buf);
buf = NULL;
}
- } else if (res == gsmCLOSED) {
+ } else if (res == lwgsmCLOSED) {
printf("MQTT connection closed!\r\n");
break;
- } else if (res == gsmTIMEOUT) {
+ } else if (res == lwgsmTIMEOUT) {
printf("Timeout on MQTT receive function. Manually publishing.\r\n");
/* Publish data on channel 1 */
generate_random(random_str);
sprintf(mqtt_topic_str, "v1/%s/things/%s/data/1", mqtt_client_info.user, mqtt_client_info.id);
- gsm_mqtt_client_api_publish(client, mqtt_topic_str, random_str, strlen(random_str), GSM_MQTT_QOS_AT_LEAST_ONCE, 0);
+ lwgsm_mqtt_client_api_publish(client, mqtt_topic_str, random_str, strlen(random_str), LWGSM_MQTT_QOS_AT_LEAST_ONCE, 0);
}
}
goto terminate;
}
-terminate:
- gsm_mqtt_client_api_delete(client);
- gsm_network_request_detach();
+terminate:
+ lwgsm_mqtt_client_api_delete(client);
+ lwgsm_network_request_detach();
printf("MQTT client thread terminate\r\n");
- gsm_sys_thread_terminate(NULL);
+ lwgsm_sys_thread_terminate(NULL);
}
diff --git a/snippets/netconn_client.c b/snippets/netconn_client.c
index 80026583..743c1d45 100644
--- a/snippets/netconn_client.c
+++ b/snippets/netconn_client.c
@@ -1,8 +1,8 @@
#include "netconn_client.h"
-#include "gsm/gsm.h"
-#include "gsm/gsm_network_api.h"
+#include "lwgsm/lwgsm.h"
+#include "lwgsm/lwgsm_network_api.h"
-#if GSM_CFG_NETCONN
+#if LWGSM_CFG_NETCONN
/**
* \brief Host and port settings
@@ -15,10 +15,10 @@
*/
static const char
request_header[] = ""
-"GET / HTTP/1.1\r\n"
-"Host: " NETCONN_HOST "\r\n"
-"Connection: close\r\n"
-"\r\n";
+ "GET / HTTP/1.1\r\n"
+ "Host: " NETCONN_HOST "\r\n"
+ "Connection: close\r\n"
+ "\r\n";
/**
* \brief Netconn client thread implementation
@@ -26,14 +26,14 @@ request_header[] = ""
*/
void
netconn_client_thread(void const* arg) {
- gsmr_t res;
- gsm_pbuf_p pbuf;
- gsm_netconn_p client;
- gsm_sys_sem_t* sem = (void *)arg;
+ lwgsmr_t res;
+ lwgsm_pbuf_p pbuf;
+ lwgsm_netconn_p client;
+ lwgsm_sys_sem_t* sem = (void*)arg;
/* Request attach to network */
- while (gsm_network_request_attach() != gsmOK) {
- gsm_delay(1000);
+ while (lwgsm_network_request_attach() != lwgsmOK) {
+ lwgsm_delay(1000);
}
/*
@@ -41,7 +41,7 @@ netconn_client_thread(void const* arg) {
* connection and initialize system message boxes
* to accept received packet buffers
*/
- client = gsm_netconn_new(GSM_NETCONN_TYPE_TCP);
+ client = lwgsm_netconn_new(LWGSM_NETCONN_TYPE_TCP);
if (client != NULL) {
/*
* Connect to external server as client
@@ -49,14 +49,14 @@ netconn_client_thread(void const* arg) {
*
* Function will block thread until we are successfully connected (or not) to server
*/
- res = gsm_netconn_connect(client, NETCONN_HOST, NETCONN_PORT);
- if (res == gsmOK) { /* Are we successfully connected? */
+ res = lwgsm_netconn_connect(client, NETCONN_HOST, NETCONN_PORT);
+ if (res == lwgsmOK) { /* Are we successfully connected? */
printf("Connected to " NETCONN_HOST "\r\n");
- res = gsm_netconn_write(client, request_header, sizeof(request_header) - 1); /* Send data to server */
- if (res == gsmOK) {
- res = gsm_netconn_flush(client);/* Flush data to output */
+ res = lwgsm_netconn_write(client, request_header, sizeof(request_header) - 1); /* Send data to server */
+ if (res == lwgsmOK) {
+ res = lwgsm_netconn_flush(client);/* Flush data to output */
}
- if (res == gsmOK) { /* Were data sent? */
+ if (res == lwgsmOK) { /* Were data sent? */
printf("Data were successfully sent to server\r\n");
/*
@@ -75,15 +75,15 @@ netconn_client_thread(void const* arg) {
* Returned status will give you info in case connection
* was closed too early from remote side
*/
- res = gsm_netconn_receive(client, &pbuf);
- if (res == gsmCLOSED) { /* Was the connection closed? This can be checked by return status of receive function */
+ res = lwgsm_netconn_receive(client, &pbuf);
+ if (res == lwgsmCLOSED) { /* Was the connection closed? This can be checked by return status of receive function */
printf("Connection closed by remote side...\r\n");
break;
- } else if (res == gsmTIMEOUT) {
+ } else if (res == lwgsmTIMEOUT) {
printf("Netconn timeout while receiving data. You may try multiple readings before deciding to close manually\r\n");
}
- if (res == gsmOK && pbuf != NULL) { /* Make sure we have valid packet buffer */
+ if (res == lwgsmOK && pbuf != NULL) { /* Make sure we have valid packet buffer */
/*
* At this point read and manipulate
* with received buffer and check if you expect more data
@@ -91,8 +91,8 @@ netconn_client_thread(void const* arg) {
* After you are done using it, it is important
* you free the memory otherwise memory leaks will appear
*/
- printf("Received new data packet of %d bytes\r\n", (int)gsm_pbuf_length(pbuf, 1));
- gsm_pbuf_free(pbuf); /* Free the memory after usage */
+ printf("Received new data packet of %d bytes\r\n", (int)lwgsm_pbuf_length(pbuf, 1));
+ lwgsm_pbuf_free(pbuf); /* Free the memory after usage */
pbuf = NULL;
}
} while (1);
@@ -104,20 +104,20 @@ netconn_client_thread(void const* arg) {
* Check if connection was closed by remote server
* and in case it wasn't, close it manually
*/
- if (res != gsmCLOSED) {
- gsm_netconn_close(client);
+ if (res != lwgsmCLOSED) {
+ lwgsm_netconn_close(client);
}
} else {
printf("Cannot connect to remote host %s:%d!\r\n", NETCONN_HOST, NETCONN_PORT);
}
- gsm_netconn_delete(client); /* Delete netconn structure */
+ lwgsm_netconn_delete(client); /* Delete netconn structure */
}
- gsm_network_request_detach(); /* Detach from network */
+ lwgsm_network_request_detach(); /* Detach from network */
- if (gsm_sys_sem_isvalid(sem)) {
- gsm_sys_sem_release(sem);
+ if (lwgsm_sys_sem_isvalid(sem)) {
+ lwgsm_sys_sem_release(sem);
}
- gsm_sys_thread_terminate(NULL); /* Terminate current thread */
+ lwgsm_sys_thread_terminate(NULL); /* Terminate current thread */
}
-#endif /* GSM_CFG_NETCONN */
+#endif /* LWGSM_CFG_NETCONN */
diff --git a/snippets/network_utils.c b/snippets/network_utils.c
index cb3c05d0..aadc468e 100644
--- a/snippets/network_utils.c
+++ b/snippets/network_utils.c
@@ -1,5 +1,5 @@
#include "network_utils.h"
-#include "gsm/gsm.h"
+#include "lwgsm/lwgsm.h"
/**
* \brief RSSI state on network
@@ -12,22 +12,31 @@ rssi;
* \param[in] evt: GSM event data
*/
void
-network_utils_process_reg_change(gsm_evt_t* evt) {
- gsm_network_reg_status_t stat;
+network_utils_process_reg_change(lwgsm_evt_t* evt) {
+ lwgsm_network_reg_status_t stat;
- stat = gsm_network_get_reg_status(); /* Get network status */
+ stat = lwgsm_network_get_reg_status(); /* Get network status */
/* Print to console */
printf("Network registration status changed. New status is: ");
switch (stat) {
- case GSM_NETWORK_REG_STATUS_CONNECTED: printf("Connected to home network!\r\n"); break;
- case GSM_NETWORK_REG_STATUS_CONNECTED_ROAMING: printf("Connected to network and roaming!\r\n"); break;
- case GSM_NETWORK_REG_STATUS_SEARCHING: printf("Searching for network!\r\n"); break;
- case GSM_NETWORK_REG_STATUS_SIM_ERR: printf("SIM CARD ERROR!\r\n"); break;
- default: printf("Other\r\n");
+ case LWGSM_NETWORK_REG_STATUS_CONNECTED:
+ printf("Connected to home network!\r\n");
+ break;
+ case LWGSM_NETWORK_REG_STATUS_CONNECTED_ROAMING:
+ printf("Connected to network and roaming!\r\n");
+ break;
+ case LWGSM_NETWORK_REG_STATUS_SEARCHING:
+ printf("Searching for network!\r\n");
+ break;
+ case LWGSM_NETWORK_REG_STATUS_SIM_ERR:
+ printf("SIM CARD ERROR!\r\n");
+ break;
+ default:
+ printf("Other\r\n");
}
- GSM_UNUSED(evt);
+ LWGSM_UNUSED(evt);
}
/**
@@ -35,31 +44,38 @@ network_utils_process_reg_change(gsm_evt_t* evt) {
* \param[in] evt: GSM event data
*/
void
-network_utils_process_curr_operator(gsm_evt_t* evt) {
- const gsm_operator_curr_t* o;
- o = gsm_evt_network_operator_get_current(evt);
+network_utils_process_curr_operator(lwgsm_evt_t* evt) {
+ const lwgsm_operator_curr_t* o;
+ o = lwgsm_evt_network_operator_get_current(evt);
if (o != NULL) {
switch (o->format) {
- case GSM_OPERATOR_FORMAT_LONG_NAME: printf("Operator long name: %s\r\n", o->data.long_name); break;
- case GSM_OPERATOR_FORMAT_SHORT_NAME: printf("Operator short name: %s\r\n", o->data.short_name); break;
- case GSM_OPERATOR_FORMAT_NUMBER: printf("Operator number: %d\r\n", (int)o->data.num); break;
- default: break;
+ case LWGSM_OPERATOR_FORMAT_LONG_NAME:
+ printf("Operator long name: %s\r\n", o->data.long_name);
+ break;
+ case LWGSM_OPERATOR_FORMAT_SHORT_NAME:
+ printf("Operator short name: %s\r\n", o->data.short_name);
+ break;
+ case LWGSM_OPERATOR_FORMAT_NUMBER:
+ printf("Operator number: %d\r\n", (int)o->data.num);
+ break;
+ default:
+ break;
}
}
/* Start RSSI info */
- gsm_network_rssi(&rssi, NULL, NULL, 0);
+ lwgsm_network_rssi(&rssi, NULL, NULL, 0);
}
-/**
+/**
* \brief Process and print RSSI info
* \param[in] evt: GSM event data
*/
void
-network_utils_process_rssi(gsm_evt_t* evt) {
+network_utils_process_rssi(lwgsm_evt_t* evt) {
int16_t rssi;
/* Get RSSi from event */
- rssi = gsm_evt_signal_strength_get_rssi(evt);
+ rssi = lwgsm_evt_signal_strength_get_rssi(evt);
/* Print message to screen */
printf("Network operator RSSI: %d dBm\r\n", (int)rssi);
diff --git a/snippets/sim_manager.c b/snippets/sim_manager.c
index c43a16cb..162f76aa 100644
--- a/snippets/sim_manager.c
+++ b/snippets/sim_manager.c
@@ -1,17 +1,17 @@
#include "sim_manager.h"
-#include "gsm/gsm.h"
+#include "lwgsm/lwgsm.h"
/**
* \brief SIM card pin code
*/
-static const char *
-pin_code = "7600";
+static const char*
+pin_code = "7958";
/**
* \brief SIM card puk code
*/
-static const char *
-puk_code = "08475703";
+static const char*
+puk_code = "10663647";
/**
* \brief Configure and enable SIM card
@@ -19,9 +19,9 @@ puk_code = "08475703";
*/
uint8_t
configure_sim_card(void) {
- GSM_UNUSED(puk_code);
+ LWGSM_UNUSED(puk_code);
if (pin_code != NULL && strlen(pin_code)) {
- if (gsm_sim_pin_enter(pin_code, NULL, NULL, 1) == gsmOK) {
+ if (lwgsm_sim_pin_enter(pin_code, NULL, NULL, 1) == lwgsmOK) {
return 1;
}
return 0;
diff --git a/snippets/sms_send_receive.c b/snippets/sms_send_receive.c
index 8bb9bfb0..1026bd5a 100644
--- a/snippets/sms_send_receive.c
+++ b/snippets/sms_send_receive.c
@@ -1,138 +1,107 @@
/*
- * SMS send and receive thread.
+ * SMS send and receive basic event based example
*
* Waits for received SMS and then replies with
*/
-
#include "sms_send_receive.h"
-#include "gsm/gsm.h"
-#include "gsm/gsm_mem.h"
+#include "lwgsm/lwgsm.h"
-static gsmr_t sms_evt_func(gsm_evt_t* evt);
+#if !LWGSM_CFG_SMS
+#error "SMS must be enabled to run this example"
+#endif /* !LWGSM_CFG_SMS */
-/**
- * \brief SMS entry information
- */
-typedef struct {
- gsm_mem_t mem;
- size_t pos;
-} sms_receive_t;
+static lwgsmr_t sms_evt_func(lwgsm_evt_t* evt);
/**
- * \brief SMS message box
+ * \brief SMS entry
*/
-static gsm_sys_mbox_t
-sms_mbox;
-
-/**
- * \brief SMS read entry
- */
-static gsm_sms_entry_t
+static lwgsm_sms_entry_t
sms_entry;
/**
- * \brief SMS Receive Send thread function
+ * \brief Start SMS send receive procedure
*/
void
-sms_send_receive_thread(void const* arg) {
- sms_receive_t* sms;
-
- /* Create message box */
- if (!gsm_sys_mbox_create(&sms_mbox, 5)) {
- goto terminate;
- }
-
- /* Register callback function for SMS */
- if (gsm_evt_register(sms_evt_func) != gsmOK) {
- goto terminate;
- }
-
- /* User can start now */
- printf("Start by sending first SMS to device...\r\n");
-
- while (1) {
- /* Get SMS entry from message queue */
- while (gsm_sys_mbox_get(&sms_mbox, (void **)&sms, 0) == GSM_SYS_TIMEOUT || sms == NULL) {}
-
- /* We have new SMS now */
- printf("New SMS received!\r\n");
-
- /* Read SMS from device */
- if (gsm_sms_read(sms->mem, sms->pos, &sms_entry, 1, NULL, NULL, 1) == gsmOK) {
- printf("SMS read ok. Number: %s, content: %s\r\n", sms_entry.number, sms_entry.data);
-
- /* Send reply back */
- if (gsm_sms_send(sms_entry.number, sms_entry.data, NULL, NULL, 1) == gsmOK) {
- printf("SMS sent back successfully!\r\n");
- } else {
- printf("Cannot send SMS back!\r\n");
- }
-
- /* Delete SMS from device memory */
- if (gsm_sms_delete(sms->mem, sms->pos, NULL, NULL, 1) == gsmOK) {
- printf("Received SMS deleted!\r\n");
- } else {
- printf("Cannot delete received SMS!\r\n");
- }
- } else {
- printf("Cannot read SMS!\r\n");
- }
-
- /* Now free the memory */
- gsm_mem_free_s((void **)&sms);
- }
-
-terminate:
- if (gsm_sys_mbox_isvalid(&sms_mbox)) {
- /* Lock to make sure GSM stack won't process any callbacks while we are cleaning */
- gsm_core_lock();
-
- /* Clean mbox first */
- while (gsm_sys_mbox_getnow(&sms_mbox, (void **)&sms)) {
- gsm_mem_free_s((void **)&sms);
- }
-
- /* Delete mbox */
- gsm_sys_mbox_delete(&sms_mbox);
- gsm_sys_mbox_invalid(&sms_mbox);
-
- gsm_core_unlock();
+sms_send_receive_start(void) {
+ /* Add custom callback */
+ lwgsm_evt_register(sms_evt_func);
+
+ /* First enable SMS functionality */
+ if (lwgsm_sms_enable(NULL, NULL, 1) == lwgsmOK) {
+ printf("SMS enabled. Send new SMS from your phone to device.\r\n");
+ } else {
+ printf("Cannot enable SMS functionality!\r\n");
+ }
- /* Now mbox is not valid anymore and event won't write any data */
- }
+ /* Now send SMS from phone to device */
+ printf("Start by sending SMS message to device...\r\n");
}
/**
* \brief Event function for received SMS
* \param[in] evt: GSM event
- * \return \ref gsmOK on success, member of \ref gsmr_t otherwise
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
*/
-static gsmr_t
-sms_evt_func(gsm_evt_t* evt) {
- switch (gsm_evt_get_type(evt)) {
- case GSM_EVT_SMS_RECV: { /* New SMS received indicator */
- uint8_t success = 0;
- sms_receive_t* sms_rx = gsm_mem_malloc(sizeof(*sms_rx));
- if (sms_rx != NULL) {
- sms_rx->mem = gsm_evt_sms_recv_get_mem(evt);
- sms_rx->pos = gsm_evt_sms_recv_get_pos(evt);
+static lwgsmr_t
+sms_evt_func(lwgsm_evt_t* evt) {
+ switch (lwgsm_evt_get_type(evt)) {
+ case LWGSM_EVT_SMS_READY: { /* SMS is ready notification from device */
+ printf("SIM device SMS service is ready!\r\n");
+ break;
+ }
+ case LWGSM_EVT_SMS_RECV: { /* New SMS received indicator */
+ lwgsmr_t res;
- /* Write to receive queue */
- if (!gsm_sys_mbox_isvalid(&sms_mbox) || !gsm_sys_mbox_putnow(&sms_mbox, sms_rx)) {
- gsm_mem_free_s((void **)&sms_rx);
+ printf("New SMS received!\r\n"); /* Notify user */
+
+ /* Try to read SMS */
+ res = lwgsm_sms_read(lwgsm_evt_sms_recv_get_mem(evt), lwgsm_evt_sms_recv_get_pos(evt), &sms_entry, 1, NULL, NULL, 0);
+ if (res == lwgsmOK) {
+ printf("SMS read in progress!\r\n");
+ } else {
+ printf("Cannot start SMS read procedure!\r\n");
+ }
+ break;
+ }
+ case LWGSM_EVT_SMS_READ: { /* SMS read event */
+ lwgsm_sms_entry_t* entry = lwgsm_evt_sms_read_get_entry(evt);
+ if (lwgsm_evt_sms_read_get_result(evt) == lwgsmOK && entry != NULL) {
+ /* Print SMS data */
+ printf("SMS read. From: %s, content: %s\r\n",
+ entry->number, entry->data
+ );
+
+ /* Try to send SMS back */
+ if (lwgsm_sms_send(entry->number, entry->data, NULL, NULL, 0) == lwgsmOK) {
+ printf("SMS send in progress!\r\n");
} else {
- success = 1;
+ printf("Cannot start SMS send procedure!\r\n");
}
- }
- /* Force SMS delete if not written successfully */
- if (!success) {
- gsm_sms_delete(gsm_evt_sms_recv_get_mem(evt), gsm_evt_sms_recv_get_pos(evt), NULL, NULL, 0);
+ /* Delete SMS from device memory */
+ lwgsm_sms_delete(entry->mem, entry->pos, NULL, NULL, 0);
+ }
+ break;
+ }
+ case LWGSM_EVT_SMS_SEND: { /* SMS send event */
+ if (lwgsm_evt_sms_send_get_result(evt) == lwgsmOK) {
+ printf("SMS has been successfully sent!\r\n");
+ } else {
+ printf("SMS has not been sent successfully!\r\n");
}
break;
}
- default: break;
+ case LWGSM_EVT_SMS_DELETE: { /* SMS delete event */
+ if (lwgsm_evt_sms_delete_get_result(evt) == lwgsmOK) {
+ printf("SMS deleted, memory position: %d\r\n", (int)lwgsm_evt_sms_delete_get_pos(evt));
+ } else {
+ printf("SMS delete operation failed!\r\n");
+ }
+ break;
+ }
+ default:
+ break;
}
- return gsmOK;
+ return lwgsmOK;
}
diff --git a/snippets/sms_send_receive_thread.c b/snippets/sms_send_receive_thread.c
new file mode 100644
index 00000000..1a0db1f8
--- /dev/null
+++ b/snippets/sms_send_receive_thread.c
@@ -0,0 +1,152 @@
+/*
+ * SMS send and receive thread.
+ *
+ * Waits for received SMS and then replies with
+ */
+#include "sms_send_receive_thread.h"
+#include "lwgsm/lwgsm.h"
+#include "lwgsm/lwgsm_mem.h"
+
+#if !LWGSM_CFG_SMS
+#error "SMS must be enabled to run this example"
+#endif /* !LWGSM_CFG_SMS */
+
+static lwgsmr_t sms_evt_func(lwgsm_evt_t* evt);
+
+/**
+ * \brief SMS entry information
+ */
+typedef struct {
+ lwgsm_mem_t mem;
+ size_t pos;
+} sms_receive_t;
+
+/**
+ * \brief SMS message box
+ */
+static lwgsm_sys_mbox_t
+sms_mbox;
+
+/**
+ * \brief SMS read entry
+ */
+static lwgsm_sms_entry_t
+sms_entry;
+
+/**
+ * \brief SMS Receive Send thread function
+ */
+void
+sms_send_receive_thread(void const* arg) {
+ sms_receive_t* sms;
+
+ /* Create message box */
+ if (!lwgsm_sys_mbox_create(&sms_mbox, 5)) {
+ goto terminate;
+ }
+
+ /* Register callback function for SMS */
+ if (lwgsm_evt_register(sms_evt_func) != lwgsmOK) {
+ goto terminate;
+ }
+
+ /* First enable SMS functionality */
+ if (lwgsm_sms_enable(NULL, NULL, 1) == lwgsmOK) {
+ printf("SMS enabled. Send new SMS from your phone to device.\r\n");
+ } else {
+ printf("Cannot enable SMS functionality!\r\n");
+ while (1) {
+ lwgsm_delay(1000);
+ }
+ }
+
+ /* User can start now */
+ printf("Start by sending first SMS to device...\r\n");
+
+ while (1) {
+ /* Get SMS entry from message queue */
+ while (lwgsm_sys_mbox_get(&sms_mbox, (void**)&sms, 0) == LWGSM_SYS_TIMEOUT || sms == NULL) {}
+
+ /* We have new SMS now */
+ printf("New SMS received!\r\n");
+
+ /* Read SMS from device */
+ if (lwgsm_sms_read(sms->mem, sms->pos, &sms_entry, 1, NULL, NULL, 1) == lwgsmOK) {
+ printf("SMS read ok. Number: %s, content: %s\r\n", sms_entry.number, sms_entry.data);
+
+ /* Send reply back */
+ if (lwgsm_sms_send(sms_entry.number, sms_entry.data, NULL, NULL, 1) == lwgsmOK) {
+ printf("SMS sent back successfully!\r\n");
+ } else {
+ printf("Cannot send SMS back!\r\n");
+ }
+
+ /* Delete SMS from device memory */
+ if (lwgsm_sms_delete(sms->mem, sms->pos, NULL, NULL, 1) == lwgsmOK) {
+ printf("Received SMS deleted!\r\n");
+ } else {
+ printf("Cannot delete received SMS!\r\n");
+ }
+ } else {
+ printf("Cannot read SMS!\r\n");
+ }
+
+ /* Now free the memory */
+ lwgsm_mem_free_s((void**)&sms);
+ }
+
+terminate:
+ if (lwgsm_sys_mbox_isvalid(&sms_mbox)) {
+ /* Lock to make sure GSM stack won't process any callbacks while we are cleaning */
+ lwgsm_core_lock();
+
+ /* Clean mbox first */
+ while (lwgsm_sys_mbox_getnow(&sms_mbox, (void**)&sms)) {
+ lwgsm_mem_free_s((void**)&sms);
+ }
+
+ /* Delete mbox */
+ lwgsm_sys_mbox_delete(&sms_mbox);
+ lwgsm_sys_mbox_invalid(&sms_mbox);
+
+ lwgsm_core_unlock();
+
+ /* Now mbox is not valid anymore and event won't write any data */
+ }
+}
+
+/**
+ * \brief Event function for received SMS
+ * \param[in] evt: GSM event
+ * \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
+ */
+static lwgsmr_t
+sms_evt_func(lwgsm_evt_t* evt) {
+ switch (lwgsm_evt_get_type(evt)) {
+ case LWGSM_EVT_SMS_RECV: { /* New SMS received indicator */
+ uint8_t success = 0;
+ sms_receive_t* sms_rx = lwgsm_mem_malloc(sizeof(*sms_rx));
+ if (sms_rx != NULL) {
+ sms_rx->mem = lwgsm_evt_sms_recv_get_mem(evt);
+ sms_rx->pos = lwgsm_evt_sms_recv_get_pos(evt);
+
+ /* Write to receive queue */
+ if (!lwgsm_sys_mbox_isvalid(&sms_mbox) || !lwgsm_sys_mbox_putnow(&sms_mbox, sms_rx)) {
+ lwgsm_mem_free_s((void**)&sms_rx);
+ } else {
+ success = 1;
+ }
+ }
+
+ /* Force SMS delete if not written successfully */
+ if (!success) {
+ lwgsm_sms_delete(lwgsm_evt_sms_recv_get_mem(evt), lwgsm_evt_sms_recv_get_pos(evt), NULL, NULL, 0);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ return lwgsmOK;
+}
diff --git a/third_party/Embedded_Libs b/third_party/Embedded_Libs
deleted file mode 160000
index fc5b3a0d..00000000
--- a/third_party/Embedded_Libs
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit fc5b3a0dc07107c63d3f2e6a5a6d31843b0606ca
diff --git a/third_party/embedded-libs b/third_party/embedded-libs
new file mode 160000
index 00000000..b92511a6
--- /dev/null
+++ b/third_party/embedded-libs
@@ -0,0 +1 @@
+Subproject commit b92511a69ee11f11efe3fb27adf53cf841291a5e