StreamPassInterface.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /**
  2. * @file StreamPassInterface.h
  3. * @author Ambroz Bizjak <ambrop7@gmail.com>
  4. *
  5. * @section LICENSE
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * 3. Neither the name of the author nor the
  15. * names of its contributors may be used to endorse or promote products
  16. * derived from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  19. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  20. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  21. * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  22. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  23. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  24. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  25. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  27. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. *
  29. * @section DESCRIPTION
  30. *
  31. * Interface allowing a stream sender to pass stream data to a stream receiver.
  32. *
  33. * Note that this interface behaves exactly the same and has the same code as
  34. * {@link StreamRecvInterface} if names and its external semantics are disregarded.
  35. * If you modify this file, you should probably modify {@link StreamRecvInterface}
  36. * too.
  37. */
  38. #ifndef BADVPN_FLOW_STREAMPASSINTERFACE_H
  39. #define BADVPN_FLOW_STREAMPASSINTERFACE_H
  40. #include <stdint.h>
  41. #include <stddef.h>
  42. #include <misc/debug.h>
  43. #include <base/DebugObject.h>
  44. #include <base/BPending.h>
  45. #define SPI_STATE_NONE 1
  46. #define SPI_STATE_OPERATION_PENDING 2
  47. #define SPI_STATE_BUSY 3
  48. #define SPI_STATE_DONE_PENDING 4
  49. typedef void (*StreamPassInterface_handler_send) (void *user, uint8_t *data, int data_len);
  50. typedef void (*StreamPassInterface_handler_done) (void *user, int data_len);
  51. typedef struct {
  52. // provider data
  53. StreamPassInterface_handler_send handler_operation;
  54. void *user_provider;
  55. // user data
  56. StreamPassInterface_handler_done handler_done;
  57. void *user_user;
  58. // operation job
  59. BPending job_operation;
  60. uint8_t *job_operation_data;
  61. int job_operation_len;
  62. // done job
  63. BPending job_done;
  64. int job_done_len;
  65. // state
  66. int state;
  67. DebugObject d_obj;
  68. } StreamPassInterface;
  69. static void StreamPassInterface_Init (StreamPassInterface *i, StreamPassInterface_handler_send handler_operation, void *user, BPendingGroup *pg);
  70. static void StreamPassInterface_Free (StreamPassInterface *i);
  71. static void StreamPassInterface_Done (StreamPassInterface *i, int data_len);
  72. static void StreamPassInterface_Sender_Init (StreamPassInterface *i, StreamPassInterface_handler_done handler_done, void *user);
  73. static void StreamPassInterface_Sender_Send (StreamPassInterface *i, uint8_t *data, int data_len);
  74. void _StreamPassInterface_job_operation (StreamPassInterface *i);
  75. void _StreamPassInterface_job_done (StreamPassInterface *i);
  76. void StreamPassInterface_Init (StreamPassInterface *i, StreamPassInterface_handler_send handler_operation, void *user, BPendingGroup *pg)
  77. {
  78. // init arguments
  79. i->handler_operation = handler_operation;
  80. i->user_provider = user;
  81. // set no user
  82. i->handler_done = NULL;
  83. // init jobs
  84. BPending_Init(&i->job_operation, pg, (BPending_handler)_StreamPassInterface_job_operation, i);
  85. BPending_Init(&i->job_done, pg, (BPending_handler)_StreamPassInterface_job_done, i);
  86. // set state
  87. i->state = SPI_STATE_NONE;
  88. DebugObject_Init(&i->d_obj);
  89. }
  90. void StreamPassInterface_Free (StreamPassInterface *i)
  91. {
  92. DebugObject_Free(&i->d_obj);
  93. // free jobs
  94. BPending_Free(&i->job_done);
  95. BPending_Free(&i->job_operation);
  96. }
  97. void StreamPassInterface_Done (StreamPassInterface *i, int data_len)
  98. {
  99. ASSERT(i->state == SPI_STATE_BUSY)
  100. ASSERT(data_len > 0)
  101. ASSERT(data_len <= i->job_operation_len)
  102. DebugObject_Access(&i->d_obj);
  103. // schedule done
  104. i->job_done_len = data_len;
  105. BPending_Set(&i->job_done);
  106. // set state
  107. i->state = SPI_STATE_DONE_PENDING;
  108. }
  109. void StreamPassInterface_Sender_Init (StreamPassInterface *i, StreamPassInterface_handler_done handler_done, void *user)
  110. {
  111. ASSERT(handler_done)
  112. ASSERT(!i->handler_done)
  113. DebugObject_Access(&i->d_obj);
  114. i->handler_done = handler_done;
  115. i->user_user = user;
  116. }
  117. void StreamPassInterface_Sender_Send (StreamPassInterface *i, uint8_t *data, int data_len)
  118. {
  119. ASSERT(data_len > 0)
  120. ASSERT(data)
  121. ASSERT(i->state == SPI_STATE_NONE)
  122. ASSERT(i->handler_done)
  123. DebugObject_Access(&i->d_obj);
  124. // schedule operation
  125. i->job_operation_data = data;
  126. i->job_operation_len = data_len;
  127. BPending_Set(&i->job_operation);
  128. // set state
  129. i->state = SPI_STATE_OPERATION_PENDING;
  130. }
  131. #endif