first commit

This commit is contained in:
2024-10-10 00:45:09 +06:00
commit e56944bbcd
89 changed files with 31498 additions and 0 deletions

View File

@@ -0,0 +1,584 @@
#include "ftpc.h"
un_l2cval remote_ip;
uint16_t remote_port;
un_l2cval local_ip;
uint16_t local_port;
uint8_t connect_state_control_ftpc = 0;
uint8_t connect_state_data_ftpc = 0;
uint8_t gModeActivePassiveflag = 0;
uint8_t FTP_destip[4] = {192, 168, 10, 230}; // For FTP client examples; destination network info
uint16_t FTP_destport = 21; // For FTP client examples; destination network info
uint8_t gMenuStart = 0;
uint8_t gDataSockReady = 0;
uint8_t gDataPutGetStart = 0;
static uint8_t gMsgBuf[20]={0,};
struct ftpc ftpc;
struct Command Command;
void ftpc_init(uint8_t * src_ip)
{
ftpc.dsock_mode = ACTIVE_MODE;
local_ip.cVal[0] = src_ip[0];
local_ip.cVal[1] = src_ip[1];
local_ip.cVal[2] = src_ip[2];
local_ip.cVal[3] = src_ip[3];
local_port = 35000;
strcpy(ftpc.workingdir, "/");
socket(CTRL_SOCK, Sn_MR_TCP, FTP_destport, 0x0);
}
uint8_t ftpc_run(uint8_t * dbuf)
{
#ifndef Need_UARTGetCharBlocking_func
uint16_t size = 0;
long ret = 0;
uint32_t send_byte, recv_byte;
uint32_t blocklen;
uint32_t remain_filesize;
uint32_t remain_datasize;
uint8_t msg_c;
uint8_t dat[50]={0,};
uint32_t totalSize = 0, availableSize = 0;
switch(getSn_SR(CTRL_SOCK))
{
case SOCK_ESTABLISHED :
if(!connect_state_control_ftpc){
printf("%d:FTP Connected\r\n", CTRL_SOCK);
strcpy(ftpc.workingdir, "/");
connect_state_control_ftpc = 1;
}
if(gMenuStart){
gMenuStart = 0;
printf("\r\n----------------------------------------\r\n");
printf("Press menu key\r\n");
printf("----------------------------------------\r\n");
printf("1> View FTP Server Directory\r\n");
printf("2> View My Directory\r\n");
printf("3> Sets the type of file to be transferred. Current state : %s\r\n", (ftpc.type==ASCII_TYPE)?"Ascii":"Binary");
printf("4> Sets Data Connection. Current state : %s\r\n", (ftpc.dsock_mode==ACTIVE_MODE)?"Active":"Passive");
printf("5> Put File to Server\r\n");
printf("6> Get File from Server\r\n");
#if defined(F_FILESYSTEM)
printf("7> Delete My File\r\n");
#endif
printf("----------------------------------------\r\n");
while(1){
msg_c=ftp_getc();
if(msg_c=='1'){
if(ftpc.dsock_mode==PASSIVE_MODE){
sprintf(dat,"PASV\r\n");
send(CTRL_SOCK, (uint8_t *)dat, strlen(dat));
Command.First = f_dir;
break;
}
else{
wiz_NetInfo gWIZNETINFO;
ctlnetwork(CN_GET_NETINFO, (void*) &gWIZNETINFO);
sprintf(dat,"PORT %d,%d,%d,%d,%d,%d\r\n", gWIZNETINFO.ip[0], gWIZNETINFO.ip[1], gWIZNETINFO.ip[2], gWIZNETINFO.ip[3], (uint8_t)(local_port>>8), (uint8_t)(local_port&0x00ff));
send(CTRL_SOCK, (uint8_t *)dat, strlen(dat));
Command.First = f_dir;
gModeActivePassiveflag = 1;
break;
}
break;
}
else if(msg_c=='5'){
if(ftpc.dsock_mode==PASSIVE_MODE){
sprintf(dat,"PASV\r\n");
send(CTRL_SOCK, (uint8_t *)dat, strlen(dat));
Command.First = f_put;
break;
}
else{
wiz_NetInfo gWIZNETINFO;
ctlnetwork(CN_GET_NETINFO, (void*) &gWIZNETINFO);
sprintf(dat,"PORT %d,%d,%d,%d,%d,%d\r\n", gWIZNETINFO.ip[0], gWIZNETINFO.ip[1], gWIZNETINFO.ip[2], gWIZNETINFO.ip[3], (uint8_t)(local_port>>8), (uint8_t)(local_port&0x00ff));
send(CTRL_SOCK, (uint8_t *)dat, strlen(dat));
Command.First = f_put;
gModeActivePassiveflag = 1;
break;
}
}
else if(msg_c=='6'){
if(ftpc.dsock_mode==PASSIVE_MODE){
sprintf(dat,"PASV\r\n");
send(CTRL_SOCK, (uint8_t *)dat, strlen(dat));
Command.First = f_get;
break;
}
else{
wiz_NetInfo gWIZNETINFO;
ctlnetwork(CN_GET_NETINFO, (void*) &gWIZNETINFO);
sprintf(dat,"PORT %d,%d,%d,%d,%d,%d\r\n", gWIZNETINFO.ip[0], gWIZNETINFO.ip[1], gWIZNETINFO.ip[2], gWIZNETINFO.ip[3], (uint8_t)(local_port>>8), (uint8_t)(local_port&0x00ff));
send(CTRL_SOCK, (uint8_t *)dat, strlen(dat));
Command.First = f_get;
gModeActivePassiveflag = 1;
break;
}
}
else if(msg_c=='2'){
#if defined(F_FILESYSTEM)
scan_files(ftpc.workingdir, dbuf, (int *)&size);
printf("\r\n%s\r\n", dbuf);
#else
if (strncmp(ftpc.workingdir, "/$Recycle.Bin", sizeof("/$Recycle.Bin")) != 0)
size = sprintf(dbuf, "drwxr-xr-x 1 ftp ftp 0 Dec 31 2014 $Recycle.Bin\r\n-rwxr-xr-x 1 ftp ftp 512 Dec 31 2014 test.txt\r\n");
printf("\r\n%s\r\n", dbuf);
#endif
gMenuStart = 1;
break;
}
else if(msg_c=='3'){
printf("1> ASCII\r\n");
printf("2> BINARY\r\n");
while(1){
msg_c=ftp_getc();
if(msg_c=='1'){
sprintf(dat,"TYPE %c\r\n", TransferAscii);
ftpc.type = ASCII_TYPE;
send(CTRL_SOCK, (uint8_t *)dat, strlen(dat));
break;
}
else if(msg_c=='2'){
sprintf(dat,"TYPE %c\r\n", TransferBinary);
ftpc.type = IMAGE_TYPE;
send(CTRL_SOCK, (uint8_t *)dat, strlen(dat));
break;
}
else{
printf("\r\nRetry...\r\n");
}
}
break;
}
else if(msg_c=='4'){
printf("1> ACTIVE\r\n");
printf("2> PASSIVE\r\n");
while(1){
msg_c=ftp_getc();
if(msg_c=='1'){
ftpc.dsock_mode=ACTIVE_MODE;
break;
}
else if(msg_c=='2'){
ftpc.dsock_mode=PASSIVE_MODE;
break;
}
else{
printf("\r\nRetry...\r\n");
}
}
gMenuStart = 1;
break;
}
#if defined(F_FILESYSTEM)
else if(msg_c=='7'){
printf(">del filename?");
sprintf(ftpc.filename, "/%s\r\n", User_Keyboard_MSG());
if (f_unlink((const char *)ftpc.filename) != 0){
printf("\r\nCould not delete.\r\n");
}
else{
printf("\r\nDeleted.\r\n");
}
gMenuStart = 1;
break;
}
#endif
else{
printf("\r\nRetry...\r\n");
}
}
}
if(gDataSockReady){
gDataSockReady = 0;
switch(Command.First){
case f_dir:
sprintf(dat,"LIST\r\n");
send(CTRL_SOCK, (uint8_t *)dat, strlen(dat));
break;
case f_put:
printf(">put file name?");
sprintf(dat,"STOR %s\r\n", User_Keyboard_MSG());
send(CTRL_SOCK, (uint8_t *)dat, strlen(dat));
break;
case f_get:
printf(">get file name?");
sprintf(dat,"RETR %s\r\n", User_Keyboard_MSG());
send(CTRL_SOCK, (uint8_t *)dat, strlen(dat));
break;
default:
printf("Command.First = default\r\n");
break;
}
}
if((size = getSn_RX_RSR(CTRL_SOCK)) > 0){ // Don't need to check SOCKERR_BUSY because it doesn't not occur.
memset(dbuf, 0, _MAX_SS);
if(size > _MAX_SS) size = _MAX_SS - 1;
ret = recv(CTRL_SOCK,dbuf,size);
dbuf[ret] = '\0';
if(ret != size)
{
if(ret==SOCK_BUSY) return 0;
if(ret < 0){
printf("%d:recv() error:%ld\r\n",CTRL_SOCK,ret);
close(CTRL_SOCK);
return ret;
}
}
printf("Rcvd Command: %s\r\n", dbuf);
proc_ftpc((char *)dbuf);
}
break;
case SOCK_CLOSE_WAIT :
printf("%d:CloseWait\r\n",CTRL_SOCK);
if((ret=disconnect(CTRL_SOCK)) != SOCK_OK) return ret;
printf("%d:Closed\r\n",CTRL_SOCK);
break;
case SOCK_CLOSED :
printf("%d:FTPStart\r\n",CTRL_SOCK);
if((ret=socket(CTRL_SOCK, Sn_MR_TCP, FTP_destport, 0x0)) != CTRL_SOCK){
printf("%d:socket() error:%ld\r\n", CTRL_SOCK, ret);
close(CTRL_SOCK);
return ret;
}
break;
case SOCK_INIT :
printf("%d:Opened\r\n",CTRL_SOCK);
if((ret = connect(CTRL_SOCK, FTP_destip, FTP_destport)) != SOCK_OK){
printf("%d:Connect error\r\n",CTRL_SOCK);
return ret;
}
connect_state_control_ftpc = 0;
printf("%d:Connectting...\r\n",CTRL_SOCK);
break;
default :
break;
}
switch(getSn_SR(DATA_SOCK)){
case SOCK_ESTABLISHED :
if(!connect_state_data_ftpc){
printf("%d:FTP Data socket Connected\r\n", DATA_SOCK);
connect_state_data_ftpc = 1;
}
if(gDataPutGetStart){
switch(Command.Second){
case s_dir:
printf("dir waiting...\r\n");
if((size = getSn_RX_RSR(DATA_SOCK)) > 0){ // Don't need to check SOCKERR_BUSY because it doesn't not occur.
printf("ok\r\n");
memset(dbuf, 0, _MAX_SS);
if(size > _MAX_SS) size = _MAX_SS - 1;
ret = recv(DATA_SOCK,dbuf,size);
dbuf[ret] = '\0';
if(ret != size){
if(ret==SOCK_BUSY) return 0;
if(ret < 0){
printf("%d:recv() error:%ld\r\n",CTRL_SOCK,ret);
close(DATA_SOCK);
return ret;
}
}
printf("Rcvd Data:\n\r%s\n\r", dbuf);
gDataPutGetStart = 0;
Command.Second = s_nocmd;
}
break;
case s_put:
printf("put waiting...\r\n");
if(strlen(ftpc.workingdir) == 1)
sprintf(ftpc.filename, "/%s", (uint8_t *)gMsgBuf);
else
sprintf(ftpc.filename, "%s/%s", ftpc.workingdir, (uint8_t *)gMsgBuf);
#if defined(F_FILESYSTEM)
ftpc.fr = f_open(&(ftpc.fil), (const char *)ftpc.filename, FA_READ);
if(ftpc.fr == FR_OK){
remain_filesize = ftpc.fil.fsize;
printf("f_open return FR_OK\r\n");
do{
memset(dbuf, 0, _MAX_SS);
if(remain_filesize > _MAX_SS)
send_byte = _MAX_SS;
else
send_byte = remain_filesize;
ftpc.fr = f_read(&(ftpc.fil), (void *)dbuf, send_byte , (UINT *)&blocklen);
if(ftpc.fr != FR_OK){
break;
}
printf("#");
send(DATA_SOCK, dbuf, blocklen);
remain_filesize -= blocklen;
}while(remain_filesize != 0);
printf("\r\nFile read finished\r\n");
ftpc.fr = f_close(&(ftpc.fil));
}
else{
printf("File Open Error: %d\r\n", ftpc.fr);
ftpc.fr = f_close(&(ftpc.fil));
}
#else
remain_filesize = strlen(ftpc.filename);
do{
memset(dbuf, 0, _MAX_SS);
blocklen = sprintf(dbuf, "%s", ftpc.filename);
printf("########## dbuf:%s\r\n", dbuf);
send(DATA_SOCK, dbuf, blocklen);
remain_filesize -= blocklen;
}while(remain_filesize != 0);
#endif
gDataPutGetStart = 0;
Command.Second = s_nocmd;
disconnect(DATA_SOCK);
break;
case s_get:
printf("get waiting...\r\n");
if(strlen(ftpc.workingdir) == 1)
sprintf(ftpc.filename, "/%s", (uint8_t *)gMsgBuf);
else
sprintf(ftpc.filename, "%s/%s", ftpc.workingdir, (uint8_t *)gMsgBuf);
#if defined(F_FILESYSTEM)
ftpc.fr = f_open(&(ftpc.fil), (const char *)ftpc.filename, FA_CREATE_ALWAYS | FA_WRITE);
if(ftpc.fr == FR_OK){
printf("f_open return FR_OK\r\n");
while(1){
if((remain_datasize = getSn_RX_RSR(DATA_SOCK)) > 0){
while(1){
memset(dbuf, 0, _MAX_SS);
if(remain_datasize > _MAX_SS) recv_byte = _MAX_SS;
else recv_byte = remain_datasize;
ret = recv(DATA_SOCK, dbuf, recv_byte);
ftpc.fr = f_write(&(ftpc.fil), (const void *)dbuf, (UINT)ret, (UINT *)&blocklen);
remain_datasize -= blocklen;
if(ftpc.fr != FR_OK){
printf("f_write failed\r\n");
break;
}
if(remain_datasize <= 0) break;
}
if(ftpc.fr != FR_OK){
printf("f_write failed\r\n");
break;
}
printf("#");
}
else{
if(getSn_SR(DATA_SOCK) != SOCK_ESTABLISHED) break;
}
}
printf("\r\nFile write finished\r\n");
ftpc.fr = f_close(&(ftpc.fil));
gDataPutGetStart = 0;
}else{
printf("File Open Error: %d\r\n", ftpc.fr);
}
#else
while(1){
if((remain_datasize = getSn_RX_RSR(DATA_SOCK)) > 0){
while(1){
memset(dbuf, 0, _MAX_SS);
if(remain_datasize > _MAX_SS)
recv_byte = _MAX_SS;
else
recv_byte = remain_datasize;
ret = recv(DATA_SOCK, dbuf, recv_byte);
printf("########## dbuf:%s\r\n", dbuf);
remain_datasize -= ret;
if(remain_datasize <= 0)
break;
}
}else{
if(getSn_SR(DATA_SOCK) != SOCK_ESTABLISHED)
break;
}
}
gDataPutGetStart = 0;
Command.Second = s_nocmd;
#endif
break;
default:
printf("Command.Second = default\r\n");
break;
}
}
break;
case SOCK_CLOSE_WAIT :
printf("%d:CloseWait\r\n",DATA_SOCK);
if((ret=disconnect(DATA_SOCK)) != SOCK_OK) return ret;
printf("%d:Closed\r\n",DATA_SOCK);
break;
case SOCK_CLOSED :
if(ftpc.dsock_state == DATASOCK_READY){
if(ftpc.dsock_mode == PASSIVE_MODE){
printf("%d:FTPDataStart, port : %d\r\n",DATA_SOCK, local_port);
if((ret=socket(DATA_SOCK, Sn_MR_TCP, local_port, 0x0)) != DATA_SOCK){
printf("%d:socket() error:%ld\r\n", DATA_SOCK, ret);
close(DATA_SOCK);
return ret;
}
local_port++;
if(local_port > 50000)
local_port = 35000;
}else{
printf("%d:FTPDataStart, port : %d\r\n",DATA_SOCK, local_port);
if((ret=socket(DATA_SOCK, Sn_MR_TCP, local_port, 0x0)) != DATA_SOCK){
printf("%d:socket() error:%ld\r\n", DATA_SOCK, ret);
close(DATA_SOCK);
return ret;
}
local_port++;
if(local_port > 50000)
local_port = 35000;
}
ftpc.dsock_state = DATASOCK_START;
}
break;
case SOCK_INIT :
printf("%d:Opened\r\n",DATA_SOCK);
if(ftpc.dsock_mode == ACTIVE_MODE){
if( (ret = listen(DATA_SOCK)) != SOCK_OK){
printf("%d:Listen error\r\n",DATA_SOCK);
return ret;
}
gDataSockReady = 1;
printf("%d:Listen ok\r\n",DATA_SOCK);
}else{
if((ret = connect(DATA_SOCK, remote_ip.cVal, remote_port)) != SOCK_OK){
printf("%d:Connect error\r\n", DATA_SOCK);
return ret;
}
gDataSockReady = 1;
}
connect_state_data_ftpc = 0;
break;
default :
break;
}
#endif
return 0;
}
char proc_ftpc(char * buf)
{
uint16_t Responses;
uint8_t dat[30]={0,};
Responses =(buf[0]-'0')*100+(buf[1]-'0')*10+(buf[2]-'0');
switch(Responses){
case R_220: /* Service ready for new user. */
printf("\r\nInput your User ID > ");
sprintf(dat,"USER %s\r\n", User_Keyboard_MSG());
printf("\r\n");
send(CTRL_SOCK, (uint8_t *)dat, strlen(dat));
break;
case R_331: /* User name okay, need password. */
printf("\r\nInput your Password > ");
sprintf(dat,"PASS %s\r\n", User_Keyboard_MSG());
printf("\r\n");
send(CTRL_SOCK, (uint8_t *)dat, strlen(dat));
break;
case R_230: /* User logged in, proceed */
printf("\r\nUser logged in, proceed\r\n");
sprintf(dat,"TYPE %c\r\n", TransferAscii);
ftpc.type = ASCII_TYPE;
send(CTRL_SOCK, (uint8_t *)dat, strlen(dat));
break;
case R_200:
if((ftpc.dsock_mode==ACTIVE_MODE)&&gModeActivePassiveflag){
ftpc.dsock_state = DATASOCK_READY;
gModeActivePassiveflag = 0;
}
else{
gMenuStart = 1;
}
break;
case R_150:
switch(Command.First){
case f_dir:
Command.First = f_nocmd;
Command.Second = s_dir;
gDataPutGetStart = 1;
break;
case f_get:
Command.First = f_nocmd;
Command.Second = s_get;
gDataPutGetStart = 1;
break;
case f_put:
Command.First = f_nocmd;
Command.Second = s_put;
gDataPutGetStart = 1;
break;
default :
printf("Command.First = default\r\n");
break;
}
break;
case R_226:
gMenuStart = 1;
break;
case R_227:
if (pportc(buf) == -1){
printf("Bad port syntax\r\n");
}
else{
printf("Go Open Data Sock...\r\n ");
ftpc.dsock_mode = PASSIVE_MODE;
ftpc.dsock_state = DATASOCK_READY;
}
break;
default:
printf("\r\nDefault Status = %d\r\n",(uint16_t)Responses);
gDataSockReady = 1;
break;
}
return 1;
}
int pportc(char * arg)
{
int i;
char* tok=0;
strtok(arg,"(");
for (i = 0; i < 4; i++)
{
if(i==0) tok = strtok(NULL,",\r\n");
else tok = strtok(NULL,",");
remote_ip.cVal[i] = (uint8_t)atoi(tok);
if (!tok){
printf("bad pport : %s\r\n", arg);
return -1;
}
}
remote_port = 0;
for (i = 0; i < 2; i++){
tok = strtok(NULL,",\r\n");
remote_port <<= 8;
remote_port += atoi(tok);
if (!tok){
printf("bad pport : %s\r\n", arg);
return -1;
}
}
printf("ip : %d.%d.%d.%d, port : %d\r\n", remote_ip.cVal[0], remote_ip.cVal[1], remote_ip.cVal[2], remote_ip.cVal[3], remote_port);
return 0;
}
uint8_t* User_Keyboard_MSG()
{
uint8_t i=0;
do{
gMsgBuf[i] = ftp_getc();
i++;
}while(gMsgBuf[i-1]!=0x0d);
gMsgBuf[i-1]=0;
return gMsgBuf;
}

View File

@@ -0,0 +1,130 @@
#ifndef _FTPC_H_
#define _FTPC_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <limits.h>
#include <stdarg.h>
#include <stdlib.h>
#include "socket.h"
/* If you need this header, use it. */
//#include "stdio_private.h"
#define F_APP_FTPC
/* If your target support a file system, you have to activate this feature and implement. */
//#define F_FILESYSTEM
/* Change to your Chipset Uart function, you have to activate this feature and implement.
* Change!! -> Board_UARTGetCharBlocking()
* Below is an example of a function of lpc_chip library. */
//#define ftp_getc() Board_UARTGetCharBlocking()
#ifdef F_FILESYSTEM
#include "ff.h"
#endif
#ifndef ftp_getc()
#define Need_UARTGetCharBlocking_func
#else
/* Change library
* Change!! -> board_api.h,
* Below is an example of a function of lpc_chip library. */
#include "board_api.h"
#endif
#define LINELEN 100
#ifndef F_FILESYSTEM
#define _MAX_SS 512
#endif
#define CTRL_SOCK 2
#define DATA_SOCK 3
/* FTP Responses */
#define R_150 150 /* File status ok; opening data conn */
#define R_200 200 /* 'Generic' command ok */
#define R_220 220 /* Service ready for new user. */
#define R_226 226 /* Closing data connection. File transfer/abort successful */
#define R_227 227 /* Entering passive mode (h1,h2,h3,h4,p1,p2) */
#define R_230 230 /* User logged in, proceed */
#define R_331 331 /* User name okay, need password. */
#define TransferAscii 'A'
#define TransferBinary 'I'
enum ftpc_type {
ASCII_TYPE,
IMAGE_TYPE,
};
enum ftpc_datasock_state{
DATASOCK_IDLE,
DATASOCK_READY,
DATASOCK_START
};
enum ftpc_datasock_mode{
PASSIVE_MODE,
ACTIVE_MODE
};
enum CommandFirst {
f_nocmd,
f_dir,
f_put,
f_get,
};
enum CommandSecond {
s_nocmd,
s_dir,
s_put,
s_get,
};
struct Command {
enum CommandFirst First;
enum CommandSecond Second;
};
struct ftpc {
uint8_t control; /* Control stream */
uint8_t data; /* Data stream */
enum ftpc_type type; /* Transfer type */
enum ftpc_datasock_state dsock_state;
enum ftpc_datasock_mode dsock_mode;
char workingdir[LINELEN];
char filename[LINELEN];
#ifdef F_FILESYSTEM
FIL fil; // FatFs File objects
FRESULT fr; // FatFs function common result code
#endif
};
#ifndef un_I2cval
typedef union _un_l2cval {
uint32_t lVal;
uint8_t cVal[4];
}un_l2cval;
#endif
void ftpc_init(uint8_t * src_ip);
uint8_t ftpc_run(uint8_t * dbuf);
char proc_ftpc(char * buf);
int pportc(char * arg);
uint8_t* User_Keyboard_MSG();
#ifdef __cplusplus
}
#endif
#endif // _FTPC_H_

View File

@@ -0,0 +1,75 @@
/* Copyright (c) 2002, Joerg Wunsch
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* 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.
* 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT OWNER 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.
*/
/* $Id: stdio_private.h,v 1.6 2003/01/07 22:17:24 joerg_wunsch Exp $ */
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdio.h>
struct __file {
char *buf; /* buffer pointer */
unsigned char unget; /* ungetc() buffer */
uint8_t flags; /* flags, see below */
#define __SRD 0x0001 /* OK to read */
#define __SWR 0x0002 /* OK to write */
#define __SSTR 0x0004 /* this is an sprintf/snprintf string */
#define __SPGM 0x0008 /* fmt string is in progmem */
#define __SERR 0x0010 /* found error */
#define __SEOF 0x0020 /* found EOF */
#define __SUNGET 0x040 /* ungetc() happened */
#if 0
/* possible future extensions, will require uint16_t flags */
#define __SRW 0x0080 /* open for reading & writing */
#define __SLBF 0x0100 /* line buffered */
#define __SNBF 0x0200 /* unbuffered */
#define __SMBF 0x0400 /* buf is from malloc */
#endif
int size; /* size of buffer */
int len; /* characters read or written so far */
int (*put)(char); /* function to write one char to device */
int (*get)(void); /* function to read one char from device */
};
/* values for PRINTF_LEVEL */
#define PRINTF_MIN 1
#define PRINTF_STD 2
#define PRINTF_FLT 3
/* values for SCANF_LEVEL */
#define SCANF_MIN 1
#define SCANF_STD 2
#define SCANF_FLT 3
#ifdef __cplusplus
}
#endif