12 #include "remote_bitbang.h"
21 /////////// Circular buffer
24 unsigned int circular_buffer_t
<T
>::size() const
29 return end
+ capacity
- start
;
33 void circular_buffer_t
<T
>::consume(unsigned int bytes
)
35 start
= (start
+ bytes
) % capacity
;
39 unsigned int circular_buffer_t
<T
>::contiguous_empty_size() const
43 return capacity
- end
- 1;
45 return capacity
- end
;
47 return start
- end
- 1;
51 unsigned int circular_buffer_t
<T
>::contiguous_data_size() const
56 return capacity
- start
;
60 void circular_buffer_t
<T
>::data_added(unsigned int bytes
)
63 assert(end
<= capacity
);
69 void circular_buffer_t
<T
>::reset()
76 void circular_buffer_t
<T
>::append(const T
*src
, unsigned int count
)
78 unsigned int copy
= std::min(count
, contiguous_empty_size());
79 memcpy(contiguous_empty(), src
, copy
* sizeof(T
));
83 assert(count
< contiguous_empty_size());
84 memcpy(contiguous_empty(), src
+copy
, count
* sizeof(T
));
89 /////////// remote_bitbang_t
91 remote_bitbang_t::remote_bitbang_t(uint16_t port
, sim_t
*sim
) :
97 socket_fd
= socket(AF_INET
, SOCK_STREAM
, 0);
98 if (socket_fd
== -1) {
99 fprintf(stderr
, "remote_bitbang failed to make socket: %s (%d)\n",
100 strerror(errno
), errno
);
104 fcntl(socket_fd
, F_SETFL
, O_NONBLOCK
);
106 if (setsockopt(socket_fd
, SOL_SOCKET
, SO_REUSEADDR
, &reuseaddr
,
107 sizeof(int)) == -1) {
108 fprintf(stderr
, "remote_bitbang failed setsockopt: %s (%d)\n",
109 strerror(errno
), errno
);
113 struct sockaddr_in addr
;
114 memset(&addr
, 0, sizeof(addr
));
115 addr
.sin_family
= AF_INET
;
116 addr
.sin_addr
.s_addr
= INADDR_ANY
;
117 addr
.sin_port
= htons(port
);
119 if (bind(socket_fd
, (struct sockaddr
*) &addr
, sizeof(addr
)) == -1) {
120 fprintf(stderr
, "remote_bitbang failed to bind socket: %s (%d)\n",
121 strerror(errno
), errno
);
125 if (listen(socket_fd
, 1) == -1) {
126 fprintf(stderr
, "remote_bitbang failed to listen on socket: %s (%d)\n",
127 strerror(errno
), errno
);
132 void remote_bitbang_t::accept()
134 client_fd
= ::accept(socket_fd
, NULL
, NULL
);
135 if (client_fd
== -1) {
136 if (errno
== EAGAIN
) {
137 // No client waiting to connect right now.
139 fprintf(stderr
, "failed to accept on socket: %s (%d)\n", strerror(errno
),
144 fcntl(client_fd
, F_SETFL
, O_NONBLOCK
);
148 void remote_bitbang_t::read()
150 // Reading from a non-blocking socket still blocks if there is no data
153 size_t count
= recv_buf
.contiguous_empty_size();
154 ssize_t bytes
= ::read(client_fd
, recv_buf
.contiguous_empty(), count
);
156 if (errno
== EAGAIN
) {
157 // We'll try again the next call.
159 fprintf(stderr
, "failed to read on socket: %s (%d)\n", strerror(errno
), errno
);
162 } else if (bytes
== 0) {
163 // The remote disconnected.
168 recv_buf
.data_added(bytes
);
169 D(fprintf(stderr
, "receive buffer: "));
170 for (unsigned i
= 0; i
< recv_buf
.size(); i
++) {
171 D(fprintf(stderr
, "%c", recv_buf
[i
]));
173 D(fprintf(stderr
, "\n"));
177 void remote_bitbang_t::write()
179 if (send_buf
.empty())
182 while (!send_buf
.empty()) {
183 unsigned int count
= send_buf
.contiguous_data_size();
185 ssize_t bytes
= ::write(client_fd
, send_buf
.contiguous_data(), count
);
187 fprintf(stderr
, "failed to write to socket: %s (%d)\n", strerror(errno
), errno
);
189 } else if (bytes
== 0) {
190 // Client can't take any more data right now.
193 D(fprintf(stderr
, "wrote %zd bytes: ", bytes
));
194 for (int i
= 0; i
< bytes
; i
++) {
195 D(fprintf(stderr
, "%c", send_buf
[i
]));
197 D(fprintf(stderr
, "\n"));
198 send_buf
.consume(bytes
);
203 void remote_bitbang_t::tick()