新增美团批量生产导入代码

This commit is contained in:
zzh 2026-01-13 15:25:10 +08:00
parent 4c50a1d163
commit 07f6927fec
3 changed files with 631 additions and 3 deletions

View File

@ -9,9 +9,9 @@
SHELL := /bin/bash
COMPILE_SH ?= /home/hyx/work/dev_doc/ap05_dev_gaiban/APP_AP05_1.1.22_tuxi_shengchan/compile.sh
SRC := update_mac_pdd.c
TARGET_ARM64 := update_mac_pdd
TARGET_NATIVE := update_mac_pdd_native
SRC := update_mac_mt.c
TARGET_ARM64 := update_mac_mt
TARGET_NATIVE := update_mac_mt_native
# Allow overriding CFLAGS via environment
CFLAGS ?= -O2 -Wall -I/home/hyx/work/write_mac_tool/hiredis

BIN
update_mac_mt Executable file

Binary file not shown.

628
update_mac_mt.c Normal file
View File

@ -0,0 +1,628 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <errno.h>
#include <stdarg.h>
#include <fcntl.h>
#include <linux/input.h>
#include <poll.h>
#include <pthread.h>
#include <time.h>
#include <sys/wait.h>
#include "hiredis.h"
// 黄灯控制相关变量
static volatile int led_running = 0;
static pthread_t led_thread;
// 黄灯控制函数声明
static void gpio_init_yellow(void);
static void* led_fast_blink_thread(void* arg);
static void start_yellow_fast_blink(void);
static void stop_yellow_blink(void);
static void set_yellow_off(void);
static void to_upper_str(char* s) {
for (; *s; ++s) *s = (char)toupper((unsigned char)*s);
}
// 提取批次号(支持 batch=XXXX / Batch:XXXX / 扫码包含"D"+14位数字
static int extract_batch(const char* input, char* out_batch, size_t out_size) {
if (!input || !out_batch || out_size < 16) return -1;
size_t n = strlen(input);
// 主匹配:任意位置出现 'D' 或 'd' 后跟 14 位数字
for (size_t i = 0; i + 15 <= n; ++i) {
char c = input[i];
if (c == 'M' || c == 'm') {
int ok = 1;
for (int k = 1; k <= 14; ++k) {
char d = input[i + k];
if (d < '0' || d > '9') { ok = 0; break; }
}
if (ok) {
out_batch[0] = 'M';
memcpy(out_batch + 1, input + i + 1, 14);
out_batch[15] = '\0';
return 0;
}
}
}
// 回退按键名解析batch/Batch/BATCH/批次)
const char* keys[] = {"batch", "Batch", "BATCH", "批次"};
for (size_t i = 0; i < sizeof(keys)/sizeof(keys[0]); ++i) {
const char* p = strstr(input, keys[i]);
if (!p) continue;
// 跳过键名后的分隔符
p += strlen(keys[i]);
while (*p == ' ' || *p == '=' || *p == ':' || (unsigned char)*p == 0xEF) {
if ((unsigned char)*p == 0xEF) { p++; if ((unsigned char)*p == 0xBC) { p++; if ((unsigned char)*p == 0x9A) { p++; } } }
else { p++; }
}
// 读取字母数字序列作为批次号
size_t j = 0;
while (*p && j < out_size - 1) {
if ((*p >= '0' && *p <= '9') || (*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') || *p == '_' || *p == '-') {
out_batch[j++] = *p++;
} else {
break;
}
}
out_batch[j] = '\0';
if (j > 0) {
// 规范化:若形如 d+14位数字转为大写D
if (j >= 15 && (out_batch[0] == 'm' || out_batch[0] == 'M')) {
int ok2 = 1;
for (int k = 1; k <= 14; ++k) {
char d = out_batch[k];
if (d < '0' || d > '9') { ok2 = 0; break; }
}
if (ok2) out_batch[0] = 'M';
}
return 0;
}
}
return -1;
}
// 通过redis-cli查询批次映射得到MAC和密钥
static int redis_query_device_info(const char* host_opt, const char* port_opt, const char* db_opt,
const char* pool_opt, const char* batch,
char* out_mac, size_t mac_size,
char* out_secret, size_t secret_size) {
if (!batch || !out_mac || mac_size < 18 || !out_secret || secret_size < 64) return -1;
const char* host = host_opt ? host_opt : (getenv("REDIS_HOST") ? getenv("REDIS_HOST") : "180.163.74.83");
int port = port_opt ? atoi(port_opt) : (getenv("REDIS_PORT") ? atoi(getenv("REDIS_PORT")) : 6379);
int db = db_opt ? atoi(db_opt) : (getenv("REDIS_DB") ? atoi(getenv("REDIS_DB")) : 0);
const char* pool = pool_opt ? pool_opt : (getenv("REDIS_POOL") ? getenv("REDIS_POOL") : "batch_sn_mapping_mt");
const char* auth = getenv("REDIS_AUTH");
if (!auth || !*auth) auth = "Zzh08165511";
fprintf(stderr, "[redis] connect host=%s port=%d db=%d pool=%s batch=%s\n", host, port, db, pool, batch);
struct timeval tv; tv.tv_sec = 3; tv.tv_usec = 0;
redisContext* c = redisConnectWithTimeout(host, port, tv);
if (!c || c->err) {
fprintf(stderr, "[redis] connect error: %s\n", c ? c->errstr : "unknown");
if (c) redisFree(c);
return -1;
}
if (auth && *auth) {
redisReply* ra = (redisReply*)redisCommand(c, "AUTH %s", auth);
if (!ra || (ra->type == REDIS_REPLY_ERROR)) {
fprintf(stderr, "[redis] AUTH error: %s\n", ra && ra->str ? ra->str : "no-reply");
if (ra) freeReplyObject(ra);
redisFree(c);
return -1;
}
fprintf(stderr, "[redis] AUTH ok\n");
freeReplyObject(ra);
}
if (db > 0) {
redisReply* rs = (redisReply*)redisCommand(c, "SELECT %d", db);
if (!rs || (rs->type == REDIS_REPLY_ERROR)) {
fprintf(stderr, "[redis] SELECT %d error: %s\n", db, rs && rs->str ? rs->str : "no-reply");
if (rs) freeReplyObject(rs);
redisFree(c);
return -1;
}
fprintf(stderr, "[redis] SELECT %d ok\n", db);
freeReplyObject(rs);
}
// 尝试 HGET pool batch
redisReply* r = (redisReply*)redisCommand(c, "HGET %s %s", pool, batch);
if (r) {
fprintf(stderr, "[redis] HGET %s %s -> type=%d len=%ld\n", pool, batch, r->type, (long)(r->type==REDIS_REPLY_STRING ? r->len : 0));
if (r->type == REDIS_REPLY_STRING && r->str && r->len > 0) {
fprintf(stderr, "[redis] HGET value: %.*s\n", (int)((r->len>128)?128:r->len), r->str);
// 解析格式: "90A9F73002CD:kapoePfwbQ2tFkeRpR3Nut"
char* colon = strchr(r->str, ':');
if (colon) {
// 提取MAC部分12个字符
size_t mac_len = colon - r->str;
if (mac_len == 12) {
// 格式化为MAC地址格式 XX:XX:XX:XX:XX:XX
snprintf(out_mac, mac_size, "%c%c:%c%c:%c%c:%c%c:%c%c:%c%c",
r->str[0], r->str[1], r->str[2], r->str[3],
r->str[4], r->str[5], r->str[6], r->str[7],
r->str[8], r->str[9], r->str[10], r->str[11]);
to_upper_str(out_mac);
// 提取密钥部分(冒号后面的内容)
strncpy(out_secret, colon + 1, secret_size - 1);
out_secret[secret_size - 1] = '\0';
fprintf(stderr, "[redis] Parsed MAC: %s, Secret: %s\n", out_mac, out_secret);
freeReplyObject(r);
redisFree(c);
return 0;
}
}
}
freeReplyObject(r);
} else {
fprintf(stderr, "[redis] HGET no-reply\n");
}
fprintf(stderr, "[redis] not found or value not parsable\n");
redisFree(c);
return -1;
}
// 审计在Redis记录每次使用的MAC、批次与时间
static int redis_audit_log(const char* host_opt, const char* port_opt, const char* db_opt,
const char* audit_key_opt, const char* batch, const char* mac, const char* note_opt) {
if (!batch || !*batch || !mac || !*mac) return -1;
const char* host = host_opt ? host_opt : (getenv("REDIS_HOST") ? getenv("REDIS_HOST") : "180.163.74.83");
int port = port_opt ? atoi(port_opt) : (getenv("REDIS_PORT") ? atoi(getenv("REDIS_PORT")) : 6379);
int db = db_opt ? atoi(db_opt) : (getenv("REDIS_DB") ? atoi(getenv("REDIS_DB")) : 0);
const char* auth = getenv("REDIS_AUTH");
if (!auth || !*auth) auth = "Zzh08165511";
const char* audit_key = audit_key_opt ? audit_key_opt : (getenv("REDIS_AUDIT_KEY") ? getenv("REDIS_AUDIT_KEY") : "mac_batch_audit_mt");
struct timeval tv; tv.tv_sec = 3; tv.tv_usec = 0;
redisContext* c = redisConnectWithTimeout(host, port, tv);
if (!c || c->err) {
fprintf(stderr, "[redis-audit] connect error: %s\n", c ? c->errstr : "unknown");
if (c) redisFree(c);
return -1;
}
if (auth && *auth) {
redisReply* ra = (redisReply*)redisCommand(c, "AUTH %s", auth);
if (!ra || (ra->type == REDIS_REPLY_ERROR)) {
fprintf(stderr, "[redis-audit] AUTH error: %s\n", ra && ra->str ? ra->str : "no-reply");
if (ra) freeReplyObject(ra);
redisFree(c);
return -1;
}
freeReplyObject(ra);
}
if (db > 0) {
redisReply* rs = (redisReply*)redisCommand(c, "SELECT %d", db);
if (!rs || (rs->type == REDIS_REPLY_ERROR)) {
fprintf(stderr, "[redis-audit] SELECT %d error: %s\n", db, rs && rs->str ? rs->str : "no-reply");
if (rs) freeReplyObject(rs);
redisFree(c);
return -1;
}
freeReplyObject(rs);
}
// 优先使用 Redis 服务器时间,避免设备本地时间不准
long long sv_secs = -1;
{
redisReply* tr = (redisReply*)redisCommand(c, "TIME");
if (tr && tr->type == REDIS_REPLY_ARRAY && tr->elements >= 2 &&
tr->element[0] && tr->element[0]->str) {
sv_secs = atoll(tr->element[0]->str);
} else {
fprintf(stderr, "[redis-audit] TIME failed, fallback to local time\n");
}
if (tr) freeReplyObject(tr);
}
time_t base = (sv_secs > 0) ? (time_t)sv_secs : time(NULL);
// 中国时区(+08:00不依赖设备TZ格式为 YYYY-MM-DD HH:MM:SS
time_t base_cn = base + 8 * 3600;
struct tm tm_sv_cn; gmtime_r(&base_cn, &tm_sv_cn);
char ts_cn[24];
strftime(ts_cn, sizeof(ts_cn), "%Y-%m-%d %H:%M:%S", &tm_sv_cn);
char val[320];
snprintf(val, sizeof(val), "ts_cn=%s batch=%s mac=%s%s%s", ts_cn, batch, mac,
(note_opt && *note_opt) ? " note=" : "",
(note_opt && *note_opt) ? note_opt : "");
// 写入总审计列表
redisReply* r = (redisReply*)redisCommand(c, "LPUSH %s %s", audit_key, val);
if (!r || r->type == REDIS_REPLY_ERROR) {
fprintf(stderr, "[redis-audit] LPUSH %s failed: %s\n", audit_key, r && r->str ? r->str : "no-reply");
if (r) freeReplyObject(r);
redisFree(c);
return -1;
}
freeReplyObject(r);
// 同时按批次维度记录key为 <audit_key>:<batch>
char batch_key[128];
snprintf(batch_key, sizeof(batch_key), "%s:%s", audit_key, batch);
r = (redisReply*)redisCommand(c, "LPUSH %s %s", batch_key, val);
if (!r || r->type == REDIS_REPLY_ERROR) {
fprintf(stderr, "[redis-audit] LPUSH %s failed: %s\n", batch_key, r && r->str ? r->str : "no-reply");
if (r) freeReplyObject(r);
redisFree(c);
return -1;
}
freeReplyObject(r);
redisFree(c);
fprintf(stderr, "[redis-audit] logged: %s | %s\n", batch, mac);
return 0;
}
// 读取interfaces文件中的MAC地址
static int get_mac_from_interfaces(const char* interfaces_path, char* out_mac, size_t out_size) {
FILE* f = fopen(interfaces_path, "r");
if (!f) return -1;
char line[256];
while (fgets(line, sizeof(line), f)) {
if (strstr(line, "hwaddress ether")) {
char* mac_start = strstr(line, "ether");
if (mac_start) {
mac_start += 6; // 跳过"ether "
char* mac_end = strchr(mac_start, '\n');
if (mac_end) {
size_t len = mac_end - mac_start;
if (len > 0 && len < out_size) {
strncpy(out_mac, mac_start, len);
out_mac[len] = '\0';
// 去除可能的空格
char* space = strchr(out_mac, ' ');
if (space) *space = '\0';
fclose(f);
return 0;
}
}
}
}
}
fclose(f);
return -1;
}
static int write_file(const char* path, const char* buf, size_t len) {
FILE* f = fopen(path, "wb");
if (!f) return -1;
size_t n = fwrite(buf, 1, len, f);
// 确保数据写入到内核缓冲区
fflush(f);
int rc = 0;
// 将数据与元数据刷新到磁盘,避免重启丢失
int fd = fileno(f);
if (fd >= 0) {
if (fsync(fd) != 0) rc = -1;
}
fclose(f);
if (n != len) rc = -1;
return rc;
}
// 写入interfaces文件使用DHCP并设置MAC
static int update_interfaces_with_mac_dhcp(const char* interfaces_path, const char* mac_colon) {
const char* tmpl =
"# interfaces(5) file used by ifup(8) and ifdown(8)\n"
"# Include files from /etc/network/interfaces.d:\n"
"source-directory /etc/network/interfaces.d\n"
"auto lo\n"
"iface lo inet loopback\n"
"auto eth0\n"
"iface eth0 inet dhcp\n"
"hwaddress ether %s\n";
char* newbuf = (char*)malloc(1024);
if (!newbuf) {
fprintf(stderr, "malloc failed\n");
return -1;
}
int n = snprintf(newbuf, 1024, tmpl, mac_colon);
if (n <= 0) {
free(newbuf);
return -1;
}
int rc = write_file(interfaces_path, newbuf, (size_t)n);
if (rc == 0) {
sync();
printf("写入interfaces文件并更新MAC: %s (DHCP)\n", mac_colon);
} else {
fprintf(stderr, "写入失败 %s\n", interfaces_path);
}
free(newbuf);
return rc;
}
static int scanner_read_event2(char* out, size_t out_size) {
const char* force_stdin = getenv("SCANNER_FORCE_STDIN");
if (force_stdin && strcmp(force_stdin, "1") == 0) return -1;
int fd = open("/dev/input/event2", O_RDONLY);
if (fd < 0) return -1;
struct input_event ev;
size_t j = 0;
int shift = 0;
while (1) {
ssize_t r = read(fd, &ev, sizeof(ev));
if (r <= 0) continue;
if (ev.type != EV_KEY) continue;
// 维护Shift状态
if (ev.code == KEY_LEFTSHIFT || ev.code == KEY_RIGHTSHIFT) {
if (ev.value == 1) shift = 1; // 按下
else if (ev.value == 0) shift = 0; // 松开
continue;
}
// 只在松开(key up)时采集字符,避免重复
if (ev.value != 0) {
if (ev.code == KEY_ENTER || ev.code == KEY_KPENTER) {
break;
}
continue;
}
char ch = 0;
switch (ev.code) {
// 数字键行
case KEY_1: ch = shift ? '!' : '1'; break;
case KEY_2: ch = shift ? '@' : '2'; break;
case KEY_3: ch = shift ? '#' : '3'; break;
case KEY_4: ch = shift ? '$' : '4'; break;
case KEY_5: ch = shift ? '%' : '5'; break;
case KEY_6: ch = shift ? '^' : '6'; break;
case KEY_7: ch = shift ? '&' : '7'; break;
case KEY_8: ch = shift ? '*' : '8'; break;
case KEY_9: ch = shift ? '(' : '9'; break;
case KEY_0: ch = shift ? ')' : '0'; break;
// 小键盘数字
case KEY_KP1: ch = '1'; break; case KEY_KP2: ch = '2'; break; case KEY_KP3: ch = '3'; break;
case KEY_KP4: ch = '4'; break; case KEY_KP5: ch = '5'; break; case KEY_KP6: ch = '6'; break;
case KEY_KP7: ch = '7'; break; case KEY_KP8: ch = '8'; break; case KEY_KP9: ch = '9'; break;
case KEY_KP0: ch = '0'; break;
// 字母(显式映射,避免假设键码连续)
case KEY_A: ch = shift ? 'A' : 'a'; break;
case KEY_B: ch = shift ? 'B' : 'b'; break;
case KEY_C: ch = shift ? 'C' : 'c'; break;
case KEY_D: ch = shift ? 'D' : 'd'; break;
case KEY_E: ch = shift ? 'E' : 'e'; break;
case KEY_F: ch = shift ? 'F' : 'f'; break;
case KEY_G: ch = shift ? 'G' : 'g'; break;
case KEY_H: ch = shift ? 'H' : 'h'; break;
case KEY_I: ch = shift ? 'I' : 'i'; break;
case KEY_J: ch = shift ? 'J' : 'j'; break;
case KEY_K: ch = shift ? 'K' : 'k'; break;
case KEY_L: ch = shift ? 'L' : 'l'; break;
case KEY_M: ch = shift ? 'M' : 'm'; break;
case KEY_N: ch = shift ? 'N' : 'n'; break;
case KEY_O: ch = shift ? 'O' : 'o'; break;
case KEY_P: ch = shift ? 'P' : 'p'; break;
case KEY_Q: ch = shift ? 'Q' : 'q'; break;
case KEY_R: ch = shift ? 'R' : 'r'; break;
case KEY_S: ch = shift ? 'S' : 's'; break;
case KEY_T: ch = shift ? 'T' : 't'; break;
case KEY_U: ch = shift ? 'U' : 'u'; break;
case KEY_V: ch = shift ? 'V' : 'v'; break;
case KEY_W: ch = shift ? 'W' : 'w'; break;
case KEY_X: ch = shift ? 'X' : 'x'; break;
case KEY_Y: ch = shift ? 'Y' : 'y'; break;
case KEY_Z: ch = shift ? 'Z' : 'z'; break;
// 其他符号
case KEY_MINUS: ch = shift ? '_' : '-'; break;
case KEY_SEMICOLON: ch = shift ? ':' : ';'; break;
case KEY_APOSTROPHE: ch = shift ? '"' : '\''; break;
case KEY_BACKSLASH: ch = shift ? '|' : '\\'; break;
case KEY_EQUAL: ch = shift ? '+' : '='; break;
default: break;
}
if (ch) {
if (j < out_size - 1) out[j++] = ch;
}
}
out[j] = '\0';
close(fd);
return strlen(out) > 0 ? 0 : -1;
}
// 黄灯控制函数实现
static void gpio_init_yellow(void) {
int fd = open("/sys/class/gpio/export", O_WRONLY);
if (fd >= 0) {
write(fd, "113", 3);
close(fd);
}
fd = open("/sys/class/gpio/gpio113/direction", O_WRONLY);
if (fd >= 0) {
write(fd, "out", 3);
close(fd);
}
}
static void* led_fast_blink_thread(void* arg) {
int fd = open("/sys/class/gpio/gpio113/value", O_WRONLY);
if (fd < 0) return NULL;
while (led_running) {
write(fd, "1", 1);
usleep(100000); // 100ms - 快速闪烁
write(fd, "0", 1);
usleep(100000); // 100ms - 快速闪烁
}
// ensure off
write(fd, "0", 1);
close(fd);
return NULL;
}
static void start_yellow_fast_blink(void) {
if (led_running) return;
gpio_init_yellow();
led_running = 1;
pthread_create(&led_thread, NULL, led_fast_blink_thread, NULL);
}
static void stop_yellow_blink(void) {
if (!led_running) return;
led_running = 0;
// 等待线程退出
pthread_join(led_thread, NULL);
}
static void set_yellow_off(void) {
// 确保不再闪烁
stop_yellow_blink();
// 初始化GPIO并置为低电平灭灯
gpio_init_yellow();
int fd = open("/sys/class/gpio/gpio113/value", O_WRONLY);
if (fd < 0) return;
write(fd, "0", 1);
close(fd);
}
static int read_qrcode_string(char* out, size_t out_size) {
// Try hardware scanner first
printf("尝试读取硬件扫码内容...\n");
if (scanner_read_event2(out, out_size) == 0) return 0;
// Fallback: read a line from stdin (useful for piping during tests)
fprintf(stdout, "请在终端输入扫码内容并回车...\n");
if (fgets(out, (int)out_size, stdin) == NULL) return -1;
// trim newline
size_t n = strlen(out);
if (n && out[n-1] == '\n') out[n-1] = '\0';
return strlen(out) > 0 ? 0 : -1;
}
int main(int argc, char** argv) {
const char* interfaces_path = (argc >= 2) ? argv[1] : "/etc/network/interfaces";
setvbuf(stderr, NULL, _IONBF, 0);
// 首先检查当前MAC地址
char current_mac[32] = {0};
if (get_mac_from_interfaces(interfaces_path, current_mac, sizeof(current_mac)) == 0) {
to_upper_str(current_mac);
printf("当前MAC地址: %s\n", current_mac);
// 如果MAC不是默认值程序退出
if (strcmp(current_mac, "90:A9:F7:30:00:00") != 0) {
printf("MAC地址非默认程序退出\n");
set_yellow_off();
return 0;
}
}
// MAC是默认值开始快速闪烁黄灯
printf("MAC地址为默认值开始快速闪烁黄灯\n");
start_yellow_fast_blink();
printf("等待扫码...\n");
while (1) {
char scanbuf[512] = {0};
if (read_qrcode_string(scanbuf, sizeof(scanbuf)) != 0) {
fprintf(stderr, "读取扫码内容失败,重试...\n");
continue;
}
printf("扫码原始内容: %s\n", scanbuf);
// 提取批次号
char batch[128] = {0};
if (extract_batch(scanbuf, batch, sizeof(batch)) != 0) {
fprintf(stderr, "未识别到批次号,请重新扫码...\n");
continue;
}
printf("识别到批次号: %s\n", batch);
// 查询Redis获取设备信息
char mac[32] = {0};
char secret[128] = {0};
if (redis_query_device_info(NULL, NULL, NULL, NULL, batch, mac, sizeof(mac), secret, sizeof(secret)) != 0) {
fprintf(stderr, "Redis查询失败请重试...\n");
continue;
}
printf("查询成功 - MAC: %s, Secret: %s\n", mac, secret);
// 写入savedDevSn文件不带冒号
char mac_no_colon[13] = {0}; // 12位MAC + \0
for (int i = 0, j = 0; i < strlen(mac) && j < 12; i++) {
if (mac[i] != ':') {
mac_no_colon[j++] = mac[i];
}
}
if (write_file("/root/savedDevSn", mac_no_colon, strlen(mac_no_colon)) == 0) {
printf("已写入 /root/savedDevSn: %s\n", mac_no_colon);
} else {
fprintf(stderr, "写入 /root/savedDevSn 失败\n");
continue;
}
// 写入appSecret文件
if (write_file("/root/appSecret", secret, strlen(secret)) == 0) {
printf("已写入 /root/appSecret: %s\n", secret);
} else {
fprintf(stderr, "写入 /root/appSecret 失败\n");
continue;
}
// 写入interfaces文件DHCP + MAC
if (update_interfaces_with_mac_dhcp(interfaces_path, mac) == 0) {
printf("已更新 %s (DHCP + MAC: %s)\n", interfaces_path, mac);
} else {
fprintf(stderr, "更新 %s 失败\n", interfaces_path);
continue;
}
// 记录审计日志
redis_audit_log(NULL, NULL, NULL, NULL, batch, mac, "success");
// 停止黄灯闪烁
stop_yellow_blink();
set_yellow_off();
printf("所有配置更新完成!\n");
// 重启mt_server服务
printf("正在重启mt_server服务...\n");
// 先重新加载systemd配置
printf("重新加载systemd配置...\n");
system("systemctl daemon-reload");
// 然后重启服务
int ret = system("systemctl restart mt_server");
if (ret == 0) {
printf("mt_server服务重启成功\n");
} else {
printf("mt_server服务重启失败返回码: %d\n", ret);
}
break;
}
return 0;
}