同步操作将从 Sean/goActionServer 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
/************************************************************************************************************* 中国软件开源组织**** 嵌入式实时操作系统**** SylixOS(TM)**** Copyright All Rights Reserved****--------------文件信息--------------------------------------------------------------------------------**** 文 件 名: udialserver.c**** 创 建 人: Wu.PengCheng (吴鹏程)**** 文件创建日期: 2018 年 4 月 19 日**** 描 述: Web后台接口拨号处理线程*********************************************************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <pthread.h>#include <spawn.h>#include "lwip/netif.h"#include "netdev.h"#include "uORB.h"#include "poll.h"#include "iniparser/iniparser.h"#include "iniparser/dictionary.h"#include "net/lwip/event/lwip_netevent.h"/*********************************************************************************************************与goahead通信宏*********************************************************************************************************/#define UDIAL_FIFO_NAME "/dev/fifo" /* 有名管道名称 */#define UDIAL_PID_FIFO "/dev/pidfifo" /* 有名管道名称 *//*********************************************************************************************************拨号ini配置文件相关宏*********************************************************************************************************/#define UDIAL_INI_FILE "/etc/ppp/ppp.ini" /* 拨号ini配置文件名称 */#define UDIAL_FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) /* 拨号ini配置文件操作权限 */#define UDIAL_INI_SECTION "pppoe_" /* 拨号ini配置文件section前缀 *//*********************************************************************************************************ini配置文件内section对应的key(拷贝udial.c源码)*********************************************************************************************************/#define UKEY_IFNAME "netif"#define UKEY_MODEM "modem"#define UKEY_BAUD "baud"#define UKEY_INIT1 "init1"#define UKEY_INIT2 "init2"#define UKEY_INIT3 "init3"#define UKEY_INIT4 "init4"#define UKEY_INIT5 "init5"#define UKEY_AREA_CODE "area code"#define UKEY_PHONE "phone"#define UKEY_USRNAME "username"#define UKEY_PASSWORD "password"#define UKEY_DIAL_CMD "dial command"#define UKEY_RESP_WAIT "resp wait"#define UKEY_DEFAULT_IF "default interface"#define UKEY_AUTO_RECONN "auto reconnect"/*********************************************************************************************************拨号处理方式宏*********************************************************************************************************/#define UDIAL_CHECK 0 /* 关闭拨号 */#define UDIAL_START 1 /* 开始拨号 */#define UDIAL_END 0 /* 关闭拨号 *//*********************************************************************************************************后台拨号信息管理结构*********************************************************************************************************/struct udialServerInfo {char pcNetifName[NETIF_NAMESIZE]; /* 网卡名称 */void *pUdialCfgInfo; /* 拨号功能的配置信息 */void *pPPPNetIfIp; /* PPP网卡IP地址 */void *pPPPNetIfNetMk; /* PPP网卡掩码地址 */void *pPPPNetIfGw; /* PPP网卡网关地址 */pid_t pid;char cConnectFlag; /* 当前拨号状态 */struct udialServerInfo *pUdialInfoNext;};typedef struct udialServerInfo __UDIAL_SERVER_INFO;typedef struct udialServerInfo *__PUDIAL_SERVER_INFO;/*********************************************************************************************************前台拨号信息管理结构*********************************************************************************************************/struct udialWebInfo {INT iNetifIndex; /* 网卡序号 */char cNetifName[NETIF_NAMESIZE]; /* 网卡名称 */char *pcUserName; /* 拨号账户 */char *pcPassWord; /* 拨号密码 */char cDefaultFace; /* 是否设置为默认网口 */char cAutoConnect; /* 是否设置为自动重连 */char cHandleFlag; /* 当前处理方法 */};typedef struct udialWebInfo __UDIAL_WEB_INFO;typedef struct udialWebInfo *__PUDIAL_WEB_INFO;/*********************************************************************************************************后台拨号信息管理结构链表头*********************************************************************************************************/static INT _G_iFifoFd;static INT _G_iPidFifoFd;__PUDIAL_SERVER_INFO pUdialServerListHead = LW_NULL;/*********************************************************************************************************申明调用的真正拨号线程*********************************************************************************************************/extern PVOID udialPPPoEEntry (PVOID parg);extern VOID udialPPPoEQuit (PVOID pPPPoECfgInfo);#define UDIAL_RESP_SIZE 1024typedef struct {int evt_num;char if_name[IF_NAMESIZE];} ppp_evt_t;/*********************************************************************************************************** 函数名称: __udialServerExitHandle** 功能描述: 线程退出操作** 输 入 : NONE** NONE** 输 出 : NONE** 返 回 : none*********************************************************************************************************/static void __udialServerExitHandle (int i){close(_G_iFifoFd);unlink(UDIAL_FIFO_NAME);}/** return:* 0: it's a ppp event* -1: it isn't a ppp event, caller should ignore*/static int udial_parse_ppp_evt (ppp_evt_t *out, char *evt_buf){unsigned int evt;unsigned char *buf = (unsigned char *)evt_buf;/** evt is make in big-endian*/evt = (((unsigned int)buf[0]) << 24)| (((unsigned int)buf[1]) << 16)| (((unsigned int)buf[2]) << 8)| (((unsigned int)buf[3]) << 0);if (evt >= NET_EVENT_PPP_DEAD && evt <= NET_EVENT_PPP_DISCONN) {out->evt_num = evt;out->if_name[0] = buf[4];out->if_name[1] = buf[5];out->if_name[2] = buf[6];out->if_name[3] = 0;return 0;}return -1;}/*********************************************************************************************************** 函数名称: __udialPPPoEMonitorThread** 功能描述: 拨号状态更新线程** 输 入 : NONE** NONE** 输 出 : NONE** 返 回 : none*********************************************************************************************************/static int __udialPPPoEMonitorThread (void *arg){int fd;char evt_buf[UDIAL_RESP_SIZE];ssize_t read_len;ppp_evt_t evt;int ret;__PUDIAL_SERVER_INFO pUdialServerInfo = LW_NULL; /* 状态变化结点 */fd = open("/dev/netevent", O_RDONLY);if (fd < 0) {printf("open /dev/netevent failed, can't monitor the ppp link status!\r\n");return -1;}while (1) {read_len = read(fd, evt_buf, UDIAL_RESP_SIZE);if (read_len > 0) {ret = udial_parse_ppp_evt(&evt, evt_buf); /* 判断当前是不是与ppp相关事件 */if (NET_EVENT_PPP_RUN == evt.evt_num) {/** 遍历链表找到对应结点*//** todo:枷锁*/for (pUdialServerInfo = pUdialServerListHead;LW_NULL != pUdialServerInfo; ) {/** 找到对应网口*/if (0 == strcmp(pUdialServerInfo->pcNetifName, evt.if_name)) {pUdialServerInfo->pUdialCfgInfo = 1;break;} else {pUdialServerInfo = pUdialServerInfo->pUdialInfoNext;}}}printf("evt.evt_num = %d\r\n", evt.evt_num);if (ret == 0) { /* 是与ppp相关事件 */switch (evt.evt_num) {case NET_EVENT_PPP_DEAD:printf("ppp link is dead");break;case NET_EVENT_PPP_INIT:printf("ppp is doing initializing");break;case NET_EVENT_PPP_AUTH:printf("ppp is doing authing");break;case NET_EVENT_PPP_RUN:printf("ppp linked and is running");break;case NET_EVENT_PPP_DISCONN:printf("ppp link is disconnect");break;default:printf("unknow ppp event");break;}} else {continue;}}if (read_len < 0) {printf("monidor netevent error, it seems the /dev/netevent device error!\r\n");close(fd);return -1;}}return 0;}/*********************************************************************************************************** 函数名称: __udialIniFileHandle** 功能描述: 对pppoe的ini配置文件进行处理** 输 入 : argc 参数个数** argv 参数** 输 出 : NONE** 返 回 : none*********************************************************************************************************/static INT __udialIniFileHandle (__UDIAL_WEB_INFO udialWebInfo){CHAR cNewSecton[50];CHAR *pcIniNetifName;CHAR cIniNetifBuf[50];CHAR cPassBuf[50];CHAR cUserBuf[50];CHAR cAutoBuf[50];CHAR cDefaultBuf[50];INT iSectionNum = 0;INT iSectionCnt = 0;INT iFd;FILE * fppp;dictionary *dict;INT i;CHAR cFlag = 0;printf("__udialIniFileHandle.\n");if(-1 == (access(UDIAL_INI_FILE, F_OK))) { /* 不存在这个文件 */iFd = open(UDIAL_INI_FILE, O_RDWR | O_CREAT | O_TRUNC, UDIAL_FILE_MODE);if (iFd < 0) {printf("Create file failed.\n");return (PX_ERROR);}close(iFd);}dict = iniparser_load(UDIAL_INI_FILE); /* 加载配置文件 */if (LW_NULL == dict) {printf("iniparser_load file error\n");return (PX_ERROR);}iSectionNum = iniparser_getnsec(dict); /* 获取section个数 */if (0 != iSectionNum) { /* 判断当前的拨号信息是否存在 */for (i = 0; i < iSectionNum; i++) {sprintf(cIniNetifBuf, "%s:%s", iniparser_getsecname(dict, i), UKEY_IFNAME);pcIniNetifName = iniparser_getstring(dict, cIniNetifBuf, "NULL");if (0 == strcmp(pcIniNetifName, udialWebInfo.cNetifName)) { /* 已经存在拨号信息 */iSectionCnt = i;cFlag = 1; /* 有对应信息 */break;}}}if (UDIAL_START == udialWebInfo.cHandleFlag) { /* 需要进行拨号操作 */if (0 == cFlag) { /* 之前没有对应的拨号信息 */iniparser_freedict(dict); /* 把之前的dictionary先删除 */fppp = fopen(UDIAL_INI_FILE, "r+"); /* r+ 格式打开配置文件 */if (fppp < 0) {printf("Create file failed.\n");return (PX_ERROR);}fseek(fppp, 0L, SEEK_END); /* 移动到文件末尾 *//** 添加一个新的section*/sprintf(cNewSecton, "%s%s", UDIAL_INI_SECTION, udialWebInfo.cNetifName);fprintf(fppp, "\n[%s]\n", cNewSecton);fclose (fppp);dict = iniparser_load(UDIAL_INI_FILE); /* 重新获取dictionary */if (LW_NULL == dict) {printf("iniparser_load file error\n");return (PX_ERROR);}iSectionCnt = iSectionNum; /* 设置最新的section的位置 */}/** 至此,找到对应的section了,现在不管现在的账号与密码是否与ini文件中的一致,都直接更新一下*/sprintf(cIniNetifBuf, "%s:%s", iniparser_getsecname(dict, iSectionCnt), UKEY_IFNAME);sprintf(cUserBuf, "%s:%s", iniparser_getsecname(dict, iSectionCnt), UKEY_USRNAME);sprintf(cPassBuf, "%s:%s", iniparser_getsecname(dict, iSectionCnt), UKEY_PASSWORD);sprintf(cAutoBuf, "%s:%s", iniparser_getsecname(dict, iSectionCnt), UKEY_AUTO_RECONN);sprintf(cDefaultBuf, "%s:%s", iniparser_getsecname(dict, iSectionCnt), UKEY_DEFAULT_IF);/** 这里用dictionary_set接口,保证大小写不变;* iniparser_set接口会把字符串变成小写*/dictionary_set(dict, cIniNetifBuf, udialWebInfo.cNetifName);dictionary_set(dict, cUserBuf, udialWebInfo.pcUserName);dictionary_set(dict, cPassBuf, udialWebInfo.pcPassWord);dictionary_set(dict, cAutoBuf, udialWebInfo.cAutoConnect ? "yes" : "no");dictionary_set(dict, cDefaultBuf, udialWebInfo.cDefaultFace ? "yes" : "no");fppp = fopen(UDIAL_INI_FILE, "w+"); /* 清空文件打开 */if (fppp < 0) {printf("Create file failed, ini has cleared.\n");iniparser_freedict(dict); /* 释放dictionar */return (PX_ERROR);}iniparser_dump_ini(dict, fppp); /* 把dictionar写入ini文件 */iniparser_freedict(dict); /* 释放dictionary */fclose (fppp);return (ERROR_NONE);} else {if (0 == cFlag) { /* 之前没有对应的拨号信息 */iniparser_freedict(dict); /* 释放dictionary */printf("Ini file has no msg.\n");return (PX_ERROR);} else {fppp = fopen(UDIAL_INI_FILE, "w+"); /* 清空文件打开 */if (fppp < 0) {printf("Create file failed.\n");iniparser_freedict(dict); /* 释放dictionar */return (PX_ERROR);}for (i = 0; i < iSectionNum; i++) {if (i != iSectionCnt) { /* 把需要删除的section剔除 */iniparser_dumpsection_ini(dict, iniparser_getsecname(dict, i), fppp);}}iniparser_freedict(dict); /* 释放dictionar */fclose (fppp);return (ERROR_NONE);}}}/*********************************************************************************************************** 函数名称: main** 功能描述: 拨号处理线程入口** 输 入 : argc 参数个数** argv 参数** 输 出 : NONE** 返 回 : none*********************************************************************************************************/INT main (int argc, char **argv){INT ret;pthread_t tid;pthread_attr_t attr;struct sched_param schedparam;posix_spawnattr_t spawnattr;pid_t pid;__UDIAL_WEB_INFO udialWebInfo; /* 保存前台传过来的信息 */__PUDIAL_SERVER_INFO pUdialServerInfo = LW_NULL; /* 当前新建的拨号信息 */__PUDIAL_SERVER_INFO pUdialListTmp = LW_NULL; /* 上一次的拨号信息 */__PUDIAL_SERVER_INFO pUdialServerDelInfo = LW_NULL; /* 当前新建的拨号信息 */__PUDIAL_SERVER_INFO pUdialListDelTmp = LW_NULL; /* 上一次的拨号信息 */__PUDIAL_SERVER_INFO pUdialServerCheckInfo = LW_NULL; /* 监测拨号信息 */CHAR cSectionBuf[50] = {0};CHAR cPidBuf[10] = {0};CHAR *cCmdArg[7];cCmdArg[0] = "udial";cCmdArg[1] = "-p";cCmdArg[2] = "-e";cCmdArg[3] = "-d";cCmdArg[4] = "-c";cCmdArg[5] = cSectionBuf;cCmdArg[6] = NULL;ret = pthread_attr_init(&attr);if (ret != 0) {printf("pthread attr init failed.\n");return (PX_ERROR);}ret = pthread_create(&tid, &attr, __udialPPPoEMonitorThread, NULL);if (ret != 0) {printf("pthread create failed.\n");return (PX_ERROR);}ret = mkfifo(UDIAL_FIFO_NAME, O_RDWR | O_CREAT | O_TRUNC); /* 创建有名管道 */if (ret < 0) {perror("mkfifo");return (PX_ERROR);}_G_iFifoFd = open(UDIAL_FIFO_NAME, O_RDWR); /* 打开有名管道 */if (_G_iFifoFd < 0) {printf( "open fifo error.\n");return (PX_ERROR);}signal(SIGQUIT, __udialServerExitHandle);signal(SIGABRT, __udialServerExitHandle);signal(SIGSEGV, __udialServerExitHandle);atexit((void (*)(void))__udialServerExitHandle);while (1) {ret = read(_G_iFifoFd, &udialWebInfo, sizeof(udialWebInfo));if (ret < 0) {printf( "read failed.\n");break;}if (PX_ERROR == __udialIniFileHandle(udialWebInfo)) { /* 对拨号配置文件进行操作失败 */continue;}/** 只要是对已有的拨号会先将其删掉*/for (pUdialServerDelInfo = pUdialListDelTmp = pUdialServerListHead;LW_NULL != pUdialServerDelInfo; ) {/** 找到需要删除的网口*/if (0 == strcmp(pUdialServerDelInfo->pcNetifName, udialWebInfo.cNetifName)) {/** 删除之前操作的对应拨号进程*/bzero(cPidBuf, sizeof(cPidBuf));sprintf(cPidBuf, "kill -n 3 %d", pUdialServerDelInfo->pid);system(cPidBuf);if (pUdialServerDelInfo == pUdialServerListHead) { /* 头结点被删除 */pUdialServerListHead = pUdialServerDelInfo->pUdialInfoNext;} else {pUdialListDelTmp->pUdialInfoNext = pUdialServerDelInfo->pUdialInfoNext;}free(pUdialServerDelInfo);break;} else {pUdialListDelTmp = pUdialServerDelInfo;pUdialServerDelInfo = pUdialServerDelInfo->pUdialInfoNext;}}if (UDIAL_START == udialWebInfo.cHandleFlag) { /* 需要进行拨号 */pUdialServerInfo = (__PUDIAL_SERVER_INFO)malloc(sizeof(__UDIAL_SERVER_INFO));if (LW_NULL == pUdialServerInfo) {printf("udial info malloc error\n");return (PX_ERROR);}bzero(pUdialServerInfo, sizeof(__UDIAL_SERVER_INFO));if (LW_NULL == pUdialServerListHead) {pUdialServerListHead = pUdialServerInfo;} else {for (pUdialListTmp = pUdialServerListHead;LW_NULL != pUdialListTmp->pUdialInfoNext;pUdialListTmp = pUdialListTmp->pUdialInfoNext) {} /* 找到最后一个结点 */pUdialListTmp->pUdialInfoNext = pUdialServerInfo; /* 尾插 */}/** 保存当前的拨号信息*/memcpy(pUdialServerInfo->pcNetifName,udialWebInfo.cNetifName,sizeof(udialWebInfo.cNetifName));pUdialServerInfo->cConnectFlag = 0;/** 初始化进程属性对象*/if (posix_spawnattr_init(&spawnattr) != 0) {printf( "init posix_spawnattr_t failed\n");return (PX_ERROR);}/** 新建进程优先级为 NORMAL*/schedparam.sched_priority = PX_PRIORITY_CONVERT(LW_PRIO_NORMAL);posix_spawnattr_setschedparam(&spawnattr, &schedparam);posix_spawnattr_setflags(&spawnattr, POSIX_SPAWN_SETSCHEDPARAM);bzero(cSectionBuf, sizeof(cSectionBuf));sprintf(cSectionBuf, "pppoe_%s", udialWebInfo.cNetifName);if (posix_spawnp(&pid, "udial", NULL,&spawnattr, cCmdArg, NULL) != 0) { /* 启动进程 */free(pUdialServerInfo);/** todo:向管道写error*/} else {/** todo:向管道写ok*/pUdialServerInfo->pid = pid;}posix_spawnattr_destroy(&spawnattr);} else if (UDIAL_END == udialWebInfo.cHandleFlag) { /* 需要删除拨号 *//** 因为整个if语句操作前已经删除对应网口,因此无需重复删除*//** todo:向管道写ok*/} else if (UDIAL_CHECK == udialWebInfo.cHandleFlag) { /* 需要检查拨号状态 */pppGetPhase();for (pUdialServerCheckInfo = pUdialServerListHead;LW_NULL != pUdialServerCheckInfo; ) {/** 找到需要的网口*/if (0 == strcmp(pUdialServerCheckInfo->pcNetifName, udialWebInfo.cNetifName)) {//write(_G_iFifoFd, &(pUdialServerCheckInfo->cConnectFlag), sizeof(char));break;}pUdialServerCheckInfo = pUdialServerCheckInfo->pUdialInfoNext;}}}return (0);}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。