From 2a537311063d3e49479ff4cc8b94287a10c37266 Mon Sep 17 00:00:00 2001 From: AntiCat Date: Mon, 8 Oct 2018 07:15:29 +0200 Subject: [PATCH] osx: disable app-nap during serial comm (#687) Apple introduced app-nap with OS X 10.10. This feature saves power by throttling apps running in background. However, it also less accurate timers in systemcalls. In our case a 30ms select timeout would take up to 10s. This patch uses an API also added with 10.10 to disable app-nap as long as the serial port is polled. --- CHANGELOG.md | 1 + client/Makefile | 18 +++++++++++++----- client/comms.c | 9 +++++++++ client/util_darwin.h | 17 +++++++++++++++++ client/util_darwin.m | 40 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 client/util_darwin.h create mode 100644 client/util_darwin.m diff --git a/CHANGELOG.md b/CHANGELOG.md index 73306b1f..993dd636 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Changed start sequence in Qt mode (fix: short commands hangs main Qt thread) (Merlok) - Changed driver file proxmark3.inf to support both old and new Product/Vendor IDs (piwi) - Changed all command line parsers in `hf emv` commands to argtable (Merlok) +- Implemented AppNap API, fixing #283 and #627 OSX USB comm issues (AntiCat) ### Added - Added `sc` smartcard (contact card) commands - reader, info, raw, upgrade, setclock, list (hardware version RDV4.0 only) must turn option on in makefile options (Willok, Iceman, marshmellow) diff --git a/client/Makefile b/client/Makefile index 90b16830..96f610cd 100644 --- a/client/Makefile +++ b/client/Makefile @@ -37,10 +37,12 @@ endif LUAPLATFORM = generic platform = $(shell uname) ifneq (,$(findstring MINGW,$(platform))) - LUAPLATFORM = mingw + LUAPLATFORM = mingw else ifeq ($(platform),Darwin) LUAPLATFORM = macosx + OBJCSRCS = util_darwin.m + LDFLAGS += -framework Foundation else LUALIB += -ldl LDLIBS += -ltermcap -lncurses @@ -210,6 +212,7 @@ QTGUISRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp guidummy.cpp COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o) CMDOBJS = $(CMDSRCS:%.c=$(OBJDIR)/%.o) +OBJCOBJS = $(OBJCSRCS:%.m=$(OBJDIR)/%.o) ZLIBOBJS = $(ZLIBSRCS:%.c=$(OBJDIR)/%.o) MULTIARCHOBJS = $(MULTIARCHSRCS:%.c=$(OBJDIR)/%_NOSIMD.o) \ $(MULTIARCHSRCS:%.c=$(OBJDIR)/%_MMX.o) \ @@ -235,7 +238,7 @@ endif BINS = proxmark3 flasher fpga_compress WINBINS = $(patsubst %, %.exe, $(BINS)) -CLEAN = $(BINS) $(WINBINS) $(COREOBJS) $(CMDOBJS) $(ZLIBOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(OBJDIR)/*.o *.moc.cpp ui/ui_overlays.h +CLEAN = $(BINS) $(WINBINS) $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(ZLIBOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(OBJDIR)/*.o *.moc.cpp ui/ui_overlays.h # need to assign dependancies to build these first... all: lua_build jansson_build $(BINS) @@ -244,10 +247,10 @@ all-static: LDLIBS:=-static $(LDLIBS) all-static: proxmark3 flasher fpga_compress proxmark3: LDLIBS+=$(LUALIB) $(JANSSONLIB) $(QTLDLIBS) -proxmark3: $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(ZLIBOBJS) lualibs/usb_cmd.lua - $(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(ZLIBOBJS) $(LDLIBS) -o $@ +proxmark3: $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(ZLIBOBJS) lualibs/usb_cmd.lua + $(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(ZLIBOBJS) $(LDLIBS) -o $@ -flasher: $(OBJDIR)/flash.o $(OBJDIR)/flasher.o $(COREOBJS) +flasher: $(OBJDIR)/flash.o $(OBJDIR)/flasher.o $(COREOBJS) $(OBJCOBJS) $(LD) $(LDFLAGS) $^ $(LDLIBS) -o $@ fpga_compress: $(OBJDIR)/fpga_compress.o $(ZLIBOBJS) @@ -310,6 +313,10 @@ $(OBJDIR)/%.o : %.cpp $(OBJDIR)/%.d $(CXX) $(DEPFLAGS) $(CXXFLAGS) $(QTINCLUDES) -c -o $@ $< $(POSTCOMPILE) +%.o: %.m +$(OBJDIR)/%.o : %.m $(OBJDIR)/%.d + $(CC) $(DEPFLAGS) $(CFLAGS) -c -o $@ $< + $(POSTCOMPILE) #$(CMDOBJS) $(COREOBJS): $(notdir $(%.c)) %.d # $(CC) $(DEPFLAGS) $(CFLAGS) -c -o $@ $< @@ -325,6 +332,7 @@ $(OBJDIR)/%.o : %.cpp $(OBJDIR)/%.d DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(CORESRCS) $(CMDSRCS) $(ZLIBSRCS) $(MULTIARCHSRCS)) \ $(patsubst %.cpp, $(OBJDIR)/%.d, $(QTGUISRCS)) \ + $(patsubst %.m, $(OBJDIR)/%.d, $(OBJCSRCS)) \ $(OBJDIR)/proxmark3.d $(OBJDIR)/flash.d $(OBJDIR)/flasher.d $(OBJDIR)/fpga_compress.d $(DEPENDENCY_FILES): ; diff --git a/client/comms.c b/client/comms.c index 0c4efa73..190b9110 100644 --- a/client/comms.c +++ b/client/comms.c @@ -18,6 +18,7 @@ #include "uart.h" #include "ui.h" #include "common.h" +#include "util_darwin.h" #include "util_posix.h" @@ -198,6 +199,10 @@ __attribute__((force_align_arg_pointer)) UsbCommand rx; UsbCommand *prx = ℞ +#if defined(__MACH__) && defined(__APPLE__) + disableAppNap("Proxmark3 polling UART"); +#endif + while (conn->run) { rxlen = 0; bool ACK_received = false; @@ -236,6 +241,10 @@ __attribute__((force_align_arg_pointer)) pthread_mutex_unlock(&txBufferMutex); } +#if defined(__MACH__) && defined(__APPLE__) + enableAppNap(); +#endif + pthread_exit(NULL); return NULL; } diff --git a/client/util_darwin.h b/client/util_darwin.h new file mode 100644 index 00000000..923a4dfc --- /dev/null +++ b/client/util_darwin.h @@ -0,0 +1,17 @@ +//----------------------------------------------------------------------------- +// (c) 2018 AntiCat +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// macOS framework bindings +//----------------------------------------------------------------------------- + +#ifndef UTIL_DARWIN_H__ +#define UTIL_DARWIN_H__ + +void disableAppNap(const char* reason); +void enableAppNap(); + +#endif \ No newline at end of file diff --git a/client/util_darwin.m b/client/util_darwin.m new file mode 100644 index 00000000..d07ebebc --- /dev/null +++ b/client/util_darwin.m @@ -0,0 +1,40 @@ +//----------------------------------------------------------------------------- +// (c) 2018 AntiCat +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// macOS framework bindings +//----------------------------------------------------------------------------- + +#import "util_darwin.h" + +#import +#import + +static id activity = nil; + +//OS X Version 10.10 is defined in OS X 10.10 and later +#if defined(MAC_OS_X_VERSION_10_10) +void disableAppNap(const char* reason) { + if(activity == nil) { + //NSLog(@"disableAppNap: %@", @(reason)); + activity = [[NSProcessInfo processInfo] beginActivityWithOptions:NSActivityBackground reason:@(reason)]; + [activity retain]; + } +} + +void enableAppNap() { + if(activity != nil) { + //NSLog(@"enableAppNap"); + [[NSProcessInfo processInfo] endActivity:activity]; + [activity release]; + activity = nil; + } +} + +#else +void disableAppNap(const char* reason) { } +void enableAppNap() { } +#endif -- 2.39.5