Make patty_ax25_sock_resend() send with V(R)
Changes:
    * Make TX slots only large enough to hold the info field of an I
      frame; do not save header information
    * Fix issue wherein patty_ax25_sock_resend() would resend the N(R)
      value of an I frame as it was originally sent, even if this is
      incorrect for a given situation
    * Make control_i() in src/sock.c accept a V(S) sequence argument, as
      this can sometimes be independent of the socket current V(S) value
    * Declare control field functions as inline in src/sock.c
			
			
This commit is contained in:
		
							parent
							
								
									3db8c9cef3
								
							
						
					
					
						commit
						f41ce994f4
					
				
					 1 changed files with 70 additions and 64 deletions
				
			
		
							
								
								
									
										134
									
								
								src/sock.c
									
										
									
									
									
								
							
							
						
						
									
										134
									
								
								src/sock.c
									
										
									
									
									
								
							|  | @ -61,7 +61,7 @@ static inline size_t tx_slots(patty_ax25_sock *sock) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static inline size_t tx_slot_size(patty_ax25_sock *sock) { | static inline size_t tx_slot_size(patty_ax25_sock *sock) { | ||||||
|     return sizeof(struct slot) + PATTY_AX25_FRAME_OVERHEAD + sock->n_maxlen_tx; |     return sizeof(struct slot) + sock->n_maxlen_tx; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static inline size_t tx_slots_size(patty_ax25_sock *sock) { | static inline size_t tx_slots_size(patty_ax25_sock *sock) { | ||||||
|  | @ -79,8 +79,13 @@ static inline struct slot *tx_slot(patty_ax25_sock *sock, int seq) { | ||||||
|         ((uint8_t *)sock->tx_slots + (i * tx_slot_size(sock))); |         ((uint8_t *)sock->tx_slots + (i * tx_slot_size(sock))); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static inline void *tx_slot_buf(patty_ax25_sock *sock, int seq) { | static inline void tx_slot_save(patty_ax25_sock *sock, void *buf, size_t len) { | ||||||
|     return (uint8_t *)tx_slot(sock, seq) + sizeof(struct slot); |     struct slot *slot = tx_slot(sock, sock->vs); | ||||||
|  | 
 | ||||||
|  |     slot->len = len; | ||||||
|  |     slot->ack = 0; | ||||||
|  | 
 | ||||||
|  |     memcpy(slot + 1, buf, len); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int init_bufs(patty_ax25_sock *sock) { | static int init_bufs(patty_ax25_sock *sock) { | ||||||
|  | @ -638,6 +643,52 @@ error_invalid_type: | ||||||
|     return -1; |     return -1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static inline uint16_t control_i(patty_ax25_sock *sock, int ns, int flag) { | ||||||
|  |     switch (sock->mode) { | ||||||
|  |         case PATTY_AX25_SOCK_SABM: | ||||||
|  |             return ((sock->vr & 0x07) << 5) | ||||||
|  |                  | ((      ns & 0x07) << 1) | ||||||
|  |                  | (flag << 4); | ||||||
|  | 
 | ||||||
|  |         case PATTY_AX25_SOCK_SABME: | ||||||
|  |             return ((sock->vr & 0x7f) << 9) | ||||||
|  |                  | ((      ns & 0x7f) << 1) | ||||||
|  |                  | (flag << 8); | ||||||
|  | 
 | ||||||
|  |         default: | ||||||
|  |             return 0; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline uint16_t control_ui(int flag) { | ||||||
|  |     return PATTY_AX25_FRAME_UI | (flag << 4); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline uint16_t control_s(patty_ax25_sock *sock, | ||||||
|  |                           enum patty_ax25_frame_type type, | ||||||
|  |                           int flag) { | ||||||
|  |     switch (sock->mode) { | ||||||
|  |         case PATTY_AX25_SOCK_SABM: | ||||||
|  |             return ((sock->vr & 0x07) << 5) | ||||||
|  |                  | (type & 0x0f) | ||||||
|  |                  | (flag << 4); | ||||||
|  | 
 | ||||||
|  |         case PATTY_AX25_SOCK_SABME: | ||||||
|  |             return ((sock->vr & 0x7f) << 9) | ||||||
|  |                  | (type & 0x0f) | ||||||
|  |                  | (flag << 8); | ||||||
|  | 
 | ||||||
|  |         default: | ||||||
|  |             return 0; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline uint16_t control_u(enum patty_ax25_frame_type type, | ||||||
|  |                           int pf) { | ||||||
|  |     return (type & PATTY_AX25_FRAME_U_MASK) | ||||||
|  |          | (pf << 4); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static ssize_t frame_send(patty_ax25_sock *sock, | static ssize_t frame_send(patty_ax25_sock *sock, | ||||||
|                           enum patty_ax25_frame_cr cr, |                           enum patty_ax25_frame_cr cr, | ||||||
|                           uint16_t control, |                           uint16_t control, | ||||||
|  | @ -647,8 +698,7 @@ static ssize_t frame_send(patty_ax25_sock *sock, | ||||||
|      size_t offset = 0; |      size_t offset = 0; | ||||||
|     ssize_t encoded; |     ssize_t encoded; | ||||||
| 
 | 
 | ||||||
|     uint8_t *buf = PATTY_AX25_FRAME_CONTROL_I(control)? |     uint8_t *buf = sock->tx_buf; | ||||||
|         tx_slot_buf(sock, sock->vs): sock->tx_buf; |  | ||||||
| 
 | 
 | ||||||
|     if (sock->iface == NULL) { |     if (sock->iface == NULL) { | ||||||
|         errno = ENETDOWN; |         errno = ENETDOWN; | ||||||
|  | @ -686,13 +736,6 @@ static ssize_t frame_send(patty_ax25_sock *sock, | ||||||
|         memcpy(buf + offset, info, infolen); |         memcpy(buf + offset, info, infolen); | ||||||
| 
 | 
 | ||||||
|         offset += infolen; |         offset += infolen; | ||||||
| 
 |  | ||||||
|         if (PATTY_AX25_FRAME_CONTROL_I(control)) { |  | ||||||
|             struct slot *slot = tx_slot(sock, sock->vs); |  | ||||||
| 
 |  | ||||||
|             slot->len = offset; |  | ||||||
|             slot->ack = 0; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return patty_ax25_if_send(sock->iface, buf, offset); |     return patty_ax25_if_send(sock->iface, buf, offset); | ||||||
|  | @ -707,7 +750,12 @@ error_noif: | ||||||
| ssize_t patty_ax25_sock_resend(patty_ax25_sock *sock, int seq) { | ssize_t patty_ax25_sock_resend(patty_ax25_sock *sock, int seq) { | ||||||
|     struct slot *slot = tx_slot(sock, seq); |     struct slot *slot = tx_slot(sock, seq); | ||||||
| 
 | 
 | ||||||
|     return slot->len > 0? patty_ax25_if_send(sock->iface, slot + 1, slot->len): 0; |     return slot->len > 0? frame_send(sock, | ||||||
|  |                                      PATTY_AX25_FRAME_COMMAND, | ||||||
|  |                                      control_i(sock, seq, 0), | ||||||
|  |                                      sock->proto, | ||||||
|  |                                      slot + 1, | ||||||
|  |                                      slot->len): 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ssize_t patty_ax25_sock_resend_pending(patty_ax25_sock *sock) { | ssize_t patty_ax25_sock_resend_pending(patty_ax25_sock *sock) { | ||||||
|  | @ -772,52 +820,6 @@ int patty_ax25_sock_ack_pending(patty_ax25_sock *sock) { | ||||||
|     return ret; |     return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static uint16_t control_i(patty_ax25_sock *sock, int flag) { |  | ||||||
|     switch (sock->mode) { |  | ||||||
|         case PATTY_AX25_SOCK_SABM: |  | ||||||
|             return ((sock->vr & 0x07) << 5) |  | ||||||
|                  | ((sock->vs & 0x07) << 1) |  | ||||||
|                  | (flag << 4); |  | ||||||
| 
 |  | ||||||
|         case PATTY_AX25_SOCK_SABME: |  | ||||||
|             return ((sock->vr & 0x7f) << 9) |  | ||||||
|                  | ((sock->vs & 0x7f) << 1) |  | ||||||
|                  | (flag << 8); |  | ||||||
| 
 |  | ||||||
|         default: |  | ||||||
|             return 0; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static uint16_t control_ui(int flag) { |  | ||||||
|     return PATTY_AX25_FRAME_UI | (flag << 4); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static uint16_t control_s(patty_ax25_sock *sock, |  | ||||||
|                           enum patty_ax25_frame_type type, |  | ||||||
|                           int flag) { |  | ||||||
|     switch (sock->mode) { |  | ||||||
|         case PATTY_AX25_SOCK_SABM: |  | ||||||
|             return ((sock->vr & 0x07) << 5) |  | ||||||
|                  | (type & 0x0f) |  | ||||||
|                  | (flag << 4); |  | ||||||
| 
 |  | ||||||
|         case PATTY_AX25_SOCK_SABME: |  | ||||||
|             return ((sock->vr & 0x7f) << 9) |  | ||||||
|                  | (type & 0x0f) |  | ||||||
|                  | (flag << 8); |  | ||||||
| 
 |  | ||||||
|         default: |  | ||||||
|             return 0; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static uint16_t control_u(enum patty_ax25_frame_type type, |  | ||||||
|                           int pf) { |  | ||||||
|     return (type & PATTY_AX25_FRAME_U_MASK) |  | ||||||
|          | (pf << 4); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| ssize_t patty_ax25_sock_send_rr(patty_ax25_sock *sock, | ssize_t patty_ax25_sock_send_rr(patty_ax25_sock *sock, | ||||||
|                                 enum patty_ax25_frame_cr cr, |                                 enum patty_ax25_frame_cr cr, | ||||||
|                                 int pf) { |                                 int pf) { | ||||||
|  | @ -968,8 +970,7 @@ static ssize_t write_segmented(patty_ax25_sock *sock, | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     while (segments--) { |     while (segments--) { | ||||||
|         uint8_t *dest = (uint8_t *)sock->tx_buf; |         uint8_t *dest  = (uint8_t *)sock->tx_buf; | ||||||
| 
 |  | ||||||
|         uint8_t header = (uint8_t)(segments & 0xff); |         uint8_t header = (uint8_t)(segments & 0xff); | ||||||
| 
 | 
 | ||||||
|         size_t copylen = segments == 0? |         size_t copylen = segments == 0? | ||||||
|  | @ -979,7 +980,7 @@ static ssize_t write_segmented(patty_ax25_sock *sock, | ||||||
|         size_t o = 0; |         size_t o = 0; | ||||||
| 
 | 
 | ||||||
|         uint16_t control = sock->type == PATTY_AX25_SOCK_STREAM? |         uint16_t control = sock->type == PATTY_AX25_SOCK_STREAM? | ||||||
|             control_i(sock, 0): |             control_i(sock, sock->vs, 0): | ||||||
|             control_ui(0); |             control_ui(0); | ||||||
| 
 | 
 | ||||||
|         if (first) { |         if (first) { | ||||||
|  | @ -994,6 +995,8 @@ static ssize_t write_segmented(patty_ax25_sock *sock, | ||||||
|             first = 0; |             first = 0; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         tx_slot_save(sock, buf + i, copylen); | ||||||
|  | 
 | ||||||
|         memcpy(dest + o, (uint8_t *)buf + i, copylen); |         memcpy(dest + o, (uint8_t *)buf + i, copylen); | ||||||
| 
 | 
 | ||||||
|         i += copylen; |         i += copylen; | ||||||
|  | @ -1030,14 +1033,16 @@ ssize_t patty_ax25_sock_write(patty_ax25_sock *sock, | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     switch (sock->type) { |     switch (sock->type) { | ||||||
|         case PATTY_AX25_SOCK_STREAM: |         case PATTY_AX25_SOCK_STREAM:{ | ||||||
|             if (len > sock->n_maxlen_tx) { |             if (len > sock->n_maxlen_tx) { | ||||||
|                 return write_segmented(sock, buf, len); |                 return write_segmented(sock, buf, len); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  |             tx_slot_save(sock, buf, len); | ||||||
|  | 
 | ||||||
|             if (frame_send(sock, |             if (frame_send(sock, | ||||||
|                            PATTY_AX25_FRAME_COMMAND, |                            PATTY_AX25_FRAME_COMMAND, | ||||||
|                            control_i(sock, 0), |                            control_i(sock, sock->vs, 0), | ||||||
|                            sock->proto, |                            sock->proto, | ||||||
|                            buf, |                            buf, | ||||||
|                            len) < 0) { |                            len) < 0) { | ||||||
|  | @ -1047,6 +1052,7 @@ ssize_t patty_ax25_sock_write(patty_ax25_sock *sock, | ||||||
|             patty_ax25_sock_vs_incr(sock); |             patty_ax25_sock_vs_incr(sock); | ||||||
| 
 | 
 | ||||||
|             break; |             break; | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         case PATTY_AX25_SOCK_DGRAM: |         case PATTY_AX25_SOCK_DGRAM: | ||||||
|             if (len > sock->n_maxlen_tx) { |             if (len > sock->n_maxlen_tx) { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue