📄 uip.lst
字号:
756 2
757 2 If the incoming packet is a FIN, we should close the connection on
758 2 this side as well, and we send out a FIN and enter the LAST_ACK
759 2 state. We require that the FIN will have to acknowledge all
760 2 outstanding data, otherwise we drop it. */
761 2
762 2 if(BUF->flags & TCP_FIN) {
763 3 uip_add_rcv_nxt(1 + uip_len);
764 3 uip_flags = UIP_CLOSE;
765 3 uip_len = 0;
766 3 UIP_APPCALL();
767 3 uip_add_ack_nxt(1);
768 3 uip_conn->tcpstateflags = LAST_ACK | UIP_OUTSTANDING;
769 3 uip_conn->nrtx = 0;
770 3 tcp_send_finack:
771 3 BUF->flags = TCP_FIN | TCP_ACK;
772 3 goto tcp_send_nodata;
773 3 }
774 2
775 2
776 2 /* If uip_len > 0 we have TCP data in the packet, and we flag this
777 2 by setting the UIP_NEWDATA flag and update the sequence number
778 2 we acknowledge. If the application has stopped the dataflow
779 2 using uip_stop(), we must not accept any data packets from the
780 2 remote host. */
781 2 if(uip_len > 0 && !(uip_conn->tcpstateflags & UIP_STOPPED)) {
782 3 uip_flags |= UIP_NEWDATA;
783 3 uip_add_rcv_nxt(uip_len);
784 3 }
785 2
786 2
787 2 /* If this packet constitutes an ACK for outstanding data (flagged
788 2 by the UIP_ACKDATA flag, we should call the application since it
789 2 might want to send more data. If the incoming packet had data
790 2 from the peer (as flagged by the UIP_NEWDATA flag), the
791 2 application must also be notified.
792 2
793 2 When the application is called, the global variable uip_len
794 2 contains the length of the incoming data. The application can
795 2 access the incoming data through the global pointer
796 2 uip_appdata, which usually points 40 bytes into the uip_buf
797 2 array.
798 2
C51 COMPILER V7.06 UIP 04/05/2006 12:13:01 PAGE 14
799 2 If the application wishes to send any data, this data should be
800 2 put into the uip_appdata and the length of the data should be
801 2 put into uip_len. If the application don't have any data to
802 2 send, uip_len must be set to 0. */
803 2 if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
804 3 UIP_APPCALL();
805 3
806 3 appsend:
807 3 if(uip_flags & UIP_ABORT) {
808 4 uip_conn->tcpstateflags = CLOSED;
809 4 BUF->flags = TCP_RST | TCP_ACK;
810 4 goto tcp_send_nodata;
811 4 }
812 3
813 3 if(uip_flags & UIP_CLOSE) {
814 4 uip_add_ack_nxt(1);
815 4 uip_conn->tcpstateflags = FIN_WAIT_1 | UIP_OUTSTANDING;
816 4 uip_conn->nrtx = 0;
817 4 BUF->flags = TCP_FIN | TCP_ACK;
818 4 goto tcp_send_nodata;
819 4 }
820 3
821 3 /* If uip_len > 0, the application has data to be sent, in which
822 3 case we set the UIP_OUTSTANDING flag in the connection
823 3 structure. But we cannot send data if the application already
824 3 has outstanding data. */
825 3 if(uip_len > 0 &&
826 3 !(uip_conn->tcpstateflags & UIP_OUTSTANDING)) {
827 4 uip_conn->tcpstateflags |= UIP_OUTSTANDING;
828 4 uip_conn->nrtx = 0;
829 4 uip_add_ack_nxt(uip_len);
830 4 } else {
831 4 uip_len = 0;
832 4 }
833 3 apprexmit:
834 3 /* If the application has data to be sent, or if the incoming
835 3 packet had new data in it, we must send out a packet. */
836 3 if(uip_len > 0 || (uip_flags & UIP_NEWDATA)) {
837 4 /* Add the length of the IP and TCP headers. */
838 4 uip_len = uip_len + 40;
839 4 /* We always set the ACK flag in response packets. */
840 4 BUF->flags = TCP_ACK;
841 4 /* Send the packet. */
842 4 goto tcp_send_noopts;
843 4 }
844 3 }
845 2 goto drop;
846 2 case LAST_ACK:
847 2 /* We can close this connection if the peer has acknowledged our
848 2 FIN. This is indicated by the UIP_ACKDATA flag. */
849 2 if(uip_flags & UIP_ACKDATA) {
850 3 uip_conn->tcpstateflags = CLOSED;
851 3 }
852 2 break;
853 2
854 2 case FIN_WAIT_1:
855 2 /* The application has closed the connection, but the remote host
856 2 hasn't closed its end yet. Thus we do nothing but wait for a
857 2 FIN from the other side. */
858 2 if(uip_len > 0) {
859 3 uip_add_rcv_nxt(uip_len);
860 3 }
C51 COMPILER V7.06 UIP 04/05/2006 12:13:01 PAGE 15
861 2 if(BUF->flags & TCP_FIN) {
862 3 if(uip_flags & UIP_ACKDATA) {
863 4 uip_conn->tcpstateflags = TIME_WAIT;
864 4 uip_conn->timer = 0;
865 4 } else {
866 4 uip_conn->tcpstateflags = CLOSING | UIP_OUTSTANDING;
867 4 }
868 3 uip_add_rcv_nxt(1);
869 3 goto tcp_send_ack;
870 3 } else if(uip_flags & UIP_ACKDATA) {
871 3 uip_conn->tcpstateflags = FIN_WAIT_2;
872 3 goto drop;
873 3 }
874 2 if(uip_len > 0) {
875 3 goto tcp_send_ack;
876 3 }
877 2 goto drop;
878 2
879 2 case FIN_WAIT_2:
880 2 if(uip_len > 0) {
881 3 uip_add_rcv_nxt(uip_len);
882 3 }
883 2 if(BUF->flags & TCP_FIN) {
884 3 uip_conn->tcpstateflags = TIME_WAIT;
885 3 uip_conn->timer = 0;
886 3 uip_add_rcv_nxt(1);
887 3 goto tcp_send_ack;
888 3 }
889 2 if(uip_len > 0) {
890 3 goto tcp_send_ack;
891 3 }
892 2 goto drop;
893 2
894 2 case TIME_WAIT:
895 2 goto tcp_send_ack;
896 2
897 2 case CLOSING:
898 2 if(uip_flags & UIP_ACKDATA) {
899 3 uip_conn->tcpstateflags = TIME_WAIT;
900 3 uip_conn->timer = 0;
901 3 }
902 2 }
903 1 goto drop;
904 1
905 1
906 1 /* We jump here when we are ready to send the packet, and just want
907 1 to set the appropriate TCP sequence numbers in the TCP header. */
908 1 tcp_send_ack:
909 1 BUF->flags = TCP_ACK;
910 1 tcp_send_nodata:
911 1 uip_len = 40;
912 1 tcp_send_noopts:
913 1 BUF->tcpoffset = 5 << 4;
914 1 tcp_send:
915 1 /* We're done with the input processing. We are now ready to send a
916 1 reply. Our job is to fill in all the fields of the TCP and IP
917 1 headers before calculating the checksum and finally send the
918 1 packet. */
919 1 BUF->ackno[0] = uip_conn->rcv_nxt[0];
920 1 BUF->ackno[1] = uip_conn->rcv_nxt[1];
921 1 BUF->ackno[2] = uip_conn->rcv_nxt[2];
922 1 BUF->ackno[3] = uip_conn->rcv_nxt[3];
C51 COMPILER V7.06 UIP 04/05/2006 12:13:01 PAGE 16
923 1
924 1 BUF->seqno[0] = uip_conn->snd_nxt[0];
925 1 BUF->seqno[1] = uip_conn->snd_nxt[1];
926 1 BUF->seqno[2] = uip_conn->snd_nxt[2];
927 1 BUF->seqno[3] = uip_conn->snd_nxt[3];
928 1
929 1 BUF->srcport = uip_conn->lport;
930 1 BUF->destport = uip_conn->rport;
931 1
932 1 #if BYTE_ORDER == BIG_ENDIAN
933 1 BUF->srcipaddr[0] = ((UIP_IPADDR0 << 8) | UIP_IPADDR1);
934 1 BUF->srcipaddr[1] = ((UIP_IPADDR2 << 8) | UIP_IPADDR3);
935 1 #else
BUF->srcipaddr[0] = ((UIP_IPADDR1 << 8) | UIP_IPADDR0);
BUF->srcipaddr[1] = ((UIP_IPADDR3 << 8) | UIP_IPADDR2);
#endif /* BYTE_ORDER == BIG_ENDIAN */
939 1
940 1 BUF->destipaddr[0] = uip_conn->ripaddr[0];
941 1 BUF->destipaddr[1] = uip_conn->ripaddr[1];
942 1
943 1 if(uip_conn->tcpstateflags & UIP_STOPPED) {
944 2 /* If the connection has issued uip_stop(), we advertise a zero
945 2 window so that the remote host will stop sending data. */
946 2 BUF->wnd[0] = BUF->wnd[1] = 0;
947 2 } else {
948 2 #if (UIP_TCP_MSS) > 255
BUF->wnd[0] = (uip_conn->mss >> 8);
#else
951 2 BUF->wnd[0] = 0;
952 2 #endif /* UIP_MSS */
953 2 BUF->wnd[1] = (uip_conn->mss & 0xff);
954 2 }
955 1
956 1 tcp_send_noconn:
957 1
958 1 BUF->vhl = 0x45;
959 1 BUF->tos = 0;
960 1 BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
961 1 BUF->ttl = UIP_TTL;
962 1 BUF->proto = IP_PROTO_TCP;
963 1
964 1 #if UIP_BUFSIZE > 255
BUF->len[0] = (uip_len >> 8);
BUF->len[1] = (uip_len & 0xff);
#else
968 1 BUF->len[0] = 0;
969 1 BUF->len[1] = uip_len;
970 1 #endif /* UIP_BUFSIZE > 255 */
971 1
972 1 ++ipid;
973 1 BUF->ipid[0] = ipid >> 8;
974 1 BUF->ipid[1] = ipid & 0xff;
975 1
976 1 /* Calculate IP and TCP checksums. */
977 1 BUF->ipchksum = 0;
978 1 BUF->ipchksum = ~(uip_ipchksum());
979 1 BUF->tcpchksum = 0;
980 1 BUF->tcpchksum = ~(uip_tcpchksum());
981 1
982 1 UIP_STAT(++uip_stat.tcp.sent);
983 1 send:
984 1 UIP_STAT(++uip_stat.ip.sent);
C51 COMPILER V7.06 UIP 04/05/2006 12:13:01 PAGE 17
985 1 /* The data that should be sent is not present in the uip_buf, and
986 1 the length of the data is in the variable uip_len. It is not our
987 1 responsibility to do the actual sending of the data however. That
988 1 is taken care of by the wrapper code, and only if uip_len > 0. */
989 1 return;
990 1 drop:
991 1 uip_len = 0;
992 1 return;
993 1 }
994 /*-----------------------------------------------------------------------------------*/
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 3655 ----
CONSTANT SIZE = ---- ----
XDATA SIZE = 594 ----
PDATA SIZE = ---- ----
DATA SIZE = ---- ----
IDATA SIZE = ---- ----
BIT SIZE = ---- ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -