<commit_before>/********************************************************************************************************************************
 * This file is created to process BA Action Frame. According to 802.11 spec, there are 3 BA action types at all. And as BA is
 * related to TS, this part need some structure defined in QOS side code. Also TX RX is going to be resturctured, so how to send
 * ADDBAREQ ADDBARSP and DELBA packet is still on consideration. Temporarily use MANAGE QUEUE instead of Normal Queue.
 * WB 2008-05-27
 * *****************************************************************************************************************************/
#include "ieee80211.h"
#include "rtl819x_BA.h"

/********************************************************************************************************************
 *function:  Activate BA entry. And if Time is nozero, start timer.
 *   input:  PBA_RECORD			pBA  //BA entry to be enabled
 *	     u16			Time //indicate time delay.
 *  output:  none
********************************************************************************************************************/
static void ActivateBAEntry(struct ieee80211_device *ieee, PBA_RECORD pBA, u16 Time)
{
	pBA->bValid = true;
	if(Time != 0)
		mod_timer(&pBA->Timer, jiffies + MSECS(Time));
}

/********************************************************************************************************************
 *function:  deactivate BA entry, including its timer.
 *   input:  PBA_RECORD			pBA  //BA entry to be disabled
 *  output:  none
********************************************************************************************************************/
static void DeActivateBAEntry(struct ieee80211_device *ieee, PBA_RECORD pBA)
{
	pBA->bValid = false;
	del_timer_sync(&pBA->Timer);
}
/********************************************************************************************************************
 *function: deactivete BA entry in Tx Ts, and send DELBA.
 *   input:
 *	     PTX_TS_RECORD		pTxTs //Tx Ts which is to deactivate BA entry.
 *  output:  none
 *  notice:  As PTX_TS_RECORD structure will be defined in QOS, so wait to be merged. //FIXME
********************************************************************************************************************/
static u8 TxTsDeleteBA(struct ieee80211_device *ieee, PTX_TS_RECORD pTxTs)
{
	PBA_RECORD		pAdmittedBa = &pTxTs->TxAdmittedBARecord;  //These two BA entries must exist in TS structure
	PBA_RECORD		pPendingBa = &pTxTs->TxPendingBARecord;
	u8			bSendDELBA = false;

	// Delete pending BA
	if(pPendingBa->bValid)
	{
		DeActivateBAEntry(ieee, pPendingBa);
		bSendDELBA = true;
	}

	// Delete admitted BA
	if(pAdmittedBa->bValid)
	{
		DeActivateBAEntry(ieee, pAdmittedBa);
		bSendDELBA = true;
	}

	return bSendDELBA;
}

/********************************************************************************************************************
 *function: deactivete BA entry in Tx Ts, and send DELBA.
 *   input:
 *	     PRX_TS_RECORD		pRxTs //Rx Ts which is to deactivate BA entry.
 *  output:  none
 *  notice:  As PRX_TS_RECORD structure will be defined in QOS, so wait to be merged. //FIXME, same with above
********************************************************************************************************************/
static u8 RxTsDeleteBA(struct ieee80211_device *ieee, PRX_TS_RECORD pRxTs)
{
	PBA_RECORD		pBa = &pRxTs->RxAdmittedBARecord;
	u8			bSendDELBA = false;

	if(pBa->bValid)
	{
		DeActivateBAEntry(ieee, pBa);
		bSendDELBA = true;
	}

	return bSendDELBA;
}

/********************************************************************************************************************
 *function: reset BA entry
 *   input:
 *	     PBA_RECORD		pBA //entry to be reset
 *  output:  none
********************************************************************************************************************/
void ResetBaEntry(PBA_RECORD pBA)
{
	pBA->bValid			= false;
	pBA->BaParamSet.shortData	= 0;
	pBA->BaTimeoutValue		= 0;
	pBA->DialogToken		= 0;
	pBA->BaStartSeqCtrl.ShortData	= 0;
}
//These functions need porting here or not?
/*******************************************************************************************************************************
 *function:  construct ADDBAREQ and ADDBARSP frame here together.
 *   input:  u8*		Dst	//ADDBA frame's destination
 *	     PBA_RECORD		pBA	//BA_RECORD entry which stores the necessary information for BA.
 *	     u16		StatusCode  //status code in RSP and I will use it to indicate whether it's RSP or REQ(will I?)
 *	     u8			type	//indicate whether it's RSP(ACT_ADDBARSP) ow REQ(ACT_ADDBAREQ)
 *  output:  none
 *  return:  sk_buff*		skb     //return constructed skb to xmit
*******************************************************************************************************************************/
static struct sk_buff *ieee80211_ADDBA(struct ieee80211_device *ieee, u8 *Dst, PBA_RECORD pBA, u16 StatusCode, u8 type)
{
	struct sk_buff *skb = NULL;
	 struct ieee80211_hdr_3addr *BAReq = NULL;
	u8 *tag = NULL;
	u16 tmp = 0;
	u16 len = ieee->tx_headroom + 9;
	//category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) +  BA Timeout Value(2) +  BA Start SeqCtrl(2)(or StatusCode(2))
	IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:%pM, ieee->dev:%p\n", __func__, type, Dst, ieee->dev);
	if (pBA == NULL||ieee == NULL)
	{
		IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA, ieee);
		return NULL;
	}
	skb = dev_alloc_skb(len + sizeof( struct ieee80211_hdr_3addr)); //need to add something others? FIXME
	if (skb == NULL)
	{
		IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc skb for ADDBA_REQ\n");
		return NULL;
	}

	memset(skb->data, 0, sizeof( struct ieee80211_hdr_3addr));	//I wonder whether it's necessary. Apparently kernel will not do it when alloc a skb.
	skb_reserve(skb, ieee->tx_headroom);

	BAReq = ( struct ieee80211_hdr_3addr *) skb_put(skb,sizeof( struct ieee80211_hdr_3addr));

	memcpy(BAReq->addr1, Dst, ETH_ALEN);
	memcpy(BAReq->addr2, ieee->dev->dev_addr, ETH_ALEN);

	memcpy(BAReq->addr3, ieee->current_network.bssid, ETH_ALEN);

	BAReq->frame_ctl = cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT); //action frame

	//tag += sizeof( struct ieee80211_hdr_3addr); //move to action field
	tag = (u8 *)skb_put(skb, 9);
	*tag ++= ACT_CAT_BA;
	*tag ++= type;
	// Dialog Token
	*tag ++= pBA->DialogToken;

	if (ACT_ADDBARSP == type)
	{
		// Status Code
		printk("=====>to send ADDBARSP\n");
		tmp = cpu_to_le16(StatusCode);
		memcpy(tag, (u8 *)&tmp, 2);
		tag += 2;
	}
	// BA Parameter Set
	tmp = cpu_to_le16(pBA->BaParamSet.shortData);
	memcpy(tag, (u8 *)&tmp, 2);
	tag += 2;
	// BA Timeout Value
	tmp = cpu_to_le16(pBA->BaTimeoutValue);
	memcpy(tag, (u8 *)&tmp, 2);
	tag += 2;

	if (ACT_ADDBAREQ == type)
	{
	// BA Start SeqCtrl
		memcpy(tag, (u8 *)&(pBA->BaStartSeqCtrl), 2);
		tag += 2;
	}

	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
	return skb;
	//return NULL;
}


/********************************************************************************************************************
 *function:  construct DELBA frame
 *   input:  u8*		dst	//DELBA frame's destination
 *	     PBA_RECORD		pBA	//BA_RECORD entry which stores the necessary information for BA
 *	     TR_SELECT	        TxRxSelect  //TX RX direction
 *	     u16		ReasonCode  //status code.
 *  output:  none
 *  return:  sk_buff*		skb     //return constructed skb to xmit
********************************************************************************************************************/
static struct sk_buff *ieee80211_DELBA(
	struct ieee80211_device  *ieee,
	u8		         *dst,
	PBA_RECORD		 pBA,
	TR_SELECT		 TxRxSelect,
	u16			 ReasonCode
	)
{
	DELBA_PARAM_SET	DelbaParamSet;
	struct sk_buff *skb = NULL;
	 struct ieee80211_hdr_3addr *Delba = NULL;
	u8 *tag = NULL;
	u16 tmp = 0;
	//len = head len + DELBA Parameter Set(2) + Reason Code(2)
	u16 len = 6 + ieee->tx_headroom;

	if (net_ratelimit())
	IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:%pM\n", __func__, ReasonCode, dst);

	memset(&DelbaParamSet, 0, 2);

	DelbaParamSet.field.Initiator	= (TxRxSelect==TX_DIR)?1:0;<commit_msg>Staging: rtl8192u: Annotate association types with proper endianness<commit_after>/********************************************************************************************************************************
 * This file is created to process BA Action Frame. According to 802.11 spec, there are 3 BA action types at all. And as BA is
 * related to TS, this part need some structure defined in QOS side code. Also TX RX is going to be resturctured, so how to send
 * ADDBAREQ ADDBARSP and DELBA packet is still on consideration. Temporarily use MANAGE QUEUE instead of Normal Queue.
 * WB 2008-05-27
 * *****************************************************************************************************************************/
#include "ieee80211.h"
#include "rtl819x_BA.h"

/********************************************************************************************************************
 *function:  Activate BA entry. And if Time is nozero, start timer.
 *   input:  PBA_RECORD			pBA  //BA entry to be enabled
 *	     u16			Time //indicate time delay.
 *  output:  none
********************************************************************************************************************/
static void ActivateBAEntry(struct ieee80211_device *ieee, PBA_RECORD pBA, u16 Time)
{
	pBA->bValid = true;
	if(Time != 0)
		mod_timer(&pBA->Timer, jiffies + MSECS(Time));
}

/********************************************************************************************************************
 *function:  deactivate BA entry, including its timer.
 *   input:  PBA_RECORD			pBA  //BA entry to be disabled
 *  output:  none
********************************************************************************************************************/
static void DeActivateBAEntry(struct ieee80211_device *ieee, PBA_RECORD pBA)
{
	pBA->bValid = false;
	del_timer_sync(&pBA->Timer);
}
/********************************************************************************************************************
 *function: deactivete BA entry in Tx Ts, and send DELBA.
 *   input:
 *	     PTX_TS_RECORD		pTxTs //Tx Ts which is to deactivate BA entry.
 *  output:  none
 *  notice:  As PTX_TS_RECORD structure will be defined in QOS, so wait to be merged. //FIXME
********************************************************************************************************************/
static u8 TxTsDeleteBA(struct ieee80211_device *ieee, PTX_TS_RECORD pTxTs)
{
	PBA_RECORD		pAdmittedBa = &pTxTs->TxAdmittedBARecord;  //These two BA entries must exist in TS structure
	PBA_RECORD		pPendingBa = &pTxTs->TxPendingBARecord;
	u8			bSendDELBA = false;

	// Delete pending BA
	if(pPendingBa->bValid)
	{
		DeActivateBAEntry(ieee, pPendingBa);
		bSendDELBA = true;
	}

	// Delete admitted BA
	if(pAdmittedBa->bValid)
	{
		DeActivateBAEntry(ieee, pAdmittedBa);
		bSendDELBA = true;
	}

	return bSendDELBA;
}

/********************************************************************************************************************
 *function: deactivete BA entry in Tx Ts, and send DELBA.
 *   input:
 *	     PRX_TS_RECORD		pRxTs //Rx Ts which is to deactivate BA entry.
 *  output:  none
 *  notice:  As PRX_TS_RECORD structure will be defined in QOS, so wait to be merged. //FIXME, same with above
********************************************************************************************************************/
static u8 RxTsDeleteBA(struct ieee80211_device *ieee, PRX_TS_RECORD pRxTs)
{
	PBA_RECORD		pBa = &pRxTs->RxAdmittedBARecord;
	u8			bSendDELBA = false;

	if(pBa->bValid)
	{
		DeActivateBAEntry(ieee, pBa);
		bSendDELBA = true;
	}

	return bSendDELBA;
}

/********************************************************************************************************************
 *function: reset BA entry
 *   input:
 *	     PBA_RECORD		pBA //entry to be reset
 *  output:  none
********************************************************************************************************************/
void ResetBaEntry(PBA_RECORD pBA)
{
	pBA->bValid			= false;
	pBA->BaParamSet.shortData	= 0;
	pBA->BaTimeoutValue		= 0;
	pBA->DialogToken		= 0;
	pBA->BaStartSeqCtrl.ShortData	= 0;
}
//These functions need porting here or not?
/*******************************************************************************************************************************
 *function:  construct ADDBAREQ and ADDBARSP frame here together.
 *   input:  u8*		Dst	//ADDBA frame's destination
 *	     PBA_RECORD		pBA	//BA_RECORD entry which stores the necessary information for BA.
 *	     u16		StatusCode  //status code in RSP and I will use it to indicate whether it's RSP or REQ(will I?)
 *	     u8			type	//indicate whether it's RSP(ACT_ADDBARSP) ow REQ(ACT_ADDBAREQ)
 *  output:  none
 *  return:  sk_buff*		skb     //return constructed skb to xmit
*******************************************************************************************************************************/
static struct sk_buff *ieee80211_ADDBA(struct ieee80211_device *ieee, u8 *Dst, PBA_RECORD pBA, u16 StatusCode, u8 type)
{
	struct sk_buff *skb = NULL;
	 struct ieee80211_hdr_3addr *BAReq = NULL;
	u8 *tag = NULL;
	__le16 tmp = 0;
	u16 len = ieee->tx_headroom + 9;
	//category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) +  BA Timeout Value(2) +  BA Start SeqCtrl(2)(or StatusCode(2))
	IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:%pM, ieee->dev:%p\n", __func__, type, Dst, ieee->dev);
	if (pBA == NULL||ieee == NULL)
	{
		IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA, ieee);
		return NULL;
	}
	skb = dev_alloc_skb(len + sizeof( struct ieee80211_hdr_3addr)); //need to add something others? FIXME
	if (skb == NULL)
	{
		IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc skb for ADDBA_REQ\n");
		return NULL;
	}

	memset(skb->data, 0, sizeof( struct ieee80211_hdr_3addr));	//I wonder whether it's necessary. Apparently kernel will not do it when alloc a skb.
	skb_reserve(skb, ieee->tx_headroom);

	BAReq = ( struct ieee80211_hdr_3addr *) skb_put(skb,sizeof( struct ieee80211_hdr_3addr));

	memcpy(BAReq->addr1, Dst, ETH_ALEN);
	memcpy(BAReq->addr2, ieee->dev->dev_addr, ETH_ALEN);

	memcpy(BAReq->addr3, ieee->current_network.bssid, ETH_ALEN);

	BAReq->frame_ctl = cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT); //action frame

	//tag += sizeof( struct ieee80211_hdr_3addr); //move to action field
	tag = (u8 *)skb_put(skb, 9);
	*tag ++= ACT_CAT_BA;
	*tag ++= type;
	// Dialog Token
	*tag ++= pBA->DialogToken;

	if (ACT_ADDBARSP == type)
	{
		// Status Code
		printk("=====>to send ADDBARSP\n");
		tmp = cpu_to_le16(StatusCode);
		memcpy(tag, (u8 *)&tmp, 2);
		tag += 2;
	}
	// BA Parameter Set
	tmp = cpu_to_le16(pBA->BaParamSet.shortData);
	memcpy(tag, (u8 *)&tmp, 2);
	tag += 2;
	// BA Timeout Value
	tmp = cpu_to_le16(pBA->BaTimeoutValue);
	memcpy(tag, (u8 *)&tmp, 2);
	tag += 2;

	if (ACT_ADDBAREQ == type)
	{
	// BA Start SeqCtrl
		memcpy(tag, (u8 *)&(pBA->BaStartSeqCtrl), 2);
		tag += 2;
	}

	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
	return skb;
	//return NULL;
}


/********************************************************************************************************************
 *function:  construct DELBA frame
 *   input:  u8*		dst	//DELBA frame's destination
 *	     PBA_RECORD		pBA	//BA_RECORD entry which stores the necessary information for BA
 *	     TR_SELECT	        TxRxSelect  //TX RX direction
 *	     u16		ReasonCode  //status code.
 *  output:  none
 *  return:  sk_buff*		skb     //return constructed skb to xmit
********************************************************************************************************************/
static struct sk_buff *ieee80211_DELBA(
	struct ieee80211_device  *ieee,
	u8		         *dst,
	PBA_RECORD		 pBA,
	TR_SELECT		 TxRxSelect,
	u16			 ReasonCode
	)
{
	DELBA_PARAM_SET	DelbaParamSet;
	struct sk_buff *skb = NULL;
	 struct ieee80211_hdr_3addr *Delba = NULL;
	u8 *tag = NULL;
	__le16 tmp = 0;
	//len = head len + DELBA Parameter Set(2) + Reason Code(2)
	u16 len = 6 + ieee->tx_headroom;

	if (net_ratelimit())
	IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:%pM\n", __func__, ReasonCode, dst);

	memset(&DelbaParamSet, 0, 2);

	DelbaParamSet.field.Initiator	= (TxRxSelect==TX_DIR)?1:0;
{'fraction_non_alphanumeric': 0.31941858369872067, 'fraction_numerical': 0.030752597753618837, 'mean_word_length': 5.1484490398818314, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 77, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4435495', 'n_tokens_mistral': 5875, 'n_tokens_neox': 5173, 'n_words': 1392}