From e29adc1159df9bfd1a60e306611ee851b6da4061 Mon Sep 17 00:00:00 2001 From: "matthias.ringwald" Date: Wed, 7 Oct 2009 20:17:19 +0000 Subject: [PATCH] add support for Cocoa CoreFoundation run loop - not fully implemented but usable by clients, use ms instead of s for run_loop_set_timer function --- TODO.txt | 7 -- configure.in | 50 ++++++++--- example/mitm.c | 1 + example/rfcomm.c | 1 + example/test.c | 1 + include/btstack/run_loop.h | 24 ++++- project.xcodeproj/project.pbxproj | 16 +++- src/Makefile.in | 5 +- src/btstack.c | 1 + src/daemon.c | 4 +- src/hci.c | 3 +- src/run_loop.c | 144 ++++++++++++++++++++++++++++++ src/run_loop_cocoa.m | 48 +++++++++- src/run_loop_posix.c | 72 +++++---------- 14 files changed, 293 insertions(+), 84 deletions(-) create mode 100644 src/run_loop.c diff --git a/TODO.txt b/TODO.txt index 8d6c4c572..c1ed33a01 100644 --- a/TODO.txt +++ b/TODO.txt @@ -5,13 +5,6 @@ Last change: use single packet handler on client side NEXT: - -- support Cocoa CFRunLoop in addition to POSIX select run loop - - define struct run_loop_t - - run_loop_posix.c: run_loop_t * BTstack_run_loop = run_loop_posix; - - convert all run_loop calls to use (*BTstack_run_loop->functionX)(..) - - new btstack_open(RUN_LOOP_MODE mode) allows to choose between both - - implement missing functions in run_loop_cocoa: remove data source and timer functions - prepare WiiMoteDemo for release - update to current stack version - add inquiry code diff --git a/configure.in b/configure.in index bf232b955..041058c24 100644 --- a/configure.in +++ b/configure.in @@ -11,7 +11,7 @@ AC_ARG_WITH(uart-device, [AS_HELP_STRING([--with-uart-device=uartDevice], [Speci AC_ARG_WITH(uart-speed, [AS_HELP_STRING([--with-uart-speed=uartSpeed], [Specify BT UART speed to use])], UART_SPEED=$withval, UART_SPEED="115200") AC_ARG_ENABLE(bluetool, [AS_HELP_STRING([--disable-bluetool],[Disable init of Bluetooth module by BlueTool])], USE_BLUETOOL=$enableval, USE_BLUETOOL="DEFAULT") AC_ARG_ENABLE(springboard, [AS_HELP_STRING([--disable-springboard],[Disable display of BTstack status in SpringBoard])], USE_SPRINGBOARD=$enableval, USE_SPRINGBOARD="DEFAULT") -AC_ARG_ENABLE(launchd, [AS_HELP_STRING([--enable-launchd],[Compiles BTdaemon for use by launchd])], USE_LAUNCHD=$enableval, USE_LAUNCHD="NO") +AC_ARG_ENABLE(launchd, [AS_HELP_STRING([--enable-launchd],[Compiles BTdaemon for use by launchd])], USE_LAUNCHD=$enableval, USE_LAUNCHD="no") AC_ARG_WITH(iphone-ip, [AS_HELP_STRING([--with-iphone-ip=192.168.1.5], [Specify IP address used by iPhone for installation (not supported yet)])], IPHONE_IP=$withval, IPHONE_IP="") AC_ARG_WITH(vendor-id, [AS_HELP_STRING([--with-vendor-id=vendorID], [Specify USB BT Dongle vendorID])], USB_VENDOR_ID=$withval, USB_VENDOR_ID="") AC_ARG_WITH(product-id, [AS_HELP_STRING([--with-product-id=productID], [Specify USB BT Dongle productID])], USB_PRODUCT_ID=$withval, USB_PRODUCT_ID="") @@ -58,10 +58,21 @@ if test "x$HCI_TRANSPORT" = xUSB; then fi AM_CONDITIONAL(HAVE_LIBUSB, [test "x$HAVE_LIBUSB" == "xyes"]) - echo echo "BTstack configured for HCI $HCI_TRANSPORT Transport" +RUN_LOOP_SOURCES=run_loop_posix.c +case "$host_os" in + darwin*) + RUN_LOOP_SOURCES="$RUN_LOOP_SOURCES run_loop_cocoa.m" + LDFLAGS="$LDFLAGS -framework CoreFoundation" + USE_COCOA_RUN_LOOP="yes" + ;; + *) + USE_COCOA_RUN_LOOP="no" + ;; +esac + # iPhone/iPod touch cross-compilation for darwin DEVELOPER_PATH="/Developer/Platforms/iPhoneOS.platform/Developer" SDK_VERSION="2.0" @@ -96,12 +107,10 @@ if test "x$target" = xiphone; then USE_BLUETOOL="yes" echo "USE_BLUETOOL: $USE_BLUETOOL" fi + if test "x$USE_SPRINGBOARD" = xDEFAULT ; then USE_SPRINGBOARD="yes" - echo "USE_SPRINGBOARD: $USE_SPRINGBOARD" - SPRINGBOARD_ACCESS_SOURCES="../SpringBoardAccess/SpringBoardAccess.c" fi - echo "USE_LAUNCHD: $USE_LAUNCHD" if test "x$USE_LDID" = xyes ; then USE_LDID="" @@ -110,13 +119,16 @@ if test "x$target" = xiphone; then USE_LDID="#" echo "USE_LDID: no" fi - else USE_LDID="#" if test "x$UART_DEVICE" = xDEFAULT ; then UART_DEVICE=/dev/ttyS0 fi + if test "x$USE_SPRINGBOARD" = xDEFAULT ; then + USE_SPRINGBOARD="no" + fi fi + AM_CONDITIONAL(USE_SPRINGBOARD, [test "x$USE_SPRINGBOARD" == "xyes"]) # summary @@ -126,9 +138,14 @@ if test "x$HCI_TRANSPORT" = xUSB; then echo "LIBUSB_CFLAGS: $LIBUSB_CFLAGS" echo "LIBUSB_LIBS: $LIBUSB_LIBS" else - echo "UART_DEVICE: $UART_DEVICE" - echo "UART_SPEED: $UART_SPEED" + echo "UART_DEVICE: $UART_DEVICE" + echo "UART_SPEED: $UART_SPEED" fi + +echo "USE_LAUNCHD: $USE_LAUNCHD" +echo "USE_SPRINGBOARD: $USE_SPRINGBOARD" +echo "USE_COCOA_RUN_LOOP: $USE_COCOA_RUN_LOOP" +echo echo # create config.h @@ -144,16 +161,21 @@ else if test "x$USE_BLUETOOL" = xyes; then echo "#define USE_BLUETOOL" >> config.h fi - if test "x$USE_SPRINGBOARD" = xyes; then - echo "#define USE_SPRINGBOARD" >> config.h - fi - if test "x$USE_LAUNCHD" = xyes; then - echo "#define USE_LAUNCHD" >> config.h - fi +fi +if test "x$USE_SPRINGBOARD" = xyes; then + SPRINGBOARD_ACCESS_SOURCES="../SpringBoardAccess/SpringBoardAccess.c" + echo "#define USE_SPRINGBOARD" >> config.h +fi +if test "x$USE_LAUNCHD" = xyes; then + echo "#define USE_LAUNCHD" >> config.h +fi +if test "x$USE_COCOA_RUN_LOOP" = xyes; then + echo "#define USE_COCOA_RUN_LOOP" >> config.h fi AC_SUBST(IPHONE_IP) AC_SUBST(HAVE_LIBUSB) AC_SUBST(USE_LDID) AC_SUBST(SPRINGBOARD_ACCESS_SOURCES) +AC_SUBST(RUN_LOOP_SOURCES) AC_OUTPUT(Makefile src/Makefile example/Makefile SpringBoardAccess/Makefile) diff --git a/example/mitm.c b/example/mitm.c index 08ddd8dd2..30945af53 100644 --- a/example/mitm.c +++ b/example/mitm.c @@ -222,6 +222,7 @@ int main (int argc, const char * argv[]){ } // start stack + run_loop_init(RUN_LOOP_POSIX); int err = bt_open(); if (err) { printf("Failed to open connection to BTdaemon\n"); diff --git a/example/rfcomm.c b/example/rfcomm.c index adeee45d5..08e698324 100644 --- a/example/rfcomm.c +++ b/example/rfcomm.c @@ -127,6 +127,7 @@ void packet_handler(uint8_t packet_type, uint8_t *packet, uint16_t size){ } int main (int argc, const char * argv[]){ + run_loop_init(RUN_LOOP_POSIX); int err = bt_open(); if (err) { printf("Failed to open connection to BTdaemon\n"); diff --git a/example/test.c b/example/test.c index e5b916bf7..ae4eaa14c 100644 --- a/example/test.c +++ b/example/test.c @@ -117,6 +117,7 @@ void packet_handler(uint8_t packet_type, uint8_t *packet, uint16_t size){ } int main (int argc, const char * argv[]){ + run_loop_init(RUN_LOOP_POSIX); int err = bt_open(); if (err) { printf("Failed to open connection to BTdaemon\n"); diff --git a/include/btstack/run_loop.h b/include/btstack/run_loop.h index bd13d2106..5266d26b3 100644 --- a/include/btstack/run_loop.h +++ b/include/btstack/run_loop.h @@ -10,6 +10,11 @@ #include +typedef enum { + RUN_LOOP_POSIX = 1, + RUN_LOOP_COCOA +} RUN_LOOP_TYPE; + typedef struct data_source { linked_item_t item; int fd; // <-- file descriptors to watch or 0 @@ -22,8 +27,11 @@ typedef struct timer { void (*process)(struct timer *ts); // <-- do processing } timer_t; +// init must be called before any other run_loop call +void run_loop_init(RUN_LOOP_TYPE type); + // set timer based on current time -void run_loop_set_timer(timer_t *a, int timeout_in_seconds); +void run_loop_set_timer(timer_t *a, int timeout_in_ms); // compare timeval or timers - NULL is assumed to be before the Big Bang int run_loop_timeval_compare(struct timeval *a, struct timeval *b); @@ -35,6 +43,18 @@ int run_loop_remove_data_source(data_source_t *dataSource); // <-- remove Data void run_loop_add_timer(timer_t *timer); // <-- add Timer to RunLoop int run_loop_remove_timer(timer_t *timer); // <-- remove Timer from RunLoop +void run_loop_execute(); // <-- execute configured RunLoop + void run_loop_timer_dump(); // debug -void run_loop_execute(); // <-- execute configured RunLoop + +// internal use only +typedef struct { + void (*init)(); + void (*add_data_source)(data_source_t *dataSource); + int (*remove_data_source)(data_source_t *dataSource); + void (*add_timer)(timer_t *timer); + int (*remove_timer)(timer_t *timer); + void (*execute)(); + void (*dump_timer)(); +} run_loop_t; diff --git a/project.xcodeproj/project.pbxproj b/project.xcodeproj/project.pbxproj index 6b5431744..30344bba4 100644 --- a/project.xcodeproj/project.pbxproj +++ b/project.xcodeproj/project.pbxproj @@ -13,6 +13,9 @@ 9C00F86410191097008DAB17 /* utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C00F86210191097008DAB17 /* utils.c */; }; 9C00F86510191097008DAB17 /* utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C00F86210191097008DAB17 /* utils.c */; }; 9C00F87410191130008DAB17 /* l2cap_signaling.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C00F87210191130008DAB17 /* l2cap_signaling.c */; }; + 9C04B826107D1CED002A63D0 /* run_loop.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C04B825107D1CED002A63D0 /* run_loop.c */; }; + 9C04B876107D2B7C002A63D0 /* run_loop_cocoa.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CEB4DAA10753B4B00DD5720 /* run_loop_cocoa.m */; }; + 9C04B87A107D2BA7002A63D0 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C04B879107D2BA7002A63D0 /* CoreFoundation.framework */; }; 9C05FC971020D3F300255261 /* socket_connection.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C00F7301017ACC3008DAB17 /* socket_connection.c */; }; 9C2071F310014D3200A07EA4 /* hci_transport_usb.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C2071F210014D3200A07EA4 /* hci_transport_usb.c */; }; 9C46FC3A0FA906F700ABEF05 /* hci_transport_h4.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C46FC360FA906F700ABEF05 /* hci_transport_h4.c */; }; @@ -27,8 +30,7 @@ 9CC813A20FFC0774002816F9 /* btstack.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CC813A10FFC0774002816F9 /* btstack.c */; }; 9CC813A50FFC0A51002816F9 /* daemon.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CC813A40FFC0A51002816F9 /* daemon.c */; }; 9CCE6CEA1025BD0000FCE9F4 /* hci.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C46FC340FA906F700ABEF05 /* hci.c */; }; - 9CEB4DAB10753B4B00DD5720 /* run_loop_cocoa.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CEB4DAA10753B4B00DD5720 /* run_loop_cocoa.m */; }; - 9CEB4DAD10753BE600DD5720 /* run_loop_posix.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CEB4DAC10753BE600DD5720 /* run_loop_posix.c */; }; + 9CEB4F17107AAAEF00DD5720 /* run_loop_posix.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CEB4DAC10753BE600DD5720 /* run_loop_posix.c */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -51,6 +53,8 @@ 9C00F86210191097008DAB17 /* utils.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = utils.c; path = src/utils.c; sourceTree = ""; }; 9C00F87110191130008DAB17 /* l2cap_signaling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = l2cap_signaling.h; path = src/l2cap_signaling.h; sourceTree = ""; }; 9C00F87210191130008DAB17 /* l2cap_signaling.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = l2cap_signaling.c; path = src/l2cap_signaling.c; sourceTree = ""; }; + 9C04B825107D1CED002A63D0 /* run_loop.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = run_loop.c; path = src/run_loop.c; sourceTree = ""; }; + 9C04B879107D2BA7002A63D0 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = ""; }; 9C1813F71042FCCA00C68F09 /* mitm.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = mitm.c; path = example/mitm.c; sourceTree = ""; }; 9C2071F210014D3200A07EA4 /* hci_transport_usb.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = hci_transport_usb.c; path = src/hci_transport_usb.c; sourceTree = ""; }; 9C46FC340FA906F700ABEF05 /* hci.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = hci.c; path = src/hci.c; sourceTree = ""; }; @@ -106,6 +110,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 9C04B87A107D2BA7002A63D0 /* CoreFoundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -132,6 +137,7 @@ 1AB674ADFE9D54B511CA2CBB /* Products */, 9CC152C61009052100223347 /* config.h */, 9CA3C0900FB8B3C4005F48DE /* TODO.txt */, + 9C04B879107D2BA7002A63D0 /* CoreFoundation.framework */, ); name = project; sourceTree = ""; @@ -160,6 +166,7 @@ 9C00F87110191130008DAB17 /* l2cap_signaling.h */, 9C00F87210191130008DAB17 /* l2cap_signaling.c */, 9C7B5ABF100BD3340065D87E /* linked_list.c */, + 9C04B825107D1CED002A63D0 /* run_loop.c */, 9CEB4DAA10753B4B00DD5720 /* run_loop_cocoa.m */, 9CEB4DAC10753BE600DD5720 /* run_loop_posix.c */, 9C00F7301017ACC3008DAB17 /* socket_connection.c */, @@ -320,8 +327,9 @@ 9C00F87410191130008DAB17 /* l2cap_signaling.c in Sources */, 9CCE6CEA1025BD0000FCE9F4 /* hci.c in Sources */, 9C77E79210667F0600F39DCF /* platform_iphone.c in Sources */, - 9CEB4DAB10753B4B00DD5720 /* run_loop_cocoa.m in Sources */, - 9CEB4DAD10753BE600DD5720 /* run_loop_posix.c in Sources */, + 9CEB4F17107AAAEF00DD5720 /* run_loop_posix.c in Sources */, + 9C04B826107D1CED002A63D0 /* run_loop.c in Sources */, + 9C04B876107D2B7C002A63D0 /* run_loop_cocoa.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/src/Makefile.in b/src/Makefile.in index fd95410c6..93f77ab1d 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -5,7 +5,7 @@ prefix = @prefix@ springboard_access_sources = @SPRINGBOARD_ACCESS_SOURCES@ -libBTstack_SOURCES = btstack.c hci_cmds.c linked_list.c run_loop_posix.c socket_connection.c utils.c +libBTstack_SOURCES = btstack.c hci_cmds.c linked_list.c run_loop.c run_loop_posix.c run_loop_cocoa.m socket_connection.c utils.c BTdaemon_SOURCES = $(libBTstack_SOURCES) \ bt_control_iphone.c \ @@ -37,7 +37,8 @@ clean: rm -f libBTstack* BTdaemon *.o install: - echo "installing BTdaemon in $(prefix)" + echo "installing BTdaemon in $(prefix)..." mkdir -p $(prefix)/lib $(prefix)/include cp libBTstack.a libBTstack.dylib $(prefix)/lib/ + cp BTdaemon $(prefix)/bin/ cp -r ../include/btstack $(prefix)/include diff --git a/src/btstack.c b/src/btstack.c index 9e725c530..9dac9852e 100644 --- a/src/btstack.c +++ b/src/btstack.c @@ -56,6 +56,7 @@ int bt_send_cmd(hci_cmd_t *cmd, ...){ } int btstack_packet_handler(connection_t *connection, uint16_t packet_type, uint16_t channel, uint8_t *data, uint16_t size){ + // printf("BTstack client handler: packet type %u, data[0] %x\n", packet_type, data[0]); (*client_packet_handler)(packet_type, data, size); return 0; } diff --git a/src/daemon.c b/src/daemon.c index f324ca522..2200a7c81 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -39,7 +39,7 @@ #include "hci_transport_usb.h" #endif -#define DAEMON_NO_CONNECTION_TIMEOUT 60 +#define DAEMON_NO_CONNECTION_TIMEOUT 60000 static hci_transport_t * transport; static hci_uart_config_t config; @@ -211,6 +211,8 @@ int main (int argc, const char * argv[]){ bluetooth_status_handler = platform_iphone_status_handler; #endif + run_loop_init(RUN_LOOP_POSIX); + // @TODO: allow configuration per HCI CMD // use logger: format HCI_DUMP_PACKETLOGGER, HCI_DUMP_BLUEZ or HCI_DUMP_STDOUT diff --git a/src/hci.c b/src/hci.c index 75588334f..ef156e240 100644 --- a/src/hci.c +++ b/src/hci.c @@ -15,7 +15,7 @@ // temp #include "l2cap.h" -#define HCI_CONNECTION_TIMEOUT 10 +#define HCI_CONNECTION_TIMEOUT 10000 // the STACK is here static hci_stack_t hci_stack; @@ -303,7 +303,6 @@ int hci_power_control(HCI_POWER_MODE power_mode){ } void hci_run(){ - uint8_t micro_packet; switch (hci_stack.state){ case HCI_STATE_INITIALIZING: if (hci_stack.substate % 2) { diff --git a/src/run_loop.c b/src/run_loop.c new file mode 100644 index 000000000..24c7a7974 --- /dev/null +++ b/src/run_loop.c @@ -0,0 +1,144 @@ +/* + * run_loop.c + * + * Created by Matthias Ringwald on 6/6/09. + */ + +#include + +#include +#include // exit() + + +#include "../config.h" + +static run_loop_t * the_run_loop = NULL; + +extern run_loop_t run_loop_posix; + +#ifdef USE_COCOA_RUN_LOOP +extern run_loop_t run_loop_cocoa; +#endif + +// assert run loop initialized +void run_loop_assert(){ + if (!the_run_loop){ + fprintf(stderr, "ERROR: run_loop function called before run_loop_init!\n"); + exit(10); + } +} + +/** + * Add data_source to run_loop + */ +void run_loop_add_data_source(data_source_t *ds){ + run_loop_assert(); + the_run_loop->add_data_source(ds); +} + +/** + * Remove data_source from run loop + */ +int run_loop_remove_data_source(data_source_t *ds){ + run_loop_assert(); + return the_run_loop->remove_data_source(ds); +} + +/** + * Add timer to run_loop (keep list sorted) + */ +void run_loop_add_timer(timer_t *ts){ + run_loop_assert(); + the_run_loop->add_timer(ts); +} + +/** + * Remove timer from run loop + */ +int run_loop_remove_timer(timer_t *ts){ + run_loop_assert(); + return the_run_loop->remove_timer(ts); +} + +void run_loop_timer_dump(){ + run_loop_assert(); + return the_run_loop->dump_timer(); +} + +/** + * Execute run_loop + */ +void run_loop_execute() { + run_loop_assert(); + the_run_loop->execute(); +} + +// init must be called before any other run_loop call +void run_loop_init(RUN_LOOP_TYPE type){ + if (the_run_loop){ + fprintf(stderr, "ERROR: run loop initialized twice!\n"); + exit(10); + } + switch (type) { + case RUN_LOOP_POSIX: + the_run_loop = &run_loop_posix; + break; +#ifdef USE_COCOA_RUN_LOOP + case RUN_LOOP_COCOA: + the_run_loop = &run_loop_cocoa; + break; +#endif + default: + fprintf(stderr, "ERROR: invalid run loop type %u selected!\n", type); + exit(10); + break; + } + the_run_loop->init(); +} + +// set timer +void run_loop_set_timer(timer_t *a, int timeout_in_ms){ + gettimeofday(&a->timeout, NULL); + a->timeout.tv_sec += timeout_in_ms / 1000; + a->timeout.tv_usec += (timeout_in_ms % 1000) * 1000; + if (a->timeout.tv_usec > 1000000) { + a->timeout.tv_usec -= 1000000; + a->timeout.tv_sec++; + } +} + +// compare timers - NULL is assumed to be before the Big Bang +// pre: 0 <= tv_usec < 1000000 +int run_loop_timeval_compare(struct timeval *a, struct timeval *b){ + if (!a || !b) return 0; + if (!a) return -1; + if (!b) return 1; + + if (a->tv_sec < b->tv_sec) { + return -1; + } + if (a->tv_sec > b->tv_sec) { + return 1; + } + + if (a->tv_usec < b->tv_usec) { + return -1; + } + if (a->tv_usec > b->tv_usec) { + return 1; + } + + return 0; + +} + +// compare timers - NULL is assumed to be before the Big Bang +// pre: 0 <= tv_usec < 1000000 +int run_loop_timer_compare(timer_t *a, timer_t *b){ + if (!a || !b) return 0; + if (!a) return -1; + if (!b) return 1; + return run_loop_timeval_compare(&a->timeout, &b->timeout); +} + + diff --git a/src/run_loop_cocoa.m b/src/run_loop_cocoa.m index 6d8fde146..02d8fabd3 100644 --- a/src/run_loop_cocoa.m +++ b/src/run_loop_cocoa.m @@ -9,6 +9,9 @@ #import #import +#include +#include + static void socketDataCallback ( CFSocketRef s, CFSocketCallBackType callbackType, @@ -20,7 +23,7 @@ static void socketDataCallback ( ds->process(ds); } -void run_loop_add_data_source(data_source_t *dataSource){ +void cocoa_add_data_source(data_source_t *dataSource){ // add fd as CF "socket" @@ -43,8 +46,49 @@ void run_loop_add_data_source(data_source_t *dataSource){ CFRunLoopAddSource( CFRunLoopGetCurrent(), socketRunLoop, kCFRunLoopDefaultMode); } -int run_loop_remove_data_source(data_source_t *dataSource){ +int cocoa_remove_data_source(data_source_t *dataSource){ // not needed yet + fprintf(stderr, "WARNING: run_loop_remove_data_source not implemented yet!"); + // warning never the less + return 0; +} +void cocoa_add_timer(timer_t * ts){ + // not needed yet + fprintf(stderr, "WARNING: run_loop_add_timer not implemented yet!"); + // warning never the less +} + +int cocoa_remove_timer(timer_t * ts){ + // not needed yet + fprintf(stderr, "WARNING: run_loop_remove_timer not implemented yet!"); + // warning never the less return 0; } +void cocoa_init(){ +} + +void cocoa_execute(){ + // not needed yet + fprintf(stderr, "WARNING: execute not available for RUN_LOOP_COCOA!"); + // warning never the less + exit(10); +} + +void cocoa_dump_timer(){ + // not needed yet + fprintf(stderr, "WARNING: run_loop_dump_timer not implemented yet!"); + // warning never the less + return; +} + +const run_loop_t run_loop_cocoa = { + &cocoa_init, + &cocoa_add_data_source, + &cocoa_remove_data_source, + &cocoa_add_timer, + &cocoa_remove_timer, + &cocoa_execute, + &cocoa_dump_timer +}; + diff --git a/src/run_loop_posix.c b/src/run_loop_posix.c index 5be438e46..4691e43eb 100644 --- a/src/run_loop_posix.c +++ b/src/run_loop_posix.c @@ -12,67 +12,27 @@ #include // the run loop -static linked_list_t data_sources = NULL; -static linked_list_t timers = NULL; - -// set timer -void run_loop_set_timer(timer_t *a, int timeout_in_seconds){ - gettimeofday(&a->timeout, NULL); - a->timeout.tv_sec += timeout_in_seconds; -} - -// compare timers - NULL is assumed to be before the Big Bang -// pre: 0 <= tv_usec < 1000000 -int run_loop_timeval_compare(struct timeval *a, struct timeval *b){ - if (!a || !b) return 0; - if (!a) return -1; - if (!b) return 1; - - if (a->tv_sec < b->tv_sec) { - return -1; - } - if (a->tv_sec > b->tv_sec) { - return 1; - } - - if (a->tv_usec < b->tv_usec) { - return -1; - } - if (a->tv_usec > b->tv_usec) { - return 1; - } - - return 0; - -} - -// compare timers - NULL is assumed to be before the Big Bang -// pre: 0 <= tv_usec < 1000000 -int run_loop_timer_compare(timer_t *a, timer_t *b){ - if (!a || !b) return 0; - if (!a) return -1; - if (!b) return 1; - return run_loop_timeval_compare(&a->timeout, &b->timeout); -} +static linked_list_t data_sources; +static linked_list_t timers; /** * Add data_source to run_loop */ -void run_loop_add_data_source(data_source_t *ds){ +void posix_add_data_source(data_source_t *ds){ linked_list_add(&data_sources, (linked_item_t *) ds); } /** * Remove data_source from run loop */ -int run_loop_remove_data_source(data_source_t *ds){ +int posix_remove_data_source(data_source_t *ds){ return linked_list_remove(&data_sources, (linked_item_t *) ds); } /** * Add timer to run_loop (keep list sorted) */ -void run_loop_add_timer(timer_t *ts){ +void posix_add_timer(timer_t *ts){ linked_item_t *it; for (it = (linked_item_t *) &timers; it ; it = it->next){ if ( run_loop_timer_compare( (timer_t *) it->next, ts) >= 0) { @@ -86,23 +46,23 @@ void run_loop_add_timer(timer_t *ts){ /** * Remove timer from run loop */ -int run_loop_remove_timer(timer_t *ts){ +int posix_remove_timer(timer_t *ts){ return linked_list_remove(&timers, (linked_item_t *) ts); } -void run_loop_timer_dump(){ +void posix_dump_timer(){ linked_item_t *it; int i = 0; for (it = (linked_item_t *) timers; it ; it = it->next){ timer_t *ts = (timer_t*) it; - printf("timer %u, timeout %u\n", i, ts->timeout.tv_sec); + printf("timer %u, timeout %u\n", i, (unsigned int) ts->timeout.tv_sec); } } /** * Execute run_loop */ -void run_loop_execute() { +void posix_execute() { fd_set descriptors; data_source_t *ds; timer_t *ts; @@ -166,5 +126,17 @@ void run_loop_execute() { } } +void posix_init(){ + data_sources = NULL; + timers = NULL; +} - +const run_loop_t run_loop_posix = { + &posix_init, + &posix_add_data_source, + &posix_remove_data_source, + &posix_add_timer, + &posix_remove_timer, + &posix_execute, + &posix_dump_timer +};