📄 sig.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 <time.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <netinet/in.h>#include "task.h"#include "list.h"#include "Mac.h"#include "wxsched.h"#include "bitops.h"#include "wxbuff.h"#include "wxtimer.h"static void bs_fsm(uint8_t *packet, uint32_t length);static void ss_fsm(ssinfo_t *ss, uint8_t *packet, uint32_t length);static void ss_ranging_fsm(ssinfo_t *ss, uint8_t *packet, uint32_t length);/*static*/ void transmit_dcd(uint32_t arga, void *argb);/*static*/ void transmit_ucd(uint32_t arga, void *argb);static int32_t build_dcd(uint8_t *buf, uint32_t len, dcdinfo_t *dcdinfo, struct burstpf_set *bp);static int32_t build_ucd(uint8_t *buf, uint32_t len, ucdinfo_t *ucdinfo, struct burstpf_set *bp);static int32_t tlv_encoding(uint8_t *buf, uint32_t len, uint8_t t, uint32_t l, uint8_t *v);static uint8_t *burstpf_encoding(uint32_t *len, uint8_t doru, uint8_t code, uint8_t xiuc, uint32_t tlvmask, struct burstpf_set *bp);static int32_t build_rngrsp(uint8_t *buf, uint32_t len, rngrspinfo_t *rngrspinfo);static void do_release_ss(uint32_t arga, void *argb);/* `bs_start' is the first function invoked after accomplishing all * the initialization job of base station. */void bs_start(){ transmit_dcd(0, NULL); //start_timer(get_timer(WXTIMER_PERIODIC, g_bsinfo.dcd_interval, 0, NULL, transmit_dcd)); start_timer(get_timer(WXTIMER_PERIODIC, 200, 0, NULL, transmit_dcd)); transmit_ucd(0, NULL); //start_timer(get_timer(WXTIMER_PERIODIC, g_bsinfo.ucd_interval, 0, NULL, transmit_ucd)); start_timer(get_timer(WXTIMER_PERIODIC, 200, 0, NULL, transmit_ucd));}void * do_task_sig(void *arg){ struct list_head *pkt_ptr; wxbuff_t *pkt; uint8_t *packet; uint32_t length; uint16_t cid; bs_start(); //#if 0 for ( ; ; ) { pkt_ptr = ringq_deque(&tq_sig_rx); pkt = list_entry(pkt_ptr, wxbuff_t, junior); cid = pkt->cid; packet = copy_and_free_wxbuff(pkt, &length); if ( ! packet ) continue; if ( cid == 0 ) bs_fsm(packet, length); else ss_fsm(&g_ssinfo[g_serviceflow[cid].ss], packet, length); free(packet); } //#endif return NULL;}void bs_fsm(uint8_t *packet, uint32_t length){ macmsghdr_t *hdr = (macmsghdr_t *)packet; switch ( hdr->msgtype ) { case CDMA_CODE : { wxbuff_t *rngrsp; /* here, arbitrate whether or not this code is quarlified, and generate the actual * ranging status of this code. But currently, each CDMA_RANGING_CODE will get * a "successful" RNG-RSP. */ if ( (rngrsp = get_wxbuff(NULL)) != NULL ) { rngrspinfo_t rngrspinfo; memset(&rngrspinfo, 0, sizeof(rngrspinfo_t)); rngrspinfo.ranging_status = SUCCESS; __set_bit(RNGRSP_TLVMASK_Ranging_Status, (volatile unsigned long *)rngrspinfo.tlvmask); build_rngrsp(rngrsp->beg, rngrsp->tail-rngrsp->beg, &rngrspinfo); softq_enque_tail(&g_softque[0], rngrsp); /* then let ul scheduling do his job if he get time */ post_cdmaie((cdmacode_t *)packet); } break; } case RNG_REQ : { ssinfo_t *ss; wxbuff_t *rngrsp; //ss = process_rng_req(packet, length, 0); /* here, ss state is SS_INVALID */ /* here, will arbitrate whether or not this new ss is qualified, such as the total * load of bs is still very healthy, or the downlink/uplink status is quite good. * but currently, each ss will be accepted. */ ss->stat = SS_RANGING; ss->substat = SS_SBCREQ_EXPECTING; pthread_mutex_lock(&g_bsinfo.mutex); list_add_tail(&ss->ranging_link, &g_bsinfo.ss_que[SS_RANGING]); g_bsinfo.nr_ranging++; pthread_mutex_unlock(&g_bsinfo.mutex); if ( (rngrsp = get_wxbuff(NULL)) != NULL ) { //build_rng_rsp(rngrsp, ss); softq_enque_tail(&g_softque[0], rngrsp); } ss->timer[9] = get_timer(WXTIMER_PERIODIC, 3000, 0, ss, do_release_ss); start_timer(ss->timer[9]); break; } default : break; } return;}void ss_fsm(ssinfo_t *ss, uint8_t *packet, uint32_t length){ switch ( ss->stat ) { case SS_RANGING : ss_ranging_fsm(ss, packet, length); break; case SS_ACTIVE : break; case SS_HO : break; case SS_SLEEP : break; case SS_IDLE : break; default: break; } return;}void ss_ranging_fsm(ssinfo_t *ss, uint8_t *packet, uint32_t length){ macmsghdr_t *hdr = (macmsghdr_t *)packet; switch ( ss->substat ) { case SS_RNGREQ_EXPECTING : if ( hdr->msgtype == RNG_REQ ) { //process_rng_req(packet, length, ss->sf[0]->cid); /* here, will arbitrate whether or not this ss need additional adjustment. * but, currently just let it go. */ ss->substat = SS_SBCREQ_EXPECTING; } break; case SS_SBCREQ_EXPECTING : if ( hdr->msgtype == SBC_REQ ) { if ( ss->timer[9] != NULL ) { cancel_timer(ss->timer[9]); ss->timer[9] = NULL; } //process_sbc_req(packet, length, ss->sf[0]->cid); ss->substat = SS_REGREQ_EXPECTING; } break; case SS_REGREQ_EXPECTING : if ( hdr->msgtype == REG_REQ ) { //process_reg_req(packet, length, ss->sf[0]->cid); ss->stat = SS_ACTIVE; ss->substat = SS_NOTHING_TODO; pthread_mutex_lock(&g_bsinfo.mutex); list_del(&ss->ranging_link); g_bsinfo.nr_ranging--; list_add_tail(&ss->active_link, &g_bsinfo.ss_que[SS_ACTIVE]); g_bsinfo.nr_active++; pthread_mutex_unlock(&g_bsinfo.mutex); } break; } return;}void transmit_dcd(uint32_t arga, void *argb){ dcdinfo_t dcdinfo; struct burstpf_set *bp; wxbuff_t *dcd = get_wxbuff(NULL); pthread_mutex_lock(&g_bsinfo.mutex); bp = g_bsinfo.bp_active; pthread_mutex_unlock(&g_bsinfo.mutex); memset(&dcdinfo, 0, sizeof(dcdinfo_t)); dcdinfo.dcdhdr.hdr.msgtype = DCD; dcdinfo.dcdhdr.config_change_count = bp->count[0]; __set_bit(DCD_TLVMASK_Downlink_Burst_Profile, (volatile unsigned long *)&dcdinfo.tlvmask); __set_bit(DCD_TLVMASK_Channel_Nr, (volatile unsigned long *)&dcdinfo.tlvmask); __set_bit(DCD_TLVMASK_TTG, (volatile unsigned long *)&dcdinfo.tlvmask); __set_bit(DCD_TLVMASK_RTG, (volatile unsigned long *)&dcdinfo.tlvmask); __set_bit(DCD_TLVMASK_RSS_IR_max, (volatile unsigned long *)&dcdinfo.tlvmask); __set_bit(DCD_TLVMASK_Frequency, (volatile unsigned long *)&dcdinfo.tlvmask); __set_bit(DCD_TLVMASK_BS_ID, (volatile unsigned long *)&dcdinfo.tlvmask); __set_bit(DCD_TLVMASK_Frame_Duration_Code, (volatile unsigned long *)&dcdinfo.tlvmask); __set_bit(DCD_TLVMASK_Frame_Number, (volatile unsigned long *)&dcdinfo.tlvmask); __set_bit(DCD_TLVMASK_Maximum_retransmission, (volatile unsigned long *)&dcdinfo.tlvmask); __set_bit(DCD_TLVMASK_MAC_version, (volatile unsigned long *)&dcdinfo.tlvmask); if ( dcd != NULL ) { wxbuff_reserve(dcd, 64); dcd->len = build_dcd(dcd->beg, dcd->tail-dcd->beg, &dcdinfo, bp); dcd->end += dcd->len; softq_enque_tail(&g_softque[0xffff], dcd); } { time_t tm; time(&tm); fprintf(stdout, "transmit_dcd @ jiffies:%d, %s", jiffies, ctime(&tm)); } return;}void transmit_ucd(uint32_t arga, void *argb){ ucdinfo_t ucdinfo; struct burstpf_set *bp; wxbuff_t *ucd = get_wxbuff(NULL); pthread_mutex_lock(&g_bsinfo.mutex); bp = g_bsinfo.bp_active; pthread_mutex_unlock(&g_bsinfo.mutex); memset(&ucdinfo, 0, sizeof(ucdinfo_t)); ucdinfo.ucdhdr.hdr.msgtype = UCD; ucdinfo.ucdhdr.config_change_count = bp->count[1]; ucdinfo.ucdhdr.ranging_backoff_start = g_bsinfo.ranging_backoff_start; ucdinfo.ucdhdr.ranging_backoff_end = g_bsinfo.ranging_backoff_end; ucdinfo.ucdhdr.request_backoff_start = g_bsinfo.request_backoff_start; ucdinfo.ucdhdr.request_backoff_end = g_bsinfo.request_backoff_end; __set_bit(UCD_TLVMASK_Uplink_Burst_Profile, (volatile unsigned long *)&ucdinfo.tlvmask); __set_bit(UCD_TLVMASK_Frequency, (volatile unsigned long *)&ucdinfo.tlvmask); __set_bit(UCD_TLVMASK_Initial_ranging_codes, (volatile unsigned long *)&ucdinfo.tlvmask); __set_bit(UCD_TLVMASK_Periodic_ranging_codes, (volatile unsigned long *)&ucdinfo.tlvmask); __set_bit(UCD_TLVMASK_Bandwidth_request_codes, (volatile unsigned long *)&ucdinfo.tlvmask); __set_bit(UCD_TLVMASK_Periodic_ranging_backoff_start, (volatile unsigned long *)&ucdinfo.tlvmask); __set_bit(UCD_TLVMASK_Periodic_ranging_backoff_end, (volatile unsigned long *)&ucdinfo.tlvmask); __set_bit(UCD_TLVMASK_Start_of_ranging_codes_group, (volatile unsigned long *)&ucdinfo.tlvmask); __set_bit(UCD_TLVMASK_Maximum_retransimission, (volatile unsigned long *)&ucdinfo.tlvmask); if ( ucd != NULL ) { wxbuff_reserve(ucd, 64); ucd->len = build_ucd(ucd->beg, ucd->tail-ucd->beg, &ucdinfo, bp); ucd->end += ucd->len; softq_enque_tail(&g_softque[0xffff], ucd); } { time_t tm; time(&tm); fprintf(stdout, "transmit_ucd @ jiffies:%d, %s", jiffies, ctime(&tm)); } return;}/* return: the actual length of bytes wrote into buf. */int32_t build_dcd(uint8_t *buf, uint32_t len, dcdinfo_t *dcd, struct burstpf_set *bp){ uint32_t off = 0, n = 0; uint8_t t; uint32_t l; void *v; uint16_t be2; uint32_t be4, tlvmask = 0; int32_t i; memcpy(buf+off, &dcd->dcdhdr, sizeof(dcd->dcdhdr)); off += sizeof(dcd->dcdhdr); while ( ! (dcd->tlvmask[0] == 0 && dcd->tlvmask[1] == 0) ) { if ( ! __test_and_clear_bit(n++, (volatile unsigned long *)dcd->tlvmask) ) continue; switch ( n-1 ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -