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

📄 ingress.c

📁 wimax BS simulation code,implemented under linux.
💻 C
字号:
/* * This piece of code is totally free. If any pitfalls found,  * please feel free to contact me at jetmotor@21cn.com * THANKS A LOT! */#include <stdlib.h>#include <string.h>#include "list.h"#include "task.h"#include "mac.h"#include "wxbuff.h"static void macpdu_decode(wxbuff_t *wxb);static void grantmngshdr_decode(uint8_t *buffer, uint16_t cid);static void fragment_decode(wxbuff_t *wxb, uint32_t offset, uint32_t length, uint16_t cid, int8_t ext);static void packing_decode(wxbuff_t *wxb, uint32_t offset, uint32_t length, uint16_t cid, int8_t ext);static void macsignalinghdr1_decode(uint8_t *buffer);static void macsignalinghdr2_decode(uint8_t *buffer);int32_t ingress_init(){	return 0;}void * do_task_burst_decode(void *arg){	struct list_head hdr, *pos, *tmp;	wxbuff_t *wxb;	genmachdr_t machdr;	uint32_t len;	int32_t exit;	for ( ; ; ) {		pos = ringq_deque(&tq_bst_rx);		wxb = list_entry(pos, wxbuff_t, senior);		list_add_tail(&hdr, &wxb->junior);		exit = 0;		list_for_each_safe(pos, tmp, &hdr) {			wxb = list_entry(pos, wxbuff_t, junior);		job:			while ( wxb->len >= sizeof(genmachdr_t) ) {				wxb->mac = (genmachdr_t *)wxb->beg;				/* if HCS checksum fails, which means we cannot				 * deduce len correctly from MAC header, `exit = 1; break;'				 * discard all the remaining burst.				 */				/* ... */				if ( genmachdr_get_cid(wxb->mac) == 0xfffe ) {					exit = 1; break;				}								if ( wxb->mac->ht == 0 ) {					len = genmachdr_get_len(wxb->mac);					if ( len < sizeof(genmachdr_t) || len > 2048 ) {						exit = 1; break;					}					if ( len > wxb->len ) {						wxbuff_t *_wxb = wxb;						uint32_t _len = len;						if ( (wxb = get_wxbuff(NULL)) == NULL )							break;												wxbuff_push(wxb, _wxb->beg, _wxb->len);						_len -= _wxb->len;												_wxb = list_entry(tmp, wxbuff_t, junior);						wxbuff_push(wxb, _wxb->beg, _len);						_wxb->beg += _len;						_wxb->len -= _len;												list_add(&wxb->junior, pos);						pos = pos->next;					}				}				else 					len = sizeof(bwrmachdr_t);				macpdu_decode(wxb);				wxb->beg += len;				wxb->len -= len;			}			if ( exit ) break;						if ( wxb->len > 0 && tmp != &hdr ) {				wxbuff_t *_wxb = list_entry(tmp, wxbuff_t, junior);				uint32_t _len = sizeof(genmachdr_t) - wxb->len;				if ( _wxb->len < _len )					break;				memcpy(&machdr, wxb->beg, wxb->len);				memcpy((uint8_t *)&machdr+wxb->len, _wxb->beg, _len);				/* if HCS checksum fails, which means we cannot				 * deduce len correctly from MAC header, `break;'				 * discard all the remaining burst.				 */				/* ... */				if ( genmachdr_get_cid(&machdr) == 0xfffe )					break;								if ( machdr.ht == 0 ) {					len = genmachdr_get_len(&machdr);					if ( len < sizeof(genmachdr_t) || len > 2048 )						break;										if ( (wxb = get_wxbuff(NULL)) == NULL )						break;					wxbuff_push(wxb, (uint8_t *)&machdr, sizeof(genmachdr_t));					_wxb->beg += _len;					_wxb->len -= _len;					wxbuff_push(wxb, _wxb->beg, len-_len);					list_add(&wxb->junior, pos);					pos = pos->next;					goto job;				}				else {					if ( machdr.ec == 0 )						macsignalinghdr1_decode((uint8_t *)&machdr);					else						macsignalinghdr2_decode((uint8_t *)&machdr);										_wxb->beg += _len;					_wxb->len -= _len;				}			}		}				list_for_each_safe(pos, tmp, &hdr) {			wxb = list_entry(pos, wxbuff_t, junior);			put_wxbuff(wxb);		}	}	return NULL;}/* @length:	the length of all the remaining data in the burst, including the current pdu. */void macpdu_decode(wxbuff_t *wxb){	uint32_t m, len = 0, off = 0;	uint16_t cid;	int8_t ext = 0;	wxbuff_t *_wxb;	wxb->mac = (genmachdr_t *)wxb->beg;	/* if generic MAC header. */	if ( wxb->mac->ht == 0 ) {		len = genmachdr_get_len(wxb->mac);		cid = genmachdr_get_cid(wxb->mac);		/* if the cid is not valid/active at all.		 */		pthread_mutex_lock(&g_serviceflow[cid].mutex);		if ( g_serviceflow[cid].stat == SF_INVALID ) {			pthread_mutex_unlock(&g_serviceflow[cid].mutex);			return;		}		pthread_mutex_unlock(&g_serviceflow[cid].mutex);		g_serviceflow[cid]._data += len;		                /* if CRC checksum fails, `return; wxb->beg += len; wxb->len -= len;'                 * discard just the current MAC message.                 */                /* ... */		off += sizeof(*(wxb->mac));		m = len - (wxb->mac->ci==1 ? 4 : 0) - sizeof(*(wxb->mac));                if ( wxb->mac->type & MESH_SUBHDR_MASK ) {			/* Obviously, we have no need to support MESH mode.			 */                }				if ( wxb->mac->type & GRANT_MANAGEMENT_SUBHDR_MASK ) {			grantmngshdr_decode(wxb->beg+off, cid);			off += sizeof(grantmngshdr_t);			m -= sizeof(grantmngshdr_t);		}		if ( wxb->mac->type & ARQ_FEEDBACK_PAYLOAD_MASK ) {			/* we will not implement this in step ONE. */                }                if ( wxb->mac->type & EXTENDED_TYPE_MASK )                        ext = 1;                if ( wxb->mac->type & FRAGMENTATION_SUBHDR_MASK ) {			fragment_decode(wxb, off, m, cid, ext);			return;		}		else if ( wxb->mac->type & PACKING_SUBHDR_MASK ) {			packing_decode(wxb, off, m, cid, ext);			return;		}		/* standalone sdu, definitely no more than 2K bytes,		 * just use one wxbuff to reference the data.		 */		if ( (_wxb = get_wxbuff(wxb)) == NULL )			return;		_wxb->beg = wxb->beg + off;		_wxb->end = _wxb->beg + m;		_wxb->tolen = _wxb->len = m;		_wxb->cid = cid;				if ( is_basic_cid(cid) || is_primary_cid(cid) || cid == 0 )			ringq_enque(&tq_sig_rx, &_wxb->junior);		else			ringq_enque(&tq_logger, &_wxb->junior);	}        else {		wxb->mac->ec == 0 ?			macsignalinghdr1_decode(wxb->beg) : macsignalinghdr2_decode(wxb->beg);        }	return;}/* @length:	the length of the fragment, including fragmentation subheader but excluding other subheaders or mac header. */void fragment_decode(wxbuff_t *wxb, uint32_t offset, uint32_t length, uint16_t cid, int8_t ext){	uint32_t fc, fsn;	wxbuff_t *_wxb;		if ( ext == 1 ) {		extfragshdr_t *efshdr = (extfragshdr_t *)(wxb->beg+offset);				fc = efshdr->fc;		fsn = extfragshdr_get_fsn(efshdr);		offset += sizeof(extfragshdr_t);		length -= sizeof(extfragshdr_t);	}	else {		fragshdr_t *fshdr = (fragshdr_t *)(wxb->beg+offset);				fc = fshdr->fc;		fsn = fshdr->fsn;		offset += sizeof(fragshdr_t);		length -= sizeof(fragshdr_t);	}		/* becase there are no other threads want to modify fc and fsn, don't lock mutex.	 */	if ( is_fcfsn_valid(g_serviceflow[cid].fc, g_serviceflow[cid].fsn, fc, fsn, ext) ) {		g_serviceflow[cid].fc = fc;		g_serviceflow[cid].fsn = ext ? (fsn+1) & 0x7ff : (fsn+1) & 0x7;		if ( (_wxb = get_wxbuff(wxb)) == NULL )			goto clean;		_wxb->beg = wxb->beg + offset;		_wxb->end = wxb->beg + length;		_wxb->len = length;				if ( softq_enque_tail(&g_softque[cid], _wxb) < 0 ) {			put_wxbuff(_wxb);			goto clean;		}				if ( fc == NO_FRAG || fc == LAST_FRAG ) {			uint32_t l = g_softque[cid].size;			_wxb = softq_dump(&g_softque[cid]);			_wxb->tolen = l;			_wxb->cid = cid;						if ( is_basic_cid(cid) || is_primary_cid(cid) || cid == 0 )				ringq_enque(&tq_sig_rx, &_wxb->senior);			else				ringq_enque(&tq_logger, &_wxb->senior);		}	}	else {		//g_serviceflow[cid].fc = NO_FRAGMENTATION;		struct list_head hdr, *pos, *tmp;	clean:		if ( (_wxb = softq_dump(&g_softque[cid])) ) {			list_add_tail(&hdr, &_wxb->junior);			list_for_each_safe(pos, tmp, &hdr) {				_wxb = list_entry(pos, wxbuff_t, junior);				put_wxbuff(_wxb);			}		}	}		return;}/* @length:	the length of the packing, including all the the packing subheader but excluing other subheaders or mac header. */void packing_decode(wxbuff_t *wxb, uint32_t offset, uint32_t length, uint16_t cid, int8_t ext){	uint32_t len, off;	uint32_t fc, fsn;	wxbuff_t *_wxb;		off = len = 0;	while ( off < length ) {		if ( ext ) {			extpackshdr_t *epshdr = (extpackshdr_t *)(wxb->beg+offset+off);			len = extpackshdr_get_len(epshdr) - sizeof(extpackshdr_t);			fc = epshdr->fc;			fsn = extpackshdr_get_fsn(epshdr);			off += sizeof(extpackshdr_t);		}		else {			packshdr_t *pshdr = (packshdr_t *)(wxb->beg+offset+off);						len = packshdr_get_len(pshdr) - sizeof(packshdr_t);			fc = pshdr->fc;			fsn = pshdr->fsn;			off += sizeof(packshdr_t);		}		if ( is_fcfsn_valid(g_serviceflow[cid].fc, g_serviceflow[cid].fsn, fc, fsn, ext) ) {			g_serviceflow[cid].fc = fc;			g_serviceflow[cid].fsn = ext ? (fsn+1) & 0x7ff : (fsn+1) & 0x7;			if ( (_wxb = get_wxbuff(wxb)) == NULL )				goto clean;			_wxb->beg = wxb->beg + offset + off;			_wxb->end = _wxb->beg + len;			_wxb->len = len;			if ( softq_enque_tail(&g_softque[cid], _wxb) < 0 ) {				put_wxbuff(_wxb);				goto clean;			}			if ( fc == NO_FRAG || fc == LAST_FRAG ) {				uint32_t l = g_softque[cid].size;								_wxb = softq_dump(&g_softque[cid]);				_wxb->tolen = l;				_wxb->cid = cid;								if ( is_basic_cid(cid) || is_primary_cid(cid) || cid == 0 )					ringq_enque(&tq_sig_rx, &_wxb->senior);				else					ringq_enque(&tq_logger, &_wxb->senior);			}		}		else {			//g_serviceflow[cid].fc = NO_FRAGMENTATION;			struct list_head hdr, *pos, *tmp;					clean:			if ( (_wxb = softq_dump(&g_softque[cid])) ) {				list_add_tail(&hdr, &_wxb->junior);				list_for_each_safe(pos, tmp, &hdr) {					_wxb = list_entry(pos, wxbuff_t, junior);					put_wxbuff(_wxb);				}			}		}		off += len;	}	return;}void grantmngshdr_decode(uint8_t *buffer, uint16_t cid){	grantmngshdr_t *hdr = (grantmngshdr_t *)buffer;	if ( g_serviceflow[cid].service_flow_scheduling_type == UPLINK_GRANT_SCHEDULING_TYPE_UGS) {	}	else if ( g_serviceflow[cid].service_flow_scheduling_type == UPLINK_GRANT_SCHEDULING_TYPE_ERTPS) {	}	else {				g_serviceflow[cid].bwr += hdr->none.pbr;	}	return;}void macsignalinghdr1_decode(uint8_t *buffer){	uint16_t cid;	bwrmachdr_t *hdr = (bwrmachdr_t *)buffer;		cid = bwrmachdr_get_cid(hdr);	pthread_mutex_lock(&g_serviceflow[cid].mutex);	if ( g_serviceflow[cid].stat == SF_INVALID ) {		pthread_mutex_unlock(&g_serviceflow[cid].mutex);		return ;	}	pthread_mutex_unlock(&g_serviceflow[cid].mutex);	if ( hdr->type == BR_INCREMENTAL ) {		g_serviceflow[cid].bwr	+= bwrmachdr_get_bwr(hdr);		g_serviceflow[cid]._bwr += bwrmachdr_get_bwr(hdr);	}	else if ( hdr->type == BR_AGGREGATE ) {		g_serviceflow[cid].bwr	= bwrmachdr_get_bwr(hdr);		g_serviceflow[cid]._bwr += bwrmachdr_get_bwr(hdr);	}	else if ( hdr->type == PHY_CHANNEL_REPORT ) {		/* not implemented yet */	}	else if ( hdr->type == BR_WITH_UL_TX_POWER_REPORT ) {		/* not implemented yet */	}	else if ( hdr->type == BANDWIDTH_REQUEST_AND_CINR_REPORT ) {		/* not implemented yet */	}	else if ( hdr->type == BR_WITH_UL_SLEEP_CONTROL ) {		/* not implemented yet */	}	else if ( hdr->type == SN_REPORT ) {		/* not implemented yet */	}	else if ( hdr->type == CQICH_ALLOCATION_REQUEST ) {		/* not implemented yet */	}	return;}void macsignalinghdr2_decode(uint8_t *buffer){}

⌨️ 快捷键说明

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