diff --git a/meshconsole/main.c b/meshconsole/main.c index 08dba62..1c14780 100644 --- a/meshconsole/main.c +++ b/meshconsole/main.c @@ -384,3 +384,21 @@ char* crashMemory = ILib_POSIX_InstallCrashHandler(argv[0]); #endif return retCode; } + +extern void* gILibChain; +void _fdsnap() +{ + char val[] = "require('ChainViewer').getSnapshot().then(function(c) { console.log(c); console.log(require('ChainViewer').getTimerInfo()); });"; + duk_eval_string_noresult(agentHost->meshCoreCtx, val); +} +void _fdsnap2() +{ + char val[] = "console.setDestination(console.Destinations.LOGFILE);require('ChainViewer').getSnapshot().then(function(c) { console.log(c); console.log(require('ChainViewer').getTimerInfo()); });"; + duk_eval_string_noresult(agentHost->meshCoreCtx, val); +} +void _timerinfo() +{ + char *s = ILibChain_GetMetadataForTimers(gILibChain); + printf("%s\n", s); + ILibMemory_Free(s); +} \ No newline at end of file diff --git a/meshcore/KVM/MacOS/mac_events.c b/meshcore/KVM/MacOS/mac_events.c index c90b34c..28bc6bd 100644 --- a/meshcore/KVM/MacOS/mac_events.c +++ b/meshcore/KVM/MacOS/mac_events.c @@ -236,9 +236,42 @@ void MouseAction(double absX, double absY, int button, short wheel) if (source != NULL) CFRelease(source); } +extern int set_kbd_state(int state); +extern int get_kbd_state(); void KeyAction(unsigned char vk, int up) { //ILIBLOGMESSAGEX("NORMAL: %u [%d]", vk, up); + if (up == 4) { up = 0; } + + if (up && (vk == 0x14 || vk == 0x90 || vk == 0x91)) + { + int state = get_kbd_state(); + + switch (vk) + { + case 0x14: // CAPS LOCK + state = set_kbd_state(state ^ 4); + break; + case 0x90: // NUM LOCK + state = set_kbd_state(state ^ 1); + break; + case 0x91: // SCROLL LOCK + state = set_kbd_state(state ^ 2); + break; + } + + unsigned char *buffer = ILibMemory_SmartAllocate(5); + ((unsigned short*)buffer)[0] = (unsigned short)htons((unsigned short)MNG_KVM_KEYSTATE); // Write the type + ((unsigned short*)buffer)[1] = (unsigned short)htons((unsigned short)5); // Write the size + buffer[4] = (unsigned char)get_kbd_state(); + + // Write the reply to the pipe. + ILibQueue_Lock(g_messageQ); + ILibQueue_EnQueue(g_messageQ, buffer); + ILibQueue_UnLock(g_messageQ); + return; + } + int i; CGKeyCode keycode; diff --git a/meshcore/KVM/MacOS/mac_kvm.c b/meshcore/KVM/MacOS/mac_kvm.c index 505ba9a..df73599 100644 --- a/meshcore/KVM/MacOS/mac_kvm.c +++ b/meshcore/KVM/MacOS/mac_kvm.c @@ -21,11 +21,15 @@ limitations under the License. #include "../../../microstack/ILibAsyncSocket.h" #include "../../../microstack/ILibAsyncServerSocket.h" #include "../../../microstack/ILibProcessPipe.h" +#include +#include +#include #include #include #include #include + int KVM_Listener_FD = -1; #define KVM_Listener_Path "/usr/local/mesh_services/meshagent/kvm" #if defined(_TLSLOG) @@ -92,7 +96,7 @@ ILibQueue g_messageQ; #define KvmDebugLog(...) -//#define KvmDebugLog(...) printf(__VA_ARGS__); //if (logfile != NULL) fprintf(logfile, __VA_ARGS__); +//#define KvmDebugLog(...) printf(__VA_ARGS__); if (logfile != NULL) fprintf(logfile, __VA_ARGS__); //#define KvmDebugLog(x) if (logenabled) printf(x); //#define KvmDebugLog(x) if (logenabled) fprintf(logfile, "Writing from slave in kvm_send_resolution\n"); @@ -129,6 +133,138 @@ void kvm_send_resolution() #define BUFSIZE 65535 +int set_kbd_state(int input_state) +{ + int ret = 0; + kern_return_t kr; + io_service_t ios; + io_connect_t ioc; + CFMutableDictionaryRef mdict; + + while (1) + { + mdict = IOServiceMatching(kIOHIDSystemClass); + ios = IOServiceGetMatchingService(kIOMasterPortDefault, (CFDictionaryRef)mdict); + if (!ios) + { + if (mdict) + { + CFRelease(mdict); + } + ILIBLOGMESSAGEX("IOServiceGetMatchingService() failed\n"); + break; + } + + kr = IOServiceOpen(ios, mach_task_self(), kIOHIDParamConnectType, &ioc); + IOObjectRelease(ios); + if (kr != KERN_SUCCESS) + { + ILIBLOGMESSAGEX("IOServiceOpen() failed: %x\n", kr); + break; + } + + // Set CAPSLOCK + kr = IOHIDSetModifierLockState(ioc, kIOHIDCapsLockState, (input_state & 4) == 4); + if (kr != KERN_SUCCESS) + { + IOServiceClose(ioc); + ILIBLOGMESSAGEX("IOHIDGetModifierLockState() failed: %x\n", kr); + break; + } + + // Set NUMLOCK + kr = IOHIDSetModifierLockState(ioc, kIOHIDNumLockState, (input_state & 1) == 1); + if (kr != KERN_SUCCESS) + { + IOServiceClose(ioc); + ILIBLOGMESSAGEX("IOHIDGetModifierLockState() failed: %x\n", kr); + break; + } + + // CAPSLOCK_QUERY + bool state; + kr = IOHIDGetModifierLockState(ioc, kIOHIDCapsLockState, &state); + if (kr != KERN_SUCCESS) + { + IOServiceClose(ioc); + ILIBLOGMESSAGEX("IOHIDGetModifierLockState() failed: %x\n", kr); + break; + } + ret |= (state << 2); + + // NUMLOCK_QUERY + kr = IOHIDGetModifierLockState(ioc, kIOHIDNumLockState, &state); + if (kr != KERN_SUCCESS) + { + IOServiceClose(ioc); + ILIBLOGMESSAGEX("IOHIDGetModifierLockState() failed: %x\n", kr); + break; + } + ret |= state; + + IOServiceClose(ioc); + break; + } + return(ret); +} +int get_kbd_state() +{ + int ret = 0; + kern_return_t kr; + io_service_t ios; + io_connect_t ioc; + CFMutableDictionaryRef mdict; + + while (1) + { + mdict = IOServiceMatching(kIOHIDSystemClass); + ios = IOServiceGetMatchingService(kIOMasterPortDefault, (CFDictionaryRef)mdict); + if (!ios) + { + if (mdict) + { + CFRelease(mdict); + } + ILIBLOGMESSAGEX("IOServiceGetMatchingService() failed\n"); + break; + } + + kr = IOServiceOpen(ios, mach_task_self(), kIOHIDParamConnectType, &ioc); + IOObjectRelease(ios); + if (kr != KERN_SUCCESS) + { + ILIBLOGMESSAGEX("IOServiceOpen() failed: %x\n", kr); + break; + } + + // CAPSLOCK_QUERY + bool state; + kr = IOHIDGetModifierLockState(ioc, kIOHIDCapsLockState, &state); + if (kr != KERN_SUCCESS) + { + IOServiceClose(ioc); + ILIBLOGMESSAGEX("IOHIDGetModifierLockState() failed: %x\n", kr); + break; + } + ret |= (state << 2); + + // NUMLOCK_QUERY + kr = IOHIDGetModifierLockState(ioc, kIOHIDNumLockState, &state); + if (kr != KERN_SUCCESS) + { + IOServiceClose(ioc); + ILIBLOGMESSAGEX("IOHIDGetModifierLockState() failed: %x\n", kr); + break; + } + ret |= state; + + IOServiceClose(ioc); + break; + } + return(ret); +} + + int kvm_init() { ILibCriticalLogFilename = "KVMSlave.log"; @@ -157,9 +293,17 @@ int kvm_init() if (SCREEN_HEIGHT % TILE_HEIGHT) { TILE_HEIGHT_COUNT++; } kvm_send_resolution(); - reset_tile_info(old_height_count); + unsigned char *buffer = ILibMemory_SmartAllocate(5); + ((unsigned short*)buffer)[0] = (unsigned short)htons((unsigned short)MNG_KVM_KEYSTATE); // Write the type + ((unsigned short*)buffer)[1] = (unsigned short)htons((unsigned short)5); // Write the size + buffer[4] = (unsigned char)get_kbd_state(); + + // Write the reply to the pipe. + ILibQueue_Lock(g_messageQ); + ILibQueue_EnQueue(g_messageQ, buffer); + ILibQueue_UnLock(g_messageQ); return 0; } diff --git a/microstack/ILibParsers.c b/microstack/ILibParsers.c index 6672224..8899d85 100644 --- a/microstack/ILibParsers.c +++ b/microstack/ILibParsers.c @@ -99,6 +99,9 @@ limitations under the License. #define PORTNUMBERRANGE 15000 #define UPNP_MAX_WAIT 86400 // 24 Hours +extern void _fdsnap(); +extern void _fdsnap2(); + #ifdef _REMOTELOGGINGSERVER #include "ILibWebServer.h" #endif @@ -3231,6 +3234,9 @@ char *ILibChain_GetMetaDataFromDescriptorSetEx(void *chain, fd_set *inr, fd_set int f, r; size_t tmp; size_t buflen = 0; + struct timeval tv = { 0 }; + fd_set temp_readset, temp_writeset, temp_errorset; + int bad; while(1) { @@ -3286,13 +3292,25 @@ char *ILibChain_GetMetaDataFromDescriptorSetEx(void *chain, fd_set *inr, fd_set { if (FD_ISSET(f, &readset) || FD_ISSET(f, &writeset) || FD_ISSET(f, &errorset)) { + bad = 0; + if (!FD_ISSET(f, inr) && !FD_ISSET(f, inw) && !FD_ISSET(f, ine)) + { + FD_ZERO(&temp_readset); + FD_ZERO(&temp_writeset); + FD_ZERO(&temp_errorset); + if (FD_ISSET(f, &readset)) { FD_SET(f, &temp_readset); } + if (FD_ISSET(f, &writeset)) { FD_SET(f, &temp_writeset); } + if (FD_ISSET(f, &errorset)) { FD_SET(f, &temp_errorset); } + bad = select(FD_SETSIZE, &temp_readset, &temp_writeset, &temp_errorset, &tv) == -1 ? 1 : 0; + } + if (retStr == NULL) { - buflen += snprintf(NULL, 0, " FD[%d] (R: %d, W: %d, E: %d) => %s\n", f, FD_ISSET(f, inr), FD_ISSET(f, inw), FD_ISSET(f, ine), ((ILibChain_Link*)module)->QueryHandler != NULL ? ((ILibChain_Link*)module)->QueryHandler(chain, module, f, &tmp) : ((ILibChain_Link*)module)->MetaData); + buflen += snprintf(NULL, 0, "%sFD[%d] (R: %d, W: %d, E: %d) => %s\n", bad==0?"":"*", f, FD_ISSET(f, inr), FD_ISSET(f, inw), FD_ISSET(f, ine), ((ILibChain_Link*)module)->QueryHandler != NULL ? ((ILibChain_Link*)module)->QueryHandler(chain, module, f, &tmp) : ((ILibChain_Link*)module)->MetaData); } else { - r = sprintf_s(retStr + len, ILibMemory_Size(retStr) - len, " FD[%d] (R: %d, W: %d, E: %d) => %s\n", f, FD_ISSET(f, inr), FD_ISSET(f, inw), FD_ISSET(f, ine), ((ILibChain_Link*)module)->QueryHandler != NULL ? ((ILibChain_Link*)module)->QueryHandler(chain, module, f, &tmp) : ((ILibChain_Link*)module)->MetaData); + r = sprintf_s(retStr + len, ILibMemory_Size(retStr) - len, " %sFD[%d] (R: %d, W: %d, E: %d) => %s\n", bad == 0 ? "" : "*", f, FD_ISSET(f, inr), FD_ISSET(f, inw), FD_ISSET(f, ine), ((ILibChain_Link*)module)->QueryHandler != NULL ? ((ILibChain_Link*)module)->QueryHandler(chain, module, f, &tmp) : ((ILibChain_Link*)module)->MetaData); if (r > 0) { len += r; } } } @@ -3386,6 +3404,7 @@ char *ILibChain_GetMetadataForTimers(void *chain) double ex = (double)(Temp->ExpirationTick - current); char *units = "milliseconds"; + if (ex < 0) { ex = 0; } if (ex > 1000) { ex = ex / 1000; @@ -3959,12 +3978,12 @@ ILibExportMethod void ILibStartChain(void *Chain) ILibChain_Link *module; ILibChain_Link_Hook *nodeHook; - fd_set readset; - fd_set errorset; - fd_set writeset; + fd_set readset, tmp_readset; + fd_set errorset, tmp_errorset; + fd_set writeset, tmp_writeset; - struct timeval tv; - int slct; + struct timeval tv, tmp_tv = { 0 }; + int slct, f; int vX; // @@ -4072,11 +4091,35 @@ ILibExportMethod void ILibStartChain(void *Chain) if (slct == -1) { // - // If the select simply timed out, we need to clear these sets + // One of the descriptors was invalid // - FD_ZERO(&readset); - FD_ZERO(&writeset); - FD_ZERO(&errorset); + for (f = 0; f < FD_SETSIZE; ++f) + { + if (FD_ISSET(f, &readset) || FD_ISSET(f, &writeset) || FD_ISSET(f, &errorset)) + { + FD_ZERO(&tmp_readset); + FD_ZERO(&tmp_writeset); + FD_ZERO(&tmp_errorset); + if (FD_ISSET(f, &readset)) { FD_SET(f, &tmp_readset); } + if (FD_ISSET(f, &writeset)) { FD_SET(f, &tmp_writeset); } + if (FD_ISSET(f, &errorset)) { FD_SET(f, &tmp_errorset); } + if (select(FD_SETSIZE, &tmp_readset, &tmp_writeset, &tmp_errorset, &tmp_tv) == -1) + { + // Found the bad descriptor... Let's dump it + FD_CLR(f, &readset); + FD_CLR(f, &writeset); + FD_CLR(f, &errorset); + } + } + } + + if ((slct = select(FD_SETSIZE, &readset, &writeset, &errorset, &tv)) == -1) + { + // Something went wrong, so we have no other choice but to clear the sets + FD_ZERO(&readset); + FD_ZERO(&writeset); + FD_ZERO(&errorset); + } } #ifndef WIN32 @@ -7565,6 +7608,8 @@ ILibLifeTime_Token ILibLifeTime_AddEx4(void *LifetimeMonitorObject, void *data, if (Destroy != NULL) { Destroy(data); } return(NULL); } + ILibLifeTime_Remove(LifetimeMonitorObject, data); + ltms = (struct LifeTimeMonitorData*)ILibMemory_SmartAllocate(sizeof(struct LifeTimeMonitorData)); //