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
00160 memcpy( (void *)&packet,
00161 (void *)data_in,
00162 PKT_PACKET_SIZE);
00163
00164
00165 #ifdef PKT_DEBUG_HIGH
00166 serial_print_str("r");
00167 pkt_print_packet(&packet);
00168 #endif
00169 if (!pkt_check_check_byte(&packet)) {
00170 #ifdef PKT_DEBUG_HIGH
00171 serial_print_str("CF! ");
00172 #endif
00173 return PKT_STATUS_CHECK_FAIL;
00174 }
00175
00176
00177 if (packet.d.dest_addr == pkt_my_addr) {
00178 status = PKT_STATUS_PKT_IS_FOR_ME;
00179
00180 if ((packet.d.payload[0] != 0xff) ||
00181 (packet.d.payload[1] != 0xff)) {
00182 ack_payload[2] = packet.d.pkt_id & 0xff;
00183 ack_payload[3] = packet.d.pkt_id >> 8;
00184 pkt_send_payload(packet.d.source_addr, ack_payload, PKT_FLAG_NO_RESEND);
00185 } else {
00186 status = PKT_STATUS_PKT_IS_ACK_FOR_ME;
00187 orig_pkt_id = packet.d.payload[3];
00188 orig_pkt_id <<= 8;
00189 orig_pkt_id += packet.d.payload[2];
00190 for (count = 0; count < PKT_TX_QUEUE_SIZE; count++) {
00191 pitem = &pkt_tx_queue[count];
00192 if ((pitem->flag != PKT_FLAG_DELETED) &&
00193 (pitem->packet.d.pkt_id == orig_pkt_id)) {
00194 status = PKT_STATUS_PKT_IS_FACK_FOR_ME;
00195 #ifdef PKT_CALLBACK_ON_SEND_SUCCEEDED
00196 pkt_send_succeeded_callback(pitem->packet.d.dest_addr, pitem->packet.d.pkt_id);
00197 #endif
00198
00199 pitem->flag = PKT_FLAG_DELETED;
00200 }
00201 }
00202 }
00203
00204
00205
00206 if (!pkt_seen(packet.d.pkt_id, packet.d.source_addr)) {
00207
00208
00209 if ((status != PKT_STATUS_PKT_IS_FACK_FOR_ME) &&
00210 (status != PKT_STATUS_PKT_IS_ACK_FOR_ME)) {
00211 pkt_payload_rx_callback(packet.d.source_addr, packet.d.pkt_id, packet.d.payload);
00212 }
00213
00214 pkt_seen_list_last++;
00215 if (pkt_seen_list_last == PKT_SEEN_LIST_SIZE) {
00216 pkt_seen_list_last = 0;
00217 }
00218 pkt_seen_list[pkt_seen_list_last].pkt_id = packet.d.pkt_id;
00219 pkt_seen_list[pkt_seen_list_last].source_addr = packet.d.source_addr;
00220 } else {
00221 #ifdef PKT_DEBUG
00222 serial_print_str(" seen ");
00223 #endif
00224 }
00225 }
00226 else
00227
00228 if (pkt_seen(packet.d.pkt_id, packet.d.source_addr)) {
00229
00230 status = PKT_STATUS_SEEN_BEFORE;
00231 } else
00232
00233 if (packet.d.source_addr == pkt_my_addr) {
00234 status = PKT_STATUS_I_AM_SENDER;
00235 } else
00236
00237 if (packet.d.r1_addr == 0xffff) {
00238 status = PKT_STATUS_DIRECT_SEND;
00239 } else
00240
00241 if ((packet.d.r1_addr == pkt_my_addr) || (packet.d.r2_addr == pkt_my_addr) ||
00242 (packet.d.r3_addr == pkt_my_addr)) {
00243 status = PKT_STATUS_PREVIOUS_ROUTED_VIA_ME;
00244 } else
00245
00246 if (packet.d.r3_addr != 0) {
00247 status = PKT_STATUS_ROUTING_FULL;
00248 } else {
00249 status = PKT_STATUS_NEED_TO_REBROADCAST;
00250
00251 if (packet.d.r1_addr == 0) {
00252 packet.d.r1_addr = pkt_my_addr;
00253 } else if (packet.d.r2_addr == 0) {
00254 packet.d.r2_addr = pkt_my_addr;
00255 } else {
00256 packet.d.r3_addr = pkt_my_addr;
00257 }
00258
00259 pkt_calc_check_byte(&packet);
00260
00261 pkt_queue_packet(&packet, PKT_FLAG_NO_RESEND);
00262
00263
00264 }
00265
00266 return status;
00267 }
00268
00269 #ifdef PKT_USE_24L01
00270 inline void pkt_send_packet(rf_packet *packet) {
00271
00272
00273 uns8 count;
00274
00275 #ifdef PKT_DEBUG
00276 print_str(" <S>");
00277 #endif
00278 #ifdef PKT_DEBUG_HIGH
00279 pkt_print_packet(packet);
00280 #endif
00281
00282
00283
00284
00285
00286
00287
00288 pic_rf_transmit((uns8 *)packet, PKT_PACKET_SIZE);
00289 }
00290
00291 #else
00292 inline void pkt_send_packet(rf_packet *packet) {
00293
00294 uns8 tx_buffer[PKT_PACKET_SIZE + 3];
00295 uns8 count;
00296
00297 #ifdef PKT_DEBUG
00298 serial_print_str(" <S>");
00299 #endif
00300 #ifdef PKT_DEBUG_HIGH
00301 pkt_print_packet(packet);
00302 #endif
00303 tx_buffer[0] = 0b11100111;
00304 tx_buffer[1] = 0b11100111;
00305 tx_buffer[2] = 0b11100111;
00306 for (count = 0; count < PKT_PACKET_SIZE; count++) {
00307 tx_buffer[count+3] = packet->a[count];
00308 }
00309 pic_rf_transmit(tx_buffer, PKT_PACKET_SIZE + 3);
00310
00311 }
00312
00313
00314 #endif
00315
00316
00317
00318 void pkt_process_tx_queue() {
00319
00320 uns8 count;
00321 uns16 current_tick;
00322 uns8 sent_count;
00323 uns8 flag;
00324 sending_item *item;
00325
00326 current_tick = tick_get_count();
00327
00328 for (count = 0; count < PKT_TX_QUEUE_SIZE; count++) {
00329 item = &pkt_tx_queue[count];
00330 flag = item->flag;
00331 if (flag != PKT_FLAG_DELETED) {
00332 sent_count = item->sent_count;
00333 if (sent_count + 1 >= PKT_SEND_MAX_TRIES) {
00334 item->flag = PKT_FLAG_DELETED;
00335 #ifdef PKT_CALLBACK_ON_SEND_FAILED
00336 pkt_send_failed_callback(item->packet.d.dest_addr, item->packet.d.pkt_id);
00337 #endif
00338 #ifdef PKT_DEBUG
00339 serial_print_str(" SF!\n ");
00340 #endif
00341 } else if ((sent_count == 0)
00342 || (tick_calc_diff(item->tick_sent, current_tick)
00343 > PKT_RESEND_TICK_DELAY*sent_count + count)) {
00344
00345 item->tick_sent = current_tick;
00346 pkt_send_packet((rf_packet*)item);
00347 if (flag == PKT_FLAG_NO_RESEND) {
00348 item->flag = PKT_FLAG_DELETED;
00349 #ifdef PKT_DEBUG_HIGH
00350 serial_print_str(" SNR ");
00351 pkt_print_packet((rf_packet*)item);
00352 #endif
00353
00354 } else {
00355 item->sent_count++;
00356 #ifdef PKT_DEBUG_HIGH
00357 serial_print_str("SC ");
00358 serial_print_int(pkt_tx_queue[count].sent_count);
00359 serial_print_spc();
00360 #endif
00361
00362
00363 if (item->packet.d.r1_addr == 0xffff) {
00364 item->packet.d.r1_addr = 0;
00365 }
00366 }
00367 }
00368 }
00369 }
00370 }
00371
00372
00373 void pkt_init(uns16 my_addr, uns16 last_sent_id) {
00374
00375 uns8 count;
00376 uns16 current_tick;
00377
00378 pkt_my_addr = my_addr;
00379 pkt_my_next_pkt_id = last_sent_id + 1;
00380 for (count = 0; count < PKT_TX_QUEUE_SIZE; count++) {
00381 pkt_tx_queue[count].flag = PKT_FLAG_DELETED;
00382 }
00383
00384 for (count = 0; count < PKT_SEEN_LIST_SIZE; count++ ) {
00385 pkt_seen_list[count].source_addr = 0xffff;
00386 }
00387 }
00388
00389
00390 uns8 pkt_send_payload(uns16 dest_addr, uns8 *payload, uns8 resend) {
00391
00392 rf_packet my_packet;
00393 uns8 result;
00394 uns8 count;
00395 #ifdef PKT_DEBUG_HIGH
00396 serial_print_str("\npkt send d:");
00397 serial_print_int(dest_addr);
00398 serial_print_str("s: ");
00399 serial_print_int(pkt_my_addr);
00400 serial_print_str("\n");
00401 #endif
00402
00403
00404
00405 my_packet.d.source_addr = pkt_my_addr;
00406 my_packet.d.pkt_id = pkt_my_next_pkt_id++;
00407 my_packet.d.dest_addr = dest_addr;
00408 my_packet.d.r1_addr = 0;
00409 if (dest_addr != PKT_BROADCAST_ADDR) {
00410 my_packet.d.r1_addr = PKT_DIRECT_SEND_ADDR;
00411 }
00412 my_packet.d.r2_addr = 0;
00413 my_packet.d.r3_addr = 0;
00414 for (count = 0; count < PKT_PAYLOAD_SIZE; count++) {
00415 my_packet.d.payload[count] = payload[count];
00416 }
00417 pkt_calc_check_byte(&my_packet);
00418
00419 #ifdef PKT_DEBUG_HIGH
00420 serial_print_str(" PS");
00421 pkt_print_packet(&my_packet);
00422 #endif
00423
00424
00425
00426 result = pkt_queue_packet(&my_packet, resend);
00427 }
00428
00429
00430
00431