Skip to content

Commit 917d9b8

Browse files
committed
qmodem-next: introduce js based luci app for qmodem
Enhanched SMS management features to luci-app-qmodem-next - Introduced new menu items for SMS messages and SMS conversations in the LuCI interface. - Implemented ACLs for SMS-related operations in the RPCD configuration. - Created a new ucode script for handling SMS functionalities, including: - Initializing and managing SMS databases for sent and received messages. - Functions to list, send, delete, and mark SMS as read. - Support for multi-part SMS reconstruction and conversation grouping. - Added functionality to clear SMS history for both sent and received messages. = add auto-translation script for i18n strings using LLM API - sms_forwarder: add sms-forwarder-next for qmodme-next
1 parent 527d18a commit 917d9b8

38 files changed

+15924
-4
lines changed

application/qmodem/files/usr/libexec/rpcd/qmodem

Lines changed: 843 additions & 0 deletions
Large diffs are not rendered by default.

application/qmodem/files/usr/share/qmodem/vendor/huawei.sh

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -399,11 +399,11 @@ cell_info()
399399
add_bar_info_entry "RxLev" "$lte_rxlev" "Received Signal Level" -120 -25 dBm
400400
unset extra_info
401401
#NR
402-
add_plain_info_entry "${nr_mode}_INFO" "$nr_mode" "$nr_mode Information"
403-
add_plain_info_entry "${nr_mode}_BAND" "$NR_INFO_BAND" "NR Band"
404-
add_plain_info_entry "${nr_mode}_DL" "$NR_INFO_DL" "$nr_mode DL"
405-
add_plain_info_entry "${nr_mode}_UL" "$NR_INFO_UL" "$nr_mode UL"
406402
extra_info="$nr_mode"
403+
add_plain_info_entry "${nr_mode}_INFO" "$nr_mode" "Information"
404+
add_plain_info_entry "${nr_mode}_BAND" "$NR_INFO_BAND" "NR Band"
405+
add_plain_info_entry "${nr_mode}_DL" "$NR_INFO_DL" "DL"
406+
add_plain_info_entry "${nr_mode}_UL" "$NR_INFO_UL" "UL"
407407
add_bar_info_entry "RSRP" "$nr_rsrp" "Reference Signal Received Power" -156 -31 dBm
408408
add_bar_info_entry "RSRQ" "$nr_rsrq" "Reference Signal Received Quality" -43 20 dBm
409409
add_bar_info_entry "SINR" "$nr_sinr" "Signal to Interference plus Noise Ratio Bandwidth" -23 40 dBm
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{
2+
"qmodem": {
3+
"description": "QModem control interface",
4+
"read": {
5+
"ubus": {
6+
"qmodem": [
7+
"base_info",
8+
"cell_info",
9+
"dial_status",
10+
"get_at_cfg",
11+
"get_copyright",
12+
"get_dial_log",
13+
"get_disabled_features",
14+
"get_dns",
15+
"get_imei",
16+
"get_lockband",
17+
"get_mode",
18+
"get_neighborcell",
19+
"get_network_prefer",
20+
"get_reboot_caps",
21+
"get_sms",
22+
"info",
23+
"network_info",
24+
"sim_info"
25+
]
26+
}
27+
},
28+
"write": {
29+
"ubus": {
30+
"qmodem": [
31+
"clear_dial_log",
32+
"delete_sms",
33+
"do_reboot",
34+
"modem_dial",
35+
"modem_hang",
36+
"modem_redial",
37+
"send_at",
38+
"send_raw_pdu",
39+
"send_sms",
40+
"set_imei",
41+
"set_lockband",
42+
"set_mode",
43+
"set_neighborcell",
44+
"set_network_prefer",
45+
"set_sms_storage"
46+
]
47+
}
48+
}
49+
}
50+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
include $(TOPDIR)/rules.mk
2+
3+
# Include unified version
4+
include ../../version.mk
5+
6+
PKG_NAME:=sms-forwarder-next
7+
PKG_RELEASE:=$(AUTORELEASE)
8+
PKG_VERSION:=$(QMODEM_VERSION)
9+
10+
include $(INCLUDE_DIR)/package.mk
11+
12+
define Package/$(PKG_NAME)
13+
SECTION:=utils
14+
CATEGORY:=Utilities
15+
TITLE:=SMS Forward Service
16+
DEPENDS:=+tom_modem +jq +curl +ucode +ucode-mod-ubus +ucode-mod-uci
17+
endef
18+
19+
define Package/$(PKG_NAME)/description
20+
SMS forward service for QModem that supports multiple forwarding methods:
21+
- Telegram Bot
22+
- ServerChan
23+
- Generic Webhook
24+
- Custom Script
25+
endef
26+
27+
28+
define Build/Compile
29+
endef
30+
31+
32+
define Package/$(PKG_NAME)/install
33+
$(INSTALL_DIR) $(1)/usr/bin
34+
$(INSTALL_BIN) ./files/sms_forwarder_next $(1)/usr/bin/
35+
$(INSTALL_DIR) $(1)/usr/share/sms_forwarder
36+
$(INSTALL_BIN) ./files/scripts/sms_forward_*.sh $(1)/usr/share/sms_forwarder/
37+
$(INSTALL_DIR) $(1)/etc/init.d
38+
$(INSTALL_BIN) ./files/sms_forwarder.init $(1)/etc/init.d/sms_forwarder
39+
$(INSTALL_DIR) $(1)/etc/config
40+
$(INSTALL_CONF) ./files/sms_forwarder.example $(1)/etc/config/sms_forwarder
41+
endef
42+
43+
define Package/$(PKG_NAME)/conffiles
44+
/etc/config/sms_forwarder
45+
endef
46+
47+
$(eval $(call BuildPackage,$(PKG_NAME)))
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#!/bin/sh
2+
3+
# Example Custom SMS Forward Script
4+
# This is a template script that can be customized for specific needs
5+
#
6+
# Environment variables available:
7+
# SMS_SENDER - sender phone number
8+
# SMS_TIME - timestamp string
9+
# SMS_CONTENT - SMS content
10+
11+
# Log the SMS to a file
12+
LOG_FILE="/tmp/sms_log.txt"
13+
echo "$(date): SMS from $SMS_SENDER: $SMS_CONTENT" >> "$LOG_FILE"
14+
15+
# Send a notification to system log
16+
logger -t sms_forwarder "New SMS from $SMS_SENDER: $SMS_CONTENT"
17+
18+
# Example: Forward to email using sendmail (if available)
19+
if command -v sendmail >/dev/null 2>&1; then
20+
{
21+
echo "To: admin@example.com"
22+
echo "Subject: New SMS from $SMS_SENDER"
23+
echo "Content-Type: text/plain; charset=UTF-8"
24+
echo ""
25+
echo "Time: $SMS_TIME"
26+
echo "Sender: $SMS_SENDER"
27+
echo "Content: $SMS_CONTENT"
28+
} | sendmail admin@example.com
29+
fi
30+
31+
# Example: Write to a named pipe for other processes
32+
PIPE_FILE="/tmp/sms_pipe"
33+
if [ -p "$PIPE_FILE" ]; then
34+
echo "$SMS_SENDER|$SMS_TIME|$SMS_CONTENT" > "$PIPE_FILE"
35+
fi
36+
37+
# Always return success unless there's a critical error
38+
exit 0
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
#!/bin/sh
2+
# QModem SMS → Feishu message card webhook
3+
# Version: 2025-11-02
4+
# author: XRSec <github.com/XRSec>
5+
6+
API_CONFIG="$1"
7+
# {"webhook_key":"xxxxxx"}
8+
9+
10+
# 飞书 webhook
11+
WEBHOOK="https://open.feishu.cn/open-apis/bot/v2/hook/"
12+
13+
# 设备 / 应用信息
14+
DEVICE_NAME="自定义"
15+
APP_NAME="QModem"
16+
CALL_TYPE="SMS"
17+
TITLE="短信通知"
18+
WEBHOOK_KEY=$(echo "$API_CONFIG" | jq -r .webhook_key)
19+
WEBHOOK="${WEBHOOK}${WEBHOOK_KEY}"
20+
21+
# 从环境变量读取短信信息
22+
FROM="${SMS_SENDER:-unknown}"
23+
RECEIVE_TIME="${SMS_TIME:-$(date '+%Y-%m-%d %H:%M:%S')}"
24+
MSG="${SMS_CONTENT:-<empty>}"
25+
26+
# 限制短信长度(防止过长)
27+
MAX_LEN=800
28+
if [ "${#MSG}" -gt "$MAX_LEN" ]; then
29+
MSG="$(printf '%s' "$MSG" | cut -c1-${MAX_LEN})..."
30+
fi
31+
32+
# JSON 转义
33+
escape_json() {
34+
printf '%s' "$1" | sed -e 's/\\/\\\\/g' -e 's/"/\\"/g' -e ':a;N;$!ba;s/\n/\\n/g'
35+
}
36+
37+
FROM_ESC="$(escape_json "$FROM")"
38+
MSG_ESC="$(escape_json "$MSG")"
39+
RECEIVE_TIME_ESC="$(escape_json "$RECEIVE_TIME")"
40+
41+
# 构造飞书卡片 JSON
42+
JSON_PAYLOAD=$(cat <<EOF
43+
{
44+
"msg_type": "interactive",
45+
"card": {
46+
"header": {
47+
"template": "blue",
48+
"title": {
49+
"content": "💬${DEVICE_NAME}",
50+
"tag": "plain_text"
51+
}
52+
},
53+
"elements": [
54+
{
55+
"tag": "div",
56+
"fields": [
57+
{
58+
"is_short": true,
59+
"text": {"tag": "lark_md","content": "**🕙接收时间:** ${RECEIVE_TIME_ESC}"}
60+
},
61+
{
62+
"is_short": true,
63+
"text": {"tag": "lark_md","content": "**📞来源号码:** ${FROM_ESC}"}
64+
}
65+
]
66+
},
67+
{
68+
"tag": "div",
69+
"fields": [
70+
{
71+
"is_short": true,
72+
"text": {"tag": "lark_md","content": "**📱设备名称:** ${DEVICE_NAME}"}
73+
},
74+
{
75+
"is_short": true,
76+
"text": {"tag": "lark_md","content": "**📲App应用名:** ${APP_NAME}"}
77+
}
78+
]
79+
},
80+
{
81+
"tag": "div",
82+
"fields": [
83+
{
84+
"is_short": true,
85+
"text": {"tag": "lark_md","content": "**📞通话类型:** ${CALL_TYPE}"}
86+
},
87+
{
88+
"is_short": true,
89+
"text": {"tag": "lark_md","content": "**📢通知标题:** ${TITLE}"}
90+
}
91+
]
92+
},
93+
{
94+
"tag": "div",
95+
"fields": [
96+
{
97+
"is_short": true,
98+
"text": {"tag": "lark_md","content": "**📝通知内容:** ${MSG_ESC}"}
99+
}
100+
]
101+
}
102+
]
103+
}
104+
}
105+
EOF
106+
)
107+
108+
# 日志输出到系统 logread
109+
logger -t sms_forward "📩 短信来自 ${FROM},长度 ${#MSG} 字符,准备推送到飞书..."
110+
111+
# 简单重试机制(最多 3 次)
112+
RETRY=0
113+
MAX_RETRY=3
114+
while [ "$RETRY" -lt "$MAX_RETRY" ]; do
115+
RETRY=$((RETRY + 1))
116+
curl -sS -m 10 -X POST -H "Content-Type: application/json" \
117+
-d "${JSON_PAYLOAD}" "${WEBHOOK}" >/dev/null 2>&1
118+
STATUS=$?
119+
120+
if [ "$STATUS" -eq 0 ]; then
121+
logger -t sms_forward "✅ 成功转发短信至飞书 (${FROM})"
122+
exit 0
123+
else
124+
logger -t sms_forward "⚠️ 第 ${RETRY} 次发送失败 (code=${STATUS}),重试中..."
125+
sleep 3
126+
fi
127+
done
128+
129+
logger -t sms_forward "❌ 最终发送失败 (${FROM}),放弃重试。"
130+
exit 1
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#!/bin/sh
2+
3+
# PushDeer SMS Forward Script
4+
# Environment variables available:
5+
# SMS_SENDER - sender phone number
6+
# SMS_TIME - timestamp string
7+
# SMS_CONTENT - SMS content
8+
9+
# Parse API config from environment or config file
10+
API_CONFIG="$1"
11+
12+
if [ -z "$API_CONFIG" ]; then
13+
echo "Error: API config not provided"
14+
exit 1
15+
fi
16+
17+
# Extract configuration using jq or manual parsing
18+
PUSH_KEY=$(echo "$API_CONFIG" | jq -r '.push_key' 2>/dev/null)
19+
ENDPOINT=$(echo "$API_CONFIG" | jq -r '.endpoint' 2>/dev/null)
20+
21+
# Handle null values from jq
22+
if [ "$PUSH_KEY" = "null" ] || [ -z "$PUSH_KEY" ]; then
23+
echo "Error: Missing required PushDeer push_key"
24+
exit 1
25+
fi
26+
27+
# Handle null value for endpoint
28+
if [ "$ENDPOINT" = "null" ]; then
29+
ENDPOINT=""
30+
fi
31+
32+
# Set default endpoint if not provided
33+
if [ -z "$ENDPOINT" ]; then
34+
ENDPOINT="https://api2.pushdeer.com"
35+
fi
36+
37+
# Build API URL
38+
API_URL="${ENDPOINT}/message/push"
39+
40+
# Prepare message content
41+
TEXT="QModem SMS: ($SMS_SENDER)
42+
43+
Time: $SMS_TIME
44+
Content: $SMS_CONTENT"
45+
46+
# URL encode function for GET method
47+
url_encode() {
48+
echo "$1" | sed 's/ /%20/g; s/\n/%0A/g; s/&/%26/g; s/?/%3F/g; s/#/%23/g; s/=/%3D/g; s/+/%2B/g; s/@/%40/g; s/!/%21/g; s/\*/%2A/g; s/'\''/%27/g; s/(/%28/g; s/)/%29/g; s/;/%3B/g; s/:/%3A/g; s/,/%2C/g; s/\$/%24/g; s/\[/%5B/g; s/\]/%5D/g; s/{/%7B/g; s/}/%7D/g; s/|/%7C/g; s/\\/%5C/g; s/\^/%5E/g; s/`/%60/g; s/"/%22/g; s/</%3C/g; s/>/%3E/g; s/~/%7E/g'
49+
}
50+
51+
# URL encode the text
52+
TEXT_ENCODED=$(url_encode "$TEXT")
53+
54+
# Try curl first, then wget
55+
if command -v curl >/dev/null 2>&1; then
56+
curl -X POST "$API_URL" \
57+
-d "pushkey=$PUSH_KEY" \
58+
-d "text=$TEXT_ENCODED" \
59+
-d "type=text" \
60+
--connect-timeout 10 \
61+
--max-time 30
62+
elif command -v wget >/dev/null 2>&1; then
63+
# Create temporary file for POST data
64+
TEMP_FILE=$(mktemp)
65+
echo "pushkey=$PUSH_KEY&text=$TEXT_ENCODED&type=text" > "$TEMP_FILE"
66+
67+
wget -O- \
68+
--post-file="$TEMP_FILE" \
69+
--header="Content-Type: application/x-www-form-urlencoded" \
70+
--timeout=30 \
71+
"$API_URL"
72+
73+
rm -f "$TEMP_FILE"
74+
else
75+
echo "Error: Neither curl nor wget available"
76+
exit 1
77+
fi
78+
79+
exit $?

0 commit comments

Comments
 (0)