zephyr/subsys/lorawan/services/clock_sync.c
Lingao Meng 302422ad9d everywhere: replace double words
import os
import re

common_words = set([
    'about', 'after', 'all', 'also', 'an', 'and',
     'any', 'are', 'as', 'at',
    'be', 'because', 'but', 'by', 'can', 'come',
    'could', 'day', 'do', 'even',
    'first', 'for', 'get', 'give', 'go', 'has',
    'have', 'he', 'her',
    'him', 'his', 'how', 'I', 'in', 'into', 'it',
    'its', 'just',
    'know', 'like', 'look', 'make', 'man', 'many',
    'me', 'more', 'my', 'new',
    'no', 'not', 'now', 'of', 'one', 'only', 'or',
    'other', 'our', 'out',
    'over', 'people', 'say', 'see', 'she', 'so',
    'some', 'take', 'tell', 'than',
    'their', 'them', 'then', 'there', 'these',
    'they', 'think',
    'this', 'time', 'two', 'up', 'use', 'very',
    'want', 'was', 'way',
    'we', 'well', 'what', 'when', 'which', 'who',
    'will', 'with', 'would',
    'year', 'you', 'your'
])

valid_extensions = set([
    'c', 'h', 'yaml', 'cmake', 'conf', 'txt', 'overlay',
    'rst', 'dtsi',
    'Kconfig', 'dts', 'defconfig', 'yml', 'ld', 'sh', 'py',
    'soc', 'cfg'
])

def filter_repeated_words(text):
    # Split the text into lines
    lines = text.split('\n')

    # Combine lines into a single string with unique separator
    combined_text = '/*sep*/'.join(lines)

    # Replace repeated words within a line
    def replace_within_line(match):
        return match.group(1)

    # Regex for matching repeated words within a line
    within_line_pattern =
	re.compile(r'\b(' +
		'|'.join(map(re.escape, common_words)) +
		r')\b\s+\b\1\b')
    combined_text = within_line_pattern.
		sub(replace_within_line, combined_text)

    # Replace repeated words across line boundaries
    def replace_across_lines(match):
        return match.group(1) + match.group(2)

    # Regex for matching repeated words across line boundaries
    across_lines_pattern = re.
		compile(r'\b(' + '|'.join(
			map(re.escape, common_words)) +
			r')\b(\s*[*\/\n\s]*)\b\1\b')
    combined_text = across_lines_pattern.
		sub(replace_across_lines, combined_text)

    # Split the text back into lines
    filtered_text = combined_text.split('/*sep*/')

    return '\n'.join(filtered_text)

def process_file(file_path):
    with open(file_path, 'r', encoding='utf-8') as file:
        text = file.read()

    new_text = filter_repeated_words(text)

    with open(file_path, 'w', encoding='utf-8') as file:
        file.write(new_text)

def process_directory(directory_path):
    for root, dirs, files in os.walk(directory_path):
        dirs[:] = [d for d in dirs if not d.startswith('.')]
        for file in files:
            # Filter out hidden files
            if file.startswith('.'):
                continue
            file_extension = file.split('.')[-1]
            if
	file_extension in valid_extensions:  # 只处理指定后缀的文件
                file_path = os.path.join(root, file)
                print(f"Processed file: {file_path}")
                process_file(file_path)

directory_to_process = "/home/mi/works/github/zephyrproject/zephyr"
process_directory(directory_to_process)

Signed-off-by: Lingao Meng <menglingao@xiaomi.com>
2024-06-25 06:05:35 -04:00

247 lines
6.7 KiB
C

/*
* Copyright (c) 2022 Martin Jäger <martin@libre.solar>
* Copyright (c) 2022 tado GmbH
*
* Parts of this implementation were inspired by LmhpClockSync.c from the
* LoRaMac-node firmware repository https://github.com/Lora-net/LoRaMac-node
* written by Miguel Luis (Semtech).
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "lorawan_services.h"
#include <LoRaMac.h>
#include <zephyr/kernel.h>
#include <zephyr/lorawan/lorawan.h>
#include <zephyr/logging/log.h>
#include <zephyr/random/random.h>
LOG_MODULE_REGISTER(lorawan_clock_sync, CONFIG_LORAWAN_SERVICES_LOG_LEVEL);
/**
* Version of LoRaWAN Application Layer Clock Synchronization Specification
*
* This implementation only supports TS003-2.0.0, as the previous revision TS003-1.0.0
* requested to temporarily disable ADR and set nb_trans to 1. This causes issues on the
* server side and is not recommended anymore.
*/
#define CLOCK_SYNC_PACKAGE_VERSION 2
/* Maximum length of clock sync answers */
#define MAX_CLOCK_SYNC_ANS_LEN 6
/* Delay between consecutive transmissions of AppTimeReq */
#define CLOCK_RESYNC_DELAY 10
enum clock_sync_commands {
CLOCK_SYNC_CMD_PKG_VERSION = 0x00,
CLOCK_SYNC_CMD_APP_TIME = 0x01,
CLOCK_SYNC_CMD_DEVICE_APP_TIME_PERIODICITY = 0x02,
CLOCK_SYNC_CMD_FORCE_DEVICE_RESYNC = 0x03,
};
struct clock_sync_context {
/** Work item for regular (re-)sync requests (uplink messages) */
struct k_work_delayable resync_work;
/** Continuously incremented token to map clock sync answers and requests */
uint8_t req_token;
/** Number of requested clock sync requests left to be transmitted */
uint8_t nb_transmissions;
/**
* Offset to be added to system uptime to get GPS time (as used by LoRaWAN)
*/
uint32_t time_offset;
/**
* AppTimeReq retransmission interval in seconds
*
* Valid range between 128 (0x80) and 8388608 (0x800000)
*/
uint32_t periodicity;
/** Indication if at least one valid time correction was received */
bool synchronized;
};
static struct clock_sync_context ctx;
/**
* Writes the DeviceTime into the buffer.
*
* @returns number of bytes written or -ENOSPC in case of error
*/
static int clock_sync_serialize_device_time(uint8_t *buf, size_t size)
{
uint32_t device_time = k_uptime_seconds() + ctx.time_offset;
if (size < sizeof(uint32_t)) {
return -ENOSPC;
}
buf[0] = (device_time >> 0) & 0xFF;
buf[1] = (device_time >> 8) & 0xFF;
buf[2] = (device_time >> 16) & 0xFF;
buf[3] = (device_time >> 24) & 0xFF;
return sizeof(uint32_t);
}
static inline k_timeout_t clock_sync_calc_periodicity(void)
{
/* add +-30s jitter to nominal periodicity as required by the spec */
return K_SECONDS(ctx.periodicity - 30 + sys_rand32_get() % 61);
}
static void clock_sync_package_callback(uint8_t port, bool data_pending, int16_t rssi, int8_t snr,
uint8_t len, const uint8_t *rx_buf)
{
uint8_t tx_buf[3 * MAX_CLOCK_SYNC_ANS_LEN];
uint8_t tx_pos = 0;
uint8_t rx_pos = 0;
__ASSERT(port == LORAWAN_PORT_CLOCK_SYNC, "Wrong port %d", port);
while (rx_pos < len) {
uint8_t command_id = rx_buf[rx_pos++];
if (sizeof(tx_buf) - tx_pos < MAX_CLOCK_SYNC_ANS_LEN) {
LOG_ERR("insufficient tx_buf size, some requests discarded");
break;
}
switch (command_id) {
case CLOCK_SYNC_CMD_PKG_VERSION:
tx_buf[tx_pos++] = CLOCK_SYNC_CMD_PKG_VERSION;
tx_buf[tx_pos++] = LORAWAN_PACKAGE_ID_CLOCK_SYNC;
tx_buf[tx_pos++] = CLOCK_SYNC_PACKAGE_VERSION;
LOG_DBG("PackageVersionReq");
break;
case CLOCK_SYNC_CMD_APP_TIME: {
/* answer from application server */
int32_t time_correction;
ctx.nb_transmissions = 0;
time_correction = rx_buf[rx_pos++];
time_correction += rx_buf[rx_pos++] << 8;
time_correction += rx_buf[rx_pos++] << 16;
time_correction += rx_buf[rx_pos++] << 24;
uint8_t token = rx_buf[rx_pos++] & 0x0F;
if (token == ctx.req_token) {
ctx.time_offset += time_correction;
ctx.req_token = (ctx.req_token + 1) % 16;
ctx.synchronized = true;
LOG_DBG("AppTimeAns time_correction %d (token %d)",
time_correction, token);
} else {
LOG_WRN("AppTimeAns with outdated token %d", token);
}
break;
}
case CLOCK_SYNC_CMD_DEVICE_APP_TIME_PERIODICITY: {
uint8_t period = rx_buf[rx_pos++] & 0x0F;
ctx.periodicity = 1U << (period + 7);
tx_buf[tx_pos++] = CLOCK_SYNC_CMD_DEVICE_APP_TIME_PERIODICITY;
tx_buf[tx_pos++] = 0x00; /* Status: OK */
tx_pos += clock_sync_serialize_device_time(tx_buf + tx_pos,
sizeof(tx_buf) - tx_pos);
lorawan_services_reschedule_work(&ctx.resync_work,
clock_sync_calc_periodicity());
LOG_DBG("DeviceAppTimePeriodicityReq period: %u", period);
break;
}
case CLOCK_SYNC_CMD_FORCE_DEVICE_RESYNC: {
uint8_t nb_transmissions = rx_buf[rx_pos++] & 0x07;
if (nb_transmissions != 0) {
ctx.nb_transmissions = nb_transmissions;
lorawan_services_reschedule_work(&ctx.resync_work, K_NO_WAIT);
}
LOG_DBG("ForceDeviceResyncCmd nb_transmissions: %u", nb_transmissions);
break;
}
default:
return;
}
}
if (tx_pos > 0) {
lorawan_services_schedule_uplink(LORAWAN_PORT_CLOCK_SYNC, tx_buf, tx_pos, 0);
}
}
static int clock_sync_app_time_req(void)
{
uint8_t tx_pos = 0;
uint8_t tx_buf[6];
if (lorawan_services_class_c_active() > 0) {
/* avoid disturbing the session and causing potential package loss */
LOG_DBG("AppTimeReq not sent because of active class C session");
return -EBUSY;
}
tx_buf[tx_pos++] = CLOCK_SYNC_CMD_APP_TIME;
tx_pos += clock_sync_serialize_device_time(tx_buf + tx_pos,
sizeof(tx_buf) - tx_pos);
/* Param: AnsRequired = 0 | TokenReq */
tx_buf[tx_pos++] = ctx.req_token;
LOG_DBG("Sending clock sync AppTimeReq (token %d)", ctx.req_token);
lorawan_services_schedule_uplink(LORAWAN_PORT_CLOCK_SYNC, tx_buf, tx_pos, 0);
return 0;
}
static void clock_sync_resync_handler(struct k_work *work)
{
clock_sync_app_time_req();
if (ctx.nb_transmissions > 0) {
ctx.nb_transmissions--;
lorawan_services_reschedule_work(&ctx.resync_work, K_SECONDS(CLOCK_RESYNC_DELAY));
} else {
lorawan_services_reschedule_work(&ctx.resync_work,
clock_sync_calc_periodicity());
}
}
int lorawan_clock_sync_get(uint32_t *gps_time)
{
__ASSERT(gps_time != NULL, "gps_time parameter is required");
if (ctx.synchronized) {
*gps_time = k_uptime_seconds() + ctx.time_offset;
return 0;
} else {
return -EAGAIN;
}
}
static struct lorawan_downlink_cb downlink_cb = {
.port = (uint8_t)LORAWAN_PORT_CLOCK_SYNC,
.cb = clock_sync_package_callback
};
int lorawan_clock_sync_run(void)
{
ctx.periodicity = CONFIG_LORAWAN_APP_CLOCK_SYNC_PERIODICITY;
lorawan_register_downlink_callback(&downlink_cb);
k_work_init_delayable(&ctx.resync_work, clock_sync_resync_handler);
lorawan_services_reschedule_work(&ctx.resync_work, K_NO_WAIT);
return 0;
}