message_queue.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #include "../include/message_queue.h"
  2. MessageQueue* message_queue_alloc() {
  3. MessageQueue* queue = malloc(sizeof(MessageQueue));
  4. queue->queueSize = PWNAGOTCHI_PROTOCOL_QUEUE_SIZE;
  5. queue->messageQueue = malloc(sizeof(uint8_t) * queue->queueSize);
  6. // Set everything to 0
  7. memset(queue->messageQueue, 0, queue->queueSize);
  8. queue->writePtr = queue->messageQueue;
  9. queue->readPtr = queue->messageQueue;
  10. return queue;
  11. }
  12. void message_queue_free(MessageQueue* queue) {
  13. free(queue->messageQueue);
  14. free(queue);
  15. queue = NULL;
  16. }
  17. bool message_queue_has_message(MessageQueue* queue) {
  18. // Make sure readPtr is at the beginning of a message
  19. if(*(queue->readPtr) != PWNAGOTCHI_PROTOCOL_START) {
  20. return false;
  21. }
  22. // Now keep looking forward through the queue until we hit a 0 or the end byte
  23. bool alreadyWrapped = false;
  24. for(uint8_t* cursor = queue->readPtr;; cursor++) {
  25. // Let's check if we should wrap around
  26. if(cursor >= queue->messageQueue + queue->queueSize) {
  27. if(alreadyWrapped) {
  28. return false;
  29. }
  30. cursor = queue->messageQueue;
  31. alreadyWrapped = true;
  32. }
  33. // Otherwise see if we're at an end byte
  34. if(*cursor == PWNAGOTCHI_PROTOCOL_END) {
  35. return true;
  36. } else if(*cursor == 0x00) {
  37. return false;
  38. }
  39. }
  40. }
  41. void message_queue_push_byte(MessageQueue* queue, uint8_t data) {
  42. *(queue->writePtr) = data;
  43. // Now increment writePtr
  44. queue->writePtr += 1;
  45. // Check to make sure we didn't exceed the size
  46. if(queue->writePtr >= queue->messageQueue + queue->queueSize) {
  47. // Then start writing over the front again
  48. queue->writePtr = queue->messageQueue;
  49. }
  50. }
  51. void message_queue_wipe(MessageQueue* queue) {
  52. // Set everything to 0
  53. memset(queue->messageQueue, 0, queue->queueSize);
  54. queue->readPtr = queue->messageQueue;
  55. queue->writePtr = queue->messageQueue;
  56. }
  57. bool message_queue_validate(MessageQueue* queue) {
  58. UNUSED(queue);
  59. /* AS OF RIGHT NOW VALIDATE IS NOT IMPLEMENTED
  60. // Loop through and confirm that each message is a valid byte
  61. for (size_t ii = 0; ii < queue->queueSize - PWNAGOTCHI_PROTOCOL_BYTE_LEN; ii += PWNAGOTCHI_PROTOCOL_BYTE_LEN) {
  62. if (queue->messageQueue[ii] == 0 && queue->messageQueue[ii + PWNAGOTCHI_PROTOCOL_BYTE_LEN - 1] == 0) {
  63. continue;
  64. }
  65. if (!(queue->messageQueue[ii] == PWNAGOTCHI_PROTOCOL_START &&
  66. queue->messageQueue[ii + PWNAGOTCHI_PROTOCOL_BYTE_LEN - 1] == PWNAGOTCHI_PROTOCOL_END)) {
  67. // This means it failed so we should wipe and breka
  68. message_queue_wipe(queue);
  69. return false;
  70. }
  71. }
  72. */
  73. return true;
  74. }
  75. bool message_queue_pop_message(MessageQueue* queue, PwnCommand* dest) {
  76. if(!message_queue_has_message(queue)) {
  77. return false;
  78. }
  79. // Otherwise let's grab the message! Currently readPtr is pointing at STX
  80. dest->parameterCode = *(queue->readPtr + 1);
  81. // Wipe current arguments to hold 0's
  82. memset(dest->arguments, 0, PWNAGOTCHI_PROTOCOL_ARGS_MAX);
  83. // Everything folowing is arguments until we hit the end
  84. // We'll count up the number of bytes in the transmission to know how many to wipe
  85. int argCount;
  86. for(argCount = 0; argCount < PWNAGOTCHI_PROTOCOL_ARGS_MAX; argCount++) {
  87. uint8_t* bytePtr = queue->readPtr + 2 + argCount;
  88. // Wrap around if needed
  89. if(bytePtr >= queue->messageQueue + queue->queueSize) {
  90. bytePtr = queue->messageQueue;
  91. }
  92. if(*bytePtr == PWNAGOTCHI_PROTOCOL_END) {
  93. break;
  94. }
  95. dest->arguments[argCount] = *bytePtr;
  96. }
  97. // STX + CODE + args + ETX
  98. size_t messageSize = 1 + 1 + argCount + 1;
  99. // Let's reset that message so we don't run across it again
  100. memset(queue->readPtr, 0, messageSize);
  101. // Now increment the readPtr
  102. queue->readPtr += messageSize;
  103. // Check if we are overflowing!
  104. if(queue->readPtr >= queue->messageQueue + queue->queueSize) {
  105. // Then start reading back from the front
  106. queue->readPtr = queue->messageQueue;
  107. }
  108. return true;
  109. }