Project

General

Profile

Revision 1676

wireless: redo of wireless_receive functions for basic and dispatch

View differences:

wireless_receive.c
60 60
extern uint8_t basic_buf_last;	// end of last packet in basic buffer
61 61
extern uint8_t other_buf_first; // beginning of first packet in other buffer
62 62
extern uint8_t other_buf_last;  // end of last packet in other buffer
63
extern uint8_t xbee_basic_buf_get(uint8_t *ptr); // get byte from basic buf
64
extern uint8_t xbee_other_buf_get(uint8_t *ptr); // get byte from other buf
63 65

  
66

  
64 67
/**
65 68
 * @addtogroup wireless Wireless
66 69
 * @{
......
94 97
 * @return the length of the used portion of data array or error (<0)
95 98
 **/
96 99
int8_t wl_get_basic(char *data, uint8_t length) {
97
    if (basic_buf_first == 0xFF)
98
      basic_buf_first = 0;
99
    uint8_t buf_pos = basic_buf_first;	// start at beginning of first (oldest) basic packet
100
    uint8_t data_length = xbee_basic_buf[buf_pos % PACKET_BUFFER_SIZE];  // get packet length
100
  uint8_t buf_pos = basic_buf_first;	// start at beginning of first (oldest) basic packet
101
  uint8_t data_length = 0xFF;
102
  while((data_length = xbee_basic_buf_get(&buf_pos)) == 0xFF) { }  // get packet length
101 103

  
102
    if (data_length - 3 > length)   // not enough room for data in destination
103
	return WL_ERROR_TOO_SMALL;
104
  if (data_length - 3 > length)   // not enough room for data in destination
105
    return WL_ERROR_TOO_SMALL;
104 106

  
105
    // packet has not fully arrived yet
106
    if (buf_pos + data_length > basic_buf_last	// length goes farther than end of buffer
107
	    && !(buf_pos >= basic_buf_last && buf_pos + data_length > buf_pos))
108
	/* basic test is Beginning + Length > Buffer End means packet isn't all there yet
109
	   if end counter overflows, a complete packet's end may still be greater than the buffer end index,
110
	   but such a packet can be read from the buffer
111
	 */
112
	return WL_SUCCESS;  // no data written
113
    
114
    WL_DEBUG_PRINT_P("entered wl_get_basic\r\n");
107
  // packet has not fully arrived yet
108
  if (buf_pos + data_length >= PACKET_BUFFER_SIZE) {
109
    if ((buf_pos + data_length - PACKET_BUFFER_SIZE) > basic_buf_last)
110
      return WL_SUCCESS;
111
  } else {
112
    if ((buf_pos + data_length) > basic_buf_last)
113
      return WL_SUCCESS;
114
  }
115
  
116
  WL_DEBUG_PRINT_P("entered wl_get_basic\r\n");
117
  
118
  // ignore the source ID
119
  xbee_basic_buf_get(&buf_pos);
120
  xbee_basic_buf_get(&buf_pos);
121
  
122
  // copy data to destination, byte by byte to account for circular buffer
123
  data_length-=2;
124
  for(uint8_t i=0;i<data_length;i++) {
125
    data[i] = xbee_basic_buf_get(&buf_pos);
126
  }
127
  
128
  basic_buf_first = buf_pos; // "free up" this packet's buffer space
115 129

  
116
    buf_pos++;
117
    buf_pos++;	// ignore the source ID
118

  
119
    // copy data to destination, byte by byte to account for circular buffer
120
    // don't copy the 3 header bytes. nobody wants those.
121
    for (; buf_pos < basic_buf_first + data_length; buf_pos++)
122
	memcpy(data + buf_pos - 3, xbee_basic_buf + (buf_pos % PACKET_BUFFER_SIZE), 1);
123

  
124
    basic_buf_first += data_length; // "free up" this packet's buffer space
125

  
126
    return data_length;
130
  return data_length;
127 131
}
128 132

  
129 133
/*
......
132 136
 * @return error codes
133 137
 */
134 138
int8_t wl_dispatch(void) {
135
    if (other_buf_first == 0xFF)
136
      other_buf_first = 0;
137
    uint8_t buf_pos = other_buf_first;	// current position in buffer
138
    uint8_t group;  // group of packet under consideration
139
    void (*handler)(uint8_t *data, uint8_t length, uint8_t source);  // handler for group of packet under consideration
140
    uint8_t length = xbee_other_buf[buf_pos % PACKET_BUFFER_SIZE];  // length of packet under consideration
141
    uint8_t source; // robot ID of sender of packet under consideration
139
  uint8_t buf_pos = other_buf_first;	// current position in buffer
140
  uint8_t group;  // group of packet under consideration
141
  FNPTR; // pointer to handler
142
  uint8_t source; // robot ID of sender of packet under consideration
143
  uint8_t data_length = 0xFF;
142 144

  
143
    // consider packets one at a time until buffer contains no complete packets
144
    while (buf_pos + length <= other_buf_last	// length goes farther than end of buffer
145
	    || (buf_pos >= other_buf_last && buf_pos + length > buf_pos)) {
146
	/* basic test is Beginning + Length > Buffer End means packet isn't all there yet
147
	   if end counter overflows, a complete packet's end may still be greater than the buffer end index,
148
	   but such a packet can be read from the buffer
149
	 */
150
	buf_pos++;
151
	group = xbee_other_buf[buf_pos];    // get group from packet
152
	if (group >= MAX_PACKET_GROUPS)  // invalid group number
153
	    buf_pos += length - 1 + 1;	// go to first byte of next packet
154
	else {	// valid group number
155
	    handler = wl_packet_handlers[group].FUNC;	// get function from handler array
156
	    buf_pos++;
157
	    buf_pos++;  // ignore 1st byte of ID (will be all 0s)
158
	    source = xbee_other_buf[buf_pos];   // get sender ID from packet
159
	    buf_pos++;  // now index of beginning of packet data (mod PACKET_BUFFER_SIZE)
160

  
161
	    if (handler)	// check whether group is handled
162
		(*handler)(xbee_other_buf + (buf_pos & PACKET_BUFFER_SIZE), length - 4, source);
163

  
164
	    // go to next packet
165
	    buf_pos += length - 4 + 1;  // go to first byte of next packet
166
	}
167

  
168
	length = xbee_other_buf[buf_pos & PACKET_BUFFER_SIZE];	// get length of next packet
145
  while (1) {
146
    while((data_length = xbee_other_buf_get(&buf_pos)) == 0xFF) { }  // get packet length
147
    
148
    // check if packet has not fully arrived yet
149
    if (buf_pos + data_length >= PACKET_BUFFER_SIZE) {
150
      if ((buf_pos + data_length - PACKET_BUFFER_SIZE) > other_buf_last)
151
        break;
152
    } else {
153
      if ((buf_pos + data_length) > other_buf_last)
154
        break;
169 155
    }
156
    
157
    // get group number
158
    group = xbee_other_buf_get(&buf_pos);
159
    if (group >= MAX_PACKET_GROUPS || wl_packet_handlers[group].FUNC == NULL) {
160
      // this is an invalid group, so go to next packet
161
      buf_pos += data_length - 2;
162
      if (buf_pos >= PACKET_BUFFER_SIZE)
163
        buf_pos -= PACKET_BUFFER_SIZE;
164
    } else {
165
      // this is a valid group number, so get handler
166
      FUNC = wl_packet_handlers[group].FUNC;
167
      xbee_other_buf_get(&buf_pos); // ignore first byte of source id
168
      source = xbee_other_buf_get(&buf_pos); // get low byte of source id
169
      
170
      // call handler
171
      (*FUNC)(xbee_other_buf+buf_pos,data_length-4,source);
172
      
173
      // go to next packet
174
      buf_pos += data_length - 4;
175
      if (buf_pos >= PACKET_BUFFER_SIZE)
176
        buf_pos -= PACKET_BUFFER_SIZE;
177
    }
178
  }
179
  
180
  // mark packets as read
181
  other_buf_first = (buf_pos==0)?(PACKET_BUFFER_SIZE-1):(buf_pos-1);
170 182

  
171
    return WL_SUCCESS;
183
  return WL_SUCCESS;
172 184
}
173 185

  
174 186

  

Also available in: Unified diff