st_mode分析

本文深入解析Linux中stat()函数的应用,详细阐述如何通过st_mode字段理解文件类型、权限及特殊属性,包括普通文件、目录、符号链接等7种类型,以及读、写、执行权限的分配。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在参考多篇文章后,自己做出的小结。

在Linux中,可以利用stat()函数来获取一个文件的状态。

#include <sys/stat.h>
#include <unistd.h>
 
int stat(const char *file_name, struct stat *buf);

这个函数通过文件名filename获取文件信息,并保存在buf所指的结构体stat中。执行成功返回0,失败返回-1。

struct stat的定义如下:

struct stat  
{  
    dev_t       st_dev;     /* ID of device containing file -文件所在设备的ID*/  
    ino_t       st_ino;     /* inode number -inode节点号*/
    mode_t      st_mode;    /* 文件的类型和存取的权限*/  
    nlink_t     st_nlink;   /* number of hard links -链向此文件的连接数(硬连接)*/  
    uid_t       st_uid;     /* user ID of owner -user id*/  
    gid_t       st_gid;     /* group ID of owner - group id*/  
    dev_t       st_rdev;    /* device ID (if special file) -设备号,针对设备文件*/  
    off_t       st_size;    /* total size, in bytes -文件大小,字节为单位*/  
    blksize_t   st_blksize; /* blocksize for filesystem I/O -系统块的大小*/  
    blkcnt_t    st_blocks;  /* number of blocks allocated -文件所占块数*/  
    time_t      st_atime;   /* time of last access -最近存取时间*/  
    time_t      st_mtime;   /* time of last modification -最近修改时间*/  
    time_t      st_ctime;   /* time of last status change -最后权限修改时间 */  
}; 

其中, st_mode这个变量用来判断文件类型,它的类型为mode_t,其实就是普通的unsigned int,但是只是用了低16位。
在这里插入图456213片描述
st_mode 主要包含了 3 部分信息:
a. 15bit ~ 12bit 保存文件类型
b. 11bit ~ 9bit 保存执行文件时设置的信息
c. 8bit ~ 0bit 保存文件访问权限

一、bit15 ~ bit12 , 文件类型属性区域

在现代linux操作系统上文件类型共分为7种,分别是:
- : 普通文件(regular file)
d : 目录(directory)
c : 字符设备(character device)
b : 块设备(block device)
p : 管道(FIFO)
l : 符号链接文件(symbolic link)
s : 套接口文件(socket)

所以文件类型属性只需3bit就够了。

二、bit11 ~ bit9,权限的特殊属性区域
bit11:set-user-ID位,执行时设置用户ID
bit10:set-group-ID位,执行时设置组ID
bit9:sticky位,仅对目录有效。设置后所有用户都可在这个目录下创建文件,但该目录下的文件只能被owner和root删除

下面来解释sticky位的作用:
首先要明白,要删除一个文件,一定要有这个文件的上级目录的写权限,可以没有文件的写权限。且没有一个目录的写权限,就不能在这个目录下创建文件。

sticky就是能使一个目录既可以让任何用户写入文件,又不让用户删除这个目录下他人的文件。sticky一般只用在目录上,普通文件的sticky位会被linux内核忽略。

sticky位出现执行许可x的位置上,用t表示(子目录不继承该权限,要再设置)。如下方的代码:

$ ls -dl /tmp  
drwxrwxrwt 15 root root  .........  // 注意 other 用户的权限位,x 变成了 t

那么原来的执行标志x到哪里去了呢? 系统是这样规定的, 假如本来在该位上有x, 则这些特别标志 (suid, sgid, sticky) 显示为小写字母 (s, s, t). 否则, 显示为大写字母 (S, S, T) 。

另外

chmod 777 abc  
chmod +t abc  

等价于

chmod 1777 abc 

即在设置sticky位后,目录的权限多了一个最高位的1。

三、bit8 ~ bit0,权限属性区域
即st_mode字段的最低9位,代表文件的许可权限,标识了文件所有者(owner)、组用户(group)、其他用户(other)的读(r)、写(w)、执行(x)权限。

四、实例分析
例一:st_mode 10进制值是 33204,转换成 8 进制后为 100664
图1 33204 填到 st_mode 中
        图1 33204 填到 st_mode 中

根据图1 我们可以得到如下信息:

  • 1000: 这是一个常规文件
  • 000: 执行时设置信息为空,黏着位为 0
  • 110-110-100: 用户权限为 RW-,组员权限为RW-,其他人权限为R--

例2:st_mode 值为 35309. 转换成 8 进制后为 104755
在这里插入图片描述
        图2 35309填充 st_mode

分析图2,可以知道:

  • 1000:这是一个普通文件
  • 100:suid 为 1
  • 111-101-101:用户权限为 RWX,组员权限为R-X,其他人权限为R-X

五、宏
通过手工分析 st_mode 字段,实际上是很不方便的。实际写程序,可使用 st_mode & 掩码来得到 st_mode 中特定的部分。比如:

st_mode & 0170000 : 得到文件类型
st_mode & 0007000 : 得到执行文件时设置信息
st_mode & 0000777 : 得到权限位
st_mode & 00100: 判断所有者是否可执行
(以上数字均为八进制)

为了方便使用,用 linux 预定义的一些宏来代替这些生硬的数字。这些宏定义在 include <sys/stat.h> 头文件中。

//bit15 ~ bit12 , 文件类型属性区域
#define  S_IFMT      0170000     文件类型的位遮罩
#define  S_IFSOCK    0140000     socket
#define  S_IFLNK     0120000     符号链接(symbolic link)
#define  S_IFREG     0100000     一般文件
#define  S_IFBLK     0060000     区块装置(block device)
#define  S_IFDIR     0040000     目录
#define  S_IFCHR     0020000     字符装置(character device)
#define  S_IFIFO     0010000     先进先出(fifo)

#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)  //提供了一些宏来帮助用户执行&操作,是则返回1
#define S_ISLNK(m)  (((m) & S_IFMT) == S_IFLNK)  
#define S_ISREG(m)  (((m) & S_IFMT) == S_IFREG)
#define S_ISBLK(m)  (((m) & S_IFMT) == S_IFBLK)
#define S_ISDIR(m)  (((m) & S_IFMT) == S_IFDIR)
#define S_ISCHR(m)  (((m) & S_IFMT) == S_IFCHR)
#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)

//bit11 ~ bit9,权限的特殊属性区域
#define  S_ISUID      0004000     文件的(set user-id on execution)位
#define  S_ISGID      0002000     文件的(set group-id on execution)位
#define  S_ISVTX      0001000     文件的sticky位

//bit8 ~ bit0,权限属性区域
//文件所有者(owner)
#define S_IRWXU 00700	/* mask for file owner permissions */
#define S_IRUSR 00400	/* owner has read permission */
#define S_IWUSR 00200	/* owner has write permission */
#define S_IXUSR 00100	/* owner has execute permission */
 //组用户(group)
#define S_IRWXG 00070	/* mask for group permissions */
#define S_IRGRP 00040	/* group has read permission */
#define S_IWGRP 00020	/* group has write permission */
#define S_IXGRP 00010	/* group has execute permission */
 //其他用户(other)
#define S_IRWXO 00007	/* mask for permissions for others (not in group) */
#define S_IROTH 00004	/* others have read permission */
#define S_IWOTH 00002	/* others have write permission */
#define S_IXOTH 00001	/* others have execute permission */

以上宏可以自由组合使用。

/****************************************************************************** Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. ****************************************************************************** 文 件 名 : hi_netapp_pon.c 版 本 号 : 初稿 作 者 : 生成日期 : D2019_01_15 最近修改 : ******************************************************************************/ /***************************************************************************** * INCLUDE * *****************************************************************************/ #include "hi_netapp.h" #include "hi_netapp_common.h" #include "hi_optical.h" #include "hi_pon_glb_api.h" #include "hi_pon_gpon_api.h" #include "hi_pon_epon_api.h" #include "hi_omci_api.h" #include "hi_oam_notify.h" #include "hi_mc_common.h" #include "hi_sml_gpon.h" #include "hi_timer.h" #include "hi_cfm_api.h" #include "hi_ucm.h" #include "hi_omci_me_equip_def.h" #include <stdatomic.h> /***************************************************************************** * LOCAL_DEFINE * *****************************************************************************/ #define HI_NETAPP_PON_ONLINE_TIMEOUT 1000 * 5 /* 5秒 */ #define HI_PON_STATS_SAMPLE_INTERVAL 1000 * 60 * 5 /* 5 min */ #define PON_TRAFFIC_RECORD "/tmp/pon_traffic_record" #define PON_TRAFFIC_RECORD_TEMP "/tmp/pon_traffic_record_temp" #define PON_TRAFFIC_SAMPLE_CNT 72 * 60 / 5 #define HI_PON_SPEED_CAL_INTERVAL 1000 /* 1s */ #define PON_SPPED_RECORD "/tmp/pon_speed_record" /***************************************************************************** * LOCAL_TYPEDEF * *****************************************************************************/ enum hi_gont_regstate { HI_PLOAM_REGSTATE_INIT = 1, /* (O1) Initial-state */ HI_PLOAM_REGSTATE_STANDBY, /* (O2) Standby-state */ HI_PLOAM_REGSTATE_SN, /* (O3) Serial-Number-state */ HI_PLOAM_REGSTATE_RANGING, /* (O4) Ranging-state */ HI_PLOAM_REGSTATE_OPERATION, /* (O5) Operation-state */ HI_PLOAM_REGSTATE_POPUP, /* (O6) POPUP-state */ HI_PLOAM_REGSTATE_EMERGENCYSTOP, /* (O7) Emergency-Stop-state */ HI_PLOAM_REGSTATE_LOSLOF_ASSERTED, HI_PLOAM_REGSTATE_BUTT }; enum hi_eont_regstate { HI_MPCP_STATE_INITIAL = 0, HI_MPCP_STATE_REGISTER_REQ, HI_MPCP_STATE_REGISTERED, HI_MPCP_STATE_HANGUP, HI_MPCP_STATE_MAX, HI_MPCP_STATE_LOS, HI_MPCP_STATE_SD }; typedef struct { hi_uint32 ui_regstart; hi_uint32 ui_regstop; hi_sal_pon_reg_status_e em_regstatus; hi_char8 ac_regtime[128]; hi_uint32 ui_tid; hi_uint32 time_pending; struct timespec st_regtime; } hi_sal_pon_regstatus_s; /***************************************************************************** * LOCAL_VARIABLE * *****************************************************************************/ /***************************************************************************** * LOCAL_FUNCTION * *****************************************************************************/ static int up_mode = -1; static hi_ulong32 ul_online_time = 0; static hi_uint32 g_epon_regsta = HI_SAL_PON_REG_ING_E; hi_sal_pon_regstatus_s g_pon_retstatus = {0}; static hi_uint32 g_pon_sample_timerid = 0; static uint32_t g_pon_speed_cal_timerid = 0; /***************************************************************************** * INIT/EXIT * *****************************************************************************/ static hi_void sal_pon_time_convert(struct timespec *now) { /* 计算得出nsec为负数时借位 */ if (now->tv_nsec < 0) { now->tv_sec--; now->tv_nsec += 1000000000; } } static hi_void sal_pon_current_regstatus_get(hi_sal_pon_status_s *pst_stats) { struct tm nowtime; struct timespec now, interval; clock_gettime(CLOCK_MONOTONIC, &now); /* 计算上线时刻与当前时刻间隔 */ interval.tv_sec = now.tv_sec - g_pon_retstatus.st_regtime.tv_sec; interval.tv_nsec = now.tv_nsec - g_pon_retstatus.st_regtime.tv_nsec; sal_pon_time_convert(&interval); clock_gettime(CLOCK_REALTIME, &now); /* 当前时间减去间隔即为注册时间 */ now.tv_sec -= interval.tv_sec; now.tv_nsec -= interval.tv_nsec; sal_pon_time_convert(&now); localtime_r(&now.tv_sec, &nowtime); sprintf_s(g_pon_retstatus.ac_regtime, sizeof(g_pon_retstatus.ac_regtime), "%04d-%02d-%02d-%02d-%02d-%02d-%03d", nowtime.tm_year + 1900, nowtime.tm_mon + 1, nowtime.tm_mday, nowtime.tm_hour, nowtime.tm_min, nowtime.tm_sec, now.tv_nsec / 1000 / 1000); pst_stats->ui_last_regist_status = g_pon_retstatus.em_regstatus; if (strlen (g_pon_retstatus.ac_regtime) > 0) { (void)memcpy_s(pst_stats->auc_last_regist_time, sizeof(pst_stats->auc_last_regist_time), g_pon_retstatus.ac_regtime, sizeof(g_pon_retstatus.ac_regtime)); } if (g_pon_retstatus.em_regstatus == HI_SAL_PON_REG_SUCC_E) { pst_stats->ui_regist_time = g_pon_retstatus.ui_regstop - g_pon_retstatus.ui_regstart; } } static hi_void sal_pon_regstatus_init(hi_void) { struct timeval tv; gettimeofday(&tv, NULL); if (g_pon_retstatus.em_regstatus != HI_SAL_PON_REG_SUCC_E) { g_pon_retstatus.em_regstatus = HI_SAL_PON_REG_ERR_E; } else { g_pon_retstatus.em_regstatus = HI_SAL_PON_REG_ING_E; } g_pon_retstatus.ui_regstart = tv.tv_sec * 1000 + tv.tv_usec / 1000; g_pon_retstatus.ui_regstop = 0; } static hi_void sal_pon_online_status_proc(hi_void *pv_cookie) { /** ui_regstop <= ui_regstart: Re-registering */ if (g_pon_retstatus.ui_regstop > g_pon_retstatus.ui_regstart) g_pon_retstatus.em_regstatus = HI_SAL_PON_REG_SUCC_E; } static hi_void sal_pon_regstatus_succ(hi_void) { struct timeval tv; gettimeofday(&tv, NULL); clock_gettime(CLOCK_MONOTONIC, &g_pon_retstatus.st_regtime); g_pon_retstatus.em_regstatus = HI_SAL_PON_REG_ING_E; g_pon_retstatus.ui_regstop = tv.tv_sec * 1000 + tv.tv_usec / 1000; if (g_pon_retstatus.time_pending) { if (hi_timer_destroy(g_pon_retstatus.ui_tid) != HI_RET_SUCC) { HI_SAL_NET_DBG("timer destory err\n"); HI_SAL_NET_TRACE(HI_RET_FAIL, 0, 0, 0, 0); return; } g_pon_retstatus.time_pending = 0; } if (hi_timer_create(sal_pon_online_status_proc, NULL, &g_pon_retstatus.ui_tid) != HI_RET_SUCC) { HI_SAL_NET_DBG("timer create err\n"); HI_SAL_NET_TRACE(HI_RET_FAIL, 0, 0, 0, 0); return; } g_pon_retstatus.time_pending = 1; if (hi_timer_mod(g_pon_retstatus.ui_tid, HI_NETAPP_PON_ONLINE_TIMEOUT) != HI_RET_SUCC) { HI_SAL_NET_DBG("timer mod err!\n"); HI_SAL_NET_TRACE(HI_RET_FAIL, 0, 0, 0, 0); return; } } static void pon_reg_fault_code_update(hi_omci_notifier_data_s *pst_data) { uint8_t auto_diag_monitor = FAULT_CODE_INIT; if (pst_data->em_type == HI_OMCI_NOTIFY_ONUSTATE_E) { switch (pst_data->ui_data) { case HI_PLOAM_REGSTATE_INIT: case HI_PLOAM_REGSTATE_EMERGENCYSTOP: auto_diag_monitor = FAULT_CODE_9000201_PON_LOS; break; case HI_PLOAM_REGSTATE_STANDBY: case HI_PLOAM_REGSTATE_SN: case HI_PLOAM_REGSTATE_RANGING: case HI_PLOAM_REGSTATE_POPUP: auto_diag_monitor = FAULT_CODE_9000202_ONU_ROGUE; break; case HI_PLOAM_REGSTATE_OPERATION: auto_diag_monitor = FAULT_CODE_INIT; /* O5 online */ break; default: auto_diag_monitor = FAULT_CODE_9000101_OLT_RESGISTER_FAILED; break; } } else if (pst_data->em_type == HI_OMCI_NOTIFY_ROGUE_ONU_E) { auto_diag_monitor = FAULT_CODE_9000202_ONU_ROGUE; } else if (pst_data->em_type == HI_OMCI_NOTIFY_LOID_REGSTA_E) { if (pst_data->ui_data > 1) auto_diag_monitor = FAULT_CODE_9000102_OLT_RESGISTER_OVERTIME; } HI_IPC_ASYN_CALL("igd_cm_auto_diag_monitor_notify", &auto_diag_monitor); } static hi_int32 __sal_pon_notify_proc_omci(void *data, hi_uint32 len) { hi_wan_uplink_status link_status = { .wan_alport = HI_WAN_PORT_WAN1, }; hi_omci_notifier_data_s *pst_data = data; if (pst_data == NULL || sizeof(*pst_data) != len) { return HI_RET_INVALID_PARA; } hi_os_printf("notify_proc_omci type %u state %u\n", pst_data->em_type, pst_data->ui_data); if (pst_data->em_type == HI_OMCI_NOTIFY_ONUSTATE_E) { switch (pst_data->ui_data) { case HI_PLOAM_REGSTATE_INIT: case HI_PLOAM_REGSTATE_STANDBY: sal_pon_regstatus_init(); case HI_PLOAM_REGSTATE_SN: case HI_PLOAM_REGSTATE_RANGING: case HI_PLOAM_REGSTATE_POPUP: case HI_PLOAM_REGSTATE_EMERGENCYSTOP: case HI_PLOAM_REGSTATE_LOSLOF_ASSERTED: link_status.status = HI_WAN_LINK_STATUS_DOWN; HI_IPC_ASYN_CALL("hi_wan_uplink_status_update", &link_status, sizeof(link_status)); HI_IPC_ASYN_CALL("igd_cm_pon_status_notify", &(link_status.status)); ul_online_time = 0; break; case HI_PLOAM_REGSTATE_OPERATION: sal_pon_regstatus_succ(); link_status.status = HI_WAN_LINK_STATUS_UP; HI_IPC_ASYN_CALL("hi_wan_uplink_status_update", &link_status, sizeof(link_status)); HI_IPC_ASYN_CALL("igd_cm_pon_status_notify", &(link_status.status)); ul_online_time = (hi_uint32)hi_os_sysuptime(); break; default: break; } } pon_reg_fault_code_update(pst_data); return HI_RET_SUCC; } static hi_int32 __sal_pon_notify_proc_oam(void *data, hi_uint32 len) { hi_oam_notifier_data_s *pst_data = data; hi_wan_uplink_status link_status = { .wan_alport = HI_WAN_PORT_WAN1, .status = HI_WAN_LINK_STATUS_DOWN, }; if (pst_data == NULL || sizeof(*pst_data) != len) { return HI_RET_INVALID_PARA; } if (HI_OAM_NOTIFIY_MPCPREG_STATE_E == pst_data->em_type) { if (HI_OAM_NOTIFY_MPCP_O3_E != pst_data->ui_state) { ul_online_time = 0; } } else if (HI_OAM_NOTIFIY_OAMREG_STATE_E == pst_data->em_type) { if (HI_OAM_NOTIFY_REG_SUCC_E != pst_data->ui_state) { ul_online_time = 0; } else { link_status.status = HI_WAN_LINK_STATUS_UP; ul_online_time = (hi_uint32)hi_os_sysuptime(); } } HI_IPC_ASYN_CALL("hi_wan_uplink_status_update", &link_status, sizeof(link_status)); return HI_RET_SUCC; } static hi_uint32 __sal_pon_online_time_get(hi_uint32 *pui_time) { if (ul_online_time) { *pui_time = (hi_uint32)hi_os_sysuptime() - ul_online_time; } else { *pui_time = 0; } return HI_RET_SUCC; } static hi_int32 __sal_epon_regstatus_get(void *data, hi_uint32 len) { hi_oam_notifier_data_s *pst_data = data; if (pst_data == NULL || sizeof(*pst_data) != len) { return- HI_RET_INVALID_PARA; } if (pst_data->ui_state == HI_OAM_NOTIFY_REG_SUCC_E){ g_epon_regsta = HI_SAL_PON_REG_SUCC_E; return HI_RET_SUCC; } g_epon_regsta = HI_SAL_PON_REG_ING_E; return HI_RET_SUCC; } static hi_uint32 __sal_pon_regstatus_get(hi_void) { hi_uint32 i_reg_sta = HI_SAL_PON_REG_ERR_E; hi_uint32 ui_sta = 0xffffffff; enum hi_pon_mode mode; HI_IPC_CALL("hi_pon_get_fail_regstate", &ui_sta, sizeof(ui_sta)); if (ui_sta != HI_FALSE) { if (ui_sta == HI_OMCI_ME_LOID_LOID_ERR) { i_reg_sta = HI_SAL_PON_REG_LOID_ERR_E; } else { i_reg_sta = HI_SAL_PON_REG_FAIL_E; } return i_reg_sta; } if (HI_IPC_CALL("hi_pon_get_mode", &mode, sizeof(mode)) == HI_RET_SUCC) { if (up_mode >= 0 && mode != up_mode && up_mode != HI_WAN_ACCESS_TYPE_GE) { up_mode = mode; } } switch (up_mode) { case HI_PON_MODE_GPON: case HI_PON_MODE_GPON_S: case HI_PON_MODE_10GGPON_U2DOT5G: case HI_PON_MODE_10GGPON_SYM: HI_IPC_CALL("hi_gpon_get_los_state", &ui_sta, sizeof(ui_sta)); if (ui_sta) { i_reg_sta = HI_SAL_PON_REG_ERR_E; return i_reg_sta; } HI_IPC_CALL("hi_gpon_get_reg_state", &ui_sta, sizeof(ui_sta)); i_reg_sta = (ui_sta == HI_PLOAM_REGSTATE_OPERATION) ? (HI_SAL_PON_REG_SUCC_E) : (HI_SAL_PON_REG_ING_E); break; case HI_PON_MODE_EPON: case HI_PON_MODE_10GEPON_1G: case HI_PON_MODE_10GEPON_U2DOT5G: case HI_PON_MODE_10GEPON_SYM: HI_IPC_CALL("hi_epon_get_los_state", &ui_sta, sizeof(ui_sta)); if (ui_sta) { i_reg_sta = HI_SAL_PON_REG_ERR_E; return i_reg_sta; } i_reg_sta = g_epon_regsta; break; default: break; } if (0 == ul_online_time && i_reg_sta == HI_SAL_PON_REG_SUCC_E) { ul_online_time = (hi_uint32)hi_os_sysuptime(); } return i_reg_sta; } static void init_ponlink_mode(void) { HI_IPC_CALL("hi_pon_get_mode", &up_mode, sizeof(up_mode)); g_pon_retstatus.em_regstatus = HI_SAL_PON_REG_ERR_E; hi_notifier_create(HI_OMCI_NOTIFIY_NAME, sizeof(hi_omci_notifier_data_s)); hi_notifier_reg(HI_OMCI_NOTIFIY_NAME, "__sal_pon_notify_proc_omci", __sal_pon_notify_proc_omci); hi_notifier_create(HI_OAM_NOTIFIY_NAME, sizeof(hi_oam_notifier_data_s)); hi_notifier_reg(HI_OAM_NOTIFIY_NAME, "__sal_pon_notify_proc_oam", __sal_pon_notify_proc_oam); hi_notifier_reg(HI_OAM_NOTIFIY_NAME, "__sal_epon_regstatus_get", __sal_epon_regstatus_get); switch (up_mode) { case HI_PON_MODE_GPON: case HI_PON_MODE_GPON_S: case HI_PON_MODE_10GGPON_U2DOT5G: case HI_PON_MODE_10GGPON_SYM: HI_IPC_CALL("hi_omci_start"); HI_SAL_NET_DBG("start omci, up_mode\n"); break; case HI_PON_MODE_EPON: case HI_PON_MODE_10GEPON_1G: case HI_PON_MODE_10GEPON_U2DOT5G: case HI_PON_MODE_10GEPON_SYM: HI_IPC_CALL("hi_oam_start"); HI_SAL_NET_DBG("start oam\n"); break; default: break; } __sal_pon_regstatus_get(); } static void pon_set_loid_reg_info(hi_uplink_reg_key *reg_key, hi_sysinfo_data_s *sysinfo) { hi_int32 ret; if (strcmp(reg_key->loid, sysinfo->ac_loid) && reg_key->loid[0]) { ret = cfmSetObj("sysinfo.loid", reg_key->loid); ret |= hi_ucm_set("sysinfo.loid", reg_key->loid); if (ret != HI_RET_SUCC) printf("err: set sysinfo.loid fail\n"); } if (strcmp(reg_key->loidpwd, sysinfo->ac_lopwd) && reg_key->loidpwd[0]) { ret = cfmSetObj("sysinfo.lopwd", reg_key->loidpwd); ret |= hi_ucm_set("sysinfo.lopwd", reg_key->loidpwd); if (ret != HI_RET_SUCC) printf("err: set sysinfo.lopwd fail\n"); } } static void gpon_set_reg_info(hi_uplink_reg_key *reg_key, hi_sysinfo_data_s *sysinfo) { char buf[128] = {0}; char hexbuf[8] = {0}; int id = 0; enum hi_pon_mode mode; hi_int32 ret = HI_RET_SUCC; if (HI_IPC_CALL("hi_pon_get_mode", &mode, sizeof(mode)) != HI_RET_SUCC) return; pon_set_loid_reg_info(reg_key, sysinfo); if ((mode == HI_PON_MODE_10GGPON_U2DOT5G) || (mode == HI_PON_MODE_10GGPON_SYM)) { if (strcmp(sysinfo->ac_reg_id, reg_key->regpwd)) { ret |= hi_ucm_set("sysinfo.reg_id", reg_key->regpwd); ret |= cfmSetObj("sysinfo.reg_id", reg_key->regpwd); } } else if ((mode == HI_PON_MODE_GPON) || (mode == HI_PON_MODE_GPON_S)) { while (id < 10) { if (reg_key->regpwd[id]) { ret |= sprintf_s(hexbuf, sizeof(hexbuf), "%02x", reg_key->regpwd[id]); } else { ret |= sprintf_s(hexbuf, sizeof(hexbuf), "%02x", 0); } id++; ret |= strcat_s(buf, sizeof(buf), hexbuf); } if (strcmp((char *)sysinfo->st_auid.auc_pwd, reg_key->regpwd)) { ret |= hi_ucm_set("sysinfo.auid.pwd", buf); ret |= cfmSetObj("sysinfo.auid.pwd", buf); } } if (ret < 0) { printf("gpon set reg info fail"); } } static void gpon_start_reg(hi_uplink_reg_key *reg_key) { struct hi_gpon_para reg_param = { 0 }; hi_sysinfo_data_s sysinfo = { 0 }; HI_IPC_CALL("hi_gpon_stop"); if (HI_IPC_CALL("hi_sysinfo_data_get", &sysinfo) != HI_RET_SUCC) { HI_SAL_NET_DBG("sysinfo not find\n"); HI_SAL_NET_TRACE(HI_RET_FAIL, 0, 0, 0, 0); return; } memcpy_s(reg_param.sn, sizeof(reg_param.sn), sysinfo.st_auid.auc_sn, sizeof(sysinfo.st_auid.auc_sn)); if (up_mode == HI_PON_MODE_10GGPON_U2DOT5G || up_mode == HI_PON_MODE_10GGPON_SYM) { (void)memcpy_s((char *)reg_param.regid, sizeof(reg_param.regid), reg_key->regpwd, strlen(reg_key->regpwd)); printf("start xgpon regist, regid=%s\n", reg_param.regid); } else { (void)memcpy_s((char *)reg_param.pwd, sizeof(reg_param.pwd), reg_key->regpwd, strlen(reg_key->regpwd)); printf("start gpon regist, pwd=%s\n", reg_param.pwd); } HI_IPC_CALL("hi_gpon_start", &reg_param); gpon_set_reg_info(reg_key, &sysinfo); } static void epon_start_reg(hi_uplink_reg_key *reg_key) { struct hi_epon_para epon_para = { 0 }; hi_sysinfo_data_s sysinfo = { 0 }; HI_IPC_CALL("hi_epon_stop"); if (HI_IPC_CALL("hi_sysinfo_data_get", &sysinfo) != HI_RET_SUCC) { HI_SAL_NET_DBG("sysinfo not find\n"); HI_SAL_NET_TRACE(HI_RET_FAIL, 0, 0, 0, 0); return; } pon_set_loid_reg_info(reg_key, &sysinfo); memcpy_s(epon_para.mac, sizeof(epon_para.mac), sysinfo.auc_llid0_mac, sizeof(sysinfo.auc_llid0_mac)); HI_IPC_CALL("hi_epon_start", &epon_para); printf("start epon regist, loid=%s, lopwd=%s\n", reg_key->loid, reg_key->loidpwd); } static hi_uint32 sal_pon_distance_calculate(hi_uint32 *ui_distance) { hi_double64 distance; hi_double64 time_delay; hi_uint32 ui_eqd = 0; hi_uint32 ui_teqd = 0; hi_uint32 ui_rate = 0; enum hi_pon_mode mode; HI_IPC_CALL("hi_pon_get_mode", &mode, sizeof(mode)); *ui_distance = 0; switch (up_mode) { case HI_PON_MODE_GPON: case HI_PON_MODE_GPON_S: case HI_PON_MODE_10GGPON_U2DOT5G: case HI_PON_MODE_10GGPON_SYM: if (HI_IPC_CALL("hi_gpon_get_eqd", &ui_eqd, sizeof(ui_eqd)) != HI_RET_SUCC) { HI_SAL_NET_DBG("get gpon eqd err\n"); HI_SAL_NET_TRACE(HI_RET_FAIL, 0, 0, 0, 0); return 0; } ui_teqd = (mode == HI_PON_MODE_GPON) || (mode == HI_PON_MODE_GPON_S) ? HI_NETAPP_GPON_TEQD : HI_NETAPP_XGPON_TEQD; ui_rate = (mode == HI_PON_MODE_GPON) || (mode == HI_PON_MODE_GPON_S) ? HI_NETAPP_GPON_RATE : HI_NETAPP_XGPON_RATE; while (ui_eqd > ui_teqd + HI_NETAPP_XGPON_TEQD_GAP) { ui_eqd -= HI_NETAPP_XGPON_TEQD_GAP; } distance = (double)abs(ui_teqd - ui_eqd) / ui_rate * 100; *ui_distance = ceil(distance); *ui_distance %= 200; /* 限制在200m内 */ /* 光速0.2km/us 往返乘2 */ time_delay = HI_NETAPP_TEQD_TIME_DELAY - 2 * (double)(*ui_distance) / 1000 / 0.2; ui_eqd = floor(time_delay); break; case HI_PON_MODE_EPON: case HI_PON_MODE_10GEPON_1G: case HI_PON_MODE_10GEPON_U2DOT5G: case HI_PON_MODE_10GEPON_SYM: break; default: break; } return ui_eqd; } /****************************************************************************** Function : hi_sal_pon_init Description : Init sal pon Input Parm : N/A Output Parm : N/A Return : HI_RET_SUCC/HI_RET_FAIL ******************************************************************************/ hi_int32 hi_sal_pon_init(hi_void) { return HI_RET_SUCC; } /****************************************************************************** Function : hi_sal_pon_exit Description : Exit sal pon Input Parm : N/A Output Parm : N/A Return : HI_RET_SUCC/HI_RET_FAIL ******************************************************************************/ hi_void hi_sal_pon_exit(hi_void) { return; } HI_DEF_IPC(hi_sal_uplink_start_reg, hi_uplink_reg_key *, pst_info) { hi_wan_common_info_s common_info = { 0 }; enum hi_pon_mode mode; if (up_mode < 0) { HI_IPC_CALL("hi_wan_common_get", &common_info); if (common_info.em_access_type != HI_WAN_ACCESS_TYPE_GE) { init_ponlink_mode(); } else { up_mode = HI_WAN_ACCESS_TYPE_GE; } } if ((up_mode != HI_WAN_ACCESS_TYPE_GE) && (HI_IPC_CALL("hi_pon_get_mode", &mode, sizeof(mode)) == HI_RET_SUCC)) { if (mode != up_mode) { up_mode = mode; } } switch (up_mode) { case HI_PON_MODE_GPON: case HI_PON_MODE_GPON_S: case HI_PON_MODE_10GGPON_U2DOT5G: case HI_PON_MODE_10GGPON_SYM: gpon_start_reg(pst_info); break; case HI_PON_MODE_EPON: case HI_PON_MODE_10GEPON_1G: case HI_PON_MODE_10GEPON_U2DOT5G: case HI_PON_MODE_10GEPON_SYM: epon_start_reg(pst_info); break; default: printf("pon mode not support\n"); break; } return 0; } HI_DEF_IPC(hi_sal_pon_reginfo_get, hi_sal_pon_reg_info_s *, pst_info) { if (up_mode == HI_WAN_ACCESS_TYPE_GE) { pst_info->em_olt_auth = HI_SAL_PON_REG_SUCC_E; return HI_RET_SUCC; } pst_info->em_olt_auth = __sal_pon_regstatus_get(); return HI_RET_SUCC; } HI_DEF_IPC(hi_sal_pon_uplink_status_get, hi_sal_pon_uplink_status_s *, pst_uplink_status) { hi_uint32 ui_sta = 0xffffffff; struct hi_epon_llidstate st_sta = { 0 }; struct hi_optical_state status = { 0 }; struct hi_gpon_fec gpon_fec = { 0 }; struct hi_epon_fec epon_fec = { 0 }; __sal_pon_online_time_get(&pst_uplink_status->ui_continuous_time); if (up_mode == HI_WAN_ACCESS_TYPE_GE) { return HI_RET_SUCC; } hi_optical_get_state(&status); pst_uplink_status->i_tx_power = status.txpower * 10000; pst_uplink_status->i_rx_power = status.rxpower * 10000; pst_uplink_status->i_temperature = status.temprature * 256; pst_uplink_status->i_bias_current = status.ibias * 500; pst_uplink_status->i_supply_vottage = status.voltage * 10000; pst_uplink_status->ui_fec_cap = 1; HI_IPC_CALL("hi_pon_get_mode", &up_mode, sizeof(up_mode)); switch (up_mode) { case HI_PON_MODE_GPON: case HI_PON_MODE_GPON_S: case HI_PON_MODE_10GGPON_U2DOT5G: case HI_PON_MODE_10GGPON_SYM: HI_IPC_CALL("hi_gpon_get_reg_state", &pst_uplink_status->em_status, sizeof(hi_uint32)); HI_IPC_CALL("hi_gpon_get_fec", &gpon_fec, sizeof(gpon_fec)); pst_uplink_status->ui_fec_status = gpon_fec.tx_fec; if (gpon_fec.rx_fec == 1) pst_uplink_status->ui_fec_status |= PON_FEC_STATE_RX_ENABLE; break; case HI_PON_MODE_EPON: case HI_PON_MODE_10GEPON_1G: case HI_PON_MODE_10GEPON_U2DOT5G: case HI_PON_MODE_10GEPON_SYM: HI_IPC_CALL("hi_epon_get_los_state", &ui_sta, sizeof(ui_sta)); HI_IPC_CALL("hi_epon_get_llidstate", &st_sta, sizeof(st_sta)); HI_IPC_CALL("hi_epon_get_fec", &epon_fec, sizeof(epon_fec)); if (ui_sta) { pst_uplink_status->em_status = HI_SAL_PON_UPLINK_NOSIGNAL_E; } else if (st_sta.state == 3) { pst_uplink_status->em_status = HI_SAL_PON_UPLINK_UP_E; } else if (st_sta.state == 4) { pst_uplink_status->em_status = HI_SAL_PON_UPLINK_POPUP_E; } else { pst_uplink_status->em_status = HI_SAL_PON_UPLINK_INITIALIZING_E; } pst_uplink_status->ui_fec_status = epon_fec.tx_fec_en; if (epon_fec.rx_fec_en == 1) pst_uplink_status->ui_fec_status |= PON_FEC_STATE_RX_ENABLE; break; default: break; } return 0; } static void hi_netapp_pon_recalculcate_stat(hi_sal_pon_status_s *stat) { int32_t ret; hi_sml_multicast_gemport_stat gemport_stat = { 0 }; hi_mc_stats_s mc_stat = { 0 }; ret = HI_IPC_CALL("hi_sml_get_multicast_gemport_stat", &gemport_stat); if (ret != HI_RET_SUCC) { HI_SAL_NET_DBG("get multicast gemport stat fail.\n"); return; } ret = HI_IPC_CALL("hi_kernel_mc_stat_get", &mc_stat); if (ret != HI_RET_SUCC) { HI_SAL_NET_DBG("get multicast stat fail.\n"); return; } /* Removing Invalid Multicast Packets. */ stat->ui_bytes_received += (mc_stat.ul_valid_bytes - gemport_stat.rxbytes); stat->ui_packets_received += (mc_stat.ul_valid_pkts - gemport_stat.rcvframes); stat->ui_rmulticast_packets += (mc_stat.ul_valid_pkts - gemport_stat.rcvframes); } HI_DEF_IPC(hi_sal_pon_stats_get, hi_sal_pon_status_s *, pst_stats) { hi_uint32 pon_mode = up_mode; struct hi_epon_llid_stat llid_stat = { 0 }; struct hi_epon_cnt epon_cnt = { 0 }; struct hi_gpon_cnt st_gpon_cnt; HI_IPC_CALL("hi_pon_get_mode", &pon_mode, sizeof(pon_mode)); switch (pon_mode) { case HI_PON_MODE_GPON: case HI_PON_MODE_GPON_S: case HI_PON_MODE_10GGPON_U2DOT5G: case HI_PON_MODE_10GGPON_SYM: HI_OS_MEMSET_S(&st_gpon_cnt, sizeof(st_gpon_cnt), 0, sizeof(st_gpon_cnt)); HI_IPC_CALL("hi_gpon_get_cnt", &st_gpon_cnt, sizeof(st_gpon_cnt)); pst_stats->ui_bytes_sent = ((hi_ulong64)st_gpon_cnt.tx_byte_h << 32) | st_gpon_cnt.tx_byte_l; pst_stats->ui_bytes_received = ((hi_ulong64)st_gpon_cnt.rx_byte_h << 32) | st_gpon_cnt.rx_byte_l; pst_stats->ui_packets_sent = st_gpon_cnt.tx; pst_stats->ui_packets_received = st_gpon_cnt.rx; pst_stats->ui_sunicast_packets = st_gpon_cnt.tx_uc; pst_stats->ui_runicast_packets = st_gpon_cnt.rx_uc; pst_stats->ui_smulticast_packets = st_gpon_cnt.tx_mc; pst_stats->ui_rmulticast_packets = st_gpon_cnt.rx_mc; pst_stats->ui_sbroadcast_packets = st_gpon_cnt.tx_bc; pst_stats->ui_rbroadcast_packets = st_gpon_cnt.rx_bc; pst_stats->ui_fec_error = st_gpon_cnt.rx_fec_err_cw; pst_stats->ui_fcs_error = st_gpon_cnt.fcs_err; pst_stats->ui_drop_packets_received = st_gpon_cnt.rx_err; pst_stats->ui_eqd = sal_pon_distance_calculate(&pst_stats->ui_distance); sal_pon_current_regstatus_get(pst_stats); hi_netapp_pon_recalculcate_stat(pst_stats); //无法获取 pst_stats->ui_hec_error = 0; pst_stats->ui_drop_packets = 0; pst_stats->ui_spause_packets = 0; pst_stats->ui_rpause_packets = 0; break; case HI_PON_MODE_EPON: case HI_PON_MODE_10GEPON_1G: case HI_PON_MODE_10GEPON_U2DOT5G: case HI_PON_MODE_10GEPON_SYM: llid_stat.llid = 0; HI_IPC_CALL("hi_epon_get_llid_stat", &llid_stat, sizeof(llid_stat)); HI_IPC_CALL("hi_epon_get_cnt", &epon_cnt, sizeof(epon_cnt)); pst_stats->ui_bytes_sent = llid_stat.tx.tx_byte; pst_stats->ui_bytes_received = llid_stat.rx.rx_byte; pst_stats->ui_packets_sent = llid_stat.tx.tx_uc + llid_stat.tx.tx_mc + llid_stat.tx.tx_bc; pst_stats->ui_packets_received = llid_stat.rx.rx_uc + llid_stat.rx.rx_mc + llid_stat.rx.rx_bc; pst_stats->ui_runicast_packets = llid_stat.rx.rx_uc; pst_stats->ui_rmulticast_packets = llid_stat.rx.rx_mc; pst_stats->ui_rbroadcast_packets = llid_stat.rx.rx_bc; pst_stats->ui_fec_error = epon_cnt.rx_fec_seconds; pst_stats->ui_fcs_error = epon_cnt.rx_fcs_err; sal_pon_current_regstatus_get(pst_stats); pst_stats->ui_sunicast_packets = llid_stat.tx.tx_uc; pst_stats->ui_smulticast_packets = llid_stat.tx.tx_mc; pst_stats->ui_sbroadcast_packets = llid_stat.tx.tx_bc; pst_stats->ui_drop_packets_received = epon_cnt.rx_err; //无法获取 pst_stats->ui_hec_error = 0; pst_stats->ui_drop_packets = 0; pst_stats->ui_spause_packets = 0; pst_stats->ui_rpause_packets = 0; pst_stats->ui_distance = 0; pst_stats->ui_eqd = 0; break; default : HI_SAL_NET_TRACE(HI_RET_FAIL, pon_mode, 0, 0, 0); return HI_RET_SUCC; } return HI_RET_SUCC; } static void hi_pon_sample_proc(void *arg) { hi_sal_pon_status_s pon_stats; FILE *fp = NULL; FILE *fp_temp = NULL; char rc; char buf[512] = {0}; int32_t rec_num = 0; uint64_t tx, rx; hi_sal_pon_stats_get(&pon_stats); if (access(PON_TRAFFIC_RECORD, F_OK) != 0) { fp = fopen(PON_TRAFFIC_RECORD,"w+"); if (fp) { (void)sprintf_s(buf, sizeof(buf)-1,"%llu %llu\n", pon_stats.ui_bytes_sent, pon_stats.ui_bytes_received); fprintf(fp, buf); fclose(fp); } goto out; } fp = fopen(PON_TRAFFIC_RECORD,"r"); if (fp == NULL) return; fp_temp = fopen(PON_TRAFFIC_RECORD_TEMP,"w"); while (fp_temp && !(feof(fp))) { if (rec_num == 0) { (void)sprintf_s(buf,sizeof(buf)-1, "%llu %llu\n", pon_stats.ui_bytes_sent, pon_stats.ui_bytes_received); fprintf(fp_temp, buf); rec_num++; } rc = fscanf_s(fp, "%llu %llu",&tx,&rx); if (rc == 2 && rc != EOF) { /* record only 72 hours data */ if (++rec_num > PON_TRAFFIC_SAMPLE_CNT) { break; } else { (void)sprintf_s(buf, sizeof(buf) - 1, "%llu %llu\n", tx, rx); fprintf(fp_temp, buf); } } } fclose(fp); if (fp_temp) { fclose(fp_temp); (void)snprintf_s(buf, sizeof(buf), sizeof(buf)-1, "cp -f %s %s",PON_TRAFFIC_RECORD_TEMP,PON_TRAFFIC_RECORD); system(buf); unlink(PON_TRAFFIC_RECORD_TEMP); } out: if (g_pon_sample_timerid) hi_timer_mod_wo_lock(g_pon_sample_timerid, HI_PON_STATS_SAMPLE_INTERVAL); } static void hi_pon_speed_cal_proc(void *arg) { hi_sal_pon_status_s pon_stats; FILE *fp = NULL; char buf[64]; uint64_t tx, rx, up_speed, dn_speed; static uint64_t lst_tx = 0, lst_rx = 0; hi_sal_pon_stats_get(&pon_stats); tx = pon_stats.ui_bytes_sent; rx = pon_stats.ui_bytes_received; if ((tx <= lst_tx) || (rx <= lst_rx)) { up_speed = 0; dn_speed = 0; lst_tx = 0; lst_rx = 0; } else { up_speed = ((tx - lst_tx) << 3) >> 10; /* kbps */ dn_speed = ((rx - lst_rx) << 3) >> 10; lst_tx = tx; lst_rx = rx; } (void)memset_s(buf, sizeof(buf), 0, sizeof(buf)); fp = fopen(PON_SPPED_RECORD, "w+"); if (fp != NULL) { (void)sprintf_s(buf, sizeof(buf), "%llu %llu\n", up_speed, dn_speed); fprintf(fp, buf); fclose(fp); } hi_timer_mod_wo_lock(g_pon_speed_cal_timerid, HI_PON_SPEED_CAL_INTERVAL); } HI_DEF_IPC(hi_pon_history_stats, struct hi_pon_history_stat_cfg *, cfg) { if (cfg->enable == HI_TRUE) { if (g_pon_sample_timerid == 0 && hi_timer_create(hi_pon_sample_proc, 0, &g_pon_sample_timerid) != HI_RET_SUCC) { printf("Create hi_pon_sample_proc timer failed\n"); return -HI_RET_FAIL; } hi_timer_mod(g_pon_sample_timerid, HI_PON_STATS_SAMPLE_INTERVAL); if (g_pon_speed_cal_timerid == 0 && hi_timer_create(hi_pon_speed_cal_proc, 0, &g_pon_speed_cal_timerid)) { printf("Create hi_pon_speed_cal_proc timer failed\n"); return -HI_RET_FAIL; } hi_timer_mod(g_pon_speed_cal_timerid, HI_PON_SPEED_CAL_INTERVAL); } else { if (g_pon_sample_timerid != 0) { hi_timer_destroy(g_pon_sample_timerid); g_pon_sample_timerid = 0; } if (g_pon_speed_cal_timerid != 0) { hi_timer_destroy(g_pon_speed_cal_timerid); g_pon_speed_cal_timerid = 0; } } return HI_RET_SUCC; } HI_DEF_IPC(hi_ponlink_stop) { struct hi_pon_history_stat_cfg cfg = { .enable = false }; HI_IPC_CALL("hi_led_pon_state_listen_stop"); hi_hi_pon_history_stats_ipc(&cfg); g_pon_retstatus.em_regstatus = HI_SAL_PON_REG_ERR_E; return HI_RET_SUCC; } HI_DEF_IPC(hi_ponlink_start) { struct hi_pon_history_stat_cfg cfg = { .enable = true }; g_pon_retstatus.em_regstatus = HI_SAL_PON_REG_ERR_E; hi_hi_pon_history_stats_ipc(&cfg); HI_IPC_CALL("hi_led_pon_state_listen_start"); return HI_RET_SUCC; } 以上是代码一 /****************************************************************************** Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. ****************************************************************************** 文 件 名 : hi_netapp_pon.c 版 本 号 : 初稿 作 者 : 生成日期 : D2019_01_15 最近修改 : ******************************************************************************/ /***************************************************************************** * INCLUDE * *****************************************************************************/ #include "hi_netapp.h" #include "hi_netapp_common.h" #include "hi_optical.h" #include "hi_pon_glb_api.h" #include "hi_pon_gpon_api.h" #include "hi_pon_epon_api.h" #include "hi_omci_api.h" #include "hi_oam_notify.h" #include "hi_timer.h" #include "hi_cfm_api.h" #include "hi_ucm.h" /***************************************************************************** * LOCAL_DEFINE * *****************************************************************************/ #define HI_NETAPP_PON_ONLINE_TIMEOUT 1000 * 5 /* 5秒 */ #define HI_PON_STATS_SAMPLE_INTERVAL 1000 * 60 * 5 /* 5 min */ #define PON_TRAFFIC_RECORD "/tmp/pon_traffic_record" #define PON_TRAFFIC_RECORD_TEMP "/tmp/pon_traffic_record_temp" #define PON_TRAFFIC_SAMPLE_CNT 72*60/5 #define HI_PON_SPEED_CAL_INTERVAL 1000 /* 1s */ #define PON_SPPED_RECORD "/tmp/pon_speed_record" /***************************************************************************** * LOCAL_TYPEDEF * *****************************************************************************/ enum hi_gont_regstate { HI_PLOAM_REGSTATE_INIT = 1, /* (O1) Initial-state */ HI_PLOAM_REGSTATE_STANDBY, /* (O2) Standby-state */ HI_PLOAM_REGSTATE_SN, /* (O3) Serial-Number-state */ HI_PLOAM_REGSTATE_RANGING, /* (O4) Ranging-state */ HI_PLOAM_REGSTATE_OPERATION, /* (O5) Operation-state */ HI_PLOAM_REGSTATE_POPUP, /* (O6) POPUP-state */ HI_PLOAM_REGSTATE_EMERGENCYSTOP, /* (O7) Emergency-Stop-state */ HI_PLOAM_REGSTATE_LOSLOF_ASSERTED, HI_PLOAM_REGSTATE_BUTT }; enum hi_eont_regstate { HI_MPCP_STATE_INITIAL = 0, HI_MPCP_STATE_REGISTER_REQ, HI_MPCP_STATE_REGISTERED, HI_MPCP_STATE_HANGUP, HI_MPCP_STATE_MAX, HI_MPCP_STATE_LOS, HI_MPCP_STATE_SD }; typedef struct { hi_uint32 ui_regstart; hi_uint32 ui_regstop; hi_sal_pon_reg_status_e em_regstatus; hi_char8 ac_regtime[128]; hi_uint32 ui_tid; hi_uint32 time_pending; struct timespec st_regtime; } hi_sal_pon_regstatus_s; /***************************************************************************** * LOCAL_VARIABLE * *****************************************************************************/ /***************************************************************************** * LOCAL_FUNCTION * *****************************************************************************/ static int up_mode = -1; static hi_ulong32 ul_online_time = 0; static hi_uint32 g_epon_regsta = HI_SAL_PON_REG_ING_E; hi_sal_pon_regstatus_s g_pon_retstatus = {0}; static hi_uint32 g_pon_sample_timerid = 0; static uint32_t g_pon_speed_cal_timerid = 0; /***************************************************************************** * INIT/EXIT * *****************************************************************************/ static hi_void sal_pon_time_convert(struct timespec *now) { /* 计算得出nsec为负数时借位 */ if (now->tv_nsec < 0) { now->tv_sec--; now->tv_nsec += 1000000000; } } static hi_void sal_pon_current_regstatus_get(hi_sal_pon_status_s *pst_stats) { struct tm nowtime; struct timespec now, interval; clock_gettime(CLOCK_MONOTONIC, &now); /* 计算上线时刻与当前时刻间隔 */ interval.tv_sec = now.tv_sec - g_pon_retstatus.st_regtime.tv_sec; interval.tv_nsec = now.tv_nsec - g_pon_retstatus.st_regtime.tv_nsec; sal_pon_time_convert(&interval); clock_gettime(CLOCK_REALTIME, &now); /* 当前时间减去间隔即为注册时间 */ now.tv_sec -= interval.tv_sec; now.tv_nsec -= interval.tv_nsec; sal_pon_time_convert(&now); localtime_r(&now.tv_sec, &nowtime); sprintf_s(g_pon_retstatus.ac_regtime, sizeof(g_pon_retstatus.ac_regtime), "%04d-%02d-%02d-%02d-%02d-%02d-%03d", nowtime.tm_year + 1900, nowtime.tm_mon + 1, nowtime.tm_mday, nowtime.tm_hour, nowtime.tm_min, nowtime.tm_sec, now.tv_nsec / 1000 / 1000); pst_stats->ui_last_regist_status = g_pon_retstatus.em_regstatus; if (strlen (g_pon_retstatus.ac_regtime) > 0) { (void)memcpy_s(pst_stats->auc_last_regist_time, sizeof(pst_stats->auc_last_regist_time), g_pon_retstatus.ac_regtime, sizeof(g_pon_retstatus.ac_regtime)); } if (g_pon_retstatus.em_regstatus == HI_SAL_PON_REG_SUCC_E) { pst_stats->ui_regist_time = g_pon_retstatus.ui_regstop - g_pon_retstatus.ui_regstart; } } static hi_void sal_pon_regstatus_init(hi_void) { struct timeval tv; gettimeofday(&tv, NULL); if (g_pon_retstatus.em_regstatus != HI_SAL_PON_REG_SUCC_E) { g_pon_retstatus.em_regstatus = HI_SAL_PON_REG_ERR_E; } else { g_pon_retstatus.em_regstatus = HI_SAL_PON_REG_ING_E; } g_pon_retstatus.ui_regstart = tv.tv_sec * 1000 + tv.tv_usec / 1000; g_pon_retstatus.ui_regstop = 0; } static hi_void sal_pon_online_status_proc(hi_void *pv_cookie) { /** ui_regstop <= ui_regstart: Re-registering */ if (g_pon_retstatus.ui_regstop > g_pon_retstatus.ui_regstart) g_pon_retstatus.em_regstatus = HI_SAL_PON_REG_SUCC_E; } static hi_void sal_pon_regstatus_succ(hi_void) { struct timeval tv; gettimeofday(&tv, NULL); clock_gettime(CLOCK_MONOTONIC, &g_pon_retstatus.st_regtime); g_pon_retstatus.em_regstatus = HI_SAL_PON_REG_ING_E; g_pon_retstatus.ui_regstop = tv.tv_sec * 1000 + tv.tv_usec / 1000; if (g_pon_retstatus.time_pending) { if (hi_timer_destroy(g_pon_retstatus.ui_tid) != HI_RET_SUCC) { HI_SAL_NET_DBG("timer destory err\n"); HI_SAL_NET_TRACE(HI_RET_FAIL, 0, 0, 0, 0); return; } g_pon_retstatus.time_pending = 0; } if (hi_timer_create(sal_pon_online_status_proc, NULL, &g_pon_retstatus.ui_tid) != HI_RET_SUCC) { HI_SAL_NET_DBG("timer create err\n"); HI_SAL_NET_TRACE(HI_RET_FAIL, 0, 0, 0, 0); return; } g_pon_retstatus.time_pending = 1; if (hi_timer_mod(g_pon_retstatus.ui_tid, HI_NETAPP_PON_ONLINE_TIMEOUT) != HI_RET_SUCC) { HI_SAL_NET_DBG("timer mod err!\n"); HI_SAL_NET_TRACE(HI_RET_FAIL, 0, 0, 0, 0); return; } } static void pon_reg_fault_code_update(hi_omci_notifier_data_s *pst_data) { uint8_t auto_diag_monitor = FAULT_CODE_INIT; if (pst_data->em_type == HI_OMCI_NOTIFY_ONUSTATE_E) { switch (pst_data->ui_data) { case HI_PLOAM_REGSTATE_INIT: case HI_PLOAM_REGSTATE_EMERGENCYSTOP: auto_diag_monitor = FAULT_CODE_9000201_PON_LOS; break; case HI_PLOAM_REGSTATE_STANDBY: case HI_PLOAM_REGSTATE_SN: case HI_PLOAM_REGSTATE_RANGING: case HI_PLOAM_REGSTATE_POPUP: auto_diag_monitor = FAULT_CODE_9000202_ONU_ROGUE; break; case HI_PLOAM_REGSTATE_OPERATION: auto_diag_monitor = FAULT_CODE_INIT; /* O5 online */ break; default: auto_diag_monitor = FAULT_CODE_9000101_OLT_RESGISTER_FAILED; break; } } else if (pst_data->em_type == HI_OMCI_NOTIFY_ROGUE_ONU_E) { auto_diag_monitor = FAULT_CODE_9000202_ONU_ROGUE; } else if (pst_data->em_type == HI_OMCI_NOTIFY_LOID_REGSTA_E) { if (pst_data->ui_data > 1) auto_diag_monitor = FAULT_CODE_9000102_OLT_RESGISTER_OVERTIME; } HI_IPC_ASYN_CALL("igd_cm_auto_diag_monitor_notify", &auto_diag_monitor); } static hi_int32 __sal_pon_notify_proc_omci(void *data, hi_uint32 len) { hi_wan_uplink_status link_status = { .wan_alport = HI_WAN_PORT_WAN1, }; hi_omci_notifier_data_s *pst_data = data; if (pst_data == NULL || sizeof(*pst_data) != len) { return HI_RET_INVALID_PARA; } hi_os_printf("notify_proc_omci type %u state %u\n", pst_data->em_type, pst_data->ui_data); if (pst_data->em_type == HI_OMCI_NOTIFY_ONUSTATE_E) { switch (pst_data->ui_data) { case HI_PLOAM_REGSTATE_INIT: case HI_PLOAM_REGSTATE_STANDBY: sal_pon_regstatus_init(); case HI_PLOAM_REGSTATE_SN: case HI_PLOAM_REGSTATE_RANGING: case HI_PLOAM_REGSTATE_POPUP: case HI_PLOAM_REGSTATE_EMERGENCYSTOP: case HI_PLOAM_REGSTATE_LOSLOF_ASSERTED: link_status.status = HI_WAN_LINK_STATUS_DOWN; HI_IPC_ASYN_CALL("hi_wan_uplink_status_update", &link_status, sizeof(link_status)); ul_online_time = 0; break; case HI_PLOAM_REGSTATE_OPERATION: sal_pon_regstatus_succ(); link_status.status = HI_WAN_LINK_STATUS_UP; HI_IPC_ASYN_CALL("hi_wan_uplink_status_update", &link_status, sizeof(link_status)); ul_online_time = (hi_uint32)hi_os_sysuptime(); break; default: break; } } pon_reg_fault_code_update(pst_data); return HI_RET_SUCC; } static hi_int32 __sal_pon_notify_proc_oam(void *data, hi_uint32 len) { hi_oam_notifier_data_s *pst_data = data; hi_wan_uplink_status link_status = { .wan_alport = HI_WAN_PORT_WAN1, .status = HI_WAN_LINK_STATUS_DOWN, }; if (pst_data == NULL || sizeof(*pst_data) != len) { return HI_RET_INVALID_PARA; } if (HI_OAM_NOTIFIY_MPCPREG_STATE_E == pst_data->em_type) { if (HI_OAM_NOTIFY_MPCP_O3_E != pst_data->ui_state) { ul_online_time = 0; } } else if (HI_OAM_NOTIFIY_OAMREG_STATE_E == pst_data->em_type) { if (HI_OAM_NOTIFY_REG_SUCC_E != pst_data->ui_state) { ul_online_time = 0; } else { link_status.status = HI_WAN_LINK_STATUS_UP; ul_online_time = (hi_uint32)hi_os_sysuptime(); } } HI_IPC_ASYN_CALL("hi_wan_uplink_status_update", &link_status, sizeof(link_status)); return HI_RET_SUCC; } static hi_uint32 __sal_pon_online_time_get(hi_uint32 *pui_time) { if (ul_online_time) { *pui_time = (hi_uint32)hi_os_sysuptime() - ul_online_time; } else { *pui_time = 0; } return HI_RET_SUCC; } static hi_int32 __sal_epon_regstatus_get(void *data, hi_uint32 len) { hi_oam_notifier_data_s *pst_data = data; if (pst_data == NULL || sizeof(*pst_data) != len) { return- HI_RET_INVALID_PARA; } if (pst_data->ui_state == HI_OAM_NOTIFY_REG_SUCC_E){ g_epon_regsta = HI_SAL_PON_REG_SUCC_E; return HI_RET_SUCC; } g_epon_regsta = HI_SAL_PON_REG_ING_E; return HI_RET_SUCC; } static hi_int32 __sal_pon_regstatus_get(hi_void) { hi_int32 i_reg_sta = HI_SAL_PON_REG_ERR_E; hi_uint32 ui_sta = 0xffffffff; enum hi_pon_mode mode; HI_IPC_CALL("hi_pon_get_fail_regstate", &ui_sta, sizeof(ui_sta)); if (HI_TRUE == ui_sta) { i_reg_sta = HI_SAL_PON_REG_FAIL_E; return i_reg_sta; } if (HI_IPC_CALL("hi_pon_get_mode", &mode, sizeof(mode)) == HI_RET_SUCC) { if (up_mode >= 0 && mode != up_mode && up_mode != HI_WAN_ACCESS_TYPE_GE) { up_mode = mode; } } switch (up_mode) { case HI_PON_MODE_GPON: case HI_PON_MODE_GPON_S: case HI_PON_MODE_10GGPON_U2DOT5G: case HI_PON_MODE_10GGPON_SYM: HI_IPC_CALL("hi_gpon_get_los_state", &ui_sta, sizeof(ui_sta)); if (ui_sta) { i_reg_sta = HI_SAL_PON_REG_ERR_E; return i_reg_sta; } HI_IPC_CALL("hi_gpon_get_reg_state", &ui_sta, sizeof(ui_sta)); i_reg_sta = (ui_sta == HI_PLOAM_REGSTATE_OPERATION) ? (HI_SAL_PON_REG_SUCC_E) : (HI_SAL_PON_REG_ING_E); break; case HI_PON_MODE_EPON: case HI_PON_MODE_10GEPON_1G: case HI_PON_MODE_10GEPON_U2DOT5G: case HI_PON_MODE_10GEPON_SYM: HI_IPC_CALL("hi_epon_get_los_state", &ui_sta, sizeof(ui_sta)); if (ui_sta) { i_reg_sta = HI_SAL_PON_REG_ERR_E; return i_reg_sta; } i_reg_sta = g_epon_regsta; break; default: break; } if (0 == ul_online_time && i_reg_sta == HI_SAL_PON_REG_SUCC_E) { ul_online_time = (hi_uint32)hi_os_sysuptime(); } return i_reg_sta; } static void init_ponlink_mode(void) { HI_IPC_CALL("hi_pon_get_mode", &up_mode, sizeof(up_mode)); g_pon_retstatus.em_regstatus = HI_SAL_PON_REG_ERR_E; hi_notifier_create(HI_OMCI_NOTIFIY_NAME, sizeof(hi_omci_notifier_data_s)); hi_notifier_reg(HI_OMCI_NOTIFIY_NAME, "__sal_pon_notify_proc_omci", __sal_pon_notify_proc_omci); hi_notifier_create(HI_OAM_NOTIFIY_NAME, sizeof(hi_oam_notifier_data_s)); hi_notifier_reg(HI_OAM_NOTIFIY_NAME, "__sal_pon_notify_proc_oam", __sal_pon_notify_proc_oam); hi_notifier_reg(HI_OAM_NOTIFIY_NAME, "__sal_epon_regstatus_get", __sal_epon_regstatus_get); switch (up_mode) { case HI_PON_MODE_GPON: case HI_PON_MODE_GPON_S: case HI_PON_MODE_10GGPON_U2DOT5G: case HI_PON_MODE_10GGPON_SYM: HI_IPC_CALL("hi_omci_start"); HI_SAL_NET_DBG("start omci, up_mode\n"); break; case HI_PON_MODE_EPON: case HI_PON_MODE_10GEPON_1G: case HI_PON_MODE_10GEPON_U2DOT5G: case HI_PON_MODE_10GEPON_SYM: HI_IPC_CALL("hi_oam_start"); HI_SAL_NET_DBG("start oam\n"); break; default: break; } __sal_pon_regstatus_get(); } static void pon_set_loid_reg_info(hi_uplink_reg_key *reg_key, hi_sysinfo_data_s *sysinfo) { hi_int32 ret; if (strcmp(reg_key->loid, sysinfo->ac_loid) && reg_key->loid[0]) { ret = cfmSetObj("sysinfo.loid", reg_key->loid); ret |= hi_ucm_set("sysinfo.loid", reg_key->loid); if (ret != HI_RET_SUCC) printf("err: set sysinfo.loid fail\n"); } if (strcmp(reg_key->loidpwd, sysinfo->ac_lopwd) && reg_key->loidpwd[0]) { ret = cfmSetObj("sysinfo.lopwd", reg_key->loidpwd); ret |= hi_ucm_set("sysinfo.lopwd", reg_key->loidpwd); if (ret != HI_RET_SUCC) printf("err: set sysinfo.lopwd fail\n"); } } static void gpon_set_reg_info(hi_uplink_reg_key *reg_key, hi_sysinfo_data_s *sysinfo) { char buf[128] = {0}; char hexbuf[8] = {0}; int id = 0; enum hi_pon_mode mode; hi_int32 ret = HI_RET_SUCC; if (HI_IPC_CALL("hi_pon_get_mode", &mode, sizeof(mode)) != HI_RET_SUCC) return; pon_set_loid_reg_info(reg_key, sysinfo); if ((mode == HI_PON_MODE_10GGPON_U2DOT5G) || (mode == HI_PON_MODE_10GGPON_SYM)) { if (strcmp(sysinfo->ac_reg_id, reg_key->regpwd)) { ret |= hi_ucm_set("sysinfo.reg_id", reg_key->regpwd); ret |= cfmSetObj("sysinfo.reg_id", reg_key->regpwd); } } else if ((mode == HI_PON_MODE_GPON) || (mode == HI_PON_MODE_GPON_S)) { while (id < 10) { if (reg_key->regpwd[id]) { ret |= sprintf_s(hexbuf, sizeof(hexbuf), "%02x", reg_key->regpwd[id]); } else { ret |= sprintf_s(hexbuf, sizeof(hexbuf), "%02x", 0); } id++; ret |= strcat_s(buf, sizeof(buf), hexbuf); } if (strcmp((char *)sysinfo->st_auid.auc_pwd, reg_key->regpwd)) { ret |= hi_ucm_set("sysinfo.auid.pwd", buf); ret |= cfmSetObj("sysinfo.auid.pwd", buf); } } if (ret < 0) { printf("gpon set reg info fail"); } } static void gpon_start_reg(hi_uplink_reg_key *reg_key) { struct hi_gpon_para reg_param = { 0 }; hi_sysinfo_data_s sysinfo = { 0 }; HI_IPC_CALL("hi_gpon_stop"); if (HI_IPC_CALL("hi_sysinfo_data_get", &sysinfo) != HI_RET_SUCC) { HI_SAL_NET_DBG("sysinfo not find\n"); HI_SAL_NET_TRACE(HI_RET_FAIL, 0, 0, 0, 0); return; } memcpy_s(reg_param.sn, sizeof(reg_param.sn), sysinfo.st_auid.auc_sn, sizeof(sysinfo.st_auid.auc_sn)); if (up_mode == HI_PON_MODE_10GGPON_U2DOT5G || up_mode == HI_PON_MODE_10GGPON_SYM) { (void)memcpy_s((char *)reg_param.regid, sizeof(reg_param.regid), reg_key->regpwd, strlen(reg_key->regpwd)); printf("start xgpon regist, regid=%s\n", reg_param.regid); } else { (void)memcpy_s((char *)reg_param.pwd, sizeof(reg_param.pwd), reg_key->regpwd, strlen(reg_key->regpwd)); printf("start gpon regist, pwd=%s\n", reg_param.pwd); } HI_IPC_CALL("hi_gpon_start", &reg_param); gpon_set_reg_info(reg_key, &sysinfo); } static void epon_start_reg(hi_uplink_reg_key *reg_key) { struct hi_epon_para epon_para = { 0 }; hi_sysinfo_data_s sysinfo = { 0 }; HI_IPC_CALL("hi_epon_stop"); if (HI_IPC_CALL("hi_sysinfo_data_get", &sysinfo) != HI_RET_SUCC) { HI_SAL_NET_DBG("sysinfo not find\n"); HI_SAL_NET_TRACE(HI_RET_FAIL, 0, 0, 0, 0); return; } pon_set_loid_reg_info(reg_key, &sysinfo); memcpy_s(epon_para.mac, sizeof(epon_para.mac), sysinfo.auc_llid0_mac, sizeof(sysinfo.auc_llid0_mac)); HI_IPC_CALL("hi_epon_start", &epon_para); printf("start epon regist, loid=%s, lopwd=%s\n", reg_key->loid, reg_key->loidpwd); } static hi_uint32 sal_pon_distance_calculate(hi_uint32 *ui_distance) { hi_double64 distance; hi_double64 time_delay; hi_uint32 ui_eqd = 0; hi_uint32 ui_teqd = 0; hi_uint32 ui_rate = 0; enum hi_pon_mode mode; HI_IPC_CALL("hi_pon_get_mode", &mode, sizeof(mode)); *ui_distance = 0; switch (up_mode) { case HI_PON_MODE_GPON: case HI_PON_MODE_GPON_S: case HI_PON_MODE_10GGPON_U2DOT5G: case HI_PON_MODE_10GGPON_SYM: if (HI_IPC_CALL("hi_gpon_get_eqd", &ui_eqd, sizeof(ui_eqd)) != HI_RET_SUCC) { HI_SAL_NET_DBG("get gpon eqd err\n"); HI_SAL_NET_TRACE(HI_RET_FAIL, 0, 0, 0, 0); return 0; } ui_teqd = (mode == HI_PON_MODE_GPON) || (mode == HI_PON_MODE_GPON_S) ? HI_NETAPP_GPON_TEQD : HI_NETAPP_XGPON_TEQD; ui_rate = (mode == HI_PON_MODE_GPON) || (mode == HI_PON_MODE_GPON_S) ? HI_NETAPP_GPON_RATE : HI_NETAPP_XGPON_RATE; while (ui_eqd > ui_teqd + HI_NETAPP_XGPON_TEQD_GAP) { ui_eqd -= HI_NETAPP_XGPON_TEQD_GAP; } distance = (double)abs(ui_teqd - ui_eqd) / ui_rate * 100; *ui_distance = ceil(distance); *ui_distance %= 200; /* 限制在200m内 */ /* 光速0.2km/us 往返乘2 */ time_delay = HI_NETAPP_TEQD_TIME_DELAY - 2 * (double)(*ui_distance) / 1000 / 0.2; ui_eqd = floor(time_delay); break; case HI_PON_MODE_EPON: case HI_PON_MODE_10GEPON_1G: case HI_PON_MODE_10GEPON_U2DOT5G: case HI_PON_MODE_10GEPON_SYM: break; default: break; } return ui_eqd; } /****************************************************************************** Function : hi_sal_pon_init Description : Init sal pon Input Parm : N/A Output Parm : N/A Return : HI_RET_SUCC/HI_RET_FAIL ******************************************************************************/ hi_int32 hi_sal_pon_init(hi_void) { return HI_RET_SUCC; } /****************************************************************************** Function : hi_sal_pon_exit Description : Exit sal pon Input Parm : N/A Output Parm : N/A Return : HI_RET_SUCC/HI_RET_FAIL ******************************************************************************/ hi_void hi_sal_pon_exit(hi_void) { return; } HI_DEF_IPC(hi_sal_uplink_start_reg, hi_uplink_reg_key *, pst_info) { hi_wan_common_info_s common_info = { 0 }; enum hi_pon_mode mode; if (up_mode < 0) { HI_IPC_CALL("hi_wan_common_get", &common_info); if (common_info.em_access_type != HI_WAN_ACCESS_TYPE_GE) { init_ponlink_mode(); } else { up_mode = HI_WAN_ACCESS_TYPE_GE; } } if ((up_mode != HI_WAN_ACCESS_TYPE_GE) && (HI_IPC_CALL("hi_pon_get_mode", &mode, sizeof(mode)) == HI_RET_SUCC)) { if (mode != up_mode) { up_mode = mode; } } switch (up_mode) { case HI_PON_MODE_GPON: case HI_PON_MODE_GPON_S: case HI_PON_MODE_10GGPON_U2DOT5G: case HI_PON_MODE_10GGPON_SYM: gpon_start_reg(pst_info); break; case HI_PON_MODE_EPON: case HI_PON_MODE_10GEPON_1G: case HI_PON_MODE_10GEPON_U2DOT5G: case HI_PON_MODE_10GEPON_SYM: epon_start_reg(pst_info); break; default: printf("pon mode not support\n"); break; } return 0; } HI_DEF_IPC(hi_sal_pon_reginfo_get, hi_sal_pon_reg_info_s *, pst_info) { if (up_mode == HI_WAN_ACCESS_TYPE_GE) { pst_info->em_olt_auth = HI_SAL_PON_REG_SUCC_E; return HI_RET_SUCC; } pst_info->em_olt_auth = __sal_pon_regstatus_get(); return HI_RET_SUCC; } HI_DEF_IPC(hi_sal_pon_uplink_status_get, hi_sal_pon_uplink_status_s *, pst_uplink_status) { hi_uint32 ui_sta = 0xffffffff; struct hi_epon_llidstate st_sta = { 0 }; struct hi_optical_state status = { 0 }; struct hi_gpon_fec gpon_fec = { 0 }; struct hi_epon_fec epon_fec = { 0 }; __sal_pon_online_time_get(&pst_uplink_status->ui_continuous_time); if (up_mode == HI_WAN_ACCESS_TYPE_GE) { return HI_RET_SUCC; } hi_optical_get_state(&status); pst_uplink_status->i_tx_power = status.txpower * 10000; pst_uplink_status->i_rx_power = status.rxpower * 10000; pst_uplink_status->i_temperature = status.temprature * 256; pst_uplink_status->i_bias_current = status.ibias * 500; pst_uplink_status->i_supply_vottage = status.voltage * 10000; pst_uplink_status->ui_fec_cap = 1; HI_IPC_CALL("hi_pon_get_mode", &up_mode, sizeof(up_mode)); switch (up_mode) { case HI_PON_MODE_GPON: case HI_PON_MODE_GPON_S: case HI_PON_MODE_10GGPON_U2DOT5G: case HI_PON_MODE_10GGPON_SYM: HI_IPC_CALL("hi_gpon_get_reg_state", &pst_uplink_status->em_status, sizeof(hi_uint32)); HI_IPC_CALL("hi_gpon_get_fec", &gpon_fec, sizeof(gpon_fec)); pst_uplink_status->ui_fec_status = gpon_fec.tx_fec; if(gpon_fec.rx_fec == 1) { pst_uplink_status->ui_fec_status |= PON_FEC_STATE_RX_ENABLE; } break; case HI_PON_MODE_EPON: case HI_PON_MODE_10GEPON_1G: case HI_PON_MODE_10GEPON_U2DOT5G: case HI_PON_MODE_10GEPON_SYM: HI_IPC_CALL("hi_epon_get_los_state", &ui_sta, sizeof(ui_sta)); HI_IPC_CALL("hi_epon_get_llidstate", &st_sta, sizeof(st_sta)); HI_IPC_CALL("hi_epon_get_fec", &epon_fec, sizeof(epon_fec)); if (ui_sta) { pst_uplink_status->em_status = HI_SAL_PON_UPLINK_NOSIGNAL_E; } else if (st_sta.state == 3) { pst_uplink_status->em_status = HI_SAL_PON_UPLINK_UP_E; } else if (st_sta.state == 4) { pst_uplink_status->em_status = HI_SAL_PON_UPLINK_POPUP_E; } else { pst_uplink_status->em_status = HI_SAL_PON_UPLINK_INITIALIZING_E; } pst_uplink_status->ui_fec_status = epon_fec.tx_fec_en; if(epon_fec.rx_fec_en == 1) { pst_uplink_status->ui_fec_status |= PON_FEC_STATE_ENABLE; } break; default: break; } return 0; } HI_DEF_IPC(hi_sal_pon_stats_get, hi_sal_pon_status_s *, pst_stats) { hi_uint32 pon_mode = up_mode; struct hi_epon_cnt st_epon_cnt; struct hi_gpon_cnt st_gpon_cnt; HI_IPC_CALL("hi_pon_get_mode", &pon_mode, sizeof(pon_mode)); switch (pon_mode) { case HI_PON_MODE_GPON: case HI_PON_MODE_GPON_S: case HI_PON_MODE_10GGPON_U2DOT5G: case HI_PON_MODE_10GGPON_SYM: HI_OS_MEMSET_S(&st_gpon_cnt, sizeof(st_gpon_cnt), 0, sizeof(st_gpon_cnt)); HI_IPC_CALL("hi_gpon_get_cnt", &st_gpon_cnt, sizeof(st_gpon_cnt)); pst_stats->ui_bytes_sent = ((hi_ulong64)st_gpon_cnt.tx_byte_h << 32) | st_gpon_cnt.tx_byte_l; pst_stats->ui_bytes_received = ((hi_ulong64)st_gpon_cnt.rx_byte_h << 32) | st_gpon_cnt.rx_byte_l; pst_stats->ui_packets_sent = st_gpon_cnt.tx; pst_stats->ui_packets_received = st_gpon_cnt.rx; pst_stats->ui_sunicast_packets = st_gpon_cnt.tx_uc; pst_stats->ui_runicast_packets = st_gpon_cnt.rx_uc; pst_stats->ui_smulticast_packets = st_gpon_cnt.tx_mc; pst_stats->ui_rmulticast_packets = st_gpon_cnt.rx_mc; pst_stats->ui_sbroadcast_packets = st_gpon_cnt.tx_bc; pst_stats->ui_rbroadcast_packets = st_gpon_cnt.rx_bc; pst_stats->ui_fec_error = st_gpon_cnt.rx_fec_err_cw; pst_stats->ui_fcs_error = st_gpon_cnt.fcs_err; pst_stats->ui_drop_packets_received = st_gpon_cnt.rx_err; pst_stats->ui_eqd = sal_pon_distance_calculate(&pst_stats->ui_distance); sal_pon_current_regstatus_get(pst_stats); //无法获取 pst_stats->ui_hec_error = 0; pst_stats->ui_drop_packets = 0; pst_stats->ui_spause_packets = 0; pst_stats->ui_rpause_packets = 0; break; case HI_PON_MODE_EPON: case HI_PON_MODE_10GEPON_1G: case HI_PON_MODE_10GEPON_U2DOT5G: case HI_PON_MODE_10GEPON_SYM: HI_OS_MEMSET_S(&st_epon_cnt, sizeof(st_epon_cnt), 0, sizeof(st_epon_cnt)); HI_IPC_CALL("hi_epon_get_cnt", &st_epon_cnt, sizeof(st_epon_cnt)); pst_stats->ui_bytes_sent = st_epon_cnt.tx_byte; pst_stats->ui_bytes_received = st_epon_cnt.rx_byte;; pst_stats->ui_packets_sent = st_epon_cnt.tx; pst_stats->ui_packets_received = st_epon_cnt.rx; pst_stats->ui_runicast_packets = st_epon_cnt.scb_rx_uc + st_epon_cnt.bc_rx_uc; pst_stats->ui_rmulticast_packets = st_epon_cnt.scb_rx_mc + st_epon_cnt.bc_rx_mc; pst_stats->ui_rbroadcast_packets = st_epon_cnt.scb_rx_bc + st_epon_cnt.bc_rx_bc; pst_stats->ui_fec_error = st_epon_cnt.rx_fec_seconds; pst_stats->ui_fcs_error = st_epon_cnt.rx_fcs_err; sal_pon_current_regstatus_get(pst_stats); //无法获取 pst_stats->ui_sunicast_packets = 0; pst_stats->ui_smulticast_packets = 0; pst_stats->ui_sbroadcast_packets = 0; pst_stats->ui_hec_error = 0; pst_stats->ui_drop_packets = 0; pst_stats->ui_spause_packets = 0; pst_stats->ui_rpause_packets = 0; pst_stats->ui_drop_packets_received = 0; pst_stats->ui_distance = 0; pst_stats->ui_eqd = 0; break; default : HI_SAL_NET_TRACE(HI_RET_FAIL, pon_mode, 0, 0, 0); return HI_RET_SUCC; } return HI_RET_SUCC; } static void hi_pon_sample_proc(void *arg) { hi_sal_pon_status_s pon_stats; FILE *fp = NULL; FILE *fp_temp = NULL; char rc; char buf[512] = {0}; int32_t rec_num = 0; uint64_t tx, rx; hi_sal_pon_stats_get(&pon_stats); if (access(PON_TRAFFIC_RECORD, F_OK) != 0) { fp = fopen(PON_TRAFFIC_RECORD,"w+"); if (fp) { (void)sprintf_s(buf, sizeof(buf)-1,"%llu %llu\n", pon_stats.ui_bytes_sent, pon_stats.ui_bytes_received); fprintf(fp, buf); fclose(fp); } goto out; } fp = fopen(PON_TRAFFIC_RECORD,"r"); if (fp == NULL) return; fp_temp = fopen(PON_TRAFFIC_RECORD_TEMP,"w"); while (fp_temp && !(feof(fp))) { if (rec_num == 0) { (void)sprintf_s(buf,sizeof(buf)-1, "%llu %llu\n", pon_stats.ui_bytes_sent, pon_stats.ui_bytes_received); fprintf(fp_temp, buf); rec_num++; } rc = fscanf(fp, "%llu %llu",&tx,&rx); if (rc == 2 && rc != EOF) { /* record only 72 hours data */ if (++rec_num > PON_TRAFFIC_SAMPLE_CNT) { break; } else { (void)sprintf_s(buf, sizeof(buf)-1, "%llu %llu\n", tx, rx); fprintf(fp_temp, buf); } } } fclose(fp); if (fp_temp) { fclose(fp_temp); snprintf(buf, sizeof(buf)-1, "cp -f %s %s",PON_TRAFFIC_RECORD_TEMP,PON_TRAFFIC_RECORD); system(buf); unlink(PON_TRAFFIC_RECORD_TEMP); } out: if (g_pon_sample_timerid) hi_timer_mod_wo_lock(g_pon_sample_timerid, HI_PON_STATS_SAMPLE_INTERVAL); } static void hi_pon_speed_cal_proc(void *arg) { hi_sal_pon_status_s pon_stats; FILE *fp = NULL; char buf[64]; uint64_t tx, rx, up_speed, dn_speed; static uint64_t lst_tx = 0, lst_rx = 0; hi_sal_pon_stats_get(&pon_stats); tx = pon_stats.ui_bytes_sent; rx = pon_stats.ui_bytes_received; if ((tx <= lst_tx) || (rx <= lst_rx)) { up_speed = 0; dn_speed = 0; lst_tx = 0; lst_rx = 0; } else { up_speed = ((tx - lst_tx) << 3) >> 10; /* kbps */ dn_speed = ((rx - lst_rx) << 3) >> 10; lst_tx = tx; lst_rx = rx; } (void)memset_s(buf, sizeof(buf), 0, sizeof(buf)); fp = fopen(PON_SPPED_RECORD, "w+"); if (fp != NULL) { (void)sprintf_s(buf, sizeof(buf), "%llu %llu\n", up_speed, dn_speed); fprintf(fp, buf); fclose(fp); } hi_timer_mod_wo_lock(g_pon_speed_cal_timerid, HI_PON_SPEED_CAL_INTERVAL); } HI_DEF_IPC(hi_pon_history_stats, struct hi_pon_history_stat_cfg *, cfg) { if (cfg->enable == HI_TRUE) { if (g_pon_sample_timerid == 0 && hi_timer_create(hi_pon_sample_proc, 0, &g_pon_sample_timerid) != HI_RET_SUCC) { printf("Create hi_pon_sample_proc timer failed\n"); return -HI_RET_FAIL; } hi_timer_mod(g_pon_sample_timerid, HI_PON_STATS_SAMPLE_INTERVAL); if (g_pon_speed_cal_timerid == 0 && hi_timer_create(hi_pon_speed_cal_proc, 0, &g_pon_speed_cal_timerid)) { printf("Create hi_pon_speed_cal_proc timer failed\n"); return -HI_RET_FAIL; } hi_timer_mod(g_pon_speed_cal_timerid, HI_PON_SPEED_CAL_INTERVAL); } else { if (g_pon_sample_timerid != 0) { hi_timer_destroy(g_pon_sample_timerid); g_pon_sample_timerid = 0; } if (g_pon_speed_cal_timerid != 0) { hi_timer_destroy(g_pon_speed_cal_timerid); g_pon_speed_cal_timerid = 0; } } return HI_RET_SUCC; } 以上是代码二 把这两部分不同的代码全都列出来,且分析两者的差异,并告诉我可能会产生的影响
08-06
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值