Merge branch 'main' into multi-tenant
This commit is contained in:
18
CHANGELOG.md
18
CHANGELOG.md
@@ -1,15 +1,17 @@
|
||||
# 版本发布日志
|
||||
|
||||
## 2.2409.1-20240925
|
||||
## 2.2409.4-20240927
|
||||
|
||||
多租户修改如下:
|
||||
- 新增 跟踪任务pcap文件获取接口
|
||||
- 优化 socket消息接收,跟踪任务推送ws
|
||||
- 修复 历史告警同步判断存在错误
|
||||
- 优化 redis数据scan数调整1000
|
||||
- 修复 SMF在线订阅用户列表接口地址错误
|
||||
- 修复 多语言SMSC原因0表示未知
|
||||
- 新增 网元版本列表主动检查服务状态的版本
|
||||
- 更新 UDM用户数据表字段
|
||||
|
||||
- ims在线用户显示异常
|
||||
- admin和tenant角色只能单选
|
||||
|
||||
合并主线版本修改如下:
|
||||
|
||||
--## 2.2409.3-20240920
|
||||
## 2.2409.3-20240920
|
||||
|
||||
- 修复 字典多语言序号重复问题
|
||||
- 更新 UDM用户数据表,SMSC参数配置属性,字典数据和跟踪相关表
|
||||
|
||||
@@ -135,7 +135,8 @@ omc:
|
||||
# TLS Skip verify: true/false
|
||||
# email/sms
|
||||
# smProxy: sms(Short Message Service)/smsc(SMS Centre)
|
||||
# dataCoding: 0:UCS2, 1:ASCII, 2:LATIN1
|
||||
# dataCoding: 0:GSM7BIT, 1:ASCII, 2:BINARY8BIT1, 3:LATIN1,
|
||||
# 4:BINARY8BIT2, 6:CYRILLIC, 7:HEBREW, 8:UCS2
|
||||
alarm:
|
||||
alarmEmailForward:
|
||||
enable: true
|
||||
|
||||
@@ -69,7 +69,7 @@ omc:
|
||||
access: "rw"
|
||||
filter: ""
|
||||
display: "Mobile List"
|
||||
comment: ""
|
||||
comment: "Multiple mobile separated by commas"
|
||||
- name: "smscAddr"
|
||||
type: "string"
|
||||
value: ""
|
||||
@@ -100,9 +100,9 @@ omc:
|
||||
comment: ""
|
||||
- name: "dataCoding"
|
||||
type: "enum"
|
||||
value: "ASCII"
|
||||
value: "GSM7BIT"
|
||||
access: "rw"
|
||||
filter: '{"0":"UCS2","1":"ASCII","2":"LATIN1"}'
|
||||
filter: '{"0":"GSM7BIT","1":"ASCII","2":"BINARY8BIT1","3":"LATIN1","4":"BINARY8BIT2","6":"CYRILLIC","7":"HEBREW","8":"UCS2"}'
|
||||
display: "Data Coding"
|
||||
comment: "Short message coding type"
|
||||
- name: "serviceNumber"
|
||||
@@ -111,4 +111,4 @@ omc:
|
||||
access: "rw"
|
||||
filter: "3~20"
|
||||
display: "Service Number"
|
||||
comment: "It is the source address and length is between 3 and 20"
|
||||
comment: "It is the source address, the length is between 3 and 20"
|
||||
@@ -112,7 +112,7 @@ INSERT INTO `ne_config` VALUES (82, 'CBC', 'mmeProfile', 'MME Profile', 'array',
|
||||
|
||||
-- OMC parameter config
|
||||
INSERT INTO `ne_config` VALUES (83, 'OMC', 'alarmEmailForward', 'Alarm Email Forward Interface', 'list', '[{\"access\":\"rw\",\"comment\":\"Is it enabled forward alarm with Email interface\",\"display\":\"Enable\",\"filter\":\"true;false\",\"name\":\"enable\",\"type\":\"bool\",\"value\":\"true\"},{\"access\":\"rw\",\"comment\":\"\",\"display\":\"Email List\",\"filter\":\"\",\"name\":\"emailList\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"Email SMTP server\",\"display\":\"SMTP Server\",\"filter\":\"\",\"name\":\"smtp\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"\",\"display\":\"Port\",\"filter\":\"0~65535\",\"name\":\"port\",\"type\":\"int\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"\",\"display\":\"User\",\"filter\":\"\",\"name\":\"user\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"\",\"display\":\"Password\",\"filter\":\"\",\"name\":\"password\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"If skip TLS verify (true/false)\",\"display\":\"TLS Skip Verify\",\"filter\":\"true;false\",\"name\":\"tlsSkipVerify\",\"type\":\"bool\",\"value\":\"true\"}]', 3, '', 1725505025649);
|
||||
INSERT INTO `ne_config` VALUES (84, 'OMC', 'alarmSMSForward', 'Alarm SMS Forward Interface', 'list', '[{\"access\":\"rw\",\"comment\":\"Is it enabled forward alarm with SMS interface\",\"display\":\"Enable\",\"filter\":\"true;false\",\"name\":\"enable\",\"type\":\"bool\",\"value\":\"true\"},{\"access\":\"rw\",\"comment\":\"\",\"display\":\"Mobile List\",\"filter\":\"\",\"name\":\"mobileList\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"The SMSC SMPP Address\",\"display\":\"SMSC Address\",\"filter\":\"\",\"name\":\"smscAddr\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"\",\"display\":\"System ID\",\"filter\":\"\",\"name\":\"systemID\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"\",\"display\":\"Password\",\"filter\":\"\",\"name\":\"password\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"\",\"display\":\"System Type\",\"filter\":\"\",\"name\":\"systemType\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"Short message coding type\",\"display\":\"Data Coding\",\"filter\":\"{\\\"0\\\":\\\"UCS2\\\",\\\"1\\\":\\\"ASCII\\\",\\\"2\\\":\\\"LATIN1\\\"}\",\"name\":\"dataCoding\",\"type\":\"enum\",\"value\":\"ASCII\"},{\"access\":\"rw\",\"comment\":\"It is the source address and length between 3 and 20\",\"display\":\"Service Number\",\"filter\":\"3~20\",\"name\":\"serviceNumber\",\"type\":\"string\",\"value\":\"OMC\"}]', 4, '', 1726799142528);
|
||||
INSERT INTO `ne_config` VALUES (84, 'OMC', 'alarmSMSForward', 'Alarm SMS Forward Interface', 'list', '[{\"access\":\"rw\",\"comment\":\"Is it enabled forward alarm with SMS interface\",\"display\":\"Enable\",\"filter\":\"true;false\",\"name\":\"enable\",\"type\":\"bool\",\"value\":\"true\"},{\"access\":\"rw\",\"comment\":\"Multiple mobile separated by commas\",\"display\":\"Mobile List\",\"filter\":\"\",\"name\":\"mobileList\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"The SMSC SMPP Address\",\"display\":\"SMSC Address\",\"filter\":\"\",\"name\":\"smscAddr\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"\",\"display\":\"System ID\",\"filter\":\"\",\"name\":\"systemID\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"\",\"display\":\"Password\",\"filter\":\"\",\"name\":\"password\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"\",\"display\":\"System Type\",\"filter\":\"\",\"name\":\"systemType\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"Short message coding type\",\"display\":\"Data Coding\",\"filter\":\"{\\\"0\\\":\\\"GSM7BIT\\\",\\\"1\\\":\\\"ASCII\\\",\\\"2\\\":\\\"BINARY8BIT1\\\",\\\"3\\\":\\\"LATIN1\\\",\\\"4\\\":\\\"BINARY8BIT2\\\",\\\"6\\\":\\\"CYRILLIC\\\",\\\"7\\\":\\\"HEBREW\\\",\\\"8\\\":\\\"UCS2\\\"}\",\"name\":\"dataCoding\",\"type\":\"enum\",\"value\":\"GSM7BIT\"},{\"access\":\"rw\",\"comment\":\"It is the source address, the length is between 3 and 20\",\"display\":\"Service Number\",\"filter\":\"3~20\",\"name\":\"serviceNumber\",\"type\":\"string\",\"value\":\"OMC\"}]', 4, '', 1727664057261);
|
||||
|
||||
-- 更新 SMSC 配置 20240920
|
||||
INSERT INTO `ne_config` VALUES (90, 'SMSC', 'system', 'System', 'list', '[{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"CDR Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"cdrFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"SM Validity\",\"filter\":\"0-2147483647\",\"name\":\"smValidity\",\"type\":\"int\",\"value\":\"259200\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Log Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"logFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"Enable or disable resend pending SMS to unattainable local users.\",\"display\":\"Local Polling Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"localPollingFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"Enable or disable resend pending SMS to unattainable outbound roaming users.\",\"display\":\"Local Roaming Out Polling Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"localRoamingOutPollingFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"Enable or disable resend pending SMS to unattainable inbound roaming users.\",\"display\":\"Visitor Roaming In Polling Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"visitorRoamingInPollingFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"Enable or disable resend pending SMS to other unattainable users.\",\"display\":\"Other Polling Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"otherPollingFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"Define the maximum port number that the queue of pending SMS may grow to.\",\"display\":\"Polling Number\",\"filter\":\"0-64\",\"name\":\"pollingNumber\",\"type\":\"int\",\"value\":\"64\"},{\"access\":\"read-write\",\"comment\":\"Specify the priority parameter of SM_RP_PRI. true = High; false = Low.\",\"display\":\"Priority Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"priorityFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"Enable or disable TP-Reply-Path parameter in the SMS-DELIVER data unit.\",\"display\":\"TP Reply Path Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"tpReplyPathFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"SMSC Domain\",\"filter\":\"0~16\",\"name\":\"smscDomain\",\"type\":\"string\",\"value\":\"0.0.0.0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"CSFB VoLTE Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"csfbVolteFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Camel Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"camelFlag\",\"type\":\"bool\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"SCF Address\",\"filter\":\"0~16\",\"name\":\"scfAddress\",\"type\":\"string\",\"value\":\"0.0.0.0\"},{\"access\":\"read-write\",\"comment\":\"If add plus then set false\",\"display\":\"MT Id Format Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"mtIdFormatFlag\",\"type\":\"bool\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"enable mcast sms\",\"display\":\"Mcast Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"mcastFlag\",\"type\":\"bool\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Log Level\",\"filter\":\"{\\\"0\\\":\\\"none\\\",\\\"1\\\":\\\"error\\\",\\\"2\\\":\\\"debug\\\"}\",\"name\":\"logLevel\",\"type\":\"enum\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"The MB sizeof log file\",\"display\":\"Log Size\",\"filter\":\"1-1000\",\"name\":\"logSize\",\"type\":\"int\",\"value\":\"200\"},{\"access\":\"read-write\",\"comment\":\"The number of log file\",\"display\":\"Log Number\",\"filter\":\"1-20\",\"name\":\"logNum\",\"type\":\"int\",\"value\":\"10\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Log Directory\",\"filter\":\"0~128\",\"name\":\"logDir\",\"type\":\"string\",\"value\":\"/var/log/\"}]', 1, '', 1726802301029);
|
||||
|
||||
@@ -78,8 +78,8 @@ INSERT INTO `sys_dict_data` VALUES (1070, 1070, 'menu.ueUser.onlineIMS', 'IMS在
|
||||
INSERT INTO `sys_dict_data` VALUES (1071, 1071, 'menu.ueUser.onlineUE', 'UE在线信息', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (1072, 1072, 'menu.ueUser.base5G', '基站信息', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (1073, 1073, 'menu.trace', '跟踪', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (1074, 1074, 'menu.trace.task', '跟踪任务', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (1075, 1075, 'menu.trace.analysis', '信令分析', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (1074, 1074, 'menu.trace.task', '网元跟踪任务', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (1075, 1075, 'menu.trace.analysis', '网元跟踪数据', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (1076, 1076, 'menu.trace.pcap', '信令抓包', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (1077, 1077, 'menu.fault', '监控', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (1078, 1078, 'menu.config.backupManageRemark', '备份管理菜单', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
@@ -254,9 +254,9 @@ INSERT INTO `sys_dict_data` VALUES (1520, 1520, 'dictType.sys_yes_no_remark', '
|
||||
INSERT INTO `sys_dict_data` VALUES (1521, 1521, 'dictType.sys_oper_type_remark', '操作类型列表', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (1522, 1522, 'dictType.sys_common_status_remark', '登录状态列表', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (1523, 1523, 'dictType.trace_type_remark', '跟踪类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
-- INSERT INTO `sys_dict_data` VALUES (1524, 1524, 'dictType.operation_log_type_remark', '操作日志类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (1525, 1525, 'dictType.alarm_status_remark', '告警日志状态类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
-- INSERT INTO `sys_dict_data` VALUES (1526, 1526, 'dictType.security_log_type_remark', '安全日志类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (1524, 1524, 'dictType.alarm_status_remark', '告警日志状态类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (1525, 1525, 'menu.trace.tshark', '信令分析', 'i18n_zh', '', '', '1', 'supervisor', 1727085393370, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (1526, 1526, 'menu.trace.wireshark', '信令跟踪', 'i18n_zh', '', '', '1', 'supervisor', 1727085393370, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (1527, 1527, 'dictType.ne_version_status_remark', '网元软件版本状态', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (1528, 1528, 'dictType.i18n_en_remark', 'Internationalization - English', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (1529, 1529, 'dictType.i18n_zh_remark', 'Internationalization - Chinese', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
@@ -656,7 +656,7 @@ INSERT INTO `sys_dict_data` VALUES (2145, 2145, 'menu.system.user.editPost', '
|
||||
INSERT INTO `sys_dict_data` VALUES (2146, 2146, 'menu.dashboard.smscCDR', '短信话单', 'i18n_zh', '', '', '1', 'supervisor', 1717051745866, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (2147, 2147, 'log.operate.title.smscCDR', '短信话单', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (2148, 2148, 'menu.trace.pcapFile', '信令抓包文件', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
|
||||
-- INSERT INTO `sys_dict_data` VALUES (2149, 2149, 'dictData.udm_sub_cn_type.2', '4G', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (2149, 2149, 'menu.trace.taskAnalyze', '跟踪数据分析', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
|
||||
-- INSERT INTO `sys_dict_data` VALUES (2150, 2150, 'dictData.udm_sub_cn_type.3', '5G&4G', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (2151, 2151, 'menu.system.setting.doc', '系统使用文档', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (2152, 2152, 'menu.system.setting.official', '官网链接', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
|
||||
@@ -673,9 +673,9 @@ INSERT INTO `sys_dict_data` VALUES (2162, 2162, 'table.cdr_event_smf', '数据
|
||||
INSERT INTO `sys_dict_data` VALUES (2163, 2163, 'table.cdr_event_smsc', '短信话单', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (2164, 2164, 'menu.log.exportFile', '导出文件管理', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (2165, 2165, 'menu.perf.kpiCReport', '自定义指标数据', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (2166, 2166, 'menu.trace.taskHLR', '跟踪任务 HLR', 'i18n_zh', '', '', '1', 'supervisor', 1726626822538, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (2166, 2166, 'menu.trace.taskHLR', 'HLR 跟踪任务', 'i18n_zh', '', '', '1', 'supervisor', 1726626822538, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (2167, 2167, 'dictType.cdr_cause_code', 'CDR 响应原因代码类别类型', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (2168, 2168, 'dictData.cdr_cause_code.0', '其他', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (2168, 2168, 'dictData.cdr_cause_code.0', '未知错误', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (2169, 2169, 'dictData.cdr_cause_code.8', '运营者要求禁止', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (2170, 2170, 'dictData.cdr_cause_code.10', '呼叫禁止', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (2171, 2171, 'dictData.cdr_cause_code.21', '短信传输拒绝', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, '');
|
||||
|
||||
@@ -78,8 +78,8 @@ INSERT INTO `sys_dict_data` VALUES (3070, 3070, 'menu.ueUser.onlineIMS', 'IMS On
|
||||
INSERT INTO `sys_dict_data` VALUES (3071, 3071, 'menu.ueUser.onlineUE', 'UE Online Information', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (3072, 3072, 'menu.ueUser.base5G', 'Radio Information', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (3073, 3073, 'menu.trace', 'Trace', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (3074, 3074, 'menu.trace.task', 'Trace Tasks', 'i18n_en', '', '', '1', 'supervisor', 1700000000000, NULL, 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (3075, 3075, 'menu.trace.analysis', 'Signaling Analysis', 'i18n_en', '', '', '1', 'supervisor', 1700000000000, NULL, 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (3074, 3074, 'menu.trace.task', 'NE Trace Task', 'i18n_en', '', '', '1', 'supervisor', 1700000000000, NULL, 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (3075, 3075, 'menu.trace.analysis', 'NE Trace Task Data', 'i18n_en', '', '', '1', 'supervisor', 1700000000000, NULL, 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (3076, 3076, 'menu.trace.pcap', 'Signaling Capture', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (3077, 3077, 'menu.fault', 'Monitor', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (3078, 3078, 'menu.config.backupManageRemark', 'Backup Management Menu', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
@@ -254,9 +254,9 @@ INSERT INTO `sys_dict_data` VALUES (3520, 3520, 'dictType.sys_yes_no_remark', 'S
|
||||
INSERT INTO `sys_dict_data` VALUES (3521, 3521, 'dictType.sys_oper_type_remark', 'Operation type list', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (3522, 3522, 'dictType.sys_common_status_remark', 'Login Status List', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (3523, 3523, 'dictType.trace_type_remark', 'Trace Types', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
-- INSERT INTO `sys_dict_data` VALUES (3524, 3524, 'dictType.operation_log_type_remark', 'Operation log type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (3525, 3525, 'dictType.alarm_status_remark', 'Alarm Log Status Type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
-- INSERT INTO `sys_dict_data` VALUES (3526, 3526, 'dictType.security_log_type_remark', 'Security Log Type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (3524, 3524, 'dictType.alarm_status_remark', 'Alarm Log Status Type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (3525, 3525, 'menu.trace.tshark', 'Signaling Analysis', 'i18n_en', '', '', '1', 'supervisor', 1727085393370, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (3526, 3526, 'menu.trace.wireshark', 'Signaling Trace', 'i18n_en', '', '', '1', 'supervisor', 1727085393370, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (3527, 3527, 'dictType.ne_version_status_remark', 'Network element software version status', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (3528, 3528, 'dictType.i18n_en_remark', 'Internationalization - English', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
INSERT INTO `sys_dict_data` VALUES (3529, 3529, 'dictType.i18n_en_remark', 'Internationalization - Chinese', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
@@ -656,7 +656,7 @@ INSERT INTO `sys_dict_data` VALUES (4145, 4145, 'menu.system.user.editPost', 'Mo
|
||||
INSERT INTO `sys_dict_data` VALUES (4146, 4146, 'menu.dashboard.smscCDR', 'SMS CDR', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (4147, 4147, 'log.operate.title.smscCDR', 'SMS CDR', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (4148, 4148, 'menu.trace.pcapFile', 'Signaling Capture File', 'i18n_en', '', '', '1', 'supervisor', 1718441035866, '', 0, '');
|
||||
-- INSERT INTO `sys_dict_data` VALUES (4149, 4149, 'dictData.udm_sub_cn_type.2', '4G', 'i18n_en', '', '', '1', 'supervisor', 1718441035866, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (4149, 4149, 'menu.trace.taskAnalyze', 'Tracking Data Analysis', 'i18n_en', '', '', '1', 'supervisor', 1718441035866, '', 0, '');
|
||||
-- INSERT INTO `sys_dict_data` VALUES (4150, 4150, 'dictData.udm_sub_cn_type.3', '5G&4G', 'i18n_en', '', '', '1', 'supervisor', 1718441035866, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (4151, 4151, 'menu.system.setting.doc', 'System User Documentation', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (4152, 4152, 'menu.system.setting.official', 'Official Website', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
|
||||
@@ -673,9 +673,9 @@ INSERT INTO `sys_dict_data` VALUES (4162, 4162, 'table.cdr_event_smf', 'Data CDR
|
||||
INSERT INTO `sys_dict_data` VALUES (4163, 4163, 'table.cdr_event_smsc', 'SMS CDR', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (4164, 4164, 'menu.log.exportFile', 'Exported File Management', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (4165, 4165, 'menu.perf.kpiCReport', 'Custom Indicator Data', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (4166, 4166, 'menu.trace.taskHLR', 'Tracking Tasks HLR', 'i18n_en', '', '', '1', 'supervisor', 1726626822538, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (4166, 4166, 'menu.trace.taskHLR', 'HLR Trace Task', 'i18n_en', '', '', '1', 'supervisor', 1726626822538, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (4167, 4167, 'dictType.cdr_cause_code', 'CDR Response Reason Code Category Type', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (4168, 4168, 'dictData.cdr_cause_code.0', 'Other', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (4168, 4168, 'dictData.cdr_cause_code.0', 'Unknown Error', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (4169, 4169, 'dictData.cdr_cause_code.8', 'OPERATOR_DETERMINED_BARRING', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (4170, 4170, 'dictData.cdr_cause_code.10', 'CALL_BARRED', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, '');
|
||||
INSERT INTO `sys_dict_data` VALUES (4171, 4171, 'dictData.cdr_cause_code.21', 'SM Trans Reject', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, '');
|
||||
|
||||
@@ -130,8 +130,8 @@ INSERT INTO `sys_menu` VALUES (2081, 'menu.ueUser.onlineUE', 5, 6, 'ue', 'neUser
|
||||
INSERT INTO `sys_menu` VALUES (2082, 'menu.ueUser.base5G', 5, 7, 'base5G', 'neUser/base5G/index', '1', '0', 'M', '1', '1', 'neUser:base5G:index', 'icon-paixu', 'supervisor', 1700000000000, NULL, 0, 'menu.ueUser.base5GRemark');
|
||||
INSERT INTO `sys_menu` VALUES (2083, 'menu.trace', 2087, 30, 'traceManage', NULL, '1', '0', 'D', '1', '1', NULL, 'icon-paixu', 'supervisor', 1700000000000, NULL, 0, 'menu.traceRemark');
|
||||
INSERT INTO `sys_menu` VALUES (2084, 'menu.trace.task', 2083, 1, 'task', 'traceManage/task/index', '1', '0', 'M', '0', '1', 'traceManage:task:index', 'icon-chexiao', 'supervisor', 1700000000000, 'admin', 1713176976458, 'menu.trace.taskRemark');
|
||||
INSERT INTO `sys_menu` VALUES (2085, 'menu.trace.analysis', 2083, 2, 'analysis', 'traceManage/analysis/index', '1', '0', 'M', '0', '1', 'traceManage:analysis:index', 'icon-gongnengjieshao', 'supervisor', 1700000000000, 'admin', 1713176987835, 'menu.trace.analysisRemark');
|
||||
INSERT INTO `sys_menu` VALUES (2086, 'menu.trace.pcap', 2083, 3, 'pcap', 'traceManage/pcap/index', '1', '1', 'M', '1', '1', 'traceManage:pcap:index', 'icon-soutubiao', 'supervisor', 1700000000000, NULL, 0, 'menu.trace.pcapRemark');
|
||||
INSERT INTO `sys_menu` VALUES (2085, 'menu.trace.analysis', 2083, 4, 'analysis', 'traceManage/analysis/index', '1', '0', 'M', '0', '1', 'traceManage:analysis:index', 'icon-gongnengjieshao', 'supervisor', 1700000000000, 'admin', 1713176987835, 'menu.trace.analysisRemark');
|
||||
INSERT INTO `sys_menu` VALUES (2086, 'menu.trace.pcap', 2083, 11, 'pcap', 'traceManage/pcap/index', '1', '1', 'M', '1', '1', 'traceManage:pcap:index', 'icon-soutubiao', 'supervisor', 1700000000000, NULL, 0, 'menu.trace.pcapRemark');
|
||||
INSERT INTO `sys_menu` VALUES (2087, 'menu.fault', 0, 2, 'faultManage', NULL, '1', '0', 'D', '1', '1', NULL, 'icon-jinggao', 'supervisor', 1700000000000, NULL, 0, 'menu.faultRemark');
|
||||
INSERT INTO `sys_menu` VALUES (2088, 'menu.fault.active', 2129, 1, 'active-alarm', 'faultManage/active-alarm/index', '1', '1', 'M', '1', '1', 'faultManage:active-alarm:index', 'icon-wenjian', 'supervisor', 1700000000000, NULL, 0, 'menu.fault.activemRemark');
|
||||
INSERT INTO `sys_menu` VALUES (2089, 'menu.log', 0, 9, 'logManage', NULL, '1', '0', 'D', '1', '1', NULL, 'icon-fuzhidaima', 'supervisor', 1700000000000, NULL, 0, 'menu.logRemark');
|
||||
@@ -196,10 +196,13 @@ INSERT INTO `sys_menu` VALUES (2154, 'menu.ne.neConfigBackup', 4, 29, 'neConfigB
|
||||
INSERT INTO `sys_menu` VALUES (2155, 'menu.common.delete', 2154, 1, '#', '', '1', '1', 'B', '1', '1', 'ne:neConfigBackup:remove', '#', 'supervisor', 1721902269805, '', 0, '');
|
||||
INSERT INTO `sys_menu` VALUES (2156, 'menu.common.edit', 2154, 2, '#', '', '1', '1', 'B', '1', '1', 'ne:neConfigBackup:edit', '#', 'supervisor', 1721902269805, '', 0, '');
|
||||
INSERT INTO `sys_menu` VALUES (2157, 'menu.dashboard.smscCDR', 2140, 9, 'smscCDR', 'dashboard/smscCDR/index', '1', '0', 'M', '1', '1', 'dashboard:cdr:index', 'icon-paixu', 'supervisor', 1723107637982, 'supervisor', 1723107637982, '');
|
||||
INSERT INTO `sys_menu` VALUES (2158, 'menu.trace.pcapFile', 2083, 4, 'pcap/inline/file', 'traceManage/pcap/file', '1', '1', 'M', '0', '1', 'traceManage:pcap:index', '#', 'supervisor', 1724144595914, '', 0, '');
|
||||
INSERT INTO `sys_menu` VALUES (2158, 'menu.trace.pcapFile', 2083, 12, 'pcap/inline/file', 'traceManage/pcap/file', '1', '1', 'M', '0', '1', 'traceManage:pcap:index', '#', 'supervisor', 1724144595914, '', 0, '');
|
||||
INSERT INTO `sys_menu` VALUES (2159, 'menu.log.exportFile', 2089, 100, 'exportFile', 'logManage/exportFile/index', '1', '1', 'M', '1', '1', 'logManage:exportFile:index', 'icon-wenjian', 'supervisor', 1724144595914, '', 0, '');
|
||||
INSERT INTO `sys_menu` VALUES (2160, 'menu.perf.kpiCReport', 2099, 100, 'kpiCReport', 'perfManage/kpiCReport/index', '1', '1', 'M', '1', '1', 'perfManage:kpiCReport:index', 'icon-tubiaoku', 'supervisor', 1724144595914, '', 0, '');
|
||||
INSERT INTO `sys_menu` VALUES (2161, 'menu.trace.taskHLR', 2083, 10, 'taskHLR', 'traceManage/task-hlr/index', '1', '0', 'M', '1', '1', 'traceManage:taskHLR:index', 'icon-gengduo', 'supervisor', 1724144595914, '', 0, '');
|
||||
INSERT INTO `sys_menu` VALUES (2161, 'menu.trace.taskHLR', 2083, 6, 'taskHLR', 'traceManage/task-hlr/index', '1', '0', 'M', '1', '1', 'traceManage:taskHLR:index', 'icon-chexiao', 'supervisor', 1724144595914, '', 0, '');
|
||||
INSERT INTO `sys_menu` VALUES (2162, 'menu.trace.taskAnalyze', 2083, 2, 'task/inline/analyze', 'traceManage/task/analyze', '1', '0', 'M', '0', '1', 'traceManage:taskAnalyze:index', '#', 'supervisor', 1724144595914, '', 0, '');
|
||||
INSERT INTO `sys_menu` VALUES (2163, 'menu.trace.tshark', 2083, 14, 'tshark', 'traceManage/tshark/index', '1', '0', 'M', '1', '1', 'traceManage:tshark:index', 'icon-gengduo', 'supervisor', 1724144595914, '', 0, '');
|
||||
INSERT INTO `sys_menu` VALUES (2164, 'menu.trace.wireshark', 2083, 16, 'wireshark', 'traceManage/wireshark/index', '1', '0', 'M', '1', '1', 'traceManage:wireshark:index', 'icon-gengduo', 'supervisor', 1724144595914, '', 0, '');
|
||||
|
||||
-- tenant management for admin user
|
||||
INSERT INTO `sys_menu` VALUES (10000, 'menu.security.tenant', 2113, 5, 'tenant', 'system/tenant/index', '1', '1', 'M', '1', '1', 'system:tenant:list', 'icon-yuzhanghao1', 'supervisor', 1700000000000, NULL, 0, 'menu.security.tenantRemark');
|
||||
|
||||
@@ -245,6 +245,13 @@ INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2148);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2149);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2152);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2153);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2154);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2155);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2156);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2157);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2160);
|
||||
|
||||
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (4, 1);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (4, 5);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (4, 112);
|
||||
@@ -295,6 +302,9 @@ INSERT IGNORE INTO `sys_role_menu` VALUES (4, 2148);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (4, 2149);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (4, 2152);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (4, 2153);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (4, 2160);
|
||||
|
||||
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (5, 1);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (5, 5);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (5, 112);
|
||||
|
||||
@@ -91,8 +91,8 @@ REPLACE INTO `sys_dict_data` VALUES (1070, 1070, 'menu.ueUser.onlineIMS', 'IMS
|
||||
REPLACE INTO `sys_dict_data` VALUES (1071, 1071, 'menu.ueUser.onlineUE', 'UE在线信息', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (1072, 1072, 'menu.ueUser.base5G', '基站信息', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (1073, 1073, 'menu.trace', '跟踪', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (1074, 1074, 'menu.trace.task', '跟踪任务', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (1075, 1075, 'menu.trace.analysis', '信令分析', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (1074, 1074, 'menu.trace.task', '网元跟踪任务', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (1075, 1075, 'menu.trace.analysis', '网元跟踪数据', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (1076, 1076, 'menu.trace.pcap', '信令抓包', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (1077, 1077, 'menu.fault', '监控', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (1078, 1078, 'menu.config.backupManageRemark', '备份管理菜单', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
@@ -261,9 +261,9 @@ REPLACE INTO `sys_dict_data` VALUES (1520, 1520, 'dictType.sys_yes_no_remark', '
|
||||
REPLACE INTO `sys_dict_data` VALUES (1521, 1521, 'dictType.sys_oper_type_remark', '操作类型列表', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (1522, 1522, 'dictType.sys_common_status_remark', '登录状态列表', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (1523, 1523, 'dictType.trace_type_remark', '跟踪类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
-- REPLACE INTO `sys_dict_data` VALUES (1524, 1524, 'dictType.operation_log_type_remark', '操作日志类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (1525, 1525, 'dictType.alarm_status_remark', '告警日志状态类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
-- REPLACE INTO `sys_dict_data` VALUES (1526, 1526, 'dictType.security_log_type_remark', '安全日志类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (1524, 1524, 'dictType.alarm_status_remark', '告警日志状态类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (1525, 1525, 'menu.trace.tshark', '信令分析', 'i18n_zh', '', '', '1', 'supervisor', 1727085393370, '', 0, '');
|
||||
REPLACE INTO `sys_dict_data` VALUES (1526, 1526, 'menu.trace.wireshark', '信令跟踪', 'i18n_zh', '', '', '1', 'supervisor', 1727085393370, '', 0, '');
|
||||
REPLACE INTO `sys_dict_data` VALUES (1527, 1527, 'dictType.ne_version_status_remark', '网元软件版本状态', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (1528, 1528, 'dictType.i18n_en_remark', 'Internationalization - English', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (1529, 1529, 'dictType.i18n_zh_remark', 'Internationalization - Chinese', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
@@ -680,9 +680,9 @@ REPLACE INTO `sys_dict_data` VALUES (2162, 2162, 'table.cdr_event_smf', '数据
|
||||
REPLACE INTO `sys_dict_data` VALUES (2163, 2163, 'table.cdr_event_smsc', '短信话单', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||
REPLACE INTO `sys_dict_data` VALUES (2164, 2164, 'menu.log.exportFile', '导出文件管理', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||
REPLACE INTO `sys_dict_data` VALUES (2165, 2165, 'menu.perf.kpiCReport', '自定义指标数据', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||
REPLACE INTO `sys_dict_data` VALUES (2166, 2166, 'menu.trace.taskHLR', '跟踪任务 HLR', 'i18n_zh', '', '', '1', 'supervisor', 1726626822538, '', 0, '');
|
||||
REPLACE INTO `sys_dict_data` VALUES (2166, 2166, 'menu.trace.taskHLR', 'HLR 跟踪任务', 'i18n_zh', '', '', '1', 'supervisor', 1726626822538, '', 0, '');
|
||||
REPLACE INTO `sys_dict_data` VALUES (2167, 2167, 'dictType.cdr_cause_code', 'CDR 响应原因代码类别类型', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, '');
|
||||
REPLACE INTO `sys_dict_data` VALUES (2168, 2168, 'dictData.cdr_cause_code.0', '其他', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, '');
|
||||
REPLACE INTO `sys_dict_data` VALUES (2168, 2168, 'dictData.cdr_cause_code.0', '未知错误', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, '');
|
||||
REPLACE INTO `sys_dict_data` VALUES (2169, 2169, 'dictData.cdr_cause_code.8', '运营者要求禁止', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, '');
|
||||
REPLACE INTO `sys_dict_data` VALUES (2170, 2170, 'dictData.cdr_cause_code.10', '呼叫禁止', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, '');
|
||||
REPLACE INTO `sys_dict_data` VALUES (2171, 2171, 'dictData.cdr_cause_code.21', '短信传输拒绝', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, '');
|
||||
|
||||
@@ -89,8 +89,8 @@ REPLACE INTO `sys_dict_data` VALUES (3070, 3070, 'menu.ueUser.onlineIMS', 'IMS O
|
||||
REPLACE INTO `sys_dict_data` VALUES (3071, 3071, 'menu.ueUser.onlineUE', 'UE Online Information', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (3072, 3072, 'menu.ueUser.base5G', 'Radio Information', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (3073, 3073, 'menu.trace', 'Trace', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (3074, 3074, 'menu.trace.task', 'Trace Tasks', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (3075, 3075, 'menu.trace.analysis', 'Signaling Analysis', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (3074, 3074, 'menu.trace.task', 'NE Trace Task', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (3075, 3075, 'menu.trace.analysis', 'NE Trace Task Data', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (3076, 3076, 'menu.trace.pcap', 'Signaling Capture', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (3077, 3077, 'menu.fault', 'Monitor', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (3078, 3078, 'menu.config.backupManageRemark', 'Backup Management Menu', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
@@ -255,9 +255,9 @@ REPLACE INTO `sys_dict_data` VALUES (3520, 3520, 'dictType.sys_yes_no_remark', '
|
||||
REPLACE INTO `sys_dict_data` VALUES (3521, 3521, 'dictType.sys_oper_type_remark', 'Operation type list', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (3522, 3522, 'dictType.sys_common_status_remark', 'Login Status List', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (3523, 3523, 'dictType.trace_type_remark', 'Trace Types', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
-- REPLACE INTO `sys_dict_data` VALUES (3524, 3524, 'dictType.operation_log_type_remark', 'Operation log type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (3525, 3525, 'dictType.alarm_status_remark', 'Alarm Log Status Type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
-- REPLACE INTO `sys_dict_data` VALUES (3526, 3526, 'dictType.security_log_type_remark', 'Security Log Type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (3524, 3524, 'dictType.alarm_status_remark', 'Alarm Log Status Type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (3525, 3525, 'menu.trace.tshark', 'Signaling Analysis', 'i18n_en', '', '', '1', 'supervisor', 1727085393370, '', 0, '');
|
||||
REPLACE INTO `sys_dict_data` VALUES (3526, 3526, 'menu.trace.wireshark', 'Signaling Trace', 'i18n_en', '', '', '1', 'supervisor', 1727085393370, '', 0, '');
|
||||
REPLACE INTO `sys_dict_data` VALUES (3527, 3527, 'dictType.ne_version_status_remark', 'Network element software version status', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (3528, 3528, 'dictType.i18n_en_remark', 'Internationalization - English', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
REPLACE INTO `sys_dict_data` VALUES (3529, 3529, 'dictType.i18n_zh_remark', 'Internationalization - Chinese', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||
@@ -675,9 +675,9 @@ REPLACE INTO `sys_dict_data` VALUES (4162, 4162, 'table.cdr_event_smf', 'Data CD
|
||||
REPLACE INTO `sys_dict_data` VALUES (4163, 4163, 'table.cdr_event_smsc', 'SMS CDR', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||
REPLACE INTO `sys_dict_data` VALUES (4164, 4164, 'menu.log.exportFile', 'Exported File Management', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||
REPLACE INTO `sys_dict_data` VALUES (4165, 4165, 'menu.perf.kpiCReport', 'Custom Indicator Data', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||
REPLACE INTO `sys_dict_data` VALUES (4166, 4166, 'menu.trace.taskHLR', 'Tracking Tasks HLR', 'i18n_en', '', '', '1', 'supervisor', 1726626822538, '', 0, '');
|
||||
REPLACE INTO `sys_dict_data` VALUES (4166, 4166, 'menu.trace.taskHLR', 'HLR Trace Task', 'i18n_en', '', '', '1', 'supervisor', 1726626822538, '', 0, '');
|
||||
REPLACE INTO `sys_dict_data` VALUES (4167, 4167, 'dictType.cdr_cause_code', 'CDR Response Reason Code Category Type', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, '');
|
||||
REPLACE INTO `sys_dict_data` VALUES (4168, 4168, 'dictData.cdr_cause_code.0', 'Other', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, '');
|
||||
REPLACE INTO `sys_dict_data` VALUES (4168, 4168, 'dictData.cdr_cause_code.0', 'Unknown Error', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, '');
|
||||
REPLACE INTO `sys_dict_data` VALUES (4169, 4169, 'dictData.cdr_cause_code.8', 'OPERATOR_DETERMINED_BARRING', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, '');
|
||||
REPLACE INTO `sys_dict_data` VALUES (4170, 4170, 'dictData.cdr_cause_code.10', 'CALL_BARRED', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, '');
|
||||
REPLACE INTO `sys_dict_data` VALUES (4171, 4171, 'dictData.cdr_cause_code.21', 'SM Trans Reject', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, '');
|
||||
|
||||
@@ -113,8 +113,8 @@ REPLACE INTO `sys_menu` VALUES (2081, 'menu.ueUser.onlineUE', 5, 6, 'ue', 'neUse
|
||||
REPLACE INTO `sys_menu` VALUES (2082, 'menu.ueUser.base5G', 5, 7, 'base5G', 'neUser/base5G/index', '1', '0', 'M', '1', '1', 'neUser:base5G:index', 'icon-paixu', 'supervisor', 1700000000000, NULL, 0, 'menu.ueUser.base5GRemark');
|
||||
REPLACE INTO `sys_menu` VALUES (2083, 'menu.trace', 2087, 30, 'traceManage', NULL, '1', '0', 'D', '1', '1', NULL, 'icon-paixu', 'supervisor', 1700000000000, NULL, 0, 'menu.traceRemark');
|
||||
REPLACE INTO `sys_menu` VALUES (2084, 'menu.trace.task', 2083, 1, 'task', 'traceManage/task/index', '1', '0', 'M', '0', '1', 'traceManage:task:index', 'icon-chexiao', 'supervisor', 1700000000000, 'admin', 1713176976458, 'menu.trace.taskRemark');
|
||||
REPLACE INTO `sys_menu` VALUES (2085, 'menu.trace.analysis', 2083, 2, 'analysis', 'traceManage/analysis/index', '1', '0', 'M', '0', '1', 'traceManage:analysis:index', 'icon-gongnengjieshao', 'supervisor', 1700000000000, 'admin', 1713176987835, 'menu.trace.analysisRemark');
|
||||
REPLACE INTO `sys_menu` VALUES (2086, 'menu.trace.pcap', 2083, 3, 'pcap', 'traceManage/pcap/index', '1', '1', 'M', '1', '1', 'traceManage:pcap:index', 'icon-soutubiao', 'supervisor', 1700000000000, NULL, 0, 'menu.trace.pcapRemark');
|
||||
REPLACE INTO `sys_menu` VALUES (2085, 'menu.trace.analysis', 2083, 4, 'analysis', 'traceManage/analysis/index', '1', '0', 'M', '0', '1', 'traceManage:analysis:index', 'icon-gongnengjieshao', 'supervisor', 1700000000000, 'admin', 1713176987835, 'menu.trace.analysisRemark');
|
||||
REPLACE INTO `sys_menu` VALUES (2086, 'menu.trace.pcap', 2083, 11, 'pcap', 'traceManage/pcap/index', '1', '1', 'M', '1', '1', 'traceManage:pcap:index', 'icon-soutubiao', 'supervisor', 1700000000000, NULL, 0, 'menu.trace.pcapRemark');
|
||||
REPLACE INTO `sys_menu` VALUES (2087, 'menu.fault', 0, 2, 'faultManage', NULL, '1', '0', 'D', '1', '1', NULL, 'icon-jinggao', 'supervisor', 1700000000000, NULL, 0, 'menu.faultRemark');
|
||||
REPLACE INTO `sys_menu` VALUES (2088, 'menu.fault.active', 2129, 1, 'active-alarm', 'faultManage/active-alarm/index', '1', '1', 'M', '1', '1', 'faultManage:active-alarm:index', 'icon-wenjian', 'supervisor', 1700000000000, NULL, 0, 'menu.fault.activemRemark');
|
||||
REPLACE INTO `sys_menu` VALUES (2089, 'menu.log', 0, 9, 'logManage', NULL, '1', '0', 'D', '1', '1', NULL, 'icon-fuzhidaima', 'supervisor', 1700000000000, NULL, 0, 'menu.logRemark');
|
||||
@@ -179,10 +179,13 @@ REPLACE INTO `sys_menu` VALUES (2154, 'menu.ne.neConfigBackup', 4, 29, 'neConfig
|
||||
REPLACE INTO `sys_menu` VALUES (2155, 'menu.common.delete', 2154, 1, '#', '', '1', '1', 'B', '1', '1', 'ne:neConfigBackup:remove', '#', 'supervisor', 1721902269805, '', 0, '');
|
||||
REPLACE INTO `sys_menu` VALUES (2156, 'menu.common.edit', 2154, 2, '#', '', '1', '1', 'B', '1', '1', 'ne:neConfigBackup:edit', '#', 'supervisor', 1721902269805, '', 0, '');
|
||||
REPLACE INTO `sys_menu` VALUES (2157, 'menu.dashboard.smscCDR', 2140, 9, 'smscCDR', 'dashboard/smscCDR/index', '1', '0', 'M', '1', '1', 'dashboard:cdr:index', 'icon-paixu', 'supervisor', 1723107637982, 'supervisor', 1723107637982, '');
|
||||
REPLACE INTO `sys_menu` VALUES (2158, 'menu.trace.pcapFile', 2083, 4, 'pcap/inline/file', 'traceManage/pcap/file', '1', '1', 'M', '0', '1', 'traceManage:pcap:index', '#', 'supervisor', 1724144595914, '', 0, '');
|
||||
REPLACE INTO `sys_menu` VALUES (2158, 'menu.trace.pcapFile', 2083, 12, 'pcap/inline/file', 'traceManage/pcap/file', '1', '1', 'M', '0', '1', 'traceManage:pcap:index', '#', 'supervisor', 1724144595914, '', 0, '');
|
||||
REPLACE INTO `sys_menu` VALUES (2159, 'menu.log.exportFile', 2089, 100, 'exportFile', 'logManage/exportFile/index', '1', '1', 'M', '1', '1', 'logManage:exportFile:index', 'icon-wenjian', 'supervisor', 1724144595914, '', 0, '');
|
||||
REPLACE INTO `sys_menu` VALUES (2160, 'menu.perf.kpiCReport', 2099, 100, 'kpiCReport', 'perfManage/kpiCReport/index', '1', '1', 'M', '1', '1', 'perfManage:kpiCReport:index', 'icon-tubiaoku', 'supervisor', 1724144595914, '', 0, '');
|
||||
REPLACE INTO `sys_menu` VALUES (2161, 'menu.trace.taskHLR', 2083, 10, 'taskHLR', 'traceManage/task-hlr/index', '1', '0', 'M', '1', '1', 'traceManage:taskHLR:index', 'icon-gengduo', 'supervisor', 1724144595914, '', 0, '');
|
||||
REPLACE INTO `sys_menu` VALUES (2161, 'menu.trace.taskHLR', 2083, 6, 'taskHLR', 'traceManage/task-hlr/index', '1', '0', 'M', '1', '1', 'traceManage:taskHLR:index', 'icon-chexiao', 'supervisor', 1724144595914, '', 0, '');
|
||||
REPLACE INTO `sys_menu` VALUES (2162, 'menu.trace.taskAnalyze', 2083, 2, 'task/inline/analyze', 'traceManage/task/analyze', '1', '0', 'M', '0', '1', 'traceManage:taskAnalyze:index', '#', 'supervisor', 1724144595914, '', 0, '');
|
||||
REPLACE INTO `sys_menu` VALUES (2163, 'menu.trace.tshark', 2083, 14, 'tshark', 'traceManage/tshark/index', '1', '0', 'M', '1', '1', 'traceManage:tshark:index', 'icon-gengduo', 'supervisor', 1724144595914, '', 0, '');
|
||||
REPLACE INTO `sys_menu` VALUES (2164, 'menu.trace.wireshark', 2083, 16, 'wireshark', 'traceManage/wireshark/index', '1', '0', 'M', '1', '1', 'traceManage:wireshark:index', 'icon-gengduo', 'supervisor', 1724144595914, '', 0, '');
|
||||
|
||||
|
||||
-- multi-tenancy
|
||||
|
||||
@@ -245,6 +245,12 @@ INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2148);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2149);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2152);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2153);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2154);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2155);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2156);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2157);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2160);
|
||||
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (4, 1);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (4, 5);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (4, 112);
|
||||
@@ -295,6 +301,8 @@ INSERT IGNORE INTO `sys_role_menu` VALUES (4, 2148);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (4, 2149);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (4, 2152);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (4, 2153);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (4, 2160);
|
||||
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (5, 1);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (5, 5);
|
||||
INSERT IGNORE INTO `sys_role_menu` VALUES (5, 112);
|
||||
|
||||
@@ -89,12 +89,12 @@ func PostCDREventFrom(w http.ResponseWriter, r *http.Request) {
|
||||
switch neInfo.NeType {
|
||||
case "IMS":
|
||||
if v, ok := cdrEvent.CDR["recordType"]; ok && (v == "MOC" || v == "MTSM") {
|
||||
wsService.NewWSSendImpl.ByGroupID(wsService.GROUP_IMS_CDR+neInfo.NeId, cdrEvent)
|
||||
wsService.NewWSSend.ByGroupID(wsService.GROUP_IMS_CDR+neInfo.NeId, cdrEvent)
|
||||
}
|
||||
case "SMF":
|
||||
wsService.NewWSSendImpl.ByGroupID(wsService.GROUP_SMF_CDR+neInfo.NeId, cdrEvent)
|
||||
wsService.NewWSSend.ByGroupID(wsService.GROUP_SMF_CDR+neInfo.NeId, cdrEvent)
|
||||
case "SMSC":
|
||||
wsService.NewWSSendImpl.ByGroupID(wsService.GROUP_SMSC_CDR+neInfo.NeId, cdrEvent)
|
||||
wsService.NewWSSend.ByGroupID(wsService.GROUP_SMSC_CDR+neInfo.NeId, cdrEvent)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ func PostUEEventFromAMF(c *gin.Context) {
|
||||
|
||||
// AMF没有RmUID,直接推送
|
||||
// 推送到ws订阅组
|
||||
wsService.NewWSSendImpl.ByGroupID(wsService.GROUP_AMF_UE, ueEvent)
|
||||
wsService.NewWSSend.ByGroupID(wsService.GROUP_AMF_UE, ueEvent)
|
||||
|
||||
services.ResponseStatusOK204NoContent(c.Writer)
|
||||
}
|
||||
@@ -124,7 +124,7 @@ func PostUEEvent(w http.ResponseWriter, r *http.Request) {
|
||||
if neInfo.RmUID == ueEvent.RmUID {
|
||||
// 推送到ws订阅组
|
||||
if ueEvent.NeType == "MME" {
|
||||
wsService.NewWSSendImpl.ByGroupID(wsService.GROUP_MME_UE+neInfo.NeId, ueEvent)
|
||||
wsService.NewWSSend.ByGroupID(wsService.GROUP_MME_UE+neInfo.NeId, ueEvent)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -595,7 +595,7 @@ func GetAlarmFromNF(w http.ResponseWriter, r *http.Request) {
|
||||
exist, err := session.Table("alarm").
|
||||
Where("ne_type=? and ne_id=? and alarm_id=? and alarm_status=1", alarmData.NeType, alarmData.NeId, alarmData.AlarmId).
|
||||
Exist()
|
||||
if err == nil || !exist {
|
||||
if err != nil || !exist {
|
||||
log.Infof("Not found active alarm: ne_id=%s, alarm_id=%s", alarmData.NeId, alarmData.AlarmId)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -202,15 +202,7 @@ func newSubmitSM(phoneNumber string, message string) (*pdu.SubmitSM, error) {
|
||||
submitSM := pdu.NewSubmitSM().(*pdu.SubmitSM)
|
||||
submitSM.SourceAddr = srcAddr
|
||||
submitSM.DestAddr = destAddr
|
||||
dataCoding := data.UCS2
|
||||
switch smsForward.DataCoding {
|
||||
case config.CODING_UCS2:
|
||||
dataCoding = data.UCS2
|
||||
case config.CODING_ASCII:
|
||||
dataCoding = data.ASCII
|
||||
case config.CODING_LATIN1:
|
||||
dataCoding = data.LATIN1
|
||||
}
|
||||
dataCoding := data.FromDataCoding(smsForward.DataCoding)
|
||||
err = submitSM.Message.SetMessageWithEncoding(message, dataCoding)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -222,3 +214,27 @@ func newSubmitSM(phoneNumber string, message string) (*pdu.SubmitSM, error) {
|
||||
|
||||
return submitSM, nil
|
||||
}
|
||||
|
||||
// const (
|
||||
// // Short message data coding type
|
||||
// SMS_CODING_GSM7BIT byte = iota
|
||||
// SMS_CODING_ASCII
|
||||
// SMS_CODING_BINARY8BIT1
|
||||
// SMS_CODING_LATIN1
|
||||
// SMS_CODING_BINARY8BIT2
|
||||
// SMS_CODING_NODEF
|
||||
// SMS_CODING_CYRILLIC
|
||||
// SMS_CODING_HEBREW
|
||||
// SMS_CODING_UCS2
|
||||
// )
|
||||
|
||||
// var codingMap = map[byte]data.Encoding{
|
||||
// SMS_CODING_GSM7BIT: data.GSM7BIT,
|
||||
// SMS_CODING_ASCII: data.ASCII,
|
||||
// SMS_CODING_BINARY8BIT1: data.BINARY8BIT1,
|
||||
// SMS_CODING_LATIN1: data.LATIN1,
|
||||
// SMS_CODING_BINARY8BIT2: data.BINARY8BIT2,
|
||||
// SMS_CODING_CYRILLIC: data.CYRILLIC,
|
||||
// SMS_CODING_HEBREW: data.HEBREW,
|
||||
// SMS_CODING_UCS2: data.UCS2,
|
||||
// }
|
||||
|
||||
@@ -330,13 +330,13 @@ func PostKPIReportFromNF(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
if neInfo.RmUID == kpiData.RmUid {
|
||||
// 推送到ws订阅组
|
||||
wsService.NewWSSendImpl.ByGroupID(fmt.Sprintf("%s%s_%s", wsService.GROUP_KPI, neInfo.NeType, neInfo.NeId), kpiEvent)
|
||||
wsService.NewWSSend.ByGroupID(fmt.Sprintf("%s%s_%s", wsService.GROUP_KPI, neInfo.NeType, neInfo.NeId), kpiEvent)
|
||||
// 推送自定义KPI到ws订阅组
|
||||
wsService.NewWSSendImpl.ByGroupID(fmt.Sprintf("%s%s_%s", wsService.GROUP_KPI_C, neInfo.NeType, neInfo.NeId), kpiCEvent)
|
||||
wsService.NewWSSend.ByGroupID(fmt.Sprintf("%s%s_%s", wsService.GROUP_KPI_C, neInfo.NeType, neInfo.NeId), kpiCEvent)
|
||||
if neInfo.NeType == "UPF" {
|
||||
wsService.NewWSSendImpl.ByGroupID(wsService.GROUP_KPI_UPF+neInfo.NeId, kpiEvent)
|
||||
// 推送标识为:12_RMUID, exp: 12_4400HXUPF001
|
||||
wsService.NewWSSendImpl.ByGroupID(wsService.GROUP_KPI_UPF+kpiReport.Task.NE.RmUID, kpiEvent)
|
||||
wsService.NewWSSend.ByGroupID(wsService.GROUP_KPI_UPF+neInfo.NeId, kpiEvent)
|
||||
// 推送标识为:12_RMUID, exp: 12_4400HXUPF001, for multi-tenancy
|
||||
wsService.NewWSSend.ByGroupID(wsService.GROUP_KPI_UPF+kpiReport.Task.NE.RmUID, kpiEvent)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -464,9 +464,9 @@ func PostGoldKPIFromNF(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// 推送到ws订阅组
|
||||
wsService.NewWSSendImpl.ByGroupID(wsService.GROUP_KPI, kpiEvent)
|
||||
wsService.NewWSSend.ByGroupID(wsService.GROUP_KPI, kpiEvent)
|
||||
if goldKpi.NEType == "UPF" {
|
||||
wsService.NewWSSendImpl.ByGroupID(wsService.GROUP_KPI_UPF, kpiEvent)
|
||||
wsService.NewWSSend.ByGroupID(wsService.GROUP_KPI_UPF, kpiEvent)
|
||||
}
|
||||
|
||||
services.ResponseStatusOK204NoContent(w)
|
||||
|
||||
34
go.mod
34
go.mod
@@ -9,6 +9,7 @@ require (
|
||||
github.com/go-resty/resty/v2 v2.14.0
|
||||
github.com/go-sql-driver/mysql v1.8.1
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1
|
||||
github.com/gopacket/gopacket v1.2.0
|
||||
github.com/gorilla/mux v1.8.1
|
||||
github.com/gorilla/websocket v1.5.3
|
||||
github.com/gosnmp/gosnmp v1.38.0
|
||||
@@ -45,11 +46,11 @@ require (
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 // indirect
|
||||
github.com/shirou/gopsutil/v3 v3.23.11 // indirect
|
||||
github.com/sirupsen/logrus v1.4.2 // indirect
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bytedance/sonic v1.12.1 // indirect
|
||||
github.com/bytedance/sonic/loader v0.2.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
filippo.io/edwards25519 v1.1.0 // indirect // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect // indirect
|
||||
github.com/bytedance/sonic v1.12.1 // indirect // indirect
|
||||
github.com/bytedance/sonic/loader v0.2.0 // indirect // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect // indirect
|
||||
github.com/chenjiandongx/ginprom v0.0.0-20210617023641-6c809602c38a
|
||||
github.com/cloudwego/base64x v0.1.4 // indirect
|
||||
github.com/cloudwego/iasm v0.2.0 // indirect
|
||||
@@ -73,10 +74,11 @@ require (
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/jonboulle/clockwork v0.4.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.17.9 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
|
||||
github.com/kr/fs v0.1.0 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/klauspost/compress v1.17.9 // indirect // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.8 // indirect // indirect
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 // indirect
|
||||
github.com/kr/fs v0.1.0 // indirect // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect // indirect
|
||||
github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570 // indirect
|
||||
github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20240513124658-fba389f38bae // indirect
|
||||
@@ -101,13 +103,15 @@ require (
|
||||
github.com/richardlehane/mscfb v1.0.4 // indirect
|
||||
github.com/richardlehane/msoleps v1.0.3 // indirect
|
||||
github.com/sagikazarmark/locafero v0.6.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect // indirect
|
||||
github.com/shirou/gopsutil/v3 v3.23.11 // indirect
|
||||
github.com/shoenig/go-m1cpu v0.1.6 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spf13/afero v1.11.0 // indirect
|
||||
github.com/spf13/cast v1.7.0 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/syndtr/goleveldb v1.0.0 // indirect
|
||||
github.com/sirupsen/logrus v1.4.2 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect // indirect
|
||||
github.com/spf13/afero v1.11.0 // indirect // indirect
|
||||
github.com/spf13/cast v1.7.0 // indirect // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect // indirect
|
||||
github.com/syndtr/goleveldb v1.0.0 // indirect // indirect
|
||||
github.com/tebeka/strftime v0.1.5 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.14 // indirect
|
||||
github.com/tklauser/numcpus v0.8.0 // indirect
|
||||
|
||||
6
go.sum
6
go.sum
@@ -124,6 +124,8 @@ github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
|
||||
github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBHwWRvkNFJUQcS4=
|
||||
github.com/googleapis/google-cloud-go-testing v0.0.0-20210719221736-1c9a4c676720/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
|
||||
github.com/gopacket/gopacket v1.2.0 h1:eXbzFad7f73P1n2EJHQlsKuvIMJjVXK5tXoSca78I3A=
|
||||
github.com/gopacket/gopacket v1.2.0/go.mod h1:BrAKEy5EOGQ76LSqh7DMAr7z0NNPdczWm2GxCG7+I8M=
|
||||
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||
@@ -350,6 +352,10 @@ github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2
|
||||
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
||||
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
|
||||
github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0=
|
||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
||||
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg=
|
||||
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
||||
github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU=
|
||||
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d h1:llb0neMWDQe87IzJLS4Ci7psK/lVsjIS2otl+1WyRyY=
|
||||
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
|
||||
|
||||
@@ -150,16 +150,6 @@ type DbConfig struct {
|
||||
Backup string `yaml:"backup"`
|
||||
}
|
||||
|
||||
//type codingType int
|
||||
|
||||
const (
|
||||
// Short message data coding type
|
||||
CODING_UCS2 int = iota
|
||||
CODING_ASCII
|
||||
CODING_LATIN1
|
||||
CODING_NODEF
|
||||
)
|
||||
|
||||
type AlarmConfig struct {
|
||||
SplitEventAlarm bool `yaml:"splitEventAlarm"`
|
||||
//ForwardAlarm bool `yaml:"forwardAlarm"`
|
||||
@@ -180,7 +170,7 @@ type AlarmConfig struct {
|
||||
SystemID string `yaml:"systemID" json:"systemID"`
|
||||
Password string `yaml:"password" json:"password"`
|
||||
SystemType string `yaml:"systemType" json:"systemType"`
|
||||
DataCoding int `yaml:"dataCoding" json:"dataCoding"`
|
||||
DataCoding byte `yaml:"dataCoding" json:"dataCoding"`
|
||||
ServiceNumber string `yaml:"serviceNumber" json:"serviceNumber"`
|
||||
} `yaml:"alarmSMSForward"`
|
||||
SMS struct {
|
||||
@@ -399,8 +389,10 @@ func UpdateStructFromMap(s any, updates map[string]any) {
|
||||
if field.Tag.Get("json") == key {
|
||||
structField := v.FieldByName(field.Name)
|
||||
if structField.IsValid() && structField.CanSet() {
|
||||
if structField.Type() == reflect.TypeOf(value) {
|
||||
structField.Set(reflect.ValueOf(value))
|
||||
// Convert value to the appropriate type if necessary
|
||||
convertedValue := reflect.ValueOf(value).Convert(structField.Type())
|
||||
if structField.Type() == convertedValue.Type() {
|
||||
structField.Set(convertedValue)
|
||||
}
|
||||
}
|
||||
break
|
||||
|
||||
@@ -132,7 +132,8 @@ omc:
|
||||
# TLS Skip verify: true/false
|
||||
# email/sms
|
||||
# smProxy: sms(Short Message Service)/smsc(SMS Centre)
|
||||
# dataCoding: 0:UCS2, 1:ASCII, 2:LATIN1
|
||||
# dataCoding: 0:GSM7BIT, 1:ASCII, 2:BINARY8BIT1, 3:LATIN1,
|
||||
# 4:BINARY8BIT2, 6:CYRILLIC, 7:HEBREW, 8:UCS2
|
||||
alarm:
|
||||
alarmEmailForward:
|
||||
enable: true
|
||||
@@ -144,10 +145,10 @@ alarm:
|
||||
tlsSkipVerify: true
|
||||
alarmSMSForward:
|
||||
enable: true
|
||||
mobileList:
|
||||
smscAddr: "192.168.13.114:2775"
|
||||
systemID: "omc"
|
||||
password: "omc123"
|
||||
mobileList: "1006,1008"
|
||||
smscAddr: "192.168.14.212:2775"
|
||||
systemID: "123456"
|
||||
password: "123456"
|
||||
systemType: "UTRAN"
|
||||
dataCoding: 0
|
||||
serviceNumber: "OMC"
|
||||
|
||||
@@ -184,7 +184,7 @@ func GetKeys(source string, pattern string) ([]string, error) {
|
||||
// 循环遍历获取匹配的键
|
||||
for {
|
||||
// 使用 SCAN 命令获取匹配的键
|
||||
batchKeys, nextCursor, err := rdb.Scan(ctx, cursor, pattern, 100).Result()
|
||||
batchKeys, nextCursor, err := rdb.Scan(ctx, cursor, pattern, 1000).Result()
|
||||
if err != nil {
|
||||
logger.Errorf("Failed to scan keys: %v", err)
|
||||
return keys, err
|
||||
|
||||
@@ -10,10 +10,10 @@ import (
|
||||
|
||||
// SocketTCP TCP服务端
|
||||
type SocketTCP struct {
|
||||
Addr string `json:"addr"` // 主机地址
|
||||
Port int64 `json:"port"` // 端口
|
||||
Listen *net.Listener `json:"listen"`
|
||||
StopChan chan struct{} `json:"stop"` // 停止信号
|
||||
Addr string `json:"addr"` // 主机地址
|
||||
Port int64 `json:"port"` // 端口
|
||||
Listener *net.TCPListener `json:"listener"`
|
||||
StopChan chan struct{} `json:"stop"` // 停止信号
|
||||
}
|
||||
|
||||
// New 创建TCP服务端
|
||||
@@ -26,53 +26,52 @@ func (s *SocketTCP) New() (*SocketTCP, error) {
|
||||
}
|
||||
address := fmt.Sprintf("%s:%d", s.Addr, s.Port)
|
||||
|
||||
ln, err := net.Listen(proto, address)
|
||||
// 解析 TCP 地址
|
||||
tcpAddr, err := net.ResolveTCPAddr(proto, address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.Listen = &ln
|
||||
// 监听 TCP 地址
|
||||
listener, err := net.ListenTCP(proto, tcpAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.Listener = listener
|
||||
s.StopChan = make(chan struct{}, 1)
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// Close 关闭当前TCP服务端
|
||||
func (s *SocketTCP) Close() {
|
||||
if s.Listen != nil {
|
||||
if s.Listener != nil {
|
||||
s.StopChan <- struct{}{}
|
||||
(*s.Listen).Close()
|
||||
(*s.Listener).Close()
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve 处理消息
|
||||
func (s *SocketTCP) Resolve(bufferSize int, callback func([]byte, int)) error {
|
||||
if s.Listen == nil {
|
||||
func (s *SocketTCP) Resolve(callback func(conn *net.Conn)) error {
|
||||
if s.Listener == nil {
|
||||
return fmt.Errorf("tcp service not created")
|
||||
}
|
||||
|
||||
ln := *s.Listen
|
||||
buffer := make([]byte, bufferSize)
|
||||
listener := *s.Listener
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-s.StopChan:
|
||||
return fmt.Errorf("udp service stop")
|
||||
default:
|
||||
conn, err := ln.Accept()
|
||||
conn, err := listener.Accept()
|
||||
if err != nil {
|
||||
logger.Errorf("Error accepting connection: %v ", err)
|
||||
continue
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
// 读取数据
|
||||
n, err := conn.Read(buffer)
|
||||
if err != nil {
|
||||
fmt.Println("Error reading from TCP connection:", err)
|
||||
continue
|
||||
}
|
||||
|
||||
callback(buffer, n)
|
||||
// 处理连接
|
||||
callback(&conn)
|
||||
|
||||
// 发送响应
|
||||
if _, err = conn.Write([]byte("tcp>")); err != nil {
|
||||
|
||||
@@ -50,29 +50,20 @@ func (s *SocketUDP) Close() {
|
||||
}
|
||||
|
||||
// Resolve 处理消息
|
||||
func (s *SocketUDP) Resolve(bufferSize int, callback func([]byte, int)) error {
|
||||
func (s *SocketUDP) Resolve(callback func(*net.UDPConn)) error {
|
||||
if s.Conn == nil {
|
||||
return fmt.Errorf("udp service not created")
|
||||
}
|
||||
|
||||
buffer := make([]byte, bufferSize)
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-s.StopChan:
|
||||
return fmt.Errorf("udp service stop")
|
||||
default:
|
||||
// 读取数据
|
||||
n, addr, err := s.Conn.ReadFromUDP(buffer)
|
||||
if err != nil {
|
||||
fmt.Println("Error reading from UDP connection:", err)
|
||||
continue
|
||||
}
|
||||
|
||||
callback(buffer, n)
|
||||
callback(s.Conn)
|
||||
|
||||
// 发送响应
|
||||
if _, err = s.Conn.WriteToUDP([]byte("udp>"), addr); err != nil {
|
||||
if _, err := s.Conn.WriteTo([]byte("udp>"), s.Conn.RemoteAddr()); err != nil {
|
||||
fmt.Println("Error sending response:", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,7 +293,7 @@ func (s *SMFController) SubUserList(c *gin.Context) {
|
||||
}
|
||||
|
||||
// 网元直连
|
||||
data, err := neFetchlink.SMFSubInfo(neInfo, map[string]string{
|
||||
data, err := neFetchlink.SMFSubInfoList(neInfo, map[string]string{
|
||||
"imsi": query.IMSI,
|
||||
"msisdn": query.MSISDN,
|
||||
"upstate": query.Upstate,
|
||||
@@ -306,24 +306,23 @@ func (s *SMFController) SubUserList(c *gin.Context) {
|
||||
|
||||
// 对数据进行处理,去掉前缀,并加入imsi拓展信息
|
||||
rows := data["rows"].([]any)
|
||||
arr := &rows
|
||||
for i := range *arr {
|
||||
item := (*arr)[i].(map[string]any)
|
||||
if v, ok := item["imsi"]; ok && v != nil {
|
||||
imsiStr := v.(string)
|
||||
imsiStr = strings.TrimPrefix(imsiStr, "imsi-")
|
||||
item["imsi"] = imsiStr
|
||||
// 查UDM拓展信息
|
||||
info := s.udmUserInfoService.SelectByIMSIAndNeID(imsiStr, "")
|
||||
item["remark"] = info.Remark
|
||||
}
|
||||
if v, ok := item["msisdn"]; ok && v != nil {
|
||||
item["msisdn"] = strings.TrimPrefix(v.(string), "msisdn-")
|
||||
if len(rows) > 0 {
|
||||
arr := &rows
|
||||
for i := range *arr {
|
||||
item := (*arr)[i].(map[string]any)
|
||||
if v, ok := item["imsi"]; ok && v != nil {
|
||||
imsiStr := v.(string)
|
||||
imsiStr = strings.TrimPrefix(imsiStr, "imsi-")
|
||||
item["imsi"] = imsiStr
|
||||
// 查UDM拓展信息
|
||||
info := s.udmUserInfoService.SelectByIMSIAndNeID(imsiStr, "")
|
||||
item["remark"] = info.Remark
|
||||
}
|
||||
if v, ok := item["msisdn"]; ok && v != nil {
|
||||
item["msisdn"] = strings.TrimPrefix(v.(string), "msisdn-")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(200, result.Ok(map[string]any{
|
||||
"total": data["total"],
|
||||
"rows": data["rows"],
|
||||
}))
|
||||
c.JSON(200, result.Ok(data))
|
||||
}
|
||||
|
||||
@@ -10,15 +10,13 @@ import (
|
||||
"be.ems/src/modules/network_element/model"
|
||||
)
|
||||
|
||||
// SMFSubInfo SMF在线订阅用户列表信息
|
||||
// SMFSubInfoList SMF在线订阅用户列表信息
|
||||
//
|
||||
// 查询参数 {"imsi":"360000100000130","msisdn":"8612300000130","upstate":"Inactive","pageNum":"1"}
|
||||
//
|
||||
// 返回结果 {"rows":[],"total":0}
|
||||
func SMFSubInfo(neInfo model.NeInfo, data map[string]string) (map[string]any, error) {
|
||||
// neUrl := "http://127.0.0.1:4523/m1/3157310-1528434-82b449ee/api/rest/ueManagement/v1/elementType/smf/objectType/ueInfo?apifoxApiId=150640017"
|
||||
neUrl := fmt.Sprintf("http://%s:%s/api/rest/ueManagement/v1/elementType/smf/objectType/ueInfo", "172.16.20.150", "33030")
|
||||
// neUrl := fmt.Sprintf("http://%s:%d/api/rest/ueManagement/v1/elementType/smf/objectType/ueInfo", neInfo.IP, neInfo.Port)
|
||||
func SMFSubInfoList(neInfo model.NeInfo, data map[string]string) (map[string]any, error) {
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/ueManagement/v1/elementType/smf/objectType/ueInfo", neInfo.IP, neInfo.Port)
|
||||
// 查询参数拼接
|
||||
query := []string{}
|
||||
if v, ok := data["imsi"]; ok && v != "" {
|
||||
|
||||
111
src/modules/trace/controller/packet.go
Normal file
111
src/modules/trace/controller/packet.go
Normal file
@@ -0,0 +1,111 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/utils/ctx"
|
||||
"be.ems/src/framework/vo/result"
|
||||
traceService "be.ems/src/modules/trace/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
)
|
||||
|
||||
// 实例化控制层 PacketController 结构体
|
||||
var NewPacket = &PacketController{
|
||||
packetService: traceService.NewPacket,
|
||||
}
|
||||
|
||||
// 信令跟踪
|
||||
//
|
||||
// PATH /trace/packet
|
||||
type PacketController struct {
|
||||
packetService *traceService.Packet // 信令跟踪服务
|
||||
}
|
||||
|
||||
// 网元跟踪网卡设备列表
|
||||
//
|
||||
// GET /devices
|
||||
func (s *PacketController) Devices(c *gin.Context) {
|
||||
data := s.packetService.NetworkDevices()
|
||||
c.JSON(200, result.OkData(data))
|
||||
}
|
||||
|
||||
// 网元跟踪开始
|
||||
//
|
||||
// POST /start
|
||||
func (s *PacketController) Start(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var body struct {
|
||||
Device string `json:"device" binding:"required"` // 网卡设备
|
||||
TaskNo string `json:"taskNo" binding:"required"` // 任务编号
|
||||
Output string `json:"output" ` // 输出PCAP文件路径,为空则不输出
|
||||
}
|
||||
if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
msg, err := s.packetService.LiveStart(body.TaskNo, body.Device, body.Output)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.OkData(msg))
|
||||
}
|
||||
|
||||
// 网元跟踪结束
|
||||
//
|
||||
// POST /stop
|
||||
func (s *PacketController) Stop(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var body struct {
|
||||
TaskNo string `json:"taskNo" binding:"required"` // 任务编号
|
||||
}
|
||||
if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
if err := s.packetService.LiveStop(body.TaskNo); err != nil {
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Ok(nil))
|
||||
}
|
||||
|
||||
// 网元跟踪过滤
|
||||
//
|
||||
// PUT /filter
|
||||
func (s *PacketController) Filter(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var body struct {
|
||||
TaskNo string `json:"taskNo" binding:"required"` // 任务编号
|
||||
Expr string `json:"expr" binding:"required"` // 过滤表达式(port 33030 or 33040)
|
||||
}
|
||||
if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
if err := s.packetService.LiveFilter(body.TaskNo, body.Expr); err != nil {
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Ok(nil))
|
||||
}
|
||||
|
||||
// 网元跟踪续期保活
|
||||
//
|
||||
// PUT /keep-alive
|
||||
func (s *PacketController) KeepAlive(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var body struct {
|
||||
IntervalIn int `json:"intervalIn" ` // 服务续约的频率,默认设置为60秒
|
||||
Duration int `json:"duration" ` // 服务失效的时间,默认设置为120秒
|
||||
}
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Ok(nil))
|
||||
}
|
||||
@@ -13,26 +13,24 @@ import (
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
)
|
||||
|
||||
// 实例化控制层 TcpdumpController 结构体
|
||||
var NewTcpdump = &TcpdumpController{
|
||||
TcpdumpService: traceService.NewTCPdump,
|
||||
// 实例化控制层 TCPdumpController 结构体
|
||||
var NewTCPdump = &TCPdumpController{
|
||||
tcpdumpService: traceService.NewTCPdump,
|
||||
neInfoService: neService.NewNeInfoImpl,
|
||||
}
|
||||
|
||||
// 信令抓包请求
|
||||
// 信令抓包
|
||||
//
|
||||
// PATH /tcpdump
|
||||
type TcpdumpController struct {
|
||||
// 信令抓包服务
|
||||
TcpdumpService *traceService.TCPdump
|
||||
// 网元信息服务
|
||||
neInfoService neService.INeInfo
|
||||
type TCPdumpController struct {
|
||||
tcpdumpService *traceService.TCPdump // 信令抓包服务
|
||||
neInfoService neService.INeInfo // 网元信息服务
|
||||
}
|
||||
|
||||
// 网元抓包PACP 开始
|
||||
//
|
||||
// POST /start
|
||||
func (s *TcpdumpController) DumpStart(c *gin.Context) {
|
||||
func (s *TCPdumpController) DumpStart(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var body struct {
|
||||
NeType string `json:"neType" binding:"required"` // 网元类型
|
||||
@@ -45,7 +43,7 @@ func (s *TcpdumpController) DumpStart(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
taskCode, err := s.TcpdumpService.DumpStart(body.NeType, body.NeId, body.Cmd)
|
||||
taskCode, err := s.tcpdumpService.DumpStart(body.NeType, body.NeId, body.Cmd)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
@@ -56,7 +54,7 @@ func (s *TcpdumpController) DumpStart(c *gin.Context) {
|
||||
// 网元抓包PACP 结束
|
||||
//
|
||||
// POST /stop
|
||||
func (s *TcpdumpController) DumpStop(c *gin.Context) {
|
||||
func (s *TCPdumpController) DumpStop(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var body struct {
|
||||
NeType string `json:"neType" binding:"required"` // 网元类型
|
||||
@@ -69,7 +67,7 @@ func (s *TcpdumpController) DumpStop(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
taskLog, err := s.TcpdumpService.DumpStop(body.NeType, body.NeId, body.TaskCode)
|
||||
taskLog, err := s.tcpdumpService.DumpStop(body.NeType, body.NeId, body.TaskCode)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
@@ -80,7 +78,7 @@ func (s *TcpdumpController) DumpStop(c *gin.Context) {
|
||||
// 网元抓包PACP 下载
|
||||
//
|
||||
// GET /download
|
||||
func (s *TcpdumpController) DumpDownload(c *gin.Context) {
|
||||
func (s *TCPdumpController) DumpDownload(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
NeType string `form:"neType" binding:"required"` // 网元类型
|
||||
@@ -93,7 +91,7 @@ func (s *TcpdumpController) DumpDownload(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
zipFilePath, err := s.TcpdumpService.DumpDownload(query.NeType, query.NeID, query.TaskCode)
|
||||
zipFilePath, err := s.tcpdumpService.DumpDownload(query.NeType, query.NeID, query.TaskCode)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
@@ -110,7 +108,7 @@ func (s *TcpdumpController) DumpDownload(c *gin.Context) {
|
||||
// UPF标准版内部抓包
|
||||
//
|
||||
// POST /upf
|
||||
func (s *TcpdumpController) UPFTrace(c *gin.Context) {
|
||||
func (s *TCPdumpController) UPFTrace(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var body struct {
|
||||
NeType string `json:"neType" binding:"required"` // 网元类型
|
||||
@@ -123,7 +121,7 @@ func (s *TcpdumpController) UPFTrace(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
msg, err := s.TcpdumpService.UPFTrace(body.NeType, body.NeId, body.Cmd)
|
||||
msg, err := s.tcpdumpService.UPFTrace(body.NeType, body.NeId, body.Cmd)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
@@ -129,3 +132,24 @@ func (s *TraceTaskController) Remove(c *gin.Context) {
|
||||
msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows})
|
||||
c.JSON(200, result.OkMsg(msg))
|
||||
}
|
||||
|
||||
// 跟踪任务文件
|
||||
//
|
||||
// GET /filePull
|
||||
func (s *TraceTaskController) FilePull(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var querys struct {
|
||||
TraceId string `form:"traceId" binding:"required"`
|
||||
}
|
||||
if err := c.ShouldBindQuery(&querys); err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
fileName := fmt.Sprintf("task_%s.pcap", querys.TraceId)
|
||||
localFilePath := filepath.Join("/tmp/omc/trace", fileName)
|
||||
if runtime.GOOS == "windows" {
|
||||
localFilePath = fmt.Sprintf("C:%s", localFilePath)
|
||||
}
|
||||
c.FileAttachment(localFilePath, fileName)
|
||||
}
|
||||
|
||||
191
src/modules/trace/service/packet.go
Normal file
191
src/modules/trace/service/packet.go
Normal file
@@ -0,0 +1,191 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/vo"
|
||||
"github.com/gopacket/gopacket"
|
||||
"github.com/gopacket/gopacket/pcap"
|
||||
"github.com/gopacket/gopacket/pcapgo"
|
||||
)
|
||||
|
||||
// 实例化服务层 Packet 结构体
|
||||
var NewPacket = &Packet{
|
||||
taskMap: sync.Map{},
|
||||
}
|
||||
|
||||
// 信令跟踪 服务层处理
|
||||
type Packet struct {
|
||||
taskMap sync.Map // 捕获任务
|
||||
}
|
||||
|
||||
// task 任务信息
|
||||
type task struct {
|
||||
TaskNo string // 任务编号
|
||||
Handle *pcap.Handle // 捕获句柄
|
||||
File *os.File // 捕获信息输出文件句柄
|
||||
Writer *pcapgo.Writer // 捕获信息输出句柄
|
||||
Expire time.Time // 过期时间
|
||||
context context.Context // 上下文 控制完成结束
|
||||
}
|
||||
|
||||
// NetworkDevices 获取网卡设备信息
|
||||
func (s *Packet) NetworkDevices() []vo.TreeSelect {
|
||||
arr := make([]vo.TreeSelect, 0)
|
||||
devices, err := pcap.FindAllDevs()
|
||||
if err != nil {
|
||||
logger.Errorf("interfaces find all devices err: %s", err.Error())
|
||||
return arr
|
||||
}
|
||||
|
||||
for _, device := range devices {
|
||||
if len(device.Addresses) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
lable := device.Description
|
||||
if lable == "" {
|
||||
lable = device.Name
|
||||
}
|
||||
item := vo.TreeSelect{
|
||||
ID: device.Name,
|
||||
Label: lable,
|
||||
Children: []vo.TreeSelect{},
|
||||
}
|
||||
|
||||
for _, address := range device.Addresses {
|
||||
if address.IP != nil {
|
||||
ip := address.IP.String()
|
||||
item.Children = append(item.Children, vo.TreeSelect{ID: ip, Label: ip})
|
||||
}
|
||||
}
|
||||
arr = append(arr, item)
|
||||
}
|
||||
|
||||
return arr
|
||||
}
|
||||
|
||||
// verifyDevice 检查网卡设备是否存在
|
||||
func (s *Packet) verifyDevice(str string) (string, bool) {
|
||||
devices, err := pcap.FindAllDevs()
|
||||
if err != nil {
|
||||
logger.Errorf("interfaces find all devices err: %s", err.Error())
|
||||
return "", false
|
||||
}
|
||||
for _, device := range devices {
|
||||
if len(device.Addresses) == 0 {
|
||||
continue
|
||||
}
|
||||
if device.Name == str {
|
||||
return device.Name, true
|
||||
}
|
||||
for _, address := range device.Addresses {
|
||||
if address.IP.String() == str {
|
||||
return device.Name, true
|
||||
}
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
// LiveStart 开始捕获数据
|
||||
func (s *Packet) LiveStart(taskNo, deviceName, outputFile string) (string, error) {
|
||||
if _, ok := s.taskMap.Load(taskNo); ok {
|
||||
return "", fmt.Errorf("task no. %s already exist", taskNo)
|
||||
}
|
||||
|
||||
// Verify the specified network interface exists
|
||||
device, deviceOk := s.verifyDevice(deviceName)
|
||||
if !deviceOk {
|
||||
return "", fmt.Errorf("network device not exist: %s", deviceName)
|
||||
}
|
||||
|
||||
snapshotLength := 262144
|
||||
|
||||
// open device
|
||||
handle, err := pcap.OpenLive(device, int32(snapshotLength), true, pcap.BlockForever)
|
||||
if err != nil {
|
||||
logger.Errorf("open live err: %s", err.Error())
|
||||
if strings.Contains(err.Error(), "operation not permitted") {
|
||||
return "", fmt.Errorf("you don't have permission to capture on that/these device(s)")
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
|
||||
// write a new file
|
||||
var w *pcapgo.Writer
|
||||
var f *os.File
|
||||
if outputFile != "" {
|
||||
f, err = os.Create(outputFile)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
w = pcapgo.NewWriter(f)
|
||||
w.WriteFileHeader(uint32(snapshotLength), handle.LinkType())
|
||||
}
|
||||
|
||||
// capture packets
|
||||
packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
|
||||
packetSource.Lazy = false
|
||||
packetSource.NoCopy = true
|
||||
packetSource.DecodeStreamsAsDatagrams = true
|
||||
|
||||
// save tasks
|
||||
ctx := context.Background()
|
||||
task := &task{
|
||||
TaskNo: taskNo,
|
||||
Handle: handle,
|
||||
File: f,
|
||||
Writer: w,
|
||||
Expire: time.Now().Add(time.Second * 120),
|
||||
context: ctx,
|
||||
}
|
||||
s.taskMap.Store(taskNo, task)
|
||||
|
||||
// start capture
|
||||
go func() {
|
||||
for packet := range packetSource.PacketsCtx(ctx) {
|
||||
if packet == nil {
|
||||
continue
|
||||
}
|
||||
if packet.Metadata().Timestamp.Before(time.Now()) {
|
||||
continue
|
||||
}
|
||||
if w != nil {
|
||||
w.WritePacket(packet.Metadata().CaptureInfo, packet.Data())
|
||||
}
|
||||
fmt.Println(packet.Dump())
|
||||
}
|
||||
}()
|
||||
return "task initiated", nil
|
||||
}
|
||||
|
||||
// LiveFilter 捕获过滤
|
||||
func (s *Packet) LiveFilter(taskNo, expr string) error {
|
||||
info, ok := s.taskMap.Load(taskNo)
|
||||
if !ok {
|
||||
return fmt.Errorf("task no. %s not exist", taskNo)
|
||||
}
|
||||
return info.(*task).Handle.SetBPFFilter(expr)
|
||||
}
|
||||
|
||||
// LiveStop 停止捕获数据
|
||||
func (s *Packet) LiveStop(taskNo string) error {
|
||||
info, ok := s.taskMap.Load(taskNo)
|
||||
if !ok {
|
||||
return fmt.Errorf("task no. %s not exist", taskNo)
|
||||
}
|
||||
info.(*task).context.Done()
|
||||
info.(*task).Handle.Close()
|
||||
if info.(task).File != nil {
|
||||
info.(task).File.Close()
|
||||
}
|
||||
s.taskMap.Delete(taskNo)
|
||||
return nil
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/config"
|
||||
@@ -14,6 +16,7 @@ import (
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
"be.ems/src/modules/trace/model"
|
||||
"be.ems/src/modules/trace/repository"
|
||||
wsService "be.ems/src/modules/ws/service"
|
||||
)
|
||||
|
||||
// 实例化数据层 TraceTask 结构体
|
||||
@@ -57,16 +60,27 @@ func (r *TraceTask) CreateUDP() error {
|
||||
}
|
||||
|
||||
// 接收处理UDP数据
|
||||
go r.udpService.Resolve(2048, func(data []byte, n int) {
|
||||
logger.Infof("socket UDP: %s", string(data))
|
||||
mData, err := UDPDataHandler(data, n)
|
||||
go r.udpService.Resolve(func(conn *net.UDPConn) {
|
||||
// 读取数据
|
||||
buf := make([]byte, 2048)
|
||||
n, err := conn.Read(buf)
|
||||
if err != nil {
|
||||
logger.Errorf("error reading from UDP connection: %s", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
logger.Infof("socket UDP: %s", string(buf[:n]))
|
||||
// logger.Infof("socket UDP Base64: %s", base64.StdEncoding.EncodeToString(buf[:n]))
|
||||
mData, err := UDPDataHandler(buf, n)
|
||||
if err != nil {
|
||||
logger.Errorf("udp resolve data fail: %s", err.Error())
|
||||
return
|
||||
}
|
||||
taskId := parse.Number(mData["taskId"])
|
||||
|
||||
// 插入数据库做记录
|
||||
r.traceDataRepository.Insert(model.TraceData{
|
||||
TaskId: parse.Number(mData["taskId"]),
|
||||
TaskId: taskId,
|
||||
IMSI: mData["imsi"].(string),
|
||||
SrcAddr: mData["srcAddr"].(string),
|
||||
DstAddr: mData["dstAddr"].(string),
|
||||
@@ -82,6 +96,7 @@ func (r *TraceTask) CreateUDP() error {
|
||||
// 推送文件
|
||||
if v, ok := mData["pcapFile"]; ok && v != "" {
|
||||
logger.Infof("pcapFile: %s", v)
|
||||
wsService.NewWSSend.ByGroupID(fmt.Sprintf("%s%d", wsService.GROUP_TRACE, taskId), taskId)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -92,16 +107,29 @@ func (r *TraceTask) CreateUDP() error {
|
||||
return err
|
||||
}
|
||||
// 接收处理TCP数据
|
||||
go tcpService.Resolve(1024, func(data []byte, n int) {
|
||||
logger.Infof("socket TCP: %s", string(data))
|
||||
mData, err := UDPDataHandler(data, n)
|
||||
go tcpService.Resolve(func(conn *net.Conn) {
|
||||
c := (*conn)
|
||||
// 读取数据
|
||||
buf := make([]byte, 2048)
|
||||
n, err := c.Read(buf)
|
||||
if err != nil {
|
||||
logger.Errorf("error reading from TCP connection: %s", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
logger.Infof("socket TCP: %s", string(buf[:n]))
|
||||
deData, _ := base64.StdEncoding.DecodeString(string(buf[:n]))
|
||||
logger.Infof("socket TCP Base64: %s", deData)
|
||||
mData, err := UDPDataHandler(deData, len(deData))
|
||||
if err != nil {
|
||||
logger.Errorf("tcp resolve data fail: %s", err.Error())
|
||||
return
|
||||
}
|
||||
taskId := parse.Number(mData["taskId"])
|
||||
|
||||
// 插入数据库做记录
|
||||
r.traceDataRepository.Insert(model.TraceData{
|
||||
TaskId: parse.Number(mData["taskId"]),
|
||||
TaskId: taskId,
|
||||
IMSI: mData["imsi"].(string),
|
||||
SrcAddr: mData["srcAddr"].(string),
|
||||
DstAddr: mData["dstAddr"].(string),
|
||||
@@ -117,6 +145,7 @@ func (r *TraceTask) CreateUDP() error {
|
||||
// 推送文件
|
||||
if v, ok := mData["pcapFile"]; ok && v != "" {
|
||||
logger.Infof("pcapFile: %s", v)
|
||||
wsService.NewWSSend.ByGroupID(fmt.Sprintf("%s%d", wsService.GROUP_TRACE, taskId), taskId)
|
||||
}
|
||||
})
|
||||
return nil
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -264,6 +265,9 @@ const versionMinor = 4
|
||||
func writeEmptyPcap(filename string, timeStamp int64, length int, data []byte) error {
|
||||
var err error
|
||||
var file *os.File
|
||||
if err := os.MkdirAll(filepath.Dir(filename), 0775); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = os.Stat(filename); os.IsNotExist(err) {
|
||||
file, err = os.Create(filename)
|
||||
// File Header
|
||||
@@ -318,7 +322,7 @@ func writeEmptyPcap(filename string, timeStamp int64, length int, data []byte) e
|
||||
|
||||
// writePcap 写Pcap文件并返回文件路径
|
||||
func writePcap(extHdr ExtHeader) string {
|
||||
filePath := fmt.Sprintf("/tmp/trace_%d .pcap", extHdr.TaskId)
|
||||
filePath := fmt.Sprintf("/tmp/omc/trace/task_%d.pcap", extHdr.TaskId)
|
||||
if runtime.GOOS == "windows" {
|
||||
filePath = fmt.Sprintf("C:%s", filePath)
|
||||
}
|
||||
|
||||
@@ -17,34 +17,61 @@ func Setup(router *gin.Engine) {
|
||||
// 启动时需要的初始参数
|
||||
InitLoad()
|
||||
|
||||
traceGroup := router.Group("/trace")
|
||||
|
||||
// 信令抓包
|
||||
tcpdumpGroup := traceGroup.Group("/tcpdump")
|
||||
tcpdumpGroup := router.Group("/trace/tcpdump")
|
||||
{
|
||||
tcpdumpGroup.POST("/start",
|
||||
middleware.PreAuthorize(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.tcpdump", collectlogs.BUSINESS_TYPE_OTHER)),
|
||||
controller.NewTcpdump.DumpStart,
|
||||
controller.NewTCPdump.DumpStart,
|
||||
)
|
||||
tcpdumpGroup.POST("/stop",
|
||||
middleware.PreAuthorize(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.tcpdump", collectlogs.BUSINESS_TYPE_OTHER)),
|
||||
controller.NewTcpdump.DumpStop,
|
||||
controller.NewTCPdump.DumpStop,
|
||||
)
|
||||
tcpdumpGroup.GET("/download",
|
||||
middleware.PreAuthorize(nil),
|
||||
controller.NewTcpdump.DumpDownload,
|
||||
controller.NewTCPdump.DumpDownload,
|
||||
)
|
||||
tcpdumpGroup.POST("/upf",
|
||||
middleware.PreAuthorize(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.tcpdump", collectlogs.BUSINESS_TYPE_OTHER)),
|
||||
controller.NewTcpdump.UPFTrace,
|
||||
controller.NewTCPdump.UPFTrace,
|
||||
)
|
||||
}
|
||||
|
||||
// 信令跟踪
|
||||
packetGroup := router.Group("/trace/packet")
|
||||
{
|
||||
packetGroup.GET("/devices",
|
||||
middleware.PreAuthorize(nil),
|
||||
controller.NewPacket.Devices,
|
||||
)
|
||||
packetGroup.POST("/start",
|
||||
middleware.PreAuthorize(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.packet", collectlogs.BUSINESS_TYPE_OTHER)),
|
||||
controller.NewPacket.Start,
|
||||
)
|
||||
packetGroup.POST("/stop",
|
||||
middleware.PreAuthorize(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.packet", collectlogs.BUSINESS_TYPE_OTHER)),
|
||||
controller.NewPacket.Stop,
|
||||
)
|
||||
packetGroup.PUT("/filter",
|
||||
middleware.PreAuthorize(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.packet", collectlogs.BUSINESS_TYPE_OTHER)),
|
||||
controller.NewPacket.Filter,
|
||||
)
|
||||
packetGroup.PUT("/keep-alive",
|
||||
middleware.PreAuthorize(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.packet", collectlogs.BUSINESS_TYPE_OTHER)),
|
||||
controller.NewPacket.KeepAlive,
|
||||
)
|
||||
}
|
||||
|
||||
// 跟踪任务 网元HLR (免登录)
|
||||
taskHLRGroup := traceGroup.Group("/task/hlr")
|
||||
taskHLRGroup := router.Group("/trace/task/hlr")
|
||||
{
|
||||
taskHLRGroup.GET("/list",
|
||||
controller.NewTraceTaskHlr.List,
|
||||
@@ -67,7 +94,7 @@ func Setup(router *gin.Engine) {
|
||||
}
|
||||
|
||||
// 跟踪任务
|
||||
taskGroup := traceGroup.Group("/task")
|
||||
taskGroup := router.Group("/trace/task")
|
||||
{
|
||||
taskGroup.GET("/list",
|
||||
middleware.PreAuthorize(nil),
|
||||
@@ -92,10 +119,14 @@ func Setup(router *gin.Engine) {
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.task", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||
controller.NewTraceTask.Remove,
|
||||
)
|
||||
taskGroup.GET("/filePull",
|
||||
middleware.PreAuthorize(nil),
|
||||
controller.NewTraceTask.FilePull,
|
||||
)
|
||||
}
|
||||
|
||||
// 跟踪数据
|
||||
taskDataGroup := traceGroup.Group("/data")
|
||||
taskDataGroup := router.Group("/trace/data")
|
||||
{
|
||||
taskDataGroup.GET("/list",
|
||||
middleware.PreAuthorize(nil),
|
||||
|
||||
@@ -21,8 +21,8 @@ import (
|
||||
|
||||
// NewWSController 实例化控制层 WSController 结构体
|
||||
var NewWSController = &WSController{
|
||||
wsService: service.NewWSImpl,
|
||||
wsSendService: service.NewWSSendImpl,
|
||||
wsService: service.NewWS,
|
||||
wsSendService: service.NewWSSend,
|
||||
neHostService: neService.NewNeHostImpl,
|
||||
neInfoService: neService.NewNeInfoImpl,
|
||||
}
|
||||
@@ -32,9 +32,9 @@ var NewWSController = &WSController{
|
||||
// PATH /ws
|
||||
type WSController struct {
|
||||
// WebSocket 服务
|
||||
wsService service.IWS
|
||||
wsService *service.WS
|
||||
// WebSocket消息发送 服务
|
||||
wsSendService service.IWSSend
|
||||
wsSendService *service.WSSend
|
||||
// 网元主机连接服务
|
||||
neHostService neService.INeHost
|
||||
// 网元信息服务
|
||||
|
||||
@@ -1,32 +1,220 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/generate"
|
||||
"be.ems/src/framework/vo/result"
|
||||
"be.ems/src/modules/ws/model"
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
// IWS WebSocket通信 服务层接口
|
||||
type IWS interface {
|
||||
// UpgraderWs http升级ws请求
|
||||
UpgraderWs(w http.ResponseWriter, r *http.Request) *websocket.Conn
|
||||
var (
|
||||
wsClients sync.Map // ws客户端 [clientId: client]
|
||||
wsUsers sync.Map // ws用户对应的多个客户端id [uid:clientIds]
|
||||
wsGroup sync.Map // ws组对应的多个客户端id [groupId:clientIds]
|
||||
)
|
||||
|
||||
// ClientCreate 客户端新建
|
||||
//
|
||||
// uid 登录用户ID
|
||||
// groupIDs 用户订阅组
|
||||
// conn ws连接实例
|
||||
// childConn 子连接实例
|
||||
ClientCreate(uid string, groupIDs []string, conn *websocket.Conn, childConn any) *model.WSClient
|
||||
// NewWS 实例化服务层 WS 结构体
|
||||
var NewWS = &WS{}
|
||||
|
||||
// ClientClose 客户端关闭
|
||||
ClientClose(clientID string)
|
||||
// WS WebSocket通信 服务层处理
|
||||
type WS struct{}
|
||||
|
||||
// ClientReadListen 客户端读取消息监听
|
||||
// receiveType 根据接收类型进行消息处理
|
||||
ClientReadListen(wsClient *model.WSClient, receiveType int)
|
||||
|
||||
// ClientWriteListen 客户端写入消息监听
|
||||
ClientWriteListen(wsClient *model.WSClient)
|
||||
// UpgraderWs http升级ws请求
|
||||
func (s *WS) UpgraderWs(w http.ResponseWriter, r *http.Request) *websocket.Conn {
|
||||
wsUpgrader := websocket.Upgrader{
|
||||
Subprotocols: []string{"omc-ws"},
|
||||
// 设置消息发送缓冲区大小(byte),如果这个值设置得太小,可能会导致服务端在发送大型消息时遇到问题
|
||||
WriteBufferSize: 1024,
|
||||
// 消息包启用压缩
|
||||
EnableCompression: true,
|
||||
// ws握手超时时间
|
||||
HandshakeTimeout: 5 * time.Second,
|
||||
// ws握手过程中允许跨域
|
||||
CheckOrigin: func(r *http.Request) bool {
|
||||
return true
|
||||
},
|
||||
}
|
||||
conn, err := wsUpgrader.Upgrade(w, r, nil)
|
||||
if err != nil {
|
||||
logger.Errorf("ws Upgrade err: %s", err.Error())
|
||||
}
|
||||
return conn
|
||||
}
|
||||
|
||||
// ClientCreate 客户端新建
|
||||
//
|
||||
// uid 登录用户ID
|
||||
// groupIDs 用户订阅组
|
||||
// conn ws连接实例
|
||||
// childConn 子连接实例
|
||||
func (s *WS) ClientCreate(uid string, groupIDs []string, conn *websocket.Conn, childConn any) *model.WSClient {
|
||||
// clientID也可以用其他方式生成,只要能保证在所有服务端中都能保证唯一即可
|
||||
clientID := generate.Code(16)
|
||||
|
||||
wsClient := &model.WSClient{
|
||||
ID: clientID,
|
||||
Conn: conn,
|
||||
LastHeartbeat: time.Now().UnixMilli(),
|
||||
BindUid: uid,
|
||||
SubGroup: groupIDs,
|
||||
MsgChan: make(chan []byte, 100),
|
||||
StopChan: make(chan struct{}, 1), // 卡死循环标记
|
||||
ChildConn: childConn,
|
||||
}
|
||||
|
||||
// 存入客户端
|
||||
wsClients.Store(clientID, wsClient)
|
||||
|
||||
// 存入用户持有客户端
|
||||
if uid != "" {
|
||||
if v, ok := wsUsers.Load(uid); ok {
|
||||
uidClientIds := v.(*[]string)
|
||||
*uidClientIds = append(*uidClientIds, clientID)
|
||||
} else {
|
||||
wsUsers.Store(uid, &[]string{clientID})
|
||||
}
|
||||
}
|
||||
|
||||
// 存入用户订阅组
|
||||
if uid != "" && len(groupIDs) > 0 {
|
||||
for _, groupID := range groupIDs {
|
||||
if v, ok := wsGroup.Load(groupID); ok {
|
||||
groupClientIds := v.(*[]string)
|
||||
*groupClientIds = append(*groupClientIds, clientID)
|
||||
} else {
|
||||
wsGroup.Store(groupID, &[]string{clientID})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return wsClient
|
||||
}
|
||||
|
||||
// ClientClose 客户端关闭
|
||||
func (s *WS) ClientClose(clientID string) {
|
||||
v, ok := wsClients.Load(clientID)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
client := v.(*model.WSClient)
|
||||
defer func() {
|
||||
client.MsgChan <- []byte("ws:close")
|
||||
client.StopChan <- struct{}{}
|
||||
client.Conn.Close()
|
||||
wsClients.Delete(clientID)
|
||||
}()
|
||||
|
||||
// 客户端断线时自动踢出Uid绑定列表
|
||||
if client.BindUid != "" {
|
||||
if v, ok := wsUsers.Load(client.BindUid); ok {
|
||||
uidClientIds := v.(*[]string)
|
||||
if len(*uidClientIds) > 0 {
|
||||
tempClientIds := make([]string, 0, len(*uidClientIds))
|
||||
for _, v := range *uidClientIds {
|
||||
if v != client.ID {
|
||||
tempClientIds = append(tempClientIds, v)
|
||||
}
|
||||
}
|
||||
*uidClientIds = tempClientIds
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 客户端断线时自动踢出已加入的组
|
||||
if len(client.SubGroup) > 0 {
|
||||
for _, groupID := range client.SubGroup {
|
||||
v, ok := wsGroup.Load(groupID)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
groupClientIds := v.(*[]string)
|
||||
if len(*groupClientIds) > 0 {
|
||||
tempClientIds := make([]string, 0, len(*groupClientIds))
|
||||
for _, v := range *groupClientIds {
|
||||
if v != client.ID {
|
||||
tempClientIds = append(tempClientIds, v)
|
||||
}
|
||||
}
|
||||
*groupClientIds = tempClientIds
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ClientReadListen 客户端读取消息监听
|
||||
// receiveType 根据接收类型进行消息处理
|
||||
func (s *WS) ClientReadListen(wsClient *model.WSClient, receiveType int) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
logger.Errorf("ws ReadMessage Panic Error: %v", err)
|
||||
}
|
||||
}()
|
||||
for {
|
||||
// 读取消息
|
||||
messageType, msg, err := wsClient.Conn.ReadMessage()
|
||||
if err != nil {
|
||||
logger.Warnf("ws ReadMessage UID %s err: %s", wsClient.BindUid, err.Error())
|
||||
s.ClientClose(wsClient.ID)
|
||||
return
|
||||
}
|
||||
// fmt.Println(messageType, string(msg))
|
||||
|
||||
// 文本 只处理文本json
|
||||
if messageType == websocket.TextMessage {
|
||||
var reqMsg model.WSRequest
|
||||
if err := json.Unmarshal(msg, &reqMsg); err != nil {
|
||||
msgByte, _ := json.Marshal(result.ErrMsg("message format json error"))
|
||||
wsClient.MsgChan <- msgByte
|
||||
continue
|
||||
}
|
||||
// 接收器处理
|
||||
switch receiveType {
|
||||
case ReceiveCommont:
|
||||
go NewWSReceive.Commont(wsClient, reqMsg)
|
||||
case ReceiveShell:
|
||||
go NewWSReceive.Shell(wsClient, reqMsg)
|
||||
case ReceiveShellView:
|
||||
go NewWSReceive.ShellView(wsClient, reqMsg)
|
||||
case ReceiveTelnet:
|
||||
go NewWSReceive.Telnet(wsClient, reqMsg)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ClientWriteListen 客户端写入消息监听
|
||||
func (s *WS) ClientWriteListen(wsClient *model.WSClient) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
logger.Errorf("ws WriteMessage Panic Error: %v", err)
|
||||
}
|
||||
}()
|
||||
// 发客户端id确认是否连接
|
||||
msgByte, _ := json.Marshal(result.OkData(map[string]string{
|
||||
"clientId": wsClient.ID,
|
||||
}))
|
||||
wsClient.MsgChan <- msgByte
|
||||
// 消息发送监听
|
||||
for msg := range wsClient.MsgChan {
|
||||
// 关闭句柄
|
||||
if string(msg) == "ws:close" {
|
||||
wsClient.Conn.WriteMessage(websocket.CloseMessage, []byte{})
|
||||
return
|
||||
}
|
||||
// 发送消息
|
||||
err := wsClient.Conn.WriteMessage(websocket.TextMessage, msg)
|
||||
if err != nil {
|
||||
logger.Warnf("ws WriteMessage UID %s err: %s", wsClient.BindUid, err.Error())
|
||||
s.ClientClose(wsClient.ID)
|
||||
return
|
||||
}
|
||||
wsClient.LastHeartbeat = time.Now().UnixMilli()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,220 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/generate"
|
||||
"be.ems/src/framework/vo/result"
|
||||
"be.ems/src/modules/ws/model"
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
var (
|
||||
wsClients sync.Map // ws客户端 [clientId: client]
|
||||
wsUsers sync.Map // ws用户对应的多个客户端id [uid:clientIds]
|
||||
wsGroup sync.Map // ws组对应的多个客户端id [groupId:clientIds]
|
||||
)
|
||||
|
||||
// NewWSImpl 实例化服务层 WSImpl 结构体
|
||||
var NewWSImpl = &WSImpl{}
|
||||
|
||||
// WSImpl WebSocket通信 服务层处理
|
||||
type WSImpl struct{}
|
||||
|
||||
// UpgraderWs http升级ws请求
|
||||
func (s *WSImpl) UpgraderWs(w http.ResponseWriter, r *http.Request) *websocket.Conn {
|
||||
wsUpgrader := websocket.Upgrader{
|
||||
Subprotocols: []string{"omc-ws"},
|
||||
// 设置消息发送缓冲区大小(byte),如果这个值设置得太小,可能会导致服务端在发送大型消息时遇到问题
|
||||
WriteBufferSize: 1024,
|
||||
// 消息包启用压缩
|
||||
EnableCompression: true,
|
||||
// ws握手超时时间
|
||||
HandshakeTimeout: 5 * time.Second,
|
||||
// ws握手过程中允许跨域
|
||||
CheckOrigin: func(r *http.Request) bool {
|
||||
return true
|
||||
},
|
||||
}
|
||||
conn, err := wsUpgrader.Upgrade(w, r, nil)
|
||||
if err != nil {
|
||||
logger.Errorf("ws Upgrade err: %s", err.Error())
|
||||
}
|
||||
return conn
|
||||
}
|
||||
|
||||
// ClientCreate 客户端新建
|
||||
//
|
||||
// uid 登录用户ID
|
||||
// groupIDs 用户订阅组
|
||||
// conn ws连接实例
|
||||
// childConn 子连接实例
|
||||
func (s *WSImpl) ClientCreate(uid string, groupIDs []string, conn *websocket.Conn, childConn any) *model.WSClient {
|
||||
// clientID也可以用其他方式生成,只要能保证在所有服务端中都能保证唯一即可
|
||||
clientID := generate.Code(16)
|
||||
|
||||
wsClient := &model.WSClient{
|
||||
ID: clientID,
|
||||
Conn: conn,
|
||||
LastHeartbeat: time.Now().UnixMilli(),
|
||||
BindUid: uid,
|
||||
SubGroup: groupIDs,
|
||||
MsgChan: make(chan []byte, 100),
|
||||
StopChan: make(chan struct{}, 1), // 卡死循环标记
|
||||
ChildConn: childConn,
|
||||
}
|
||||
|
||||
// 存入客户端
|
||||
wsClients.Store(clientID, wsClient)
|
||||
|
||||
// 存入用户持有客户端
|
||||
if uid != "" {
|
||||
if v, ok := wsUsers.Load(uid); ok {
|
||||
uidClientIds := v.(*[]string)
|
||||
*uidClientIds = append(*uidClientIds, clientID)
|
||||
} else {
|
||||
wsUsers.Store(uid, &[]string{clientID})
|
||||
}
|
||||
}
|
||||
|
||||
// 存入用户订阅组
|
||||
if uid != "" && len(groupIDs) > 0 {
|
||||
for _, groupID := range groupIDs {
|
||||
if v, ok := wsGroup.Load(groupID); ok {
|
||||
groupClientIds := v.(*[]string)
|
||||
*groupClientIds = append(*groupClientIds, clientID)
|
||||
} else {
|
||||
wsGroup.Store(groupID, &[]string{clientID})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return wsClient
|
||||
}
|
||||
|
||||
// ClientClose 客户端关闭
|
||||
func (s *WSImpl) ClientClose(clientID string) {
|
||||
v, ok := wsClients.Load(clientID)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
client := v.(*model.WSClient)
|
||||
defer func() {
|
||||
client.MsgChan <- []byte("ws:close")
|
||||
client.StopChan <- struct{}{}
|
||||
client.Conn.Close()
|
||||
wsClients.Delete(clientID)
|
||||
}()
|
||||
|
||||
// 客户端断线时自动踢出Uid绑定列表
|
||||
if client.BindUid != "" {
|
||||
if v, ok := wsUsers.Load(client.BindUid); ok {
|
||||
uidClientIds := v.(*[]string)
|
||||
if len(*uidClientIds) > 0 {
|
||||
tempClientIds := make([]string, 0, len(*uidClientIds))
|
||||
for _, v := range *uidClientIds {
|
||||
if v != client.ID {
|
||||
tempClientIds = append(tempClientIds, v)
|
||||
}
|
||||
}
|
||||
*uidClientIds = tempClientIds
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 客户端断线时自动踢出已加入的组
|
||||
if len(client.SubGroup) > 0 {
|
||||
for _, groupID := range client.SubGroup {
|
||||
v, ok := wsGroup.Load(groupID)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
groupClientIds := v.(*[]string)
|
||||
if len(*groupClientIds) > 0 {
|
||||
tempClientIds := make([]string, 0, len(*groupClientIds))
|
||||
for _, v := range *groupClientIds {
|
||||
if v != client.ID {
|
||||
tempClientIds = append(tempClientIds, v)
|
||||
}
|
||||
}
|
||||
*groupClientIds = tempClientIds
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ClientReadListen 客户端读取消息监听
|
||||
// receiveType 根据接收类型进行消息处理
|
||||
func (s *WSImpl) ClientReadListen(wsClient *model.WSClient, receiveType int) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
logger.Errorf("ws ReadMessage Panic Error: %v", err)
|
||||
}
|
||||
}()
|
||||
for {
|
||||
// 读取消息
|
||||
messageType, msg, err := wsClient.Conn.ReadMessage()
|
||||
if err != nil {
|
||||
logger.Warnf("ws ReadMessage UID %s err: %s", wsClient.BindUid, err.Error())
|
||||
s.ClientClose(wsClient.ID)
|
||||
return
|
||||
}
|
||||
// fmt.Println(messageType, string(msg))
|
||||
|
||||
// 文本 只处理文本json
|
||||
if messageType == websocket.TextMessage {
|
||||
var reqMsg model.WSRequest
|
||||
if err := json.Unmarshal(msg, &reqMsg); err != nil {
|
||||
msgByte, _ := json.Marshal(result.ErrMsg("message format json error"))
|
||||
wsClient.MsgChan <- msgByte
|
||||
continue
|
||||
}
|
||||
// 接收器处理
|
||||
switch receiveType {
|
||||
case ReceiveCommont:
|
||||
go NewWSReceiveImpl.Commont(wsClient, reqMsg)
|
||||
case ReceiveShell:
|
||||
go NewWSReceiveImpl.Shell(wsClient, reqMsg)
|
||||
case ReceiveShellView:
|
||||
go NewWSReceiveImpl.ShellView(wsClient, reqMsg)
|
||||
case ReceiveTelnet:
|
||||
go NewWSReceiveImpl.Telnet(wsClient, reqMsg)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ClientWriteListen 客户端写入消息监听
|
||||
func (s *WSImpl) ClientWriteListen(wsClient *model.WSClient) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
logger.Errorf("ws WriteMessage Panic Error: %v", err)
|
||||
}
|
||||
}()
|
||||
// 发客户端id确认是否连接
|
||||
msgByte, _ := json.Marshal(result.OkData(map[string]string{
|
||||
"clientId": wsClient.ID,
|
||||
}))
|
||||
wsClient.MsgChan <- msgByte
|
||||
// 消息发送监听
|
||||
for msg := range wsClient.MsgChan {
|
||||
// 关闭句柄
|
||||
if string(msg) == "ws:close" {
|
||||
wsClient.Conn.WriteMessage(websocket.CloseMessage, []byte{})
|
||||
return
|
||||
}
|
||||
// 发送消息
|
||||
err := wsClient.Conn.WriteMessage(websocket.TextMessage, msg)
|
||||
if err != nil {
|
||||
logger.Warnf("ws WriteMessage UID %s err: %s", wsClient.BindUid, err.Error())
|
||||
s.ClientClose(wsClient.ID)
|
||||
return
|
||||
}
|
||||
wsClient.LastHeartbeat = time.Now().UnixMilli()
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,18 @@
|
||||
package service
|
||||
|
||||
import "be.ems/src/modules/ws/model"
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/telnet"
|
||||
"be.ems/src/framework/utils/ssh"
|
||||
"be.ems/src/framework/vo/result"
|
||||
"be.ems/src/modules/ws/model"
|
||||
"be.ems/src/modules/ws/processor"
|
||||
)
|
||||
|
||||
const (
|
||||
ReceiveCommont = iota // Commont 接收通用业务处理
|
||||
@@ -9,17 +21,245 @@ const (
|
||||
ReceiveTelnet // Telnet 接收终端交互业务处理
|
||||
)
|
||||
|
||||
// IWSReceive WebSocket消息接收处理 服务层接口
|
||||
type IWSReceive interface {
|
||||
// Commont 接收通用业务处理
|
||||
Commont(client *model.WSClient, reqMsg model.WSRequest)
|
||||
// 实例化服务层 WSReceive 结构体
|
||||
var NewWSReceive = &WSReceive{}
|
||||
|
||||
// Shell 接收终端交互业务处理
|
||||
Shell(client *model.WSClient, reqMsg model.WSRequest)
|
||||
// WSReceive WebSocket消息接收处理 服务层处理
|
||||
type WSReceive struct{}
|
||||
|
||||
// ShellView 接收查看文件终端交互业务处理
|
||||
ShellView(client *model.WSClient, reqMsg model.WSRequest)
|
||||
|
||||
// Telnet 接收终端交互业务处理
|
||||
Telnet(client *model.WSClient, reqMsg model.WSRequest)
|
||||
// close 关闭服务连接
|
||||
func (s *WSReceive) close(client *model.WSClient) {
|
||||
// 主动关闭
|
||||
resultByte, _ := json.Marshal(result.OkMsg("user initiated closure"))
|
||||
client.MsgChan <- resultByte
|
||||
// 等待1s后关闭连接
|
||||
time.Sleep(1 * time.Second)
|
||||
NewWS.ClientClose(client.ID)
|
||||
}
|
||||
|
||||
// Commont 接收通用业务处理
|
||||
func (s *WSReceive) Commont(client *model.WSClient, reqMsg model.WSRequest) {
|
||||
// 必传requestId确认消息
|
||||
if reqMsg.RequestID == "" {
|
||||
msg := "message requestId is required"
|
||||
logger.Infof("ws Commont UID %s err: %s", client.BindUid, msg)
|
||||
msgByte, _ := json.Marshal(result.ErrMsg(msg))
|
||||
client.MsgChan <- msgByte
|
||||
return
|
||||
}
|
||||
|
||||
var resByte []byte
|
||||
var err error
|
||||
|
||||
switch reqMsg.Type {
|
||||
case "close":
|
||||
s.close(client)
|
||||
return
|
||||
case "ps":
|
||||
resByte, err = processor.GetProcessData(reqMsg.RequestID, reqMsg.Data)
|
||||
case "net":
|
||||
resByte, err = processor.GetNetConnections(reqMsg.RequestID, reqMsg.Data)
|
||||
case "ims_cdr":
|
||||
resByte, err = processor.GetCDRConnectByIMS(reqMsg.RequestID, reqMsg.Data)
|
||||
case "smf_cdr":
|
||||
resByte, err = processor.GetCDRConnectBySMF(reqMsg.RequestID, reqMsg.Data)
|
||||
case "smsc_cdr":
|
||||
resByte, err = processor.GetCDRConnectBySMSC(reqMsg.RequestID, reqMsg.Data)
|
||||
case "amf_ue":
|
||||
resByte, err = processor.GetUEConnectByAMF(reqMsg.RequestID, reqMsg.Data)
|
||||
case "mme_ue":
|
||||
resByte, err = processor.GetUEConnectByMME(reqMsg.RequestID, reqMsg.Data)
|
||||
case "upf_tf":
|
||||
resByte, err = processor.GetUPFTotalFlow(reqMsg.RequestID, reqMsg.Data)
|
||||
case "ne_state":
|
||||
resByte, err = processor.GetNeState(reqMsg.RequestID, reqMsg.Data)
|
||||
default:
|
||||
err = fmt.Errorf("message type %s not supported", reqMsg.Type)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
logger.Warnf("ws Commont UID %s err: %s", client.BindUid, err.Error())
|
||||
msgByte, _ := json.Marshal(result.ErrMsg(err.Error()))
|
||||
client.MsgChan <- msgByte
|
||||
return
|
||||
}
|
||||
if len(resByte) > 0 {
|
||||
client.MsgChan <- resByte
|
||||
}
|
||||
}
|
||||
|
||||
// Shell 接收终端交互业务处理
|
||||
func (s *WSReceive) Shell(client *model.WSClient, reqMsg model.WSRequest) {
|
||||
// 必传requestId确认消息
|
||||
if reqMsg.RequestID == "" {
|
||||
msg := "message requestId is required"
|
||||
logger.Infof("ws Shell UID %s err: %s", client.BindUid, msg)
|
||||
msgByte, _ := json.Marshal(result.ErrMsg(msg))
|
||||
client.MsgChan <- msgByte
|
||||
return
|
||||
}
|
||||
|
||||
var resByte []byte
|
||||
var err error
|
||||
|
||||
switch reqMsg.Type {
|
||||
case "close":
|
||||
s.close(client)
|
||||
return
|
||||
case "ssh":
|
||||
// SSH会话消息接收写入会话
|
||||
command := reqMsg.Data.(string)
|
||||
sshClientSession := client.ChildConn.(*ssh.SSHClientSession)
|
||||
_, err = sshClientSession.Write(command)
|
||||
case "ssh_resize":
|
||||
// SSH会话窗口重置
|
||||
msgByte, _ := json.Marshal(reqMsg.Data)
|
||||
var data struct {
|
||||
Cols int `json:"cols"`
|
||||
Rows int `json:"rows"`
|
||||
}
|
||||
err = json.Unmarshal(msgByte, &data)
|
||||
if err == nil {
|
||||
sshClientSession := client.ChildConn.(*ssh.SSHClientSession)
|
||||
err = sshClientSession.Session.WindowChange(data.Rows, data.Cols)
|
||||
}
|
||||
default:
|
||||
err = fmt.Errorf("message type %s not supported", reqMsg.Type)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
logger.Warnf("ws Shell UID %s err: %s", client.BindUid, err.Error())
|
||||
msgByte, _ := json.Marshal(result.ErrMsg(err.Error()))
|
||||
client.MsgChan <- msgByte
|
||||
if err == io.EOF {
|
||||
// 等待1s后关闭连接
|
||||
time.Sleep(1 * time.Second)
|
||||
client.StopChan <- struct{}{}
|
||||
}
|
||||
return
|
||||
}
|
||||
if len(resByte) > 0 {
|
||||
client.MsgChan <- resByte
|
||||
}
|
||||
}
|
||||
|
||||
// ShellView 接收查看文件终端交互业务处理
|
||||
func (s *WSReceive) ShellView(client *model.WSClient, reqMsg model.WSRequest) {
|
||||
// 必传requestId确认消息
|
||||
if reqMsg.RequestID == "" {
|
||||
msg := "message requestId is required"
|
||||
logger.Infof("ws ShellView UID %s err: %s", client.BindUid, msg)
|
||||
msgByte, _ := json.Marshal(result.ErrMsg(msg))
|
||||
client.MsgChan <- msgByte
|
||||
return
|
||||
}
|
||||
|
||||
var resByte []byte
|
||||
var err error
|
||||
|
||||
switch reqMsg.Type {
|
||||
case "close":
|
||||
s.close(client)
|
||||
return
|
||||
case "cat", "tail":
|
||||
var command string
|
||||
if reqMsg.Type == "cat" {
|
||||
command, err = processor.ParseCat(reqMsg.Data)
|
||||
}
|
||||
if reqMsg.Type == "tail" {
|
||||
command, err = processor.ParseTail(reqMsg.Data)
|
||||
}
|
||||
if command != "" && err == nil {
|
||||
sshClientSession := client.ChildConn.(*ssh.SSHClientSession)
|
||||
_, err = sshClientSession.Write(command)
|
||||
}
|
||||
case "ctrl-c":
|
||||
// 模拟按下 Ctrl+C
|
||||
sshClientSession := client.ChildConn.(*ssh.SSHClientSession)
|
||||
_, err = sshClientSession.Write("\u0003\n")
|
||||
case "resize":
|
||||
// 会话窗口重置
|
||||
msgByte, _ := json.Marshal(reqMsg.Data)
|
||||
var data struct {
|
||||
Cols int `json:"cols"`
|
||||
Rows int `json:"rows"`
|
||||
}
|
||||
err = json.Unmarshal(msgByte, &data)
|
||||
if err == nil {
|
||||
sshClientSession := client.ChildConn.(*ssh.SSHClientSession)
|
||||
err = sshClientSession.Session.WindowChange(data.Rows, data.Cols)
|
||||
}
|
||||
default:
|
||||
err = fmt.Errorf("message type %s not supported", reqMsg.Type)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
logger.Warnf("ws ShellView UID %s err: %s", client.BindUid, err.Error())
|
||||
msgByte, _ := json.Marshal(result.ErrMsg(err.Error()))
|
||||
client.MsgChan <- msgByte
|
||||
if err == io.EOF {
|
||||
// 等待1s后关闭连接
|
||||
time.Sleep(1 * time.Second)
|
||||
client.StopChan <- struct{}{}
|
||||
}
|
||||
return
|
||||
}
|
||||
if len(resByte) > 0 {
|
||||
client.MsgChan <- resByte
|
||||
}
|
||||
}
|
||||
|
||||
// Telnet 接收终端交互业务处理
|
||||
func (s *WSReceive) Telnet(client *model.WSClient, reqMsg model.WSRequest) {
|
||||
// 必传requestId确认消息
|
||||
if reqMsg.RequestID == "" {
|
||||
msg := "message requestId is required"
|
||||
logger.Infof("ws Shell UID %s err: %s", client.BindUid, msg)
|
||||
msgByte, _ := json.Marshal(result.ErrMsg(msg))
|
||||
client.MsgChan <- msgByte
|
||||
return
|
||||
}
|
||||
|
||||
var resByte []byte
|
||||
var err error
|
||||
|
||||
switch reqMsg.Type {
|
||||
case "close":
|
||||
s.close(client)
|
||||
return
|
||||
case "telnet":
|
||||
// Telnet会话消息接收写入会话
|
||||
command := reqMsg.Data.(string)
|
||||
telnetClientSession := client.ChildConn.(*telnet.TelnetClientSession)
|
||||
_, err = telnetClientSession.Write(command)
|
||||
case "telnet_resize":
|
||||
// Telnet会话窗口重置
|
||||
msgByte, _ := json.Marshal(reqMsg.Data)
|
||||
var data struct {
|
||||
Cols int `json:"cols"`
|
||||
Rows int `json:"rows"`
|
||||
}
|
||||
err = json.Unmarshal(msgByte, &data)
|
||||
if err == nil {
|
||||
// telnetClientSession := client.ChildConn.(*telnet.TelnetClientSession)
|
||||
// _ = telnetClientSession.WindowChange(data.Rows, data.Cols)
|
||||
}
|
||||
default:
|
||||
err = fmt.Errorf("message type %s not supported", reqMsg.Type)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
logger.Warnf("ws Shell UID %s err: %s", client.BindUid, err.Error())
|
||||
msgByte, _ := json.Marshal(result.ErrMsg(err.Error()))
|
||||
client.MsgChan <- msgByte
|
||||
if err == io.EOF {
|
||||
// 等待1s后关闭连接
|
||||
time.Sleep(1 * time.Second)
|
||||
client.StopChan <- struct{}{}
|
||||
}
|
||||
return
|
||||
}
|
||||
if len(resByte) > 0 {
|
||||
client.MsgChan <- resByte
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,258 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/telnet"
|
||||
"be.ems/src/framework/utils/ssh"
|
||||
"be.ems/src/framework/vo/result"
|
||||
"be.ems/src/modules/ws/model"
|
||||
"be.ems/src/modules/ws/processor"
|
||||
)
|
||||
|
||||
// 实例化服务层 WSReceiveImpl 结构体
|
||||
var NewWSReceiveImpl = &WSReceiveImpl{}
|
||||
|
||||
// WSReceiveImpl WebSocket消息接收处理 服务层处理
|
||||
type WSReceiveImpl struct{}
|
||||
|
||||
// Commont 接收通用业务处理
|
||||
func (s *WSReceiveImpl) close(client *model.WSClient) {
|
||||
// 主动关闭
|
||||
resultByte, _ := json.Marshal(result.OkMsg("user initiated closure"))
|
||||
client.MsgChan <- resultByte
|
||||
// 等待1s后关闭连接
|
||||
time.Sleep(1 * time.Second)
|
||||
NewWSImpl.ClientClose(client.ID)
|
||||
}
|
||||
|
||||
// Commont 接收通用业务处理
|
||||
func (s *WSReceiveImpl) Commont(client *model.WSClient, reqMsg model.WSRequest) {
|
||||
// 必传requestId确认消息
|
||||
if reqMsg.RequestID == "" {
|
||||
msg := "message requestId is required"
|
||||
logger.Infof("ws Commont UID %s err: %s", client.BindUid, msg)
|
||||
msgByte, _ := json.Marshal(result.ErrMsg(msg))
|
||||
client.MsgChan <- msgByte
|
||||
return
|
||||
}
|
||||
|
||||
var resByte []byte
|
||||
var err error
|
||||
|
||||
switch reqMsg.Type {
|
||||
case "close":
|
||||
s.close(client)
|
||||
return
|
||||
case "ps":
|
||||
resByte, err = processor.GetProcessData(reqMsg.RequestID, reqMsg.Data)
|
||||
case "net":
|
||||
resByte, err = processor.GetNetConnections(reqMsg.RequestID, reqMsg.Data)
|
||||
case "ims_cdr":
|
||||
resByte, err = processor.GetCDRConnectByIMS(reqMsg.RequestID, reqMsg.Data)
|
||||
case "smf_cdr":
|
||||
resByte, err = processor.GetCDRConnectBySMF(reqMsg.RequestID, reqMsg.Data)
|
||||
case "smsc_cdr":
|
||||
resByte, err = processor.GetCDRConnectBySMSC(reqMsg.RequestID, reqMsg.Data)
|
||||
case "amf_ue":
|
||||
resByte, err = processor.GetUEConnectByAMF(reqMsg.RequestID, reqMsg.Data)
|
||||
case "mme_ue":
|
||||
resByte, err = processor.GetUEConnectByMME(reqMsg.RequestID, reqMsg.Data)
|
||||
case "upf_tf":
|
||||
resByte, err = processor.GetUPFTotalFlow(reqMsg.RequestID, reqMsg.Data)
|
||||
case "ne_state":
|
||||
resByte, err = processor.GetNeState(reqMsg.RequestID, reqMsg.Data)
|
||||
default:
|
||||
err = fmt.Errorf("message type %s not supported", reqMsg.Type)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
logger.Warnf("ws Commont UID %s err: %s", client.BindUid, err.Error())
|
||||
msgByte, _ := json.Marshal(result.ErrMsg(err.Error()))
|
||||
client.MsgChan <- msgByte
|
||||
return
|
||||
}
|
||||
if len(resByte) > 0 {
|
||||
client.MsgChan <- resByte
|
||||
}
|
||||
}
|
||||
|
||||
// Shell 接收终端交互业务处理
|
||||
func (s *WSReceiveImpl) Shell(client *model.WSClient, reqMsg model.WSRequest) {
|
||||
// 必传requestId确认消息
|
||||
if reqMsg.RequestID == "" {
|
||||
msg := "message requestId is required"
|
||||
logger.Infof("ws Shell UID %s err: %s", client.BindUid, msg)
|
||||
msgByte, _ := json.Marshal(result.ErrMsg(msg))
|
||||
client.MsgChan <- msgByte
|
||||
return
|
||||
}
|
||||
|
||||
var resByte []byte
|
||||
var err error
|
||||
|
||||
switch reqMsg.Type {
|
||||
case "close":
|
||||
s.close(client)
|
||||
return
|
||||
case "ssh":
|
||||
// SSH会话消息接收写入会话
|
||||
command := reqMsg.Data.(string)
|
||||
sshClientSession := client.ChildConn.(*ssh.SSHClientSession)
|
||||
_, err = sshClientSession.Write(command)
|
||||
case "ssh_resize":
|
||||
// SSH会话窗口重置
|
||||
msgByte, _ := json.Marshal(reqMsg.Data)
|
||||
var data struct {
|
||||
Cols int `json:"cols"`
|
||||
Rows int `json:"rows"`
|
||||
}
|
||||
err = json.Unmarshal(msgByte, &data)
|
||||
if err == nil {
|
||||
sshClientSession := client.ChildConn.(*ssh.SSHClientSession)
|
||||
err = sshClientSession.Session.WindowChange(data.Rows, data.Cols)
|
||||
}
|
||||
default:
|
||||
err = fmt.Errorf("message type %s not supported", reqMsg.Type)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
logger.Warnf("ws Shell UID %s err: %s", client.BindUid, err.Error())
|
||||
msgByte, _ := json.Marshal(result.ErrMsg(err.Error()))
|
||||
client.MsgChan <- msgByte
|
||||
if err == io.EOF {
|
||||
// 等待1s后关闭连接
|
||||
time.Sleep(1 * time.Second)
|
||||
client.StopChan <- struct{}{}
|
||||
}
|
||||
return
|
||||
}
|
||||
if len(resByte) > 0 {
|
||||
client.MsgChan <- resByte
|
||||
}
|
||||
}
|
||||
|
||||
// ShellView 接收查看文件终端交互业务处理
|
||||
func (s *WSReceiveImpl) ShellView(client *model.WSClient, reqMsg model.WSRequest) {
|
||||
// 必传requestId确认消息
|
||||
if reqMsg.RequestID == "" {
|
||||
msg := "message requestId is required"
|
||||
logger.Infof("ws ShellView UID %s err: %s", client.BindUid, msg)
|
||||
msgByte, _ := json.Marshal(result.ErrMsg(msg))
|
||||
client.MsgChan <- msgByte
|
||||
return
|
||||
}
|
||||
|
||||
var resByte []byte
|
||||
var err error
|
||||
|
||||
switch reqMsg.Type {
|
||||
case "close":
|
||||
s.close(client)
|
||||
return
|
||||
case "cat", "tail":
|
||||
var command string
|
||||
if reqMsg.Type == "cat" {
|
||||
command, err = processor.ParseCat(reqMsg.Data)
|
||||
}
|
||||
if reqMsg.Type == "tail" {
|
||||
command, err = processor.ParseTail(reqMsg.Data)
|
||||
}
|
||||
if command != "" && err == nil {
|
||||
sshClientSession := client.ChildConn.(*ssh.SSHClientSession)
|
||||
_, err = sshClientSession.Write(command)
|
||||
}
|
||||
case "ctrl-c":
|
||||
// 模拟按下 Ctrl+C
|
||||
sshClientSession := client.ChildConn.(*ssh.SSHClientSession)
|
||||
_, err = sshClientSession.Write("\u0003\n")
|
||||
case "resize":
|
||||
// 会话窗口重置
|
||||
msgByte, _ := json.Marshal(reqMsg.Data)
|
||||
var data struct {
|
||||
Cols int `json:"cols"`
|
||||
Rows int `json:"rows"`
|
||||
}
|
||||
err = json.Unmarshal(msgByte, &data)
|
||||
if err == nil {
|
||||
sshClientSession := client.ChildConn.(*ssh.SSHClientSession)
|
||||
err = sshClientSession.Session.WindowChange(data.Rows, data.Cols)
|
||||
}
|
||||
default:
|
||||
err = fmt.Errorf("message type %s not supported", reqMsg.Type)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
logger.Warnf("ws ShellView UID %s err: %s", client.BindUid, err.Error())
|
||||
msgByte, _ := json.Marshal(result.ErrMsg(err.Error()))
|
||||
client.MsgChan <- msgByte
|
||||
if err == io.EOF {
|
||||
// 等待1s后关闭连接
|
||||
time.Sleep(1 * time.Second)
|
||||
client.StopChan <- struct{}{}
|
||||
}
|
||||
return
|
||||
}
|
||||
if len(resByte) > 0 {
|
||||
client.MsgChan <- resByte
|
||||
}
|
||||
}
|
||||
|
||||
// Telnet 接收终端交互业务处理
|
||||
func (s *WSReceiveImpl) Telnet(client *model.WSClient, reqMsg model.WSRequest) {
|
||||
// 必传requestId确认消息
|
||||
if reqMsg.RequestID == "" {
|
||||
msg := "message requestId is required"
|
||||
logger.Infof("ws Shell UID %s err: %s", client.BindUid, msg)
|
||||
msgByte, _ := json.Marshal(result.ErrMsg(msg))
|
||||
client.MsgChan <- msgByte
|
||||
return
|
||||
}
|
||||
|
||||
var resByte []byte
|
||||
var err error
|
||||
|
||||
switch reqMsg.Type {
|
||||
case "close":
|
||||
s.close(client)
|
||||
return
|
||||
case "telnet":
|
||||
// Telnet会话消息接收写入会话
|
||||
command := reqMsg.Data.(string)
|
||||
telnetClientSession := client.ChildConn.(*telnet.TelnetClientSession)
|
||||
_, err = telnetClientSession.Write(command)
|
||||
case "telnet_resize":
|
||||
// Telnet会话窗口重置
|
||||
msgByte, _ := json.Marshal(reqMsg.Data)
|
||||
var data struct {
|
||||
Cols int `json:"cols"`
|
||||
Rows int `json:"rows"`
|
||||
}
|
||||
err = json.Unmarshal(msgByte, &data)
|
||||
if err == nil {
|
||||
// telnetClientSession := client.ChildConn.(*telnet.TelnetClientSession)
|
||||
// _ = telnetClientSession.WindowChange(data.Rows, data.Cols)
|
||||
}
|
||||
default:
|
||||
err = fmt.Errorf("message type %s not supported", reqMsg.Type)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
logger.Warnf("ws Shell UID %s err: %s", client.BindUid, err.Error())
|
||||
msgByte, _ := json.Marshal(result.ErrMsg(err.Error()))
|
||||
client.MsgChan <- msgByte
|
||||
if err == io.EOF {
|
||||
// 等待1s后关闭连接
|
||||
time.Sleep(1 * time.Second)
|
||||
client.StopChan <- struct{}{}
|
||||
}
|
||||
return
|
||||
}
|
||||
if len(resByte) > 0 {
|
||||
client.MsgChan <- resByte
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,87 @@
|
||||
package service
|
||||
|
||||
// IWSSend WebSocket消息发送处理 服务层接口
|
||||
type IWSSend interface {
|
||||
// ByClientID 给已知客户端发消息
|
||||
ByClientID(clientID string, data any) error
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
// ByGroupID 给订阅组的客户端发送消息
|
||||
ByGroupID(gid string, data any) error
|
||||
"be.ems/src/framework/vo/result"
|
||||
"be.ems/src/modules/ws/model"
|
||||
)
|
||||
|
||||
// 订阅组指定编号为支持服务器向客户端主动推送数据
|
||||
const (
|
||||
// 组号-其他
|
||||
GROUP_OTHER = "0"
|
||||
// 组号-跟踪任务数据变更 2_traceId
|
||||
GROUP_TRACE = "2_"
|
||||
// 组号-指标通用 10_neType_neId
|
||||
GROUP_KPI = "10_"
|
||||
// 组号-指标UPF 12_neId
|
||||
GROUP_KPI_UPF = "12_"
|
||||
// 组号-自定义KPI指标20_neType_neId
|
||||
GROUP_KPI_C = "20_"
|
||||
// 组号-IMS_CDR会话事件 1005_neId
|
||||
GROUP_IMS_CDR = "1005_"
|
||||
// 组号-SMF_CDR会话事件 1006_neId
|
||||
GROUP_SMF_CDR = "1006_"
|
||||
// 组号-SMSC_CDR会话事件 1007_neId
|
||||
GROUP_SMSC_CDR = "1007_"
|
||||
// 组号-AMF_UE会话事件
|
||||
GROUP_AMF_UE = "1010"
|
||||
// 组号-MME_UE会话事件 1011_neId
|
||||
GROUP_MME_UE = "1011_"
|
||||
)
|
||||
|
||||
// 实例化服务层 WSSend 结构体
|
||||
var NewWSSend = &WSSend{}
|
||||
|
||||
// WSSend WebSocket消息发送处理 服务层处理
|
||||
type WSSend struct{}
|
||||
|
||||
// ByClientID 给已知客户端发消息
|
||||
func (s *WSSend) ByClientID(clientID string, data any) error {
|
||||
v, ok := wsClients.Load(clientID)
|
||||
if !ok {
|
||||
return fmt.Errorf("no fount client ID: %s", clientID)
|
||||
}
|
||||
|
||||
dataByte, err := json.Marshal(result.OkData(data))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client := v.(*model.WSClient)
|
||||
if len(client.MsgChan) > 90 {
|
||||
NewWS.ClientClose(client.ID)
|
||||
return fmt.Errorf("msg chan over 90 will close client ID: %s", clientID)
|
||||
}
|
||||
client.MsgChan <- dataByte
|
||||
return nil
|
||||
}
|
||||
|
||||
// ByGroupID 给订阅组的客户端发送消息
|
||||
func (s *WSSend) ByGroupID(groupID string, data any) error {
|
||||
clientIds, ok := wsGroup.Load(groupID)
|
||||
if !ok {
|
||||
return fmt.Errorf("no fount Group ID: %s", groupID)
|
||||
}
|
||||
|
||||
// 检查组内是否有客户端
|
||||
ids := clientIds.(*[]string)
|
||||
if len(*ids) == 0 {
|
||||
return fmt.Errorf("no members in the group")
|
||||
}
|
||||
|
||||
// 遍历给客户端发消息
|
||||
for _, clientId := range *ids {
|
||||
err := s.ByClientID(clientId, map[string]any{
|
||||
"groupId": groupID,
|
||||
"data": data,
|
||||
})
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"be.ems/src/framework/vo/result"
|
||||
"be.ems/src/modules/ws/model"
|
||||
)
|
||||
|
||||
// 订阅组指定编号为支持服务器向客户端主动推送数据
|
||||
const (
|
||||
// 组号-其他
|
||||
GROUP_OTHER = "0"
|
||||
// 组号-指标通用 10_neType_neId
|
||||
GROUP_KPI = "10_"
|
||||
// 组号-指标UPF 12_neId
|
||||
GROUP_KPI_UPF = "12_"
|
||||
// 组号-自定义KPI指标20_neType_neId
|
||||
GROUP_KPI_C = "20_"
|
||||
// 组号-IMS_CDR会话事件 1005_neId
|
||||
GROUP_IMS_CDR = "1005_"
|
||||
// 组号-SMF_CDR会话事件 1006_neId
|
||||
GROUP_SMF_CDR = "1006_"
|
||||
// 组号-SMSC_CDR会话事件 1007_neId
|
||||
GROUP_SMSC_CDR = "1007_"
|
||||
// 组号-AMF_UE会话事件
|
||||
GROUP_AMF_UE = "1010"
|
||||
// 组号-MME_UE会话事件 1011_neId
|
||||
GROUP_MME_UE = "1011_"
|
||||
)
|
||||
|
||||
// 实例化服务层 WSSendImpl 结构体
|
||||
var NewWSSendImpl = &WSSendImpl{}
|
||||
|
||||
// IWSSend WebSocket消息发送处理 服务层处理
|
||||
type WSSendImpl struct{}
|
||||
|
||||
// ByClientID 给已知客户端发消息
|
||||
func (s *WSSendImpl) ByClientID(clientID string, data any) error {
|
||||
v, ok := wsClients.Load(clientID)
|
||||
if !ok {
|
||||
return fmt.Errorf("no fount client ID: %s", clientID)
|
||||
}
|
||||
|
||||
dataByte, err := json.Marshal(result.OkData(data))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client := v.(*model.WSClient)
|
||||
if len(client.MsgChan) > 90 {
|
||||
NewWSImpl.ClientClose(client.ID)
|
||||
return fmt.Errorf("msg chan over 90 will close client ID: %s", clientID)
|
||||
}
|
||||
client.MsgChan <- dataByte
|
||||
return nil
|
||||
}
|
||||
|
||||
// ByGroupID 给订阅组的客户端发送消息
|
||||
func (s *WSSendImpl) ByGroupID(groupID string, data any) error {
|
||||
clientIds, ok := wsGroup.Load(groupID)
|
||||
if !ok {
|
||||
return fmt.Errorf("no fount Group ID: %s", groupID)
|
||||
}
|
||||
|
||||
// 检查组内是否有客户端
|
||||
ids := clientIds.(*[]string)
|
||||
if len(*ids) == 0 {
|
||||
return fmt.Errorf("no members in the group")
|
||||
}
|
||||
|
||||
// 遍历给客户端发消息
|
||||
for _, clientId := range *ids {
|
||||
err := s.ByClientID(clientId, map[string]any{
|
||||
"groupId": groupID,
|
||||
"data": data,
|
||||
})
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
7567
sshsvc/mibs/CINTEL-HLR-MIB.my
Normal file
7567
sshsvc/mibs/CINTEL-HLR-MIB.my
Normal file
File diff suppressed because it is too large
Load Diff
BIN
sshsvc/mibs/CINTEL-HLR-MIB.smidb
Normal file
BIN
sshsvc/mibs/CINTEL-HLR-MIB.smidb
Normal file
Binary file not shown.
656
sshsvc/mibs/CINTEL-MIB.my
Normal file
656
sshsvc/mibs/CINTEL-MIB.my
Normal file
@@ -0,0 +1,656 @@
|
||||
--
|
||||
-- CINTEL-MIB.my
|
||||
-- MIB generated by MG-SOFT Visual MIB Builder Version 7.0 Build 209
|
||||
-- Friday, December 16, 2011 at 15:52:13
|
||||
--
|
||||
|
||||
CINTEL-MIB DEFINITIONS ::= BEGIN
|
||||
|
||||
IMPORTS
|
||||
enterprises, TimeTicks, MODULE-IDENTITY
|
||||
FROM SNMPv2-SMI
|
||||
TEXTUAL-CONVENTION
|
||||
FROM SNMPv2-TC;
|
||||
|
||||
|
||||
-- 1.3.6.1.4.1.1379.2
|
||||
cintelSS MODULE-IDENTITY
|
||||
LAST-UPDATED "201706041222Z" -- June 04, 2017 at 12:22 GMT
|
||||
ORGANIZATION
|
||||
"CINTEL"
|
||||
CONTACT-INFO
|
||||
"cintel
|
||||
support@cintel.com.cn"
|
||||
DESCRIPTION
|
||||
"The MIB module for cintel's Softswitch products."
|
||||
REVISION "201706041223Z" -- June 04, 2017 at 12:23 GMT
|
||||
DESCRIPTION
|
||||
"This is the first release version of the MIB"
|
||||
::= { cintelNS 2 }
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Type definitions
|
||||
--
|
||||
|
||||
AdminStateChoices ::= INTEGER
|
||||
{
|
||||
locked(0),
|
||||
unlocked(1),
|
||||
shutDown(2)
|
||||
}
|
||||
|
||||
OperStateChoices ::= INTEGER
|
||||
{
|
||||
disable(0),
|
||||
enable(1)
|
||||
}
|
||||
|
||||
AvailStateChoices ::= INTEGER
|
||||
{
|
||||
inTest(0),
|
||||
failed(1),
|
||||
powerOff(2),
|
||||
offLine(3),
|
||||
onLine(4),
|
||||
dependency(5),
|
||||
degraded(6),
|
||||
notInstalled(7)
|
||||
}
|
||||
|
||||
|
||||
--
|
||||
-- Textual conventions
|
||||
--
|
||||
|
||||
-- TEXTUAL-CONVENTION MACRO ::=
|
||||
-- BEGIN
|
||||
-- TYPE NOTATION ::=
|
||||
-- DisplayPart
|
||||
-- "STATUS" Status
|
||||
-- "DESCRIPTION" Text
|
||||
-- ReferPart
|
||||
-- "SYNTAX" Syntax
|
||||
--
|
||||
-- VALUE NOTATION ::=
|
||||
-- value(VALUE Syntax)
|
||||
--
|
||||
-- DisplayPart ::=
|
||||
-- "DISPLAY-HINT" Text
|
||||
-- | empty
|
||||
--
|
||||
-- Status ::=
|
||||
-- "current"
|
||||
-- | "deprecated"
|
||||
-- | "obsolete"
|
||||
--
|
||||
-- ReferPart ::=
|
||||
-- "REFERENCE" Text
|
||||
-- | empty
|
||||
--
|
||||
-- -- -- uses the NVT ASCII character set
|
||||
-- Text ::= """" string """"
|
||||
--
|
||||
-- Syntax ::=
|
||||
-- type(ObjectSyntax)
|
||||
-- | "BITS" "{" Kibbles "}"
|
||||
-- Kibbles ::=
|
||||
-- Kibble
|
||||
-- | Kibbles "," Kibble
|
||||
-- Kibble ::=
|
||||
-- identifier "(" nonNegativeNumber ")"
|
||||
-- END
|
||||
DisplayString8 ::= TEXTUAL-CONVENTION
|
||||
DISPLAY-HINT
|
||||
"8a"
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Represents textual information taken from the NVT ASCII
|
||||
character set, as defined in pages 4, 10-11 of RFC 854.
|
||||
|
||||
To summarize RFC 854, the NVT ASCII repertoire specifies:
|
||||
|
||||
- the use of character codes 0-127 (decimal)
|
||||
|
||||
- the graphics characters (32-126) are interpreted as
|
||||
US ASCII
|
||||
|
||||
- NUL, LF, CR, BEL, BS, HT, VT and FF have the special
|
||||
meanings specified in RFC 854
|
||||
|
||||
- the other 25 codes have no standard interpretation
|
||||
|
||||
- the sequence 'CR LF' means newline
|
||||
|
||||
- the sequence 'CR NUL' means carriage-return
|
||||
|
||||
- an 'LF' not preceded by a 'CR' means moving to the
|
||||
same column on the next line.
|
||||
|
||||
- the sequence 'CR x' for any x other than LF or NUL is
|
||||
illegal. (Note that this also means that a string may
|
||||
end with either 'CR LF' or 'CR NUL', but not with CR.)
|
||||
|
||||
Any object defined using this syntax may not exceed 255
|
||||
characters in length."
|
||||
SYNTAX OCTET STRING (SIZE (0..8))
|
||||
|
||||
DisplayString16 ::= TEXTUAL-CONVENTION
|
||||
DISPLAY-HINT
|
||||
"16a"
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"A version of DisplayString that contains only 16 characters most."
|
||||
SYNTAX OCTET STRING (SIZE (0..16))
|
||||
|
||||
DisplayString32 ::= TEXTUAL-CONVENTION
|
||||
DISPLAY-HINT
|
||||
"32a"
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"A version of DisplayString that contains only 32 characters most."
|
||||
SYNTAX OCTET STRING (SIZE (0..32))
|
||||
|
||||
DisplayString64 ::= TEXTUAL-CONVENTION
|
||||
DISPLAY-HINT
|
||||
"64a"
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"A version of DisplayString that contains only 64 characters most."
|
||||
SYNTAX OCTET STRING (SIZE (0..64))
|
||||
|
||||
DisplayString ::= TEXTUAL-CONVENTION
|
||||
DISPLAY-HINT
|
||||
"255a"
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"A version of DisplayString that contains only 255 characters most."
|
||||
SYNTAX OCTET STRING (SIZE (0..255))
|
||||
|
||||
RowStatus ::= TEXTUAL-CONVENTION
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"The RowStatus textual convention is used to manage the
|
||||
creation and deletion of conceptual rows, and is used as the
|
||||
value of the SYNTAX clause for the status column of a
|
||||
conceptual row (as described in Section 7.7.1 of [2].)
|
||||
|
||||
The status column has six defined values:
|
||||
|
||||
- `active', which indicates that the conceptual row is
|
||||
available for use by the managed device;
|
||||
|
||||
- `notInService', which indicates that the conceptual
|
||||
row exists in the agent, but is unavailable for use by
|
||||
the managed device (see NOTE below);
|
||||
|
||||
- `notReady', which indicates that the conceptual row
|
||||
exists in the agent, but is missing information
|
||||
necessary in order to be available for use by the
|
||||
managed device;
|
||||
|
||||
- `createAndGo', which is supplied by a management
|
||||
station wishing to create a new instance of a
|
||||
conceptual row and to have its status automatically set
|
||||
to active, making it available for use by the managed
|
||||
device;
|
||||
|
||||
- `createAndWait', which is supplied by a management
|
||||
station wishing to create a new instance of a
|
||||
conceptual row (but not make it available for use by
|
||||
the managed device); and,
|
||||
|
||||
- `destroy', which is supplied by a management station
|
||||
wishing to delete all of the instances associated with
|
||||
an existing conceptual row.
|
||||
|
||||
Whereas five of the six values (all except `notReady') may
|
||||
be specified in a management protocol set operation, only
|
||||
three values will be returned in response to a management
|
||||
protocol retrieval operation: `notReady', `notInService' or
|
||||
`active'. That is, when queried, an existing conceptual row
|
||||
has only three states: it is either available for use by
|
||||
the managed device (the status column has value `active');
|
||||
it is not available for use by the managed device, though
|
||||
the agent has sufficient information to make it so (the
|
||||
status column has value `notInService'); or, it is not
|
||||
available for use by the managed device, and an attempt to
|
||||
make it so would fail because the agent has insufficient
|
||||
information (the state column has value `notReady').
|
||||
|
||||
NOTE WELL
|
||||
|
||||
This textual convention may be used for a MIB table,
|
||||
irrespective of whether the values of that table's
|
||||
conceptual rows are able to be modified while it is
|
||||
active, or whether its conceptual rows must be taken
|
||||
out of service in order to be modified. That is, it is
|
||||
the responsibility of the DESCRIPTION clause of the
|
||||
status column to specify whether the status column must
|
||||
not be `active' in order for the value of some other
|
||||
column of the same conceptual row to be modified. If
|
||||
such a specification is made, affected columns may be
|
||||
changed by an SNMP set PDU if the RowStatus would not
|
||||
be equal to `active' either immediately before or after
|
||||
processing the PDU. In other words, if the PDU also
|
||||
contained a varbind that would change the RowStatus
|
||||
value, the column in question may be changed if the
|
||||
RowStatus was not equal to `active' as the PDU was
|
||||
received, or if the varbind sets the status to a value
|
||||
other than 'active'.
|
||||
|
||||
|
||||
Also note that whenever any elements of a row exist, the
|
||||
RowStatus column must also exist.
|
||||
|
||||
To summarize the effect of having a conceptual row with a
|
||||
status column having a SYNTAX clause value of RowStatus,
|
||||
consider the following state diagram:
|
||||
|
||||
|
||||
STATE
|
||||
+--------------+-----------+-------------+-------------
|
||||
| A | B | C | D
|
||||
| |status col.|status column|
|
||||
|status column | is | is |status column
|
||||
ACTION |does not exist| notReady | notInService| is active
|
||||
--------------+--------------+-----------+-------------+-------------
|
||||
set status |noError ->D|inconsist- |inconsistent-|inconsistent-
|
||||
column to | or | entValue| Value| Value
|
||||
createAndGo |inconsistent- | | |
|
||||
| Value| | |
|
||||
--------------+--------------+-----------+-------------+-------------
|
||||
set status |noError see 1|inconsist- |inconsistent-|inconsistent-
|
||||
column to | or | entValue| Value| Value
|
||||
createAndWait |wrongValue | | |
|
||||
--------------+--------------+-----------+-------------+-------------
|
||||
set status |inconsistent- |inconsist- |noError |noError
|
||||
column to | Value| entValue| |
|
||||
active | | | |
|
||||
| | or | |
|
||||
| | | |
|
||||
| |see 2 ->D| ->D| ->D
|
||||
--------------+--------------+-----------+-------------+-------------
|
||||
set status |inconsistent- |inconsist- |noError |noError ->C
|
||||
column to | Value| entValue| |
|
||||
notInService | | | |
|
||||
| | or | | or
|
||||
| | | |
|
||||
| |see 3 ->C| ->C|wrongValue
|
||||
--------------+--------------+-----------+-------------+-------------
|
||||
set status |noError |noError |noError |noError
|
||||
column to | | | |
|
||||
destroy | ->A| ->A| ->A| ->A
|
||||
--------------+--------------+-----------+-------------+-------------
|
||||
set any other |see 4 |noError |noError |see 5
|
||||
column to some| | | |
|
||||
value | | see 1| ->C| ->D
|
||||
--------------+--------------+-----------+-------------+-------------
|
||||
|
||||
(1) goto B or C, depending on information available to the
|
||||
agent.
|
||||
|
||||
(2) if other variable bindings included in the same PDU,
|
||||
provide values for all columns which are missing but
|
||||
required, then return noError and goto D.
|
||||
|
||||
(3) if other variable bindings included in the same PDU,
|
||||
provide values for all columns which are missing but
|
||||
required, then return noError and goto C.
|
||||
|
||||
(4) at the discretion of the agent, the return value may be
|
||||
either:
|
||||
|
||||
inconsistentName: because the agent does not choose to
|
||||
create such an instance when the corresponding
|
||||
RowStatus instance does not exist, or
|
||||
|
||||
inconsistentValue: if the supplied value is
|
||||
inconsistent with the state of some other MIB object's
|
||||
value, or
|
||||
|
||||
noError: because the agent chooses to create the
|
||||
instance.
|
||||
|
||||
If noError is returned, then the instance of the status
|
||||
column must also be created, and the new state is B or C,
|
||||
depending on the information available to the agent. If
|
||||
inconsistentName or inconsistentValue is returned, the row
|
||||
remains in state A.
|
||||
|
||||
(5) depending on the MIB definition for the column/table,
|
||||
either noError or inconsistentValue may be returned.
|
||||
|
||||
NOTE: Other processing of the set request may result in a
|
||||
response other than noError being returned, e.g.,
|
||||
wrongValue, noCreation, etc.
|
||||
|
||||
|
||||
Conceptual Row Creation
|
||||
|
||||
There are four potential interactions when creating a
|
||||
conceptual row: selecting an instance-identifier which is
|
||||
not in use; creating the conceptual row; initializing any
|
||||
objects for which the agent does not supply a default; and,
|
||||
making the conceptual row available for use by the managed
|
||||
device.
|
||||
|
||||
Interaction 1: Selecting an Instance-Identifier
|
||||
|
||||
The algorithm used to select an instance-identifier varies
|
||||
for each conceptual row. In some cases, the instance-
|
||||
identifier is semantically significant, e.g., the
|
||||
destination address of a route, and a management station
|
||||
selects the instance-identifier according to the semantics.
|
||||
|
||||
In other cases, the instance-identifier is used solely to
|
||||
distinguish conceptual rows, and a management station
|
||||
without specific knowledge of the conceptual row might
|
||||
examine the instances present in order to determine an
|
||||
unused instance-identifier. (This approach may be used, but
|
||||
it is often highly sub-optimal; however, it is also a
|
||||
questionable practice for a naive management station to
|
||||
attempt conceptual row creation.)
|
||||
|
||||
Alternately, the MIB module which defines the conceptual row
|
||||
might provide one or more objects which provide assistance
|
||||
in determining an unused instance-identifier. For example,
|
||||
if the conceptual row is indexed by an integer-value, then
|
||||
an object having an integer-valued SYNTAX clause might be
|
||||
defined for such a purpose, allowing a management station to
|
||||
issue a management protocol retrieval operation. In order
|
||||
to avoid unnecessary collisions between competing management
|
||||
stations, `adjacent' retrievals of this object should be
|
||||
different.
|
||||
|
||||
Finally, the management station could select a pseudo-random
|
||||
number to use as the index. In the event that this index
|
||||
was already in use and an inconsistentValue was returned in
|
||||
response to the management protocol set operation, the
|
||||
management station should simply select a new pseudo-random
|
||||
number and retry the operation.
|
||||
|
||||
A MIB designer should choose between the two latter
|
||||
algorithms based on the size of the table (and therefore the
|
||||
efficiency of each algorithm). For tables in which a large
|
||||
number of entries are expected, it is recommended that a MIB
|
||||
object be defined that returns an acceptable index for
|
||||
creation. For tables with small numbers of entries, it is
|
||||
recommended that the latter pseudo-random index mechanism be
|
||||
used.
|
||||
|
||||
|
||||
Interaction 2: Creating the Conceptual Row
|
||||
|
||||
Once an unused instance-identifier has been selected, the
|
||||
management station determines if it wishes to create and
|
||||
activate the conceptual row in one transaction or in a
|
||||
negotiated set of interactions.
|
||||
|
||||
Interaction 2a: Creating and Activating the Conceptual Row
|
||||
|
||||
The management station must first determine the column
|
||||
requirements, i.e., it must determine those columns for
|
||||
which it must or must not provide values. Depending on the
|
||||
complexity of the table and the management station's
|
||||
knowledge of the agent's capabilities, this determination
|
||||
can be made locally by the management station. Alternately,
|
||||
the management station issues a management protocol get
|
||||
operation to examine all columns in the conceptual row that
|
||||
it wishes to create. In response, for each column, there
|
||||
are three possible outcomes:
|
||||
|
||||
- a value is returned, indicating that some other
|
||||
management station has already created this conceptual
|
||||
row. We return to interaction 1.
|
||||
|
||||
- the exception `noSuchInstance' is returned,
|
||||
indicating that the agent implements the object-type
|
||||
associated with this column, and that this column in at
|
||||
least one conceptual row would be accessible in the MIB
|
||||
view used by the retrieval were it to exist. For those
|
||||
columns to which the agent provides read-create access,
|
||||
the `noSuchInstance' exception tells the management
|
||||
station that it should supply a value for this column
|
||||
when the conceptual row is to be created.
|
||||
|
||||
- the exception `noSuchObject' is returned, indicating
|
||||
that the agent does not implement the object-type
|
||||
associated with this column or that there is no
|
||||
conceptual row for which this column would be
|
||||
accessible in the MIB view used by the retrieval. As
|
||||
such, the management station can not issue any
|
||||
management protocol set operations to create an
|
||||
instance of this column.
|
||||
|
||||
Once the column requirements have been determined, a
|
||||
management protocol set operation is accordingly issued.
|
||||
This operation also sets the new instance of the status
|
||||
column to `createAndGo'.
|
||||
|
||||
When the agent processes the set operation, it verifies that
|
||||
it has sufficient information to make the conceptual row
|
||||
available for use by the managed device. The information
|
||||
available to the agent is provided by two sources: the
|
||||
management protocol set operation which creates the
|
||||
conceptual row, and, implementation-specific defaults
|
||||
supplied by the agent (note that an agent must provide
|
||||
implementation-specific defaults for at least those objects
|
||||
which it implements as read-only). If there is sufficient
|
||||
information available, then the conceptual row is created, a
|
||||
`noError' response is returned, the status column is set to
|
||||
`active', and no further interactions are necessary (i.e.,
|
||||
interactions 3 and 4 are skipped). If there is insufficient
|
||||
information, then the conceptual row is not created, and the
|
||||
set operation fails with an error of `inconsistentValue'.
|
||||
On this error, the management station can issue a management
|
||||
protocol retrieval operation to determine if this was
|
||||
because it failed to specify a value for a required column,
|
||||
or, because the selected instance of the status column
|
||||
already existed. In the latter case, we return to
|
||||
interaction 1. In the former case, the management station
|
||||
can re-issue the set operation with the additional
|
||||
information, or begin interaction 2 again using
|
||||
`createAndWait' in order to negotiate creation of the
|
||||
conceptual row.
|
||||
|
||||
NOTE WELL
|
||||
|
||||
Regardless of the method used to determine the column
|
||||
requirements, it is possible that the management
|
||||
station might deem a column necessary when, in fact,
|
||||
the agent will not allow that particular columnar
|
||||
instance to be created or written. In this case, the
|
||||
management protocol set operation will fail with an
|
||||
error such as `noCreation' or `notWritable'. In this
|
||||
case, the management station decides whether it needs
|
||||
to be able to set a value for that particular columnar
|
||||
instance. If not, the management station re-issues the
|
||||
management protocol set operation, but without setting
|
||||
a value for that particular columnar instance;
|
||||
otherwise, the management station aborts the row
|
||||
creation algorithm.
|
||||
|
||||
Interaction 2b: Negotiating the Creation of the Conceptual
|
||||
Row
|
||||
|
||||
The management station issues a management protocol set
|
||||
operation which sets the desired instance of the status
|
||||
column to `createAndWait'. If the agent is unwilling to
|
||||
process a request of this sort, the set operation fails with
|
||||
an error of `wrongValue'. (As a consequence, such an agent
|
||||
must be prepared to accept a single management protocol set
|
||||
operation, i.e., interaction 2a above, containing all of the
|
||||
columns indicated by its column requirements.) Otherwise,
|
||||
the conceptual row is created, a `noError' response is
|
||||
returned, and the status column is immediately set to either
|
||||
`notInService' or `notReady', depending on whether it has
|
||||
sufficient information to make the conceptual row available
|
||||
for use by the managed device. If there is sufficient
|
||||
information available, then the status column is set to
|
||||
`notInService'; otherwise, if there is insufficient
|
||||
information, then the status column is set to `notReady'.
|
||||
Regardless, we proceed to interaction 3.
|
||||
|
||||
Interaction 3: Initializing non-defaulted Objects
|
||||
|
||||
The management station must now determine the column
|
||||
requirements. It issues a management protocol get operation
|
||||
to examine all columns in the created conceptual row. In
|
||||
the response, for each column, there are three possible
|
||||
outcomes:
|
||||
|
||||
- a value is returned, indicating that the agent
|
||||
implements the object-type associated with this column
|
||||
and had sufficient information to provide a value. For
|
||||
those columns to which the agent provides read-create
|
||||
access (and for which the agent allows their values to
|
||||
be changed after their creation), a value return tells
|
||||
the management station that it may issue additional
|
||||
management protocol set operations, if it desires, in
|
||||
order to change the value associated with this column.
|
||||
|
||||
- the exception `noSuchInstance' is returned,
|
||||
indicating that the agent implements the object-type
|
||||
associated with this column, and that this column in at
|
||||
least one conceptual row would be accessible in the MIB
|
||||
view used by the retrieval were it to exist. However,
|
||||
the agent does not have sufficient information to
|
||||
provide a value, and until a value is provided, the
|
||||
conceptual row may not be made available for use by the
|
||||
managed device. For those columns to which the agent
|
||||
provides read-create access, the `noSuchInstance'
|
||||
exception tells the management station that it must
|
||||
issue additional management protocol set operations, in
|
||||
order to provide a value associated with this column.
|
||||
|
||||
- the exception `noSuchObject' is returned, indicating
|
||||
that the agent does not implement the object-type
|
||||
associated with this column or that there is no
|
||||
conceptual row for which this column would be
|
||||
accessible in the MIB view used by the retrieval. As
|
||||
such, the management station can not issue any
|
||||
management protocol set operations to create an
|
||||
instance of this column.
|
||||
|
||||
If the value associated with the status column is
|
||||
`notReady', then the management station must first deal with
|
||||
all `noSuchInstance' columns, if any. Having done so, the
|
||||
value of the status column becomes `notInService', and we
|
||||
proceed to interaction 4.
|
||||
|
||||
Interaction 4: Making the Conceptual Row Available
|
||||
|
||||
Once the management station is satisfied with the values
|
||||
associated with the columns of the conceptual row, it issues
|
||||
a management protocol set operation to set the status column
|
||||
to `active'. If the agent has sufficient information to
|
||||
make the conceptual row available for use by the managed
|
||||
device, the management protocol set operation succeeds (a
|
||||
`noError' response is returned). Otherwise, the management
|
||||
protocol set operation fails with an error of
|
||||
`inconsistentValue'.
|
||||
|
||||
|
||||
NOTE WELL
|
||||
|
||||
A conceptual row having a status column with value
|
||||
`notInService' or `notReady' is unavailable to the
|
||||
managed device. As such, it is possible for the
|
||||
managed device to create its own instances during the
|
||||
time between the management protocol set operation
|
||||
which sets the status column to `createAndWait' and the
|
||||
management protocol set operation which sets the status
|
||||
column to `active'. In this case, when the management
|
||||
protocol set operation is issued to set the status
|
||||
column to `active', the values held in the agent
|
||||
supersede those used by the managed device.
|
||||
|
||||
If the management station is prevented from setting the
|
||||
status column to `active' (e.g., due to management station
|
||||
or network failure) the conceptual row will be left in the
|
||||
`notInService' or `notReady' state, consuming resources
|
||||
indefinitely. The agent must detect conceptual rows that
|
||||
have been in either state for an abnormally long period of
|
||||
time and remove them. It is the responsibility of the
|
||||
DESCRIPTION clause of the status column to indicate what an
|
||||
abnormally long period of time would be. This period of
|
||||
time should be long enough to allow for human response time
|
||||
(including `think time') between the creation of the
|
||||
conceptual row and the setting of the status to `active'.
|
||||
In the absense of such information in the DESCRIPTION
|
||||
clause, it is suggested that this period be approximately 5
|
||||
minutes in length. This removal action applies not only to
|
||||
newly-created rows, but also to previously active rows which
|
||||
are set to, and left in, the notInService state for a
|
||||
prolonged period exceeding that which is considered normal
|
||||
for such a conceptual row.
|
||||
|
||||
|
||||
Conceptual Row Suspension
|
||||
|
||||
When a conceptual row is `active', the management station
|
||||
may issue a management protocol set operation which sets the
|
||||
instance of the status column to `notInService'. If the
|
||||
agent is unwilling to do so, the set operation fails with an
|
||||
error of `wrongValue'. Otherwise, the conceptual row is
|
||||
taken out of service, and a `noError' response is returned.
|
||||
It is the responsibility of the DESCRIPTION clause of the
|
||||
status column to indicate under what circumstances the
|
||||
status column should be taken out of service (e.g., in order
|
||||
for the value of some other column of the same conceptual
|
||||
row to be modified).
|
||||
|
||||
|
||||
Conceptual Row Deletion
|
||||
|
||||
For deletion of conceptual rows, a management protocol set
|
||||
operation is issued which sets the instance of the status
|
||||
column to `destroy'. This request may be made regardless of
|
||||
the current value of the status column (e.g., it is possible
|
||||
to delete conceptual rows which are either `notReady',
|
||||
`notInService' or `active'.) If the operation succeeds,
|
||||
then all instances associated with the conceptual row are
|
||||
immediately removed."
|
||||
SYNTAX INTEGER
|
||||
{
|
||||
active(1),
|
||||
notInService(2),
|
||||
notReady(3),
|
||||
createAndGo(4),
|
||||
createAndWait(5),
|
||||
destroy(6)
|
||||
}
|
||||
|
||||
-- the following two values are states:
|
||||
-- these values may be read or written
|
||||
-- the following value is a state:
|
||||
-- this value may be read, but not written
|
||||
-- the following three values are
|
||||
-- actions: these values may be written,
|
||||
-- but are never read
|
||||
TimeStamp ::= TEXTUAL-CONVENTION
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"The value of the sysUpTime object at which a specific
|
||||
occurrence happened. The specific occurrence must be
|
||||
defined in the description of any object defined using this
|
||||
type."
|
||||
SYNTAX TimeTicks
|
||||
|
||||
|
||||
--
|
||||
-- Node definitions
|
||||
--
|
||||
|
||||
-- 1.3.6.1.4.1.1379
|
||||
cintelNS OBJECT IDENTIFIER ::= { enterprises 1379 }
|
||||
|
||||
|
||||
|
||||
END
|
||||
|
||||
--
|
||||
-- CINTEL-MIB.my
|
||||
--
|
||||
BIN
sshsvc/mibs/CINTEL-MIB.smidb
Normal file
BIN
sshsvc/mibs/CINTEL-MIB.smidb
Normal file
Binary file not shown.
Reference in New Issue
Block a user