⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 utils.c

📁 qt91上实现的mp3播放机,支持sam9260,参考用
💻 C
字号:
/*!
 * Copyright (C) 2006-2007 by egnite Software GmbH. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the copyright holders nor the names of
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE
 * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * For additional information see http://www.ethernut.de/
 */

/*!
 * \file utils.c
 * \brief Utility routines.
 *
 * \verbatim
 *
 * $Log$
 *
 * \endverbatim
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "utils.h"

/*!
 * \brief Get a specified number of characters from TCP socket connection.
 *
 * The low level NutTcpReceive() routine may return less than the number
 * of bytes specified. This routine makes sure, that the complete buffer
 * is filled. However, an additional pointer to a status is passed to
 * this routine. If the status changes, the routine will be aborted.
 *
 * Any TCP receive timeout is ignored, but required in order to detect
 * status changes.
 *
 * \param sock   Socket descriptor. This pointer must have been retrieved 
 *               by calling NutTcpCreateSocket(). In addition a connection 
 *               must have been established by calling NutTcpConnect() or 
 *               NutTcpAccept().
 * \param line   Pointer to the buffer.
 * \param size   Size of the buffer.
 * \param status Pointer to a status.
 *
 * \return 0 if the buffer is filled. Otherwise -1 is returned.
 */
int TcpGetBuffer(TCPSOCKET * sock, char * buff, u_int size, u_int *status)
{
    u_int initial = *status;
    int got;

    while (size) {
        if (*status != initial || (got = NutTcpReceive(sock, buff, size)) < 0) {
            /* Status change or receive error. */
            return -1;
        }
        size -= got;
        buff += got;
    }
    return 0;
}

/*!
 * \brief Get line from TCP socket connection.
 *
 * ASCII codes below 32 or above 127 are discarded.
 *
 * \param sock Socket descriptor. This pointer must have been retrieved 
 *             by calling NutTcpCreateSocket(). In addition a connection 
 *             must have been established by calling NutTcpConnect() or 
 *             NutTcpAccept().
 * \param line Pointer to the buffer that receives the string.
 * \param size Size of the buffer. If the received line doesn't fit,
 *             then remaining characters will be discarded.
 *
 * \return Number of characters stored in the line buffer or -1 in case
 *         of an error or timeout.
 */
int TcpGetLine(TCPSOCKET * sock, char * line, u_short size)
{
    int rc = 0;
    int got;
    char *cp = line;

    if (size > 0) {
        for (;;) {
            if ((got = NutTcpReceive(sock, cp, 1)) <= 0) {
                rc = -1;
                break;
            }
            if (*cp == '\n') {
                *cp = 0;
                puts(line);
                break;
            }
            if (*cp >= ' ' && rc < (int) size) {
                rc++;
                cp++;
            }
        }
    }
    return rc;
}

/*!
 * \brief Send complete string via TCP.
 *
 * The low level NutTcpSend() routine limits the number of bytes to
 * the maximum segment size of the connection. This routine makes
 * sure, that the complete string is transmitted.
 *
 * \param sock Socket descriptor. This pointer must have been retrieved 
 *             by calling NutTcpCreateSocket(). In addition a connection 
 *             must have been established by calling NutTcpConnect() or 
 *             NutTcpAccept().
 * \param str  Pointer to a buffer containing the string to send.
 *
 * \return 0 on success. Otherwise -1 is returned.
 */
int TcpPutString(TCPSOCKET * sock, char * str)
{
    int len = (int)strlen(str);
    int c;

    puts(str);
    while(len) {
        if ((c = NutTcpSend(sock, str, (u_short)len)) <= 0) {
            break;
        }
        len -= c;
        str += c;
    }
    return len ? -1 : 0;
}

/*!
 * \brief Get header line array from TCP socket connection.
 *
 * Receives lines from a TCP stream until the first empty line appears
 * and stores all lines in an array of strings. The empty line is not
 * stored, but the last pointer of the array is set to NULL.
 *
 * The routine allocates the array and all string. The caller should use
 * TcpReleaseHeaderLines() to release all allocated memory.
 *
 * \param sock  Socket descriptor. This pointer must have been retrieved 
 *              by calling NutTcpCreateSocket(). In addition a connection 
 *              must have been established by calling NutTcpConnect() or 
 *              NutTcpAccept().
 * \param array Pointer to a string array pointer, which receives the
 *              address of the newly allocated string array. If no
 *              non-empty lines were received or if an error occured,
 *              then the string array pointer will be set to NULL.
 *
 * \return The number of header lines stored. In case of an error, the
 *         function result is -1 instead.
 */
int TcpGetHeaderLines(TCPSOCKET * sock, char ***array)
{
    int rc = -1;
    struct LILI_ {
        struct LILI_ *ll_next;
        char *ll_line;
    };
    struct LILI_ *root = NULL;
    struct LILI_ *link = NULL;
    struct LILI_ **next = &root;
    char *buf;
    int len;

    /*
     * Allocate a line buffer. On success, build a linked list of
     * incoming lines. Stop on errors or at the first empty line.
     */
    if ((buf = malloc(255)) != NULL) {
        for (;;) {
            if ((len = TcpGetLine(sock, buf, 255)) == 0) {
                /* Empty line. */
                break;
            }
            if (len < 0) {
                /* Error occured. */
                rc = -1;
                break;
            }
            /* Allocate a linked list item. */
            if ((*next = malloc(sizeof(struct LILI_))) == NULL) {
                break;
            }
            /* Initially set the next link to NULL. */
            (*next)->ll_next = NULL;
            /* Copy the line to the linked list item. */
            (*next)->ll_line = malloc(len + 1);
            memcpy((*next)->ll_line, buf, len);
            (*next)->ll_line[len] = '\0';
            /* Set pointer to the next link. */
            next = &((*next)->ll_next);
            rc++;
        }
        free(buf);
    }

    if (rc > 0) {
        /* Allocate a new string array. */
        *array = malloc((rc + 1) * sizeof(char *));
        rc = 0;
    }
    else {
        /* Error or single empty line only. Set array pointer to NULL. */
        *array = NULL;
    }

    /*
     * This loop serves two purposes. It moves the strings from the
     * linked list to the string array (if one had been allocated)
     * and it releases all memory allocated for the linked list.
     */
    while (root) {
        if (*array) {
            /* Move string to the array. */
            (*array)[rc] = root->ll_line;
            rc++;
        }
        else {
            /* No array. Just release the string. */
            free(root->ll_line);
        }
        /* Get the next link and release the current entry. */
        link = root;
        root = root->ll_next;
        free(link);
    }

    /* NULL marks the end of the array. */
    if (*array) {
        (*array)[rc] = NULL;
    }
    return rc;
}

/*!
 * \brief Release previously allocated memory for the header lines.
 *
 * Should be called to release all memory allocated by TcpGetHeaderLines().
 *
 * \param array String array to be released.
 */
void TcpReleaseHeaderLines(char **array)
{
    char **ap = array;

    if (ap) {
        /* Thanks, Dany. */
        while (*ap) {
            free(*ap);
            ap++;
        }
        free(array);
    }
}

/*!
 * \brief Switch LED0 on or off.
 *
 * On the SAM7X-EK the LED labeled DS4 is used.
 *
 * On the SAM9260-EK we use the only one user LED.
 *
 * \param on If 0, then the LED will be switched off. Otherwise it will be lit.
 */
void Led0(int on)
{
#ifdef AT91SAM7X_EK
    outr(PIOB_PER, _BV(22));
    outr(PIOB_OER, _BV(22));
    if (on) {
        outr(PIOB_CODR, _BV(22));
    }
    else {
        outr(PIOB_SODR, _BV(22));
    }
#else
    outr(PIOA_PER, _BV(6));
    outr(PIOA_OER, _BV(6));
    if (on) {
        outr(PIOA_CODR, _BV(6));
    }
    else {
        outr(PIOA_SODR, _BV(6));
    }
#endif
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -