00001
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "pic_packet.h"
00025
00026
00027 typedef union _rf_packet {
00028 rf_packet_det d;
00029 char a[PKT_PACKET_SIZE];
00030 } rf_packet;
00031
00032
00033
00034 typedef struct _sending_item {
00035 rf_packet packet;
00036 uns16 tick_sent;
00037 uns8 sent_count;
00038 uns8 flag;
00039 } sending_item;
00040
00041
00042 typedef struct _seen_packet {
00043 uns16 pkt_id;
00044 uns16 source_addr;
00045 } seen_packet;
00046
00047 static seen_packet pkt_seen_list[PKT_SEEN_LIST_SIZE];
00048 static sending_item pkt_tx_queue[PKT_TX_QUEUE_SIZE];
00049
00050 uns8 pkt_seen_list_last = 0;
00051 uns16 pkt_my_addr = 0x66;
00052 uns16 pkt_my_next_pkt_id = 0;
00053
00054
00055 #define PKT_FLAG_DELETED 0xff
00056
00057 uns8 pkt_seen(uns16 pkt_id, uns16 source_addr) {
00058
00059 uns8 count;
00060
00061 for (count = 0; count < PKT_SEEN_LIST_SIZE; count++ ) {
00062 if ((pkt_seen_list[count].pkt_id == pkt_id) &&
00063 (pkt_seen_list[count].source_addr == source_addr)) {
00064 return 1;
00065 }
00066 }
00067 return 0;
00068 }
00069
00070 void pkt_calc_check_byte(rf_packet *packet) {
00071
00072 uns8 calc, count;
00073
00074 calc = 0;
00075 for (count = 0; count < PKT_PACKET_SIZE -1; count++) {
00076 calc ^= packet->a[count];
00077 }
00078 packet->d.check_byte = calc;
00079 }
00080
00081 uns8 pkt_check_check_byte(rf_packet *packet) {
00082
00083 uns8 calc, count;
00084
00085 calc = 0;
00086 for (count = 0; count < PKT_PACKET_SIZE -1; count++) {
00087 calc ^= packet->a[count];
00088 }
00089
00090 if (calc == packet->d.check_byte)
00091 return 1;
00092 else
00093 return 0;
00094
00095 }
00096
00097 uns8 pkt_print_packet(rf_packet *my_packet) {
00098
00099 serial_print_str("[Pkt: s:");
00100 serial_print_int_hex(my_packet->d.source_addr);
00101 serial_print_str(" i:");
00102 serial_print_int_hex(my_packet->d.pkt_id);
00103 serial_print_str(" d:");
00104 serial_print_int_hex(my_packet->d.dest_addr);
00105 serial_print_str(" r1:");
00106 serial_print_int_hex(my_packet->d.r1_addr);
00107 serial_print_str(" r2:");
00108 serial_print_int_hex(my_packet->d.r2_addr);
00109 serial_print_str(" r3:");
00110 serial_print_int_hex(my_packet->d.r3_addr);
00111 serial_print_str(" p:");
00112 for (uns8 count = 0; count < PKT_PAYLOAD_SIZE; count++) {
00113 serial_print_int_hex(my_packet->d.payload[count]);
00114 serial_print_spc();
00115 }
00116 serial_print_str("] ");
00117 }
00118
00119
00120
00121 uns8 pkt_queue_packet(rf_packet *packet, uns8 resend)
00122 {
00123 uns8 count, found;
00124
00125 found = 0;
00126 for (count = 0; count < PKT_TX_QUEUE_SIZE; count++) {
00127 if (pkt_tx_queue[count].flag == PKT_FLAG_DELETED) {
00128 found = 1;
00129 break;
00130 }
00131 }
00132 if (found) {
00133 #ifdef PKT_DEBUG_HIGH
00134 serial_print_str(" Qin ");
00135 serial_print_int(count);
00136 #endif
00137 memcpy( (void *)&pkt_tx_queue[count],
00138 (void *)packet,
00139 PKT_PACKET_SIZE);
00140 pkt_tx_queue[count].sent_count = 0;
00141
00142 pkt_tx_queue[count].flag = resend;
00143 return PKT_STATUS_QUEUED;
00144 } else {
00145 return PKT_STATUS_TX_QUEUE_FULL;
00146 }
00147
00148 }
00149
00150
00151 uns8 pkt_process_rf_data(uns8 *data_in) {
00152
00153 uns8 status = 0;
00154 uns8 count;
00155 uns16 orig_pkt_id;
00156 uns8 ack_payload[PKT_PAYLOAD_SIZE] = { 0xff, 0xff };
00157 sending_item *pitem;
00158 rf_packet packet;
00159 start_crit_sec();
00160
00161 memcpy( (void *)&packet,
00162 (void *)data_in,
00163 PKT_PACKET_SIZE);
00164 end_crit_sec();
00165
00166 #ifdef PKT_DEBUG
00167 serial_putc('r');
00168 pkt_print_packet(&packet);
00169 #endif
00170 if (!pkt_check_check_byte(&packet)) {
00171 #ifdef PKT_DEBUG_HIGH
00172 serial_print_str("CF! ");
00173 #endif
00174 return PKT_STATUS_CHECK_FAIL;
00175 }
00176
00177
00178 if ((packet.d.dest_addr == pkt_my_addr) ||
00179 (packet.d.dest_addr == PKT_BROADCAST_ADDR)) {
00180 status = PKT_STATUS_PKT_IS_FOR_ME;
00181
00182 if ((packet.d.payload[0] != 0xff) ||
00183 (packet.d.payload[1] != 0xff)) {
00184 ack_payload[2] = packet.d.pkt_id & 0xff;
00185 ack_payload[3] = packet.d.pkt_id >> 8;
00186 #ifndef PKT_DEBUG_NO_TRANSMIT
00187 uns8 send_status = pkt_send_payload(packet.d.source_addr, ack_payload, PKT_FLAG_NO_RESEND);
00188 #ifdef PKT_DEBUG
00189 serial_print_str("ACKst=");
00190 serial_print_int(send_status);
00191 #endif
00192 #endif
00193 } else {
00194 status = PKT_STATUS_PKT_IS_ACK_FOR_ME;
00195 orig_pkt_id = packet.d.payload[3];
00196 orig_pkt_id <<= 8;
00197 orig_pkt_id += packet.d.payload[2];
00198 for (count = 0; count < PKT_TX_QUEUE_SIZE; count++) {
00199 pitem = &pkt_tx_queue[count];
00200 if ((pitem->flag != PKT_FLAG_DELETED) &&
00201 (pitem->packet.d.pkt_id == orig_pkt_id)) {
00202 status = PKT_STATUS_PKT_IS_FACK_FOR_ME;
00203 #ifdef PKT_CALLBACK_ON_SEND_SUCCEEDED
00204 pkt_send_succeeded_callback(pitem->packet.d.dest_addr, pitem->packet.d.pkt_id);
00205 #endif
00206
00207 pitem->flag = PKT_FLAG_DELETED;
00208 }
00209 }
00210 }
00211
00212
00213
00214 if (!pkt_seen(packet.d.pkt_id, packet.d.source_addr)) {
00215
00216
00217 if ((status != PKT_STATUS_PKT_IS_FACK_FOR_ME) &&
00218 (status != PKT_STATUS_PKT_IS_ACK_FOR_ME)) {
00219 pkt_payload_rx_callback(packet.d.source_addr, packet.d.pkt_id, packet.d.payload);
00220 }
00221
00222 pkt_seen_list_last++;
00223 if (pkt_seen_list_last == PKT_SEEN_LIST_SIZE) {
00224 pkt_seen_list_last = 0;
00225 }
00226 pkt_seen_list[pkt_seen_list_last].pkt_id = packet.d.pkt_id;
00227 pkt_seen_list[pkt_seen_list_last].source_addr = packet.d.source_addr;
00228 } else {
00229 status = PKT_STATUS_PKT_FOR_ME_BUT_SEEN;
00230 #ifdef PKT_DEBUG_HIGH
00231 serial_print_str(" seen ");
00232 #endif
00233 }
00234 }
00235 else
00236
00237 if (pkt_seen(packet.d.pkt_id, packet.d.source_addr)) {
00238
00239 status = PKT_STATUS_SEEN_BEFORE;
00240 } else
00241
00242 if (packet.d.source_addr == pkt_my_addr) {
00243 status = PKT_STATUS_I_AM_SENDER;
00244 } else
00245
00246 if (packet.d.r1_addr == PKT_DIRECT_SEND_ADDR) {
00247 status = PKT_STATUS_DIRECT_SEND;
00248 } else
00249
00250 if ((packet.d.r1_addr == pkt_my_addr) ||
00251 (packet.d.r2_addr == pkt_my_addr) ||
00252 (packet.d.r3_addr == pkt_my_addr)) {
00253 status = PKT_STATUS_PREVIOUS_ROUTED_VIA_ME;
00254 } else
00255
00256 if (packet.d.r3_addr != 0) {
00257 status = PKT_STATUS_ROUTING_FULL;
00258 } else {
00259 status = PKT_STATUS_NEED_TO_REBROADCAST;
00260
00261 if (packet.d.r1_addr == 0) {
00262 packet.d.r1_addr = pkt_my_addr;
00263 } else if (packet.d.r2_addr == 0) {
00264 packet.d.r2_addr = pkt_my_addr;
00265 } else {
00266 packet.d.r3_addr = pkt_my_addr;
00267 }
00268
00269 pkt_calc_check_byte(&packet);
00270
00271
00272 #ifndef PKT_DEBUG_NO_TRANSMIT
00273 pkt_queue_packet(&packet, PKT_FLAG_NO_RESEND);
00274 #endif
00275
00276 }
00277
00278 return status;
00279 }
00280
00281 #ifdef PKT_USE_24L01
00282 inline void pkt_send_packet(rf_packet *packet) {
00283
00284
00285 uns8 count;
00286
00287 #ifdef PKT_DEBUG
00288 serial_print_str(" <S>");
00289 #endif
00290 #ifdef PKT_DEBUG_HIGH
00291 pkt_print_packet(packet);
00292 #endif
00293
00294
00295
00296
00297
00298
00299
00300
00301 pic_rf_transmit((uns8 *)packet, PKT_PACKET_SIZE);
00302 }
00303
00304 #else
00305 inline void pkt_send_packet(rf_packet *packet) {
00306
00307 uns8 tx_buffer[PKT_PACKET_SIZE + 3];
00308 uns8 count;
00309
00310 #ifdef PKT_DEBUG
00311 serial_print_str(" <S>");
00312 #endif
00313 #ifdef PKT_DEBUG_HIGH
00314 pkt_print_packet(packet);
00315 #endif
00316 tx_buffer[0] = 0b11100111;
00317 tx_buffer[1] = 0b11100111;
00318 tx_buffer[2] = 0b11100111;
00319 for (count = 0; count < PKT_PACKET_SIZE; count++) {
00320 tx_buffer[count+3] = packet->a[count];
00321 }
00322 pic_rf_transmit(tx_buffer, PKT_PACKET_SIZE + 3);
00323
00324 }
00325
00326
00327 #endif
00328
00329
00330
00331 void pkt_process_tx_queue() {
00332
00333 uns8 count;
00334 uns16 current_tick;
00335 uns8 sent_count;
00336 uns8 flag;
00337 sending_item *item;
00338
00339 current_tick = tick_get_count();
00340
00341 for (count = 0; count < PKT_TX_QUEUE_SIZE; count++) {
00342 item = &pkt_tx_queue[count];
00343 flag = item->flag;
00344 if (flag != PKT_FLAG_DELETED) {
00345 sent_count = item->sent_count;
00346 if (sent_count > PKT_SEND_MAX_TRIES) {
00347 item->flag = PKT_FLAG_DELETED;
00348 #ifdef PKT_CALLBACK_ON_SEND_FAILED
00349 pkt_send_failed_callback(item->packet.d.dest_addr, item->packet.d.pkt_id);
00350 #endif
00351 #ifdef PKT_DEBUG
00352 serial_print_str(" SF!\n ");
00353 #endif
00354 } else if ((sent_count == 0)
00355 || (tick_calc_diff(item->tick_sent, current_tick)
00356 > PKT_RESEND_TICK_DELAY*sent_count + count)) {
00357
00358 item->tick_sent = current_tick;
00359
00360 #ifdef PKT_DEBUG_PAYLOAD_SENT
00361 item->packet.d.payload[7] = sent_count;
00362 pkt_calc_check_byte((rf_packet*)item);
00363 #endif
00364 #ifdef PKT_DEBUG_HIGH
00365 serial_print_str(" t=");
00366 serial_print_int(current_tick);
00367 serial_print_spc();
00368 #endif
00369 pkt_send_packet((rf_packet*)item);
00370 #ifdef PKT_CALLBACK_ON_SEND
00371 pkt_send_callback(item->packet.d.dest_addr, item->packet.d.pkt_id);
00372 #endif
00373
00374 if (flag != PKT_FLAG_RESEND) {
00375 item->flag = PKT_FLAG_DELETED;
00376 #ifdef PKT_DEBUG_HIGH
00377 serial_print_str(" SNR ");
00378 pkt_print_packet((rf_packet*)item);
00379 #endif
00380
00381 } else {
00382 item->sent_count++;
00383 #ifdef PKT_DEBUG_HIGH
00384 serial_print_str("SC ");
00385 serial_print_int(pkt_tx_queue[count].sent_count);
00386 serial_print_spc();
00387 #endif
00388
00389
00390 if (item->packet.d.r1_addr == 0xffff) {
00391 item->packet.d.r1_addr = 0;
00392 }
00393 }
00394 }
00395 }
00396 }
00397 }
00398
00399
00400 void pkt_init(uns16 my_addr, uns16 last_sent_id) {
00401
00402 uns8 count;
00403 uns16 current_tick;
00404
00405 pkt_my_addr = my_addr;
00406 pkt_my_next_pkt_id = last_sent_id + 1;
00407 for (count = 0; count < PKT_TX_QUEUE_SIZE; count++) {
00408 pkt_tx_queue[count].flag = PKT_FLAG_DELETED;
00409 }
00410
00411 for (count = 0; count < PKT_SEEN_LIST_SIZE; count++ ) {
00412 pkt_seen_list[count].source_addr = 0xffff;
00413 }
00414 }
00415
00416
00417 uns8 pkt_send_payload(uns16 dest_addr, uns8 *payload, uns8 resend) {
00418
00419 rf_packet my_packet;
00420 uns8 count;
00421
00422 #ifdef PKT_DEBUG_HIGH
00423 serial_print_str("\npkt send d:");
00424 serial_print_int(dest_addr);
00425 serial_print_str("s: ");
00426 serial_print_int(pkt_my_addr);
00427 serial_print_str("\n");
00428 #endif
00429
00430
00431
00432 my_packet.d.source_addr = pkt_my_addr;
00433 my_packet.d.pkt_id = pkt_my_next_pkt_id++;
00434 my_packet.d.dest_addr = dest_addr;
00435 my_packet.d.r1_addr = 0;
00436 if ((dest_addr != PKT_BROADCAST_ADDR) &&
00437 ((payload[0] != 0xff) || (payload[1] != 0xff))) {
00438 my_packet.d.r1_addr = PKT_DIRECT_SEND_ADDR;
00439 }
00440 my_packet.d.r2_addr = 0;
00441 my_packet.d.r3_addr = 0;
00442 for (count = 0; count < PKT_PAYLOAD_SIZE; count++) {
00443 my_packet.d.payload[count] = payload[count];
00444 }
00445 pkt_calc_check_byte(&my_packet);
00446
00447 #ifdef PKT_DEBUG
00448 serial_print_str(" PS");
00449 pkt_print_packet(&my_packet);
00450 #endif
00451
00452
00453
00454 return pkt_queue_packet(&my_packet, resend);
00455 }
00456
00457
00458
00459