亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? tftpserver.c

?? 基于STM32F107的UDP服務器程序
?? C
?? 第 1 頁 / 共 2 頁
字號:
/* tftpsercer.c */

#include "tftpserver.h"
#include "stm3210c_eval_lcd.h"  // w w w . a r m j i s h u . c o m
#include "tftputils.h" 
#include "efs.h"
#include "ls.h"
#include "sd.h"
#include <stdio.h>
#include <string.h>

#define MFS_MODE_READ 0
#define MFS_MODE_WRITE 1

#define TFTP_OPCODE_LEN         2
#define TFTP_BLKNUM_LEN         2
#define TFTP_ERRCODE_LEN        2
#define TFTP_DATA_LEN_MAX       512
#define TFTP_DATA_PKT_HDR_LEN   (TFTP_OPCODE_LEN + TFTP_BLKNUM_LEN)
#define TFTP_ERR_PKT_HDR_LEN    (TFTP_OPCODE_LEN + TFTP_ERRCODE_LEN)
#define TFTP_ACK_PKT_LEN        (TFTP_OPCODE_LEN + TFTP_BLKNUM_LEN)
#define TFTP_DATA_PKT_LEN_MAX   (TFTP_DATA_PKT_HDR_LEN + TFTP_DATA_LEN_MAX)
#define TFTP_MAX_RETRIES        3
#define TFTP_TIMEOUT_INTERVAL   5


typedef struct
{
  int op;    /* RRQ/WRQ */

  /* last block read */
  char data[TFTP_DATA_PKT_LEN_MAX];
  int  data_len;

  /* destination ip:port */
  struct ip_addr to_ip;
  int to_port;

  /* next block number */
  int block;

  /* total number of bytes transferred */
  int tot_bytes;

  /* timer interrupt count when last packet was sent */
  /* this should be used to resend packets on timeout */
  unsigned long long last_time;

}tftp_connection_args;


EmbeddedFileSystem  efs1, efs2;
DirList             list1, list2;
EmbeddedFile        file_SD, file_CR;
/* UDPpcb to be binded with port 69  */
struct udp_pcb *UDPpcb;
/* tftp_errorcode error strings */
char *tftp_errorcode_string[] = {
                                  "not defined",
                                  "file not found",
                                  "access violation",
                                  "disk full",
                                  "illegal operation",
                                  "unknown transfer id",
                                  "file already exists",
                                  "no such user",
                                };

void recv_callback_tftp(void *arg, struct udp_pcb *upcb, struct pbuf *pkt_buf, struct ip_addr *addr, u16_t port);


err_t tftp_send_message(struct udp_pcb *upcb, struct ip_addr *to_ip, int to_port, char *buf, int buflen)
{

  err_t err;
  struct pbuf *pkt_buf; /* Chain of pbuf's to be sent */

  /* PBUF_TRANSPORT - specifies the transport layer */
  pkt_buf = pbuf_alloc(PBUF_TRANSPORT, buflen, PBUF_POOL);

  if (!pkt_buf)      /*if the packet pbuf == NULL exit and EndTransfertransmission */
    return ERR_MEM;

  /* Copy the original data buffer over to the packet buffer's payload */
  memcpy(pkt_buf->payload, buf, buflen);

  /* Sending packet by UDP protocol */
  err = udp_sendto(upcb, pkt_buf, to_ip, to_port);

  /* free the buffer pbuf */
  pbuf_free(pkt_buf);

  return err;
}


/* construct an error message into buf using err as the error code */
int tftp_construct_error_message(char *buf, tftp_errorcode err)
{

  int errorlen;
  /* Set the opcode in the 2 first bytes */
  tftp_set_opcode(buf, TFTP_ERROR);
  /* Set the errorcode in the 2 second bytes  */
  tftp_set_errorcode(buf, err);
  /* Set the error message in the last bytes */
  tftp_set_errormsg(buf, tftp_errorcode_string[err]);
  /* Set the length of the error message  */
  errorlen = strlen(tftp_errorcode_string[err]);

  /* return message size */
  return 4 + errorlen + 1;
}

/* construct and send an error message back to client */
int tftp_send_error_message(struct udp_pcb *upcb, struct ip_addr *to, int to_port, tftp_errorcode err)
{
  char buf[512];
  int error_len;

  /* construct error */
  error_len = tftp_construct_error_message(buf, err);	 //error包的長度
  /* sEndTransfererror  */
  return tftp_send_message(upcb, to, to_port, buf, error_len);
}

/* construct and send a data packet */
int tftp_send_data_packet(struct udp_pcb *upcb, struct ip_addr *to, int to_port, int block,
                          char *buf, int buflen)
{
  char packet[TFTP_DATA_PKT_LEN_MAX]; /* (512+4) bytes */

  /* Set the opcode 3 in the 2 first bytes */
  tftp_set_opcode(packet, TFTP_DATA);
  /* Set the block numero in the 2 second bytes */
  tftp_set_block(packet, block);
  /* Set the data message in the n last bytes */
  tftp_set_data_message(packet, buf, buflen);
  /* SEndTransferthe DATA packet */
  return tftp_send_message(upcb, to, to_port, packet, buflen + 4);
}

int tftp_send_ack_packet(struct udp_pcb *upcb, struct ip_addr *to, int to_port, int block)
{

  /* create the maximum possible size packet that a TFTP ACK packet can be */
  char packet[TFTP_ACK_PKT_LEN];

  /* define the first two bytes of the packet */
  tftp_set_opcode(packet, TFTP_ACK);

  /* Specify the block number being ACK'd.
   * If we are ACK'ing a DATA pkt then the block number echoes that of the DATA pkt being ACK'd (duh)
   * If we are ACK'ing a WRQ pkt then the block number is always 0
   * RRQ packets are never sent ACK pkts by the server, instead the server sends DATA pkts to the
   * host which are, obviously, used as the "acknowledgement".  This saves from having to sEndTransferboth
   * an ACK packet and a DATA packet for RRQs - see RFC1350 for more info.  */
  tftp_set_block(packet, block);

  return tftp_send_message(upcb, to, to_port, packet, TFTP_ACK_PKT_LEN);
}

/* close the file sent, disconnect and close the connection */
void tftp_cleanup_rd(struct udp_pcb *upcb, tftp_connection_args *args)
{
  /* close the filesystem */
  file_fclose(&file_SD);
  fs_umount(&efs1.myFs);
  /* Free the tftp_connection_args structure reserverd for */
  mem_free(args);

  /* Disconnect the udp_pcb*/
  udp_disconnect(upcb);

  /* close the connection */
  udp_remove(upcb);

  udp_recv(UDPpcb, recv_callback_tftp, NULL);
}

/* close the file writen, disconnect and close the connection */
void tftp_cleanup_wr(struct udp_pcb *upcb, tftp_connection_args *args)
{
  /* close the filesystem */
  file_fclose(&file_CR);
  fs_umount(&efs2.myFs);
  /* Free the tftp_connection_args structure reserverd for */
  mem_free(args);

  /* Disconnect the udp_pcb*/
  udp_disconnect(upcb);

  /* close the connection */
  udp_remove(upcb);

  /* reset the callback function */
  udp_recv(UDPpcb, recv_callback_tftp, NULL);
}

void tftp_send_next_block(struct udp_pcb *upcb, tftp_connection_args *args,
                          struct ip_addr *to_ip, u16_t to_port)
{
  /* Function to read 512 bytes from the file to sEndTransfer(file_SD), put them
   * in "args->data" and return the number of bytes read */
  args->data_len = file_read(&file_SD, TFTP_DATA_LEN_MAX, (euint8*)args->data);

  /*   NOTE: We need to sEndTransferanother data packet even if args->data_len = 0
     The reason for this is as follows:
     1) This function is only ever called if the previous packet payload was
        512 bytes.
     2) If args->data_len = 0 then that means the file being sent is an exact
         multiple of 512 bytes.
     3) RFC1350 specifically states that only a payload of <= 511 can EndTransfera
        transfer.
     4) Therefore, we must sEndTransferanother data message of length 0 to complete
        the transfer.                */


  /* sEndTransferthe data */	 
/*   
   last block read 
   char data[TFTP_DATA_PKT_LEN_MAX];
   int  data_len;              */ 
  tftp_send_data_packet(upcb, to_ip, to_port, args->block, args->data, args->data_len);

}

void rrq_recv_callback(void *_args, struct udp_pcb *upcb, struct pbuf *p,
                       struct ip_addr *addr, u16_t port)
{
  /* Get our connection state  */
  tftp_connection_args *args = (tftp_connection_args *)_args;

  if (tftp_is_correct_ack(p->payload, args->block))
  {
    /* increment block # */
    args->block++;			 //下一個塊號
  }
  else
  {
    /* we did not receive the expected ACK, so
       do not update block #. This causes the current block to be resent. */
  }

  /* if the last read returned less than the requested number of bytes
   * (i.e. TFTP_DATA_LEN_MAX), then we've sent the whole file and we can quit
   */
  if (args->data_len < TFTP_DATA_LEN_MAX)	//數據部分小于512字節
  {
    /* Clean the connection*/
    tftp_cleanup_rd(upcb, args);

    pbuf_free(p);
  }

  /* if the whole file has not yet been sent then continue  */
  tftp_send_next_block(upcb, args, addr, port);		//file_read要改

  pbuf_free(p);

}

int tftp_process_read(struct udp_pcb *upcb, struct ip_addr *to, int to_port, char* FileName)
{
  tftp_connection_args *args = NULL;	//聲明了一個指向連接結構體的指針

  /* If Could not open the file which will be transmitted  */
  if (file_fopen(&file_SD, &efs1.myFs, FileName, 'r') != 0)
  {
    //upcb開辟的PCB塊,用于保存UDP回話狀態,to為目的IP、to_port=0,
    tftp_send_error_message(upcb, to, to_port, TFTP_ERR_FILE_NOT_FOUND);

    tftp_cleanup_rd(upcb, args);

    return 0;
  }

  /* This function is called from a callback,
   * therefore, interrupts are disabled,
   * therefore, we can use regular malloc. */

  args = mem_malloc(sizeof *args); //申請分配內存,將總共需要的字節數作為參數
  /* If we aren't able to allocate memory for a "tftp_connection_args" */

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产一区三区三区| 91精品国产一区二区三区| 2欧美一区二区三区在线观看视频 337p粉嫩大胆噜噜噜噜噜91av | 久久久国际精品| 极品少妇一区二区| 久久久精品国产免费观看同学| 国产成人在线看| 国产精品国产三级国产a| 91在线porny国产在线看| 亚洲无线码一区二区三区| 69p69国产精品| 久久国产夜色精品鲁鲁99| 久久无码av三级| 粉嫩13p一区二区三区| 欧美国产日韩精品免费观看| 成人av网站在线观看| 一区二区三区鲁丝不卡| 欧美挠脚心视频网站| 国产在线播放一区二区三区| 中文字幕av不卡| 91在线一区二区| 国产精品久久久久永久免费观看| 成人网在线播放| 中文字幕日韩av资源站| 在线观看91精品国产入口| 午夜电影网一区| 国产日韩欧美一区二区三区乱码| 99在线精品观看| 五月综合激情网| 亚洲精品一区二区三区香蕉| 成人avav在线| 舔着乳尖日韩一区| 中文字幕精品综合| 7777精品伊人久久久大香线蕉经典版下载 | 久久精品视频在线免费观看| 国产凹凸在线观看一区二区| 亚洲欧美激情在线| 欧美大白屁股肥臀xxxxxx| 国产成人免费在线观看不卡| 亚洲日本va在线观看| 在线播放欧美女士性生活| 国产成人夜色高潮福利影视| 亚洲精品视频一区二区| 精品少妇一区二区三区| 91色|porny| 美女一区二区视频| 亚洲免费在线观看| 日韩精品影音先锋| 欧洲国产伦久久久久久久| 国产一本一道久久香蕉| 亚洲成人一区在线| 成人免费在线视频观看| 日韩网站在线看片你懂的| 91高清在线观看| 国产成人免费xxxxxxxx| 久久国产欧美日韩精品| 亚洲不卡av一区二区三区| 《视频一区视频二区| 精品日韩av一区二区| 欧美视频一区二区三区| 成人国产精品视频| 国产在线精品免费| 日本伊人午夜精品| 亚洲制服欧美中文字幕中文字幕| 国产精品免费丝袜| 精品第一国产综合精品aⅴ| 在线播放国产精品二区一二区四区| 色婷婷久久99综合精品jk白丝 | 国产精品一区二区三区四区| 日本中文一区二区三区| 亚洲一卡二卡三卡四卡无卡久久 | 91麻豆精品国产91久久久| 一本一道久久a久久精品 | 欧美伦理电影网| 欧美在线影院一区二区| 色噜噜偷拍精品综合在线| 97久久精品人人做人人爽50路| 福利91精品一区二区三区| 国产99久久久精品| 国产91富婆露脸刺激对白| 国产精品一卡二卡| 成人免费的视频| 成人av影视在线观看| 不卡av免费在线观看| 91小视频在线免费看| 91美女在线看| 欧美亚洲综合色| 欧美日本国产一区| 日韩精品中午字幕| 精品国产乱码久久久久久老虎 | 国产老肥熟一区二区三区| 久久99精品国产.久久久久| 久草在线在线精品观看| 国模少妇一区二区三区| 国产不卡一区视频| 99久久婷婷国产综合精品| 一本大道综合伊人精品热热| 在线视频国内自拍亚洲视频| 欧美天天综合网| 555夜色666亚洲国产免| 欧美精品一区男女天堂| 国产欧美日韩精品在线| 综合在线观看色| 香蕉加勒比综合久久| 国产成人免费网站| av高清久久久| 99国产精品国产精品毛片| 91小视频免费观看| 欧美日韩免费观看一区三区| 日韩午夜中文字幕| 久久青草欧美一区二区三区| 欧美激情综合在线| 一区二区日韩电影| 蜜桃久久精品一区二区| 粉嫩av一区二区三区在线播放| 91一区二区三区在线观看| 欧美日韩专区在线| 久久精品一区二区三区av| 亚洲乱码日产精品bd | 亚洲欧洲成人精品av97| 亚洲第一在线综合网站| 国产主播一区二区| 色女孩综合影院| 精品国产一区二区精华| 国产精品不卡视频| 奇米影视7777精品一区二区| 成人午夜激情在线| 色拍拍在线精品视频8848| 欧美日本一区二区三区四区| 2021中文字幕一区亚洲| 亚洲免费av在线| 精品亚洲免费视频| 欧美在线一区二区| 国产女主播在线一区二区| 亚洲大片在线观看| 成人黄色在线看| 91精品国产色综合久久不卡蜜臀| 国产精品乱子久久久久| 日本欧美加勒比视频| 一本大道av伊人久久综合| 亚洲精品一区二区三区香蕉| 亚洲电影激情视频网站| 不卡视频一二三四| 久久精品夜色噜噜亚洲aⅴ| 午夜欧美2019年伦理| 99久久精品国产一区| 久久久无码精品亚洲日韩按摩| 爽爽淫人综合网网站| 色婷婷综合久久久中文字幕| 久久精品亚洲精品国产欧美| 日产国产高清一区二区三区 | 国产一区二区在线视频| 678五月天丁香亚洲综合网| 一区二区三区中文在线观看| 国产91在线观看丝袜| 精品久久国产97色综合| 亚洲超碰97人人做人人爱| 欧美亚州韩日在线看免费版国语版| 国产亚洲综合色| 国产美女在线精品| 精品少妇一区二区三区视频免付费| 亚洲电影在线播放| 在线精品视频一区二区三四| 成人欧美一区二区三区白人| 成人av电影观看| 中文字幕制服丝袜成人av| 成人午夜视频在线观看| 国产欧美日本一区视频| 国产一区久久久| 国产日韩欧美亚洲| 成人永久免费视频| 亚洲欧洲av色图| 91丨九色丨国产丨porny| 亚洲视频一区二区在线| 91麻豆精品一区二区三区| 亚洲精品美国一| 欧洲在线/亚洲| 日韩在线一区二区三区| 91精品国产综合久久香蕉麻豆 | 97se亚洲国产综合自在线| 亚洲欧美在线视频观看| 色999日韩国产欧美一区二区| 亚洲精品中文字幕乱码三区| 在线亚洲一区二区| 视频在线在亚洲| 精品国精品国产| 国产91高潮流白浆在线麻豆| √…a在线天堂一区| 欧美午夜不卡视频| 精品一区二区在线播放| 国产喷白浆一区二区三区| 99久久亚洲一区二区三区青草| 亚洲欧美韩国综合色| 在线不卡欧美精品一区二区三区| 久久精品国内一区二区三区| 国产欧美一区二区精品性色超碰| 99精品欧美一区二区三区小说 | 精品国精品自拍自在线| 成人性视频免费网站| 亚洲国产一区二区在线播放|