mirror of
https://github.com/estkme-group/lpac
synced 2025-08-18 10:03:02 +02:00
133 lines
3.8 KiB
C
133 lines
3.8 KiB
C
#include "at_cmd.h"
|
|
|
|
#include <lpac/utils.h>
|
|
|
|
#include <dirent.h>
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
struct at_userdata {
|
|
char *default_device;
|
|
FILE *fuart;
|
|
char *buffer;
|
|
};
|
|
|
|
static int enumerate_serial_device_for_linux(cJSON *devices) {
|
|
const char *dir_path = "/dev/serial/by-id";
|
|
DIR *dir = opendir(dir_path);
|
|
if (dir == NULL)
|
|
return -1;
|
|
struct dirent *entry;
|
|
while ((entry = readdir(dir)) != NULL) {
|
|
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
|
|
continue;
|
|
}
|
|
|
|
const size_t path_len = strlen(dir_path) + 1 /* SEP */ + strlen(entry->d_name) + 1 /* NUL */;
|
|
_cleanup_free_ char *full_path = malloc(path_len);
|
|
snprintf(full_path, path_len, "%s/%s", dir_path, entry->d_name);
|
|
|
|
cJSON *device = cJSON_CreateObject();
|
|
cJSON_AddStringToObject(device, "env", full_path);
|
|
cJSON_AddStringToObject(device, "name", entry->d_name);
|
|
cJSON_AddItemToArray(devices, device);
|
|
}
|
|
closedir(dir);
|
|
return 0;
|
|
}
|
|
|
|
#ifdef __linux__
|
|
int (*enumerate_serial_device)(cJSON *) = enumerate_serial_device_for_linux;
|
|
#else
|
|
int (*enumerate_serial_device)(cJSON *) = NULL;
|
|
#endif
|
|
|
|
char *get_at_default_device(struct at_userdata *userdata) { return userdata->default_device; }
|
|
|
|
int at_write_command(struct at_userdata *userdata, const char *command) { return fputs(command, userdata->fuart); }
|
|
|
|
int at_expect(struct at_userdata *userdata, char **response, const char *expected) {
|
|
FILE *fuart = userdata->fuart;
|
|
char *buffer = userdata->buffer;
|
|
|
|
memset(buffer, 0, AT_BUFFER_SIZE);
|
|
|
|
if (response)
|
|
*response = NULL;
|
|
|
|
while (true) {
|
|
if (fgets(buffer, AT_BUFFER_SIZE, fuart) == NULL) {
|
|
return -1;
|
|
}
|
|
buffer[strcspn(buffer, "\r\n")] = 0;
|
|
if (getenv_or_default(ENV_AT_DEBUG, (bool)false))
|
|
printf("AT_DEBUG_RX: %s\n", buffer);
|
|
|
|
if (strcmp(buffer, "ERROR") == 0)
|
|
return -1;
|
|
if (strcmp(buffer, "OK") == 0)
|
|
return 0;
|
|
|
|
if (expected != NULL && strncmp(buffer, expected, strlen(expected)) == 0) {
|
|
if (response == NULL || *response != NULL)
|
|
continue;
|
|
*response = strdup(buffer + strlen(expected));
|
|
}
|
|
}
|
|
}
|
|
|
|
int at_device_open(struct at_userdata *userdata, const char *device_name) {
|
|
if (userdata->buffer != NULL || userdata->fuart != NULL) {
|
|
at_device_close(userdata);
|
|
}
|
|
|
|
userdata->buffer = calloc(AT_BUFFER_SIZE, 1);
|
|
if (userdata->buffer == NULL) {
|
|
fprintf(stderr, "Error allocating buffer\n");
|
|
return -1;
|
|
}
|
|
userdata->fuart = fopen(device_name, "r+");
|
|
if (userdata->fuart == NULL) {
|
|
fprintf(stderr, "Failed to open device: %s\n", device_name);
|
|
free(userdata->buffer);
|
|
userdata->buffer = NULL;
|
|
return -1;
|
|
}
|
|
setbuf(userdata->fuart, NULL);
|
|
return 0;
|
|
}
|
|
|
|
int at_device_close(struct at_userdata *userdata) {
|
|
if (userdata->fuart != NULL) {
|
|
fclose(userdata->fuart);
|
|
userdata->fuart = NULL;
|
|
}
|
|
if (userdata->buffer != NULL) {
|
|
free(userdata->buffer);
|
|
userdata->buffer = NULL;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int at_setup_userdata(struct at_userdata **userdata) {
|
|
if (userdata == NULL)
|
|
return -1;
|
|
*userdata = malloc(sizeof(struct at_userdata));
|
|
if (*userdata == NULL)
|
|
return -1;
|
|
memset(*userdata, 0, sizeof(struct at_userdata));
|
|
(*userdata)->default_device = "/dev/ttyUSB0";
|
|
(*userdata)->fuart = NULL;
|
|
(*userdata)->buffer = NULL;
|
|
return 0;
|
|
}
|
|
|
|
void at_cleanup_userdata(struct at_userdata **userdata) {
|
|
if (userdata == NULL || *userdata == NULL)
|
|
return;
|
|
at_device_close(*userdata);
|
|
free(*userdata);
|
|
*userdata = NULL;
|
|
}
|