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

📄 buf.c

📁 软件无线电的平台
💻 C
字号:
/*************************************************************************** *    buf.c  -  Implement the buffering of the ip-packets *                           ------------------- *   begin                :  2003 *   authors              :  Linus Gasser *   emails               :  linus.gasser@epfl.ch ***************************************************************************//*************************************************************************** *                                Changes *                                ------- * date - name - description * 03/05/02 - ineiti - start * **************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************//* ------------------------------------------------------------------------ * -----------------------------------------------------------------------*/#include "spc.h"#include "system.h"#include "tcpip.h"#include "net.h"#include "buf.h"#include "ack.h"#define DBG_LVL 1/** * @short initialise the buffers * * Initialises enough memory for a couple of IP-packets... * * @param buf where all the stuff shall be stored */void buf_init( struct buffer_t *buf ) {  buf->ip_buf_rcv = swr_malloc( IP_BUF_LEN );  buf->ip_buf_rcv_pos = 0;  buf->ip_buf_send = swr_malloc( IP_BUF_LEN );  buf->ip_buf_send_pos = 0;  ack_init( &buf->ack_sent );  ack_init( &buf->ack_rcvd );  ack_init( &buf->rcvd );  ack_init( &buf->send );}/** * Clean up the buffers */void buf_cleanup( struct buffer_t *buf ) {  if ( buf ) {    swr_free( buf->ip_buf_rcv );    swr_free( buf->ip_buf_send );    ack_free( &buf->ack_sent );    ack_free( &buf->ack_rcvd );    ack_free( &buf->rcvd );    ack_free( &buf->send );  }}/** * @short update the references * * When receiving an acknowledge over the air, we can delete some * references from our table... * * TODO: is it possible to have two acks with same pos but different * length? * * @param buf the buffer-structure * @param pack what to remove */void buf_update_ack_sent( struct buffer_t *buf, struct rf_packet *pack ) {  if ( !buf->ack_sent->len ) {    PR_DBG( 0, "Receiving acknowledge while no waiting acks!\n" );  } else {    if ( ack_delete( buf->ack_sent, pack->pos ) < 0 ) {      PR_DBG( 0, "Couldn't find the packet to ack!\n" );    }  }}/** * @short copies b to a with wrap-over in the destination  * * Copies b to a and takes care about an eventual overflow in the * destination block. It then returns the new position. * * @param a destination * @param b source * @param pos the position in the destination * @param len how many bytes * @param wrap the size of the destination * @return the new position in the destination */int buf_copy_wrap_dst( void *a, void *b, int pos, int len, int wrap ) {  int ret;  if ( pos + len > wrap ) {    // Do some magick on the boundaries    ret = wrap - pos;    memcpy( a + pos, b, ret );    memcpy( a, b + ret, len - ret );    ret = len - ret;  } else {    memcpy( a + pos, b, len );    ret = pos + len;  }  return ret;}/** * @short copies b to a with wrap-over in the source * * Copies b to a and takes care about an eventual overflow in the * source block. It then returns the new position. * * @param a destination * @param b source * @param pos the position in the source * @param len how many bytes * @param wrap the size of the source * @return the new position in the source */int buf_copy_wrap_src( void *a, void *b, int pos, int len, int wrap ) {  int ret;  if ( pos + len > wrap ) {    // Do some magick on the boundaries    ret = wrap - pos;    memcpy( a, b + pos, ret );    memcpy( a + ret, b, len - ret );    ret = len - ret;  } else {    memcpy( a, b + pos, len );    ret = pos + len;  }  return ret;}/** * @short inserts a rf-packet in the buffer * * Puts together received data that comes from the rf-interface. * Also inserts acks in the list and calls the kernel-rx  * function if a packet has been received successfully. * * @param buf the buffer-structure * @param pack the received packet */void buf_rf_to_net( struct buffer_t *buf, struct rf_packet *pack ) {  struct ack *a;  char *block;  int ip_len, half, pa, pb;  // Copy the received data in the ip-buffer  buf_copy_wrap_dst( buf->ip_buf_rcv, &pack->data,                     pack->pos, pack->len, IP_BUF_LEN );  // Append in the ack_rcvd  ack_append( buf->ack_rcvd, pack->pos, pack->len );  // Look if the packet is new or resent due to a lost ack  half = IP_BUF_LEN / 2;  pa = pack->pos;  pb = buf->ip_buf_rcv_pos;  if ( ( ( pa >= pb ) && ( pa - pb >= half ) ) ||       ( ( pa < pb ) && ( pb - pa <= half ) ) ) {    PR_DBG( 1, "Rejected packet because it already got processed\n" );    // Reject packet  } else {    PR_DBG( 4, "Incoming: %i, last good: %i\n", pack->pos, buf->ip_buf_rcv_pos );    // Append in the rcvd list    ack_ins_sorted( buf->rcvd, pack->pos, pack->len );    // Search if we have already enough bytes to build a ip-packet    a = ack_join_blocks( buf->rcvd );    if ( a->len > 2 ) {      PR_DBG( 4, "Received a block of len %i and allocating\n", a->len );      block = swr_malloc( a->len );      buf->ip_buf_rcv_pos = buf_copy_wrap_src( block, buf->ip_buf_rcv,                            a->pos, a->len, IP_BUF_LEN );      ip_len = *((u16*)block);      if ( ip_len <= a->len ) {        PR_DBG( 1, "Block contains at least one ip-packet with len %i and CRC %x\n",                ip_len, *((U32*)( block + 2 ) ) );        // If we have enough data, we cut a packet from the beginnning        // but without the length-indicator and send it to the kernel        net_send_to_kernel( buf->dev, block + 2, ip_len );        ack_cut_begin( buf->rcvd, ip_len + 2 );      }      swr_free( block );    }  }}/** * @short prepare a packet over the air * */void buf_net_to_rf( struct buffer_t *buf, char *packet, int len ) {  PR_DBG( 1, "Putting packet to rf, len:%i\n", len );  // Add it to the packets to send  ack_append( buf->send, buf->ip_buf_send_pos, len );  // And copy the data to send into the ring-buffer  buf->ip_buf_send_pos = buf_copy_wrap_dst( buf->ip_buf_send, packet,                         buf->ip_buf_send_pos, len, IP_BUF_LEN );}

⌨️ 快捷键说明

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