From e12093a478955b4d5140ba5fec9cb407dc0d241e Mon Sep 17 00:00:00 2001 From: Joseph Poirier Date: Sat, 19 Dec 2015 14:18:48 -0600 Subject: [PATCH] mock test async read --- mock_test/Makefile | 4 +- mock_test/gortlsdr/librtlsdr.c | 206 ++++++++++++--------------------- mock_test/main.go | 46 +++++--- 3 files changed, 111 insertions(+), 145 deletions(-) diff --git a/mock_test/Makefile b/mock_test/Makefile index 5832d6c..e23c2c3 100644 --- a/mock_test/Makefile +++ b/mock_test/Makefile @@ -1,8 +1,8 @@ # all: - # cd gortlsdr && gcc -fPIC -shared -Wl,-soname,librtlsdr.so.0 -o librtlsdr.so.0 librtlsdr.c - cd gortlsdr && gcc -Wall -c librtlsdr.c -o librtlsdr.o + # cd gortlsdr && gcc -fPIC -shared -Wl,-soname,librtlsdr.so.0 -lpthread -o librtlsdr.so.0 librtlsdr.c + cd gortlsdr && gcc -Wall -c librtlsdr.c -lpthread -o librtlsdr.o cd gortlsdr && ar rcs librtlsdr.a librtlsdr.o cd gortlsdr && cp ../../rtlsdr.go . cd gortlsdr && cp ../../exports.go . diff --git a/mock_test/gortlsdr/librtlsdr.c b/mock_test/gortlsdr/librtlsdr.c index 4913238..4212f01 100644 --- a/mock_test/gortlsdr/librtlsdr.c +++ b/mock_test/gortlsdr/librtlsdr.c @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include "rtl-sdr_moc.h" @@ -25,39 +27,15 @@ #define STRINGS_OFFSET_START (9) #define MAX_RAW_STR_SZ (2*35+2) -// struct rtlsdr_dev { -// libusb_context *ctx; -// struct libusb_device_handle *devh; -// uint32_t xfer_buf_num; -// uint32_t xfer_buf_len; -// struct libusb_transfer **xfer; -// unsigned char **xfer_buf; -// rtlsdr_read_async_cb_t cb; -// void *cb_ctx; -// enum rtlsdr_async_status async_status; -// int async_cancel; -// /* rtl demod context */ -// uint32_t rate; /* Hz */ -// uint32_t rtl_xtal; /* Hz */ -// int fir[FIR_LEN]; -// int direct_sampling; -// /* tuner context */ -// enum rtlsdr_tuner tuner_type; -// rtlsdr_tuner_iface_t *tuner; -// uint32_t tun_xtal; /* Hz */ -// uint32_t freq; /* Hz */ -// uint32_t bw; -// uint32_t offs_freq; /* Hz */ -// int corr; /* ppm */ -// int gain; /* tenth dB */ -// struct e4k_state e4k_s; -// struct r82xx_config r82xx_c; -// struct r82xx_priv r82xx_p; -// /* status */ -// int dev_lost; -// int driver_active; -// unsigned int xfer_errors; -// }; + +static void do_init(void); +static bool dev_valid(rtlsdr_dev_t *dev); + +enum rtlsdr_async_status { + RTLSDR_INACTIVE = 0, + RTLSDR_CANCELING, + RTLSDR_RUNNING +}; struct rtlsdr_dev { bool status; @@ -74,7 +52,14 @@ struct rtlsdr_dev { int agc_mode; int direct_sampling_mode; int offset_tuning; + uint32_t xfer_buf_num; + uint32_t xfer_buf_len; enum rtlsdr_tuner type; + enum rtlsdr_async_status async_status; + rtlsdr_read_async_cb_t cb; + int async_cancel; + void *cb_ctx; + pthread_mutex_t lock; char eeprom_buffer[256]; int gains[DEVICE_GAIN_CNT]; char xbuf[DEFAULT_BUF_LENGTH]; @@ -97,14 +82,16 @@ strings are written as "["char", 0x00]" pairs static int device_count = DEBVICE_CNT; -struct rtlsdr_dev s0 = {0}; -struct rtlsdr_dev s1 = {0}; -struct rtlsdr_dev s2 = {0}; +static struct rtlsdr_dev s0 = {0}; +static struct rtlsdr_dev s1 = {0}; +static struct rtlsdr_dev s2 = {0}; struct rtlsdr_dev *rtlsdr_devs[DEBVICE_CNT] = {&s0, &s1, &s2}; static bool is_initialized = false; +static pthread_t tid; + void do_init(void) { if (is_initialized) return; @@ -517,21 +504,32 @@ int rtlsdr_open(rtlsdr_dev_t **out_dev, uint32_t index) { if (!out_dev) return -1; + // FIXME: + // if (pthread_mutex_init(&lock, NULL) != 0) { + // return 1; + // } + int status = 1; switch(index) { case 0: *out_dev = &s0; s0.status = true; + s0.async_status = RTLSDR_INACTIVE; + pthread_mutex_init(&s0.lock, NULL); status = 0; break; case 1: *out_dev = &s1; s1.status = true; + s1.async_status = RTLSDR_INACTIVE; + pthread_mutex_init(&s1.lock, NULL); status = 0; break; case 2: - *out_dev = &s1; + *out_dev = &s2; s2.status = true; + s2.async_status = RTLSDR_INACTIVE; + pthread_mutex_init(&s2.lock, NULL); status = 0; break; } @@ -547,7 +545,6 @@ int rtlsdr_close(rtlsdr_dev_t *dev) { return 0; } -// TODO: int rtlsdr_reset_buffer(rtlsdr_dev_t *dev) { if (!dev || !dev_valid(dev)) return -1; @@ -567,8 +564,8 @@ int rtlsdr_read_sync(rtlsdr_dev_t *dev, void *buf, int len, int *n_read) { memcpy(buf, &s0.xbuf[0], len); } else if (dev == &s1) { memcpy(buf, &s1.xbuf[0], len); - } else if (dev == &s1) { - memcpy(buf, &s1.xbuf[0], len); + } else if (dev == &s2) { + memcpy(buf, &s2.xbuf[0], len); } else { return -2; } @@ -576,7 +573,25 @@ int rtlsdr_read_sync(rtlsdr_dev_t *dev, void *buf, int len, int *n_read) { return 0; } -// TODO: +static unsigned char async_buf[DEFAULT_BUF_LENGTH]; +void read_asyn_handler(void *dev) { + struct rtlsdr_dev *d = (struct rtlsdr_dev*)dev; + rtlsdr_read_async_cb_t cb = d->cb; + // void *cb_ctx = d->cb_ctx; + + for (;;) { + pthread_mutex_lock(&d->lock); + if (d->async_status == RTLSDR_CANCELING) { + pthread_mutex_unlock(&d->lock); + break; + } + pthread_mutex_unlock(&d->lock); + cb(async_buf, DEFAULT_BUF_LENGTH, NULL); + sleep(1); + } + d->async_status = RTLSDR_INACTIVE; +} + int rtlsdr_read_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb, void *ctx, uint32_t buf_num, uint32_t buf_len) { // unsigned int i; @@ -588,108 +603,41 @@ int rtlsdr_read_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb, void *ctx, if (!dev || !dev_valid(dev)) return -1; - // if (RTLSDR_INACTIVE != dev->async_status) - // return -2; + if (RTLSDR_INACTIVE != dev->async_status) + return -2; - // dev->async_status = RTLSDR_RUNNING; - // dev->async_cancel = 0; + dev->async_status = RTLSDR_RUNNING; + dev->async_cancel = 0; - // dev->cb = cb; - // dev->cb_ctx = ctx; + dev->cb = cb; + dev->cb_ctx = ctx; - // if (buf_num > 0) - // dev->xfer_buf_num = buf_num; - // else - // dev->xfer_buf_num = DEFAULT_BUF_NUMBER; + if (buf_num > 0) + dev->xfer_buf_num = buf_num; + else + dev->xfer_buf_num = DEFAULT_BUF_NUMBER; - // if (buf_len > 0 && buf_len % 512 == 0) /* len must be multiple of 512 */ + // if (buf_len > 0 && buf_len % 512 == 0) len must be multiple of 512 // dev->xfer_buf_len = buf_len; // else - // dev->xfer_buf_len = DEFAULT_BUF_LENGTH; - - // _rtlsdr_alloc_async_buffers(dev); - - // for(i = 0; i < dev->xfer_buf_num; ++i) { - // libusb_fill_bulk_transfer(dev->xfer[i], - // dev->devh, - // 0x81, - // dev->xfer_buf[i], - // dev->xfer_buf_len, - // _libusb_callback, - // (void *)dev, - // BULK_TIMEOUT); - - // r = libusb_submit_transfer(dev->xfer[i]); - // if (r < 0) { - // fprintf(stderr, "Failed to submit transfer %i!\n", i); - // dev->async_status = RTLSDR_CANCELING; - // break; - // } - // } + dev->xfer_buf_len = DEFAULT_BUF_LENGTH; - // while (RTLSDR_INACTIVE != dev->async_status) { - // r = libusb_handle_events_timeout_completed(dev->ctx, &tv, - // &dev->async_cancel); - // if (r < 0) { - // /*fprintf(stderr, "handle_events returned: %d\n", r);*/ - // if (r == LIBUSB_ERROR_INTERRUPTED) /* stray signal */ - // continue; - // break; - // } - - // if (RTLSDR_CANCELING == dev->async_status) { - // next_status = RTLSDR_INACTIVE; - - // if (!dev->xfer) - // break; - - // for(i = 0; i < dev->xfer_buf_num; ++i) { - // if (!dev->xfer[i]) - // continue; - - // if (LIBUSB_TRANSFER_CANCELLED != - // dev->xfer[i]->status) { - // r = libusb_cancel_transfer(dev->xfer[i]); - // /* handle events after canceling - // * to allow transfer status to - // * propagate */ - // libusb_handle_events_timeout_completed(dev->ctx, - // &zerotv, NULL); - // if (r < 0) - // continue; - - // next_status = RTLSDR_CANCELING; - // } - // } - - // if (dev->dev_lost || RTLSDR_INACTIVE == next_status) { - // /* handle any events that still need to - // * be handled before exiting after we - // * just cancelled all transfers */ - // libusb_handle_events_timeout_completed(dev->ctx, - // &zerotv, NULL); - // break; - // } - // } - // } - - // _rtlsdr_free_async_buffers(dev); - - // dev->async_status = next_status; + if (pthread_create(&tid, NULL, (void*)read_asyn_handler, (void*)dev) != 0) + return -3; return 0; } -// TODO: int rtlsdr_cancel_async(rtlsdr_dev_t *dev) { if (!dev || !dev_valid(dev)) return -1; - // /* if streaming, try to cancel gracefully */ - // if (RTLSDR_RUNNING == dev->async_status) { - // dev->async_status = RTLSDR_CANCELING; - // dev->async_cancel = 1; - // return 0; - // } + // if streaming, try to cancel gracefully + pthread_mutex_lock(&dev->lock); + if (RTLSDR_RUNNING == dev->async_status) { + dev->async_status = RTLSDR_CANCELING; + dev->async_cancel = 1; + } + pthread_mutex_unlock(&dev->lock); return 0; } diff --git a/mock_test/main.go b/mock_test/main.go index 45c34c0..36d78e1 100644 --- a/mock_test/main.go +++ b/mock_test/main.go @@ -9,6 +9,7 @@ package main import ( "fmt" "log" + "time" rtl "./gortlsdr" ) @@ -334,14 +335,6 @@ func ReadSync(d *rtl.Context, i int) { } } -// func ReadAsync(d *rtl.Context, i int) { - -// } - -// func CancelAsync(d *rtl.Context, i int) { - -// } - func GetHwInfo(d *rtl.Context, i int) { if info, err := d.GetHwInfo(); err != nil { failed++ @@ -376,6 +369,13 @@ func SetHwInfo(d *rtl.Context, i int) { } } +var asyncReadCnt int + +func rtlsdrCb(buf []byte) { + asyncReadCnt++ + log.Printf("Cnt:%d, Length: %d\n", asyncReadCnt, len(buf)) +} + func main() { var cnt int @@ -505,22 +505,40 @@ func main() { GetOffsetTuning(d, i) SetOffsetTuning(d, i) - ResetBuffer(d, i) - SetHwInfo(d, i) GetHwInfo(d, i) ReadSync(d, i) - // ReadAsync(d, i) - // CancelAsync(d, i) + ResetBuffer(d, i) + asyncReadCnt = 0 + err = d.ReadAsync(rtlsdrCb, nil, rtl.DefaultAsyncBufNumber, rtl.DefaultBufLength) + if err == nil { + passed++ + log.Printf("ReadAsync start successful: %d\n", i) + + log.Printf("---Sleeping for 10 seconds while async read runs...\n") + time.Sleep(10 * time.Second) + + if err := d.CancelAsync(); err != nil { + failed++ + log.Printf("CancelAsync failed: %d - %s\n", i, err) + } else { + passed++ + log.Printf("CancelAsync successful: %d\n", i) + time.Sleep(2 * time.Second) + } + } else { + failed++ + log.Printf("\tReadAsync start fail: %d - %s\n", i, err) + } if err = d.Close(); err != nil { failed++ - log.Printf("--- FAILED, Close %s - %s...\n", err, i) + log.Printf("--- FAILED, Close %d - %s...\n", i, err) } else { passed++ - log.Println("--- PASSED, Close...") + log.Printf("--- PASSED, Close: %d\n", i) } }