Ejemplo n.º 1
0
int main(void)
{
    const unsigned int FrameLen = 36;
    unsigned char *macframe = malloc(FrameLen);  // alloc MAC header until frame body
    
    // fill header with junk, to make this more interesting
    for (unsigned int i = 0; i < FrameLen; i++) {
        macframe[i] = 0xde;
    }
    
    set_proto_version(macframe, 0);
    set_type(macframe, 1);
    set_subtype(macframe, 1);
    set_to_ds(macframe, 1);
    set_from_ds(macframe, 0);
    set_retry(macframe, 0);
    set_more_data(macframe, 0);
    
    print_header(macframe);
    
    printf("Protocol version: %d\n", get_proto_version(macframe));
    printf("Type: %d\n", get_type(macframe));
    printf("Subtype: %d\n", get_subtype(macframe));
    printf("Flags: To DS: %d  From DS: %d  Retry: %d  More Data: %d\n",
            get_to_ds(macframe) != 0, get_from_ds(macframe) != 0,
            get_retry(macframe) != 0, get_more_data(macframe) != 0);
    
    free(macframe);
}
void wlan_to_wlan(msdu_indicate_t *msdu, CIPHER_T ct, UWORD8 key_type,
                  UWORD8 key_index, TYPESUBTYPE_T frm_type,
                  asoc_entry_t *ae, BOOL_T use_same_buffer)
{
    UWORD8        q_num        = 0;
    UWORD8        tx_rate      = 0;
    UWORD8        pream        = 0;
    UWORD8        service_class= 0;
    UWORD8        *mac_hdr     = 0;
    UWORD8        *tx_dscr     = 0;
    UWORD16       mac_hdr_len  = 0;
    void          *amsdu_ctxt  = NULL;
    UWORD8        is_amsdu     = 0;
    BOOL_T        is_qos       = BFALSE;
    BOOL_T        is_htc       = BFALSE;
    msdu_desc_t   *buff_desc   = &(msdu->frame_desc);
    UWORD32       phy_tx_mode  = 0;
    UWORD32       sta_index    = INVALID_ID;
    buffer_desc_t buffer_desc  = {0};
    UWORD32       retry_set[2] = {0};

#ifdef DEBUG_MODE
        g_mac_stats.w2w++;
#endif /* DEBUG_MODE */

    /* Find the queue to which this packet needs to be added */
    q_num = get_w2w_txq_num_ap(msdu->priority);

    if(ae != NULL)
        sta_index = ae->sta_index;

    /* If the queue for which this packet belongs is full, then return */
    if(is_txq_full(q_num, sta_index) == BTRUE)
    {
        return;
    }

    /* Prepare the buffer descriptor for the payload based on the flag to    */
    /* use the same buffer. If the frame is to be sent on both WLAN as well  */
    /* as the host there may be cases in which the payload portion needs to  */
    /* be modified to be sent to the host. This causes the packet being sent */
    /* on WLAN to be altered if the same buffer is used. As a result the     */
    /* same buffer cannot be used for transmitting on WLAN in this case.     */
    /* However if the packet is to be sent only on WLAN this problem does    */
    /* not occur and hence the same buffer can be used.                      */
    if(use_same_buffer == BTRUE)
    {
        /* Add one user to the incoming buffer. This ensures that the buffer */
        /* will remain allocated even after the process rx frame function    */
        /* frees it.                                                         */
        mem_add_users(g_shared_pkt_mem_handle, buff_desc->buffer_addr, 1);

        /* Prepare a buffer descriptor with required information */
        buffer_desc.buff_hdl    = buff_desc->buffer_addr;
        buffer_desc.data_offset = buff_desc->data_offset;
        buffer_desc.data_length = buff_desc->data_len;
    }
    else
    {
        UWORD8 *out_data = 0;

        /* Allocate a new buffer for the payload outgoing on WLAN */
        out_data = (UWORD8*)pkt_mem_alloc(MEM_PRI_TX);
        if(out_data == NULL)
            return;

        /* Prepare a buffer descriptor with required information */
        buffer_desc.buff_hdl    = out_data;
        buffer_desc.data_offset = MAX_MAC_HDR_LEN;
        buffer_desc.data_length = buff_desc->data_len;

	if(buffer_desc.data_offset + buff_desc->data_len > SHARED_PKT_MEM_BUFFER_SIZE){
		printk("@@@:BUG! bad memcpy offset:%d, len:%d\n", buffer_desc.data_offset,
			buff_desc->data_len);
	}
        /* Copy the payload from the incoming packet to the outgoing buffer */
        memcpy(buffer_desc.buff_hdl + buffer_desc.data_offset,
               buff_desc->buffer_addr + buff_desc->data_offset,
               buff_desc->data_len);
    }

    /* Set the transmit rate to the required value. To support Multi-Rate    */
    /* the transmit rate is set to the maximum basic rate and the preamble   */
    /* is set to Long.                                                       */

    if(is_group(msdu->da) == BTRUE)
    {
        /* For multicast frames send frames at maximum rate */
        tx_rate = get_max_basic_rate();
        pream   = 1;
        service_class = BCAST_NO_ACK;

        /* Update the retry set information for this frame */
        update_retry_rate_set(0, tx_rate, 0, retry_set);
    }
    else
    {
        /* Get the transmit rate for the associated station based on the     */
        /* auto-rate, multi-rate or user-rate settings. The preamble must be */
        /* set accordingly.                                                  */
	    if(!ae)
		    printk("@@@:BUG ae==NULL to get rate\n");
        tx_rate = get_tx_rate_to_sta(ae);
        pream   = get_preamble(tx_rate);
        service_class = g_ack_policy;

        /* Update the retry set information for this frame */
        update_retry_rate_set(1, tx_rate, ae, retry_set);
    }

    /* AMSDU on WLAN-WLAN path is disabled since no space currently exists */
    /* in the RX-Buffer to add the sub-MSDU header                         */
#ifdef TX_MACHDR_IN_DSCR_MEM
    /* Check whether AMSDU aggregation is possible */
    amsdu_ctxt = get_amsdu_handle(msdu->da, msdu->priority, q_num, ae,
                                  buff_desc->data_len, 1, tx_rate);
#endif /* TX_MACHDR_IN_DSCR_MEM */

    /* Check whether AMSDU option is enabled */
    is_amsdu = (amsdu_ctxt != NULL);

    /* Check whether AMSDU aggregation is not supported or if this is the */
    /* first sub-MSDU of an AMSDU.                                        */
    if((0 == is_amsdu) || (NULL == amsdu_get_tx_dscr(amsdu_ctxt)))
    {
        /* Check whether QoS option is implemented */
        is_qos = is_qos_required(sta_index);

        /* Check whether the receiver is HT capable */
        is_htc = is_htc_capable(ae);

        /* Create the transmit descriptor and set default contents */
        tx_dscr = create_default_tx_dscr(is_qos, msdu->priority, is_amsdu);
        if(tx_dscr == NULL)
        {
            if(is_amsdu == 1)
            {
                /* If allocation of the AMSDU decriptor has failed, then */
                /* attempt transmission of the MSDU as a normal-MSDU.    */
                free_amsdu_handle(amsdu_ctxt);
                is_amsdu   = 0;
                amsdu_ctxt = NULL;
                tx_dscr = create_default_tx_dscr(is_qos, msdu->priority,
                                                 is_amsdu);
            }

            if(tx_dscr == NULL)
            {
				//caisf add 2013-02-15
                if(g_mac_net_stats)
                    g_mac_net_stats->tx_dropped++;
					
                pkt_mem_free(buffer_desc.buff_hdl);
                return;
            }
        }

        /* Update the AMSDU handle with the tx descriptor */
        if(1 == is_amsdu)
            amsdu_set_tx_dscr(amsdu_ctxt, tx_dscr);

        /* Create the MAC header of the out-going frame */
#ifdef TX_MACHDR_IN_DSCR_MEM
        mac_hdr = mem_alloc(g_shared_dscr_mem_handle, MAX_MAC_HDR_LEN);
        if(NULL == mac_hdr)
        {
            free_tx_dscr((UWORD32 *)tx_dscr);
			
			//caisf add 2013-02-15
            if(g_mac_net_stats)
                g_mac_net_stats->tx_dropped++;
				
            pkt_mem_free(buffer_desc.buff_hdl);
            free_amsdu_handle(amsdu_ctxt);
            return;
        }
#else  /* TX_MACHDR_IN_DSCR_MEM */
        mac_hdr = buffer_desc.buff_hdl + buffer_desc.data_offset - MAX_MAC_HDR_LEN;
#endif /* TX_MACHDR_IN_DSCR_MEM */

        /* Reset the frame control field. Set type/subtype extracted from the    */
        /* incoming frame and set 'from_ds' bit in the outgoing frame.           */
        /* Also set the Security type for the outgoing frame based on cipher type*/
        mac_hdr_len = set_mac_hdr_prot(mac_hdr, msdu->priority, service_class,
                                       is_qos, is_htc, is_amsdu);

        set_from_ds(mac_hdr, 1);
        if(ct != NO_ENCRYP)
            set_wep(mac_hdr, 1);

        /* Set Destination Address (DA), BSSID and Source Address (SA) in the   */
        /* outgoing frame.                                                      */
        set_address1(mac_hdr, msdu->da);
        set_address2(mac_hdr, mget_bssid());
        set_address3(mac_hdr, msdu->sa);

        /* Set the mac header related parameters in the Tx descriptor */
        set_tx_dscr_buffer_addr((UWORD32 *)tx_dscr, (UWORD32)mac_hdr);
        set_tx_dscr_mh_len((UWORD32 *)tx_dscr, mac_hdr_len);
        set_tx_dscr_mh_offset((UWORD32 *)tx_dscr, 0);

        /* Get the PHY transmit mode based on the transmit rate and preamble */
        phy_tx_mode = get_dscr_phy_tx_mode(tx_rate, pream, (void *)ae);

        /* Set the Tx-descriptor parameters */
        set_tx_params(tx_dscr, tx_rate, pream, service_class, phy_tx_mode,
                      retry_set);
        set_tx_dscr_q_num((UWORD32 *)tx_dscr, q_num);

        /* Set Security Parameters for the frame */
        set_tx_security(tx_dscr, ct, key_type, key_index);

        /* Set the HT power save parameters */
        set_ht_ps_params(tx_dscr, (void *)ae, tx_rate);

        /* Set the receiver address LUT index */
        set_ht_ra_lut_index(tx_dscr, get_ht_handle_entry((void *)ae),
                            msdu->priority, tx_rate);

    }
    else
        tx_dscr = amsdu_get_tx_dscr(amsdu_ctxt);


    /* Set the sub-MSDU info table in the Tx-Descriptor */
    set_submsdu_info(tx_dscr, &buffer_desc, 1, buffer_desc.data_length,
                     mac_hdr_len, msdu->sa, msdu->da, amsdu_ctxt);

    /* Update the TSF timestamp */
    update_tx_dscr_tsf_ts((UWORD32 *)tx_dscr);

    /* Transmit the MSDU */
    if(BTRUE == is_tx_ready(amsdu_ctxt))
    {
		// 20120709 caisf mod, merged ittiam mac v1.2 code
        if(BTRUE == tx_data_packet((UWORD8 *)ae, msdu->da, msdu->priority, q_num,
                                   tx_dscr, amsdu_ctxt))
        {
		    /* Increment count indicating packet added to Hw queue */
		    /* Check if packet Bcast/Mcast or Unicast */
		    if(is_group(msdu->da) == BTRUE)
		    {
		        g_num_mc_bc_qd_pkt++;
		    }
		    else
		    {
		        ae->num_qd_pkt++;
            }
        }
    }
}