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 + -
显示快捷键?