sync libkysdk-system version 2.3.0.0

This commit is contained in:
xibowen 2023-10-17 16:56:22 +08:00
parent 394dcd5672
commit 59d3510fac
30 changed files with 2690 additions and 257 deletions

View File

@ -2,6 +2,11 @@ include(FindPkgConfig)
pkg_check_modules(GLIB REQUIRED glib-2.0)
include_directories(${GLIB_INCLUDE_DIRS})
pkg_search_module(LIB_NL3 REQUIRED libnl-3.0)
pkg_search_module(LIB_NL3_ROUTE REQUIRED libnl-route-3.0)
include_directories(${LIB_NL3_INCLUDE_DIRS})
include_directories(${LIB_NL3_ROUTE_INCLUDE_DIRS})
set(HARDWARE_TOP_DIR ${CMAKE_CURRENT_LIST_DIR})
set(hwcode
"${HARDWARE_TOP_DIR}/libkybios.h"
@ -65,7 +70,7 @@ set_target_properties(kyhwinfo PROPERTIES VERSION 2.0.0 SOVERSION 1)
# add_executable(kyfan-test test/kyfan-test.c)
# add_executable(kyhw-test test/kyhw-test.c)
#
target_link_libraries(kyhw kylog kyconf pthread systemd cups curl udev ${GLIB_LIBRARIES})
target_link_libraries(kysdk-hardware kylog kyconf pthread systemd cups curl udev ${GLIB_LIBRARIES} ${LIB_NL3_LIBRARIES} ${LIB_NL3_ROUTE_LIBRARIES})
target_link_libraries(kybluetooth bluetooth hd gobject-2.0)
target_link_libraries(kyedid kylog m X11 Xrandr hd)
target_link_libraries(kyfan sensors)

View File

@ -55,7 +55,12 @@ extern const char *kdk_bios_get_vendor();
*/
extern const char *kdk_bios_get_version();
extern void kdk_bios_free(char *info);
/**
* @brief
*
* @param info
*/
extern void kdk_bios_free(char *info);
#ifdef __cplusplus
}

View File

@ -28,13 +28,29 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "sys/sysinfo.h"
#include <dirent.h>
#include "unistd.h"
#ifdef __linux__
#include <sys/utsname.h>
#endif
#define MIDSIZE 128
#ifndef max
# define max(x, y) __extension__ ({ \
__typeof__(x) _max1 = (x); \
__typeof__(y) _max2 = (y); \
(void) (&_max1 == &_max2); \
_max1 > _max2 ? _max1 : _max2; })
#endif
#ifndef min
# define min(x, y) __extension__ ({ \
__typeof__(x) _min1 = (x); \
__typeof__(y) _min2 = (y); \
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; })
#endif
struct _cpuInfo{
size_t ncpus; // CPU数量
size_t corenums; // CPU核心数量
@ -359,6 +375,7 @@ static void _get_cpu_info()
char buffer[CPUINF_BUFSIZE];
char *corenums;
char *cpu_process;
int cur_freq = 0;
while (fgets(buffer, CPUINF_BUFSIZE, fp))
{
// klog_debug("%s",buffer);
@ -454,6 +471,33 @@ static void _get_cpu_info()
cpuinf->corenums = sysconf(_SC_NPROCESSORS_ONLN);
}
if(cpuinf->cur_freq_MHz == NULL)
{
char ret[MIDSIZE] = {0};
int part = 0;
char path[128] = {0};
int i = 0;
char buffer[64] = {0};
for(i = 0; i < cpuinf->cpu_process; i++)
{
memset(path, 0, 128);
sprintf(path, "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_cur_freq", i);
fp = fopen(path, "rt");
if (!fp)
{
klog_err("cpuinfo_max_freq 读取失败:%s\n", strerror(errno));
return ;
}
fgets(ret, MIDSIZE, fp);
part = atoi(ret);
part = part / 1000;
cur_freq += part;
fclose(fp);
}
sprintf(buffer, "%ld", cur_freq / cpuinf->cpu_process);
cpuinf->cur_freq_MHz = strdup(buffer);
}
#endif
return;
}
@ -498,3 +542,419 @@ unsigned int kdk_cpu_get_process()
{
GET_VALUE(cpu_process, 0);
}
float kdk_cpu_get_max_freq_MHz()
{
char ret[MIDSIZE] = {0};
int num = 0;
int part = 0;
char path[128] = {0};
FILE *fp = NULL;
#ifdef __linux__
int process = kdk_cpu_get_process();
int i = 0;
for(i = 0; i < process; i++)
{
memset(path, 0, 128);
sprintf(path, "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_max_freq", i);
fp = fopen(path, "rt");
if (!fp)
{
klog_err("cpuinfo_max_freq 读取失败:%s\n", strerror(errno));
return -1;
}
fgets(ret, MIDSIZE, fp);
part = atoi(ret);
part = part / 1000;
num = max(num, part);
fclose(fp);
}
#endif
return num;
}
float kdk_cpu_get_min_freq_MHz()
{
char ret[MIDSIZE] = {0};
int num = kdk_cpu_get_max_freq_MHz();
int part = 0;
char path[128] = {0};
FILE *fp = NULL;
#ifdef __linux__
int process = kdk_cpu_get_process();
int i = 0;
for(i = 0; i < process; i++)
{
memset(path, 0, 128);
sprintf(path, "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_min_freq", i);
fp = fopen(path, "rt");
if (!fp)
{
klog_err("cpuinfo_min_freq 读取失败:%s\n", strerror(errno));
return -1;
}
fgets(ret, MIDSIZE, fp);
part = atoi(ret);
part = part / 1000;
num = min(num, part);
fclose(fp);
}
#endif
return num;
}
char* kdk_cpu_get_running_time()
{
FILE *fp = NULL;
int time_sec = 0;
char *runtime = (char *)malloc(sizeof(char) * 128);
if(!runtime)
return NULL;
memset(runtime, 0, 128);
if ((fp = fopen("/proc/uptime", "r"))) {
char buf[128] = {0};
long up_sec, up_usec;
if (fgets(buf, sizeof(buf), fp)) {
int nm = sscanf(buf, "%ld.%ld", &up_sec, &up_usec);
if (nm == 2) {
time_sec = up_sec;
long days = time_sec / 86400;
long hours = (time_sec - days * 86400) / 3600;
long mins = (time_sec - days * 86400 - hours * 3600) / 60;
sprintf(runtime, "%ld天%ld小时%ld分钟", days, hours, mins);
}
}
fclose(fp);
}
return runtime;
}
unsigned int kdk_cpu_get_sockets()
{
int sockets = 0;
char buffer[64] = {0};
memset(buffer, 0, 64);
char buf[2048] = {0};
memset(buf, 0, 2048);
int i = 0;
FILE *pipeLine = popen("lscpu", "r");
if (!pipeLine)
{
return -1;
}
if (__glibc_likely(pipeLine != NULL))
{
while (fgets(buf, sizeof(buf), pipeLine))
{
if(strstr(buf, "座:"))
{
sscanf(buf, "%*s %s", buffer);
strstripspace(buffer);
sockets = atoi(buffer);
}
else if(strstr(buf, "socket(s)"))
{
sscanf(buf, "%*s %s", buffer);
strstripspace(buffer);
sockets = atoi(buffer);
}
}
}
pclose(pipeLine);
return sockets;
}
unsigned int kdk_cpu_get_L1d_cache()
{
#ifdef __linux__
char res_buffer[64] = {0};
char buf[1024] = {0};
FILE *fp = NULL;
int cache_nums = 0;
fp = popen("lscpu", "r");
if(!fp)
{
return -1;
}
while (fgets(buf, sizeof(buf), fp))
{
if(strstr(buf, "L1d cache"))
{
sscanf(buf, "%*s %*s %s", res_buffer);
strstrip(res_buffer, 'K');
cache_nums = atoi(res_buffer);
if(strstr(buf, "MiB"))
{
cache_nums = cache_nums * 1024;
}
}
else if(strstr(buf, "L1d 缓存"))
{
sscanf(buf, "%*s %*s %s", res_buffer);
strstrip(res_buffer, 'K');
cache_nums = atoi(res_buffer);
if(strstr(buf, "MiB"))
{
cache_nums = cache_nums * 1024;
}
}
}
pclose(fp);
if(cache_nums == 0)
{
int i = 0;
FILE *pipeLine = popen("dmidecode -t cache", "r");
if (pipeLine != NULL)
{
memset(buf, 0, 1024);
memset(res_buffer, 0, 64);
while (fgets(buf, sizeof(buf), pipeLine))
{
if(strstr(buf, "L1 Data Cache"))
{
i = 1;
}
if(i != 1)
{
continue;
}
if(strstr(buf, "Installed Size"))
{
strstripspace(buf);
sscanf(buf, "Installed Size: %s %*s", res_buffer);
cache_nums = atoi(res_buffer);
break;
}
}
pclose(pipeLine);
}
}
#endif
return cache_nums;
}
unsigned int kdk_cpu_get_L1i_cache()
{
#ifdef __linux__
char res_buffer[64] = {0};
char buf[1024] = {0};
FILE *fp = NULL;
int cache_nums = 0;
fp = popen("lscpu", "r");
if(!fp)
{
return -1;
}
while (fgets(buf, sizeof(buf), fp))
{
if(strstr(buf, "L1i cache"))
{
sscanf(buf, "%*s %*s %s", res_buffer);
strstrip(res_buffer, 'K');
cache_nums = atoi(res_buffer);
if(strstr(buf, "MiB"))
{
cache_nums = cache_nums * 1024;
}
}
else if(strstr(buf, "L1i 缓存"))
{
sscanf(buf, "%*s %*s %s", res_buffer);
strstrip(res_buffer, 'K');
cache_nums = atoi(res_buffer);
if(strstr(buf, "MiB"))
{
cache_nums = cache_nums * 1024;
}
}
}
pclose(fp);
if(cache_nums == 0)
{
int i = 0;
FILE *pipeLine = popen("dmidecode -t cache", "r");
if (pipeLine != NULL)
{
memset(buf, 0, 1024);
memset(res_buffer, 0, 64);
while (fgets(buf, sizeof(buf), pipeLine))
{
if(strstr(buf, "L1 Instruction Cache"))
{
i = 1;
}
if(i != 1)
{
continue;
}
if(strstr(buf, "Installed Size"))
{
strstripspace(buf);
sscanf(buf, "Installed Size: %s %*s", res_buffer);
cache_nums = atoi(res_buffer);
break;
}
}
pclose(pipeLine);
}
}
#endif
return cache_nums;
}
unsigned int kdk_cpu_get_L2_cache()
{
#ifdef __linux__
char res_buffer[64] = {0};
char buf[1024] = {0};
FILE *fp = NULL;
int cache_nums = 0;
fp = popen("lscpu", "r");
if(!fp)
{
return -1;
}
while (fgets(buf, sizeof(buf), fp))
{
if(strstr(buf, "L2 cache"))
{
sscanf(buf, "%*s %*s %s", res_buffer);
strstrip(res_buffer, 'K');
cache_nums = atoi(res_buffer);
if(strstr(buf, "MiB"))
{
cache_nums = cache_nums * 1024;
}
}
else if(strstr(buf, "L2 缓存"))
{
sscanf(buf, "%*s %*s %s", res_buffer);
strstrip(res_buffer, 'K');
cache_nums = atoi(res_buffer);
if(strstr(buf, "MiB"))
{
cache_nums = cache_nums * 1024;
}
}
}
pclose(fp);
if(cache_nums == 0)
{
int i = 0;
FILE *pipeLine = popen("dmidecode -t cache", "r");
if (pipeLine != NULL)
{
memset(buf, 0, 1024);
memset(res_buffer, 0, 64);
while (fgets(buf, sizeof(buf), pipeLine))
{
if(strstr(buf, "L2 Cache") || strstr(buf, "L2 - Cache"))
{
i = 1;
}
if(i != 1)
{
continue;
}
if(strstr(buf, "Installed Size"))
{
strstripspace(buf);
sscanf(buf, "Installed Size: %s %*s", res_buffer);
cache_nums = atoi(res_buffer);
break;
}
}
pclose(pipeLine);
}
}
#endif
return cache_nums;
}
unsigned int kdk_cpu_get_L3_cache()
{
#ifdef __linux__
char res_buffer[64] = {0};
char buf[1024] = {0};
FILE *fp = NULL;
int cache_nums = 0;
fp = popen("lscpu", "r");
if(!fp)
{
return -1;
}
while (fgets(buf, sizeof(buf), fp))
{
if(strstr(buf, "L3 cache"))
{
sscanf(buf, "%*s %*s %s", res_buffer);
strstrip(res_buffer, 'K');
cache_nums = atoi(res_buffer);
if(strstr(buf, "MiB"))
{
cache_nums = cache_nums * 1024;
}
}
else if(strstr(buf, "L3 缓存"))
{
sscanf(buf, "%*s %*s %s", res_buffer);
strstrip(res_buffer, 'K');
cache_nums = atoi(res_buffer);
if(strstr(buf, "MiB"))
{
cache_nums = cache_nums * 1024;
}
}
}
pclose(fp);
if(cache_nums == 0)
{
int i = 0;
FILE *pipeLine = popen("dmidecode -t cache", "r");
if (pipeLine != NULL)
{
memset(buf, 0, 1024);
memset(res_buffer, 0, 64);
while (fgets(buf, sizeof(buf), pipeLine))
{
if(strstr(buf, "L3 Cache") || strstr(buf, "L3 - Cache"))
{
i = 1;
}
if(i != 1)
{
continue;
}
if(strstr(buf, "Installed Size"))
{
strstripspace(buf);
sscanf(buf, "Installed Size: %s %*s", res_buffer);
cache_nums = atoi(res_buffer);
break;
}
}
pclose(pipeLine);
}
}
#endif
return cache_nums;
}

View File

@ -82,23 +82,73 @@ extern unsigned int kdk_cpu_get_corenums();
extern const char* kdk_cpu_get_virt();
/**
* @brief CPU线程数
* @brief CPU线程数/
*
* @return unsigned int cpu支持的线程数
* @return unsigned int cpu支持的线程数/
*/
extern unsigned int kdk_cpu_get_process();
/**
* @brief CPU最大频率
*
* @return float cpu频率最大频率2600.0000MHz
*/
extern float kdk_cpu_get_max_freq_MHz();
/**
* @brief CPU最小频率
*
* @return float cpu频率最小频率1900.0000MHz
*/
extern float kdk_cpu_get_min_freq_MHz();
/**
* @brief CPU运行时间
*
* @return char* cpu运行时间xx天xx小时xx分钟NULL free
*/
extern char* kdk_cpu_get_running_time();
/**
* @brief CPU插槽
*
* @return unsigned int cpu插槽数量; -1
*/
extern unsigned int kdk_cpu_get_sockets();
/**
* @brief CPU L1缓存
*
* @return unsigned int cpu L1缓存; -1
*/
extern unsigned int kdk_cpu_get_L1d_cache();
/**
* @brief CPU L1缓存
*
* @return unsigned int cpu L1缓存; -1
*/
extern unsigned int kdk_cpu_get_L1i_cache();
/**
* @brief CPU L2缓存
*
* @return unsigned int cpu L2缓存; -1
*/
extern unsigned int kdk_cpu_get_L2_cache();
/**
* @brief CPU L3缓存
*
* @return unsigned int cpu L3缓存; -1
*/
extern unsigned int kdk_cpu_get_L3_cache();
#ifdef __cplusplus
}
#endif
#endif
/**
* \example kysdk-system/src/hardware/test/kycpu-test.c
*
*/
/**
* @}
*/

View File

@ -42,6 +42,15 @@
#include <glib.h>
#include <linux/sockios.h>
#include <linux/ethtool.h>
#include <net/if_arp.h>
#include <linux/wireless.h>
#include <libnl3/netlink/route/link.h>
#include <libnl3/netlink/route/addr.h>
#include <libnl3/netlink/addr.h>
#include <libnl3/netlink/types.h>
#include <libnl3/netlink/route/route.h>
#include <libnl3/netlink/netlink.h>
enum cardspec{
NCSPEC_ALL,
@ -68,6 +77,25 @@ enum cardcfg{
#define SIOCGIWNAME 0x8B01
#define PCIID_PATH "/usr/share/misc/pci.ids"
struct get_ipv4_addr_ctx_t {
struct nl_sock *sk;
int flag; /* 是否找到ip */
int index; /* 网卡索引 */
unsigned char *ip;
unsigned char *netmask;
unsigned char *broadaddr;
};
struct get_ipv6_addr_ctx_t {
struct nl_sock *sk;
int flag; /* 是否找到ip */
int index; /* 网卡索引 */
unsigned char *ip;
int scope;
int prefixlen;
int type;
};
static GKeyFile *
configure_open_file(const gchar *filename)
{
@ -168,25 +196,37 @@ get_ip_list(enum cardcfg type,const char *nc)
if (0 == strcmp(val->str, nc))
{
configure_read_string(keyFile, val, value, "address1", "null");
//这种实现方式一个网卡只能取到9个ip 因为ascii码只有1-9
char num = '1';
while (1)
{
char key[16];
memset(key,0,16);
strncpy(key,"address",7);
key[7] = num++;
configure_read_string(keyFile, val, value, key, "null");
if (0 != strcmp(val->str, "null"))
{
int i = -1;
while(val->str[++i] != 0x2f); // 0x2f是'/'的ascii码值
while (val->str[++i] != 0x2f)
; // 0x2f是'/'的ascii码值
val->str[i] = '\0';
if (0 != strcmp(curAddr, val->str))
{
res = (char **)realloc(result, (++count + 1) * sizeof(char *));
if(!res)
if (!res)
goto err_out;
result = res;
result[count - 1] = (char *)calloc(i + 1, sizeof(char));
if(!result[count - 1])
if (!result[count - 1])
goto err_out;
strncpy(result[count - 1], val->str, i);
result[count] = NULL;
}
}
else
break;
}
}
g_string_free(val,TRUE);
g_key_file_free(keyFile);
@ -698,3 +738,786 @@ inline void kdk_nc_freeall(char **list)
}
free(list);
}
static void ipv4_prefixlen2netmask(int prefixlen, unsigned char *netmask)
{
char buffer[32] = {0};
uint32_t mask = 0XFFFFFFFF;
mask = -1 << (32 - prefixlen);
sprintf(buffer, "%d.%d.%d.%d", (mask >> 24) & 0xFF, (mask >> 16) & 0xFF, (mask >> 8) & 0xFF, mask & 0xFF);
strcpy(netmask, buffer);
}
static void get_ipv4_addr_cache_cb(struct nl_object *obj, void *arg)
{
const size_t bufsiz = 128;
char tmpbuf[bufsiz];
char broadcast[bufsiz];
struct get_ipv4_addr_ctx_t *ctx = (struct get_ipv4_addr_ctx_t *)arg;
struct rtnl_addr *rtnl_addr = (struct rtnl_addr *)obj;
if (rtnl_addr_get_ifindex(rtnl_addr) == ctx->index) {
struct nl_addr *nl_addr = rtnl_addr_get_local(rtnl_addr);
if (nl_addr_get_family(nl_addr) == AF_INET && nl_addr_get_len(nl_addr) == 4) {
ctx->flag = 0x01;
nl_addr2str(nl_addr, tmpbuf, bufsiz);
tmpbuf[bufsiz - 1] = '\0';
char ** res = strsplit(tmpbuf, '/');
if(strstr(res[0], ctx->ip))
{
struct nl_addr *nl_broad = rtnl_addr_get_broadcast(rtnl_addr);
nl_addr2str(nl_broad, broadcast, bufsiz);
broadcast[bufsiz - 1] = '\0';
ctx->broadaddr = (char *)malloc(sizeof(char) * 32);
strcpy(ctx->broadaddr, broadcast);
int netmask_prefixlen = rtnl_addr_get_prefixlen(rtnl_addr);
if (netmask_prefixlen <= 32) {
ctx->netmask = (char *)malloc(sizeof(char) * 32);
memset(ctx->netmask, 0, 32);
ipv4_prefixlen2netmask(netmask_prefixlen, ctx->netmask);
}
}
}
}
}
static void get_ipv6_addr_cache_cb(struct nl_object *obj, void *arg)
{
const size_t bufsiz = 128;
char tmpbuf[bufsiz];
char broadcast[bufsiz];
struct get_ipv6_addr_ctx_t *ctx = (struct get_ipv_addr_ctx_t *)arg;
struct rtnl_addr *rtnl_addr = (struct rtnl_addr *)obj;
if (rtnl_addr_get_ifindex(rtnl_addr) == ctx->index) {
struct nl_addr *nl_addr = rtnl_addr_get_local(rtnl_addr);
if(ctx->type == 1)
{
if (nl_addr_get_family(nl_addr) == AF_INET && nl_addr_get_len(nl_addr) == 4) {
ctx->flag = 0x01;
nl_addr2str(nl_addr, tmpbuf, bufsiz);
tmpbuf[bufsiz - 1] = '\0';
char ** res = strsplit(tmpbuf, '/');
if(strstr(res[0], ctx->ip))
{
int netmask_prefixlen = rtnl_addr_get_prefixlen(rtnl_addr);
if (netmask_prefixlen <= 32) {
ctx->prefixlen = netmask_prefixlen;
}
}
}
}
else{
if (nl_addr_get_family(nl_addr) == AF_INET6 && nl_addr_get_len(nl_addr) == 16) {
ctx->flag = 0x01;
nl_addr2str(nl_addr, tmpbuf, bufsiz);
tmpbuf[bufsiz - 1] = '\0';
char ** res = strsplit(tmpbuf, '/');
if(strstr(res[0], ctx->ip))
{
int netmask_prefixlen = rtnl_addr_get_prefixlen(rtnl_addr);
ctx->prefixlen = netmask_prefixlen;
int scope = rtnl_addr_get_scope(rtnl_addr);
ctx->scope = scope;
}
}
}
}
}
char *kdk_nc_get_broadAddr(const char *eth_name, const char *address)
{
if (!address || !eth_name)
return NULL;
int ret = 0;
struct nl_cache *addr_cache;
struct rtnl_link *link;
char *ip = (char *)malloc(sizeof(char) * 32);
if(!ip)
{
return NULL;
}
memset(ip, 0, 32);
strcpy(ip, address);
char *broadAddr = (char *)malloc(sizeof(char) * 64);
if(!broadAddr)
{
free(ip);
return NULL;
}
memset(broadAddr, 0, 64);
struct nl_sock *sk = nl_socket_alloc();
nl_connect(sk, NETLINK_ROUTE);
ret = rtnl_link_get_kernel(sk, 0, eth_name, &link);
if (ret < 0) {
ret = -1;
goto error_out;
}
struct get_ipv4_addr_ctx_t ctx;
memset(&ctx, 0x00, sizeof(struct get_ipv4_addr_ctx_t));
ctx.index = rtnl_link_get_ifindex(link);
ctx.ip = ip;
rtnl_addr_alloc_cache(sk, &addr_cache);
nl_cache_foreach(addr_cache, get_ipv4_addr_cache_cb, &ctx);
if (ctx.flag == 0) {
goto error_out;
}
nl_cache_put(addr_cache);
rtnl_link_put(link);
free(ip);
strcpy(broadAddr, ctx.broadaddr);
free(ctx.broadaddr);
nl_close(sk);
nl_socket_free(sk);
return broadAddr;
error_out:
nl_close(sk);
nl_socket_free(sk);
free(ip);
free(broadAddr);
return NULL;
}
char *kdk_nc_get_netmask(const char *eth_name, const char *addr)
{
if (!addr || !eth_name)
return NULL;
int ret = 0;
struct nl_cache *addr_cache;
struct rtnl_link *link;
char *ip = (char *)malloc(sizeof(char) * 32);
if(!ip)
{
return NULL;
}
memset(ip, 0, 32);
strcpy(ip, addr);
char *netmask = (char *)malloc(sizeof(char) * 64);
if(!netmask)
{
free(ip);
return NULL;
}
memset(netmask, 0, 64);
struct nl_sock *sk = nl_socket_alloc();
nl_connect(sk, NETLINK_ROUTE);
ret = rtnl_link_get_kernel(sk, 0, eth_name, &link);
if (ret < 0) {
ret = -1;
goto error_out;
}
struct get_ipv4_addr_ctx_t ctx;
memset(&ctx, 0x00, sizeof(struct get_ipv4_addr_ctx_t));
ctx.index = rtnl_link_get_ifindex(link);
ctx.ip = ip;
rtnl_addr_alloc_cache(sk, &addr_cache);
nl_cache_foreach(addr_cache, get_ipv4_addr_cache_cb, &ctx);
if (ctx.flag == 0) {
goto error_out;
}
nl_cache_put(addr_cache);
rtnl_link_put(link);
free(ip);
strcpy(netmask, ctx.netmask);
free(ctx.netmask);
nl_close(sk);
nl_socket_free(sk);
return netmask;
error_out:
nl_close(sk);
nl_socket_free(sk);
free(ip);
free(netmask);
return NULL;
}
int kdk_nc_get_mask_length(int type, const char *eth_name, const char *addr)
{
if (!addr || !eth_name)
return -1;
int ret = 0;
struct nl_cache *addr_cache;
struct rtnl_link *link;
char *ip = (char *)malloc(sizeof(char) * 32);
if(!ip)
{
return -1;
}
memset(ip, 0, 32);
strcpy(ip, addr);
struct nl_sock *sk = nl_socket_alloc();
nl_connect(sk, NETLINK_ROUTE);
ret = rtnl_link_get_kernel(sk, 0, eth_name, &link);
if (ret < 0) {
ret = -1;
goto error_out;
}
struct get_ipv6_addr_ctx_t ctx;
memset(&ctx, 0x00, sizeof(struct get_ipv6_addr_ctx_t));
ctx.index = rtnl_link_get_ifindex(link);
ctx.ip = ip;
rtnl_addr_alloc_cache(sk, &addr_cache);
nl_cache_foreach(addr_cache, get_ipv6_addr_cache_cb, &ctx);
if (ctx.flag == 0) {
goto error_out;
}
nl_cache_put(addr_cache);
rtnl_link_put(link);
free(ip);
nl_close(sk);
nl_socket_free(sk);
return ctx.prefixlen;
error_out:
nl_close(sk);
nl_socket_free(sk);
free(ip);
return -1;
}
char *kdk_nc_get_conn_type(const char *nc)
{
if(!nc)
return NULL;
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, nc);
int fd = socket(PF_INET, SOCK_DGRAM, 0);
if (!ioctl(fd, SIOCGIFHWADDR, &ifr)) {
int m_sa_family = ifr.ifr_hwaddr.sa_family;
close(fd);
switch (m_sa_family) {
case ARPHRD_ETHER:
return "Ethernet";
case ARPHRD_SLIP:
return "SLIP";
case ARPHRD_LOOPBACK:
return "loopback";
case ARPHRD_FDDI:
return "FDDI";
case ARPHRD_IEEE1394:
return "IEEE1394";
case ARPHRD_IRDA:
return "IRDA";
case ARPHRD_PPP:
return "PPP";
case ARPHRD_X25:
return "X25";
case ARPHRD_TUNNEL:
return "IPtunnel";
case ARPHRD_DLCI:
return "Framerelay.DLCI";
case ARPHRD_FRAD:
return "Framerelay.AD";
case ARPHRD_TUNNEL6:
return "IP6tunnel";
case ARPHRD_SIT:
return "IP6inIP4";
default:
return "";
}
}
else{
close(fd);
return NULL;
}
}
char *kdk_nc_get_wifi_name(const char *nc)
{
if(!nc)
return NULL;
struct iwreq wrq;
struct iw_statistics stats;
char *wifi_name = (char *)malloc(sizeof(char) * 512);
if(!wifi_name)
return NULL;
memset(wifi_name, 0, 512);
char buffer[512];
memset(&wrq,0,sizeof(wrq));
memset(&stats,0,sizeof(stats));
memset(buffer, 0, 512);
strcpy(wrq.ifr_name, nc);
wrq.u.data.pointer = &stats;
wrq.u.data.length = sizeof(struct iw_statistics);
int sock = 0;
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
close(sock);
free(wifi_name);
return NULL;
}
if (ioctl(sock, SIOCGIWSTATS, &wrq) == -1) {
close(sock);
free(wifi_name);
return NULL;
}
wrq.u.essid.pointer = buffer;//如果不写这行可能会错误
wrq.u.essid.length = 512;
if (ioctl(sock, SIOCGIWESSID, &wrq) == -1) {
close(sock);
free(wifi_name);
return NULL;
}
if(wrq.u.essid.flags != 0){
strncpy(wifi_name, buffer, 512); //wifi名称
}
close(sock);
return wifi_name;
}
int kdk_nc_get_wifi_signal_qual(const char *nc)
{
struct iwreq wrq;
struct iw_statistics stats;
char buffer[512];
memset(&wrq,0,sizeof(wrq));
memset(&stats,0,sizeof(stats));
memset(buffer, 0, 512);
strcpy(wrq.ifr_name, nc);
wrq.u.data.pointer = &stats;
wrq.u.data.length = sizeof(struct iw_statistics);
int sock = 0;
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
close(sock);
return -1;
}
if (ioctl(sock, SIOCGIWSTATS, &wrq) == -1) {
close(sock);
return -1;
}
wrq.u.essid.pointer = buffer;//如果不写这行可能会错误
wrq.u.essid.length = 512;
if (ioctl(sock, SIOCGIWESSID, &wrq) == -1) {
close(sock);
return -1;
}
close(sock);
return stats.qual.qual;
}
int kdk_nc_get_wifi_signal_level(const char *nc)
{
struct iwreq wrq;
struct iw_statistics stats;
char buffer[512];
memset(&wrq,0,sizeof(wrq));
memset(&stats,0,sizeof(stats));
memset(buffer, 0, 512);
strcpy(wrq.ifr_name, nc);
wrq.u.data.pointer = &stats;
wrq.u.data.length = sizeof(struct iw_statistics);
int sock = 0;
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
close(sock);
return -1;
}
if (ioctl(sock, SIOCGIWSTATS, &wrq) == -1) {
close(sock);
return -1;
}
wrq.u.essid.pointer = buffer;//如果不写这行可能会错误
wrq.u.essid.length = 512;
if (ioctl(sock, SIOCGIWESSID, &wrq) == -1) {
close(sock);
return -1;
}
close(sock);
return stats.qual.level;
}
int kdk_nc_get_wifi_noise(const char *nc)
{
struct iwreq wrq;
struct iw_statistics stats;
char buffer[512];
memset(&wrq,0,sizeof(wrq));
memset(&stats,0,sizeof(stats));
memset(buffer, 0, 512);
strcpy(wrq.ifr_name, nc);
wrq.u.data.pointer = &stats;
wrq.u.data.length = sizeof(struct iw_statistics);
int sock = 0;
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
close(sock);
return -1;
}
if (ioctl(sock, SIOCGIWSTATS, &wrq) == -1) {
close(sock);
return -1;
}
wrq.u.essid.pointer = buffer;//如果不写这行可能会错误
wrq.u.essid.length = 512;
if (ioctl(sock, SIOCGIWESSID, &wrq) == -1) {
close(sock);
return -1;
}
close(sock);
return stats.qual.noise;
}
char *kdk_nc_get_speed(const char *nc)
{
if(!nc)
return NULL;
struct ifreq ifr;
struct ethtool_cmd ecmd;
char *speed = (char *)malloc(sizeof(char) * 32);
if(!speed)
return NULL;
memset(speed, 0, 32);
ecmd.cmd = 0x00000001;
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, nc);
ifr.ifr_data = &ecmd;
int fd = socket(PF_INET, SOCK_DGRAM, 0);
if (!ioctl(fd, SIOCETHTOOL, &ifr)) {
sprintf(speed, "%d Mb/s", ecmd.speed);
close(fd);
return speed;
}
else{
close(fd);
free(speed);
return NULL;
}
}
int kdk_nc_get_rx_packets(const char *nc)
{
if(!nc)
return -1;
char filename[256] = {0};
char res[64] = {0};
int packets = 0;
sprintf(filename, "/sys/class/net/%s/statistics/rx_packets", nc);
FILE *fp = fopen(filename, "r");
if (! fp)
return -1;
fgets(res, sizeof(res), fp);
strstrip(res, '\n');
sscanf(res, "%d", &packets);
fclose(fp);
return packets;
}
int kdk_nc_get_rx_bytes(const char *nc)
{
if(!nc)
return -1;
char filename[256] = {0};
char res[64] = {0};
int bytes = 0;
sprintf(filename, "/sys/class/net/%s/statistics/rx_bytes", nc);
FILE *fp = fopen(filename, "r");
if (! fp)
return -1;
fgets(res, sizeof(res), fp);
strstrip(res, '\n');
sscanf(res, "%d", &bytes);
fclose(fp);
return bytes;
}
int kdk_nc_get_rx_errors(const char *nc)
{
if(!nc)
return -1;
char filename[256] = {0};
char res[64] = {0};
int errors = 0;
sprintf(filename, "/sys/class/net/%s/statistics/rx_errors", nc);
FILE *fp = fopen(filename, "r");
if (! fp)
return -1;
fgets(res, sizeof(res), fp);
strstrip(res, '\n');
sscanf(res, "%d", &errors);
fclose(fp);
return errors;
}
int kdk_nc_get_rx_dropped(const char *nc)
{
if(!nc)
return -1;
char filename[256] = {0};
char res[64] = {0};
int dropped = 0;
sprintf(filename, "/sys/class/net/%s/statistics/rx_dropped", nc);
FILE *fp = fopen(filename, "r");
if (! fp)
return -1;
fgets(res, sizeof(res), fp);
strstrip(res, '\n');
sscanf(res, "%d", &dropped);
fclose(fp);
return dropped;
}
int kdk_nc_get_rx_fifo_errors(const char *nc)
{
if(!nc)
return -1;
char filename[256] = {0};
char res[64] = {0};
int fifo_errors = 0;
sprintf(filename, "/sys/class/net/%s/statistics/rx_fifo_errors", nc);
FILE *fp = fopen(filename, "r");
if (! fp)
return -1;
fgets(res, sizeof(res), fp);
strstrip(res, '\n');
sscanf(res, "%d", &fifo_errors);
fclose(fp);
return fifo_errors;
}
int kdk_nc_get_rx_frame_errors(const char *nc)
{
if(!nc)
return -1;
char filename[256] = {0};
char res[64] = {0};
int frame_errors = 0;
sprintf(filename, "/sys/class/net/%s/statistics/rx_frame_errors", nc);
FILE *fp = fopen(filename, "r");
if (! fp)
return -1;
fgets(res, sizeof(res), fp);
strstrip(res, '\n');
sscanf(res, "%d", &frame_errors);
fclose(fp);
return frame_errors;
}
int kdk_nc_get_tx_packets(const char *nc)
{
if(!nc)
return -1;
char filename[256] = {0};
char res[64] = {0};
int packets = 0;
sprintf(filename, "/sys/class/net/%s/statistics/tx_packets", nc);
FILE *fp = fopen(filename, "r");
if (! fp)
return -1;
fgets(res, sizeof(res), fp);
strstrip(res, '\n');
sscanf(res, "%d", &packets);
fclose(fp);
return packets;
}
int kdk_nc_get_tx_bytes(const char *nc)
{
if(!nc)
return -1;
char filename[256] = {0};
char res[64] = {0};
int tx_bytes = 0;
sprintf(filename, "/sys/class/net/%s/statistics/tx_bytes", nc);
FILE *fp = fopen(filename, "r");
if (! fp)
return -1;
fgets(res, sizeof(res), fp);
strstrip(res, '\n');
sscanf(res, "%d", &tx_bytes);
fclose(fp);
return tx_bytes;
}
int kdk_nc_get_tx_errors(const char *nc)
{
if(!nc)
return -1;
char filename[256] = {0};
char res[64] = {0};
int tx_errors = 0;
sprintf(filename, "/sys/class/net/%s/statistics/tx_errors", nc);
FILE *fp = fopen(filename, "r");
if (! fp)
return -1;
fgets(res, sizeof(res), fp);
strstrip(res, '\n');
sscanf(res, "%d", &tx_errors);
fclose(fp);
return tx_errors;
}
int kdk_nc_get_tx_dropped(const char *nc)
{
if(!nc)
return -1;
char filename[256] = {0};
char res[64] = {0};
int tx_dropped = 0;
sprintf(filename, "/sys/class/net/%s/statistics/tx_dropped", nc);
FILE *fp = fopen(filename, "r");
if (! fp)
return -1;
fgets(res, sizeof(res), fp);
strstrip(res, '\n');
sscanf(res, "%d", &tx_dropped);
fclose(fp);
return tx_dropped;
}
int kdk_nc_get_tx_fifo_errors(const char *nc)
{
if(!nc)
return -1;
char filename[256] = {0};
char res[64] = {0};
int fifo_errors = 0;
sprintf(filename, "/sys/class/net/%s/statistics/tx_fifo_errors", nc);
FILE *fp = fopen(filename, "r");
if (! fp)
return -1;
fgets(res, sizeof(res), fp);
strstrip(res, '\n');
sscanf(res, "%d", &fifo_errors);
fclose(fp);
return fifo_errors;
}
int kdk_nc_get_tx_carrier_errors(const char *nc)
{
if(!nc)
return -1;
char filename[256] = {0};
char res[64] = {0};
int carrier_errors = 0;
sprintf(filename, "/sys/class/net/%s/statistics/tx_carrier_errors", nc);
FILE *fp = fopen(filename, "r");
if (! fp)
return -1;
fgets(res, sizeof(res), fp);
strstrip(res, '\n');
sscanf(res, "%d", &carrier_errors);
fclose(fp);
return carrier_errors;
}
int kdk_nc_get_scope(const char *eth_name, const char *addr)
{
if (!addr || !eth_name)
return -1;
int ret = 0;
struct nl_cache *addr_cache;
struct rtnl_link *link;
char *ip = (char *)malloc(sizeof(char) * 32);
if(!ip)
{
return -1;
}
memset(ip, 0, 32);
strcpy(ip, addr);
struct nl_sock *sk = nl_socket_alloc();
nl_connect(sk, NETLINK_ROUTE);
ret = rtnl_link_get_kernel(sk, 0, eth_name, &link);
if (ret < 0) {
ret = -1;
goto error_out;
}
struct get_ipv6_addr_ctx_t ctx;
memset(&ctx, 0x00, sizeof(struct get_ipv6_addr_ctx_t));
ctx.index = rtnl_link_get_ifindex(link);
ctx.ip = ip;
rtnl_addr_alloc_cache(sk, &addr_cache);
nl_cache_foreach(addr_cache, get_ipv6_addr_cache_cb, &ctx);
if (ctx.flag == 0) {
goto error_out;
}
nl_cache_put(addr_cache);
rtnl_link_put(link);
free(ip);
nl_close(sk);
nl_socket_free(sk);
return ctx.scope;
error_out:
nl_close(sk);
nl_socket_free(sk);
free(ip);
return -1;
}

View File

@ -135,17 +135,192 @@ extern char *kdk_nc_get_driver(const char *nc);
*/
extern inline void kdk_nc_freeall(char **ptr);
/**
* @brief 广
*
* @param nc eno1
* @param addr ip地址
* @return char * 广, NULL free
*/
extern char *kdk_nc_get_broadAddr(const char *nc, const char *addr);
/**
* @brief
*
* @param nc eno1
* @param addr ip地址
* @return char * , NULL free
*/
extern char *kdk_nc_get_netmask(const char *nc, const char *addr);
/**
* @brief
*
* @param nc eno1
* @param type 1 ipv40 ipv6
* @param addr ip地址
* @return int
*/
extern int kdk_nc_get_mask_length(int type, const char *nc, const char *addr);
/**
* @brief
*
* @param nc eno1
* @return char * "Ethernet", NULL;free
*/
extern char *kdk_nc_get_conn_type(const char *nc);
/**
* @brief wifi名称
*
* @param nc eno1
* @return char * wifi名称, free
*/
extern char *kdk_nc_get_wifi_name(const char *nc);
/**
* @brief ( wifi )
*
* @param nc eno1
* @return int , -1
*/
extern int kdk_nc_get_wifi_signal_qual(const char *nc);
/**
* @brief ( wifi )
*
* @param nc eno1
* @return int , -1
*/
extern int kdk_nc_get_wifi_signal_level(const char *nc);
/**
* @brief ( wifi )
*
* @param nc eno1
* @return int , -1
*/
extern int kdk_nc_get_wifi_noise(const char *nc);
/**
* @brief
*
* @param nc eno1
* @return char * "1000Mb/s", NULL; free
*/
extern char *kdk_nc_get_speed(const char *nc);
/**
* @brief
*
* @param nc eno1
* @return int , -1
*/
extern int kdk_nc_get_rx_packets(const char *nc);
/**
* @brief
*
* @param nc eno1
* @return int ,, -1
*/
extern int kdk_nc_get_rx_bytes(const char *nc);
/**
* @brief ()
*
* @param nc eno1
* @return int (), -1
*/
extern int kdk_nc_get_rx_errors(const char *nc);
/**
* @brief ()
*
* @param nc eno1
* @return int (), -1
*/
extern int kdk_nc_get_rx_dropped(const char *nc);
/**
* @brief FIFO
*
* @param nc eno1
* @return int FIFO数量, -1
*/
extern int kdk_nc_get_rx_fifo_errors(const char *nc);
/**
* @brief
*
* @param nc eno1
* @return int , -1
*/
extern int kdk_nc_get_rx_frame_errors(const char *nc);
/**
* @brief
*
* @param nc eno1
* @return int , -1
*/
extern int kdk_nc_get_tx_packets(const char *nc);
/**
* @brief
*
* @param nc eno1
* @return int , , -1
*/
extern int kdk_nc_get_tx_bytes(const char *nc);
/**
* @brief ()
*
* @param nc eno1
* @return int (), -1
*/
extern int kdk_nc_get_tx_errors(const char *nc);
/**
* @brief ()
*
* @param nc eno1
* @return int (), -1
*/
extern int kdk_nc_get_tx_dropped(const char *nc);
/**
* @brief FIFO
*
* @param nc eno1
* @return int FIFO数量, -1
*/
extern int kdk_nc_get_tx_fifo_errors(const char *nc);
/**
* @brief
*
* @param nc eno1
* @return int , -1
*/
extern int kdk_nc_get_tx_carrier_errors(const char *nc);
/**
* @brief
*
* @param nc eno1
* @param addr ip地址
* @return int , -1
*/
extern int kdk_nc_get_scope(const char *nc, const char *addr);
#ifdef __cplusplus
}
#endif
#endif
/**
* \example kysdk-system/src/hardware/test/kync-test.c
*
*/
/**
* @}
*/

View File

@ -22,6 +22,7 @@
#include "../libkycpu.h"
#include <stdio.h>
#include <stdlib.h>
int main()
{
@ -32,5 +33,16 @@ int main()
printf("CPU 单核核心数量:%u\n", kdk_cpu_get_corenums());
printf("CPU 虚拟化支持:%s\n", kdk_cpu_get_virt());
printf("CPU 线程数:%u\n", kdk_cpu_get_process());
printf("CPU 最大频率:%0.2f MHz\n", kdk_cpu_get_max_freq_MHz());
printf("CPU 最小频率:%0.2f MHz\n", kdk_cpu_get_min_freq_MHz());
char *run_time = kdk_cpu_get_running_time();
printf("CPU 运行时间:%s\n", run_time);
free(run_time);
printf("CPU 插槽:%d\n", kdk_cpu_get_sockets());
printf("CPU L1缓存数据%d\n", kdk_cpu_get_L1d_cache());
printf("CPU L1缓存指令%d\n", kdk_cpu_get_L1i_cache());
printf("CPU L2缓存%d\n", kdk_cpu_get_L2_cache());
printf("CPU L3缓存%d\n", kdk_cpu_get_L3_cache());
return 0;
}

View File

@ -20,7 +20,7 @@
*
*/
#include "libkync.h"
#include "../libkync.h"
#include <stdio.h>
#include <stdlib.h>
@ -37,17 +37,81 @@ int main()
char *driver = kdk_nc_get_driver(cards[index]);
char vendor[256] = "\0", product[256] = "\0";
kdk_nc_get_vendor_and_product(cards[index], vendor, product);
printf("Card %zd: %s\tStatus: %s\tMac: %s\tIPv4: %s\tIPv6: %s\t Vendor: %s\t Product: %s\t Type: %s\t driver: %s\n",
printf("Card %zd: %s\tStatus: %s\tMac: %s\tIPv4: %s\tIPv6: %s\t Vendor: %s\t Product: %s\t Type: %s\t driver: %s\t \n",
index + 1, cards[index], kdk_nc_is_up(cards[index]) == 1 ? "Up" : "Down",
mac, ipv4, ipv6, vendor, product,
kdk_nc_is_wireless(cards[index]) ? "wireless" : "ethernet", driver);
char *conn = kdk_nc_get_conn_type(cards[index]);
printf("Conn type = %s\n", conn);
char *wifi_name = kdk_nc_get_wifi_name(cards[index]);
printf("wifi name = %s\n", wifi_name);
free(wifi_name);
char *speed = kdk_nc_get_speed(cards[index]);
printf("speed = %s\n", speed);
free(speed);
int rx_packets = kdk_nc_get_rx_packets(cards[index]);
printf("rx_packets = %d\n", rx_packets);
int rx_bytes = kdk_nc_get_rx_bytes(cards[index]);
printf("rx_bytes = %d\n", rx_bytes);
int rx_errors = kdk_nc_get_rx_errors(cards[index]);
printf("rx_errors = %d\n", rx_errors);
int rx_dropped = kdk_nc_get_rx_dropped(cards[index]);
printf("rx_dropped = %d\n", rx_dropped);
int fifo_errors = kdk_nc_get_rx_fifo_errors(cards[index]);
printf("fifo_errors = %d\n", fifo_errors);
int frame_errors = kdk_nc_get_rx_frame_errors(cards[index]);
printf("frame_errors = %d\n", frame_errors);
int tx_packets = kdk_nc_get_tx_packets(cards[index]);
printf("tx_packets = %d\n", tx_packets);
int tx_bytes = kdk_nc_get_tx_bytes(cards[index]);
printf("tx_bytes = %d\n", tx_bytes);
int tx_errors = kdk_nc_get_tx_errors(cards[index]);
printf("tx_errors = %d\n", tx_errors);
int tx_dropped = kdk_nc_get_tx_dropped(cards[index]);
printf("tx_dropped = %d\n", tx_dropped);
int tx_fifo_errors = kdk_nc_get_tx_fifo_errors(cards[index]);
printf("tx_fifo_errors = %d\n", tx_fifo_errors);
int tx_carrier_errors = kdk_nc_get_tx_carrier_errors(cards[index]);
printf("tx_carrier_errors = %d\n", tx_carrier_errors);
int signal_qual = kdk_nc_get_wifi_signal_qual(cards[index]);
printf("signal_qual = %d\n", signal_qual);
int signal_level = kdk_nc_get_wifi_signal_level(cards[index]);
printf("signal_level = %d\n", signal_level);
int noise = kdk_nc_get_wifi_noise(cards[index]);
printf("noise = %d\n", noise);
char **list4 = kdk_nc_get_ipv4(cards[index]);
int i = 0;
printf("AllIpV4: ");
while (list4 && list4[i])
{
printf("%s\t", list4[i++]);
printf("%s\n", list4[i]);
char *boardaddr = kdk_nc_get_broadAddr(cards[index], list4[i]);
printf("boardaddr = %s\n", boardaddr);
free(boardaddr);
char *netmask = kdk_nc_get_netmask(cards[index], list4[i]);
printf("netmask = %s\n", netmask);
free(netmask);
i++;
}
printf("\n");
char **list6 = kdk_nc_get_ipv6(cards[index]);
@ -55,8 +119,15 @@ int main()
i = 0;
while (list6 && list6[i])
{
printf("%s\t", list6[i++]);
printf("%s\t", list6[i]);
int len = kdk_nc_get_mask_length(0, cards[index], list6[i]);
printf("netmask_length = %d\n", len);
int scope = kdk_nc_get_scope(cards[index], list6[i]);
printf("scope = %d\n", scope);
i++;
}
printf("\n");
free(mac);
free(ipv4);

View File

@ -1,3 +1,25 @@
/*
* libkysdk-system's Library
*
* Copyright (C) 2023, KylinSoft Co., Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library. If not, see <https://www.gnu.org/licenses/>.
*
* Authors: Yunhe Liu <liuyunhe@kylinos.cn>
*
*/
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
@ -24,6 +46,25 @@ typedef struct rgb {
}rgb_t;
int verify_file(char *pFileName)
{
char *p = pFileName;
int len = strlen(pFileName);
if(len <= 4)
{
klog_err("filename is illeagal\n");
return -1;
}
len -= 4;
p+= len;
if(strcmp(p,".ppm"))
{
klog_err("file format is illeagal\n");
return -1;
}
else
return 0;
}
int read_image(const char * const file, size_t *width, size_t *height, rgb_t **buffer)
{
char line[0x80];
@ -33,7 +74,12 @@ int read_image(const char * const file, size_t *width, size_t *height, rgb_t **b
char* ret2;
ret = 0;
FILE *fp = fopen(file, "rb");
char fullname[256]={0};
if(!realpath(file,fullname) || verify_file(file))
{
return 0x05;
}
FILE *fp = fopen(fullname, "rb");
if(fp == NULL) {
klog_err("Could not open file:%s\n",file);
return 0x1;

View File

@ -1,3 +1,25 @@
/*
* libkysdk-system's Library
*
* Copyright (C) 2023, KylinSoft Co., Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library. If not, see <https://www.gnu.org/licenses/>.
*
* Authors: Yunhe Liu <liuyunhe@kylinos.cn>
*
*/
#ifndef LIBKYJIMAGEPROC_H
#define LIBKYJIMAGEPROC_H

View File

@ -204,28 +204,28 @@ set_target_properties(kysdk-ocr PROPERTIES VERSION 2.0.0 SOVERSION 1)
install(TARGETS kysdk-ocr LIBRARY DESTINATION ${CMAKE_INSTALL_RPATH})
install(TARGETS kysdk-ocr LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(FILES ${PROJECT_SOURCE_DIR}/libkyocr.hpp DESTINATION include/kysdk/kysdk-system)
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/libs/amd64/paddle_inference/paddle/lib/libpaddle_inference.so")
install(FILES ${PROJECT_SOURCE_DIR}/libs/libpaddle_inference DESTINATION lib/${CMAKE_HOST_SYSTEM_PROCESSOR}-linux-gnu/libpaddle_inference.so)
install(FILES ${PROJECT_SOURCE_DIR}/libs/libpaddle_inference DESTINATION ${CMAKE_INSTALL_LIBDIR}/libpaddle_inference.so)
elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86_64")
install(FILES ${PROJECT_SOURCE_DIR}/libs/amd64/paddle_inference/paddle/lib/libpaddle_inference.so DESTINATION lib/${CMAKE_HOST_SYSTEM_PROCESSOR}-linux-gnu/)
install(FILES ${PROJECT_SOURCE_DIR}/libs/amd64/paddle_inference/paddle/lib/libpaddle_inference.so DESTINATION ${CMAKE_INSTALL_LIBDIR})
elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "AMD64")
install(FILES ${PROJECT_SOURCE_DIR}/libs/amd64/paddle_inference/paddle/lib/libpaddle_inference.so DESTINATION lib/${CMAKE_HOST_SYSTEM_PROCESSOR}-linux-gnu/)
install(FILES ${PROJECT_SOURCE_DIR}/libs/amd64/paddle_inference/paddle/lib/libpaddle_inference.so DESTINATION ${CMAKE_INSTALL_LIBDIR})
elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "aarch64")
install(FILES ${PROJECT_SOURCE_DIR}/libs/arm64/paddle_inference/paddle/lib/libpaddle_inference.so DESTINATION lib/${CMAKE_HOST_SYSTEM_PROCESSOR}-linux-gnu/)
install(FILES ${PROJECT_SOURCE_DIR}/libs/arm64/paddle_inference/paddle/lib/libpaddle_inference.so DESTINATION ${CMAKE_INSTALL_LIBDIR})
elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "mips64")
install(FILES ${PROJECT_SOURCE_DIR}/libs/mips64el/paddle_inference/paddle/lib/libpaddle_inference.so DESTINATION lib/${CMAKE_HOST_SYSTEM_PROCESSOR}-linux-gnu/)
install(FILES ${PROJECT_SOURCE_DIR}/libs/mips64el/paddle_inference/paddle/lib/libpaddle_inference.so DESTINATION ${CMAKE_INSTALL_LIBDIR})
elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "loongarch64")
install(FILES ${PROJECT_SOURCE_DIR}/libs/libpaddle_inference DESTINATION lib/${CMAKE_HOST_SYSTEM_PROCESSOR}-linux-gnu/libpaddle_inference.so)
install(FILES ${PROJECT_SOURCE_DIR}/libs/libpaddle_inference DESTINATION ${CMAKE_INSTALL_LIBDIR}/libpaddle_inference.so)
elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "riscv64")
install(FILES ${PROJECT_SOURCE_DIR}/libs/libpaddle_inference DESTINATION lib/${CMAKE_HOST_SYSTEM_PROCESSOR}-linux-gnu/libpaddle_inference.so)
install(FILES ${PROJECT_SOURCE_DIR}/libs/libpaddle_inference DESTINATION ${CMAKE_INSTALL_LIBDIR}/libpaddle_inference.so)
# install(FILES ${PROJECT_SOURCE_DIR}/libs/loongarch64/paddle_inference/paddle/lib/libpaddle_inference.so DESTINATION lib/)
elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "sw_64")
install(FILES ${PROJECT_SOURCE_DIR}/libs/libpaddle_inference DESTINATION lib/${CMAKE_HOST_SYSTEM_PROCESSOR}-linux-gnu/libpaddle_inference.so)
install(FILES ${PROJECT_SOURCE_DIR}/libs/libpaddle_inference DESTINATION ${CMAKE_INSTALL_LIBDIR}/libpaddle_inference.so)
elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "armv8l")
install(FILES ${PROJECT_SOURCE_DIR}/libs/libpaddle_inference DESTINATION lib/${CMAKE_HOST_SYSTEM_PROCESSOR}-linux-gnu/libpaddle_inference.so)
install(FILES ${PROJECT_SOURCE_DIR}/libs/libpaddle_inference DESTINATION ${CMAKE_INSTALL_LIBDIR}/libpaddle_inference.so)
# install(FILES ${PROJECT_SOURCE_DIR}/libs/sw64/paddle_inference/paddle/lib/libpaddle_inference.so DESTINATION lib/)
endif()
#target_link_libraries(test libkdkOCR.so)

View File

@ -1,3 +1,19 @@
/*
* Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*******************************************************************************
* *
* Author : Angus Johnson *

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/../../.." vcs="Git" />
</component>
</project>

View File

@ -14,6 +14,10 @@
<policy context="default">
<allow send_destination="com.kylin.kysdk.service" />
<!-- remove the following line for debug -->
<!--
<allow send_interface="com.jd.ccis"/>
-->
</policy>
</busconfig>

View File

@ -14,6 +14,10 @@
<policy context="default">
<allow send_destination="com.kysdk.location" />
<!-- remove the following line for debug -->
<!--
<allow send_interface="com.jd.ccis"/>
-->
</policy>
</busconfig>

View File

@ -14,6 +14,10 @@
<policy context="default">
<allow send_destination="com.kysdk.base" />
<!-- remove the following line for debug -->
<!--
<allow send_interface="com.jd.ccis"/>
-->
</policy>
</busconfig>

View File

@ -70,15 +70,31 @@ typedef struct chain
struct chain *next;
} Chain, *pChain;
/// @brief 获取指定网络端口的状态
/// @param port 端口号
/// @return TCP_ESTABLISHED:0x1 TCP_SYN_SENT:0x2 TCP_SYN_RECV:0x3 TCP_FIN_WAIT1:0x4 TCP_FIN_WAIT2:0x5 \
/**
* @brief
*
* @param port
* @return int TCP_ESTABLISHED:0x1 TCP_SYN_SENT:0x2 TCP_SYN_RECV:0x3 TCP_FIN_WAIT1:0x4 TCP_FIN_WAIT2:0x5
TCP_TIME_WAIT:0x6 TCP_CLOSE:0x7 TCP_CLOSE_WAIT:0x8 TCP_LAST_ACL:0x9 TCP_LISTEN:0xa TCP_CLOSING:0xb
extern int kdk_net_get_port_stat(int port);
*/
extern int kdk_net_get_port_stat(int port);
extern int kdk_net_get_multiple_port_stat(int start, int end, int *result);
/**
* @brief
*
* @param start
* @param end
* @param result
* @return int 0 -1
*/
extern int kdk_net_get_multiple_port_stat(int start, int end, int *result);
extern prouteMapList kdk_net_get_route();
/**
* @brief
*
* @return prouteMapList
*/
extern prouteMapList kdk_net_get_route();
/**
* @brief kdk_net_get_route返回的网关信息结构体
@ -101,7 +117,7 @@ extern pChain kdk_net_get_iptable_rules();
extern void kdk_net_free_chain(pChain list);
/**
* @brief
* @brief
*
* @param nc eno1
* @param mask

View File

@ -350,3 +350,183 @@ int kdk_rti_get_uptime(unsigned int *day, unsigned int *hour, unsigned int *min,
#endif
return 0;
}
unsigned long kdk_rti_get_mem_shared_KiB()
{
unsigned long shmem = 0;
#ifdef __linux__
FILE *fp = fopen(MEMINFO_FILE, "rt");
if (!fp)
return 0;
char buffer[1025];
while (fgets(buffer, 1024, fp))
{
if (lookup(buffer, "Shmem", &shmem))
break;
}
fclose(fp);
#endif
return shmem;
}
unsigned long kdk_rti_get_mem_cached_KiB()
{
unsigned long cached = 0;
#ifdef __linux__
FILE *fp = fopen(MEMINFO_FILE, "rt");
if (!fp)
return 0;
char buffer[1025];
while (fgets(buffer, 1024, fp))
{
if (lookup(buffer, "Cached", &cached))
break;
}
fclose(fp);
#endif
return cached;
}
unsigned long kdk_rti_get_mem_buffers_KiB()
{
unsigned long buffers = 0;
#ifdef __linux__
FILE *fp = fopen(MEMINFO_FILE, "rt");
if (!fp)
return 0;
char buffer[1025];
while (fgets(buffer, 1024, fp))
{
if (lookup(buffer, "Buffers", &buffers))
break;
}
fclose(fp);
#endif
return buffers;
}
unsigned long kdk_rti_get_mem_swap_cached_KiB()
{
unsigned long swapCached = 0;
#ifdef __linux__
FILE *fp = fopen(MEMINFO_FILE, "rt");
if (!fp)
return 0;
char buffer[1025];
while (fgets(buffer, 1024, fp))
{
if (lookup(buffer, "SwapCached", &swapCached))
break;
}
fclose(fp);
#endif
return swapCached;
}
unsigned long kdk_rti_get_mem_active_KiB()
{
unsigned long active = 0;
#ifdef __linux__
FILE *fp = fopen(MEMINFO_FILE, "rt");
if (!fp)
return 0;
char buffer[1025];
while (fgets(buffer, 1024, fp))
{
if (lookup(buffer, "Active", &active))
break;
}
fclose(fp);
#endif
return active;
}
unsigned long kdk_rti_get_mem_inactive_KiB()
{
unsigned long inactive = 0;
#ifdef __linux__
FILE *fp = fopen(MEMINFO_FILE, "rt");
if (!fp)
return 0;
char buffer[1025];
while (fgets(buffer, 1024, fp))
{
if (lookup(buffer, "Inactive", &inactive))
break;
}
fclose(fp);
#endif
return inactive;
}
unsigned long kdk_rti_get_mem_dirty_KiB()
{
unsigned long dirty = 0;
#ifdef __linux__
FILE *fp = fopen(MEMINFO_FILE, "rt");
if (!fp)
return 0;
char buffer[1025];
while (fgets(buffer, 1024, fp))
{
if (lookup(buffer, "Dirty", &dirty))
break;
}
fclose(fp);
#endif
return dirty;
}
unsigned long kdk_rti_get_mem_map_KiB()
{
unsigned long map = 0;
#ifdef __linux__
FILE *fp = fopen(MEMINFO_FILE, "rt");
if (!fp)
return 0;
char buffer[1025];
while (fgets(buffer, 1024, fp))
{
if (lookup(buffer, "Mapped", &map))
break;
}
fclose(fp);
#endif
return map;
}
unsigned long kdk_rti_get_mem_slab_KiB()
{
unsigned long slab = 0;
#ifdef __linux__
FILE *fp = fopen(MEMINFO_FILE, "rt");
if (!fp)
return 0;
char buffer[1025];
while (fgets(buffer, 1024, fp))
{
if (lookup(buffer, "Slab", &slab))
break;
}
fclose(fp);
#endif
return slab;
}

View File

@ -135,17 +135,74 @@ extern float kdk_rti_get_cpu_current_usage();
*/
extern int kdk_rti_get_uptime(unsigned int *day, unsigned int *hour, unsigned int *min, unsigned int *sec);
/**
* @brief
*
* @return unsigned long KiB为单位
*/
extern unsigned long kdk_rti_get_mem_shared_KiB();
/**
* @brief
*
* @return unsigned long KiB为单位
*/
extern unsigned long kdk_rti_get_mem_cached_KiB();
/**
* @brief
*
* @return unsigned long KiB为单位
*/
extern unsigned long kdk_rti_get_mem_buffers_KiB();
/**
* @brief
*
* @return unsigned long KiB为单位
*/
extern unsigned long kdk_rti_get_mem_swap_cached_KiB();
/**
* @brief
*
* @return unsigned long KiB为单位
*/
extern unsigned long kdk_rti_get_mem_active_KiB();
/**
* @brief
*
* @return unsigned long KiB为单位
*/
extern unsigned long kdk_rti_get_mem_inactive_KiB();
/**
* @brief
*
* @return unsigned long KiB为单位
*/
extern unsigned long kdk_rti_get_mem_dirty_KiB();
/**
* @brief
*
* @return unsigned long KiB为单位
*/
extern unsigned long kdk_rti_get_mem_map_KiB();
/**
* @brief
*
* @return unsigned long KiB为单位
*/
extern unsigned long kdk_rti_get_mem_slab_KiB();
#ifdef __cplusplus
}
#endif
#endif
/**
* \example kysdk-system/src/proc/test/kyrtinfo-test.c
*
*/
/**
* @}
*/

View File

@ -34,6 +34,15 @@ int main()
printf("交换分区已用量:%lu KiB, %f\n", kdk_rti_get_mem_swap_usage_KiB(), kdk_rti_get_mem_swap_usage_percent());
printf("交换分区剩余大小:%lu KiB\n", kdk_rti_get_mem_swap_free_KiB());
printf("当前CPU使用率%f\n", kdk_rti_get_cpu_current_usage());
printf("共享内存大小:%lu KiB\n", kdk_rti_get_mem_shared_KiB());
printf("高速缓存大小:%lu KiB\n", kdk_rti_get_mem_cached_KiB());
printf("数据缓存大小:%lu KiB\n", kdk_rti_get_mem_buffers_KiB());
printf("交换缓存区大小:%lu KiB\n", kdk_rti_get_mem_swap_cached_KiB());
printf("活跃的缓冲文件大小:%lu KiB\n", kdk_rti_get_mem_active_KiB());
printf("不活跃的缓冲文件大小:%lu KiB\n", kdk_rti_get_mem_inactive_KiB());
printf("脏页大小:%lu KiB\n", kdk_rti_get_mem_dirty_KiB());
printf("映射大小:%lu KiB\n", kdk_rti_get_mem_map_KiB());
printf("内核数据结构缓存大小:%lu KiB\n", kdk_rti_get_mem_slab_KiB());
unsigned int day, hour, min, sec;
kdk_rti_get_uptime(&day, &hour, &min, &sec);
printf("开机时长:%u天%u小时%u分钟%u秒\n", day, hour, min, sec);

View File

@ -164,7 +164,7 @@ float kdk_real_get_net_speed(const char *nc)
int ret = 0;
memset(&ndev, 0, sizeof(ndev));
sprintf(ndev.ifs_name, "%s", nc);
ndev.ifs_us = 1000000;
ndev.ifs_us = 100000;
ret = get_if_speed(&ndev);
if (ret < 0)
return -1;

View File

@ -40,6 +40,7 @@
#include <utime.h>
#include "pci/pci.h"
#include <locale.h>
#include "sys/sysinfo.h"
#define SAFE_FREE(x) if (x) {free(x); x = NULL;}
#define KYLIN_ACTIVATION_DBUS_ADDRESS "org.freedesktop.activation"
@ -71,6 +72,11 @@ struct device
unsigned char *present; /* Maps which configuration bytes are present */
};
uint verify_file(char *pFileName)
{
return !strncmp(pFileName, "/proc", strlen("/proc"));
}
static char* get_val_from_file(FILE *fp, const char *key)
{
if (! fp)
@ -524,216 +530,419 @@ char* kdk_system_get_kernelVersion()
return kernver;
}
char* kdk_system_get_eUser()
char *kdk_system_get_eUser()
{
char *e_user = NULL;
char *active = NULL;
DBusConnection *conn;
DBusMessageIter args, sub;
DBusError err;
char *e_user;
int ret;
DBusConnection *connection = NULL, *user_conn = NULL;
DBusMessage *message = NULL, *reply = NULL;
DBusError error;
DBusMessageIter iter, args;
char *interface = calloc(64,1);
strcpy(interface,"org.freedesktop.login1.User");
char *property = calloc(32,1);
strcpy(property,"Name");
dbus_error_init(&err);
conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
if(dbus_error_is_set(&err))
// 初始化DBus连接
dbus_error_init(&error);
connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
if (connection == NULL)
{
dbus_error_free(&err);
fprintf(stderr, "DBus connection error: %s\n", error.message);
goto out;
}
if(NULL == conn)
// 创建DBus方法调用消息
message = dbus_message_new_method_call("org.freedesktop.login1",
"/org/freedesktop/login1",
"org.freedesktop.login1.Manager",
"ListUsers");
if (message == NULL)
{
free(interface);
free(property);
return NULL;
fprintf(stderr, "DBus message allocation failed\n");
goto out;
}
DBusMessage *msg=NULL;
DBusMessage *pending_msg=NULL;
DBusPendingCall *pending=NULL;
// 发送DBus消息并等待回复
reply = dbus_connection_send_with_reply_and_block(connection, message, -1, &error);
if (reply == NULL)
{
fprintf(stderr, "DBus reply error: %s\n", error.message);
goto out;
}
msg = dbus_message_new_method_call("org.freedesktop.login1",
"/org/freedesktop/login1/user/self",
// 释放message
dbus_message_unref(message);
// 解析回复消息
if (!dbus_message_iter_init(reply, &iter) ||
dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT)
{
fprintf(stderr, "DBus reply parsing failed\n");
goto out;
}
// 释放reply
dbus_message_unref(reply);
// 获取数组长度 获取的长度不对 弃用
// int array_length;
dbus_message_iter_recurse(&iter, &iter);
// array_length = dbus_message_iter_get_array_len(&iter);
// printf("%d\n", array_length);
// 解析数组中的每个结构体元素
while (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INVALID)
{
DBusMessageIter struct_iter;
dbus_uint32_t uid;
char *name = NULL, *path = NULL;
dbus_message_iter_recurse(&iter, &struct_iter);
// dbus_message_iter_get_basic(&struct_iter, &path); // 获取uid
dbus_message_iter_next(&struct_iter);
// dbus_message_iter_get_basic(&struct_iter, &name); // 获取name
dbus_message_iter_next(&struct_iter);
dbus_message_iter_get_basic(&struct_iter, &path); // 获取interface
// 获取EUser
char *interface = "org.freedesktop.login1.User";
char *state = "State";
char *property = "Name";
user_conn = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
if (user_conn == NULL)
{
fprintf(stderr, "DBus connection error: %s\n", error.message);
goto out;
}
// 创建DBus方法调用消息
message = dbus_message_new_method_call("org.freedesktop.login1",
path,
"org.freedesktop.DBus.Properties",
"Get");
if(NULL == msg)
if (message == NULL)
{
free(interface);
free(property);
return NULL;
fprintf(stderr, "DBus message allocation failed\n");
goto out;
}
dbus_message_iter_init_append(msg, &args);
if(!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &interface))
//添加入参
dbus_message_iter_init_append(message, &args);
if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &interface))
{
free(interface);
free(property);
return NULL;
}
free(interface);
if(!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &property))
{
free(property);
return NULL;
}
free(property);
if(!dbus_connection_send_with_reply(conn, msg, &pending, -1))
{
return NULL;
}
if(NULL == pending)
{
return NULL;
goto out;
}
dbus_connection_flush(conn);
dbus_message_unref(msg);
dbus_pending_call_block(pending);
pending_msg = dbus_pending_call_steal_reply(pending);
if(NULL == pending_msg)
if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &state))
{
return NULL;
goto out;
}
dbus_pending_call_unref(pending);
if(!dbus_message_iter_init(pending_msg, &args))
// 发送DBus消息并等待回复
reply = dbus_connection_send_with_reply_and_block(connection, message, -1, &error);
if (reply == NULL)
{
return NULL;
fprintf(stderr, "DBus reply error: %s\n", error.message);
goto out;
}
else
//释放message
dbus_message_unref(message);
// 解析回复消息
if (!dbus_message_iter_init(reply, &args) ||
dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_VARIANT)
{
dbus_message_iter_recurse(&args,&sub);
fprintf(stderr, "DBus reply parsing failed\n");
goto out;
}
// 释放reply
dbus_message_unref(reply);
DBusMessageIter sub;
dbus_message_iter_recurse(&args, &sub);
dbus_message_iter_get_basic(&sub, &active);
if(0 == strcmp(active, "active"))
{
message = dbus_message_new_method_call("org.freedesktop.login1",
path,
"org.freedesktop.DBus.Properties",
"Get");
if (message == NULL)
{
fprintf(stderr, "DBus message allocation failed\n");
goto out;
}
// 添加入参
dbus_message_iter_init_append(message, &args);
if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &interface))
{
goto out;
}
if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &property))
{
goto out;
}
// 发送DBus消息并等待回复
reply = dbus_connection_send_with_reply_and_block(connection, message, -1, &error);
if (reply == NULL)
{
fprintf(stderr, "DBus reply error: %s\n", error.message);
goto out;
}
// 释放message
dbus_message_unref(message);
// 解析回复消息
if (!dbus_message_iter_init(reply, &args) ||
dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_VARIANT)
{
fprintf(stderr, "DBus reply parsing failed\n");
goto out;
}
// 释放reply
dbus_message_unref(reply);
dbus_message_iter_recurse(&args, &sub);
dbus_message_iter_get_basic(&sub, &e_user);
}
dbus_message_unref(pending_msg);
// if(msg)
// dbus_message_unref(msg);
// if(pending_msg)
// dbus_message_unref(pending_msg);
// if (pending)
// dbus_pending_call_unref(pending);
dbus_connection_unref(user_conn);
user_conn = NULL;
if(e_user)
break;
dbus_message_iter_next(&iter);
}
// 释放内存
out:
dbus_error_free(&error);
// if(message)
// dbus_message_unref(message);
// if(reply)
// dbus_message_unref(reply);
if(connection)
dbus_connection_unref(connection);
if(user_conn)
dbus_connection_unref(user_conn);
return e_user;
// char *loginName = NULL;
// #ifdef __linux__
// loginName = strdup(getpwuid(getuid())->pw_name);
// #endif
// return loginName;
}
char* kdk_system_get_eUser_login_time()
char *kdk_system_get_eUser_login_time()
{
DBusConnection *conn;
DBusMessageIter args, sub;
DBusError err;
dbus_uint64_t *time_stamp = calloc(1, sizeof(dbus_uint64_t));
int ret;
char *active = NULL;
dbus_uint64_t time_stamp = 0;
char *interface = calloc(64,1);
strcpy(interface,"org.freedesktop.login1.User");
char *property = calloc(32,1);
strcpy(property,"Timestamp");
DBusConnection *connection = NULL, *user_conn = NULL;
DBusMessage *message = NULL, *reply = NULL;
DBusError error;
DBusMessageIter iter, args;
dbus_error_init(&err);
conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
if(dbus_error_is_set(&err))
// 初始化DBus连接
dbus_error_init(&error);
connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
if (connection == NULL)
{
dbus_error_free(&err);
fprintf(stderr, "DBus connection error: %s\n", error.message);
goto out;
}
if(NULL == conn)
// 创建DBus方法调用消息
message = dbus_message_new_method_call("org.freedesktop.login1",
"/org/freedesktop/login1",
"org.freedesktop.login1.Manager",
"ListUsers");
if (message == NULL)
{
free(interface);
free(property);
return NULL;
fprintf(stderr, "DBus message allocation failed\n");
goto out;
}
DBusMessage *msg=NULL;
DBusMessage *pending_msg=NULL;
DBusPendingCall *pending=NULL;
// 发送DBus消息并等待回复
reply = dbus_connection_send_with_reply_and_block(connection, message, -1, &error);
if (reply == NULL)
{
fprintf(stderr, "DBus reply error: %s\n", error.message);
goto out;
}
msg = dbus_message_new_method_call("org.freedesktop.login1",
"/org/freedesktop/login1/user/self",
// 释放message
dbus_message_unref(message);
// 解析回复消息
if (!dbus_message_iter_init(reply, &iter) ||
dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT)
{
fprintf(stderr, "DBus reply parsing failed\n");
goto out;
}
// 释放reply
dbus_message_unref(reply);
// 获取数组长度 获取的长度不对 弃用
// int array_length;
dbus_message_iter_recurse(&iter, &iter);
// array_length = dbus_message_iter_get_array_len(&iter);
// printf("%d\n", array_length);
// 解析数组中的每个结构体元素
while (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INVALID)
{
DBusMessageIter struct_iter;
dbus_uint32_t uid;
char *name = NULL, *path = NULL;
dbus_message_iter_recurse(&iter, &struct_iter);
// dbus_message_iter_get_basic(&struct_iter, &path); // 获取uid
dbus_message_iter_next(&struct_iter);
// dbus_message_iter_get_basic(&struct_iter, &name); // 获取name
dbus_message_iter_next(&struct_iter);
dbus_message_iter_get_basic(&struct_iter, &path); // 获取interface
// 获取EUser
char *interface = "org.freedesktop.login1.User";
char *state = "State";
char *property = "Timestamp";
user_conn = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
if (user_conn == NULL)
{
fprintf(stderr, "DBus connection error: %s\n", error.message);
goto out;
}
// 创建DBus方法调用消息
message = dbus_message_new_method_call("org.freedesktop.login1",
path,
"org.freedesktop.DBus.Properties",
"Get");
if(NULL == msg)
if (message == NULL)
{
free(interface);
free(property);
return NULL;
fprintf(stderr, "DBus message allocation failed\n");
goto out;
}
dbus_message_iter_init_append(msg, &args);
if(!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &interface))
//添加入参
dbus_message_iter_init_append(message, &args);
if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &interface))
{
free(interface);
free(property);
return NULL;
}
free(interface);
if(!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &property))
{
free(property);
return NULL;
}
free(property);
if(!dbus_connection_send_with_reply(conn, msg, &pending, -1))
{
return NULL;
}
if(NULL == pending)
{
return NULL;
goto out;
}
dbus_connection_flush(conn);
dbus_message_unref(msg);
dbus_pending_call_block(pending);
pending_msg = dbus_pending_call_steal_reply(pending);
if(NULL == pending_msg)
if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &state))
{
return NULL;
goto out;
}
dbus_pending_call_unref(pending);
if(!dbus_message_iter_init(pending_msg, &args))
// 发送DBus消息并等待回复
reply = dbus_connection_send_with_reply_and_block(connection, message, -1, &error);
if (reply == NULL)
{
return NULL;
fprintf(stderr, "DBus reply error: %s\n", error.message);
goto out;
}
else
{
dbus_message_iter_recurse(&args,&sub);
dbus_message_iter_get_basic(&sub, time_stamp);
}
dbus_message_unref(pending_msg);
time_t t1 = *time_stamp / 1000000;
//释放message
dbus_message_unref(message);
// 解析回复消息
if (!dbus_message_iter_init(reply, &args) ||
dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_VARIANT)
{
fprintf(stderr, "DBus reply parsing failed\n");
goto out;
}
// 释放reply
dbus_message_unref(reply);
DBusMessageIter sub;
dbus_message_iter_recurse(&args, &sub);
dbus_message_iter_get_basic(&sub, &active);
if(0 == strcmp(active, "active"))
{
message = dbus_message_new_method_call("org.freedesktop.login1",
path,
"org.freedesktop.DBus.Properties",
"Get");
if (message == NULL)
{
fprintf(stderr, "DBus message allocation failed\n");
goto out;
}
// 添加入参
dbus_message_iter_init_append(message, &args);
if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &interface))
{
goto out;
}
if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &property))
{
goto out;
}
// 发送DBus消息并等待回复
reply = dbus_connection_send_with_reply_and_block(connection, message, -1, &error);
if (reply == NULL)
{
fprintf(stderr, "DBus reply error: %s\n", error.message);
goto out;
}
// 释放message
dbus_message_unref(message);
// 解析回复消息
if (!dbus_message_iter_init(reply, &args) ||
dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_VARIANT)
{
fprintf(stderr, "DBus reply parsing failed\n");
goto out;
}
// 释放reply
dbus_message_unref(reply);
dbus_message_iter_recurse(&args, &sub);
dbus_message_iter_get_basic(&sub, &time_stamp);
}
dbus_connection_unref(user_conn);
user_conn = NULL;
if(0 < time_stamp)
break;
dbus_message_iter_next(&iter);
}
time_t t1 = time_stamp / 1000000;
struct tm *timeDate = localtime(&t1);
char *login_time = calloc(32, sizeof(char));
sprintf(login_time,"%04d-%02d-%02d %02d:%02d:%02d",timeDate->tm_year+1900,timeDate->tm_mon+1,\
timeDate->tm_mday,timeDate->tm_hour,timeDate->tm_min,timeDate->tm_sec);
// if(msg)
// dbus_message_unref(msg);
// if(pending_msg)
// dbus_message_unref(pending_msg);
// if (pending)
// dbus_pending_call_unref(pending);
sprintf(login_time, "%04d-%02d-%02d %02d:%02d:%02d", timeDate->tm_year + 1900, timeDate->tm_mon + 1,
timeDate->tm_mday, timeDate->tm_hour, timeDate->tm_min, timeDate->tm_sec);
// 释放内存
out:
dbus_error_free(&error);
// if(message)
// dbus_message_unref(message);
// if(reply)
// dbus_message_unref(reply);
if(connection)
dbus_connection_unref(connection);
if(user_conn)
dbus_connection_unref(user_conn);
return login_time;
}
@ -2218,3 +2427,135 @@ char *kdk_system_get_appScene()
#endif
return scene;
}
unsigned int kdk_system_get_file_descriptor()
{
FILE *fp = NULL;
unsigned int file_nr = 0;
errno = 0;
if ((fp = fopen("/proc/sys/fs/file-nr", "r"))) {
char buf[128] = {0};
if (fgets(buf, sizeof(buf), fp)) {
int nm = sscanf(buf, "%u", &file_nr);
if (nm == 1)
{
return file_nr;
}
}
}
fclose(fp);
return 0;
}
unsigned int kdk_system_get_process_nums()
{
DIR *dir;
struct dirent *entry;
int count = 0;
// 打开/proc目录
dir = opendir("/proc");
if (dir == NULL) {
// perror("无法打开/proc目录");
return 1;
}
// 遍历目录并计算进程总数
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_DIR) {
// 判断目录名是否为数字(代表进程)
char *name = entry->d_name;
int is_process = 1;
for (int i = 0; name[i] != '\0'; i++) {
if (!isdigit(name[i])) {
is_process = 0;
break;
}
}
if (is_process) {
count++;
}
}
}
closedir(dir);
return count;
}
unsigned int kdk_system_get_thread_nums()
{
DIR *dir;
struct dirent *entry;
char path[128] = {0};
struct stat fileStat;
int threadCount = 0;
char buffer[1024] = {0};
// 打开/proc目录
dir = opendir("/proc");
if (dir == NULL) {
perror("无法打开/proc目录");
return 1;
}
// 遍历目录并计算进程总数
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_DIR) {
// 判断目录名是否为数字(代表进程)
char *name = entry->d_name;
int is_process = 1;
for (int i = 0; name[i] != '\0'; i++) {
if (!isdigit(name[i])) {
is_process = 0;
break;
}
}
if (is_process) {
// count++;
sprintf(path, "/proc/%s/status", entry->d_name);
char canonical_filename[4096] = {"\0"};
FILE *fp = NULL;
if (!realpath(path, canonical_filename) || !verify_file(canonical_filename))
{
closedir(dir);
return -1;
}
fp = fopen(canonical_filename, "r");
if(!fp)
{
closedir(dir);
return -1;
}
char *threads = get_val_from_file(fp, "Threads");
strstripspace(threads);
threadCount += atoi(threads);
fclose(fp);
free(threads);
}
}
}
closedir(dir);
return threadCount;
}
kdk_loadavg kdk_system_get_loadavg()
{
struct sysinfo info;
kdk_loadavg loadAvg;
int rc = sysinfo(&info);
if (!rc) {
loadAvg.loadavg_1m = info.loads[0];
loadAvg.loadavg_5m = info.loads[1];
loadAvg.loadavg_15m = info.loads[2];
}
else{
return;
}
return loadAvg;
}

View File

@ -66,6 +66,13 @@ struct KPci
struct KPci *next;
};
typedef struct _kdk_loadavg{
/* 1, 5, and 15 minute load averages */
float loadavg_1m;
float loadavg_5m;
float loadavg_15m;
}kdk_loadavg;
/**
* @brief
*
@ -301,17 +308,40 @@ extern void kdk_hw_free_pci_info(struct KPci *info);
*/
extern char *kdk_system_get_appScene();
/**
* @brief
*
* @return unsigned int cpu的文件描述符数
*/
extern unsigned int kdk_system_get_file_descriptor();
/**
* @brief
*
* @return unsigned int cpu的进程数
*/
extern unsigned int kdk_system_get_process_nums();
/**
* @brief 线
*
* @return unsigned int cpu的线程数
*/
extern unsigned int kdk_system_get_thread_nums();
/**
* @brief CPU负载均衡
*
* @return kdk_loadavg cpu的1,5,15
*/
extern kdk_loadavg kdk_system_get_loadavg();
#ifdef __cplusplus
}
#endif
#endif // KYSDK_SYSTEM_SYSINFO_H__
/**
* \example kysdk-system/src/systeminfo/test/kysysinfo_test.c
*
*/
/**
* @}
*/

View File

@ -57,6 +57,7 @@ int main()
res = kdk_system_get_eUser_login_time();
printf("登录时间:%s\n", res);
free(res);
res = kdk_system_get_projectName();
printf("项目编号名:%s\n", res);
@ -158,5 +159,11 @@ int main()
printf("应用场景:%s\n", res);
free(res);
printf("系统中文件描述符数:%d\n", kdk_system_get_file_descriptor());
printf("系统中进程数:%d\n", kdk_system_get_process_nums());
printf("系统中线程数:%d\n", kdk_system_get_thread_nums());
kdk_loadavg loadAvg = kdk_system_get_loadavg();
printf("CPU 负载均衡 1m %0.2f, 5m %0.2f, 15m %0.2f\n", loadAvg.loadavg_1m, loadAvg.loadavg_5m, loadAvg.loadavg_15m);
return 0;
}

View File

@ -13,7 +13,6 @@ find_library(DBUS_LIB dbus-1)
find_library(DBUS_GLIB_LIB dbus-glib-1)
find_library(THREAD_LIB pthread)
link_directories(/usr/lib/kysdk/kysdk-base/)
link_directories(/usr/lib/${CMAKE_SYSTEM_PROCESSOR}-linux-gnu/)
include_directories(${PKGS_INCLUDE_DIRS} /usr/lib/aarch64-linux-gnu/glib-2.0/include /usr/include/glib-2.0)
# SET( EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
ADD_EXECUTABLE(systime m_systime.c)

View File

@ -14,6 +14,10 @@
<policy context="default">
<allow send_destination="com.kylin.kysdk.TimeServer" />
<!-- remove the following line for debug -->
<!--
<allow send_interface="com.jd.ccis"/>
-->
</policy>
</busconfig>

View File

@ -428,6 +428,58 @@ static void *print_shortDate(DBusConnection *ptr)
strcpy(str_tmp, tmp);
if (g_DateChanged == 1)
{
msg = dbus_message_new_signal("/com/kylin/kysdk/Date",
"com.kylin.kysdk.DateInterface",
"ShortDateSignal");
if (NULL == msg)
{
fprintf(stderr, "Message Null\n");
}
// append arguments onto signal
dbus_message_iter_init_append(msg, &args);
dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &tmpvalue);
dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &str_tmp);
dbus_connection_send(conn, msg, &serial);
dbus_connection_flush(conn);
dbus_message_unref(msg);
g_key_file_free(config);
}
out:
if(tmpvalue)
free(tmpvalue);
if(str_tmp)
free(str_tmp);
return ;
}
static void *print_Time(DBusConnection *ptr)
{
setlocale (LC_ALL, "");
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
textdomain (GETTEXT_PACKAGE);
DBusConnection *conn = ptr;
DBusMessage *msg;
DBusMessageIter args;
dbus_uint32_t serial = 0;
struct tm *now;
time_t current;
time(&current);
now = localtime(&current);
char value[64] = "\0";
char tvalue[64] = "\0";
char tmp[64] = "\0";
char *str_tmp = (char *)malloc(sizeof(char) * 64);
if(!str_tmp)
{
goto out;
}
GKeyFile *config = g_key_file_new();
char *lang = getenv("LANG");
g_key_file_load_from_file(config, path, 0, NULL);
char *gvalue = g_key_file_get_string(config, "DATEFORMAT", "TIME_FORMAT", NULL);
if(gvalue == NULL)
{
@ -453,19 +505,26 @@ static void *print_shortDate(DBusConnection *ptr)
strcpy(tvalue, gettext("12-hour clock"));
}
}
if(tvalue[0] != '\0')
{
strcpy(str_tmp, tvalue);
}
else{
free(str_tmp);
return;
}
if (g_DateChanged == 1)
{
msg = dbus_message_new_signal("/com/kylin/kysdk/Date",
"com.kylin.kysdk.DateInterface",
"ShortDateSignal");
"TimeSignal");
if (NULL == msg)
{
fprintf(stderr, "Message Null\n");
}
// append arguments onto signal
dbus_message_iter_init_append(msg, &args);
dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &tmpvalue);
dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &str_tmp);
dbus_connection_send(conn, msg, &serial);
dbus_connection_flush(conn);
@ -473,8 +532,6 @@ static void *print_shortDate(DBusConnection *ptr)
g_key_file_free(config);
}
out:
if(tmpvalue)
free(tmpvalue);
if(str_tmp)
free(str_tmp);
return ;
@ -577,6 +634,7 @@ void *actionDateChanged(void *ptr)
printDate(conn);
print_longDate(conn);
print_shortDate(conn);
print_Time(conn);
}
}
inotify_rm_watch(fd, fdate);
@ -654,6 +712,9 @@ const char *server_introspection_xml =
" <signal name='ShortDateSignal'>\n"
" <arg name='date' type='s' />\n"
" </signal>"
" <signal name='TimeSignal'>\n"
" <arg name='date' type='s' />\n"
" </signal>"
" </interface>\n"
"</node>\n";

View File

@ -156,7 +156,7 @@ char** kdk_system_get_dateformat()
time(&timep);
struct tm *p;
p = localtime(&timep);
char tmp[32] = {0};
char tmp[64] = {0};
size_t index = 0;
char **res = (char **)malloc(sizeof(tmp) * 256);
@ -182,7 +182,7 @@ char** kdk_system_get_dateformat()
if (strstr(tmpval, "**年**月**日"))
{
char tmpe[30] = {0};
char tmpe[64] = {0};
index++;
res[index] = malloc(sizeof(char) * (sizeof(tmpe) + 1));
if(!res[index])
@ -642,7 +642,7 @@ char* kdk_system_get_now_timeformat()
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
textdomain (GETTEXT_PACKAGE);
char *homeDir = NULL;
char *value = NULL;
char value[64] = "\0";
char *tvalue = malloc(sizeof(char) * 128);
char canonical_filename[PATH_MAX] = "\0";
char filename[PATH_MAX] = "\0";
@ -678,8 +678,8 @@ char* kdk_system_get_now_timeformat()
}
else{
g_key_file_load_from_file(config, canonical_filename, 0, NULL);
value = g_key_file_get_string(config, "DATEFORMAT", "TIME_FORMAT", NULL);
if(value == NULL || strstr(value, "24"))
char *gkey = g_key_file_get_string(config, "DATEFORMAT", "TIME_FORMAT", NULL);
if(gkey == NULL)
{
if(strstr(lang, "en_US"))
{
@ -688,6 +688,9 @@ char* kdk_system_get_now_timeformat()
strcpy(tvalue, gettext("24-hour clock"));
}
}
else{
strcpy(value, gkey);
}
if(strstr(value, "12"))
{
if(strstr(lang, "en_US"))
@ -697,6 +700,15 @@ char* kdk_system_get_now_timeformat()
strcpy(tvalue, gettext("12-hour clock"));
}
}
else if(strstr(value, "24"))
{
if(strstr(lang, "en_US"))
{
strcpy(tvalue, "24-hour clock");
}else{
strcpy(tvalue, gettext("24-hour clock"));
}
}
fclose(fp);
g_key_file_free(config);
}
@ -1489,7 +1501,7 @@ kdk_logn_dateinfo *kdk_system_logn_dateinfo(char *user)
GKeyFile *config = g_key_file_new();
kdk_logn_dateinfo *res = (kdk_dateinfo *)calloc(1, sizeof(kdk_dateinfo));
res->time = malloc(sizeof(char) * 48);
res->time = malloc(sizeof(char) * 64);
g_key_file_load_from_file(config, path, 0, NULL);
tvalue = g_key_file_get_string(config, "DATEFORMAT", "TIME_FORMAT", NULL);
@ -2050,14 +2062,14 @@ char* kdk_system_get_longformat_date()
setlocale (LC_ALL, "");
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
textdomain (GETTEXT_PACKAGE);
char tmp[32];
char tmp[64];
char *homeDir = NULL;
struct tm *p;
time_t current;
time(&current);
p = localtime(&current);
char tvalue[32] = "\0";
char *value = malloc(sizeof(char) * 32);
char tvalue[64] = "\0";
char *value = malloc(sizeof(char) * 64);
if(!value)
{
return NULL;
@ -2143,8 +2155,8 @@ char* kdk_system_get_shortformat_date()
time_t current;
time(&current);
p = localtime(&current);
char tvalue[32] = "\0";
char *value = malloc(sizeof(char) * 32);
char tvalue[64] = "\0";
char *value = malloc(sizeof(char) * 64);
if(!value)
{
return NULL;

View File

@ -54,6 +54,11 @@ typedef struct _kdk_logn_dateinfo{
char *week;
}kdk_logn_dateinfo;
typedef struct _kdk_timeinfo{
char *time; // 时间
char *timesec; //带秒钟数时间
}kdk_timeinfo;
/**
* @brief
*
@ -247,6 +252,21 @@ extern char* kdk_system_shortformat_transform(struct tm *ptr);
*/
extern kdk_logn_dateinfo *kdk_system_login_lock_dateinfo(char *user);
/**
* @brief
*
* @param struct tm *,
* @return char*,
*/
extern kdk_timeinfo *kdk_system_timeformat_transform(struct tm *ptr);
/**
* @brief kdk_system_timeformat_transform返回的时间信息结构体
*
* @param date kdk_system_timeformat_transform返回的结构体指针
*/
extern void kdk_free_timeinfo(kdk_timeinfo *time);
#ifdef __cplusplus
}
#endif

View File

@ -42,7 +42,7 @@ int main()
// int ret = kdk_system_set_dateformat("22-1-2");
// printf("ret = %d\n",ret);
// int date = kdk_system_set_12_timeformat();
int date = kdk_system_set_12_timeformat();
// // ret = kdk_system_set_24_timeformat();
// // // printf("ret = %d\n",ret);
@ -138,6 +138,12 @@ int main()
printf("date = %s,time = %s,week = %s\n",info->date,info->time,info->week);
kdk_free_logn_dateinfo(info);
ptr.tm_hour = 19;
ptr.tm_min = 3;
ptr.tm_sec = 2;
kdk_timeinfo *ti = kdk_system_timeformat_transform(&ptr);
printf("time = %s, timesec = %s\n", ti->time, ti->timesec);
kdk_free_timeinfo(ti);