예제 #1
0
static void smt_send_sif_config(struct s_smc *smc, struct fddi_addr *dest,
				u_long tid, int local)
/* struct fddi_addr *dest;	dest address */
/* u_long tid;			transaction id */
{
	struct smt_sif_config	*sif ;
	SMbuf			*mb ;
	int			len ;
	if (!(mb = smt_build_frame(smc,SMT_SIF_CONFIG,SMT_REPLY,
		SIZEOF_SMT_SIF_CONFIG)))
		return ;

	sif = smtod(mb, struct smt_sif_config *) ;
	smt_fill_timestamp(smc,&sif->ts) ;	/* set time stamp */
	smt_fill_sde(smc,&sif->sde) ;		/* set station descriptor */
	smt_fill_version(smc,&sif->version) ;	/* set version information */
	smt_fill_state(smc,&sif->state) ;	/* set state information */
	smt_fill_policy(smc,&sif->policy) ;	/* set station policy */
	smt_fill_latency(smc,&sif->latency);	/* set station latency */
	smt_fill_neighbor(smc,&sif->neighbor);	/* set station neighbor */
	smt_fill_setcount(smc,&sif->setcount) ;	/* set count */
	len = smt_fill_path(smc,&sif->path);	/* set station path descriptor*/
	sif->smt.smt_dest = *dest ;		/* destination address */
	sif->smt.smt_tid = tid ;		/* transaction ID */
	smt_add_frame_len(mb,len) ;		/* adjust length fields */
	dump_smt(smc,(struct smt_header *)sif,"SIF Configuration Reply") ;
	smt_send_frame(smc,mb,FC_SMT_INFO,local) ;
}
예제 #2
0
static void smt_send_sif_config(struct s_smc *smc, struct fddi_addr *dest,
				u_long tid, int local)


{
	struct smt_sif_config	*sif ;
	SMbuf			*mb ;
	int			len ;
	if (!(mb = smt_build_frame(smc,SMT_SIF_CONFIG,SMT_REPLY,
		SIZEOF_SMT_SIF_CONFIG)))
		return ;

	sif = smtod(mb, struct smt_sif_config *) ;
	smt_fill_timestamp(smc,&sif->ts) ;	
	smt_fill_sde(smc,&sif->sde) ;		
	smt_fill_version(smc,&sif->version) ;	
	smt_fill_state(smc,&sif->state) ;	
	smt_fill_policy(smc,&sif->policy) ;	
	smt_fill_latency(smc,&sif->latency);	
	smt_fill_neighbor(smc,&sif->neighbor);	
	smt_fill_setcount(smc,&sif->setcount) ;	
	len = smt_fill_path(smc,&sif->path);	
	sif->smt.smt_dest = *dest ;		
	sif->smt.smt_tid = tid ;		
	smt_add_frame_len(mb,len) ;		
	dump_smt(smc,(struct smt_header *)sif,"SIF Configuration Reply") ;
	smt_send_frame(smc,mb,FC_SMT_INFO,local) ;
}
예제 #3
0
파일: srf.c 프로젝트: johnny/CobraDroidBeta
/*
 * build and send SMT SRF frame
 */
static void smt_send_srf(struct s_smc *smc)
{

	struct smt_header	*smt ;
	struct s_srf_evc	*evc ;
	SK_LOC_DECL(struct s_pcon,pcon) ;
	SMbuf			*mb ;
	int			i ;

	static const struct fddi_addr SMT_SRF_DA = {
		{ 0x80, 0x01, 0x43, 0x00, 0x80, 0x08 }
	} ;

	/*
	 * build SMT header
	 */
	if (!smc->r.sm_ma_avail)
		return ;
	if (!(mb = smt_build_frame(smc,SMT_SRF,SMT_ANNOUNCE,0)))
		return ;

	RS_SET(smc,RS_SOFTERROR) ;

	smt = smtod(mb, struct smt_header *) ;
	smt->smt_dest = SMT_SRF_DA ;		/* DA == SRF multicast */

	/*
	 * setup parameter status
	 */
	pcon.pc_len = SMT_MAX_INFO_LEN ;	/* max para length */
	pcon.pc_err = 0 ;			/* no error */
	pcon.pc_badset = 0 ;			/* no bad set count */
	pcon.pc_p = (void *) (smt + 1) ;	/* paras start here */

	smt_add_para(smc,&pcon,(u_short) SMT_P1033,0,0) ;
	smt_add_para(smc,&pcon,(u_short) SMT_P1034,0,0) ;

	for (i = 0, evc = smc->evcs ; (unsigned) i < MAX_EVCS ; i++, evc++) {
		if (evc->evc_rep_required) {
			smt_add_para(smc,&pcon,evc->evc_para,
				(int)evc->evc_index,0) ;
		}
	}
	smt->smt_len = SMT_MAX_INFO_LEN - pcon.pc_len ;
	mb->sm_len = smt->smt_len + sizeof(struct smt_header) ;

	DB_SMT("SRF: sending SRF at %x, len %d \n",smt,mb->sm_len) ;
	DB_SMT("SRF: state SR%d Threshold %d\n",
		smc->srf.sr_state,smc->srf.SRThreshold/TICKS_PER_SECOND) ;
#ifdef	DEBUG
	dump_smt(smc,smt,"SRF Send") ;
#endif
	smt_send_frame(smc,mb,FC_SMT_INFO,0) ;
	clear_reported(smc) ;
}
예제 #4
0
static void smt_send_sif_operation(struct s_smc *smc, struct fddi_addr *dest,
				   u_long tid, int local)
/* struct fddi_addr *dest;	dest address */
/* u_long tid;			transaction id */
{
	struct smt_sif_operation *sif ;
	SMbuf			*mb ;
	int			ports ;
	int			i ;

	ports = NUMPHYS ;
#ifndef	CONCENTRATOR
	if (smc->s.sas == SMT_SAS)
		ports = 1 ;
#endif

	if (!(mb = smt_build_frame(smc,SMT_SIF_OPER,SMT_REPLY,
		SIZEOF_SMT_SIF_OPERATION+ports*sizeof(struct smt_p_lem))))
		return ;
	sif = smtod(mb, struct smt_sif_operation *) ;
	smt_fill_timestamp(smc,&sif->ts) ;	/* set time stamp */
	smt_fill_mac_status(smc,&sif->status) ; /* set mac status */
	smt_fill_mac_counter(smc,&sif->mc) ; /* set mac counter field */
	smt_fill_mac_fnc(smc,&sif->fnc) ; /* set frame not copied counter */
	smt_fill_manufacturer(smc,&sif->man) ; /* set manufacturer field */
	smt_fill_user(smc,&sif->user) ;		/* set user field */
	smt_fill_setcount(smc,&sif->setcount) ;	/* set count */
	/*
	 * set link error mon information
	 */
	if (ports == 1) {
		smt_fill_lem(smc,sif->lem,PS) ;
	}
	else {
		for (i = 0 ; i < ports ; i++) {
			smt_fill_lem(smc,&sif->lem[i],i) ;
		}
	}

	sif->smt.smt_dest = *dest ;	/* destination address */
	sif->smt.smt_tid = tid ;	/* transaction ID */
	dump_smt(smc,(struct smt_header *)sif,"SIF Operation Reply") ;
	smt_send_frame(smc,mb,FC_SMT_INFO,local) ;
}
예제 #5
0
static void smt_send_ecf(struct s_smc *smc, struct fddi_addr *dest, int fc,
			 u_long tid, int type, int len)





{
	struct smt_ecf	*ecf ;
	SMbuf		*mb ;

	if (!(mb = smt_build_frame(smc,SMT_ECF,type,SMT_ECF_LEN + len)))
		return ;
	ecf = smtod(mb, struct smt_ecf *) ;

	smt_fill_echo(smc,&ecf->ec_echo,tid,len) ;	
	ecf->smt.smt_dest = *dest ;	
	ecf->smt.smt_tid = tid ;	
	smc->mib.priv.fddiPRIVECF_Req_Tx++ ;
	smt_send_frame(smc,mb,fc,0) ;
}
예제 #6
0
static void smt_send_ecf(struct s_smc *smc, struct fddi_addr *dest, int fc,
			 u_long tid, int type, int len)
/* struct fddi_addr *dest;	dest address */
/* int fc;			frame control */
/* u_long tid;			transaction id */
/* int type;			frame type */
/* int len;			frame length */
{
	struct smt_ecf	*ecf ;
	SMbuf		*mb ;

	if (!(mb = smt_build_frame(smc,SMT_ECF,type,SMT_ECF_LEN + len)))
		return ;
	ecf = smtod(mb, struct smt_ecf *) ;

	smt_fill_echo(smc,&ecf->ec_echo,tid,len) ;	/* set ECHO */
	ecf->smt.smt_dest = *dest ;	/* destination address */
	ecf->smt.smt_tid = tid ;	/* transaction ID */
	smc->mib.priv.fddiPRIVECF_Req_Tx++ ;
	smt_send_frame(smc,mb,fc,0) ;
}
예제 #7
0
static void smt_send_nif(struct s_smc *smc, const struct fddi_addr *dest, 
			 int fc, u_long tid, int type, int local)




{
	struct smt_nif	*nif ;
	SMbuf		*mb ;

	if (!(mb = smt_build_frame(smc,SMT_NIF,type,sizeof(struct smt_nif))))
		return ;
	nif = smtod(mb, struct smt_nif *) ;
	smt_fill_una(smc,&nif->una) ;	
	smt_fill_sde(smc,&nif->sde) ;	
	smt_fill_state(smc,&nif->state) ;	
#ifdef	SMT6_10
	smt_fill_fsc(smc,&nif->fsc) ;	
#endif
	nif->smt.smt_dest = *dest ;	
	nif->smt.smt_tid = tid ;	
	dump_smt(smc,(struct smt_header *)nif,"NIF") ;
	smt_send_frame(smc,mb,fc,local) ;
}
예제 #8
0
static void smt_send_nif(struct s_smc *smc, const struct fddi_addr *dest, 
			 int fc, u_long tid, int type, int local)
/* struct fddi_addr *dest;	dest address */
/* int fc;			frame control */
/* u_long tid;			transaction id */
/* int type;			frame type */
{
	struct smt_nif	*nif ;
	SMbuf		*mb ;

	if (!(mb = smt_build_frame(smc,SMT_NIF,type,sizeof(struct smt_nif))))
		return ;
	nif = smtod(mb, struct smt_nif *) ;
	smt_fill_una(smc,&nif->una) ;	/* set UNA */
	smt_fill_sde(smc,&nif->sde) ;	/* set station descriptor */
	smt_fill_state(smc,&nif->state) ;	/* set state information */
#ifdef	SMT6_10
	smt_fill_fsc(smc,&nif->fsc) ;	/* set frame status cap. */
#endif
	nif->smt.smt_dest = *dest ;	/* destination address */
	nif->smt.smt_tid = tid ;	/* transaction ID */
	dump_smt(smc,(struct smt_header *)nif,"NIF") ;
	smt_send_frame(smc,mb,fc,local) ;
}
예제 #9
0
static void ess_send_alc_req(struct s_smc *smc)
{
	struct smt_sba_alc_req *req ;
	SMbuf	*mb ;

	if (!smc->mib.fddiESSPayload) {
		smc->mib.fddiESSOverhead = 0 ;
	}
	else {
		if (!smc->mib.fddiESSOverhead)
			smc->mib.fddiESSOverhead = DEFAULT_OV ;
	}

	if (smc->mib.fddiESSOverhead ==
		smc->mib.a[PATH0].fddiPATHSbaOverhead &&
		smc->mib.fddiESSPayload ==
		smc->mib.a[PATH0].fddiPATHSbaPayload){
		smc->ess.raf_act_timer_poll = FALSE ;
		smc->ess.timer_count = 7 ;	
		return ;
	}
	
	if (!(mb=smt_build_frame(smc,SMT_RAF,SMT_REQUEST,
			sizeof(struct smt_sba_alc_req))))
			return ;
	req = smtod(mb,struct smt_sba_alc_req *) ;
	req->smt.smt_tid = smc->ess.alloc_trans_id = smt_get_tid(smc) ;
	req->smt.smt_dest = smt_sba_da ;

	
	req->s_type.para.p_type = SMT_P0015 ;
	req->s_type.para.p_len = sizeof(struct smt_p_0015) - PARA_LEN ;
	req->s_type.res_type = SYNC_BW ;

	
	req->cmd.para.p_type = SMT_P0016 ;
	req->cmd.para.p_len = sizeof(struct smt_p_0016) - PARA_LEN ;
	req->cmd.sba_cmd = REQUEST_ALLOCATION ;


	
	req->path.para.p_type = SMT_P320B ;
	req->path.para.p_len = sizeof(struct smt_p_320b) - PARA_LEN ;
	req->path.mib_index = SBAPATHINDEX ;
	req->path.path_pad = 0;
	req->path.path_index = PRIMARY_RING ;

	
	req->pl_req.para.p_type = SMT_P0017 ;
	req->pl_req.para.p_len = sizeof(struct smt_p_0017) - PARA_LEN ;
	req->pl_req.sba_pl_req = smc->mib.fddiESSPayload -
		smc->mib.a[PATH0].fddiPATHSbaPayload ;

	
	req->ov_req.para.p_type = SMT_P0018 ;
	req->ov_req.para.p_len = sizeof(struct smt_p_0018) - PARA_LEN ;
	req->ov_req.sba_ov_req = smc->mib.fddiESSOverhead -
		smc->mib.a[PATH0].fddiPATHSbaOverhead ;

	
	req->payload.para.p_type = SMT_P320F ;
	req->payload.para.p_len = sizeof(struct smt_p_320f) - PARA_LEN ;
	req->payload.mib_index = SBAPATHINDEX ;
	req->payload.mib_payload = smc->mib.a[PATH0].fddiPATHSbaPayload ;

	
	req->overhead.para.p_type = SMT_P3210 ;
	req->overhead.para.p_len = sizeof(struct smt_p_3210) - PARA_LEN ;
	req->overhead.mib_index = SBAPATHINDEX ;
	req->overhead.mib_overhead = smc->mib.a[PATH0].fddiPATHSbaOverhead ;

	
	req->a_addr.para.p_type = SMT_P0019 ;
	req->a_addr.para.p_len = sizeof(struct smt_p_0019) - PARA_LEN ;
	req->a_addr.sba_pad = 0;
	req->a_addr.alloc_addr = null_addr ;

	
	req->cat.para.p_type = SMT_P001A ;
	req->cat.para.p_len = sizeof(struct smt_p_001a) - PARA_LEN ;
	req->cat.category = smc->mib.fddiESSCategory ;

	
	req->tneg.para.p_type = SMT_P001B ;
	req->tneg.para.p_len = sizeof(struct smt_p_001b) - PARA_LEN ;
	req->tneg.max_t_neg = smc->mib.fddiESSMaxTNeg ;

	
	req->segm.para.p_type = SMT_P001C ;
	req->segm.para.p_len = sizeof(struct smt_p_001c) - PARA_LEN ;
	req->segm.min_seg_siz = smc->mib.fddiESSMinSegmentSize ;

	dump_smt(smc,(struct smt_header *)req,"RAF") ;
	ess_send_frame(smc,mb) ;
}
예제 #10
0
static void ess_send_response(struct s_smc *smc, struct smt_header *sm,
			      int sba_cmd)
{
	struct smt_sba_chg	*chg ;
	SMbuf			*mb ;
	void			*p ;

	if (sba_cmd == CHANGE_ALLOCATION) {
		if (!(mb=smt_build_frame(smc,SMT_RAF,SMT_REPLY,
				sizeof(struct smt_sba_chg))))
				return ;
	}
	else {
		if (!(mb=smt_build_frame(smc,SMT_RAF,SMT_REPLY,
				sizeof(struct smt_sba_rep_res))))
				return ;
	}

	chg = smtod(mb,struct smt_sba_chg *) ;
	chg->smt.smt_tid = sm->smt_tid ;
	chg->smt.smt_dest = sm->smt_source ;

	
	chg->s_type.para.p_type = SMT_P0015 ;
	chg->s_type.para.p_len = sizeof(struct smt_p_0015) - PARA_LEN ;
	chg->s_type.res_type = SYNC_BW ;

	
	chg->cmd.para.p_type = SMT_P0016 ;
	chg->cmd.para.p_len = sizeof(struct smt_p_0016) - PARA_LEN ;
	chg->cmd.sba_cmd = sba_cmd ;

	
	chg->path.para.p_type = SMT_P320B ;
	chg->path.para.p_len = sizeof(struct smt_p_320b) - PARA_LEN ;
	chg->path.mib_index = SBAPATHINDEX ;
	chg->path.path_pad = 0;
	chg->path.path_index = PRIMARY_RING ;

	
	chg->payload.para.p_type = SMT_P320F ;
	chg->payload.para.p_len = sizeof(struct smt_p_320f) - PARA_LEN ;
	chg->payload.mib_index = SBAPATHINDEX ;
	chg->payload.mib_payload = smc->mib.a[PATH0].fddiPATHSbaPayload ;

	
	chg->overhead.para.p_type = SMT_P3210 ;
	chg->overhead.para.p_len = sizeof(struct smt_p_3210) - PARA_LEN ;
	chg->overhead.mib_index = SBAPATHINDEX ;
	chg->overhead.mib_overhead = smc->mib.a[PATH0].fddiPATHSbaOverhead ;

	if (sba_cmd == CHANGE_ALLOCATION) {
		
		chg->cat.para.p_type = SMT_P001A ;
		chg->cat.para.p_len = sizeof(struct smt_p_001a) - PARA_LEN ;
		p = (void *) sm_to_para(smc,sm,SMT_P001A) ;
		chg->cat.category = ((struct smt_p_001a *)p)->category ;
	}
	dump_smt(smc,(struct smt_header *)chg,"RAF") ;
	ess_send_frame(smc,mb) ;
}
예제 #11
0
static void ess_send_alc_req(struct s_smc *smc)
{
	struct smt_sba_alc_req *req ;
	SMbuf	*mb ;

	/*
	 * send never allocation request where the requested payload and
	 * overhead is zero or deallocate bandwidth when no bandwidth is
	 * parsed
	 */
	if (!smc->mib.fddiESSPayload) {
		smc->mib.fddiESSOverhead = 0 ;
	}
	else {
		if (!smc->mib.fddiESSOverhead)
			smc->mib.fddiESSOverhead = DEFAULT_OV ;
	}

	if (smc->mib.fddiESSOverhead ==
		smc->mib.a[PATH0].fddiPATHSbaOverhead &&
		smc->mib.fddiESSPayload ==
		smc->mib.a[PATH0].fddiPATHSbaPayload){
		smc->ess.raf_act_timer_poll = FALSE ;
		smc->ess.timer_count = 7 ;	/* next RAF alc req after 3 s */
		return ;
	}

	/*
	 * get and initialize the response frame
	 */
	if (!(mb=smt_build_frame(smc,SMT_RAF,SMT_REQUEST,
			sizeof(struct smt_sba_alc_req))))
			return ;
	req = smtod(mb,struct smt_sba_alc_req *) ;
	req->smt.smt_tid = smc->ess.alloc_trans_id = smt_get_tid(smc) ;
	req->smt.smt_dest = smt_sba_da ;

	/* set P15 */
	req->s_type.para.p_type = SMT_P0015 ;
	req->s_type.para.p_len = sizeof(struct smt_p_0015) - PARA_LEN ;
	req->s_type.res_type = SYNC_BW ;

	/* set P16 */
	req->cmd.para.p_type = SMT_P0016 ;
	req->cmd.para.p_len = sizeof(struct smt_p_0016) - PARA_LEN ;
	req->cmd.sba_cmd = REQUEST_ALLOCATION ;

	/*
	 * set the parameter type and parameter length of all used
	 * parameters
	 */

	/* set P320B */
	req->path.para.p_type = SMT_P320B ;
	req->path.para.p_len = sizeof(struct smt_p_320b) - PARA_LEN ;
	req->path.mib_index = SBAPATHINDEX ;
	req->path.path_pad = 0;
	req->path.path_index = PRIMARY_RING ;

	/* set P0017 */
	req->pl_req.para.p_type = SMT_P0017 ;
	req->pl_req.para.p_len = sizeof(struct smt_p_0017) - PARA_LEN ;
	req->pl_req.sba_pl_req = smc->mib.fddiESSPayload -
		smc->mib.a[PATH0].fddiPATHSbaPayload ;

	/* set P0018 */
	req->ov_req.para.p_type = SMT_P0018 ;
	req->ov_req.para.p_len = sizeof(struct smt_p_0018) - PARA_LEN ;
	req->ov_req.sba_ov_req = smc->mib.fddiESSOverhead -
		smc->mib.a[PATH0].fddiPATHSbaOverhead ;

	/* set P320F */
	req->payload.para.p_type = SMT_P320F ;
	req->payload.para.p_len = sizeof(struct smt_p_320f) - PARA_LEN ;
	req->payload.mib_index = SBAPATHINDEX ;
	req->payload.mib_payload = smc->mib.a[PATH0].fddiPATHSbaPayload ;

	/* set P3210 */
	req->overhead.para.p_type = SMT_P3210 ;
	req->overhead.para.p_len = sizeof(struct smt_p_3210) - PARA_LEN ;
	req->overhead.mib_index = SBAPATHINDEX ;
	req->overhead.mib_overhead = smc->mib.a[PATH0].fddiPATHSbaOverhead ;

	/* set P19 */
	req->a_addr.para.p_type = SMT_P0019 ;
	req->a_addr.para.p_len = sizeof(struct smt_p_0019) - PARA_LEN ;
	req->a_addr.sba_pad = 0;
	req->a_addr.alloc_addr = null_addr ;

	/* set P1A */
	req->cat.para.p_type = SMT_P001A ;
	req->cat.para.p_len = sizeof(struct smt_p_001a) - PARA_LEN ;
	req->cat.category = smc->mib.fddiESSCategory ;

	/* set P1B */
	req->tneg.para.p_type = SMT_P001B ;
	req->tneg.para.p_len = sizeof(struct smt_p_001b) - PARA_LEN ;
	req->tneg.max_t_neg = smc->mib.fddiESSMaxTNeg ;

	/* set P1C */
	req->segm.para.p_type = SMT_P001C ;
	req->segm.para.p_len = sizeof(struct smt_p_001c) - PARA_LEN ;
	req->segm.min_seg_siz = smc->mib.fddiESSMinSegmentSize ;

	dump_smt(smc,(struct smt_header *)req,"RAF") ;
	ess_send_frame(smc,mb) ;
}
예제 #12
0
static void smt_send_rdf(struct s_smc *smc, SMbuf *rej, int fc, int reason,
			 int local)



{
	SMbuf	*mb ;
	struct smt_header	*sm ;	
	struct smt_rdf	*rdf ;
	int		len ;
	int		frame_len ;

	sm = smtod(rej,struct smt_header *) ;
	if (sm->smt_type != SMT_REQUEST)
		return ;

	DB_SMT("SMT: sending RDF to %s,reason = 0x%x\n",
		addr_to_string(&sm->smt_source),reason) ;


	
	frame_len = rej->sm_len ;

	if (!(mb=smt_build_frame(smc,SMT_RDF,SMT_REPLY,sizeof(struct smt_rdf))))
		return ;
	rdf = smtod(mb,struct smt_rdf *) ;
	rdf->smt.smt_tid = sm->smt_tid ;		
	rdf->smt.smt_dest = sm->smt_source ;		

	
	rdf->reason.para.p_type = SMT_P_REASON ;
	rdf->reason.para.p_len = sizeof(struct smt_p_reason) - PARA_LEN ;
	rdf->reason.rdf_reason = reason ;

	
	rdf->version.para.p_type = SMT_P_VERSION ;
	rdf->version.para.p_len = sizeof(struct smt_p_version) - PARA_LEN ;
	rdf->version.v_pad = 0 ;
	rdf->version.v_n = 1 ;
	rdf->version.v_index = 1 ;
	rdf->version.v_version[0] = SMT_VID_2 ;
	rdf->version.v_pad2 = 0 ;

	
	if ((unsigned) frame_len <= SMT_MAX_INFO_LEN - sizeof(*rdf) +
		2*sizeof(struct smt_header))
		len = frame_len ;
	else
		len = SMT_MAX_INFO_LEN - sizeof(*rdf) +
			2*sizeof(struct smt_header) ;
	
	len &= ~3 ;
	rdf->refused.para.p_type = SMT_P_REFUSED ;
	
	rdf->refused.para.p_len = len + 4 ;
	rdf->refused.ref_fc = fc ;

	
	smt_swap_para(sm,frame_len,0) ;

	memcpy((char *) &rdf->refused.ref_header,(char *) sm,len) ;

	len -= sizeof(struct smt_header) ;
	mb->sm_len += len ;
	rdf->smt.smt_len += len ;

	dump_smt(smc,(struct smt_header *)rdf,"RDF") ;
	smc->mib.priv.fddiPRIVRDF_Tx++ ;
	smt_send_frame(smc,mb,FC_SMT_INFO,local) ;
}
예제 #13
0
static void smt_send_rdf(struct s_smc *smc, SMbuf *rej, int fc, int reason,
			 int local)
/* SMbuf *rej;	mbuf of offending frame */
/* int fc;	FC of denied frame */
/* int reason;	reason code */
{
	SMbuf	*mb ;
	struct smt_header	*sm ;	/* header of offending frame */
	struct smt_rdf	*rdf ;
	int		len ;
	int		frame_len ;

	sm = smtod(rej,struct smt_header *) ;
	if (sm->smt_type != SMT_REQUEST)
		return ;

	DB_SMT("SMT: sending RDF to %s,reason = 0x%x\n",
		addr_to_string(&sm->smt_source),reason) ;


	/*
	 * note: get framelength from MAC length, NOT from SMT header
	 * smt header length is included in sm_len
	 */
	frame_len = rej->sm_len ;

	if (!(mb=smt_build_frame(smc,SMT_RDF,SMT_REPLY,sizeof(struct smt_rdf))))
		return ;
	rdf = smtod(mb,struct smt_rdf *) ;
	rdf->smt.smt_tid = sm->smt_tid ;		/* use TID from sm */
	rdf->smt.smt_dest = sm->smt_source ;		/* set dest = source */

	/* set P12 */
	rdf->reason.para.p_type = SMT_P_REASON ;
	rdf->reason.para.p_len = sizeof(struct smt_p_reason) - PARA_LEN ;
	rdf->reason.rdf_reason = reason ;

	/* set P14 */
	rdf->version.para.p_type = SMT_P_VERSION ;
	rdf->version.para.p_len = sizeof(struct smt_p_version) - PARA_LEN ;
	rdf->version.v_pad = 0 ;
	rdf->version.v_n = 1 ;
	rdf->version.v_index = 1 ;
	rdf->version.v_version[0] = SMT_VID_2 ;
	rdf->version.v_pad2 = 0 ;

	/* set P13 */
	if ((unsigned) frame_len <= SMT_MAX_INFO_LEN - sizeof(*rdf) +
		2*sizeof(struct smt_header))
		len = frame_len ;
	else
		len = SMT_MAX_INFO_LEN - sizeof(*rdf) +
			2*sizeof(struct smt_header) ;
	/* make length multiple of 4 */
	len &= ~3 ;
	rdf->refused.para.p_type = SMT_P_REFUSED ;
	/* length of para is smt_frame + ref_fc */
	rdf->refused.para.p_len = len + 4 ;
	rdf->refused.ref_fc = fc ;

	/* swap it back */
	smt_swap_para(sm,frame_len,0) ;

	memcpy((char *) &rdf->refused.ref_header,(char *) sm,len) ;

	len -= sizeof(struct smt_header) ;
	mb->sm_len += len ;
	rdf->smt.smt_len += len ;

	dump_smt(smc,(struct smt_header *)rdf,"RDF") ;
	smc->mib.priv.fddiPRIVRDF_Tx++ ;
	smt_send_frame(smc,mb,FC_SMT_INFO,local) ;
}