LwGSM 0.1.0 documentation¶
Welcome to the documentation for version 0.1.0.
LwGSM is generic, platform independent, library to control SIM800/SIM900 or SIM7000/SIM7020 (NB-Iot LTE) devices from SIMCom. Its objective is to run on master system, while SIMCom device runs official AT commands firmware developed and maintained by SIMCom.
Download library Getting started Open Github
Features¶
Supports
SIM800/SIM900 (2G)
andSIM7000/SIM7020 (NB-Iot LTE)
modulesPlatform 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
Requirements¶
C compiler
Supported GSM Physical device
Contribute¶
Fresh contributions are always welcome. Simple instructions to proceed:
Fork Github repository
Respect C style & coding rules used by the library
Create a pull request to
develop
branch with new features or bug fixes
Alternatively you may:
Report a bug
Ask for a feature request
License¶
MIT License
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.
Table of contents¶
Getting started¶
Download library¶
Library is primarly hosted on Github.
Download latest release from releases area on Github
Clone develop branch for latest development
Download from releases¶
All releases are available on Github releases area.
Clone from Github¶
First-time clone¶
Download and install
git
if not alreadyOpen console and navigate to path in the system to clone repository to. Use command
cd your_path
Clone repository with one of available
3
optionsRun
git clone --recurse-submodules https://github.com/MaJerle/lwgsm
command to clone entire repository, including submodulesRun
git clone --recurse-submodules --branch develop https://github.com/MaJerle/lwgsm
to clone development branch, including submodulesRun
git clone --recurse-submodules --branch master https://github.com/MaJerle/lwgsm
to clone latest stable branch, including submodules
Navigate to
examples
directory and run favourite example
Update cloned to latest version¶
Open console and navigate to path in the system where your resources repository is. Use command
cd your_path
Run
git pull origin master --recurse-submodules
command to pull latest changes and to fetch latest changes from submodulesRun
git submodule foreach git pull origin master
to update & merge all submodules
Note
This is preferred option to use when you want to evaluate library and run prepared examples. Repository consists of multiple submodules which can be automatically downloaded when cloning and pulling changes from root repository.
Add library to project¶
At this point it is assumed that you have successfully download library, either cloned it or from releases page.
Copy
lwgsm
folder to your projectAdd
lwgsm/src/include
folder to include path of your toolchainAdd port architecture
lwgsm/src/include/system/port/_arch_
folder to include path of your toolchainAdd source files from
lwgsm/src/
folder to toolchain buildAdd source files from
lwgsm/src/system/
folder to toolchain build for arch portCopy
lwgsm/src/include/lwgsm/lwgsm_opts_template.h
to project folder and rename it tolwgsm_opts.h
Build the project
Configuration file¶
Library comes with template config file, which can be modified according to needs.
This file shall be named lwgsm_opts.h
and its default template looks like the one below.
Note
Default configuration template file location: lwgsm/src/include/lwgsm/lwgsm_opts_template.h
.
File must be renamed to lwgsm_opts.h
first and then copied to the project directory (or simply renamed in-place) where compiler
include paths have access to it by using #include "lwgsm_opts.h"
.
Tip
Check Configuration section for possible configuration settings
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | /**
* \file lwgsm_opts_template.h
* \brief Template config 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 <tilen@majerle.eu>
* 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
*/
#endif /* LWGSM_HDR_OPTS_H */
|
User manual¶
Overview¶
IoT activity is embedded in today’s application. Almost every device uses some type of communication, from WiFi, BLE, Sub-GHz or NB-IoT/LTE/2G/3G.
LwGSM has been developed to allow customers to:
Develop on single (host MCU) architecture at the same time and do not care about device arch
Shorten time to market
Customers using LwGSM do not need to take care about proper command for specific task, they can call API functions to execute the task. Library will take the necessary steps in order to send right command to device via low-level driver (usually UART) and process incoming response from device before it will notify application layer if it was successfuly or not.
To summarize:
GSM device runs official AT firmware, provided by device vendor
Host MCU runs custom application, together with LwGSM library
Host MCU communicates with GSM device with UART or similar interface.
Architecture¶
Architecture of the library consists of 4
layers.
LwGSM layer architecture overview¶
Application layer¶
User layer is the highest layer of the final application. This is the part where API functions are called to execute some command.
Middleware layer¶
Middleware part is actively developed and shall not be modified by customer by any means. If there is a necessity to do it, often it means that developer of the application uses it wrongly. This part is platform independent and does not use any specific compiler features for proper operation.
Note
There is no compiler specific features implemented in this layer.
System & low-level layer¶
Application needs to fully implement this part and resolve it with care. Functions are related to actual implementation with GSM device and are highly architecture oriented. Some examples for WIN32 and ARM Cortex-M are included with library.
Tip
Check Porting guide for detailed instructions and examples.
System functions¶
System functions are bridge between operating system running on embedded system and LwGSM middleware. Functions need to provide:
Thread management
Binary semaphore management
Recursive mutex management
Message queue management
Current time status information
Tip
System function prototypes are available in System functions section.
Low-level implementation¶
Low-Level, or LWGSM_LL, is part, dedicated for communication between LwGSM middleware and GSM physical device. Application needs to implement output function to send necessary AT command instruction aswell as implement input module to send received data from GSM device to LwGSM middleware.
Application must also assure memory assignment for Memory manager when default allocation is used.
Tip
Low level, input module & memory function prototypes are available in Low-Level functions, Input module and Memory manager respectfully.
GSM physical device¶
Inter thread communication¶
LwGSM is only available with operating system.
For successful resources management, it uses 2
threads within library and allows multiple application threads to post new command to be processed.
Inter-thread architecture block diagram¶
Producing and Processing threads are part of library, its implementation is in lwgsm_threads.c
file.
Processing thread¶
Processing thread is in charge of processing each and every received character from GSM device. It can process URC messages which are received from GSM device without any command request. Some of them are:
+RECEIVE indicating new data packet received from remote side on active connection
RING indicating new call to be processed by GSM
and more others
Note
Received messages without any command (URC messages) are sent to application layer using events, where they can be processed and used in further steps
This thread also checks and processes specific received messages based on active command.
As an example, when application tries to make a new connection to remote server, it starts command with AT+CIPSTART
message.
Thread understands that active command is to connect to remote side and will wait for potential 0, CONNECT OK
message,
indicating connection status. it will also wait for OK
or ERROR
,
indicating command finished status before it unlocks sync_sem to unblock producing thread.
Tip
When thread tries to unlock sync_sem, it first checks if it has been locked by producing thread.
Producing thread¶
Producing thread waits for command messages posted from application thread. When new message has been received, it sends initial AT message over AT port.
It checks if command is valid and if it has corresponding initial AT sequence, such as
AT+CIPSTART
It locks sync_sem semaphore and waits for processing thread to unlock it
Processing thread is in charge to read respone from GSM and react accordingly. See previous section for details.
If application uses blocking mode, it unlocks command sem semaphore and returns response
If application uses non-blocking mode, it frees memory for message and sends event with response message
Application thread¶
Application thread is considered any thread which calls API functions and therefore writes new messages to producing message queue, later processed by producing thread.
A new message memory is allocated in this thread and type of command is assigned to it, together with required input data for command. It also sets blocking or non-blocking mode, how command shall be executed.
When application tries to execute command in blocking mode, it creates new sync semaphore sem, locks it, writes message to producing queue and waits for sem to get unlocked. This effectively puts thread to blocked state by operating system and removes it from scheduler until semaphore is unlocked again. Semaphore sem gets unlocked in producing thread when response has been received for specific command.
Tip
sem semaphore is unlocked in producing thread after sync_sem is unlocked in processing thread
Note
Every command message uses its own sem semaphore to sync multiple application threads at the same time.
If message is to be executed in non-blocking mode, sem is not created as there is no need to block application thread. When this is the case, application thread will only write message command to producing queue and return status of writing to application.
Events and callback functions¶
Library uses events to notify application layer for (possible, but not limited to) unexpected events. This concept is used aswell for commands with longer executing time, such as scanning access points or when application starts new connection as client mode.
There are 3
types of events/callbacks available:
Global event callback function, assigned when initializing library
Connection specific event callback function, to process only events related to connection, such as connection error, data send, data receive, connection closed
API function call based event callback function
Every callback is always called from protected area of middleware (when exclusing access is granted to single thread only),
and it can be called from one of these 3
threads:
Producing thread
Processing thread
Input thread, when
LWGSM_CFG_INPUT_USE_PROCESS
is enabled andlwgsm_input_process()
function is called
Tip
Check Inter thread communication for more details about Producing and Processing thread.
Global event callback¶
Global event callback function is assigned at library initialization. It is used by the application to receive any kind of event, except the one related to connection:
GSM station successfully connected to access point
GSM physical device reset has been detected
Restore operation finished
New station has connected to access point
and many more..
Tip
Check Event management section for different kind of events
By default, global event function is single function.
If the application tries to split different events with different callback functions,
it is possible to do so by using lwgsm_evt_register()
function to register a new,
custom, event function.
Tip
Implementation of Netconn API leverages lwgsm_evt_register()
to
receive event when station disconnected from wifi access point.
Check its source file for actual implementation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 | /**
* \file lwgsm_netconn.c
* \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 <tilen@majerle.eu>
* Version: v0.1.0
*/
#include "lwgsm/lwgsm_netconn.h"
#include "lwgsm/lwgsm_private.h"
#include "lwgsm/lwgsm_conn.h"
#include "lwgsm/lwgsm_mem.h"
#if LWGSM_CFG_NETCONN || __DOXYGEN__
/* Check conditions */
#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 lwgsm_netconn {
struct lwgsm_netconn* next; /*!< Linked list entry */
lwgsm_netconn_type_t type; /*!< Netconn type */
size_t rcv_packets; /*!< Number of received packets so far on this connection */
lwgsm_conn_p conn; /*!< Pointer to actual connection */
lwgsm_sys_mbox_t mbox_receive; /*!< Message queue for receive mbox */
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 LWGSM_CFG_NETCONN_RECEIVE_TIMEOUT || __DOXYGEN__
uint32_t rcv_timeout; /*!< Receive timeout in unit of milliseconds */
#endif
} lwgsm_netconn_t;
static uint8_t recv_closed = 0xFF;
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(lwgsm_netconn_t* nc, uint8_t protect) {
lwgsm_pbuf_p pbuf;
if (protect) {
lwgsm_core_lock();
}
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 */
}
}
lwgsm_sys_mbox_delete(&nc->mbox_receive); /* Delete message queue */
lwgsm_sys_mbox_invalid(&nc->mbox_receive); /* Invalid handle */
}
if (protect) {
lwgsm_core_unlock();
}
}
/**
* \brief Callback function for every server connection
* \param[in] evt: Pointer to callback structure
* \return Member of \ref lwgsmr_t enumeration
*/
static lwgsmr_t
netconn_evt(lwgsm_evt_t* evt) {
lwgsm_conn_p conn;
lwgsm_netconn_t* nc = NULL;
uint8_t close = 0;
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 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 {
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) {
lwgsm_conn_set_arg(conn, NULL); /* Reset argument */
lwgsm_netconn_delete(nc); /* Free memory for API */
}
lwgsm_conn_close(conn, 0); /* Close the connection */
close = 0;
}
break;
}
/*
* We have a new data received which
* should have netconn structure as argument
*/
case LWGSM_EVT_CONN_RECV: {
lwgsm_pbuf_p pbuf;
nc = lwgsm_conn_get_arg(conn); /* Get API from connection */
pbuf = lwgsm_evt_conn_recv_get_buff(evt); /* Get received buff */
lwgsm_conn_recved(conn, pbuf); /* Notify stack about received 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 */
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 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 && lwgsm_sys_mbox_isvalid(&nc->mbox_receive)) {
lwgsm_sys_mbox_putnow(&nc->mbox_receive, (void*)&recv_closed);
}
break;
}
default:
return lwgsmERR;
}
return lwgsmOK;
}
/**
* \brief Global event callback function
* \param[in] evt: Callback information and data
* \return \ref lwgsmOK on success, member of \ref lwgsmr_t otherwise
*/
static lwgsmr_t
lwgsm_evt(lwgsm_evt_t* evt) {
switch (lwgsm_evt_get_type(evt)) {
default:
break;
}
return lwgsmOK;
}
/**
* \brief Create new netconn connection
* \param[in] type: Netconn connection type
* \return New netconn connection on success, `NULL` otherwise
*/
lwgsm_netconn_p
lwgsm_netconn_new(lwgsm_netconn_type_t type) {
lwgsm_netconn_t* a;
static uint8_t first = 1;
/* Register only once! */
lwgsm_core_lock();
if (first) {
first = 0;
lwgsm_evt_register(lwgsm_evt); /* Register global event function */
}
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 (!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;
}
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;
}
lwgsm_core_unlock();
}
return a;
free_ret:
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) {
lwgsm_mem_free_s((void**)&a);
}
return NULL;
}
/**
* \brief Delete netconn connection
* \param[in] nc: Netconn handle
* \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
lwgsmr_t
lwgsm_netconn_delete(lwgsm_netconn_p nc) {
LWGSM_ASSERT("netconn != NULL", nc != NULL);
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) {
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) {
if (nc == tmp) {
prev->next = tmp->next; /* Remove tmp from linked list */
break;
}
}
}
lwgsm_core_unlock();
lwgsm_mem_free_s((void**)&nc);
return lwgsmOK;
}
/**
* \brief Connect to server as client
* \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 lwgsmOK if successfully connected, member of \ref lwgsmr_t otherwise
*/
lwgsmr_t
lwgsm_netconn_connect(lwgsm_netconn_p nc, const char* host, lwgsm_port_t port) {
lwgsmr_t res;
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:
*
* - Set current netconn structure as argument
* - Set netconn callback function for connection management
* - Start connection in blocking mode
*/
res = lwgsm_conn_start(NULL, (lwgsm_conn_type_t)nc->type, host, port, nc, netconn_evt, 1);
return res;
}
/**
* \brief Write data to connection output buffers
* \note This function may only be used on TCP or SSL connections
* \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 lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
lwgsmr_t
lwgsm_netconn_write(lwgsm_netconn_p nc, const void* data, size_t btw) {
size_t len, sent;
const uint8_t* d = data;
lwgsmr_t res;
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 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 = LWGSM_MIN(nc->buff.len - nc->buff.ptr, btw); /* Get number of bytes we can write to buffer */
if (len > 0) {
LWGSM_MEMCPY(&nc->buff.buff[nc->buff.ptr], data, len); /* Copy memory to temporary write buffer */
d += len;
nc->buff.ptr += len;
btw -= len;
}
/* Step 1.1 */
if (nc->buff.ptr == nc->buff.len) {
res = lwgsm_conn_send(nc->conn, nc->buff.buff, nc->buff.len, &sent, 1);
lwgsm_mem_free_s((void**)&nc->buff.buff);
if (res != lwgsmOK) {
return res;
}
} else {
return lwgsmOK; /* Buffer is not yet full yet */
}
}
/* Step 2 */
if (btw >= LWGSM_CFG_CONN_MAX_DATA_LEN) {
size_t rem;
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 */
btw -= sent; /* Decrease remaining data to send */
}
if (btw == 0) { /* Sent everything? */
return lwgsmOK;
}
/* Step 3 */
if (nc->buff.buff == NULL) { /* Check if we should allocate a new buffer */
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? */
LWGSM_MEMCPY(&nc->buff.buff[nc->buff.ptr], d, btw); /* Copy data to buffer */
nc->buff.ptr += btw;
} else { /* Still no memory available? */
return lwgsm_conn_send(nc->conn, data, btw, NULL, 1); /* Simply send directly blocking */
}
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 lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
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,
* flush them out to network
*/
if (nc->buff.buff != NULL) { /* Check remaining data */
if (nc->buff.ptr > 0) { /* Do we have data in current buffer? */
lwgsm_conn_send(nc->conn, nc->buff.buff, nc->buff.ptr, NULL, 1);/* Send data */
}
lwgsm_mem_free_s((void**)&nc->buff.buff);
}
return lwgsmOK;
}
/**
* \brief Send data on \e UDP connection to default IP and port
* \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 lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
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 lwgsm_conn_send(nc->conn, data, btw, NULL, 1);
}
/**
* \brief Send data on \e UDP connection to specific IP and port
* \note Use this function in case of UDP type netconn
* \param[in] nc: Netconn handle used to send
* \param[in] ip: Pointer to IP address
* \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 lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
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 lwgsm_conn_sendto(nc->conn, ip, port, data, btw, NULL, 1);
}
/**
* \brief Receive data from connection
* \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 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
*/
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 LWGSM_CFG_NETCONN_RECEIVE_TIMEOUT
/*
* Wait for new received data for up to specific timeout
* or throw error for timeout notification
*/
if (lwgsm_sys_mbox_get(&nc->mbox_receive, (void**)pbuf, nc->rcv_timeout) == LWGSM_SYS_TIMEOUT) {
return lwgsmTIMEOUT;
}
#else /* LWGSM_CFG_NETCONN_RECEIVE_TIMEOUT */
/* Forever wait for new receive packet */
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) {
*pbuf = NULL; /* Reset pbuf */
return lwgsmCLOSED;
}
return lwgsmOK; /* We have data available */
}
/**
* \brief Close a netconn connection
* \param[in] nc: Netconn handle to close
* \return \ref lwgsmOK on success, member of \ref lwgsmr_t enumeration otherwise
*/
lwgsmr_t
lwgsm_netconn_close(lwgsm_netconn_p nc) {
lwgsm_conn_p 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));
lwgsm_netconn_flush(nc); /* Flush data and ignore result */
conn = nc->conn;
nc->conn = NULL;
lwgsm_conn_set_arg(conn, NULL); /* Reset argument */
lwgsm_conn_close(conn, 1); /* Close the connection */
flush_mboxes(nc, 1); /* Flush message queues */
return lwgsmOK;
}
/**
* \brief Get connection number used for netconn
* \param[in] nc: Netconn handle
* \return `-1` on failure, connection number between `0` and \ref LWGSM_CFG_MAX_CONNS otherwise
*/
int8_t
lwgsm_netconn_getconnnum(lwgsm_netconn_p nc) {
if (nc != NULL && nc->conn != NULL) {
return lwgsm_conn_getnum(nc->conn);
}
return -1;
}
#if LWGSM_CFG_NETCONN_RECEIVE_TIMEOUT || __DOXYGEN__
/**
* \brief Set timeout value for receiving data.
*
* 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 lwgsm_netconn_receive function
*/
void
lwgsm_netconn_set_receive_timeout(lwgsm_netconn_p nc, uint32_t timeout) {
nc->rcv_timeout = timeout;
}
/**
* \brief Get netconn receive timeout value
* \param[in] nc: Netconn handle
* \return Timeout in units of milliseconds.
* If value is `0`, timeout is disabled (wait forever)
*/
uint32_t
lwgsm_netconn_get_receive_timeout(lwgsm_netconn_p nc) {
return nc->rcv_timeout; /* Return receive timeout */
}
#endif /* LWGSM_CFG_NETCONN_RECEIVE_TIMEOUT || __DOXYGEN__ */
#endif /* LWGSM_CFG_NETCONN || __DOXYGEN__ */
|
Connection specific event¶
This events are subset of global event callback. They work exactly the same way as global, but only receive events related to connections.
Tip
Connection related events start with LWGSM_EVT_CONN_*
, such as LWGSM_EVT_CONN_RECV
.
Check Event management for list of all connection events.
Connection events callback function is set when client (application starts connection) starts a new connection with lwgsm_conn_start()
function
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 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;
}
|
API call event¶
API function call event function is special type of event and is linked to command execution. It is especially useful when dealing with non-blocking commands to understand when specific command execution finished and when next operation could start.
Every API function, which directly operates with AT command on physical device layer,
has optional 2
parameters for API call event:
Callback function, called when command finished
Custom user parameter for callback function
Below is an example code for SMS send. It uses custom API callback function to notify application when command has been executed successfully
1 2 3 4 5 6 7 8 9 10 | /* Somewhere in thread function */
/* Get device hostname in blocking mode */
/* Function returns actual result */
if (lwgsm_sms_send("+0123456789", "text", NULL, NULL, 1 /* 1 means blocking call */) == lwgsmOK) {
/* At this point we have valid result from device */
printf("SMS sent successfully\r\n");
} else {
printf("Error trying to send SMS..\r\n");
}
|
Blocking or non-blocking API calls¶
API functions often allow application to set blocking
parameter indicating if function shall be blocking or non-blocking.
Blocking mode¶
When the function is called in blocking mode blocking = 1
, application thread gets suspended until response from GSM device is received.
If there is a queue of multiple commands, thread may wait a while before receiving data.
When API function returns, application has valid response data and can react immediately.
Linear programming model may be used
Application may use multiple threads for real-time execution to prevent system stalling when running function call
Warning
Due to internal architecture, it is not allowed to call API functions in blocking mode from events or callbacks. Any attempt to do so will result in function returning error.
Example code:
1 2 3 4 5 6 7 8 9 10 | /* Somewhere in thread function */
/* Get device hostname in blocking mode */
/* Function returns actual result */
if (lwgsm_sms_send("+0123456789", "text", NULL, NULL, 1 /* 1 means blocking call */) == lwgsmOK) {
/* At this point we have valid result from device */
printf("SMS sent successfully\r\n");
} else {
printf("Error trying to send SMS..\r\n");
}
|
Non-blocking mode¶
If the API function is called in non-blocking mode, function will return immediately with status indicating if command request has been successfully sent to internal command queue. Response has to be processed in event callback function.
Warning
Due to internal architecture, it is only allowed to call API functions in non-blocking mode from events or callbacks. Any attempt to do so will result in function returning error.
Example code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | /* Hostname event function, called when lwgsm_sms_send() function finishes */
void
sms_send_fn(lwgsmr_t res, void* arg) {
/* Check actual result from device */
if (res == lwgsmOK) {
printf("SMS sent successfully\r\n");
} else {
printf("Error trying to send SMS\r\n");
}
}
/* Somewhere in thread and/or other GSM event function */
/* Send SMS in non-blocking mode */
/* Function now returns if command has been sent to internal message queue */
if (lwgsm_sms_send("number", "text message", sms_send_fn, NULL, 0 /* 0 means non-blocking call */) == lwgsmOK) {
/* At this point we only know that command has been sent to queue */
printf("SMS send message command sent to queue.\r\n");
} else {
/* Error writing message to queue */
printf("Cannot send SMS send message command to queue. Maybe out of memory? Check result from function\r\n");
}
|
Warning
When using non-blocking API calls, do not use local variables as parameter. This may introduce undefined behavior and memory corruption if application function returns before command is executed.
Example of a bad code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | /* Hostname event function, called when lwgsm_sms_send() function finishes */
void
sms_send_fn(lwgsmr_t res, void* arg) {
/* Check actual result from device */
if (res == lwgsmOK) {
printf("SMS sent successfully\r\n");
} else {
printf("Error trying to send SMS\r\n");
}
}
/* Check hostname */
void
check_hostname(void) {
char message[] = "text message";
/* Send SMS in non-blocking mode */
/* Function now returns if command has been sent to internal message queue */
/* It uses pointer to local data but w/o blocking command */
if (lwgsm_sms_send("number", message, sms_send_fn, NULL, 0 /* 0 means non-blocking call */) == lwgsmOK) {
/* At this point we only know that command has been sent to queue */
printf("SMS send message command sent to queue.\r\n");
} else {
/* Error writing message to queue */
printf("Cannot send SMS send message command to queue. Maybe out of memory? Check result from function\r\n");
}
}
|
Porting guide¶
High level of LwGSM library is platform independent, written in ANSI C99, however there is an important part where middleware needs to communicate with target GSM device and it must work under different optional operating systems selected by final customer.
Porting consists of:
Implementation of low-level part, for actual communication between host device and GSM device
Implementation of system functions, link between target operating system and middleware functions
Assignment of memory for allocation manager
Implement low-level driver¶
To successfully prepare all parts of low-level driver, application must take care of:
Implementing
lwgsm_ll_init()
andlwgsm_ll_deinit()
callback functionsImplement and assign send data and optional hardware reset function callbacks
Assign memory for allocation manager when using default allocator or use custom allocator
Process received data from ESP device and send it to input module for further processing
Tip
Port examples are available for STM32 and WIN32 architectures. Both actual working and up-to-date implementations are available within the library.
Note
Check Input module for more information about direct & indirect input processing.
Implement system functions¶
System functions are bridge between operating system calls and GSM middleware. GSM library relies on stable operating system features and its implementation and does not require any special features which do not normally come with operating systems.
Operating system must support:
Thread management functions
Mutex management functions
Binary semaphores only functions, no need for counting semaphores
Message queue management functions
Warning
If any of the features are not available within targeted operating system, customer needs to resolve it with care. As an example, message queue is not available in WIN32 OS API therefore custom message queue has been implemented using binary semaphores
Application needs to implement all system call functions, starting with lwgsm_sys_
.
It must also prepare header file for standard types in order to support OS types within GSM middleware.
An example code is provided latter section of this page for WIN32 and STM32.
Note
Check System functions for function prototypes.
Steps to follow¶
Copy
lwgsm/src/system/lwgsm_sys_template.c
to the same folder and rename it to application port, eg.lwgsm_sys_win32.c
Open newly created file and implement all system functions
Copy folder
lwgsm/src/include/system/port/template/*
to the same folder and rename folder name to application port, eg.cmsis_os
Open
lwgsm_sys_port.h
file from newly created folder and implement all typedefs and macros for specific targetAdd source file to compiler sources and add path to header file to include paths in compiler options
Note
Check System functions for function prototypes.
Example: Low-level driver for WIN32¶
Example code for low-level porting on WIN32 platform. It uses native Windows features to open COM port and read/write from/to it.
Notes:
It uses separate thread for received data processing. It uses
lwgsm_input_process()
orlwgsm_input()
functions, based on application configuration ofLWGSM_CFG_INPUT_USE_PROCESS
parameter.When
LWGSM_CFG_INPUT_USE_PROCESS
is disabled, dedicated receive buffer is created by LwGSM library andlwgsm_input()
function just writes data to it and does not process received characters immediately. This is handled by Processing thread at later stage instead.When
LWGSM_CFG_INPUT_USE_PROCESS
is enabled,lwgsm_input_process()
is used, which directly processes input data and sends potential callback/event functions to application layer.
Memory manager has been assigned to
1
region ofLWGSM_MEM_SIZE
sizeIt sets send and reset callback functions for LwGSM library
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 | /**
* \file lwgsm_ll_win32.c
* \brief Low-level communication with GSM device for WIN32
*/
/*
* 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 <tilen@majerle.eu>
* Version: v0.1.0
*/
#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 */
static void uart_thread(void* param);
/**
* \brief Send data to GSM device, function called from GSM stack when we have data to send
* \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) {
DWORD written;
if (com_port != NULL) {
#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) {
printf("%c", d[i]);
}
SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
#endif /* !LWGSM_CFG_AT_ECHO */
/* Write data to AT port */
WriteFile(com_port, data, len, &written, NULL);
FlushFileBuffers(com_port);
return written;
}
return 0;
}
/**
* \brief Configure UART (USB to UART)
*/
static void
configure_uart(uint32_t baudrate) {
DCB dcb = { 0 };
dcb.DCBlength = sizeof(dcb);
/*
* On first call,
* create virtual file on selected COM port and open it
* as generic read and write
*/
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) {
com_port = CreateFile(com_ports[i],
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]);
break;
}
}
}
/* Configure COM port parameters */
if (GetCommState(com_port, &dcb)) {
COMMTIMEOUTS timeouts;
dcb.BaudRate = baudrate;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
if (!SetCommState(com_port, &dcb)) {
printf("Cannot set COM PORT info\r\n");
}
if (GetCommTimeouts(com_port, &timeouts)) {
/* Set timeout to return immediately from ReadFile function */
timeouts.ReadIntervalTimeout = MAXDWORD;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.ReadTotalTimeoutMultiplier = 0;
if (!SetCommTimeouts(com_port, &timeouts)) {
printf("Cannot set COM PORT timeouts\r\n");
}
GetCommTimeouts(com_port, &timeouts);
} else {
printf("Cannot get COM PORT timeouts\r\n");
}
} else {
printf("Cannot get COM PORT info\r\n");
}
/* On first function call, create a thread to read data from COM port */
if (!initialized) {
thread_handle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)uart_thread, NULL, 0, 0);
}
}
/**
* \brief UART thread
*/
static void
uart_thread(void* param) {
DWORD bytes_read;
lwgsm_sys_sem_t sem;
FILE* file = NULL;
lwgsm_sys_sem_create(&sem, 0); /* Create semaphore for delay functions */
while (com_port == NULL) {
lwgsm_sys_sem_wait(&sem, 1); /* Add some delay with yield */
}
fopen_s(&file, "log_file.txt", "w+"); /* Open debug file in write mode */
while (1) {
/*
* Try to read data from COM port
* and send it to upper layer for processing
*/
do {
ReadFile(com_port, data_buffer, sizeof(data_buffer), &bytes_read, NULL);
if (bytes_read > 0) {
HANDLE hConsole;
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, FOREGROUND_GREEN);
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 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) {
fwrite(data_buffer, 1, bytes_read, file);
fflush(file);
}
}
} while (bytes_read == (DWORD)sizeof(data_buffer));
/* Implement delay to allow other tasks processing */
lwgsm_sys_sem_wait(&sem, 1);
}
}
/**
* \brief Callback function called from initialization process
*
* \note This function may be called multiple times if AT baudrate is changed from application.
* 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 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 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_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 */
/*
* Create memory region(s) of memory.
* If device has internal/external memory available,
* multiple memories may be used
*/
lwgsm_mem_region_t mem_regions[] = {
{ memory, sizeof(memory) }
};
if (!initialized) {
lwgsm_mem_assignmemory(mem_regions, LWGSM_ARRAYSIZE(mem_regions)); /* Assign memory for allocations to GSM library */
}
#endif /* !LWGSM_CFG_MEM_CUSTOM */
/* Step 2: Set AT port send function to use when we have data to transmit */
if (!initialized) {
ll->send_fn = send_data; /* Set callback function to send data */
}
/* 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 lwgsmOK;
}
#endif /* !__DOXYGEN__ */
|
Example: Low-level driver for STM32¶
Example code for low-level porting on STM32 platform. It uses CMSIS-OS based application layer functions for implementing threads & other OS dependent features.
Notes:
It uses separate thread for received data processing. It uses
lwgsm_input_process()
function to directly process received data without using intermediate receive bufferMemory manager has been assigned to
1
region ofLWGSM_MEM_SIZE
sizeIt sets send and reset callback functions for LwGSM library
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 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 <tilen@majerle.eu>
* 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__ */
|
Example: System functions for WIN32¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | /**
* \file lwgsm_sys_port.h
* \brief WIN32 based system file implementation
*/
/*
* 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 <tilen@majerle.eu>
* Version: v0.1.0
*/
#ifndef LWGSM_HDR_SYSTEM_PORT_H
#define LWGSM_HDR_SYSTEM_PORT_H
#include <stdint.h>
#include <stdlib.h>
#include "lwgsm/lwgsm_opt.h"
#include "windows.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#if LWGSM_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;
#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 /* LWGSM_CFG_OS && !__DOXYGEN__ */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* LWGSM_HDR_SYSTEM_PORT_H */
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 | /**
* \file lwgsm_sys_win32.c
* \brief System dependant functions for WIN32
*/
/*
* 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 <tilen@majerle.eu>
* Version: v0.1.0
*/
#include <string.h>
#include <stdlib.h>
#include "system/lwgsm_sys.h"
#if !__DOXYGEN__
/**
* \brief Custom message queue implementation for WIN32
*/
typedef struct {
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 lwgsm_sys_mutex_t sys_mutex; /* Mutex ID for main protection */
static uint8_t
mbox_is_full(win32_mbox_t* m) {
size_t size = 0;
if (m->in > m->out) {
size = (m->in - m->out);
} else if (m->out > m->in) {
size = m->size - m->out + m->in;
}
return size == m->size - 1;
}
static uint8_t
mbox_is_empty(win32_mbox_t* m) {
return m->in == m->out;
}
static uint32_t
osKernelSysTick(void) {
LONGLONG ret;
LARGE_INTEGER now;
QueryPerformanceFrequency(&freq); /* Get frequency */
QueryPerformanceCounter(&now); /* Get current time */
ret = now.QuadPart - sys_start_time.QuadPart;
return (uint32_t)(((ret) * 1000) / freq.QuadPart);
}
uint8_t
lwgsm_sys_init(void) {
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&sys_start_time);
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) {
*p = CreateMutex(NULL, FALSE, NULL);
return *p != NULL;
}
uint8_t
lwgsm_sys_mutex_delete(lwgsm_sys_mutex_t* p) {
return CloseHandle(*p);
}
uint8_t
lwgsm_sys_mutex_lock(lwgsm_sys_mutex_t* p) {
DWORD ret;
ret = WaitForSingleObject(*p, INFINITE);
if (ret != WAIT_OBJECT_0) {
return 0;
}
return 1;
}
uint8_t
lwgsm_sys_mutex_unlock(lwgsm_sys_mutex_t* p) {
return (uint8_t)ReleaseMutex(*p);
}
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) {
HANDLE h;
h = CreateSemaphore(NULL, !!cnt, 1, NULL);
*p = h;
return *p != NULL;
}
uint8_t
lwgsm_sys_sem_delete(lwgsm_sys_sem_t* p) {
return CloseHandle(*p);
}
uint32_t
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;
} else {
ret = WaitForSingleObject(*p, timeout);
if (ret == WAIT_OBJECT_0) {
return 1;
} else {
return LWGSM_SYS_TIMEOUT;
}
}
}
uint8_t
lwgsm_sys_sem_release(lwgsm_sys_sem_t* p) {
return ReleaseSemaphore(*p, 1, NULL);
}
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) {
win32_mbox_t* mbox;
*b = NULL;
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 */
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
lwgsm_sys_mbox_delete(lwgsm_sys_mbox_t* b) {
win32_mbox_t* mbox = *b;
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
lwgsm_sys_mbox_put(lwgsm_sys_mbox_t* b, void* m) {
win32_mbox_t* mbox = *b;
uint32_t time = osKernelSysTick(); /* Get start time */
lwgsm_sys_sem_wait(&mbox->sem, 0); /* Wait for access */
/*
* Since function is blocking until ready to write something to queue,
* wait and release the semaphores to allow other threads
* to process the queue before we can write new value.
*/
while (mbox_is_full(mbox)) {
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->size) {
mbox->in = 0;
}
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
lwgsm_sys_mbox_get(lwgsm_sys_mbox_t* b, void** m, uint32_t timeout) {
win32_mbox_t* mbox = *b;
uint32_t time;
time = osKernelSysTick();
/* Get exclusive access to message queue */
if (lwgsm_sys_sem_wait(&mbox->sem, timeout) == LWGSM_SYS_TIMEOUT) {
return LWGSM_SYS_TIMEOUT;
}
while (mbox_is_empty(mbox)) {
lwgsm_sys_sem_release(&mbox->sem);
if (lwgsm_sys_sem_wait(&mbox->sem_not_empty, timeout) == LWGSM_SYS_TIMEOUT) {
return LWGSM_SYS_TIMEOUT;
}
lwgsm_sys_sem_wait(&mbox->sem, timeout);
}
*m = mbox->entries[mbox->out];
if (++mbox->out >= mbox->size) {
mbox->out = 0;
}
lwgsm_sys_sem_release(&mbox->sem_not_full);
lwgsm_sys_sem_release(&mbox->sem);
return osKernelSysTick() - time;
}
uint8_t
lwgsm_sys_mbox_putnow(lwgsm_sys_mbox_t* b, void* m) {
win32_mbox_t* mbox = *b;
lwgsm_sys_sem_wait(&mbox->sem, 0);
if (mbox_is_full(mbox)) {
lwgsm_sys_sem_release(&mbox->sem);
return 0;
}
mbox->entries[mbox->in] = m;
if (mbox->in == mbox->out) {
lwgsm_sys_sem_release(&mbox->sem_not_empty);
}
if (++mbox->in >= mbox->size) {
mbox->in = 0;
}
lwgsm_sys_sem_release(&mbox->sem);
return 1;
}
uint8_t
lwgsm_sys_mbox_getnow(lwgsm_sys_mbox_t* b, void** m) {
win32_mbox_t* mbox = *b;
lwgsm_sys_sem_wait(&mbox->sem, 0); /* Wait exclusive access */
if (mbox->in == mbox->out) {
lwgsm_sys_sem_release(&mbox->sem); /* Release access */
return 0;
}
*m = mbox->entries[mbox->out];
if (++mbox->out >= mbox->size) {
mbox->out = 0;
}
lwgsm_sys_sem_release(&mbox->sem_not_full); /* Queue not full anymore */
lwgsm_sys_sem_release(&mbox->sem); /* Release semaphore */
return 1;
}
uint8_t
lwgsm_sys_mbox_isvalid(lwgsm_sys_mbox_t* b) {
return b != NULL && *b != NULL; /* Return status if message box is valid */
}
uint8_t
lwgsm_sys_mbox_invalid(lwgsm_sys_mbox_t* b) {
*b = LWGSM_SYS_MBOX_NULL; /* Invalidate message box */
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) {
HANDLE h;
DWORD id;
h = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)thread_func, arg, 0, &id);
if (t != NULL) {
*t = h;
}
return h != NULL;
}
uint8_t
lwgsm_sys_thread_terminate(lwgsm_sys_thread_t* t) {
HANDLE h = NULL;
if (t == NULL) { /* Shall we terminate ourself? */
h = GetCurrentThread(); /* Get current thread handle */
} else { /* We have known thread, find handle by looking at ID */
h = *t;
}
TerminateThread(h, 0);
return 1;
}
uint8_t
lwgsm_sys_thread_yield(void) {
/* Not implemented */
return 1;
}
#endif /* !__DOXYGEN__ */
|
Example: System functions for CMSIS-OS¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | /**
* \file lwgsm_sys_port.h
* \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 <tilen@majerle.eu>
* Version: v0.1.0
*/
#ifndef LWGSM_HDR_SYSTEM_PORT_H
#define LWGSM_HDR_SYSTEM_PORT_H
#include <stdint.h>
#include <stdlib.h>
#include "lwgsm/lwgsm_opt.h"
#include "cmsis_os.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#if LWGSM_CFG_OS && !__DOXYGEN__
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;
#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 /* LWGSM_CFG_OS && !__DOXYGEN__ */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* LWGSM_HDR_SYSTEM_PORT_H */
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 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 <tilen@majerle.eu>
* 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__ */
|
API reference¶
List of all the modules:
LwGSM¶
Ring buffer¶
-
group
LWGSM_BUFF
Generic ring buffer.
Defines
-
BUF_PREF
(x)¶ 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
- Note
Modification of this macro must be done in header and source file aswell
Functions
-
uint8_t
lwgsm_buff_init
(lwgsm_buff_t *buff, size_t size)¶ Initialize buffer.
- Return
1
on success,0
otherwise- Parameters
[in] buff
: Pointer to buffer structure[in] size
: Size of buffer in units of bytes
-
void
lwgsm_buff_free
(lwgsm_buff_t *buff)¶ Free dynamic allocation if used on memory.
- Parameters
[in] buff
: Pointer to buffer structure
-
void
lwgsm_buff_reset
(lwgsm_buff_t *buff)¶ Resets buffer to default values. Buffer size is not modified.
- Parameters
[in] buff
: Buffer handle
-
size_t
lwgsm_buff_write
(lwgsm_buff_t *buff, const void *data, size_t btw)¶ Write data to buffer Copies data from
data
array to buffer and marks buffer as full for maximumcount
number of bytes.- Return
Number of bytes written to buffer. When returned value is less than
btw
, there was no enough memory available to copy full data array- Parameters
[in] buff
: Buffer handle[in] data
: Pointer to data to write into buffer[in] btw
: Number of bytes to write
-
size_t
lwgsm_buff_read
(lwgsm_buff_t *buff, void *data, size_t btr)¶ Read data from buffer Copies data from buffer to
data
array and marks buffer as free for maximumbtr
number of bytes.- Return
Number of bytes read and copied to data array
- Parameters
[in] buff
: Buffer handle[out] data
: Pointer to output memory to copy buffer data to[in] btr
: Number of bytes to read
-
size_t
lwgsm_buff_peek
(lwgsm_buff_t *buff, size_t skip_count, void *data, size_t btp)¶ Read from buffer without changing read pointer (peek only)
- Return
Number of bytes peeked and written to output array
- Parameters
[in] buff
: Buffer handle[in] skip_count
: Number of bytes to skip before reading data[out] data
: Pointer to output memory to copy buffer data to[in] btp
: Number of bytes to peek
-
size_t
lwgsm_buff_get_free
(lwgsm_buff_t *buff)¶ Get number of bytes in buffer available to write.
- Return
Number of free bytes in memory
- Parameters
[in] buff
: Buffer handle
-
size_t
lwgsm_buff_get_full
(lwgsm_buff_t *buff)¶ Get number of bytes in buffer available to read.
- Return
Number of bytes ready to be read
- Parameters
[in] buff
: Buffer handle
-
void *
lwgsm_buff_get_linear_block_read_address
(lwgsm_buff_t *buff)¶ Get linear address for buffer for fast read.
- Return
Linear buffer start address
- Parameters
[in] buff
: Buffer handle
-
size_t
lwgsm_buff_get_linear_block_read_length
(lwgsm_buff_t *buff)¶ Get length of linear block address before it overflows for read operation.
- Return
Linear buffer size in units of bytes for read operation
- Parameters
[in] buff
: Buffer handle
-
size_t
lwgsm_buff_skip
(lwgsm_buff_t *buff, size_t len)¶ Skip (ignore; advance read pointer) buffer data Marks data as read in the buffer and increases free memory for up to
len
bytes.- Note
Useful at the end of streaming transfer such as DMA
- Return
Number of bytes skipped
- Parameters
[in] buff
: Buffer handle[in] len
: Number of bytes to skip and mark as read
-
void *
lwgsm_buff_get_linear_block_write_address
(lwgsm_buff_t *buff)¶ Get linear address for buffer for fast read.
- Return
Linear buffer start address
- Parameters
[in] buff
: Buffer handle
-
size_t
lwgsm_buff_get_linear_block_write_length
(lwgsm_buff_t *buff)¶ Get length of linear block address before it overflows for write operation.
- Return
Linear buffer size in units of bytes for write operation
- Parameters
[in] buff
: Buffer handle
-
size_t
lwgsm_buff_advance
(lwgsm_buff_t *buff, size_t len)¶ Advance write pointer in the buffer. Similar to skip function but modifies write pointer instead of read.
- Note
Useful when hardware is writing to buffer and application needs to increase number of bytes written to buffer by hardware
- Return
Number of bytes advanced for write operation
- Parameters
[in] buff
: Buffer handle[in] len
: Number of bytes to advance
-
struct
lwgsm_buff_t
¶ - #include <lwgsm_typedefs.h>
Buffer structure.
Public Members
-
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 whenw == r - 1
-
size_t
w
¶ Next write pointer. Buffer is considered empty when
r == w
and full whenw == r - 1
-
uint8_t *
-
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 timeUp to
5
UDP connections active at the same timeUp 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 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;
}
|
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
By calling 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.
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 lwgsm_conn_send()
or lwgsm_conn_sendto()
functions.
-
group
LWGSM_CONN
Connection API functions.
Typedefs
-
typedef struct lwgsm_conn *
lwgsm_conn_p
¶ Pointer to lwgsm_conn_t structure.
Enums
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)¶ Start a new connection of specific type.
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[out] conn
: Pointer to connection handle to set new connection reference in case of successful connection[in] type
: Connection type. This parameter can be a value of lwgsm_conn_type_t enumeration[in] host
: Connection host. In case of IP, write it as string, ex. “192.168.1.1”[in] port
: Connection port[in] arg
: Pointer to user argument passed to connection if successfully connected[in] conn_evt_fn
: Callback function for this connection[in] blocking
: Status whether command should be blocking or not
-
lwgsmr_t
lwgsm_conn_close
(lwgsm_conn_p conn, const uint32_t blocking)¶ Close specific or all connections.
-
lwgsmr_t
lwgsm_conn_send
(lwgsm_conn_p conn, const void *data, size_t btw, size_t *const bw, const uint32_t blocking)¶ Send data on already active connection either as client or server.
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[in] conn
: Connection handle to send data[in] data
: Data to send[in] btw
: Number of bytes to send[out] bw
: Pointer to output variable to save number of sent data when successfully sent. Parameter value might not be accurate if you combine lwgsm_conn_write and lwgsm_conn_send functions[in] blocking
: Status whether command should be blocking or not
-
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)¶ Send data on active connection of type UDP to specific remote IP and port.
- Note
In case IP and port values are not set, it will behave as normal send function (suitable for TCP too)
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[in] conn
: Connection handle to send data[in] ip
: Remote IP address for UDP connection[in] port
: Remote port connection[in] data
: Pointer to data to send[in] btw
: Number of bytes to send[out] bw
: Pointer to output variable to save number of sent data when successfully sent[in] blocking
: Status whether command should be blocking or not
-
lwgsmr_t
lwgsm_conn_set_arg
(lwgsm_conn_p conn, void *const arg)¶ Set argument variable for connection.
-
void *
lwgsm_conn_get_arg
(lwgsm_conn_p conn)¶ Get user defined connection argument.
- Return
User argument
- See
- Parameters
[in] conn
: Connection handle to get argument
-
uint8_t
lwgsm_conn_is_client
(lwgsm_conn_p conn)¶ Check if connection type is client.
- Return
1
on success,0
otherwise- Parameters
[in] conn
: Pointer to connection to check for status
-
uint8_t
lwgsm_conn_is_active
(lwgsm_conn_p conn)¶ Check if connection is active.
- Return
1
on success,0
otherwise- Parameters
[in] conn
: Pointer to connection to check for status
-
uint8_t
lwgsm_conn_is_closed
(lwgsm_conn_p conn)¶ Check if connection is closed.
- Return
1
on success,0
otherwise- Parameters
[in] conn
: Pointer to connection to check for status
-
int8_t
lwgsm_conn_getnum
(lwgsm_conn_p conn)¶ Get the number from connection.
- Return
Connection number in case of success or -1 on failure
- Parameters
[in] conn
: Connection pointer
-
lwgsm_conn_p
lwgsm_conn_get_from_evt
(lwgsm_evt_t *evt)¶ Get connection from connection based event.
- Return
Connection pointer on success,
NULL
otherwise- Parameters
[in] evt
: Event which happened for connection
-
lwgsmr_t
lwgsm_conn_write
(lwgsm_conn_p conn, const void *data, size_t btw, uint8_t flush, size_t *const mem_available)¶ Write data to connection buffer and if it is full, send it non-blocking way.
- Note
This function may only be called from core (connection callbacks)
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[in] conn
: Connection to write[in] data
: Data to copy to write buffer[in] btw
: Number of bytes to write[in] flush
: Flush flag. Set to1
if you want to send data immediately after copying[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 lwgsmOK and*mem_available = 0
, there was a problem allocating a new buffer for next operation
-
lwgsmr_t
lwgsm_conn_recved
(lwgsm_conn_p conn, lwgsm_pbuf_p pbuf)¶ Notify connection about received data which means connection is ready to accept more data.
Once data reception is confirmed, stack will try to send more data to user.
- Note
Since this feature is not supported yet by AT commands, function is only prototype and should be used in connection callback when data are received
- Note
Function is not thread safe and may only be called from connection event function
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[in] conn
: Connection handle[in] pbuf
: Packet buffer received on connection
-
size_t
lwgsm_conn_get_total_recved_count
(lwgsm_conn_p conn)¶ Get total number of bytes ever received on connection and sent to user.
- Return
Count of received bytes on connection
- Parameters
[in] conn
: Connection handle
-
uint8_t
lwgsm_conn_get_remote_ip
(lwgsm_conn_p conn, lwgsm_ip_t *ip)¶ Get connection remote IP address.
- Return
1
on success,0
otherwise- Parameters
[in] conn
: Connection handle[out] ip
: Pointer to IP output handle
-
lwgsm_port_t
lwgsm_conn_get_remote_port
(lwgsm_conn_p conn)¶ Get connection remote port number.
- Return
Port number on success,
0
otherwise- Parameters
[in] conn
: Connection handle
-
lwgsm_port_t
lwgsm_conn_get_local_port
(lwgsm_conn_p conn)¶ Get connection local port number.
- Return
Port number on success,
0
otherwise- Parameters
[in] conn
: Connection handle
-
typedef struct lwgsm_conn *
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 LWGSM_CFG_DBG_OUT
configuration.
For successful debugging, application must:
Enable global debugging by setting
LWGSM_CFG_DBG
toLWGSM_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
LWGSM_DBG_ON
Tip
Check Configuration for all modules with debug implementation.
An example code with config and latter usage:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | /* Modifications of lwgsm_opts.h file for configuration */
/* Enable global debug */
#define LWGSM_CFG_DBG LWGSM_DBG_ON
/*
* Enable debug types.
* Application may use bitwise OR | to use multiple types:
* LWGSM_DBG_TYPE_TRACE | LWGSM_DBG_TYPE_STATE
*/
#define LWGSM_CFG_DBG_TYPES_ON LWGSM_DBG_TYPE_TRACE
/* Enable debug on custom module */
#define MY_DBG_MODULE LWGSM_DBG_ON
|
1 2 3 4 5 6 7 8 9 | #include "lwgsm/lwgsm_debug.h"
/*
* Print debug message to the screen
* Trace message will be printed as it is enabled in types
* while state message will not be printed.
*/
LWGSM_DEBUGF(MY_DBG_MODULE | LWGSM_DBG_TYPE_TRACE, "This is trace message on my program\r\n");
LWGSM_DEBUGF(MY_DBG_MODULE | LWGSM_DBG_TYPE_STATE, "This is state message on my program\r\n");
|
-
group
LWGSM_DEBUG
Debugging support module to track stack.
Debug levels
List of debug levels
-
LWGSM_DBG_LVL_ALL
¶ Print all messages of all types
-
LWGSM_DBG_LVL_WARNING
¶ Print warning and upper messages
-
LWGSM_DBG_LVL_DANGER
¶ Print danger errors
-
LWGSM_DBG_LVL_SEVERE
¶ Print severe problems affecting program flow
-
LWGSM_DBG_LVL_MASK
¶ Mask for getting debug level
Debug types
List of possible debugging types
-
LWGSM_DBG_TYPE_TRACE
¶ Debug trace messages for program flow
-
LWGSM_DBG_TYPE_STATE
¶ Debug state messages (such as state machines)
-
LWGSM_DBG_TYPE_ALL
¶ All debug types
Defines
-
LWGSM_DBG_ON
¶ Indicates debug is enabled
-
LWGSM_DBG_OFF
¶ Indicates debug is disabled
-
LWGSM_DEBUGF
(c, fmt, ...)¶ Print message to the debug “window” if enabled.
- Parameters
[in] c
: Condition if debug of specific type is enabled[in] fmt
: Formatted string for debug[in] ...
: Variable parameters for formatted string
-
LWGSM_DEBUGW
(c, cond, fmt, ...)¶ Print message to the debug “window” if enabled when specific condition is met.
- Parameters
[in] c
: Condition if debug of specific type is enabled[in] cond
: Debug only if this condition is true[in] fmt
: Formatted string for debug[in] ...
: Variable parameters for formatted string
-
Device info¶
-
group
LWGSM_DEVICE_INFO
Basic device information.
Functions
-
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)¶ Get device manufacturer.
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[in] manuf
: Pointer to output string array to save manufacturer info[in] len
: Length of string array includingNULL
termination[in] evt_fn
: Callback function called when command has finished. Set toNULL
when not used[in] evt_arg
: Custom argument for event callback function[in] blocking
: Status whether command should be blocking or not
-
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)¶ Get device model name.
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[in] model
: Pointer to output string array to save model info[in] len
: Length of string array includingNULL
termination[in] evt_fn
: Callback function called when command has finished. Set toNULL
when not used[in] evt_arg
: Custom argument for event callback function[in] blocking
: Status whether command should be blocking or not
-
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)¶ Get device revision.
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[in] rev
: Pointer to output string array to save revision info[in] len
: Length of string array includingNULL
termination[in] evt_fn
: Callback function called when command has finished. Set toNULL
when not used[in] evt_arg
: Custom argument for event callback function[in] blocking
: Status whether command should be blocking or not
-
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)¶ Get device serial number.
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[in] serial
: Pointer to output string array to save serial number info[in] len
: Length of string array includingNULL
termination[in] evt_fn
: Callback function called when command has finished. Set toNULL
when not used[in] evt_arg
: Custom argument for event callback function[in] blocking
: Status whether command should be blocking or not
-
lwgsmr_t
Event management¶
-
group
LWGSM_EVT
Event helper functions.
Reset event
Event helper functions for LWGSM_EVT_RESET event
-
lwgsmr_t
lwgsm_evt_reset_get_result
(lwgsm_evt_t *cc)¶ Get reset sequence operation status.
- Return
Member of lwgsmr_t enumeration
- Parameters
[in] cc
: Event data
Restore event
Event helper functions for LWGSM_EVT_RESTORE event
-
lwgsmr_t
lwgsm_evt_restore_get_result
(lwgsm_evt_t *cc)¶ Get restore sequence operation status.
- Return
Member of lwgsmr_t enumeration
- Parameters
[in] cc
: Event data
Current network operator
Event helper functions for LWGSM_EVT_NETWORK_OPERATOR_CURRENT event
-
const lwgsm_operator_curr_t *
lwgsm_evt_network_operator_get_current
(lwgsm_evt_t *cc)¶ Get current operator data from event.
- Return
Current operator handle
- Parameters
[in] cc
: Event data
Connection data received
Event helper functions for LWGSM_EVT_CONN_RECV event
-
lwgsm_pbuf_p
lwgsm_evt_conn_recv_get_buff
(lwgsm_evt_t *cc)¶ Get buffer from received data.
- Return
Buffer handle
- Parameters
[in] cc
: Event handle
-
lwgsm_conn_p
lwgsm_evt_conn_recv_get_conn
(lwgsm_evt_t *cc)¶ Get connection handle for receive.
- Return
Connection handle
- Parameters
[in] cc
: Event handle
Connection data send
Event helper functions for LWGSM_EVT_CONN_SEND event
-
lwgsm_conn_p
lwgsm_evt_conn_send_get_conn
(lwgsm_evt_t *cc)¶ Get connection handle for data sent event.
- Return
Connection handle
- Parameters
[in] cc
: Event handle
-
size_t
lwgsm_evt_conn_send_get_length
(lwgsm_evt_t *cc)¶ Get number of bytes sent on connection.
- Return
Number of bytes sent
- Parameters
[in] cc
: Event handle
-
lwgsmr_t
lwgsm_evt_conn_send_get_result
(lwgsm_evt_t *cc)¶ Check if connection send was successful.
- Return
Member of lwgsmr_t enumeration
- Parameters
[in] cc
: Event handle
Connection active
Event helper functions for LWGSM_EVT_CONN_ACTIVE event
-
lwgsm_conn_p
lwgsm_evt_conn_active_get_conn
(lwgsm_evt_t *cc)¶ Get connection handle.
- Return
Connection handle
- Parameters
[in] cc
: Event handle
-
uint8_t
lwgsm_evt_conn_active_is_client
(lwgsm_evt_t *cc)¶ Check if new connection is client.
- Return
1
if client,0
otherwise- Parameters
[in] cc
: Event handle
Connection close event
Event helper functions for LWGSM_EVT_CONN_CLOSE event
-
lwgsm_conn_p
lwgsm_evt_conn_close_get_conn
(lwgsm_evt_t *cc)¶ Get connection handle.
- Return
Connection handle
- Parameters
[in] cc
: Event handle
-
uint8_t
lwgsm_evt_conn_close_is_client
(lwgsm_evt_t *cc)¶ Check if close connection was client.
- Return
1
if client,0
otherwise- Parameters
[in] cc
: Event handle
-
uint8_t
lwgsm_evt_conn_close_is_forced
(lwgsm_evt_t *cc)¶ Check if connection close even was forced by user.
- Return
1
if forced,0
otherwise- Parameters
[in] cc
: Event handle
-
lwgsmr_t
lwgsm_evt_conn_close_get_result
(lwgsm_evt_t *cc)¶ Get connection close event result.
- Return
Member of lwgsmr_t enumeration
- Parameters
[in] cc
: Event handle
Connection poll
Event helper functions for LWGSM_EVT_CONN_POLL event
-
lwgsm_conn_p
lwgsm_evt_conn_poll_get_conn
(lwgsm_evt_t *cc)¶ Get connection handle.
- Return
Connection handle
- Parameters
[in] cc
: Event handle
Connection error
Event helper functions for LWGSM_EVT_CONN_ERROR event
-
lwgsmr_t
lwgsm_evt_conn_error_get_error
(lwgsm_evt_t *cc)¶ Get connection error type.
- Return
Member of lwgsmr_t enumeration
- Parameters
[in] cc
: Event handle
-
lwgsm_conn_type_t
lwgsm_evt_conn_error_get_type
(lwgsm_evt_t *cc)¶ Get connection type.
- Return
Member of lwgsmr_t enumeration
- Parameters
[in] cc
: Event handle
-
const char *
lwgsm_evt_conn_error_get_host
(lwgsm_evt_t *cc)¶ Get connection host.
- Return
Host name for connection
- Parameters
[in] cc
: Event handle
-
lwgsm_port_t
lwgsm_evt_conn_error_get_port
(lwgsm_evt_t *cc)¶ Get connection port.
- Return
Host port number
- Parameters
[in] cc
: Event handle
-
void *
lwgsm_evt_conn_error_get_arg
(lwgsm_evt_t *cc)¶ Get user argument.
- Return
User argument
- Parameters
[in] cc
: Event handle
Signal strength
Event helper functions for LWGSM_EVT_CONN_RECV event
-
int16_t
lwgsm_evt_signal_strength_get_rssi
(lwgsm_evt_t *cc)¶ Get RSSi from CSQ command.
- Return
RSSI value in units of dBm
- Parameters
[in] cc
: Event data
SMS received
Event helper functions for LWGSM_EVT_SMS_RECV event
-
size_t
lwgsm_evt_sms_recv_get_pos
(lwgsm_evt_t *cc)¶ Get SMS position in memory which has been saved on receive.
- Return
SMS position in memory
- Parameters
[in] cc
: Event handle
-
lwgsm_mem_t
lwgsm_evt_sms_recv_get_mem
(lwgsm_evt_t *cc)¶ Get SMS memory used to save SMS on receive.
- Return
SMS memory location
- Parameters
[in] cc
: Event handle
SMS content read
Event helper functions for LWGSM_EVT_SMS_READ event
-
lwgsm_sms_entry_t *
lwgsm_evt_sms_read_get_entry
(lwgsm_evt_t *cc)¶ Get SMS entry after successful read.
- Return
SMS entry
- Parameters
[in] cc
: Event handle
-
lwgsmr_t
lwgsm_evt_sms_read_get_result
(lwgsm_evt_t *cc)¶ Get SMS read operation result.
- Return
SMS entry
- Parameters
[in] cc
: Event handle
SMS send
Event helper functions for LWGSM_EVT_SMS_SEND event
-
lwgsmr_t
lwgsm_evt_sms_send_get_result
(lwgsm_evt_t *cc)¶ Get SMS send result status.
- Return
Member of lwgsmr_t enumeration
- Parameters
[in] cc
: Event handle
-
size_t
lwgsm_evt_sms_send_get_pos
(lwgsm_evt_t *cc)¶ Get SMS send position in memory.
- Note
Use only if SMS sent successfully
- Return
Position in memory
- Parameters
[in] cc
: Event handle
SMS delete
Event helper functions for LWGSM_EVT_SMS_DELETE event
-
lwgsmr_t
lwgsm_evt_sms_delete_get_result
(lwgsm_evt_t *cc)¶ Get SMS delete result status.
- Return
Member of lwgsmr_t enumeration
- Parameters
[in] cc
: Event handle
-
size_t
lwgsm_evt_sms_delete_get_pos
(lwgsm_evt_t *cc)¶ Get SMS delete memory position.
- Return
Deleted position in memory
- Parameters
[in] cc
: Event handle
-
lwgsm_mem_t
lwgsm_evt_sms_delete_get_mem
(lwgsm_evt_t *cc)¶ Get SMS delete memory.
- Return
SMS memory for delete operation
- Parameters
[in] cc
: Event handle
Call status changed
Event helper functions for LWGSM_EVT_CALL_CHANGED event
-
const lwgsm_call_t *
lwgsm_evt_call_changed_get_call
(lwgsm_evt_t *cc)¶ Get call information from changed event.
- Return
Position in memory
- Parameters
[in] cc
: Event handle
Operator scan
Event helper functions for LWGSM_EVT_OPERATOR_SCAN event
-
lwgsmr_t
lwgsm_evt_operator_scan_get_result
(lwgsm_evt_t *cc)¶ Get operator scan operation status.
- Return
Member of lwgsmr_t enumeration
- Parameters
[in] cc
: Event data
-
lwgsm_operator_t *
lwgsm_evt_operator_scan_get_entries
(lwgsm_evt_t *cc)¶ Get operator entries from scan.
- Return
Pointer to array of operator entries
- Parameters
[in] cc
: Event data
-
size_t
lwgsm_evt_operator_scan_get_length
(lwgsm_evt_t *cc)¶ Get length of operators scanned.
- Return
Number of operators scanned
- Parameters
[in] cc
: Event data
Typedefs
Enums
-
enum
lwgsm_evt_type_t
¶ List of possible callback types received to user.
Values:
-
enumerator
LWGSM_EVT_INIT_FINISH
¶ Initialization has been finished at this point
-
enumerator
LWGSM_EVT_RESET
¶ Device reset operation finished
-
enumerator
LWGSM_EVT_RESTORE
¶ Device restore operation finished
-
enumerator
LWGSM_EVT_CMD_TIMEOUT
¶ Timeout on command. When application receives this event, it may reset system as there was (maybe) a problem in device
-
enumerator
LWGSM_EVT_DEVICE_PRESENT
¶ Notification when device present status changes
-
enumerator
LWGSM_EVT_DEVICE_IDENTIFIED
¶ Device identified event
-
enumerator
LWGSM_EVT_SIGNAL_STRENGTH
¶ Signal strength event
-
enumerator
LWGSM_EVT_SIM_STATE_CHANGED
¶ SIM card state changed
-
enumerator
LWGSM_EVT_OPERATOR_SCAN
¶ Operator scan finished event
-
enumerator
LWGSM_EVT_NETWORK_OPERATOR_CURRENT
¶ Current operator event
-
enumerator
LWGSM_EVT_NETWORK_REG_CHANGED
¶ Network registration changed. Available even when LWGSM_CFG_NETWORK is disabled
-
enumerator
LWGSM_EVT_NETWORK_ATTACHED
¶ Attached to network, PDP context active and ready for TCP/IP application
-
enumerator
LWGSM_EVT_NETWORK_DETACHED
¶ Detached from network, PDP context not active anymore
-
enumerator
LWGSM_EVT_CONN_RECV
¶ Connection data received
-
enumerator
LWGSM_EVT_CONN_SEND
¶ Connection data send
-
enumerator
LWGSM_EVT_CONN_ACTIVE
¶ Connection just became active
-
enumerator
LWGSM_EVT_CONN_ERROR
¶ Client connection start was not successful
-
enumerator
LWGSM_EVT_CONN_CLOSE
¶ Connection close event. Check status if successful
-
enumerator
LWGSM_EVT_CONN_POLL
¶ Poll for connection if there are any changes
-
enumerator
LWGSM_EVT_SMS_ENABLE
¶ SMS enable event
-
enumerator
LWGSM_EVT_SMS_READY
¶ SMS ready event
-
enumerator
LWGSM_EVT_SMS_SEND
¶ SMS send event
-
enumerator
LWGSM_EVT_SMS_RECV
¶ SMS received
-
enumerator
LWGSM_EVT_SMS_READ
¶ SMS read
-
enumerator
LWGSM_EVT_SMS_DELETE
¶ SMS delete
-
enumerator
LWGSM_EVT_SMS_LIST
¶ SMS list
-
enumerator
LWGSM_EVT_CALL_ENABLE
¶ Call enable event
-
enumerator
LWGSM_EVT_CALL_READY
¶ Call ready event
-
enumerator
LWGSM_EVT_CALL_CHANGED
¶ Call info changed,
+CLCK
statement received
-
enumerator
LWGSM_EVT_CALL_RING
¶ Call is ringing event
-
enumerator
LWGSM_EVT_CALL_BUSY
¶ Call is busy
-
enumerator
LWGSM_EVT_CALL_NO_CARRIER
¶ No carrier to make a call
-
enumerator
LWGSM_EVT_PB_ENABLE
¶ Phonebook enable event
-
enumerator
LWGSM_EVT_PB_LIST
¶ Phonebook list event
-
enumerator
LWGSM_EVT_PB_SEARCH
¶ Phonebook search event
-
enumerator
Functions
-
lwgsmr_t
lwgsm_evt_register
(lwgsm_evt_fn fn)¶ Register callback function for global (non-connection based) events.
-
lwgsmr_t
lwgsm_evt_unregister
(lwgsm_evt_fn fn)¶ Unregister callback function for global (non-connection based) events.
- Note
Function must be first registered using lwgsm_evt_register
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[in] fn
: Callback function to remove from event list
-
lwgsm_evt_type_t
lwgsm_evt_get_type
(lwgsm_evt_t *cc)¶ Get event type.
- Return
Event type. Member of lwgsm_evt_type_t enumeration
- Parameters
[in] cc
: Event handle
-
struct
lwgsm_evt_t
¶ - #include <lwgsm_typedefs.h>
Global callback structure to pass as parameter to callback function.
Public Members
-
lwgsm_evt_type_t
type
¶ Callback type
-
lwgsmr_t
res
¶ Reset operation result
Restore operation result
Scan operation result
Send data result
Result of close event. Set to lwgsmOK on success.
SMS send result information
SMS read result information
Operation success
Result on command
Enable status
-
struct lwgsm_evt_t::[anonymous]::[anonymous]
reset
¶ Reset sequence finish. Use with LWGSM_EVT_RESET event
-
struct lwgsm_evt_t::[anonymous]::[anonymous]
restore
¶ Restore sequence finish. Use with LWGSM_EVT_RESTORE event
-
lwgsm_sim_state_t
state
¶ SIM state
-
struct lwgsm_evt_t::[anonymous]::[anonymous]
cpin
¶ CPIN event
-
const lwgsm_operator_curr_t *
operator_current
¶ Current operator info
-
struct lwgsm_evt_t::[anonymous]::[anonymous]
operator_current
Current operator event. Use with LWGSM_EVT_NETWORK_OPERATOR_CURRENT event
-
lwgsm_operator_t *
ops
¶ Pointer to operators
-
size_t
opf
¶ Number of operators found
-
struct lwgsm_evt_t::[anonymous]::[anonymous]
operator_scan
¶ Operator scan event. Use with LWGSM_EVT_OPERATOR_SCAN event
-
int16_t
rssi
¶ Strength in units of dBm
-
struct lwgsm_evt_t::[anonymous]::[anonymous]
rssi
Signal strength event. Use with LWGSM_EVT_SIGNAL_STRENGTH event
-
lwgsm_conn_p
conn
¶ Connection where data were received
Connection where data were sent
Pointer to connection
Set connection pointer
-
lwgsm_pbuf_p
buff
¶ Pointer to received data
-
struct lwgsm_evt_t::[anonymous]::[anonymous]
conn_data_recv
¶ Network data received. Use with LWGSM_EVT_CONN_RECV event
-
size_t
sent
¶ Number of bytes sent on connection
-
struct lwgsm_evt_t::[anonymous]::[anonymous]
conn_data_send
¶ Data successfully sent. Use with LWGSM_EVT_CONN_SEND event
-
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
-
struct lwgsm_evt_t::[anonymous]::[anonymous]
conn_error
¶ Client connection start error. Use with LWGSM_EVT_CONN_ERROR event
-
uint8_t
client
¶ Set to
1
if connection is/was client mode
-
uint8_t
forced
¶ Set to
1
if connection action was forced
-
struct lwgsm_evt_t::[anonymous]::[anonymous]
conn_active_close
¶ Process active and closed statuses at the same time. Use with LWGSM_EVT_CONN_ACTIVE or LWGSM_EVT_CONN_CLOSE events
-
struct lwgsm_evt_t::[anonymous]::[anonymous]
conn_poll
¶ Polling active connection to check for timeouts. Use with LWGSM_EVT_CONN_POLL event
-
struct lwgsm_evt_t::[anonymous]::[anonymous]
sms_enable
¶ SMS enable event. Use with LWGSM_EVT_SMS_ENABLE event
-
size_t
pos
¶ Position in memory
Received position in memory for sent SMS
Deleted position in memory for sent SMS
-
struct lwgsm_evt_t::[anonymous]::[anonymous]
sms_send
¶ SMS sent info. Use with LWGSM_EVT_SMS_SEND event
-
lwgsm_mem_t
mem
¶ Memory of received message
Memory of deleted message
Memory used for scan
-
struct lwgsm_evt_t::[anonymous]::[anonymous]
sms_recv
¶ SMS received info. Use with LWGSM_EVT_SMS_RECV event
-
lwgsm_sms_entry_t *
entry
¶ SMS entry
-
struct lwgsm_evt_t::[anonymous]::[anonymous]
sms_read
¶ SMS read. Use with LWGSM_EVT_SMS_READ event
-
struct lwgsm_evt_t::[anonymous]::[anonymous]
sms_delete
¶ SMS delete. Use with LWGSM_EVT_SMS_DELETE event
-
lwgsm_sms_entry_t *
entries
¶ Pointer to entries
-
size_t
size
¶ Number of valid entries
-
struct lwgsm_evt_t::[anonymous]::[anonymous]
sms_list
¶ SMS list. Use with LWGSM_EVT_SMS_LIST event
-
struct lwgsm_evt_t::[anonymous]::[anonymous]
call_enable
¶ Call enable event. Use with LWGSM_EVT_CALL_ENABLE event
-
const lwgsm_call_t *
call
¶ Call information
-
struct lwgsm_evt_t::[anonymous]::[anonymous]
call_changed
¶ Call changed info. Use with LWGSM_EVT_CALL_CHANGED event
-
struct lwgsm_evt_t::[anonymous]::[anonymous]
pb_enable
¶ Phonebook enable event. Use with LWGSM_EVT_PB_ENABLE event
-
lwgsm_pb_entry_t *
entries
Pointer to entries
-
struct lwgsm_evt_t::[anonymous]::[anonymous]
pb_list
¶ Phonebok list. Use with LWGSM_EVT_PB_LIST event
-
const char *
search
¶ Search string
-
struct lwgsm_evt_t::[anonymous]::[anonymous]
pb_search
¶ Phonebok search list. Use with LWGSM_EVT_PB_SEARCH event
-
union lwgsm_evt_t::[anonymous]
evt
¶ Callback event union
-
lwgsm_evt_type_t
-
lwgsmr_t
File Transfer Protocol¶
-
group
LWGSM_FTP
File Transfer Protocol (FTP) manager.
Currently it is under development
HTTP¶
-
group
LWGSM_HTTP
Hyper Text Transfer Protocol (HTTP) manager.
Currently it is under development
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
lwgsm_input()
(default mode)Direct processing with
lwgsm_input_process()
Tip
Direct or indirect processing mode is select by setting 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 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 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 Porting guide for implementation examples.
-
group
LWGSM_INPUT
Input function for received data.
Functions
-
lwgsmr_t
lwgsm_input
(const void *data, size_t len)¶ Write data to input buffer.
- Note
LWGSM_CFG_INPUT_USE_PROCESS must be disabled to use this function
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[in] data
: Pointer to data to write[in] len
: Number of data elements in units of bytes
-
lwgsmr_t
lwgsm_input_process
(const void *data, size_t len)¶ 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
LWGSM_CFG_INPUT_USE_PROCESS must be enabled to use this function
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[in] data
: Pointer to received data to be processed[in] len
: Length of data to process in units of bytes
-
lwgsmr_t
Memory manager¶
-
group
LWGSM_MEM
Dynamic memory manager.
Functions
-
uint8_t
lwgsm_mem_assignmemory
(const lwgsm_mem_region_t *regions, size_t size)¶ Assign memory region(s) for allocation functions.
- Note
You can allocate multiple regions by assigning start address and region size in units of bytes
- Return
1
on success,0
otherwise- Note
Function is not available when LWGSM_CFG_MEM_CUSTOM is
1
- Parameters
[in] regions
: Pointer to list of regions to use for allocations[in] len
: Number of regions to use
-
void *
lwgsm_mem_malloc
(size_t size)¶ Allocate memory of specific size.
- Return
Memory address on success,
NULL
otherwise- Note
Function is not available when LWGSM_CFG_MEM_CUSTOM is
1
and must be implemented by user- Parameters
[in] size
: Number of bytes to allocate
-
void *
lwgsm_mem_realloc
(void *ptr, size_t size)¶ Reallocate memory to specific size.
- Note
After new memory is allocated, content of old one is copied to new memory
- Return
Memory address on success,
NULL
otherwise- Note
Function is not available when LWGSM_CFG_MEM_CUSTOM is
1
and must be implemented by user- Parameters
[in] ptr
: Pointer to current allocated memory to resize, returned using lwgsm_mem_malloc, lwgsm_mem_calloc or lwgsm_mem_realloc functions[in] size
: Number of bytes to allocate on new memory
-
void *
lwgsm_mem_calloc
(size_t num, size_t size)¶ Allocate memory of specific size and set memory to zero.
- Return
Memory address on success,
NULL
otherwise- Note
Function is not available when LWGSM_CFG_MEM_CUSTOM is
1
and must be implemented by user- Parameters
[in] num
: Number of elements to allocate[in] size
: Size of each element
-
void
lwgsm_mem_free
(void *ptr)¶ Free memory.
- Note
Function is not available when LWGSM_CFG_MEM_CUSTOM is
1
and must be implemented by user- Parameters
[in] ptr
: Pointer to memory previously returned using lwgsm_mem_malloc, lwgsm_mem_calloc or lwgsm_mem_realloc functions
-
uint8_t
lwgsm_mem_free_s
(void **ptr)¶ Free memory in safe way by invalidating pointer after freeing.
- Return
1
on success,0
otherwise- Parameters
[in] ptr
: Pointer to pointer to allocated memory to free
-
struct
lwgsm_mem_region_t
¶ - #include <lwgsm_mem.h>
Single memory region descriptor.
-
uint8_t
Network¶
-
group
LWGSM_NETWORK
Network manager.
Enums
-
enum
lwgsm_network_reg_status_t
¶ Network Registration status.
Values:
-
enumerator
LWGSM_NETWORK_REG_STATUS_SIM_ERR
¶ SIM card error
-
enumerator
LWGSM_NETWORK_REG_STATUS_CONNECTED
¶ Device is connected to network
-
enumerator
LWGSM_NETWORK_REG_STATUS_SEARCHING
¶ Network search is in progress
-
enumerator
LWGSM_NETWORK_REG_STATUS_DENIED
¶ Registration denied
-
enumerator
LWGSM_NETWORK_REG_STATUS_CONNECTED_ROAMING
¶ Device is connected and is roaming
-
enumerator
LWGSM_NETWORK_REG_STATUS_CONNECTED_SMS_ONLY
¶ Device is connected to home network in SMS-only mode
-
enumerator
LWGSM_NETWORK_REG_STATUS_CONNECTED_ROAMING_SMS_ONLY
¶ Device is roaming in SMS-only mode
-
enumerator
Functions
-
lwgsmr_t
lwgsm_network_rssi
(int16_t *rssi, const lwgsm_api_cmd_evt_fn evt_fn, void *const evt_arg, const uint32_t blocking)¶ Read RSSI signal from network operator.
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[out] rssi
: RSSI output variable. When set to0
, RSSI is not valid[in] evt_fn
: Callback function called when command has finished. Set toNULL
when not used[in] evt_arg
: Custom argument for event callback function[in] blocking
: Status whether command should be blocking or not
-
lwgsm_network_reg_status_t
lwgsm_network_get_reg_status
(void)¶ Get network registration status.
- Return
Member of lwgsm_network_reg_status_t enumeration
-
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)¶ Attach to network and active PDP context.
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[in] apn
: APN name[in] user
: User name to attach. Set toNULL
if not used[in] pass
: User password to attach. Set toNULL
if not used[in] evt_fn
: Callback function called when command has finished. Set toNULL
when not used[in] evt_arg
: Custom argument for event callback function[in] blocking
: Status whether command should be blocking or not
-
lwgsmr_t
lwgsm_network_detach
(const lwgsm_api_cmd_evt_fn evt_fn, void *const evt_arg, const uint32_t blocking)¶ Detach from network.
-
uint8_t
lwgsm_network_is_attached
(void)¶ Check if device is attached to network and PDP context is active.
- Return
1
on success,0
otherwise
-
lwgsmr_t
lwgsm_network_copy_ip
(lwgsm_ip_t *ip)¶ Copy IP address from internal value to user variable.
-
lwgsmr_t
lwgsm_network_check_status
(const lwgsm_api_cmd_evt_fn evt_fn, void *const evt_arg, const uint32_t blocking)¶ Check network PDP status.
-
enum
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.
-
group
LWGSM_NETWORK_API
Network API functions for multi-thread operations.
Functions
-
lwgsmr_t
lwgsm_network_set_credentials
(const char *apn, const char *user, const char *pass)¶ Set system network credentials before asking for attach.
-
lwgsmr_t
Network operator¶
-
group
LWGSM_OPERATOR
network operator API
Enums
-
enum
lwgsm_operator_status_t
¶ Operator status value.
Values:
-
enumerator
LWGSM_OPERATOR_STATUS_UNKNOWN
¶ Unknown operator
-
enumerator
LWGSM_OPERATOR_STATUS_AVAILABLE
¶ Operator is available
-
enumerator
LWGSM_OPERATOR_STATUS_CURRENT
¶ Operator is currently active
-
enumerator
LWGSM_OPERATOR_STATUS_FORBIDDEN
¶ Operator is forbidden
-
enumerator
-
enum
lwgsm_operator_mode_t
¶ Operator selection mode.
Values:
-
enumerator
LWGSM_OPERATOR_MODE_AUTO
¶ Operator automatic mode
-
enumerator
LWGSM_OPERATOR_MODE_MANUAL
¶ Operator manual mode
-
enumerator
LWGSM_OPERATOR_MODE_DEREGISTER
¶ Operator deregistered from network
-
enumerator
LWGSM_OPERATOR_MODE_MANUAL_AUTO
¶ Operator manual mode first. If fails, auto mode enabled
-
enumerator
-
enum
lwgsm_operator_format_t
¶ Operator data format.
Values:
-
enumerator
LWGSM_OPERATOR_FORMAT_LONG_NAME
¶ COPS command returned long name
-
enumerator
LWGSM_OPERATOR_FORMAT_SHORT_NAME
¶ COPS command returned short name
-
enumerator
LWGSM_OPERATOR_FORMAT_NUMBER
¶ COPS command returned number
-
enumerator
LWGSM_OPERATOR_FORMAT_INVALID
¶ Unknown format
-
enumerator
Functions
-
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)¶ Get current operator.
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[out] curr
: Pointer to output variable to save info about current operator[in] evt_fn
: Callback function called when command has finished. Set toNULL
when not used[in] evt_arg
: Custom argument for event callback function[in] blocking
: Status whether command should be blocking or not
-
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)¶ Set current operator.
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[in] mode
: Operator mode. This parameter can be a value of lwgsm_operator_mode_t enumeration[in] format
: Operator data format. This parameter can be a value of lwgsm_operator_format_t enumeration[in] name
: Operator name. This parameter must be valid according toformat
parameter[in] num
: Operator number. This parameter must be valid according toformat
parameter[in] evt_fn
: Callback function called when command has finished. Set toNULL
when not used[in] evt_arg
: Custom argument for event callback function[in] blocking
: Status whether command should be blocking or not
-
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)¶ Scan for available operators.
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[in] ops
: Pointer to array to write found operators[in] opsl
: Length of input array in units of elements[out] opf
: Pointer to ouput variable to save number of operators found[in] evt_fn
: Callback function called when command has finished. Set toNULL
when not used[in] evt_arg
: Custom argument for event callback function[in] blocking
: Status whether command should be blocking or not
-
struct
lwgsm_operator_t
¶ - #include <lwgsm_typedefs.h>
Operator details for scan.
Public Members
-
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_status_t
-
struct
lwgsm_operator_curr_t
¶ - #include <lwgsm_typedefs.h>
Current operator info.
Public Members
-
lwgsm_operator_mode_t
mode
¶ Operator mode
-
lwgsm_operator_format_t
format
¶ Data format
-
char
long_name
[20]¶ Long name format
-
char
short_name
[20]¶ Short name format
-
uint32_t
num
¶ Number format
-
union lwgsm_operator_curr_t::[anonymous]
data
¶ Operator data union
-
lwgsm_operator_mode_t
-
enum
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¶
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 chainLength 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
Block number |
Next pbuf |
Block size |
Total size in chain |
Reference counter |
---|---|---|---|---|
Block 1 |
Block 2 |
|
|
|
Block 2 |
Block 3 |
|
|
|
Block 3 |
|
|
|
|
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 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 memoryIf reference counter
!= 0
after decrease, it stops free procedureGo 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.
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 |
|
|
|
Block 3 |
|
|
|
|
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 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.
Different pbufs, each pointed to by its own variable¶
Concat operation shall be used when 2
pbufs are linked together and reference to second is no longer used.
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 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | lwgsm_pbuf_p a, b;
/* Create 2 pbufs of different sizes */
a = lwgsm_pbuf_new(10);
b = lwgsm_pbuf_new(20);
/* Link them together with concat operation */
/* Reference on b will stay as is, won't be increased */
lwgsm_pbuf_cat(a, b);
/*
* Operating with b variable has from now on undefined behavior,
* application shall stop using variable b to access pbuf.
*
* The best way would be to set b reference to NULL
*/
b = NULL;
/*
* When application doesn't need pbufs anymore,
* free a and it will also free b
*/
lwgsm_pbuf_free(a);
|
Chain operation shall be used when 2
pbufs are linked together and reference to second is still required.
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 lwgsm_pbuf_chain()
,
it also has to manually free its reference using lwgsm_pbuf_free()
function.
Forgetting to free pbuf invokes memory leak
An example code showing proper usage of chain operation:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | lwgsm_pbuf_p a, b;
/* Create 2 pbufs of different sizes */
a = lwgsm_pbuf_new(10);
b = lwgsm_pbuf_new(20);
/* Chain both pbufs together */
/* This will increase reference on b as 2 variables now point to it */
lwgsm_pbuf_chain(a, b);
/*
* When application does not need a anymore, it may free it
* This will free only pbuf a, as pbuf b has now 2 references:
* - one from pbuf a
* - one from variable b
*/
/* If application calls this, it will free only first pbuf */
/* As there is link to b pbuf somewhere */
lwgsm_pbuf_free(a);
/* Reset a variable, not used anymore */
a = NULL;
/*
* At this point, b is still valid memory block,
* but when application doesn't need it anymore,
* it should free it, otherwise memory leak appears
*/
lwgsm_pbuf_free(b);
/* Reset b variable */
b = NULL;
|
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | const void* data;
size_t pos, len;
lwgsm_pbuf_p a, b, c;
const char str_a[] = "This is one long";
const char str_a[] = "string. We want to save";
const char str_a[] = "chain of pbufs to file";
/* Create pbufs to hold these strings */
a = lwgsm_pbuf_new(strlen(str_a));
b = lwgsm_pbuf_new(strlen(str_b));
c = lwgsm_pbuf_new(strlen(str_c));
/* Write data to pbufs */
lwgsm_pbuf_take(a, str_a, strlen(str_a), 0);
lwgsm_pbuf_take(b, str_b, strlen(str_b), 0);
lwgsm_pbuf_take(c, str_c, strlen(str_c), 0);
/* Connect pbufs together */
lwgsm_pbuf_chain(a, b);
lwgsm_pbuf_chain(a, c);
/*
* pbuf a now contains chain of b and c together
* and at this point application wants to print (or save) data from chained pbuf
*
* Process pbuf by pbuf with code below
*/
/*
* Get linear address of current pbuf at specific offset
* Function will return pointer to memory address at specific position
* and `len` will hold length of data block
*/
pos = 0;
while ((data = lwgsm_pbuf_get_linear_addr(a, pos, &len)) != NULL) {
/* Custom process function... */
/* Process data with data pointer and block length */
process_data(data, len);
printf("Str: %.*s", len, data);
/* Increase offset position for next block */
pos += len;
}
/* Call free only on a pbuf. Since it is chained, b and c will be freed too */
lwgsm_pbuf_free(a);
|
-
group
LWGSM_PBUF
Packet buffer manager.
Typedefs
-
typedef struct lwgsm_pbuf *
lwgsm_pbuf_p
¶ Pointer to lwgsm_pbuf_t structure.
Functions
-
lwgsm_pbuf_p
lwgsm_pbuf_new
(size_t len)¶ Allocate packet buffer for network data of specific size.
- Return
Pointer to allocated memory,
NULL
otherwise- Parameters
[in] len
: Length of payload memory to allocate
-
size_t
lwgsm_pbuf_free
(lwgsm_pbuf_p pbuf)¶ Free previously allocated packet buffer.
- Return
Number of freed pbufs from head
- Parameters
[in] pbuf
: Packet buffer to free
-
void *
lwgsm_pbuf_data
(const lwgsm_pbuf_p pbuf)¶ Get data pointer from packet buffer.
- Return
Pointer to data buffer on success,
NULL
otherwise- Parameters
[in] pbuf
: Packet buffer
-
size_t
lwgsm_pbuf_length
(const lwgsm_pbuf_p pbuf, uint8_t tot)¶ Get length of packet buffer.
- Return
Length of data in units of bytes
- Parameters
[in] pbuf
: Packet buffer to get length for[in] tot
: Set to1
to return total packet chain length or0
to get only first packet length
-
lwgsmr_t
lwgsm_pbuf_take
(lwgsm_pbuf_p pbuf, const void *data, size_t len, size_t offset)¶ Copy user data to chain of pbufs.
-
size_t
lwgsm_pbuf_copy
(lwgsm_pbuf_p pbuf, void *data, size_t len, size_t offset)¶ Copy memory from pbuf to user linear memory.
- Return
Number of bytes copied
- Parameters
[in] pbuf
: Pbuf to copy from[out] data
: User linear memory to copy to[in] len
: Length of data in units of bytes[in] offset
: Possible start offset in pbuf
-
lwgsmr_t
lwgsm_pbuf_cat
(lwgsm_pbuf_p head, const lwgsm_pbuf_p tail)¶ Concatenate
2
packet buffers together to one big packet.- Note
After
tail
pbuf has been added tohead
pbuf chain, it must not be referenced by user anymore as it is now completely controlled byhead
pbuf. In simple words, when user calls this function, it should not call lwgsm_pbuf_free function anymore, as it might make memory undefined forhead
pbuf.- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- See
- Parameters
[in] head
: Head packet buffer to append new pbuf to[in] tail
: Tail packet buffer to append to head pbuf
-
lwgsmr_t
lwgsm_pbuf_chain
(lwgsm_pbuf_p head, lwgsm_pbuf_p tail)¶ Chain 2 pbufs together. Similar to lwgsm_pbuf_cat but now new reference is done from head pbuf to tail pbuf.
- Note
After this function call, user must call lwgsm_pbuf_free to remove its reference to tail pbuf and allow control to head pbuf:
lwgsm_pbuf_free(tail)
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- See
- Parameters
[in] head
: Head packet buffer to append new pbuf to[in] tail
: Tail packet buffer to append to head pbuf
-
lwgsmr_t
lwgsm_pbuf_ref
(lwgsm_pbuf_p pbuf)¶ Increment reference count on pbuf.
-
uint8_t
lwgsm_pbuf_get_at
(const lwgsm_pbuf_p pbuf, size_t pos, uint8_t *el)¶ Get value from pbuf at specific position.
- Return
1
on success,0
otherwise- Parameters
[in] pbuf
: Pbuf used to get data from[in] pos
: Position at which to get element[out] el
: Output variable to save element value at desired position
-
size_t
lwgsm_pbuf_memcmp
(const lwgsm_pbuf_p pbuf, const void *data, size_t len, size_t offset)¶ Compare pbuf memory with memory from data.
- Note
Compare is done on entire pbuf chain
- Return
0
if equal,LWGSM_SIZET_MAX
if memory/offset too big or anything between if not equal- See
- Parameters
[in] pbuf
: Pbuf used to compare with data memory[in] data
: Actual data to compare with[in] len
: Length of input data in units of bytes[in] offset
: Start offset to use when comparing data
-
size_t
lwgsm_pbuf_strcmp
(const lwgsm_pbuf_p pbuf, const char *str, size_t offset)¶ Compare pbuf memory with input string.
- Note
Compare is done on entire pbuf chain
- Return
0
if equal,LWGSM_SIZET_MAX
if memory/offset too big or anything between if not equal- See
- Parameters
[in] pbuf
: Pbuf used to compare with data memory[in] str
: String to be compared with pbuf[in] offset
: Start memory offset in pbuf
-
size_t
lwgsm_pbuf_memfind
(const lwgsm_pbuf_p pbuf, const void *data, size_t len, size_t off)¶ Find desired needle in a haystack.
- Return
LWGSM_SIZET_MAX
if no match or position where in pbuf we have a match- See
- Parameters
[in] pbuf
: Pbuf used as haystack[in] needle
: Data memory used as needle[in] len
: Length of needle memory[in] off
: Starting offset in pbuf memory
-
size_t
lwgsm_pbuf_strfind
(const lwgsm_pbuf_p pbuf, const char *str, size_t off)¶ Find desired needle (str) in a haystack (pbuf)
- Return
LWGSM_SIZET_MAX
if no match or position where in pbuf we have a match- See
- Parameters
[in] pbuf
: Pbuf used as haystack[in] str
: String to search for in pbuf[in] off
: Starting offset in pbuf memory
-
uint8_t
lwgsm_pbuf_advance
(lwgsm_pbuf_p pbuf, int len)¶ Advance pbuf payload pointer by number of len bytes. It can only advance single pbuf in a chain.
- Note
When other pbufs are referencing current one, they are not adjusted in length and total length
- Return
1
on success,0
otherwise- Parameters
[in] pbuf
: Pbuf to advance[in] len
: Number of bytes to advance. when negative is used, buffer size is increased only if it was decreased before
-
lwgsm_pbuf_p
lwgsm_pbuf_skip
(lwgsm_pbuf_p pbuf, size_t offset, size_t *new_offset)¶ Skip a list of pbufs for desired offset.
- Note
Reference is not changed after return and user must not free the memory of new pbuf directly
- Return
New pbuf on success,
NULL
otherwise- Parameters
[in] pbuf
: Start of pbuf chain[in] offset
: Offset in units of bytes to skip[out] new_offset
: Pointer to output variable to save new offset in returned pbuf
-
void *
lwgsm_pbuf_get_linear_addr
(const lwgsm_pbuf_p pbuf, size_t offset, size_t *new_len)¶ Get linear offset address for pbuf from specific offset.
- Note
Since pbuf memory can be fragmented in chain, you may need to call function multiple times to get memory for entire pbuf chain
- Return
Pointer to memory on success,
NULL
otherwise- Parameters
[in] pbuf
: Pbuf to get linear address[in] offset
: Start offset from where to start[out] new_len
: Length of memory returned by function
-
void
lwgsm_pbuf_set_ip
(lwgsm_pbuf_p pbuf, const lwgsm_ip_t *ip, lwgsm_port_t port)¶ Set IP address and port number for received data.
- Parameters
[in] pbuf
: Packet buffer[in] ip
: IP to assing to packet buffer[in] port
: Port number to assign to packet buffer
-
struct
lwgsm_pbuf_t
¶ - #include <lwgsm_private.h>
Packet buffer structure.
Public Members
-
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
-
struct lwgsm_pbuf *
-
typedef struct lwgsm_pbuf *
Phonebook¶
-
group
LWGSM_PHONEBOOK
Phonebook manager.
Functions
-
lwgsmr_t
lwgsm_pb_enable
(const lwgsm_api_cmd_evt_fn evt_fn, void *const evt_arg, const uint32_t blocking)¶ Enable phonebook functionality.
-
lwgsmr_t
lwgsm_pb_disable
(const lwgsm_api_cmd_evt_fn evt_fn, void *const evt_arg, const uint32_t blocking)¶ Disable phonebook functionality.
-
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)¶ Add new phonebook entry to desired memory.
- Return
- Parameters
[in] mem
: Memory to use to save entry. Use LWGSM_MEM_CURRENT to use current memory[in] name
: Entry name[in] num
: Entry phone number[in] type
: Entry phone number type[in] evt_fn
: Callback function called when command has finished. Set toNULL
when not used[in] evt_arg
: Custom argument for event callback function[in] blocking
: Status whether command should be blocking or not
-
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)¶ Edit or overwrite phonebook entry at desired memory and position.
- Return
- Parameters
[in] mem
: Memory to use to save entry. Use LWGSM_MEM_CURRENT to use current memory[in] pos
: Entry position in memory to edit[in] name
: New entry name[in] num
: New entry phone number[in] type
: New entry phone number type[in] evt_fn
: Callback function called when command has finished. Set toNULL
when not used[in] evt_arg
: Custom argument for event callback function[in] blocking
: Status whether command should be blocking or not
-
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)¶ Delete phonebook entry at desired memory and position.
- Return
- Parameters
[in] mem
: Memory to use to save entry. Use LWGSM_MEM_CURRENT to use current memory[in] pos
: Entry position in memory to delete[in] evt_fn
: Callback function called when command has finished. Set toNULL
when not used[in] evt_arg
: Custom argument for event callback function[in] blocking
: Status whether command should be blocking or not
-
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)¶ Read single phonebook entry.
- Return
- Parameters
[in] mem
: Memory to use to save entry. Use LWGSM_MEM_CURRENT to use current memory[in] pos
: Entry position in memory to read[out] entry
: Pointer to entry variable to save data[in] evt_fn
: Callback function called when command has finished. Set toNULL
when not used[in] evt_arg
: Custom argument for event callback function[in] blocking
: Status whether command should be blocking or not
-
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)¶ List entires from specific memory.
- Return
- Parameters
[in] mem
: Memory to use to save entry. Use LWGSM_MEM_CURRENT to use current memory[in] start_index
: Start position in memory to list[out] entries
: Pointer to array to save entries[in] etr
: Number of entries to read[out] er
: Pointer to output variable to save entries listed[in] evt_fn
: Callback function called when command has finished. Set toNULL
when not used[in] evt_arg
: Custom argument for event callback function[in] blocking
: Status whether command should be blocking or not
-
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)¶ Search for entires with specific name from specific memory.
- Note
Search works by entry name only. Phone number search is not available
- Return
- Parameters
[in] mem
: Memory to use to save entry. Use LWGSM_MEM_CURRENT to use current memory[in] search
: String to search for[out] entries
: Pointer to array to save entries[in] etr
: Number of entries to read[out] er
: Pointer to output variable to save entries found[in] evt_fn
: Callback function called when command has finished. Set toNULL
when not used[in] evt_arg
: Custom argument for event callback function[in] blocking
: Status whether command should be blocking or not
-
lwgsmr_t
Ping support¶
-
group
LWGSM_PING
PING manager.
SIM card¶
-
group
LWGSM_SIM
SIM card manager.
Enums
-
enum
lwgsm_sim_state_t
¶ SIM state.
Values:
-
enumerator
LWGSM_SIM_STATE_NOT_INSERTED
¶ SIM is not inserted in socket
-
enumerator
LWGSM_SIM_STATE_READY
¶ SIM is ready for operations
-
enumerator
LWGSM_SIM_STATE_NOT_READY
¶ SIM is not ready for any operation
-
enumerator
LWGSM_SIM_STATE_PIN
¶ SIM is waiting for SIM to be given
-
enumerator
LWGSM_SIM_STATE_PUK
¶ SIM is waiting for PUT to be given
-
enumerator
LWGSM_SIM_STATE_PH_PIN
¶
-
enumerator
LWGSM_SIM_STATE_PH_PUK
¶
-
enumerator
Functions
-
lwgsm_sim_state_t
lwgsm_sim_get_current_state
(void)¶ Get current cached SIM state from stack.
- Note
Information is always valid, starting after successful device reset using lwgsm_reset function call
- Return
Member of lwgsm_sim_state_t enumeration
-
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)¶ Enter pin code to unlock SIM.
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[in] pin
: Pin code in string format[in] evt_fn
: Callback function called when command has finished. Set toNULL
when not used[in] evt_arg
: Custom argument for event callback function[in] blocking
: Status whether command should be blocking or not
-
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)¶ 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 lwgsm_sim_pin_change instead
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[in] pin
: Current SIM pin code[in] evt_fn
: Callback function called when command has finished. Set toNULL
when not used[in] evt_arg
: Custom argument for event callback function[in] blocking
: Status whether command should be blocking or not
-
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)¶ Remove pin code from SIM.
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[in] pin
: Current pin code[in] evt_fn
: Callback function called when command has finished. Set toNULL
when not used[in] evt_arg
: Custom argument for event callback function[in] blocking
: Status whether command should be blocking or not
-
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)¶ Change current pin code.
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[in] pin
: Current pin code[in] new_pin
: New pin code[in] evt_fn
: Callback function called when command has finished. Set toNULL
when not used[in] evt_arg
: Custom argument for event callback function[in] blocking
: Status whether command should be blocking or not
-
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)¶ Enter PUK code and new PIN to unlock SIM card.
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[in] puk
: PUK code associated with SIM card[in] new_pin
: New PIN code to use[in] evt_fn
: Callback function called when command has finished. Set toNULL
when not used[in] evt_arg
: Custom argument for event callback function[in] blocking
: Status whether command should be blocking or not
-
enum
SMS¶
-
group
LWGSM_SMS
SMS manager.
Enums
-
enum
lwgsm_sms_status_t
¶ SMS status in current memory.
Values:
-
enumerator
LWGSM_SMS_STATUS_ALL
¶ Process all SMS, used for mass delete or SMS list
-
enumerator
LWGSM_SMS_STATUS_READ
¶ SMS status is read
-
enumerator
LWGSM_SMS_STATUS_UNREAD
¶ SMS status is unread
-
enumerator
LWGSM_SMS_STATUS_SENT
¶ SMS status is sent
-
enumerator
LWGSM_SMS_STATUS_UNSENT
¶ SMS status is unsent
-
enumerator
LWGSM_SMS_STATUS_INBOX
¶ SMS status, used only for mass delete operation
-
enumerator
Functions
-
lwgsmr_t
lwgsm_sms_enable
(const lwgsm_api_cmd_evt_fn evt_fn, void *const evt_arg, const uint32_t blocking)¶ Enable SMS functionality.
-
lwgsmr_t
lwgsm_sms_disable
(const lwgsm_api_cmd_evt_fn evt_fn, void *const evt_arg, const uint32_t blocking)¶ Disable SMS functionality.
-
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)¶ Send SMS text to phone number.
- Return
- Parameters
[in] num
: String number[in] text
: Text to send. Maximal160
characters[in] evt_fn
: Callback function called when command has finished. Set toNULL
when not used[in] evt_arg
: Custom argument for event callback function[in] blocking
: Status whether command should be blocking or not
-
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)¶ Read SMS entry at specific memory and position.
- Return
- Parameters
[in] mem
: Memory used to read message from[in] pos
: Position number in memory to read[out] entry
: Pointer to SMS entry structure to fill data to[in] update
: Flag indicates update. Set to1
to changeUNREAD
messages toREAD
or0
to leave as is[in] evt_fn
: Callback function called when command has finished. Set toNULL
when not used[in] evt_arg
: Custom argument for event callback function[in] blocking
: Status whether command should be blocking or not
-
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)¶ Delete SMS entry at specific memory and position.
- Return
- Parameters
[in] mem
: Memory used to read message from[in] pos
: Position number in memory to read[in] evt_fn
: Callback function called when command has finished. Set toNULL
when not used[in] evt_arg
: Custom argument for event callback function[in] blocking
: Status whether command should be blocking or not
-
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)¶ Delete all SMS entries with specific status.
- Return
- Parameters
[in] status
: SMS status. This parameter can be one of all possible types in lwgsm_sms_status_t enumeration[in] evt_fn
: Callback function called when command has finished. Set toNULL
when not used[in] evt_arg
: Custom argument for event callback function[in] blocking
: Status whether command should be blocking or not
-
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)¶ List SMS from SMS memory.
- Return
- Parameters
[in] mem
: Memory to read entries from. Use LWGSM_MEM_CURRENT to read from current memory[in] stat
: SMS status to read, eitherread
,unread
,sent
,unsent
orall
[out] entries
: Pointer to array to save SMS entries[in] etr
: Number of entries to read[out] er
: Pointer to output variable to save number of entries in array[in] update
: Flag indicates update. Set to1
to changeUNREAD
messages toREAD
or0
to leave as is[in] evt_fn
: Callback function called when command has finished. Set toNULL
when not used[in] evt_arg
: Custom argument for event callback function[in] blocking
: Status whether command should be blocking or not
-
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)¶ Set preferred storage for SMS.
- Return
- Parameters
[in] mem1
: Preferred memory for read/delete SMS operations. Use LWGSM_MEM_CURRENT to keep it as is[in] mem2
: Preferred memory for sent/write SMS operations. Use LWGSM_MEM_CURRENT to keep it as is[in] mem3
: Preferred memory for received SMS entries. Use LWGSM_MEM_CURRENT to keep it as is[in] evt_fn
: Callback function called when command has finished. Set toNULL
when not used[in] evt_arg
: Custom argument for event callback function[in] blocking
: Status whether command should be blocking or not
-
struct
lwgsm_sms_mem_t
¶ - #include <lwgsm_private.h>
SMS memory information.
Public Members
-
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
-
uint32_t
-
struct
lwgsm_sms_t
¶ - #include <lwgsm_private.h>
SMS structure.
Public Members
-
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
-
uint8_t
-
struct
lwgsm_pb_mem_t
¶ - #include <lwgsm_private.h>
SMS memory information.
Public Members
-
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
-
uint32_t
-
struct
lwgsm_sms_entry_t
¶ - #include <lwgsm_typedefs.h>
SMS entry structure.
Public Members
-
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_mem_t
-
enum
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.
-
group
LWGSM_TIMEOUT
Timeout manager.
Typedefs
-
typedef void (*
lwgsm_timeout_fn
)(void *arg)¶ Timeout callback function prototype.
- Parameters
[in] arg
: Custom user argument
Functions
-
lwgsmr_t
lwgsm_timeout_add
(uint32_t time, lwgsm_timeout_fn fn, void *arg)¶ Add new timeout to processing list.
-
lwgsmr_t
lwgsm_timeout_remove
(lwgsm_timeout_fn fn)¶ Remove callback from timeout list.
-
typedef void (*
Structures and enumerations¶
-
group
LWGSM_TYPEDEFS
List of core structures and enumerations.
Typedefs
-
typedef uint16_t
lwgsm_port_t
¶ Port variable.
Enums
-
enum
lwgsm_cmd_t
¶ List of possible messages.
Values:
-
enumerator
LWGSM_CMD_IDLE
¶ IDLE mode
-
enumerator
LWGSM_CMD_RESET
¶ Reset device
-
enumerator
LWGSM_CMD_RESET_DEVICE_FIRST_CMD
¶ Reset device first driver specific command
-
enumerator
LWGSM_CMD_ATE0
¶ Disable ECHO mode on AT commands
-
enumerator
LWGSM_CMD_ATE1
¶ Enable ECHO mode on AT commands
-
enumerator
LWGSM_CMD_GSLP
¶ Set GSM to sleep mode
-
enumerator
LWGSM_CMD_RESTORE
¶ Restore GSM internal settings to default values
-
enumerator
LWGSM_CMD_UART
¶
-
enumerator
LWGSM_CMD_CGACT_SET_0
¶
-
enumerator
LWGSM_CMD_CGACT_SET_1
¶
-
enumerator
LWGSM_CMD_CGATT_SET_0
¶
-
enumerator
LWGSM_CMD_CGATT_SET_1
¶
-
enumerator
LWGSM_CMD_NETWORK_ATTACH
¶ Attach to a network
-
enumerator
LWGSM_CMD_NETWORK_DETACH
¶ Detach from network
-
enumerator
LWGSM_CMD_CIPMUX_SET
¶
-
enumerator
LWGSM_CMD_CIPRXGET_SET
¶
-
enumerator
LWGSM_CMD_CSTT_SET
¶
-
enumerator
LWGSM_CMD_CALL_ENABLE
¶
-
enumerator
LWGSM_CMD_A
¶ Re-issues the Last Command Given
-
enumerator
LWGSM_CMD_ATA
¶ Answer an Incoming Call
-
enumerator
LWGSM_CMD_ATD
¶ Mobile Originated Call to Dial A Number
-
enumerator
LWGSM_CMD_ATD_N
¶ Originate Call to Phone Number in Current Memory: ATD<n>
-
enumerator
LWGSM_CMD_ATD_STR
¶ Originate Call to Phone Number in Memory Which Corresponds to Field “str”: ATD>str
-
enumerator
LWGSM_CMD_ATDL
¶ Redial Last Telephone Number Used
-
enumerator
LWGSM_CMD_ATE
¶ Set Command Echo Mode
-
enumerator
LWGSM_CMD_ATH
¶ Disconnect Existing
-
enumerator
LWGSM_CMD_ATI
¶ Display Product Identification Information
-
enumerator
LWGSM_CMD_ATL
¶ Set Monitor speaker
-
enumerator
LWGSM_CMD_ATM
¶ Set Monitor Speaker Mode
-
enumerator
LWGSM_CMD_PPP
¶ Switch from Data Mode or PPP Online Mode to Command Mode, “+++” originally
-
enumerator
LWGSM_CMD_ATO
¶ Switch from Command Mode to Data Mode
-
enumerator
LWGSM_CMD_ATP
¶ Select Pulse Dialing
-
enumerator
LWGSM_CMD_ATQ
¶ Set Result Code Presentation Mode
-
enumerator
LWGSM_CMD_ATS0
¶ Set Number of Rings before Automatically Answering the Call
-
enumerator
LWGSM_CMD_ATS3
¶ Set Command Line Termination Character
-
enumerator
LWGSM_CMD_ATS4
¶ Set Response Formatting Character
-
enumerator
LWGSM_CMD_ATS5
¶ Set Command Line Editing Character
-
enumerator
LWGSM_CMD_ATS6
¶ Pause Before Blind
-
enumerator
LWGSM_CMD_ATS7
¶ Set Number of Seconds to Wait for Connection Completion
-
enumerator
LWGSM_CMD_ATS8
¶ Set Number of Seconds to Wait for Comma Dial Modifier Encountered in Dial String of D Command
-
enumerator
LWGSM_CMD_ATS10
¶ Set Disconnect Delay after Indicating the Absence of Data Carrier
-
enumerator
LWGSM_CMD_ATT
¶ Select Tone Dialing
-
enumerator
LWGSM_CMD_ATV
¶ TA Response Format
-
enumerator
LWGSM_CMD_ATX
¶ Set CONNECT Result Code Format and Monitor Call Progress
-
enumerator
LWGSM_CMD_ATZ
¶ Reset Default Configuration
-
enumerator
LWGSM_CMD_AT_C
¶ Set DCD Function Mode, AT&C
-
enumerator
LWGSM_CMD_AT_D
¶ Set DTR Function, AT&D
-
enumerator
LWGSM_CMD_AT_F
¶ Factory Defined Configuration, AT&F
-
enumerator
LWGSM_CMD_AT_V
¶ Display Current Configuration, AT&V
-
enumerator
LWGSM_CMD_AT_W
¶ Store Active Profile, AT&W
-
enumerator
LWGSM_CMD_GCAP
¶ Request Complete TA Capabilities List
-
enumerator
LWGSM_CMD_GMI
¶ Request Manufacturer Identification
-
enumerator
LWGSM_CMD_GMM
¶ Request TA Model Identification
-
enumerator
LWGSM_CMD_GMR
¶ Request TA Revision Identification of Software Release
-
enumerator
LWGSM_CMD_GOI
¶ Request Global Object Identification
-
enumerator
LWGSM_CMD_GSN
¶ Request TA Serial Number Identification (IMEI)
-
enumerator
LWGSM_CMD_ICF
¶ Set TE-TA Control Character Framing
-
enumerator
LWGSM_CMD_IFC
¶ Set TE-TA Local Data Flow Control
-
enumerator
LWGSM_CMD_IPR
¶ Set TE-TA Fixed Local Rate
-
enumerator
LWGSM_CMD_HVOIC
¶ Disconnect Voice Call Only
-
enumerator
LWGSM_CMD_COPS_SET
¶ Set operator
-
enumerator
LWGSM_CMD_COPS_GET
¶ Get current operator
-
enumerator
LWGSM_CMD_COPS_GET_OPT
¶ Get a list of available operators
-
enumerator
LWGSM_CMD_CPAS
¶ Phone Activity Status
-
enumerator
LWGSM_CMD_CGMI_GET
¶ Request Manufacturer Identification
-
enumerator
LWGSM_CMD_CGMM_GET
¶ Request Model Identification
-
enumerator
LWGSM_CMD_CGMR_GET
¶ Request TA Revision Identification of Software Release
-
enumerator
LWGSM_CMD_CGSN_GET
¶ Request Product Serial Number Identification (Identical with +GSN)
-
enumerator
LWGSM_CMD_CLCC_SET
¶ List Current Calls of ME
-
enumerator
LWGSM_CMD_CLCK
¶ Facility Lock
-
enumerator
LWGSM_CMD_CACM
¶ Accumulated Call Meter (ACM) Reset or Query
-
enumerator
LWGSM_CMD_CAMM
¶ Accumulated Call Meter Maximum (ACM max) Set or Query
-
enumerator
LWGSM_CMD_CAOC
¶ Advice of Charge
-
enumerator
LWGSM_CMD_CBST
¶ Select Bearer Service Type
-
enumerator
LWGSM_CMD_CCFC
¶ Call Forwarding Number and Conditions Control
-
enumerator
LWGSM_CMD_CCWA
¶ Call Waiting Control
-
enumerator
LWGSM_CMD_CEER
¶ Extended Error Report
-
enumerator
LWGSM_CMD_CSCS
¶ Select TE Character Set
-
enumerator
LWGSM_CMD_CSTA
¶ Select Type of Address
-
enumerator
LWGSM_CMD_CHLD
¶ Call Hold and Multiparty
-
enumerator
LWGSM_CMD_CIMI
¶ Request International Mobile Subscriber Identity
-
enumerator
LWGSM_CMD_CLIP
¶ Calling Line Identification Presentation
-
enumerator
LWGSM_CMD_CLIR
¶ Calling Line Identification Restriction
-
enumerator
LWGSM_CMD_CMEE_SET
¶ Report Mobile Equipment Error
-
enumerator
LWGSM_CMD_COLP
¶ Connected Line Identification Presentation
-
enumerator
LWGSM_CMD_PHONEBOOK_ENABLE
¶
-
enumerator
LWGSM_CMD_CPBF
¶ Find Phonebook Entries
-
enumerator
LWGSM_CMD_CPBR
¶ Read Current Phonebook Entries
-
enumerator
LWGSM_CMD_CPBS_SET
¶ Select Phonebook Memory Storage
-
enumerator
LWGSM_CMD_CPBS_GET
¶ Get current Phonebook Memory Storage
-
enumerator
LWGSM_CMD_CPBS_GET_OPT
¶ Get available Phonebook Memory Storages
-
enumerator
LWGSM_CMD_CPBW_SET
¶ Write Phonebook Entry
-
enumerator
LWGSM_CMD_CPBW_GET_OPT
¶ Get options for write Phonebook Entry
-
enumerator
LWGSM_CMD_SIM_PROCESS_BASIC_CMDS
¶ Command setup, executed when SIM is in READY state
-
enumerator
LWGSM_CMD_CPIN_SET
¶ Enter PIN
-
enumerator
LWGSM_CMD_CPIN_GET
¶ Read current SIM status
-
enumerator
LWGSM_CMD_CPIN_ADD
¶ Add new PIN to SIM if pin is not set
-
enumerator
LWGSM_CMD_CPIN_CHANGE
¶ Change already active SIM
-
enumerator
LWGSM_CMD_CPIN_REMOVE
¶ Remove current PIN
-
enumerator
LWGSM_CMD_CPUK_SET
¶ Enter PUK and set new PIN
-
enumerator
LWGSM_CMD_CSQ_GET
¶ Signal Quality Report
-
enumerator
LWGSM_CMD_CFUN_SET
¶ Set Phone Functionality
-
enumerator
LWGSM_CMD_CFUN_GET
¶ Get Phone Functionality
-
enumerator
LWGSM_CMD_CREG_SET
¶ Network Registration set output
-
enumerator
LWGSM_CMD_CREG_GET
¶ Get current network registration status
-
enumerator
LWGSM_CMD_CBC
¶ Battery Charge
-
enumerator
LWGSM_CMD_CNUM
¶ Subscriber Number
-
enumerator
LWGSM_CMD_CPWD
¶ Change Password
-
enumerator
LWGSM_CMD_CR
¶ Service Reporting Control
-
enumerator
LWGSM_CMD_CRC
¶ Set Cellular Result Codes for Incoming Call Indication
-
enumerator
LWGSM_CMD_CRLP
¶ Select Radio Link Protocol Parameters
-
enumerator
LWGSM_CMD_CRSM
¶ Restricted SIM Access
-
enumerator
LWGSM_CMD_VTD
¶ Tone Duration
-
enumerator
LWGSM_CMD_VTS
¶ DTMF and Tone Generation
-
enumerator
LWGSM_CMD_CMUX
¶ Multiplexer Control
-
enumerator
LWGSM_CMD_CPOL
¶ Preferred Operator List
-
enumerator
LWGSM_CMD_COPN
¶ Read Operator Names
-
enumerator
LWGSM_CMD_CCLK
¶ Clock
-
enumerator
LWGSM_CMD_CSIM
¶ Generic SIM Access
-
enumerator
LWGSM_CMD_CALM
¶ Alert Sound Mode
-
enumerator
LWGSM_CMD_CALS
¶ Alert Sound Select
-
enumerator
LWGSM_CMD_CRSL
¶ Ringer Sound Level
-
enumerator
LWGSM_CMD_CLVL
¶ Loud Speaker Volume Level
-
enumerator
LWGSM_CMD_CMUT
¶ Mute Control
-
enumerator
LWGSM_CMD_CPUC
¶ Price Per Unit and Currency Table
-
enumerator
LWGSM_CMD_CCWE
¶ Call Meter Maximum Event
-
enumerator
LWGSM_CMD_CUSD_SET
¶ Unstructured Supplementary Service Data, Set command
-
enumerator
LWGSM_CMD_CUSD_GET
¶ Unstructured Supplementary Service Data, Get command
-
enumerator
LWGSM_CMD_CUSD
¶ Unstructured Supplementary Service Data, Execute command
-
enumerator
LWGSM_CMD_CSSN
¶ Supplementary Services Notification
-
enumerator
LWGSM_CMD_CIPMUX
¶ Start Up Multi-IP Connection
-
enumerator
LWGSM_CMD_CIPSTART
¶ Start Up TCP or UDP Connection
-
enumerator
LWGSM_CMD_CIPSEND
¶ Send Data Through TCP or UDP Connection
-
enumerator
LWGSM_CMD_CIPQSEND
¶ Select Data Transmitting Mode
-
enumerator
LWGSM_CMD_CIPACK
¶ Query Previous Connection Data Transmitting State
-
enumerator
LWGSM_CMD_CIPCLOSE
¶ Close TCP or UDP Connection
-
enumerator
LWGSM_CMD_CIPSHUT
¶ Deactivate GPRS PDP Context
-
enumerator
LWGSM_CMD_CLPORT
¶ Set Local Port
-
enumerator
LWGSM_CMD_CSTT
¶ Start Task and Set APN, username, password
-
enumerator
LWGSM_CMD_CIICR
¶ Bring Up Wireless Connection with GPRS or CSD
-
enumerator
LWGSM_CMD_CIFSR
¶ Get Local IP Address
-
enumerator
LWGSM_CMD_CIPSTATUS
¶ Query Current Connection Status
-
enumerator
LWGSM_CMD_CDNSCFG
¶ Configure Domain Name Server
-
enumerator
LWGSM_CMD_CDNSGIP
¶ Query the IP Address of Given Domain Name
-
enumerator
LWGSM_CMD_CIPHEAD
¶ Add an IP Head at the Beginning of a Package Received
-
enumerator
LWGSM_CMD_CIPATS
¶ Set Auto Sending Timer
-
enumerator
LWGSM_CMD_CIPSPRT
¶ Set Prompt of greater than sign When Module Sends Data
-
enumerator
LWGSM_CMD_CIPSERVER
¶ Configure Module as Server
-
enumerator
LWGSM_CMD_CIPCSGP
¶ Set CSD or GPRS for Connection Mode
-
enumerator
LWGSM_CMD_CIPSRIP
¶ Show Remote IP Address and Port When Received Data
-
enumerator
LWGSM_CMD_CIPDPDP
¶ Set Whether to Check State of GPRS Network Timing
-
enumerator
LWGSM_CMD_CIPMODE
¶ Select TCPIP Application Mode
-
enumerator
LWGSM_CMD_CIPCCFG
¶ Configure Transparent Transfer Mode
-
enumerator
LWGSM_CMD_CIPSHOWTP
¶ Display Transfer Protocol in IP Head When Received Data
-
enumerator
LWGSM_CMD_CIPUDPMODE
¶ UDP Extended Mode
-
enumerator
LWGSM_CMD_CIPRXGET
¶ Get Data from Network Manually
-
enumerator
LWGSM_CMD_CIPSCONT
¶ Save TCPIP Application Context
-
enumerator
LWGSM_CMD_CIPRDTIMER
¶ Set Remote Delay Timer
-
enumerator
LWGSM_CMD_CIPSGTXT
¶ Select GPRS PDP context
-
enumerator
LWGSM_CMD_CIPTKA
¶ Set TCP Keepalive Parameters
-
enumerator
LWGSM_CMD_CIPSSL
¶ Connection SSL function
-
enumerator
LWGSM_CMD_SMS_ENABLE
¶
-
enumerator
LWGSM_CMD_CMGD
¶ Delete SMS Message
-
enumerator
LWGSM_CMD_CMGF
¶ Select SMS Message Format
-
enumerator
LWGSM_CMD_CMGL
¶ List SMS Messages from Preferred Store
-
enumerator
LWGSM_CMD_CMGR
¶ Read SMS Message
-
enumerator
LWGSM_CMD_CMGS
¶ Send SMS Message
-
enumerator
LWGSM_CMD_CMGW
¶ Write SMS Message to Memory
-
enumerator
LWGSM_CMD_CMSS
¶ Send SMS Message from Storage
-
enumerator
LWGSM_CMD_CMGDA
¶ MASS SMS delete
-
enumerator
LWGSM_CMD_CNMI
¶ New SMS Message Indications
-
enumerator
LWGSM_CMD_CPMS_SET
¶ Set preferred SMS Message Storage
-
enumerator
LWGSM_CMD_CPMS_GET
¶ Get preferred SMS Message Storage
-
enumerator
LWGSM_CMD_CPMS_GET_OPT
¶ Get optional SMS message storages
-
enumerator
LWGSM_CMD_CRES
¶ Restore SMS Settings
-
enumerator
LWGSM_CMD_CSAS
¶ Save SMS Settings
-
enumerator
LWGSM_CMD_CSCA
¶ SMS Service Center Address
-
enumerator
LWGSM_CMD_CSCB
¶ Select Cell Broadcast SMS Messages
-
enumerator
LWGSM_CMD_CSDH
¶ Show SMS Text Mode Parameters
-
enumerator
LWGSM_CMD_CSMP
¶ Set SMS Text Mode Parameters
-
enumerator
LWGSM_CMD_CSMS
¶ Select Message Service
-
enumerator
LWGSM_CMD_END
¶ Last CMD entry
-
enumerator
-
enum
lwgsm_conn_connect_res_t
¶ Connection result on connect command.
Values:
-
enumerator
LWGSM_CONN_CONNECT_UNKNOWN
¶ No valid result
-
enumerator
LWGSM_CONN_CONNECT_OK
¶ Connected OK
-
enumerator
LWGSM_CONN_CONNECT_ERROR
¶ Error on connection
-
enumerator
LWGSM_CONN_CONNECT_ALREADY
¶ Already connected
-
enumerator
-
enum
lwgsmr_t
¶ Result enumeration used across application functions.
Values:
-
enumerator
lwgsmOK
¶ Function returned OK
-
enumerator
lwgsmOKIGNOREMORE
¶ Function succedded, should continue as lwgsmOK but ignore sending more data. This result is possible on connection data receive callback
-
enumerator
lwgsmERR
¶ Generic error
-
enumerator
lwgsmPARERR
¶ Wrong parameters on function call
-
enumerator
lwgsmERRMEM
¶ Memory error occurred
-
enumerator
lwgsmTIMEOUT
¶ Timeout occurred on command
-
enumerator
lwgsmCONT
¶ There is still some command to be processed in current command
-
enumerator
lwgsmCLOSED
¶ Connection just closed
-
enumerator
lwgsmINPROG
¶ Operation is in progress
-
enumerator
lwgsmERRNOTENABLED
¶ Feature not enabled error
-
enumerator
lwgsmERRNOIP
¶ Station does not have IP address
-
enumerator
lwgsmERRNOFREECONN
¶ There is no free connection available to start
-
enumerator
lwgsmERRCONNTIMEOUT
¶ Timeout received when connection to access point
-
enumerator
lwgsmERRPASS
¶ Invalid password for access point
-
enumerator
lwgsmERRNOAP
¶ No access point found with specific SSID and MAC address
-
enumerator
lwgsmERRCONNFAIL
¶ Connection failed to access point
-
enumerator
lwgsmERRWIFINOTCONNECTED
¶ Wifi not connected to access point
-
enumerator
lwgsmERRNODEVICE
¶ Device is not present
-
enumerator
lwgsmERRBLOCKING
¶ Blocking mode command is not allowed
-
enumerator
-
enum
lwgsm_device_model_t
¶ GSM device model type.
Values:
-
enumerator
LWGSM_DEVICE_MODEL_END
¶ End of device model
-
enumerator
LWGSM_DEVICE_MODEL_UNKNOWN
¶ Unknown device model
-
enumerator
-
struct
lwgsm_conn_t
¶ - #include <lwgsm_private.h>
Connection structure.
Public Members
-
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
-
uint8_t
active
¶ Status whether connection is active
-
uint8_t
client
¶ Status whether connection is in client mode
-
uint8_t
data_received
¶ Status whether first data were received on connection
-
uint8_t
in_closing
¶ Status if connection is in closing mode. When in closing mode, ignore any possible received data from function
-
uint8_t
bearer
¶ Bearer used. Can be
1
or0
-
struct lwgsm_conn_t::[anonymous]::[anonymous]
f
¶ Connection flags
-
union lwgsm_conn_t::[anonymous]
status
¶ Connection status union with flag bits
-
lwgsm_conn_type_t
-
struct
lwgsm_pbuf_t
- #include <lwgsm_private.h>
Packet buffer structure.
Public Members
-
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
-
struct lwgsm_pbuf *
-
struct
lwgsm_ipd_t
¶ - #include <lwgsm_private.h>
Incoming network data read structure.
Public Members
-
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
whileread = 1
, reading should ignore incoming data
-
lwgsm_pbuf_p
buff
¶ Pointer to data buffer used for receiving data
-
uint8_t
-
struct
lwgsm_msg_t
¶ - #include <lwgsm_private.h>
Message queue structure to share between threads.
Public Members
-
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
-
uint32_t
delay
¶ Delay to use before sending first reset AT command
-
struct lwgsm_msg_t::[anonymous]::[anonymous]
reset
¶ Reset device
-
uint32_t
baudrate
¶ Baudrate for AT port
-
struct lwgsm_msg_t::[anonymous]::[anonymous]
uart
¶ UART configuration
-
uint8_t
mode
¶ Functionality mode
-
struct lwgsm_msg_t::[anonymous]::[anonymous]
cfun
¶ Set phone functionality
-
const char *
pin
¶ Pin code to write
New pin code
Current pin code
New PIN code
-
struct lwgsm_msg_t::[anonymous]::[anonymous]
cpin_enter
¶ Enter pin code
-
struct lwgsm_msg_t::[anonymous]::[anonymous]
cpin_add
¶ Add pin code if previously wasn’t set
-
const char *
current_pin
¶ Current pin code
-
const char *
new_pin
¶ New pin code
-
struct lwgsm_msg_t::[anonymous]::[anonymous]
cpin_change
¶ Change current pin code
-
struct lwgsm_msg_t::[anonymous]::[anonymous]
cpin_remove
¶ Remove PIN code
-
const char *
puk
¶ PUK code
-
struct lwgsm_msg_t::[anonymous]::[anonymous]
cpuk_enter
¶ Enter PUK and new PIN
-
size_t
cnum_tries
¶ Number of tries
-
struct lwgsm_msg_t::[anonymous]::[anonymous]
sim_info
¶ Get information for SIM card
-
char *
str
¶ Pointer to output string array
-
size_t
len
¶ Length of output string array including trailing zero memory
-
struct lwgsm_msg_t::[anonymous]::[anonymous]
device_info
¶ All kind of device info, serial number, model, manufacturer, revision
-
int16_t *
rssi
¶ Pointer to RSSI variable
-
struct lwgsm_msg_t::[anonymous]::[anonymous]
csq
¶ Signal strength
-
uint8_t
read
¶ Flag indicating we can read the COPS actual data
Read the data flag
-
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
-
struct lwgsm_msg_t::[anonymous]::[anonymous]
cops_scan
¶ Scan operators
-
lwgsm_operator_curr_t *
curr
¶ Pointer to output current operator
-
struct lwgsm_msg_t::[anonymous]::[anonymous]
cops_get
¶ Get current operator info
-
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
Entry name
-
uint32_t
num
¶ Number in case format is number
-
struct lwgsm_msg_t::[anonymous]::[anonymous]
cops_set
¶ Set operator settings
-
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
-
struct lwgsm_msg_t::[anonymous]::[anonymous]
conn_start
¶ Structure for starting new connection
-
lwgsm_conn_t *
conn
Pointer to connection to close
Pointer to connection to send data
-
uint8_t
val_id
¶ Connection current validation ID when command was sent to queue
-
struct lwgsm_msg_t::[anonymous]::[anonymous]
conn_close
¶ Close connection
-
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
-
struct lwgsm_msg_t::[anonymous]::[anonymous]
conn_send
¶ Structure to send data on connection
-
const char *
num
Phone number
Entry 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 position in memory
Memory position. Set to 0 to use new one or SIZE_T MAX to delete entry
-
struct lwgsm_msg_t::[anonymous]::[anonymous]
sms_send
¶ Send SMS
-
lwgsm_mem_t
mem
¶ Memory to read from
Memory to delete from
Memory to use for read
Array of memories
Memory to use
-
lwgsm_sms_entry_t *
entry
¶ Pointer to entry to write info
-
uint8_t
update
¶ Update SMS status after read operation
-
struct lwgsm_msg_t::[anonymous]::[anonymous]
sms_read
¶ Read single SMS
-
struct lwgsm_msg_t::[anonymous]::[anonymous]
sms_delete
¶ Delete SMS message
-
lwgsm_sms_status_t
status
¶ SMS status to delete
SMS entries status
-
struct lwgsm_msg_t::[anonymous]::[anonymous]
sms_delete_all
¶ Mass delete SMS messages
-
lwgsm_sms_entry_t *
entries
¶ Pointer to entries
-
size_t
etr
¶ Entries to read (array length)
NUmber of entries to read
-
size_t
ei
¶ Current entry index in array
Current entry index
-
size_t *
er
¶ Final entries read pointer for user
-
struct lwgsm_msg_t::[anonymous]::[anonymous]
sms_list
¶ List SMS messages
-
struct lwgsm_msg_t::[anonymous]::[anonymous]
sms_memory
¶ Set preferred memories
-
const char *
number
¶ Phone number to dial
-
struct lwgsm_msg_t::[anonymous]::[anonymous]
call_start
¶ Start a new call
-
lwgsm_number_type_t
type
Entry phone number type
-
uint8_t
del
¶ Flag indicates delete
-
struct lwgsm_msg_t::[anonymous]::[anonymous]
pb_write
¶ Write/Edit/Delete entry
-
size_t
start_index
¶ Start index in phonebook to read
-
lwgsm_pb_entry_t *
entries
Pointer to entries array
-
struct lwgsm_msg_t::[anonymous]::[anonymous]
pb_list
¶ List phonebook entries
-
const char *
search
¶ Search string
-
struct lwgsm_msg_t::[anonymous]::[anonymous]
pb_search
¶ Search phonebook entries
-
const char *
code
¶ Code to send
-
char *
resp
¶ Response array
-
size_t
resp_len
¶ Length of response array
-
size_t
resp_write_ptr
¶ Write pointer for response
-
uint8_t
quote_det
¶ Information if quote has been detected
-
struct lwgsm_msg_t::[anonymous]::[anonymous]
ussd
¶ Execute USSD command
-
const char *
apn
¶ APN address
-
const char *
user
¶ APN username
-
const char *
pass
¶ APN password
-
struct lwgsm_msg_t::[anonymous]::[anonymous]
network_attach
¶ Settings for network attach
-
union lwgsm_msg_t::[anonymous]
msg
¶ Group of different possible message contents
-
lwgsm_cmd_t
-
struct
lwgsm_ip_mac_t
¶ - #include <lwgsm_private.h>
IP and MAC structure with netmask and gateway addresses.
Public Members
-
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_t
-
struct
lwgsm_link_conn_t
¶ - #include <lwgsm_private.h>
Link connection active info.
Public Members
-
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
-
uint8_t
-
struct
lwgsm_evt_func_t
¶ - #include <lwgsm_private.h>
Callback function linked list prototype.
Public Members
-
struct lwgsm_evt_func *
next
¶ Next function in the list
-
lwgsm_evt_fn
fn
¶ Function pointer itself
-
struct lwgsm_evt_func *
-
struct
lwgsm_sms_mem_t
- #include <lwgsm_private.h>
SMS memory information.
Public Members
-
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
-
uint32_t
-
struct
lwgsm_sms_t
- #include <lwgsm_private.h>
SMS structure.
Public Members
-
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
-
uint8_t
-
struct
lwgsm_pb_mem_t
- #include <lwgsm_private.h>
SMS memory information.
Public Members
-
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
-
uint32_t
-
struct
lwgsm_pb_t
¶ - #include <lwgsm_private.h>
Phonebook structure.
Public Members
-
uint8_t
ready
¶ Flag indicating feature ready by device
-
uint8_t
enabled
¶ Flag indicating feature enabled
-
lwgsm_pb_mem_t
mem
¶ Memory information
-
uint8_t
-
struct
lwgsm_sim_t
¶ - #include <lwgsm_private.h>
SIM structure.
Public Members
-
lwgsm_sim_state_t
state
¶ Current SIM status
-
lwgsm_sim_state_t
-
struct
lwgsm_network_t
¶ - #include <lwgsm_private.h>
Network info.
Public Members
-
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_reg_status_t
-
struct
lwgsm_modules_t
¶ - #include <lwgsm_private.h>
GSM modules structure.
Public Members
-
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
-
lwgsm_sim_t
sim
¶ SIM data
-
lwgsm_network_t
network
¶ Network status
-
int16_t
rssi
¶ RSSI signal strength.
0
= invalid,-53 % -113
= valid
-
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
-
lwgsm_sms_t
sms
¶ SMS information
-
lwgsm_pb_t
pb
¶ Phonebook information
-
lwgsm_call_t
call
¶ Call information
-
char
-
struct
lwgsm_t
¶ - #include <lwgsm_private.h>
GSM global structure.
Public Members
-
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
-
lwgsm_buff_t
buff
¶ Input processing buffer
-
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
-
uint8_t
initialized
¶ Flag indicating GSM library is initialized
-
uint8_t
dev_present
¶ Flag indicating GSM device is present
-
size_t
-
struct
lwgsm_dev_mem_map_t
¶ - #include <lwgsm_private.h>
Memory mapping structure between string and value in app.
-
struct
lwgsm_dev_model_map_t
¶ - #include <lwgsm_private.h>
Device models map between model and other information.
Public Members
-
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_device_model_t
-
struct
lwgsm_unicode_t
¶ - #include <lwgsm_private.h>
Unicode support structure.
-
struct
lwgsm_ip_t
¶ - #include <lwgsm_typedefs.h>
IP structure.
Public Members
-
uint8_t
ip
[4]¶ IPv4 address
-
uint8_t
-
struct
lwgsm_mac_t
¶ - #include <lwgsm_typedefs.h>
MAC address.
Public Members
-
uint8_t
mac
[6]¶ MAC address
-
uint8_t
-
struct
lwgsm_datetime_t
¶ - #include <lwgsm_typedefs.h>
Date and time structure.
Public Members
-
uint8_t
date
¶ Day in a month, from
1
to up to31
-
uint8_t
month
¶ Month in a year, from
1
to12
-
uint16_t
year
¶ Year
-
uint8_t
day
¶ Day in a week, from
1
to7
, 0 = invalid
-
uint8_t
hours
¶ Hours in a day, from
0
to23
-
uint8_t
minutes
¶ Minutes in a hour, from
0
to59
-
uint8_t
seconds
¶ Seconds in a minute, from
0
to59
-
uint8_t
-
struct
lwgsm_linbuff_t
¶ - #include <lwgsm_typedefs.h>
Linear buffer structure.
-
typedef uint16_t
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.
-
group
LWGSM_UNICODE
Unicode support manager.
Functions
-
lwgsmr_t
lwgsmi_unicode_decode
(lwgsm_unicode_t *uni, uint8_t ch)¶ Decode single character for unicode (UTF-8 only) format.
- Parameters
[inout] s
: Pointer to unicode decode control structure[in] c
: UTF-8 character sequence to test for device
- Return Value
lwgsmOK
: Function succedded, there is a valid UTF-8 sequencelwgsmINPROG
: Function continues well but expects some more data to finish sequencelwgsmERR
: Error in UTF-8 sequence
-
struct
lwgsm_unicode_t
- #include <lwgsm_private.h>
Unicode support structure.
Public Members
-
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
-
uint8_t
-
lwgsmr_t
Unstructured Supplementary Service Data¶
-
group
LWGSM_USSD
Unstructured Supplementary Service Data.
Functions
-
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)¶ Run USSD command, such as
*123#
to get balance on SIM card.- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[in] code
: Code to run, such as*123#
[out] resp
: Pointer to array to save response[in] resp_len
: Length of array, including stringNULL
termination[in] evt_fn
: Callback function called when command has finished. Set toNULL
when not used[in] evt_arg
: Custom argument for event callback function[in] blocking
: Status whether command should be blocking or not
-
lwgsmr_t
Utilities¶
Utility functions for various cases. These function are used across entire middleware and can also be used by application.
-
group
LWGSM_UTILS
Utilities.
Defines
-
LWGSM_ASSERT
(msg, c)¶ 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 lwgsmr_t enumeration
- Parameters
[in] msg
: message to print to debug if test fails[in] c
: Condition to test
-
LWGSM_MEM_ALIGN
(x)¶ Align
x
value to specific number of bytes, provided by LWGSM_CFG_MEM_ALIGNMENT configuration.- Return
Input value aligned to specific number of bytes
- Parameters
[in] x
: Input value to align
-
LWGSM_MIN
(x, y)¶ Get minimal value between
x
andy
inputs.- Return
Minimal value between
x
andy
parameters- Parameters
[in] x
: First input to test[in] y
: Second input to test
-
LWGSM_MAX
(x, y)¶ Get maximal value between
x
andy
inputs.- Return
Maximal value between
x
andy
parameters- Parameters
[in] x
: First input to test[in] y
: Second input to test
-
LWGSM_ARRAYSIZE
(x)¶ Get size of statically declared array.
- Return
Number of array elements
- Parameters
[in] x
: Input array
-
LWGSM_UNUSED
(x)¶ Unused argument in a function call.
- Note
Use this on all parameters in a function which are not used to prevent compiler warnings complaining about “unused variables”
- Parameters
[in] x
: Variable which is not used
-
LWGSM_U32
(x)¶ Get input value casted to
unsigned 32-bit
value.- Parameters
[in] x
: Input value
-
LWGSM_U16
(x)¶ Get input value casted to
unsigned 16-bit
value.- Parameters
[in] x
: Input value
-
LWGSM_U8
(x)¶ Get input value casted to
unsigned 8-bit
value.- Parameters
[in] x
: Input value
-
LWGSM_I32
(x)¶ Get input value casted to
signed 32-bit
value.- Parameters
[in] x
: Input value
-
LWGSM_I16
(x)¶ Get input value casted to
signed 16-bit
value.- Parameters
[in] x
: Input value
-
LWGSM_I8
(x)¶ Get input value casted to
signed 8-bit
value.- Parameters
[in] x
: Input value
-
LWGSM_SZ
(x)¶ Get input value casted to
size_t
value.- Parameters
[in] x
: Input value
-
lwgsm_u32_to_str
(num, out)¶ Convert
unsigned 32-bit
number to string.- Return
Pointer to output variable
- Parameters
[in] num
: Number to convert[out] out
: Output variable to save string
-
lwgsm_u32_to_hex_str
(num, out, w)¶ Convert
unsigned 32-bit
number to HEX string.- Return
Pointer to output variable
- Parameters
[in] num
: Number to convert[out] out
: Output variable to save string[in] w
: Width of output string. When number is shorter than width, leading0
characters will apply.
-
lwgsm_i32_to_str
(num, out)¶ Convert
signed 32-bit
number to string.- Return
Pointer to output variable
- Parameters
[in] num
: Number to convert[out] out
: Output variable to save string
-
lwgsm_u16_to_str
(num, out)¶ Convert
unsigned 16-bit
number to string.- Return
Pointer to output variable
- Parameters
[in] num
: Number to convert[out] out
: Output variable to save string
-
lwgsm_u16_to_hex_str
(num, out, w)¶ Convert
unsigned 16-bit
number to HEX string.- Return
Pointer to output variable
- Parameters
[in] num
: Number to convert[out] out
: Output variable to save string[in] w
: Width of output string. When number is shorter than width, leading0
characters will apply.
-
lwgsm_i16_to_str
(num, out)¶ Convert
signed 16-bit
number to string.- Return
Pointer to output variable
- Parameters
[in] num
: Number to convert[out] out
: Output variable to save string
-
lwgsm_u8_to_str
(num, out)¶ Convert
unsigned 8-bit
number to string.- Return
Pointer to output variable
- Parameters
[in] num
: Number to convert[out] out
: Output variable to save string
-
lwgsm_u8_to_hex_str
(num, out, w)¶ Convert
unsigned 16-bit
number to HEX string.- Return
Pointer to output variable
- Parameters
[in] num
: Number to convert[out] out
: Output variable to save string[in] w
: Width of output string. When number is shorter than width, leading0
characters will apply.
-
lwgsm_i8_to_str
(num, out)¶ Convert
signed 8-bit
number to string.- Return
Pointer to output variable
- Parameters
[in] num
: Number to convert[out] out
: Output variable to save string
Functions
-
char *
lwgsm_u32_to_gen_str
(uint32_t num, char *out, uint8_t is_hex, uint8_t padding)¶ Convert
unsigned 32-bit
number to string.- Return
Pointer to output variable
- Parameters
[in] num
: Number to convert[out] out
: Output variable to save string[in] is_hex
: Set to1
to output hex, 0 otherwise[in] width
: Width of output string. When number is shorter than width, leading0
characters will apply. This parameter is valid only when formatting hex numbers
-
char *
lwgsm_i32_to_gen_str
(int32_t num, char *out)¶ Convert
signed 32-bit
number to string.- Return
Pointer to output variable
- Parameters
[in] num
: Number to convert[out] out
: Output variable to save string
-
-
group
LWGSM
Lightweight GSM-AT parser library.
Functions
-
lwgsmr_t
lwgsm_init
(lwgsm_evt_fn evt_func, const uint32_t blocking)¶ 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 LWGSM_CFG_RESET_ON_INIT is enabled, reset sequence will be sent to device otherwise manual call to lwgsm_reset is required to setup device
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[in] evt_func
: Global event callback function for all major events[in] blocking
: Status whether command should be blocking or not. Used when LWGSM_CFG_RESET_ON_INIT is enabled.
-
lwgsmr_t
lwgsm_reset
(const lwgsm_api_cmd_evt_fn evt_fn, void *const evt_arg, const uint32_t blocking)¶ Execute reset and send default commands.
-
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)¶ Execute reset and send default commands with delay.
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[in] delay
: Number of milliseconds to wait before initiating first command to device[in] evt_fn
: Callback function called when command is finished. Set toNULL
when not used[in] evt_arg
: Custom argument for event callback function[in] blocking
: Status whether command should be blocking or not
-
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)¶ Set modem function mode.
- Note
Use this function to set modem to normal or low-power mode
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[in] mode
: Mode status. Set to1
for full functionality or0
for low-power mode (no functionality)[in] evt_fn
: Callback function called when command is finished. Set toNULL
when not used[in] evt_arg
: Custom argument for event callback function[in] blocking
: Status whether command should be blocking or not
-
lwgsmr_t
lwgsm_core_lock
(void)¶ 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 lwgsm_core_unlock the same amount of time to make sure lock gets back to
0
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
-
lwgsmr_t
lwgsm_core_unlock
(void)¶ Unlock stack for multi-thread access.
Used in conjunction with 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
-
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)¶ 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
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[in] present
: Flag indicating device is present[in] evt_fn
: Callback function called when command is finished. Set toNULL
when not used[in] evt_arg
: Custom argument for event callback function[in] blocking
: Status whether command should be blocking or not
-
uint8_t
lwgsm_device_is_present
(void)¶ Check if device is present.
- Return
1
on success,0
otherwise
-
uint8_t
lwgsm_delay
(uint32_t ms)¶ 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 blocked list during delay and may improve execution speed- Return
1
on success,0
otherwise- Parameters
[in] ms
: Milliseconds to delay
-
lwgsmr_t
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 Getting started for guidelines on how to create and use configuration file.
-
group
LWGSM_OPT
GSM-AT options.
Defines
-
LWGSM_CFG_OS
¶ Enables
1
or disables0
operating system support for GSM library.- Note
Value must be set to 1 in the current revision
- Note
Check OS configuration group for more configuration related to operating system
-
LWGSM_CFG_MEM_CUSTOM
¶ Enables
1
or disables0
custom memory management functions.When set to
1
, Memory manager block must be provided manually. This includes implementation of functions lwgsm_mem_malloc, lwgsm_mem_calloc, lwgsm_mem_realloc and lwgsm_mem_free- Note
Function declaration follows standard C functions
malloc, calloc, realloc, free
. Declaration is available inlwgsm/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
-
LWGSM_CFG_MEM_ALIGNMENT
¶ Memory alignment for dynamic memory allocations.
- Note
Some CPUs can work faster if memory is aligned, usually to 4 or 8 bytes. To speed up this possibilities, you can set memory alignment and library will try to allocate memory on aligned boundaries.
- Note
Some CPUs such ARM Cortex-M0 don’t support unaligned memory access. This CPUs must have set correct memory alignment value.
- Note
This value must be power of
2
-
LWGSM_CFG_USE_API_FUNC_EVT
¶ Enables
1
or disables0
callback function and custom parameter for API functions.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 toNULL
.
-
LWGSM_CFG_MAX_CONNS
¶ Maximal number of connections AT software can support on GSM device.
-
LWGSM_CFG_CONN_MAX_DATA_LEN
¶ Maximal number of bytes we can send at single command to GSM.
- Note
Value can not exceed
1460
bytes or no data will be ever send- Note
This is limitation of GSM AT commands and on systems where RAM is not an issue, it should be set to maximal value (
1460
) to optimize data transfer speed performance
-
LWGSM_CFG_MAX_SEND_RETRIES
¶ Set number of retries for send data command.
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.
-
LWGSM_CFG_IPD_MAX_BUFF_SIZE
¶ Maximum single buffer size for network receive data (TCP/UDP connections)
- Note
When GSM sends buffer buffer than maximal, multiple buffers are created
-
LWGSM_CFG_AT_PORT_BAUDRATE
¶ Default baudrate used for AT port.
- Note
Later, user may call API function to change to desired baudrate if necessary
-
LWGSM_CFG_RCV_BUFF_SIZE
¶ Buffer size for received data waiting to be processed.
- Note
When server mode is active and a lot of connections are in queue this should be set high otherwise your buffer may overflow
- Note
Buffer size also depends on TX user driver if it uses DMA or blocking mode 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 LWGSM_CFG_INPUT_USE_PROCESS is enabled
-
LWGSM_CFG_RESET_ON_INIT
¶ Enables
1
or disables0
reset sequence after lwgsm_init call.- Note
When this functionality is disabled, user must manually call lwgsm_reset to send reset sequence to GSM device.
-
LWGSM_CFG_RESET_ON_DEVICE_PRESENT
¶ Enables
1
or disables0
reset sequence after lwgsm_device_set_present call.- Note
When this functionality is disabled, user must manually call lwgsm_reset to send reset sequence to GSM device.
-
LWGSM_CFG_RESET_DELAY_DEFAULT
¶ Default delay (milliseconds unit) before sending first AT command on reset sequence.
-
LWGSM_CFG_CONN_POLL_INTERVAL
¶ Poll interval for connections in units of milliseconds.
Value indicates interval time to call poll event on active connections.
- Note
Single poll interval applies for all connections
-
-
group
LWGSM_OPT_DBG
Debugging configurations.
Defines
-
LWGSM_CFG_DBG
¶ Set global debug support.
Possible values are LWGSM_DBG_ON or LWGSM_DBG_OFF
- Note
Set to LWGSM_DBG_OFF to globally disable all debugs
-
LWGSM_CFG_DBG_OUT
(fmt, ...)¶ Debugging output function.
Called with format and optional parameters for printf style debug
-
LWGSM_CFG_DBG_LVL_MIN
¶ Minimal debug level.
Check LWGSM_DBG_LVL for possible values
-
LWGSM_CFG_DBG_TYPES_ON
¶ Enabled debug types.
When debug is globally enabled with LWGSM_CFG_DBG parameter, user must enable debug types such as TRACE or STATE messages.
Check LWGSM_DBG_TYPE for possible options. Separate values with
bitwise OR
operator
-
LWGSM_CFG_DBG_INIT
¶ Set debug level for init function.
Possible values are LWGSM_DBG_ON or LWGSM_DBG_OFF
-
LWGSM_CFG_DBG_MEM
¶ Set debug level for memory manager.
Possible values are LWGSM_DBG_ON or LWGSM_DBG_OFF
-
LWGSM_CFG_DBG_INPUT
¶ Set debug level for input module.
Possible values are LWGSM_DBG_ON or LWGSM_DBG_OFF
-
LWGSM_CFG_DBG_THREAD
¶ Set debug level for GSM threads.
Possible values are LWGSM_DBG_ON or LWGSM_DBG_OFF
-
LWGSM_CFG_DBG_ASSERT
¶ Set debug level for asserting of input variables.
Possible values are LWGSM_DBG_ON or LWGSM_DBG_OFF
-
LWGSM_CFG_DBG_IPD
¶ Set debug level for incoming data received from device.
Possible values are LWGSM_DBG_ON or LWGSM_DBG_OFF
-
LWGSM_CFG_DBG_PBUF
¶ Set debug level for packet buffer manager.
Possible values are LWGSM_DBG_ON or LWGSM_DBG_OFF
-
LWGSM_CFG_DBG_CONN
¶ Set debug level for connections.
Possible values are LWGSM_DBG_ON or LWGSM_DBG_OFF
-
LWGSM_CFG_DBG_VAR
¶ Set debug level for dynamic variable allocations.
Possible values are LWGSM_DBG_ON or LWGSM_DBG_OFF
-
LWGSM_CFG_DBG_NETCONN
¶ Set debug level for netconn sequential API.
Possible values are LWGSM_DBG_ON or LWGSM_DBG_OFF
-
LWGSM_CFG_AT_ECHO
¶ Enables
1
or disables0
echo mode on AT commands sent to GSM device.- Note
This mode is useful when debugging GSM communication
-
-
group
LWGSM_OPT_OS
Operating system dependant configuration.
Defines
-
LWGSM_CFG_THREAD_PRODUCER_MBOX_SIZE
¶ Set number of message queue entries for procuder thread.
Message queue is used for storing memory address to command data
-
LWGSM_CFG_THREAD_PROCESS_MBOX_SIZE
¶ Set number of message queue entries for processing thread.
Message queue is used to notify processing thread about new received data on AT port
-
LWGSM_CFG_INPUT_USE_PROCESS
¶ Enables
1
or disables0
direct support for processing input data.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 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
-
LWGSM_THREAD_PRODUCER_HOOK
()¶ Producer thread hook, called each time thread wakes-up and does the processing.
It can be used to check if thread is alive.
-
LWGSM_THREAD_PROCESS_HOOK
()¶ Process thread hook, called each time thread wakes-up and does the processing.
It can be used to check if thread is alive.
-
-
group
LWGSM_OPT_STD_LIB
Standard C library configuration.
Configuration allows you to overwrite default C language function in case of better implementation with hardware (for example DMA for data copy).
Defines
-
LWGSM_MEMCPY
(dst, src, len)¶ Memory copy function declaration.
User is able to change the memory function, in case hardware supports copy operation, it may implement its own
Function prototype must be similar to:
void * my_memcpy(void* dst, const void* src, size_t len);
- Return
Destination memory start address
- Parameters
[in] dst
: Destination memory start address[in] src
: Source memory start address[in] len
: Number of bytes to copy
-
LWGSM_MEMSET
(dst, b, len)¶ Memory set function declaration.
Function prototype must be similar to:
void * my_memset(void* dst, int b, size_t len);
- Return
Destination memory start address
- Parameters
[in] dst
: Destination memory start address[in] b
: Value (byte) to set in memory[in] len
: Number of bytes to set
-
-
group
LWGSM_OPT_MODULES
Configuration of specific modules.
Defines
-
LWGSM_CFG_NETWORK
¶ Enables
1
or disables0
network functionality used for TCP/IP communication.Network must be enabled to use all GPRS/LTE functions such as connection API, FTP, HTTP, etc.
-
LWGSM_CFG_NETWORK_IGNORE_CGACT_RESULT
¶ Ignores
1
or not0
result fromAT+CGACT
command.- Note
This may be used for data-only SIM cards where command might fail when trying to attach to network for data transfer
-
LWGSM_CFG_CONN
¶ Enables
1
or disables0
connection API.- Note
LWGSM_CFG_NETWORK must be enabled to use connection feature
-
LWGSM_CFG_SMS
¶ Enables
1
or disables0
SMS API.
-
LWGSM_CFG_CALL
¶ Enables
1
or disables0
call API.
-
LWGSM_CFG_PHONEBOOK
¶ Enables
1
or disables0
phonebook API.
-
LWGSM_CFG_HTTP
¶ Enables
1
or disables0
HTTP API.- Note
LWGSM_CFG_NETWORK must be enabled to use connection feature
-
LWGSM_CFG_FTP
¶ Enables
1
or disables0
FTP API.- Note
LWGSM_CFG_NETWORK must be enabled to use connection feature
-
LWGSM_CFG_PING
¶ Enables
1
or disables0
PING API.- Note
LWGSM_CFG_NETWORK must be enabled to use connection feature
-
LWGSM_CFG_USSD
¶ Enables
1
or disables0
USSD API.
-
-
group
LWGSM_OPT_MODULES_NETCONN
Configuration of netconn API module.
Defines
-
LWGSM_CFG_NETCONN
¶ Enables
1
or disables0
NETCONN sequential API support for OS systems.- Note
To use this feature, OS support is mandatory.
- See
-
LWGSM_CFG_NETCONN_RECEIVE_TIMEOUT
¶ Enables
1
or disables0
receive timeout feature.When this option is enabled, user will get an option to set timeout value for receive data on netconn, before function returns timeout error.
- 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.
-
LWGSM_CFG_NETCONN_ACCEPT_QUEUE_LEN
¶ Accept queue length for new client when netconn server is used.
Defines number of maximal clients waiting in accept queue of server connection
-
LWGSM_CFG_NETCONN_RECEIVE_QUEUE_LEN
¶ Receive queue length for pbuf entries.
Defines maximal number of pbuf data packet references for receive
-
-
group
LWGSM_OPT_MODULES_MQTT
Configuration of MQTT and MQTT API client modules.
Defines
-
LWGSM_CFG_MQTT_MAX_REQUESTS
¶ Maximal number of open MQTT requests at a time.
-
LWGSM_CFG_DBG_MQTT
¶ Set debug level for MQTT client module.
Possible values are LWGSM_DBG_ON or LWGSM_DBG_OFF
-
LWGSM_CFG_DBG_MQTT_API
¶ Set debug level for MQTT API client module.
Possible values are LWGSM_DBG_ON or LWGSM_DBG_OFF
-
Platform specific¶
List of all the modules:
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 Porting guide for actual implementation
-
group
LWGSM_LL
Low-level communication functions.
Typedefs
-
typedef size_t (*
lwgsm_ll_send_fn
)(const void *data, size_t len)¶ Function prototype for AT output data.
- Return
Number of bytes sent
- Parameters
[in] data
: Pointer to data to send. This parameter can be set toNULL
[in] len
: Number of bytes to send. This parameter can be set to0
to indicate that internal buffer can be flushed to stream. This is implementation defined and feature might be ignored
-
typedef uint8_t (*
lwgsm_ll_reset_fn
)(uint8_t state)¶ Function prototype for hardware reset of GSM device.
- Return
1
on successful action,0
otherwise- Parameters
[in] state
: State indicating reset. When set to1
, reset must be active (usually pin active low), or set to0
when reset is cleared
Functions
-
lwgsmr_t
lwgsm_ll_init
(lwgsm_ll_t *ll)¶ Callback function called from initialization process.
- Note
This function may be called multiple times if AT baudrate is changed from application. 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 LWGSM_CFG_INPUT_USE_PROCESS is set to 1, this function may be called from user UART thread.
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[inout] ll
: Pointer to lwgsm_ll_t structure to fill data for communication functions
-
lwgsmr_t
lwgsm_ll_deinit
(lwgsm_ll_t *ll)¶ Callback function to de-init low-level communication part.
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[inout] ll
: Pointer to lwgsm_ll_t structure to fill data for communication functions
-
struct
lwgsm_ll_t
¶ - #include <lwgsm_typedefs.h>
Low level user specific functions.
Public Members
-
lwgsm_ll_send_fn
send_fn
¶ Callback function to transmit data
-
lwgsm_ll_reset_fn
reset_fn
¶ Reset callback function
-
uint32_t
baudrate
¶ UART baudrate value
-
struct lwgsm_ll_t::[anonymous]
uart
¶ UART communication parameters
-
lwgsm_ll_send_fn
-
typedef size_t (*
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 Porting guide for actual implementation guidelines.
-
group
LWGSM_SYS
System based function for OS management, timings, etc.
Main
-
uint8_t
lwgsm_sys_init
(void)¶ Init system dependant parameters.
After this function is called, all other system functions must be fully ready.
- Return
1
on success,0
otherwise
-
uint32_t
lwgsm_sys_now
(void)¶ Get current time in units of milliseconds.
- Return
Current time in units of milliseconds
-
uint8_t
lwgsm_sys_protect
(void)¶ 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_unprotect
(void)¶ Unprotect middleware core.
This function must follow number of calls of 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
Mutex
-
uint8_t
lwgsm_sys_mutex_create
(lwgsm_sys_mutex_t *p)¶ Create new recursive mutex.
- Note
Recursive mutex has to be created as it may be locked multiple times before unlocked
- Return
1
on success,0
otherwise- Parameters
[out] p
: Pointer to mutex structure to allocate
-
uint8_t
lwgsm_sys_mutex_delete
(lwgsm_sys_mutex_t *p)¶ Delete recursive mutex from system.
- Return
1
on success,0
otherwise- Parameters
[in] p
: Pointer to mutex structure
-
uint8_t
lwgsm_sys_mutex_lock
(lwgsm_sys_mutex_t *p)¶ Lock recursive mutex, wait forever to lock.
- Return
1
on success,0
otherwise- Parameters
[in] p
: Pointer to mutex structure
-
uint8_t
lwgsm_sys_mutex_unlock
(lwgsm_sys_mutex_t *p)¶ Unlock recursive mutex.
- Return
1
on success,0
otherwise- Parameters
[in] p
: Pointer to mutex structure
-
uint8_t
lwgsm_sys_mutex_isvalid
(lwgsm_sys_mutex_t *p)¶ Check if mutex structure is valid system.
- Return
1
on success,0
otherwise- Parameters
[in] p
: Pointer to mutex structure
-
uint8_t
lwgsm_sys_mutex_invalid
(lwgsm_sys_mutex_t *p)¶ Set recursive mutex structure as invalid.
- Return
1
on success,0
otherwise- Parameters
[in] p
: Pointer to mutex structure
Semaphores
-
uint8_t
lwgsm_sys_sem_create
(lwgsm_sys_sem_t *p, uint8_t cnt)¶ Create a new binary semaphore and set initial state.
- Note
Semaphore may only have
1
token available- Return
1
on success,0
otherwise- Parameters
[out] p
: Pointer to semaphore structure to fill with result[in] cnt
: Count indicating default semaphore state:0
: Take semaphore token immediately1
: Keep token available
-
uint8_t
lwgsm_sys_sem_delete
(lwgsm_sys_sem_t *p)¶ Delete binary semaphore.
- Return
1
on success,0
otherwise- Parameters
[in] p
: Pointer to semaphore structure
-
uint32_t
lwgsm_sys_sem_wait
(lwgsm_sys_sem_t *p, uint32_t timeout)¶ Wait for semaphore to be available.
- Return
Number of milliseconds waited for semaphore to become available or LWGSM_SYS_TIMEOUT if not available within given time
- Parameters
[in] p
: Pointer to semaphore structure[in] timeout
: Timeout to wait in milliseconds. When0
is applied, wait forever
-
uint8_t
lwgsm_sys_sem_release
(lwgsm_sys_sem_t *p)¶ Release semaphore.
- Return
1
on success,0
otherwise- Parameters
[in] p
: Pointer to semaphore structure
-
uint8_t
lwgsm_sys_sem_isvalid
(lwgsm_sys_sem_t *p)¶ Check if semaphore is valid.
- Return
1
on success,0
otherwise- Parameters
[in] p
: Pointer to semaphore structure
-
uint8_t
lwgsm_sys_sem_invalid
(lwgsm_sys_sem_t *p)¶ Invalid semaphore.
- Return
1
on success,0
otherwise- Parameters
[in] p
: Pointer to semaphore structure
Message queues
-
uint8_t
lwgsm_sys_mbox_create
(lwgsm_sys_mbox_t *b, size_t size)¶ Create a new message queue with entry type of
void *
- Return
1
on success,0
otherwise- Parameters
[out] b
: Pointer to message queue structure[in] size
: Number of entries for message queue to hold
-
uint8_t
lwgsm_sys_mbox_delete
(lwgsm_sys_mbox_t *b)¶ Delete message queue.
- Return
1
on success,0
otherwise- Parameters
[in] b
: Pointer to message queue structure
-
uint32_t
lwgsm_sys_mbox_put
(lwgsm_sys_mbox_t *b, void *m)¶ Put a new entry to message queue and wait until memory available.
- Return
Time in units of milliseconds needed to put a message to queue
- Parameters
[in] b
: Pointer to message queue structure[in] m
: Pointer to entry to insert to message queue
-
uint32_t
lwgsm_sys_mbox_get
(lwgsm_sys_mbox_t *b, void **m, uint32_t timeout)¶ Get a new entry from message queue with timeout.
- Return
Time in units of milliseconds needed to put a message to queue or LWGSM_SYS_TIMEOUT if it was not successful
- Parameters
[in] b
: Pointer to message queue structure[in] m
: Pointer to pointer to result to save value from message queue to[in] timeout
: Maximal timeout to wait for new message. When0
is applied, wait for unlimited time
-
uint8_t
lwgsm_sys_mbox_putnow
(lwgsm_sys_mbox_t *b, void *m)¶ Put a new entry to message queue without timeout (now or fail)
- Return
1
on success,0
otherwise- Parameters
[in] b
: Pointer to message queue structure[in] m
: Pointer to message to save to queue
-
uint8_t
lwgsm_sys_mbox_getnow
(lwgsm_sys_mbox_t *b, void **m)¶ Get an entry from message queue immediately.
- Return
1
on success,0
otherwise- Parameters
[in] b
: Pointer to message queue structure[in] m
: Pointer to pointer to result to save value from message queue to
-
uint8_t
lwgsm_sys_mbox_isvalid
(lwgsm_sys_mbox_t *b)¶ Check if message queue is valid.
- Return
1
on success,0
otherwise- Parameters
[in] b
: Pointer to message queue structure
-
uint8_t
lwgsm_sys_mbox_invalid
(lwgsm_sys_mbox_t *b)¶ Invalid message queue.
- Return
1
on success,0
otherwise- Parameters
[in] b
: Pointer to message queue structure
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)¶ Create a new thread.
- Return
1
on success,0
otherwise- Parameters
[out] t
: Pointer to thread identifier if create was successful. It may be set toNULL
[in] name
: Name of a new thread[in] thread_func
: Thread function to use as thread body[in] arg
: Thread function argument[in] stack_size
: Size of thread stack in uints of bytes. If set to 0, reserve default stack size[in] prio
: Thread priority
-
uint8_t
lwgsm_sys_thread_terminate
(lwgsm_sys_thread_t *t)¶ Terminate thread (shut it down and remove)
- Return
1
on success,0
otherwise- Parameters
[in] t
: Pointer to thread handle to terminate. If set toNULL
, terminate current thread (thread from where function is called)
-
uint8_t
lwgsm_sys_thread_yield
(void)¶ Yield current thread.
- Return
1
on success,0
otherwise
Defines
-
LWGSM_SYS_MUTEX_NULL
¶ Mutex invalid value.
Value assigned to lwgsm_sys_mutex_t type when it is not valid.
-
LWGSM_SYS_SEM_NULL
¶ Semaphore invalid value.
Value assigned to lwgsm_sys_sem_t type when it is not valid.
-
LWGSM_SYS_MBOX_NULL
¶ Message box invalid value.
Value assigned to lwgsm_sys_mbox_t type when it is not valid.
-
LWGSM_SYS_TIMEOUT
¶ 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
-
LWGSM_SYS_THREAD_PRIO
¶ 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.
-
LWGSM_SYS_THREAD_SS
¶ Stack size in units of bytes for system threads.
It is used as default stack size for all built-in threads.
Typedefs
-
typedef void (*
lwgsm_sys_thread_fn
)(void*)¶ Thread function prototype.
-
typedef osMutexId_t
lwgsm_sys_mutex_t
¶ System mutex type.
It is used by middleware as base type of mutex.
-
typedef osSemaphoreId_t
lwgsm_sys_sem_t
¶ System semaphore type.
It is used by middleware as base type of mutex.
-
typedef osMessageQueueId_t
lwgsm_sys_mbox_t
¶ System message queue type.
It is used by middleware as base type of mutex.
-
typedef osThreadId_t
lwgsm_sys_thread_t
¶ System thread ID type.
-
typedef osPriority
lwgsm_sys_thread_prio_t
¶ System thread priority type.
It is used as priority type for system function, to start new threads by middleware.
-
uint8_t
Applications¶
MQTT Client¶
MQTT client v3.1.1 implementation, based on callback (non-netconn) connection API.
-
group
LWGSM_APP_MQTT_CLIENT
MQTT client.
Typedefs
-
typedef struct lwgsm_mqtt_client *
lwgsm_mqtt_client_p
¶ Pointer to lwgsm_mqtt_client_t structure.
-
typedef void (*
lwgsm_mqtt_evt_fn
)(lwgsm_mqtt_client_p client, lwgsm_mqtt_evt_t *evt)¶ MQTT event callback function.
- Parameters
[in] client
: MQTT client[in] evt
: MQTT event with type and related data
Enums
-
enum
lwgsm_mqtt_qos_t
¶ Quality of service enumeration.
Values:
-
enumerator
LWGSM_MQTT_QOS_AT_MOST_ONCE
¶ Delivery is not guaranteed to arrive, but can arrive
up to 1 time
= non-critical packets where losses are allowed
-
enumerator
LWGSM_MQTT_QOS_AT_LEAST_ONCE
¶ Delivery is quaranteed
at least once
, but it may be delivered multiple times with the same content
-
enumerator
LWGSM_MQTT_QOS_EXACTLY_ONCE
¶ Delivery is quaranteed
exactly once
= very critical packets such as billing informations or similar
-
enumerator
-
enum
lwgsm_mqtt_state_t
¶ State of MQTT client.
Values:
-
enumerator
LWGSM_MQTT_CONN_DISCONNECTED
¶ Connection with server is not established
-
enumerator
LWGSM_MQTT_CONN_CONNECTING
¶ Client is connecting to server
-
enumerator
LWGSM_MQTT_CONN_DISCONNECTING
¶ Client connection is disconnecting from server
-
enumerator
LWGSM_MQTT_CONNECTING
¶ MQTT client is connecting… CONNECT command has been sent to server
-
enumerator
LWGSM_MQTT_CONNECTED
¶ MQTT is fully connected and ready to send data on topics
-
enumerator
-
enum
lwgsm_mqtt_evt_type_t
¶ MQTT event types.
Values:
-
enumerator
LWGSM_MQTT_EVT_CONNECT
¶ MQTT client connect event
-
enumerator
LWGSM_MQTT_EVT_SUBSCRIBE
¶ MQTT client subscribed to specific topic
-
enumerator
LWGSM_MQTT_EVT_UNSUBSCRIBE
¶ MQTT client unsubscribed from specific topic
-
enumerator
LWGSM_MQTT_EVT_PUBLISH
¶ MQTT client publish message to server event.
- Note
When publishing packet with quality of service 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 = LWGSM_MQTT_QOS_AT_MOST_ONCE
-
enumerator
LWGSM_MQTT_EVT_PUBLISH_RECV
¶ MQTT client received a publish message from server
-
enumerator
LWGSM_MQTT_EVT_DISCONNECT
¶ MQTT client disconnected from MQTT server
-
enumerator
LWGSM_MQTT_EVT_KEEP_ALIVE
¶ MQTT keep-alive sent to server and reply received
-
enumerator
-
enum
lwgsm_mqtt_conn_status_t
¶ List of possible results from MQTT server when executing connect command.
Values:
-
enumerator
LWGSM_MQTT_CONN_STATUS_ACCEPTED
¶ Connection accepted and ready to use
-
enumerator
LWGSM_MQTT_CONN_STATUS_REFUSED_PROTOCOL_VERSION
¶ Connection Refused, unacceptable protocol version
-
enumerator
LWGSM_MQTT_CONN_STATUS_REFUSED_ID
¶ Connection refused, identifier rejected
-
enumerator
LWGSM_MQTT_CONN_STATUS_REFUSED_SERVER
¶ Connection refused, server unavailable
-
enumerator
LWGSM_MQTT_CONN_STATUS_REFUSED_USER_PASS
¶ Connection refused, bad user name or password
-
enumerator
LWGSM_MQTT_CONN_STATUS_REFUSED_NOT_AUTHORIZED
¶ Connection refused, not authorized
-
enumerator
LWGSM_MQTT_CONN_STATUS_TCP_FAILED
¶ TCP connection to server was not successful
-
enumerator
Functions
-
lwgsm_mqtt_client_p
lwgsm_mqtt_client_new
(size_t tx_buff_len, size_t rx_buff_len)¶ Allocate a new MQTT client structure.
- Return
Pointer to new allocated MQTT client structure or
NULL
on failure- Parameters
[in] tx_buff_len
: Length of raw data output buffer[in] rx_buff_len
: Length of raw data input buffer
-
void
lwgsm_mqtt_client_delete
(lwgsm_mqtt_client_p client)¶ Delete MQTT client structure.
- Note
MQTT client must be disconnected first
- Parameters
[in] client
: MQTT 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)¶ Connect to MQTT server.
- Note
After TCP connection is established, CONNECT packet is automatically sent to server
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[in] client
: MQTT client[in] host
: Host address for server[in] port
: Host port number[in] evt_fn
: Callback function for all events on this MQTT client[in] info
: Information structure for connection
-
lwgsmr_t
lwgsm_mqtt_client_disconnect
(lwgsm_mqtt_client_p client)¶ Disconnect from MQTT server.
-
uint8_t
lwgsm_mqtt_client_is_connected
(lwgsm_mqtt_client_p client)¶ Test if client is connected to server and accepted to MQTT protocol.
- Note
Function will return error if TCP is connected but MQTT not accepted
- Return
1
on success,0
otherwise- Parameters
[in] client
: MQTT client
-
lwgsmr_t
lwgsm_mqtt_client_subscribe
(lwgsm_mqtt_client_p client, const char *topic, lwgsm_mqtt_qos_t qos, void *arg)¶ Subscribe to MQTT topic.
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[in] client
: MQTT client[in] topic
: Topic name to subscribe to[in] qos
: Quality of service. This parameter can be a value of lwgsm_mqtt_qos_t[in] arg
: User custom argument used in callback
-
lwgsmr_t
lwgsm_mqtt_client_unsubscribe
(lwgsm_mqtt_client_p client, const char *topic, void *arg)¶ Unsubscribe from MQTT topic.
-
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)¶ Publish a new message on specific topic.
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[in] client
: MQTT client[in] topic
: Topic to send message to[in] payload
: Message data[in] payload_len
: Length of payload data[in] qos
: Quality of service. This parameter can be a value of lwgsm_mqtt_qos_t enumeration[in] retain
: Retian parameter value[in] arg
: User custom argument used in callback
-
void *
lwgsm_mqtt_client_get_arg
(lwgsm_mqtt_client_p client)¶ Get user argument on client.
- Return
User argument
- Parameters
[in] client
: MQTT client handle
-
void
lwgsm_mqtt_client_set_arg
(lwgsm_mqtt_client_p client, void *arg)¶ Set user argument on client.
- Parameters
[in] client
: MQTT client handle[in] arg
: User argument
-
struct
lwgsm_mqtt_client_info_t
¶ - #include <lwgsm_mqtt_client.h>
MQTT client information structure.
Public Members
-
const char *
id
¶ Client unique identifier. It is required and must be set by user
-
const char *
user
¶ Authentication username. Set to
NULL
if not required
-
const char *
pass
¶ Authentication password, set to
NULL
if not required
-
uint16_t
keep_alive
¶ Keep-alive parameter in units of seconds. When set to
0
, functionality is disabled (not recommended)
-
const char *
will_topic
¶ Will topic
-
const char *
will_message
¶ Will message
-
lwgsm_mqtt_qos_t
will_qos
¶ Will topic quality of service
-
const char *
-
struct
lwgsm_mqtt_request_t
¶ - #include <lwgsm_mqtt_client.h>
MQTT request object.
Public Members
-
uint8_t
status
¶ Entry status flag for in use or pending bit
-
uint16_t
packet_id
¶ Packet ID generated by client on publish
-
void *
arg
¶ User defined argument
-
uint32_t
expected_sent_len
¶ Number of total bytes which must be sent on connection before we can say “packet was sent”.
-
uint32_t
timeout_start_time
¶ Timeout start time in units of milliseconds
-
uint8_t
-
struct
lwgsm_mqtt_evt_t
¶ - #include <lwgsm_mqtt_client.h>
MQTT event structure for callback function.
Public Members
-
lwgsm_mqtt_evt_type_t
type
¶ Event type
-
lwgsm_mqtt_conn_status_t
status
¶ Connection status with MQTT
-
struct lwgsm_mqtt_evt_t::[anonymous]::[anonymous]
connect
¶ Event for connecting to server
-
uint8_t
is_accepted
¶ Status if client was accepted to MQTT prior disconnect event
-
struct lwgsm_mqtt_evt_t::[anonymous]::[anonymous]
disconnect
¶ Event for disconnecting from server
-
void *
arg
¶ User argument for callback function
-
struct lwgsm_mqtt_evt_t::[anonymous]::[anonymous]
sub_unsub_scribed
¶ Event for (un)subscribe to/from topics
-
struct lwgsm_mqtt_evt_t::[anonymous]::[anonymous]
publish
¶ Published event
-
const uint8_t *
topic
¶ Pointer to topic identifier
-
size_t
topic_len
¶ Length of topic
-
const void *
payload
¶ Topic payload
-
size_t
payload_len
¶ Length of topic payload
-
uint8_t
dup
¶ Duplicate flag if message was sent again
-
lwgsm_mqtt_qos_t
qos
¶ Received packet quality of service
-
struct lwgsm_mqtt_evt_t::[anonymous]::[anonymous]
publish_recv
¶ Publish received event
-
union lwgsm_mqtt_evt_t::[anonymous]
evt
¶ Event data parameters
-
lwgsm_mqtt_evt_type_t
-
typedef struct lwgsm_mqtt_client *
-
group
LWGSM_APP_MQTT_CLIENT_EVT
Event helper functions.
Connect event
- Note
Use these functions on LWGSM_MQTT_EVT_CONNECT event
-
lwgsm_mqtt_client_evt_connect_get_status
(client, evt)¶ Get connection status.
- Return
Connection status. Member of lwgsm_mqtt_conn_status_t
- Parameters
[in] client
: MQTT client[in] evt
: Event handle
Disconnect event
- Note
Use these functions on LWGSM_MQTT_EVT_DISCONNECT event
-
lwgsm_mqtt_client_evt_disconnect_is_accepted
(client, evt)¶ Check if MQTT client was accepted by server when disconnect event occurred.
- Return
1
on success,0
otherwise- Parameters
[in] client
: MQTT client[in] evt
: Event handle
Subscribe/unsubscribe event
- Note
Use these functions on LWGSM_MQTT_EVT_SUBSCRIBE or LWGSM_MQTT_EVT_UNSUBSCRIBE events
-
lwgsm_mqtt_client_evt_subscribe_get_argument
(client, evt)¶ Get user argument used on lwgsm_mqtt_client_subscribe.
- Return
User argument
- Parameters
[in] client
: MQTT client[in] evt
: Event handle
-
lwgsm_mqtt_client_evt_subscribe_get_result
(client, evt)¶ Get result of subscribe event.
-
lwgsm_mqtt_client_evt_unsubscribe_get_argument
(client, evt)¶ Get user argument used on lwgsm_mqtt_client_unsubscribe.
- Return
User argument
- Parameters
[in] client
: MQTT client[in] evt
: Event handle
Publish receive event
- Note
Use these functions on LWGSM_MQTT_EVT_PUBLISH_RECV event
-
lwgsm_mqtt_client_evt_publish_recv_get_topic
(client, evt)¶ Get topic from received publish packet.
- Return
Topic name
- Parameters
[in] client
: MQTT client[in] evt
: Event handle
-
lwgsm_mqtt_client_evt_publish_recv_get_topic_len
(client, evt)¶ Get topic length from received publish packet.
- Return
Topic length
- Parameters
[in] client
: MQTT client[in] evt
: Event handle
-
lwgsm_mqtt_client_evt_publish_recv_get_payload
(client, evt)¶ Get payload from received publish packet.
- Return
Packet payload
- Parameters
[in] client
: MQTT client[in] evt
: Event handle
-
lwgsm_mqtt_client_evt_publish_recv_get_payload_len
(client, evt)¶ Get payload length from received publish packet.
- Return
Payload length
- Parameters
[in] client
: MQTT client[in] evt
: Event handle
-
lwgsm_mqtt_client_evt_publish_recv_is_duplicate
(client, evt)¶ Check if packet is duplicated.
- Return
1
if duplicated,0
otherwise- Parameters
[in] client
: MQTT client[in] evt
: Event handle
-
lwgsm_mqtt_client_evt_publish_recv_get_qos
(client, evt)¶ Get received quality of service.
- Return
Member of lwgsm_mqtt_qos_t enumeration
- Parameters
[in] client
: MQTT client[in] evt
: Event handle
Publish event
- Note
Use these functions on LWGSM_MQTT_EVT_PUBLISH event
-
lwgsm_mqtt_client_evt_publish_get_argument
(client, evt)¶ Get user argument used on lwgsm_mqtt_client_publish.
- Return
User argument
- Parameters
[in] client
: MQTT client[in] evt
: Event handle
Defines
-
lwgsm_mqtt_client_evt_get_type
(client, evt)¶ Get MQTT event type.
- Return
MQTT Event type, value of lwgsm_mqtt_evt_type_t enumeration
- Parameters
[in] client
: MQTT client[in] evt
: Event handle
MQTT Client API¶
MQTT Client API provides sequential API built on top of MQTT Client.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | /*
* MQTT client API example with GSM device.
*
* 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 "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 "lwgsm/apps/lwgsm_mqtt_client_api.h"
#include "mqtt_client_api.h"
#include "lwgsm/lwgsm_mem.h"
#include "lwgsm/lwgsm_network_api.h"
/**
* \brief Connection information for MQTT CONNECT packet
*/
static const lwgsm_mqtt_client_info_t
mqtt_client_info = {
.keep_alive = 10,
/* Server login data */
.user = "8a215f70-a644-11e8-ac49-e932ed599553",
.pass = "26aa943f702e5e780f015cd048a91e8fb54cca28",
/* Device identifier address */
.id = "2c3573a0-0176-11e9-a056-c5cffe7f75f9",
};
/**
* \brief Memory for temporary topic
*/
static char
mqtt_topic_str[256];
/**
* \brief Generate random number and write it to string
* \param[out] str: Output string with new number
*/
void
generate_random(char* str) {
static uint32_t random_beg = 0x8916;
random_beg = random_beg * 0x00123455 + 0x85654321;
sprintf(str, "%u", (unsigned)((random_beg >> 8) & 0xFFFF));
}
/**
* \brief MQTT client API thread
*/
void
mqtt_client_api_thread(void const* arg) {
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 (lwgsm_network_request_attach() != lwgsmOK) {
lwgsm_delay(1000);
}
/* Create new MQTT API */
client = lwgsm_mqtt_client_api_new(256, 128);
if (client == NULL) {
goto terminate;
}
while (1) {
/* Make a connection */
printf("Joining MQTT server\r\n");
/* Try to join */
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);
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 (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");
}
while (1) {
/* Receive MQTT packet with 1000ms timeout */
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);
lwgsm_mqtt_client_api_buf_free(buf);
buf = NULL;
}
} else if (res == lwgsmCLOSED) {
printf("MQTT connection closed!\r\n");
break;
} 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);
lwgsm_mqtt_client_api_publish(client, mqtt_topic_str, random_str, strlen(random_str), LWGSM_MQTT_QOS_AT_LEAST_ONCE, 0);
}
}
goto terminate;
}
terminate:
lwgsm_mqtt_client_api_delete(client);
lwgsm_network_request_detach();
printf("MQTT client thread terminate\r\n");
lwgsm_sys_thread_terminate(NULL);
}
|
-
group
LWGSM_APP_MQTT_CLIENT_API
Sequential, single thread MQTT client API.
Typedefs
-
typedef struct lwgsm_mqtt_client_api_buf *
lwgsm_mqtt_client_api_buf_p
¶ Pointer to lwgsm_mqtt_client_api_buf_t structure.
Functions
-
lwgsm_mqtt_client_api_p
lwgsm_mqtt_client_api_new
(size_t tx_buff_len, size_t rx_buff_len)¶ Create new MQTT client API.
- Return
Client handle on success,
NULL
otherwise- Parameters
[in] tx_buff_len
: Maximal TX buffer for maximal packet length[in] rx_buff_len
: Maximal RX buffer
-
void
lwgsm_mqtt_client_api_delete
(lwgsm_mqtt_client_api_p client)¶ Delete client from memory.
- Parameters
[in] client
: MQTT API client handle
-
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)¶ Connect to MQTT broker.
- Return
LWGSM_MQTT_CONN_STATUS_ACCEPTED on success, member of lwgsm_mqtt_conn_status_t otherwise
- Parameters
[in] client
: MQTT API client handle[in] host
: TCP host[in] port
: TCP port[in] info
: MQTT client info
-
lwgsmr_t
lwgsm_mqtt_client_api_subscribe
(lwgsm_mqtt_client_api_p client, const char *topic, lwgsm_mqtt_qos_t qos)¶ Subscribe to topic.
- Return
- Parameters
[in] client
: MQTT API client handle[in] topic
: Topic to subscribe on[in] qos
: Quality of service. This parameter can be a value of lwgsm_mqtt_qos_t
-
lwgsmr_t
lwgsm_mqtt_client_api_unsubscribe
(lwgsm_mqtt_client_api_p client, const char *topic)¶ Unsubscribe from 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)¶ Publish new packet to MQTT network.
- Return
- Parameters
[in] client
: MQTT API client handle[in] topic
: Topic to publish on[in] data
: Data to send[in] btw
: Number of bytes to send for data parameter[in] qos
: Quality of service. This parameter can be a value of lwgsm_mqtt_qos_t[in] retain
: Set to1
for retain flag,0
otherwise
-
uint8_t
lwgsm_mqtt_client_api_is_connected
(lwgsm_mqtt_client_api_p client)¶ Check if client MQTT connection is active.
- Return
1
on success,0
otherwise- Parameters
[in] client
: MQTT API client handle
-
lwgsmr_t
lwgsm_mqtt_client_api_receive
(lwgsm_mqtt_client_api_p client, lwgsm_mqtt_client_api_buf_p *p, uint32_t timeout)¶ 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
- Return
lwgsmOK on success, lwgsmCLOSED if MQTT is closed, lwgsmTIMEOUT on timeout
- Parameters
[in] client
: MQTT API client handle[in] p
: Pointer to output buffer[in] timeout
: Maximal time to wait before function returns timeout
-
void
lwgsm_mqtt_client_api_buf_free
(lwgsm_mqtt_client_api_buf_p p)¶ Free buffer memory after usage.
- Parameters
[in] p
: Buffer to free
-
struct
lwgsm_mqtt_client_api_buf_t
¶ - #include <lwgsm_mqtt_client_api.h>
MQTT API RX buffer.
-
typedef struct lwgsm_mqtt_client_api_buf *
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¶
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | #include "netconn_client.h"
#include "lwgsm/lwgsm.h"
#include "lwgsm/lwgsm_network_api.h"
#if LWGSM_CFG_NETCONN
/**
* \brief Host and port settings
*/
#define NETCONN_HOST "example.com"
#define NETCONN_PORT 80
/**
* \brief Request header to send on successful connection
*/
static const char
request_header[] = ""
"GET / HTTP/1.1\r\n"
"Host: " NETCONN_HOST "\r\n"
"Connection: close\r\n"
"\r\n";
/**
* \brief Netconn client thread implementation
* \param[in] arg: User argument
*/
void
netconn_client_thread(void const* arg) {
lwgsmr_t res;
lwgsm_pbuf_p pbuf;
lwgsm_netconn_p client;
lwgsm_sys_sem_t* sem = (void*)arg;
/* Request attach to network */
while (lwgsm_network_request_attach() != lwgsmOK) {
lwgsm_delay(1000);
}
/*
* First create a new instance of netconn
* connection and initialize system message boxes
* to accept received packet buffers
*/
client = lwgsm_netconn_new(LWGSM_NETCONN_TYPE_TCP);
if (client != NULL) {
/*
* Connect to external server as client
* with custom NETCONN_CONN_HOST and CONN_PORT values
*
* Function will block thread until we are successfully connected (or not) to server
*/
res = lwgsm_netconn_connect(client, NETCONN_HOST, NETCONN_PORT);
if (res == lwgsmOK) { /* Are we successfully connected? */
printf("Connected to " NETCONN_HOST "\r\n");
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 == lwgsmOK) { /* Were data sent? */
printf("Data were successfully sent to server\r\n");
/*
* Since we sent HTTP request,
* we are expecting some data from server
* or at least forced connection close from remote side
*/
do {
/*
* Receive single packet of data
*
* Function will block thread until new packet
* is ready to be read from remote side
*
* After function returns, don't forgot the check value.
* Returned status will give you info in case connection
* was closed too early from remote side
*/
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 == lwgsmTIMEOUT) {
printf("Netconn timeout while receiving data. You may try multiple readings before deciding to close manually\r\n");
}
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
*
* 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)lwgsm_pbuf_length(pbuf, 1));
lwgsm_pbuf_free(pbuf); /* Free the memory after usage */
pbuf = NULL;
}
} while (1);
} else {
printf("Error writing data to remote host!\r\n");
}
/*
* Check if connection was closed by remote server
* and in case it wasn't, close it manually
*/
if (res != lwgsmCLOSED) {
lwgsm_netconn_close(client);
}
} else {
printf("Cannot connect to remote host %s:%d!\r\n", NETCONN_HOST, NETCONN_PORT);
}
lwgsm_netconn_delete(client); /* Delete netconn structure */
}
lwgsm_network_request_detach(); /* Detach from network */
if (lwgsm_sys_sem_isvalid(sem)) {
lwgsm_sys_sem_release(sem);
}
lwgsm_sys_thread_terminate(NULL); /* Terminate current thread */
}
#endif /* LWGSM_CFG_NETCONN */
|
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, lwgsm_netconn_receive()
will block for maximal timeout set with
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
LWGSM_CFG_NETCONN_RECEIVE_TIMEOUT
must be set to 1
to use this feature.
-
group
LWGSM_NETCONN
Network connection.
Typedefs
-
typedef struct lwgsm_netconn *
lwgsm_netconn_p
¶ Netconn object structure.
Enums
Functions
-
lwgsm_netconn_p
lwgsm_netconn_new
(lwgsm_netconn_type_t type)¶ Create new netconn connection.
- Return
New netconn connection on success,
NULL
otherwise- Parameters
[in] type
: Netconn connection type
-
lwgsmr_t
lwgsm_netconn_delete
(lwgsm_netconn_p nc)¶ Delete netconn connection.
-
lwgsmr_t
lwgsm_netconn_connect
(lwgsm_netconn_p nc, const char *host, lwgsm_port_t port)¶ Connect to server as client.
-
lwgsmr_t
lwgsm_netconn_receive
(lwgsm_netconn_p nc, lwgsm_pbuf_p *pbuf)¶ Receive data from connection.
- Return
lwgsmOK when new data ready,
- Return
lwgsmCLOSED when connection closed by remote side,
- Return
lwgsmTIMEOUT when receive timeout occurs
- Return
Any other member of lwgsmr_t otherwise
- Parameters
[in] nc
: Netconn handle used to receive from[in] pbuf
: Pointer to pointer to save new receive buffer to. When function returns, user must check for valid pbuf valuepbuf != NULL
-
lwgsmr_t
lwgsm_netconn_close
(lwgsm_netconn_p nc)¶ Close a netconn connection.
-
int8_t
lwgsm_netconn_getconnnum
(lwgsm_netconn_p nc)¶ Get connection number used for netconn.
- Return
-1
on failure, connection number between0
and LWGSM_CFG_MAX_CONNS otherwise- Parameters
[in] nc
: Netconn handle
-
void
lwgsm_netconn_set_receive_timeout
(lwgsm_netconn_p nc, uint32_t timeout)¶ Set timeout value for receiving data.
When enabled, lwgsm_netconn_receive will only block for up to timeout value and will return if no new data within this time
- Parameters
[in] nc
: Netconn handle[in] timeout
: Timeout in units of milliseconds. Set to0
to disable timeout for lwgsm_netconn_receive function
-
uint32_t
lwgsm_netconn_get_receive_timeout
(lwgsm_netconn_p nc)¶ Get netconn receive timeout value.
- Return
Timeout in units of milliseconds. If value is
0
, timeout is disabled (wait forever)- Parameters
[in] nc
: Netconn handle
-
lwgsmr_t
lwgsm_netconn_write
(lwgsm_netconn_p nc, const void *data, size_t btw)¶ Write data to connection output buffers.
-
lwgsmr_t
lwgsm_netconn_flush
(lwgsm_netconn_p nc)¶ Flush buffered data on netconn TCP/SSL connection.
-
lwgsmr_t
lwgsm_netconn_send
(lwgsm_netconn_p nc, const void *data, size_t btw)¶ Send data on UDP connection to default IP and port.
-
lwgsmr_t
lwgsm_netconn_sendto
(lwgsm_netconn_p nc, const lwgsm_ip_t *ip, lwgsm_port_t port, const void *data, size_t btw)¶ Send data on UDP connection to specific IP and port.
- Note
Use this function in case of UDP type netconn
- Return
lwgsmOK on success, member of lwgsmr_t enumeration otherwise
- Parameters
[in] nc
: Netconn handle used to send[in] ip
: Pointer to IP address[in] port
: Port number used to send data[in] data
: Pointer to data to write[in] btw
: Number of bytes to write
-
typedef struct lwgsm_netconn *
Examples and demos¶
Various examples are provided for fast library evaluation on embedded systems. These are prepared and maintained for 2
platforms, but could be easily extended to more platforms:
WIN32 examples, prepared as Visual Studio Community projects
ARM Cortex-M examples for STM32, prepared as STM32CubeIDE GCC projects
Warning
Library is platform independent and can be used on any platform.
Example architectures¶
There are many platforms available today on a market, however supporting them all would be tough task for single person.
Therefore it has been decided to support (for purpose of examples) 2
platforms only, WIN32 and STM32.
WIN32¶
Examples for WIN32 are prepared as Visual Studio Community projects. You can directly open project in the IDE, compile & debug.
Application opens COM port, set in the low-level driver. External USB to UART converter (FTDI-like device) is necessary in order to connect to GSM device.
Note
GSM device is connected with USB to UART converter only by RX and TX pins.
Device driver is located in /lwgsm/src/system/lwgsm_ll_win32.c
STM32¶
Embedded market is supported by many vendors and STMicroelectronics is, with their STM32 series of microcontrollers, one of the most important players. There are numerous amount of examples and topics related to this architecture.
Examples for STM32 are natively supported with STM32CubeIDE, an official development IDE from STMicroelectronics.
You can run examples on one of official development boards, available in repository examples.
Board name |
GSM settings |
Debug settings |
|||||
---|---|---|---|---|---|---|---|
UART |
MTX |
MRX |
RST |
UART |
MDTX |
MDRX |
|
STM32F429ZI-Nucleo |
USART6 |
PC6 |
PC7 |
PC5 |
USART3 |
PD8 |
PD9 |
Pins to connect with GSM device:
MTX: MCU TX pin, connected to GSM RX pin
MRX: MCU RX pin, connected to GSM TX pin
RST: MCU output pin to control reset state of GSM device
Other pins are for your information and are used for debugging purposes on board.
MDTX: MCU Debug TX pin, connected via on-board ST-Link to PC
MDRX: MCU Debug RX pin, connected via on-board ST-Link to PC
Baudrate is always set to
921600
bauds
Examples list¶
Here is a list of all examples coming with this library.
Tip
Examples are located in /examples/
folder in downloaded package.
Check Download library section to get your package.
Tip
Do not forget to set PIN & PUK codes of your SIM card before running any of examples.
Open /snippets/sim_manager.c
and update pin_code
and puk_code
variables.
Device info¶
Simple example which prints basic device information:
Device Manufacturer
Device Model
Device serial number
Device revision number
MQTT Client API¶
Similar to MQTT Client examples, but it uses separate thread to process events in blocking mode. Application does not use events to process data, rather it uses blocking API to receive packets
Netconn client¶
Netconn client is based on sequential API. It starts connection to server, sends initial request and then waits to receive data.
Processing is in separate thread and fully sequential, no callbacks or events.
Call¶
Call example answers received call. If GSM device supports calls and has microphone/speaker connected to module itself, it can simply communicate over voice.
Call & SMS¶
This example shows how to receive a call and send reply with SMS. When application receives call, it hangs-up immediately and sends back SMS asking caller to send SMS instead.
When application receives SMS, it will send same SMS content back to the sender’s number.
SMS Send receive¶
It demonstrates sending and receiving SMS either in events or using thread processing.