ssapunitdata.c

来自「ftam等标准协议服务器和客户端的源代码。」· C语言 代码 · 共 1,384 行 · 第 1/2 页

C
1,384
字号
 *  remote address has been binded on the socket.               * *								* *  This routine blocks until completion.			* *								* **************************************************************** */int     SUnitDataWriteV (sd, uv, si)int 	 sd;register struct udvec	*uv;{int 	 n, cc, len, j;SBV      smask;			 	/* signal save mask */int      result; 		 	/* write result     */register struct ssapblk *sb;	 	/* ssap ctl blk ptr */register struct ssapkt *s;struct TSAPdisconnect   tds;register struct TSAPdisconnect *td = &tds;struct udvec vvs[NSPUV];register struct udvec  *vv, *xv;#ifdef HULADEBUG	printf ("\n     in SUnitDataWriteV \n");	printf ("\n     writing on socket %d \n", sd);#endif    /*     * 	Check for missing parameters.     */    missing_udP (uv);    missing_udP (uv -> uv_base);    /*     *  Check user data.     */    n = 0;    for (vv = uv; vv -> uv_base; vv++)	n += vv -> uv_len;#ifdef HULADEBUG	printf ("\n     len of data in vectors = %d \n", n);#endif    if ( (n <= 0) || (n > UD_MAX_DATA) )	return susaplose (si,			  SC_PARAMETER,			  NULLCP,			  SuErrString(UDERR_ILLEGAL_UD_SIZE));    /*      *  Block any signals while we do the write.     */    smask = sigioblock ();    /*      *  Find the correct session block and set the signal mask.     */     ssap_udPsig (sb, sd);        /*     *  Init our working udvec struct.     */    vv = vvs;    vvs[0].uv_base = vvs[1].uv_base = NULL;    /*     *  Allocate a new UNITDATA spkt for this datagram message.     */#ifdef HULADEBUG	printf ("\n     allocating new SPKT \n");#endif    if ((s = newspkt (SPDU_UD)) == NULL)        return susaplose (si,			  SC_CONGEST,			  NULLCP,			  SuErrString(UDERR_NO_MEMORY));    /*     *  Set the parameter field values in the spkt for encoding.     */    s -> s_mask |= (SMASK_SPDU_UD | SMASK_UD_VERSION);    s -> s_ud_version = sb -> sb_version;    if (sb -> sb_initiating.sa_selectlen > 0)        {	s -> s_mask |= SMASK_UD_CALLING;	bcopy (sb -> sb_initiating.sa_selector, s -> s_ud_calling,	        s -> s_ud_callinglen = sb -> sb_initiating.sa_selectlen);	}    if (sb -> sb_responding.sa_selectlen > 0) 	{	s -> s_mask |= SMASK_UD_CALLED;	bcopy (sb -> sb_responding.sa_selector, s -> s_ud_called,		s -> s_ud_calledlen = sb -> sb_responding.sa_selectlen);    	}#ifdef HULADEBUG		spkt2text (stdout, s, NULL);#endif    /*     *  Format the session protocol data unit.     *  The encode routine will put the SPDU header in the base     *  portion of the work udvec[0] passed to it.     */#ifdef HULADEBUG		printf ("\n     formatting the unitdata SPDU \n");#endif     if (spkt2tsdu (s, &vv -> uv_base, &vv -> uv_len) == NOTOK)        {	susaplose (si,		   SC_PROTOCOL,		   NULLCP,		   SuErrString(UDERR_ENCODE_UDSPDU_FAILED));	freespkt (s);	return NOTOK;	}#ifdef HULADEBUG	for (j = 0; j < vv->uv_len; j++)	    printf ( " %x ", *(vv->uv_base + j) );#endif		    /*     *  Now copy the user udvec to the work udvec.  The SPDU UD header     *  was encoded and put as the 1st base element so start the copy      *  from there. Note:  we just copy the pointers to the user info.     */    xv = ++vv;#ifdef HULADEBUG	printf ("\n     header len in [1] = %d \n", xv->uv_len);#endif	    len = n;    for (vv = uv; vv -> uv_base; vv++, xv++)	{	/*	 *  Copy the user base to the work base.	 */	xv -> uv_base = vv -> uv_base;        xv -> uv_len  = vv -> uv_len;	len -= vv -> uv_len;#ifdef HULADEBUG	printf ("\n     in copy...len = %d \n", xv->uv_len);#endif		}    if (len > 0)	{	susaplose (si,		   SC_PARAMETER,		   NULLCP,		   SuErrString(UDERR_TOO_MANY_VECTORS));	freespkt (s);        if (vvs[0].uv_base)	    free (vvs[0].uv_base);	return NOTOK;	}	    /*     *  Set the last base to NULL (by convention to signal end).     */    xv -> uv_base = NULL;    xv -> uv_len = 0;    freespkt (s);    s = NULL;   /*    *  Do the unit data write over the TSAP unitdata service.    */#ifdef HULADEBUG	printf ("\n     calling the TSAP unitdata write \n");	for (j = 0; j < vvs[0].uv_len; j++)	    printf ( " %x ", *((vvs[0].uv_base) + j) );	for (j = 0; j < 25; j++)	    printf ( " %x ", *((vvs[1].uv_base) + j) );#endif    if ( (result = TUnitDataWrite (sb -> sb_fd, vvs, td)) == NOTOK)        ts2suslose (si, "TUnitDataWrite", td);    /*       *  Free the encoded header.     */	    free (vvs[0].uv_base);    /*    *  Restore the mask.    */    (void) sigiomask (smask);    if (result == NOTOK)    	return NOTOK;    else        return OK;}/*  */ /* **************************************************************** *								* *  SUnitDataRead						* *  								* *  This routine is the high-level routine that reads datagram  * *  messages from the tsap unit data service.  It calls the     * *  auxilliary routine that does the actual read.               * *								* *  returns:  OK, NOTOK, DONE 	 				* *								* **************************************************************** */int	SUnitDataRead (sd, sud, secs, si)int	sd;struct  SuSAPstart     *sud;int	secs;struct  SSAPindication *si;{    SBV	    smask;    int     result;    register struct ssapblk *sb;    register struct TSAPunitdata tx;#ifdef HULADEBUG	printf ("\n     in SUnitDataRead \n");	printf ("\n     reading on socket %d \n", sd);#endif    missing_udP (sud);    missing_udP (si);    /*      *  Block any signals while we do the read.     */    smask = sigioblock ();    /*      *  Find the correct session block and set the signal mask.     */     ssap_udPsig (sb, sd);    /*      *  Do the unitdata read.      */        result = SUnitDataReadAux (sb, sud, secs, si, SSAP_NOT_ASYNC, &tx);    /*     *  Restore the mask.     */    (void) sigiomask (smask);    /*     *  Return the result.     */    return result;}/*  */ /* **************************************************************** *								* *  SUnitDataReadAux						* *  								* *  This routine is the low-level routine that does tha actual  * *  unitdata read from the tsap.  It blocks until data is read  * *  or secs expires.  If secs is 0, it blocks indefinitely.	* *								* *  returns:  OK, NOTOK 					* *								* **************************************************************** */static int  SUnitDataReadAux (sb, sud, secs, si, async, tud)register struct ssapblk *sb;register struct SuSAPstart *sud;int	secs;struct SSAPindication *si;int	async;register struct TSAPunitdata   *tud;{    register struct ssapkt *s;#ifdef HULADEBUG	printf ("\n     in SUnitDataReadAux \n");#endif    /*     *  Ready the sap unitdata structure for receive.     */    bzero ((char *) sud, sizeof *sud);    bzero ((char *) si, sizeof *si);    for ( ; (s = sb2udspkt (sb, si, secs, tud)) != NULL; )	{	if (!(s -> s_mask & SMASK_SPDU_UD))	    break;	if (sb -> sb_len > 0)	    {	    switch (s -> s_code)	 	{		case SPDU_UD:		    if (s -> s_mask & SMASK_SPDU_UD)			break;		default:    		    freespkt (s);		    return susaplose (si,				      SC_PROTOCOL,				      NULLCP,				      SuErrString(UDERR_UNEXPECTED_SPDU_TYPE));	        }#ifdef HULADEBUG	printf ("\n     got a UNITDATA SPDU \n");	for (secs=0; secs < 25; secs++)	    printf (" %x ", *(tud->tud_qbuf.qb_data + secs) );#endif	    	    sb -> sb_code = s -> s_code;	    /*              *  Format the unitdata indication.	     */	    sud -> ss_sd = sb -> sb_fd;	    /*               *  Copy the TSAP addresses.	     */	    bcopy (&tud -> tud_calling, 		   &sud -> ss_calling.sa_addr, 		   sizeof (sud -> ss_calling.sa_addr) );	    bcopy (&tud -> tud_called,		   &sud -> ss_called.sa_addr,		   sizeof (sud -> ss_called.sa_addr) );			    	    /*             *  Copy the SSAP selectors.	     */       	    sud -> ss_calling.sa_selectlen = s -> s_ud_callinglen;	    bcopy (s -> s_ud_calling, 		   sud -> ss_calling.sa_selector, 		   		   s -> s_ud_callinglen);       	    sud -> ss_called.sa_selectlen = s -> s_ud_calledlen;	    bcopy (s -> s_ud_called,		   sud -> ss_called.sa_selector,		   s -> s_ud_calledlen);	   /*            *  Copy in the data and misc.	    */			    sud -> ss_ssdusize = UD_MAX_DATA;	    sud -> ss_version = s -> s_ud_version;	    sud -> ss_cc = tud -> tud_qbuf.qb_len;	    sud -> ss_data = tud -> tud_qbuf.qb_data;	    sud -> ss_base = tud -> tud_base;	    sb -> sb_len = 0;	    freespkt (s);	    return OK;	    }  /* end if > 0 */	   /*	    *  Check if timeout with no data on read.	    */	    if (si -> si_abort.sa_reason == SC_TIMER)	        	        break;    	}   /* end for loop */    if (si -> si_abort.sa_reason == SC_TIMER)	{	sud -> ss_cc = 0;	sud -> ss_data = NULL;	sud -> ss_base = NULL;	return OK;	}    return NOTOK;}#if FALSE/*    define vectors for INDICATION events */int	SSetIndications (sd, data, tokens, sync, activity, report, finish,		abort, si)int	sd;IFP	data,		tokens,	sync,	activity,	report,	finish,	abort;struct SSAPindication *si;{    SBV     smask;    register struct ssapblk *sb;    struct TSAPdisconnect   tds;    register struct TSAPdisconnect *td = &tds;    if (data || tokens || sync || activity || report || finish || abort) {	missingP (data);	missingP (tokens);	missingP (sync);	missingP (activity);	missingP (report);	missingP (finish);	missingP (abort);    }    smask = sigioblock ();    ssapPsig (sb, sd);    if (TSetIndications (sb -> sb_fd, TDATAser, TDISCser, td) == NOTOK)	if (td -> td_reason == DR_WAITING)	    return ssaplose (si, SC_WAITING, NULLCP, NULLCP);	else	    return ts2sslose (si, "TSetIndications", td);    if (sb -> sb_DataIndication = data)	sb -> sb_flags |= SB_ASYN;    else	sb -> sb_flags &= ~SB_ASYN;    sb -> sb_TokenIndication = tokens;    sb -> sb_SyncIndication = sync;    sb -> sb_ActivityIndication = activity;    sb -> sb_ReportIndication = report;    sb -> sb_ReleaseIndication = finish;    sb -> sb_AbortIndication = abort;    (void) sigiomask (smask);    return OK;}#endif/*  */struct ssapkt   *sb2udspkt (sb, si, secs, tud)register struct ssapblk *sb;register struct SSAPindication *si;int     secs;register struct TSAPunitdata   *tud;{    int     			cc;    register struct ssapkt   	*s;    struct TSAPdisconnect  	tds;    register struct TSAPdisconnect *td = &tds;    /*     *  Read the tsap datagram.     */#ifdef HULADEBUG	printf ("\n     calling TUnitDataRead \n");#endif    if (TUnitDataRead (sb -> sb_fd, tud, secs, td) == NOTOK)	{	if (td -> td_reason == DR_TIMER)	                si -> si_abort.sa_reason = SC_TIMER;	sb -> sb_len = 0;        return ts2suslose (si, "TUnitDataRead", td);	}    /*     *  Decode the SPDU unitdata from the TSDU.     */#ifdef HULADEBUG	printf ("\n     getting ready to decode the tsdu \n");#endif    if ( ((s = udtsdu2spkt (&tud->tud_qbuf, tud->tud_cc) ) == NULL)	    || s -> s_errno != OK)	{	freespkt (s);	TUDFREE (tud);	return susaplose (si,			  SC_PROTOCOL,			  NULLCP,			  SuErrString(UDERR_DECODE_UDSPDU_FAILED));	}#ifdef HULADEBUG	    spkt2text (stdout, s, NULL);#endif    switch (s -> s_code) 	{	case SPDU_UD: 	    /* 	     *  Check if data got queued on the qbuf chain.	     */		    if (tud -> tud_qbuf.qb_forw != &tud -> tud_qbuf)	        {#ifdef HULADEBUG	        printf ("\n     got data in the spkt ... format indication \n");#endif		s -> s_qbuf.qb_data = tud -> tud_qbuf.qb_data;		s -> s_qbuf.qb_forw -> qb_back =			s -> s_qbuf.qb_back -> qb_forw = &s -> s_qbuf;		s -> s_qlen = tud -> tud_cc;	        }	    sb -> sb_spdu = s;		    sb -> sb_len = tud -> tud_cc;	    return s;	default:	    sb -> sb_spdu = NULL;	    freespkt (s);	    TUDFREE (tud);	    return NULL;        }}#if FALSE/*  *//* **************************************************************** *								* *  SUnitDataSetIndications					* *  								* *  This routine is sets the data handler routine to be called  * *  on unitdata indications from the transport.			* *								* *  returns:  OK, NOTOK 					* *								* **************************************************************** */static int  TUNITDATAser (sd, tud)int     sd;register struct TSAPunitdata   *tx;{    IFP	    abort;    register struct ssapblk *sb;    struct SSAPdata sxs;    register struct SSAPdata   *sx = &sxs;    struct SSAPindication   sis;    register struct SSAPindication *si = &sis;    register struct SSAPabort  *sa = &si -> si_abort;    if ((sb = findsublk (sd)) == NULL)	return;    abort = sb -> sb_AbortIndication;    for (;; tx = NULLTX) {	switch (SReadRequestAux (sb, sx, OK, si, 1, tx)) {	    case NOTOK: 		(*abort) (sd, sa);		return;	    case OK: 		(*sb -> sb_DataIndication) (sd, sx);		break;	    case DONE: 		switch (si -> si_type) {		    case SI_TOKEN: 			(*sb -> sb_TokenIndication) (sd, &si -> si_token);			break;		    case SI_SYNC: 			(*sb -> sb_SyncIndication) (sd, &si -> si_sync);			break;		    case SI_ACTIVITY: 			(*sb -> sb_ActivityIndication) (sd, &si -> si_activity);			break;		    case SI_REPORT: 			(*sb -> sb_ReportIndication) (sd, &si -> si_report);			break;		    case SI_FINISH: 			(*sb -> sb_ReleaseIndication) (sd, &si -> si_finish);			break;		    case SI_DATA: /* partially assembled (T)SSDU */			break;		}		break;	}	if (sb -> sb_spdu == NULL)	    break;    }}#endif#endif

⌨️ 快捷键说明

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