перепись кода кирилла под пк от нервосетки, скомпилися, запустился, но ещё не проверен
This commit is contained in:
parent
2bdf5fd4fd
commit
10bcb00929
16
clang_client/.vscode/launch.json
vendored
Normal file
16
clang_client/.vscode/launch.json
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Run sim808_app",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/sim808_app",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "gdb",
|
||||
"stopAtEntry": false,
|
||||
"preLaunchTask": "build"
|
||||
}
|
||||
]
|
||||
}
|
||||
3
clang_client/.vscode/settings.json
vendored
Normal file
3
clang_client/.vscode/settings.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"idf.pythonInstallPath": "/usr/bin/python3"
|
||||
}
|
||||
21
clang_client/.vscode/tasks.json
vendored
Normal file
21
clang_client/.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "build",
|
||||
"type": "shell",
|
||||
"command": "gcc",
|
||||
"args": [
|
||||
"-std=c99",
|
||||
"-O2",
|
||||
"-g",
|
||||
"main.c",
|
||||
"Drivers/sim808.c",
|
||||
"-o",
|
||||
"sim808_app"
|
||||
],
|
||||
"group": "build",
|
||||
"problemMatcher": ["$gcc"]
|
||||
}
|
||||
]
|
||||
}
|
||||
321
clang_client/Drivers/sim808.c
Normal file
321
clang_client/Drivers/sim808.c
Normal file
@ -0,0 +1,321 @@
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
#include "sim808.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
/* -------------------- Внутреннее состояние (аналог глобалей из прошивки) -------------------- */
|
||||
|
||||
static int g_sock = -1;
|
||||
|
||||
static char* g_packet_buf = NULL;
|
||||
static size_t g_packet_len = 0;
|
||||
static size_t g_packet_cap = 0;
|
||||
|
||||
static const size_t PACKET_INIT_CAP = 4096; /* стартовая ёмкость буфера */
|
||||
static const size_t PACKET_MAX_CAP = (size_t)32 * 1024 * 1024; /* ограничение от дурака: 32 МБ */
|
||||
|
||||
/* -------------------- Утилиты -------------------- */
|
||||
|
||||
static sim800_stat_t ensure_capacity(size_t need_extra)
|
||||
{
|
||||
if (g_packet_len + need_extra <= g_packet_cap)
|
||||
return SIM808_OK;
|
||||
|
||||
size_t new_cap = g_packet_cap ? g_packet_cap : PACKET_INIT_CAP;
|
||||
while (new_cap < g_packet_len + need_extra) {
|
||||
if (new_cap > PACKET_MAX_CAP / 2) { /* защита от переполнения и чрезмерного роста */
|
||||
new_cap = PACKET_MAX_CAP;
|
||||
break;
|
||||
}
|
||||
new_cap *= 2;
|
||||
}
|
||||
if (new_cap < g_packet_len + need_extra)
|
||||
return SIM808_ERR;
|
||||
|
||||
char* p = (char*)realloc(g_packet_buf, new_cap);
|
||||
if (!p) return SIM808_ERR;
|
||||
|
||||
g_packet_buf = p;
|
||||
g_packet_cap = new_cap;
|
||||
return SIM808_OK;
|
||||
}
|
||||
|
||||
static void packet_reset_buffer(void)
|
||||
{
|
||||
free(g_packet_buf);
|
||||
g_packet_buf = NULL;
|
||||
g_packet_len = 0;
|
||||
g_packet_cap = 0;
|
||||
}
|
||||
|
||||
/* Получить строковый IP из sockaddr (локальный/удалённый) */
|
||||
static sim800_stat_t sockaddr_to_ipstr(const struct sockaddr* sa, char* out, size_t outsz)
|
||||
{
|
||||
if (!sa || !out || outsz == 0) return SIM808_ERR;
|
||||
|
||||
void* addr_ptr = NULL;
|
||||
if (sa->sa_family == AF_INET) {
|
||||
addr_ptr = &((struct sockaddr_in*)sa)->sin_addr;
|
||||
} else if (sa->sa_family == AF_INET6) {
|
||||
addr_ptr = &((struct sockaddr_in6*)sa)->sin6_addr;
|
||||
} else {
|
||||
return SIM808_ERR;
|
||||
}
|
||||
|
||||
const char* r = inet_ntop(sa->sa_family, addr_ptr, out, (socklen_t)outsz);
|
||||
return (r ? SIM808_OK : SIM808_ERR);
|
||||
}
|
||||
|
||||
/* -------------------- Реализация API -------------------- */
|
||||
|
||||
sim800_stat_t sim808_init(void)
|
||||
{
|
||||
/* На ПК ничего инициализировать не нужно */
|
||||
return SIM808_OK;
|
||||
}
|
||||
|
||||
sim800_stat_t sim808_open_connection(char* apn, char* host, char* port, char* self_ip)
|
||||
{
|
||||
(void)apn; /* на ПК APN не используется */
|
||||
|
||||
/* Если сокет уже открыт — закроем */
|
||||
if (g_sock >= 0) {
|
||||
close(g_sock);
|
||||
g_sock = -1;
|
||||
}
|
||||
|
||||
struct addrinfo hints;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_family = AF_UNSPEC; /* IPv4 или IPv6 */
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
|
||||
struct addrinfo* res = NULL;
|
||||
int gai = getaddrinfo(host, port, &hints, &res);
|
||||
if (gai != 0 || !res) {
|
||||
return SIM808_ERR;
|
||||
}
|
||||
|
||||
int sockfd = -1;
|
||||
struct addrinfo* it = res;
|
||||
for (; it; it = it->ai_next) {
|
||||
sockfd = (int)socket(it->ai_family, it->ai_socktype, it->ai_protocol);
|
||||
if (sockfd < 0) continue;
|
||||
|
||||
/* Можно поставить таймауты (опционально) */
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 10;
|
||||
tv.tv_usec = 0;
|
||||
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
|
||||
setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
|
||||
|
||||
if (connect(sockfd, it->ai_addr, (socklen_t)it->ai_addrlen) == 0) {
|
||||
g_sock = sockfd;
|
||||
break;
|
||||
}
|
||||
close(sockfd);
|
||||
sockfd = -1;
|
||||
}
|
||||
freeaddrinfo(res);
|
||||
|
||||
if (g_sock < 0) return SIM808_ERR;
|
||||
|
||||
/* По запросу — вернуть локальный IP интерфейса, через который установилось соединение */
|
||||
if (self_ip) {
|
||||
struct sockaddr_storage sa_local;
|
||||
socklen_t slen = (socklen_t)sizeof(sa_local);
|
||||
if (getsockname(g_sock, (struct sockaddr*)&sa_local, &slen) == 0) {
|
||||
if (sockaddr_to_ipstr((struct sockaddr*)&sa_local, self_ip, 64) != SIM808_OK) {
|
||||
/* если не смогли — просто оставим как есть */
|
||||
self_ip[0] = '\0';
|
||||
}
|
||||
} else {
|
||||
self_ip[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
return SIM808_OK;
|
||||
}
|
||||
|
||||
sim800_stat_t sim808_close_connection(void)
|
||||
{
|
||||
if (g_sock >= 0) {
|
||||
close(g_sock);
|
||||
g_sock = -1;
|
||||
}
|
||||
return SIM808_OK;
|
||||
}
|
||||
|
||||
sim800_stat_t packet_start(void)
|
||||
{
|
||||
packet_reset_buffer();
|
||||
/* выделим стартовую ёмкость сразу, чтобы меньше реаллокаций */
|
||||
g_packet_buf = (char*)malloc(PACKET_INIT_CAP);
|
||||
if (!g_packet_buf) {
|
||||
g_packet_cap = 0;
|
||||
return SIM808_ERR;
|
||||
}
|
||||
g_packet_cap = PACKET_INIT_CAP;
|
||||
g_packet_len = 0;
|
||||
return SIM808_OK;
|
||||
}
|
||||
|
||||
sim800_stat_t packet_data(char* msg)
|
||||
{
|
||||
if (!msg) return SIM808_ERR;
|
||||
if (g_sock < 0) return SIM808_ERR; /* нет соединения */
|
||||
if (!g_packet_buf && packet_start() != SIM808_OK) /* безопасности ради */
|
||||
return SIM808_ERR;
|
||||
|
||||
size_t n = strlen(msg); /* как и в вашей версии — работаем со строками */
|
||||
if (n == 0) return SIM808_OK;
|
||||
|
||||
if (ensure_capacity(n) != SIM808_OK)
|
||||
return SIM808_ERR;
|
||||
|
||||
memcpy(g_packet_buf + g_packet_len, msg, n);
|
||||
g_packet_len += n;
|
||||
return SIM808_OK;
|
||||
}
|
||||
|
||||
sim800_stat_t packet_end(void)
|
||||
{
|
||||
if (g_sock < 0) {
|
||||
packet_reset_buffer();
|
||||
return SIM808_ERR;
|
||||
}
|
||||
size_t total = g_packet_len;
|
||||
size_t sent = 0;
|
||||
|
||||
while (sent < total) {
|
||||
ssize_t r = send(g_sock, g_packet_buf + sent, total - sent, 0);
|
||||
if (r < 0) {
|
||||
if (errno == EINTR) continue;
|
||||
packet_reset_buffer();
|
||||
return SIM808_ERR;
|
||||
}
|
||||
if (r == 0) { /* неожиданное закрытие */
|
||||
packet_reset_buffer();
|
||||
return SIM808_ERR;
|
||||
}
|
||||
sent += (size_t)r;
|
||||
}
|
||||
|
||||
packet_reset_buffer();
|
||||
return SIM808_OK;
|
||||
}
|
||||
|
||||
sim800_stat_t sim808_send_msg(char* msg)
|
||||
{
|
||||
sim800_stat_t ret = SIM808_OK;
|
||||
ret = packet_start();
|
||||
if (ret != SIM808_OK) return ret;
|
||||
ret = packet_data(msg);
|
||||
if (ret != SIM808_OK) { packet_reset_buffer(); return ret; }
|
||||
ret = packet_end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* -------------------- Заглушки “модемных” функций -------------------- */
|
||||
|
||||
sim800_stat_t reset(void) { return SIM808_OK; }
|
||||
sim800_stat_t echo_off(void) { return SIM808_OK; }
|
||||
sim800_stat_t check_sim_connection(void) { return SIM808_OK; }
|
||||
sim800_stat_t chech_sim_card(void) { return SIM808_OK; }
|
||||
sim800_stat_t check_network_registration(void) { return SIM808_OK; }
|
||||
sim800_stat_t check_gprs_registration(void) { return SIM808_OK; }
|
||||
sim800_stat_t close_ip_sessions(void) { return SIM808_OK; }
|
||||
sim800_stat_t set_single_ip_mode(void) { return SIM808_OK; }
|
||||
sim800_stat_t set_apn(char* apn, char* user, char* pass) { (void)apn; (void)user; (void)pass; return SIM808_OK; }
|
||||
sim800_stat_t start_gprs(void) { return SIM808_OK; }
|
||||
|
||||
/* Возвращаем локальный IP уже открытого сокета */
|
||||
sim800_stat_t get_ip(char* ip_ret)
|
||||
{
|
||||
if (!ip_ret) return SIM808_ERR;
|
||||
if (g_sock < 0) { ip_ret[0] = '\0'; return SIM808_ERR; }
|
||||
|
||||
struct sockaddr_storage sa_local;
|
||||
socklen_t slen = (socklen_t)sizeof(sa_local);
|
||||
if (getsockname(g_sock, (struct sockaddr*)&sa_local, &slen) != 0) {
|
||||
ip_ret[0] = '\0';
|
||||
return SIM808_ERR;
|
||||
}
|
||||
return sockaddr_to_ipstr((struct sockaddr*)&sa_local, ip_ret, 64);
|
||||
}
|
||||
|
||||
/* Непосредственные TCP-обёртки (оставлены для совместимости) */
|
||||
sim800_stat_t open_tcp(char* host, char* port)
|
||||
{
|
||||
return sim808_open_connection(NULL, host, port, NULL);
|
||||
}
|
||||
sim800_stat_t close_tcp(void)
|
||||
{
|
||||
return sim808_close_connection();
|
||||
}
|
||||
|
||||
/* -------------------- Заглушки обработчиков/таймеров -------------------- */
|
||||
|
||||
void sim808_gprs_usart_handler(void) { /* на ПК не используется */ }
|
||||
void sim808_timeout_processing(void) { /* на ПК не используется */ }
|
||||
|
||||
/* -------------------- Демонстрационный стейт-машин (как в вашем исходнике) -------------------- */
|
||||
|
||||
static unsigned char self_ip_buf[64] = {0};
|
||||
|
||||
static unsigned char cmd = 0;
|
||||
enum {
|
||||
CMD_NONE = 0,
|
||||
CMD_SIM808_OPEN_CONNECTION,
|
||||
CMD_SIM808_SEND_SMG,
|
||||
CMD_SIM808_CLOSE_CONNECTION,
|
||||
};
|
||||
|
||||
static sim800_stat_t conn_open = SIM808_ERR;
|
||||
static sim800_stat_t conn_clos = SIM808_ERR;
|
||||
static sim800_stat_t msg_sent = SIM808_ERR;
|
||||
|
||||
void sim808_demo_send(void)
|
||||
{
|
||||
switch (cmd)
|
||||
{
|
||||
case CMD_SIM808_OPEN_CONNECTION:
|
||||
cmd = CMD_NONE;
|
||||
conn_open = SIM808_ERR;
|
||||
conn_open = sim808_open_connection(
|
||||
"unused-apn", /* игнорируется */
|
||||
(char*)"212.193.61.100", /* или домен */
|
||||
(char*)"5000",
|
||||
(char*)self_ip_buf /* вернём локальный IP интерфейса */
|
||||
);
|
||||
break;
|
||||
|
||||
case CMD_SIM808_SEND_SMG:
|
||||
cmd = CMD_NONE;
|
||||
msg_sent = SIM808_ERR;
|
||||
msg_sent = sim808_send_msg("biba");
|
||||
break;
|
||||
|
||||
case CMD_SIM808_CLOSE_CONNECTION:
|
||||
cmd = CMD_NONE;
|
||||
conn_clos = SIM808_ERR;
|
||||
conn_clos = sim808_close_connection();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
41
clang_client/Drivers/sim808.h
Normal file
41
clang_client/Drivers/sim808.h
Normal file
@ -0,0 +1,41 @@
|
||||
#ifndef SRC_DRIVERS_SIM808_H_
|
||||
#define SRC_DRIVERS_SIM808_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SIM808_OK = 0,
|
||||
SIM808_ERR = -1
|
||||
} sim800_stat_t;
|
||||
|
||||
sim800_stat_t sim808_init(void);
|
||||
sim800_stat_t sim808_open_connection(char* apn, char* host, char* port, char* self_ip);
|
||||
sim800_stat_t sim808_close_connection(void);
|
||||
|
||||
/* Пакетная отправка: start → (data)* → end */
|
||||
sim800_stat_t packet_start(void);
|
||||
sim800_stat_t packet_data(char* msg); /* добавляет строку (strlen), бинарные нули не поддерживаются */
|
||||
sim800_stat_t packet_end(void); /* отправляет накопленное */
|
||||
|
||||
sim800_stat_t reset(void); /* заглушка */
|
||||
sim800_stat_t echo_off(void); /* заглушка */
|
||||
sim800_stat_t check_sim_connection(void); /* заглушка */
|
||||
sim800_stat_t chech_sim_card(void); /* заглушка */
|
||||
sim800_stat_t check_network_registration(void); /* заглушка */
|
||||
sim800_stat_t check_gprs_registration(void); /* заглушка */
|
||||
sim800_stat_t close_ip_sessions(void); /* заглушка */
|
||||
sim800_stat_t set_single_ip_mode(void); /* заглушка */
|
||||
sim800_stat_t set_apn(char* apn, char* username, char* password); /* заглушка */
|
||||
sim800_stat_t start_gprs(void); /* заглушка */
|
||||
sim800_stat_t get_ip(char* ip_ret); /* вернёт локальный IP подключенного сокета (если есть) */
|
||||
sim800_stat_t open_tcp(char* host, char* port);
|
||||
sim800_stat_t close_tcp(void);
|
||||
|
||||
void sim808_gprs_usart_handler(void); /* заглушка */
|
||||
void sim808_timeout_processing(void); /* заглушка */
|
||||
void sim808_demo_send(void); /* демонстрационная машина состояний — как в исходнике */
|
||||
|
||||
sim800_stat_t sim808_send_msg(char* msg); /* удобная обёртка */
|
||||
|
||||
#endif /* SRC_DRIVERS_SIM808_H_ */
|
||||
15
clang_client/main.c
Normal file
15
clang_client/main.c
Normal file
@ -0,0 +1,15 @@
|
||||
#include "Drivers/sim808.h"
|
||||
|
||||
sim800_stat_t sim808_init_ok = SIM808_ERR;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
sim808_init_ok = sim808_init();
|
||||
|
||||
while (1)
|
||||
{
|
||||
sim808_demo_send();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user