Esempio n. 1
0
/*********************************************************************************************************
** 函数名称: aio_suspend
** 功能描述: 等待指定的一个或多个异步 I/O 请求操作完成
** 输 入  : list              aio 请求控制块数组 (如果其中有 NULL, 程序将忽略)
**           nent              数组元素个数
**           timeout           超时时间
** 输 出  : ERROR or OK
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API 
int  aio_suspend (const struct aiocb * const list[], int nent, const struct timespec *timeout)
{
    AIO_WAIT_CHAIN     *paiowc;
    struct aiowait     *paiowait;
    ULONG               ulTimeout;
    
    BOOL                bNeedWait = LW_FALSE;
    
    int                 iWait = 0;                                      /*  paiowait 下标               */
    int                 iCnt;                                           /*  list 下标                   */
    int                 iRet = ERROR_NONE;
    
#ifdef __SYLIXOS_KERNEL
    if (__PROC_GET_PID_CUR() != 0) {                                    /*  需要使用外部库提供的 aio    */
        errno = ENOSYS;
        return  (PX_ERROR);
    }
#endif                                                                  /*  __SYLIXOS_KERNEL            */

    __THREAD_CANCEL_POINT();                                            /*  测试取消点                  */

    if ((nent <= 0) || (list == LW_NULL)) {
        errno = EINVAL;
        return  (PX_ERROR);
    }
    
    if (timeout == LW_NULL) {                                           /*  永久等待                    */
        ulTimeout = LW_OPTION_WAIT_INFINITE;
    } else {
        ulTimeout = __timespecToTick(timeout);
    }
    
    paiowc = __aioCreateWaitChain(nent, LW_TRUE);                       /*  创建等待队列                */
    if (paiowc == LW_NULL) {
        errno = ENOMEM;                                                 /*  should be EAGAIN ?          */
        return  (PX_ERROR);
    }
    
    paiowait = paiowc->aiowc_paiowait;
    
    API_SemaphoreMPend(_G_aioqueue.aioq_mutex, LW_OPTION_WAIT_INFINITE);
    
    for (iCnt = 0; iCnt < nent; iCnt++) {
        if (list[iCnt]) {
            if (list[iCnt]->aio_req.aioreq_error == EINPROGRESS) {      /*  必须为正在处理状态          */
                
                paiowait[iWait].aiowt_pcond     = &paiowc->aiowc_cond;
                paiowait[iWait].aiowt_pcnt      = LW_NULL;
                paiowait[iWait].aiowt_psigevent = LW_NULL;
                paiowait[iWait].aiowt_paiowc    = LW_NULL;              /*  不需要代理线程释放          */
                
                iRet = __aioAttachWait(list[iCnt], &paiowait[iWait]);
                if (iRet != ERROR_NONE) {
                    errno = EINVAL;
                    break;
                }
                
                _List_Line_Add_Tail(&paiowait[iWait].aiowt_line, 
                                    &paiowc->aiowc_pline);              /*  加入 wait 链表              */
                iWait++;
                
                bNeedWait = LW_TRUE;                                    /*  有 wait 链表节点连接,       */
            } else {
                break;
            }
        }
    }
    
    if (iRet != ERROR_NONE) {                                           /*  __aioAttachWait 失败        */
        __aioDeleteWaitChain(paiowc);
        API_SemaphoreMPost(_G_aioqueue.aioq_mutex);
        errno = EINVAL;
        return  (PX_ERROR);
    }
    
    if ((iCnt == nent) && bNeedWait) {                                  /*  是否需要等待                */
        API_ThreadCleanupPush(__aioWaitCleanup, paiowc);
        
        iRet = (INT)API_ThreadCondWait(&paiowc->aiowc_cond, _G_aioqueue.aioq_mutex, ulTimeout);
        
        API_ThreadCleanupPop(LW_FALSE);                                 /*  这里已经锁定 _G_aioqueue    */
                                                                        /*  不能运行 __aioWaitCleanup   */
        __aioDeleteWaitChain(paiowc);
        
        if (iRet != ERROR_NONE) {
            API_SemaphoreMPost(_G_aioqueue.aioq_mutex);
            errno = EAGAIN;
            return  (PX_ERROR);
        }
    
    } else {                                                            /*  不需要等待                  */
        __aioDeleteWaitChain(paiowc);
    }
    
    API_SemaphoreMPost(_G_aioqueue.aioq_mutex);
    
    return  (iRet);
}
/*********************************************************************************************************
** 函数名称: __tshellFsCmdXmodems
** 功能描述: 系统命令 "xmodems"
** 输 入  : iArgC         参数个数
**           ppcArgV       参数表
** 输 出  : 0
** 全局变量:
** 调用模块:
*********************************************************************************************************/
static INT  __tshellFsCmdXmodems (INT  iArgC, PCHAR  ppcArgV[])
{
    INT             i;
    INT             j;

    BOOL            bIsEot = LW_FALSE;
    BOOL            bStart = LW_FALSE;

    INT             iFile;
    INT             iRetVal;
    UCHAR           ucRead;
    UCHAR           ucTemp[__LW_XMODEM_PACKET_LEN] = {__LW_XMODEM_SOH};
    UCHAR           ucSeq = 1;
    UCHAR           ucChkSum;

    ssize_t         sstRecvNum;
    ssize_t         sstReadNum;

    fd_set          fdsetRead;
    struct timeval  timevalTO = {__LW_XMODEM_TIMEOUT, 0};


    if (iArgC != 2) {
        fprintf(stderr, "argments error!\n");
        return  (-ERROR_TSHELL_EPARAM);
    }

    iFile = open(ppcArgV[1], O_RDONLY);
    if (iFile < 0) {
        fprintf(stderr, "can not open source file!\n");
        return  (-ERROR_TSHELL_EPARAM);
    }

    API_ThreadCleanupPush(__tshellXmodemCleanup, (PVOID)iFile);         /*  加入清除函数                */

    ioctl(STD_IN, FIOSETOPTIONS, OPT_RAW);                              /*  将标准文件改为 raw 模式     */
    ioctl(STD_OUT, FIOSETOPTIONS, OPT_RAW);                             /*  将标准文件改为 raw 模式     */

    /*
     *  构建第一个数据包
     */
    sstReadNum = read(iFile, &ucTemp[3], __LW_XMODEM_DATA_LEN);
    if (sstReadNum <= 0) {
        __LW_XMODEM_SEND_CMD(__LW_XMODEM_EOT);                          /*  传输结束                    */
        API_ThreadCleanupPop(LW_TRUE);
        printf("0 bytes read from source file!\n");
        return  (-ERROR_TSHELL_EPARAM);
    }
    for (j = (INT)sstReadNum; j < __LW_XMODEM_DATA_LEN; j++) {          /*  补全数据                    */
        ucTemp[j + 3] = __LW_XMODEM_PAD;
    }

    ucTemp[1] = (UCHAR)(ucSeq);                                         /*  序列号                      */
    ucTemp[2] = (UCHAR)(~ucSeq);

    ucChkSum = 0;
    for (j = 3; j < (__LW_XMODEM_DATA_LEN + 3); j++) {
        ucChkSum = (UCHAR)(ucChkSum + ucTemp[j]);                       /*  计算校验和                  */
    }
    ucTemp[__LW_XMODEM_DATA_LEN + 3] = ucChkSum;

    /*
     *  开始循环发送文件
     */
    FD_ZERO(&fdsetRead);
    /*
     *  超时次数默认为 30 次
     */
    for (i = 0; i < 30; i++) {
        FD_SET(STD_IN, &fdsetRead);
        iRetVal = select(1, &fdsetRead, LW_NULL, LW_NULL, &timevalTO);  /*  等待可读                    */
        if (iRetVal != 1) {
            if (bIsEot) {
                if (bStart) {
                    write(STD_OUT, ucTemp, __LW_XMODEM_PACKET_LEN);     /*  重发数据                    */
                }
            } else {
                __LW_XMODEM_SEND_CMD(__LW_XMODEM_EOT);                  /*  重新结束                    */
            }
            continue;                                                   /*  接收超时                    */
        }
        i = 0;                                                          /*  重置超时次数                */

        sstRecvNum = read(STD_IN, &ucRead, 1);
        if (sstRecvNum <= 0) {
            API_ThreadCleanupPop(LW_TRUE);
            fprintf(stderr, "standard in device error!\n");
            return  (PX_ERROR);
        }

        if (ucRead == __LW_XMODEM_CAN) {                                /*  接收结束                    */
            break;

        } else if (ucRead == __LW_XMODEM_NAK) {                         /*  需要重发                    */
            write(STD_OUT, ucTemp, __LW_XMODEM_PACKET_LEN);
            bStart = LW_TRUE;

        } else if (ucRead == __LW_XMODEM_ACK) {
            ucSeq++;
            if (ucSeq > 255) {
                ucSeq = 1;
            }
            bStart = LW_TRUE;

            if (bIsEot) {
                break;                                                  /*  发送结束                    */

            } else {
                sstReadNum = read(iFile, &ucTemp[3], __LW_XMODEM_DATA_LEN);
                if (sstReadNum <= 0) {
                    bIsEot = LW_TRUE;
                    __LW_XMODEM_SEND_CMD(__LW_XMODEM_EOT);              /*  发送结束                    */
                } else {
                    /*
                     *  补全数据
                     */
                    for (j = (INT)sstReadNum; j < __LW_XMODEM_DATA_LEN; j++) {
                        ucTemp[j + 3] = __LW_XMODEM_PAD;
                    }

                    ucTemp[1] = (UCHAR)(ucSeq);                         /*  序列号                      */
                    ucTemp[2] = (UCHAR)(~ucSeq);

                    ucChkSum = 0;
                    for (j = 3; j < (__LW_XMODEM_DATA_LEN + 3); j++) {
                        ucChkSum = (UCHAR)(ucChkSum + ucTemp[j]);       /*  计算校验和                  */
                    }
                    ucTemp[__LW_XMODEM_DATA_LEN + 3] = ucChkSum;

                    write(STD_OUT, ucTemp, __LW_XMODEM_PACKET_LEN);     /*  发送数据                    */
                }
            }
        }
    }

    API_ThreadCleanupPop(LW_TRUE);
    return  (ERROR_NONE);
}
Esempio n. 3
0
/*********************************************************************************************************
** 函数名称: API_INetPing6
** 功能描述: internet ipv6 ping
** 输 入  : pinaddr       目标 ip 地址.
**           iTimes        次数
**           iDataSize     数据大小
**           iTimeout      超时时间
**           pcNetif       网络接口名 (NULL 表示自动确定接口)
** 输 出  : ERROR
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API  
INT  API_INetPing6 (struct in6_addr  *pin6addr, 
                    INT               iTimes, 
                    INT               iDataSize, 
                    INT               iTimeout, 
                    CPCHAR            pcNetif)
{
             CHAR       cInetAddr[INET6_ADDRSTRLEN];                    /*  IP 地址缓存                 */

    REGISTER INT        iSock;
             INT        i;
             UINT16     usSeqRecv = 0;
             ULONG      ulTime1;
             ULONG      ulTime2;
             
             INT        iSuc = 0;
             INT        iHLRecv;

    struct  sockaddr_in6    sockaddrin6To;
    
    REGISTER ULONG      ulTimeMax = 0;
    REGISTER ULONG      ulTimeMin = 0xFFFFFFFF;
    REGISTER ULONG      ulTimeAvr = 0;
    
    
    if ((iDataSize >= (64 * LW_CFG_KB_SIZE)) || (iDataSize < 0)) {      /*  0 - 64KB                    */
        _ErrorHandle(EINVAL);
        return  (PX_ERROR);
    }
    
    sockaddrin6To.sin6_len    = sizeof(struct sockaddr_in6);
    sockaddrin6To.sin6_family = AF_INET6;
    sockaddrin6To.sin6_addr   = *pin6addr;
    
    iSock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);                 /*  必须原子运行到 push         */
    if (iSock < 0) {
        return  (PX_ERROR);
    }
    API_ThreadCleanupPush(__inetPing6Cleanup, (PVOID)iSock);            /*  加入清除函数                */
    
    setsockopt(iSock, SOL_SOCKET, SO_RCVTIMEO, &iTimeout, sizeof(INT));
    
    connect(iSock, (struct sockaddr *)&sockaddrin6To, 
            sizeof(struct sockaddr_in6));                               /*  设定目标                    */
    
    printf("Pinging %s\n\n", inet6_ntoa_r(*pin6addr, cInetAddr, sizeof(cInetAddr)));
    
    for (i = 0; ;) {
        if (__inetPing6Send(iSock, pin6addr, iDataSize, pcNetif, &usSeqRecv) < 0) {
                                                                        /*  发送 icmp 数据包            */
            fprintf(stderr, "error : %s.\n", lib_strerror(errno));
        
            i++;
            if (i >= iTimes) {
                break;
            }
            API_TimeSSleep(1);                                          /*  等待 1 S                    */
            continue;
        
        } else {
            i++;                                                        /*  发送次数 ++                 */
        }
        
        ulTime1 = API_TimeGet();
        if (__inetPing6Recv(iSock, usSeqRecv, &iHLRecv) < 0) {          /*  接收 icmp 数据包            */
            printf("Request time out.\n");                              /*  timeout                     */
            if (i >= iTimes) {
                break;                                                  /*  ping 结束                   */
            }
        
        } else {
            ulTime2 = API_TimeGet();
            ulTime2 = (ulTime2 >= ulTime1) ? (ulTime2 - ulTime1) 
                    : ((__ARCH_ULONG_MAX - ulTime1) + ulTime2 + 1);
            ulTime2 = ((ulTime2 * 1000) / LW_TICK_HZ);                  /*  转为毫秒数                  */
                    
            printf("Reply from %s: bytes=%d time=%ldms hoplim=%d\n", inet6_ntoa_r(*pin6addr, 
                                                                     cInetAddr, 
                                                                     sizeof(cInetAddr)),
                   iDataSize, ulTime2, iHLRecv);
        
            iSuc++;
            
            ulTimeAvr += ulTime2;
            ulTimeMax = (ulTimeMax > ulTime2) ? ulTimeMax : ulTime2;
            ulTimeMin = (ulTimeMin < ulTime2) ? ulTimeMin : ulTime2;
            
            if (i >= iTimes) {
                break;                                                  /*  ping 结束                   */
            } else {
                API_TimeSSleep(1);                                      /*  等待 1 S                    */
            }
        }
    }
    API_ThreadCleanupPop(LW_TRUE);                                      /*  ping 清除                   */
    
    /*
     *  打印总结信息
     */
    printf("\nPing statistics for %s:\n", inet6_ntoa_r(*pin6addr, cInetAddr, sizeof(cInetAddr)));
    printf("    Packets: Send = %d, Received = %d, Lost = %d(%d%% loss),\n", 
                  iTimes, iSuc, (iTimes - iSuc), (((iTimes - iSuc) * 100) / iTimes));
    
    if (iSuc == 0) {                                                    /*  没有一次成功                */
        return  (PX_ERROR);
    }
    
    ulTimeAvr = ulTimeAvr / iSuc;
    
    printf("Approximate round trip times in milli-seconds:\n");
    printf("    Minimum = %ldms, Maximum = %ldms, Average = %ldms\r\n\r\n",
                  ulTimeMin, ulTimeMax, ulTimeAvr);
    
    return  (ERROR_NONE);
}
/*********************************************************************************************************
** 函数名称: __tshellFsCmdXmodemr
** 功能描述: 系统命令 "xmodemr"
** 输 入  : iArgC         参数个数
**           ppcArgV       参数表
** 输 出  : 0
** 全局变量:
** 调用模块:
*********************************************************************************************************/
static INT  __tshellFsCmdXmodemr (INT  iArgC, PCHAR  ppcArgV[])
{
    INT             i;
    INT             j;

    INT             iFile;
    INT             iRetVal;
    UCHAR           ucTemp[__LW_XMODEM_PACKET_LEN];
    UCHAR           ucSeq = 1;
    UCHAR           ucChkSum;

    ssize_t         sstRecvNum;
    ssize_t         sstWriteNum;
    size_t          stTotalNum = 0;

    fd_set          fdsetRead;
    struct timeval  timevalTO = {__LW_XMODEM_TIMEOUT, 0};


    if (iArgC != 2) {
        fprintf(stderr, "argments error!\n");
        return  (-ERROR_TSHELL_EPARAM);
    }

    /*
     *  检测文件是否存在
     */
    iFile = open(ppcArgV[1], O_RDONLY);
    if (iFile >= 0) {
        close(iFile);                                                   /*  关闭文件                    */

__re_select:
        printf("destination file is exist, overwrite? (Y/N)\n");
        read(0, ucTemp, __LW_XMODEM_DATA_LEN);
        if ((ucTemp[0] == 'N') ||
                (ucTemp[0] == 'n')) {                                       /*  不覆盖                      */
            return  (ERROR_NONE);

        } else if ((ucTemp[0] != 'Y') &&
                   (ucTemp[0] != 'y')) {                                /*  选择错误                    */
            goto    __re_select;
        }
    }

    iFile = open(ppcArgV[1], (O_WRONLY | O_CREAT | O_TRUNC), 0666);     /*  创建文件                    */
    if (iFile < 0) {
        fprintf(stderr, "can not open destination file!\n");
        return  (-ERROR_TSHELL_EPARAM);
    }

    API_ThreadCleanupPush(__tshellXmodemCleanup, (PVOID)iFile);         /*  加入清除函数                */

    ioctl(STD_IN, FIOSETOPTIONS, OPT_RAW);                              /*  将标准文件改为 raw 模式     */
    ioctl(STD_OUT, FIOSETOPTIONS, OPT_RAW);                             /*  将标准文件改为 raw 模式     */

    __LW_XMODEM_SEND_CMD(__LW_XMODEM_NAK);                              /*  启动接收                    */

    FD_ZERO(&fdsetRead);
    /*
     *  超时次数默认为 20 次
     */
    for (i = 0; i < 20; i++) {
        FD_SET(STD_IN, &fdsetRead);
        iRetVal = select(1, &fdsetRead, LW_NULL, LW_NULL, &timevalTO);  /*  等待可读                    */
        if (iRetVal != 1) {
            stTotalNum = 0;                                             /*  清除已接收的数据            */
            __LW_XMODEM_SEND_CMD(__LW_XMODEM_NAK);                      /*  重新请求接收数据包          */
            continue;                                                   /*  接收超时                    */
        }
        i = 0;                                                          /*  重置超时次数                */

        sstRecvNum = read(STD_IN, &ucTemp[stTotalNum], __LW_XMODEM_PACKET_LEN - stTotalNum);
        if (sstRecvNum <= 0) {
            API_ThreadCleanupPop(LW_TRUE);
            fprintf(stderr, "standard in device error!\n");
            return  (PX_ERROR);
        }
        if (ucTemp[0] == __LW_XMODEM_EOT) {                             /*  接收结束                    */
            __LW_XMODEM_SEND_CMD(__LW_XMODEM_ACK);
            break;
        }
        stTotalNum += (size_t)sstRecvNum;
        if (stTotalNum < __LW_XMODEM_PACKET_LEN) {                      /*  数据包不完整                */
            continue;
        } else {
            stTotalNum = 0;                                             /*  已经接到一个完整的数据包    */
        }

        /*
         *  开始判断数据包正确性
         */
        if (ucTemp[1] != ucSeq) {                                       /*  序列号是否错误              */
            if (ucTemp[1] == (ucSeq - 1)) {
                __LW_XMODEM_SEND_CMD(__LW_XMODEM_ACK);                  /*  需要下一包数据              */
            } else {
                __LW_XMODEM_SEND_CMD(__LW_XMODEM_CAN);                  /*  结束通信                    */
                API_ThreadCleanupPop(LW_TRUE);
                fprintf(stderr, "sequence number error!\n");
                return  (PX_ERROR);
            }
            continue;
        }

        if (~ucTemp[1] == ucTemp[2]) {                                  /*  序列号校验错误              */
            __LW_XMODEM_SEND_CMD(__LW_XMODEM_NAK);
            continue;
        }

        ucChkSum = 0;
        for (j = 3; j < (__LW_XMODEM_DATA_LEN + 3); j++) {
            ucChkSum = (UCHAR)(ucChkSum + ucTemp[j]);                   /*  计算校验和                  */
        }

        if (ucTemp[__LW_XMODEM_DATA_LEN + 3] != ucChkSum) {             /*  校验错误                    */
            __LW_XMODEM_SEND_CMD(__LW_XMODEM_NAK);
            continue;
        }

        /*
         *  将数据写入目标文件
         */
        sstWriteNum = write(iFile, &ucTemp[3], __LW_XMODEM_DATA_LEN);
        if (sstWriteNum != __LW_XMODEM_DATA_LEN) {
            INT     iErrNo = errno;
            __LW_XMODEM_SEND_CMD(__LW_XMODEM_CAN);                      /*  结束通信                    */
            API_ThreadCleanupPop(LW_TRUE);
            fprintf(stderr, "write file error %s!\n", lib_strerror(iErrNo));
            return  (PX_ERROR);
        }

        ucSeq++;
        __LW_XMODEM_SEND_CMD(__LW_XMODEM_ACK);                          /*  需要下一包数据              */
    }

    API_ThreadCleanupPop(LW_TRUE);
    return  (ERROR_NONE);
}