int uei_508_write(int m_port, const char *m_buf, uint32_t m_len) { uint64_t written_bytes = 0; if (m_port >= 8 || m_port < 0) { blast_err("Invalid port %d", m_port); return -1; } ph_bufq_append(SL508_write_buffer[m_port], m_buf, m_len, &written_bytes); return written_bytes; }
static int bio_bufq_write(BIO *h, const char *buf, int size) { uint64_t n; ph_bufq_t *q = h->ptr; BIO_clear_retry_flags(h); if (ph_bufq_append(q, buf, size, &n) != PH_OK) { BIO_set_retry_write(h); errno = EAGAIN; return -1; } return (int)n; }
static void test_straddle_edges(void) { const char *delim = "\r\n"; int delim_len = strlen(delim); int default_buf_size = 8192; int i; char pad[8192]; memset(pad, 'x', sizeof(pad)); #define PAD_IT(__n) { \ uint64_t n = __n; \ while (n > 0) { \ ph_bufq_append(q, pad, MIN(n, sizeof(pad)), 0); \ n -= MIN(n, sizeof(pad)); \ } \ } // We want two buffers: [8192][8192] // And then to place our delimiter around the first boundary to verify // that the delimiter matching operates correctly // We define a cursor offset relative to the end of the first buffer // (0 means the last byte of the delimiter is in the last byte of the // first buffer, 1 means that the last delimiter byte is in the first // byte of the second buffer) for (i = - 2 * delim_len; i < 2 * delim_len; i++) { ph_bufq_t *q; q = ph_bufq_new(16*1024); // Fill up the start of the buffer uint64_t num_first = default_buf_size + i - delim_len; // first data PAD_IT(num_first); is(num_first, ph_bufq_len(q)); // first delim ph_bufq_append(q, delim, delim_len, 0); // second data PAD_IT(16); // second delim ph_bufq_append(q, delim, delim_len, 0); ph_buf_t *first = ph_bufq_consume_record(q, delim, delim_len); is_int(num_first + 2, ph_buf_len(first)); ph_buf_t *second = ph_bufq_consume_record(q, delim, delim_len); is_int(18, ph_buf_len(second)); diag("for i = %d, num_first = %d. first->len=%d second->len=%d", i, (int)num_first, (int)ph_buf_len(first), (int)ph_buf_len(second)); ph_buf_delref(first); ph_buf_delref(second); ph_bufq_free(q); } // Now, test the case where we have a partial match at a boundary, but not // the true match until later ph_bufq_t *q; q = ph_bufq_new(24*1024); PAD_IT(8191); ph_bufq_append(q, "\r", 1, 0); PAD_IT(8192); ph_bufq_append(q, delim, delim_len, 0); ph_buf_t *first = ph_bufq_consume_record(q, delim, delim_len); is_int(16386, ph_buf_len(first)); ph_buf_delref(first); ph_bufq_free(q); }
void *uei_508_loop(void *m_arg) { struct timespec next; uint64_t periodns = ((double)(NSEC_PER_SEC) / 10); int ret; int channel_list_508[8] = {0, 1, 2, 3, 4, 5, 6, 7}; uint32_t channel_cfg_508[8] = { CFG_485(DQ_SL501_BAUD_9600), CFG_485(DQ_SL501_BAUD_9600), CFG_485(DQ_SL501_BAUD_9600), CFG_485(DQ_SL501_BAUD_9600), CFG_485(DQ_SL501_BAUD_9600), CFG_485(DQ_SL501_BAUD_9600), CFG_485(DQ_SL501_BAUD_9600), CFG_485(DQ_SL501_BAUD_9600) }; int channel_flags_508[8] = { 0 }; ph_library_init(); ph_thread_set_name("UEI508"); blast_startup("Starting UEI 508 loop"); // set channel configuration for (int i = 0; i < 8; i++) { if ((ret = DqAdv501SetChannelCfg(hd_508, 4, i, channel_cfg_508[i])) < 0) { blast_err("Error in DqAdv501SetChannelCfg()"); } } ret = DqRtVmapAddChannel(hd_508, vmapid_508, 4, DQ_SS0IN, channel_list_508, channel_flags_508, 8); ret = DqRtVmapAddChannel(hd_508, vmapid_508, 4, DQ_SS0OUT, channel_list_508, channel_flags_508, 8); ret = DqRtVmapStart(hd_508, vmapid_508); clock_gettime(CLOCK_MONOTONIC, &next); while (!shutdown_mcp) { for (int i = 0; i < 8; i++) { size_t num_bytes; ph_buf_t *outbuf = NULL; if ((num_bytes = ph_bufq_len(SL508_write_buffer[i]))) { outbuf = ph_bufq_consume_bytes(SL508_write_buffer[i], num_bytes); DqRtVmapWriteOutput(hd_508, vmapid_508, 4, i, num_bytes, ph_buf_mem(outbuf)); ph_buf_delref(outbuf); } DqRtVmapRequestInput(hd_508, vmapid_508, 4, i, 128); } // Write output data to each TX port FIFO and Read each RX port FIFO ret = DqRtVmapRefresh(hd_508, vmapid_508, 0); // Read data received during the last refresh for (int i = 0; i < 8; i++) { uint8_t read_buffer[128]; int read_len; DqRtVmapReadInput(hd_508, vmapid_508, 4, i, sizeof(read_buffer), &read_len, read_buffer); if (read_len > 0) { ph_bufq_append(SL508_read_buffer[i], read_buffer, read_len, NULL); } } timespec_add_ns(&next, periodns); clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next, NULL); } DqRtVmapStop(hd_508, vmapid_508); DqRtVmapClose(hd_508, vmapid_508); return NULL; }