Beispiel #1
0
static void MyNetworkConnectionCallBack(
    SCNetworkConnectionRef          connection,
    SCNetworkConnectionStatus       status,
    void                            *info
)
    // Our network connection callback.  Called out of the runloop 
    // when there's a change in the status of the network connection.
    // It can be called as part of both a connection attempt and a 
    // disconnection attempt.
    //
    // In response to this callback we do two things:
    //
    // 1. Print the current connection status.
    // 2. Once the [dis]connection attempt is resolved (the status 
    //    hits either 'connected' or 'disconnected'), we stop 
    //    the runloop.  This has the effect of breaking the "main" 
    //    function out of its called to CFRunLoopRun, after which 
    //    it can examine the results of the connection.
    //
    // The "info" parameter is a pointer to our per-connection data. 
    // In this case we use this as a pointer to a CallbackParams 
    // structure.  We use this to track the previous state of the 
    // connection so that we don't print redundant status changes.
{
    CallbackParams *                params;
    SCNetworkConnectionPPPStatus    minorStatus;
    time_t                          now;
    struct tm                       nowLocal;
    char                            nowLocalStr[30];
    Boolean                         printMinorStatus;
    
    assert(connection != NULL);
    assert(info != NULL);
    params = (CallbackParams *) info;
    assert(params->magic = kCallbackParamsMagic);

    // Get a string that represents the current time.
    
    (void) time(&now);
    (void) localtime_r(&now, &nowLocal);
    (void) strftime(nowLocalStr, sizeof(nowLocalStr), "%X", &nowLocal);

    // Due to a bug <rdar://problem/3725976>, it's best to get the major status via 
    // SCNetworkConnectionGetStatus than rely on the value being passed into 
    // the callback.

    status = SCNetworkConnectionGetStatus(connection);
    
    // Get the minor status from the extended status associated with 
    // the connection.
    
    minorStatus = GetMinorStatus(connection);
    
    // Print any status changes.
    
    printMinorStatus = (params->lastMinorStatus != minorStatus);
    if (  (params->forcePrintStatus) 
       || (params->lastMajorStatus != status) 
       ) {
        fprintf(
            stderr, 
            "%s %s (%ld)\n", 
            nowLocalStr, 
            StatusToString(status), 
            (long) status
        );
        printMinorStatus = true;
        params->forcePrintStatus = false;
    }
    if (printMinorStatus) {
        fprintf(
            stderr, 
            "%s     %s (%ld)\n", 
            nowLocalStr, 
            MinorStatusToString(minorStatus), 
            (long) minorStatus
        );
    }

    // If we hit either the connected or disconnected state, 
    // we signal the runloop to stop so that the main function 
    // can process the result of the [dis]connection attempt.
    
    if (  (  minorStatus == kSCNetworkConnectionPPPDisconnected ) 
       || (  minorStatus == kSCNetworkConnectionPPPConnected    ) 
       ) {
        CFRunLoopStop(CFRunLoopGetCurrent());
    }

    // Record the new status.
    
    params->lastMajorStatus = status;
    params->lastMinorStatus = minorStatus;
}
Beispiel #2
0
int
main (int argc, const char *argv[])
{
    CFURLRef audioFileURLRef;
    OSStatus ret;

    audioFileURLRef = CFURLCreateWithFileSystemPath (
            kCFAllocatorDefault,
			/* CFSTR ("../misc/test.wav"), */
			CFSTR ("../misc/alin.wav"),
            kCFURLPOSIXPathStyle,
            FALSE
            );

    ret = AudioFileOpenURL(
            audioFileURLRef,
            kAudioFileReadWritePermission,
            0,
            &myInfo.mAudioFile);
    if (ret != noErr) {
        printf("fail to open audio file %x\n", ret);
        return 1;
    }

    UInt32 propSize = sizeof(myInfo.mDataFormat);
    ret = AudioFileGetProperty(
            myInfo.mAudioFile,
            kAudioFilePropertyDataFormat,
            &propSize,
            &myInfo.mDataFormat
            );
    if (ret != noErr) {
        printf("AudioFileGetProperty error code %d\n", ret);
        return 1;
    }
    printf("sample rate: %f\n"
            "mFormatID: %u\n"
            "mFormatFlags: %u\n"
            "mBytesPerPacket: %u\n"
            "mChannelsPerFrame: %u\n",
            myInfo.mDataFormat.mSampleRate,
            myInfo.mDataFormat.mFormatID,
            myInfo.mDataFormat.mFormatFlags,
            myInfo.mDataFormat.mBytesPerPacket,
            myInfo.mDataFormat.mChannelsPerFrame
          );

    // Instantiate an audio queue object
    ret = AudioQueueNewOutput(
            &myInfo.mDataFormat,
            AQTestBufferCallback,
            &myInfo,
            CFRunLoopGetCurrent(),
            kCFRunLoopCommonModes,
            0,
            &myInfo.mQueue
            );
    if (ret != noErr) {
        printf("AudioQueueNewOutput error code %d\n", ret);
        return 1;
    }

    AudioQueueAddPropertyListener(myInfo.mQueue, kAudioQueueProperty_IsRunning,
            AudioEnginePropertyListenerProc, &myInfo);
    

    /* FIXME allocate AudioQueue buffer */ 
    int i;
    for (i = 0; i < 3; i++) {
        AudioQueueAllocateBuffer(myInfo.mQueue, 441 * 4, &myInfo.mBuffers[i]);
    }
    AudioQueueStart(myInfo.mQueue, NULL);

    printf("Run loop\n");
    // create a system sound ID to represent the sound file
    /* OSStatus error = AudioServicesCreateSystemSoundID (myURLRef, &mySSID); */

    // Register the sound completion callback.
    // Again, useful when you need to free memory after playing.
    /* AudioServicesAddSystemSoundCompletion ( */
            /* mySSID, */
            /* NULL, */
            /* NULL, */
            /* MyCompletionCallback, */
            /* (void *) myURLRef */
            /* ); */

    // Play the sound file.
    /* AudioServicesPlaySystemSound (mySSID); */

    // Invoke a run loop on the current thread to keep the application
    // running long enough for the sound to play; the sound completion
    // callback later stops this run loop.
    CFRunLoopRun ();
    return 0;
}
Beispiel #3
0
IncrementalSweeper* IncrementalSweeper::create(Heap* heap)
{
    return new IncrementalSweeper(heap, CFRunLoopGetCurrent());
}
void RunLoop::stop()
{
    ASSERT(m_runLoop == CFRunLoopGetCurrent());
    CFRunLoopStop(m_runLoop.get());
}
Beispiel #5
0
bool wxApp::Initialize(int& argc, wxChar **argv)
{
    // Mac-specific

#if __WXDEBUG__
    InstallDebugAssertOutputHandler ( NewDebugAssertOutputHandlerUPP( wxMacAssertOutputHandler ) );
#endif
    UMAInitToolbox( 4, sm_isEmbedded ) ;
    SetEventMask( everyEvent ) ;
    UMAShowWatchCursor() ;

#ifndef __DARWIN__
#  if __option(profile)
    ProfilerInit( collectDetailed, bestTimeBase , 40000 , 50 ) ;
#  endif
#endif

#ifndef __DARWIN__
    // now avoid exceptions thrown for new (bad_alloc)
    // FIXME CS for some changes outside wxMac does not compile anymore
#if 0
    std::__throws_bad_alloc = 0 ;
#endif

#endif

    s_macCursorRgn = ::NewRgn() ;

    // Mac OS X passes a process serial number command line argument when
    // the application is launched from the Finder. This argument must be
    // removed from the command line arguments before being handled by the
    // application (otherwise applications would need to handle it)
    if ( argc > 1 )
    {
        static const wxChar *ARG_PSN = _T("-psn_");
        if ( wxStrncmp(argv[1], ARG_PSN, wxStrlen(ARG_PSN)) == 0 )
        {
            // remove this argument
            --argc;
            memmove(argv + 1, argv + 2, argc * sizeof(char *));
        }
    }

    if ( !wxAppBase::Initialize(argc, argv) )
        return false;

#if wxUSE_INTL
    wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding());
#endif

#if TARGET_API_MAC_OSX
    // these might be the startup dirs, set them to the 'usual' dir containing the app bundle
    wxString startupCwd = wxGetCwd() ;
    if ( startupCwd == wxT("/") || startupCwd.Right(15) == wxT("/Contents/MacOS") )
    {
        CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle() ) ;
        CFURLRef urlParent = CFURLCreateCopyDeletingLastPathComponent( kCFAllocatorDefault , url ) ;
        CFRelease( url ) ;
        CFStringRef path = CFURLCopyFileSystemPath ( urlParent , kCFURLPOSIXPathStyle ) ;
        CFRelease( urlParent ) ;
        wxString cwd = wxMacCFStringHolder(path).AsString(wxLocale::GetSystemEncoding());       
        wxSetWorkingDirectory( cwd ) ;
    }
#endif

    wxMacCreateNotifierTable() ;

#ifdef __WXMAC_OSX__
    /* connect posted events to common-mode run loop so that wxPostEvent events
       are handled even while we're in the menu or on a scrollbar */
    CFRunLoopSourceContext event_posted_context = {0};
    event_posted_context.perform = macPostedEventCallback;
    m_macEventPosted = CFRunLoopSourceCreate(NULL,0,&event_posted_context);
    CFRunLoopAddSource(CFRunLoopGetCurrent(), m_macEventPosted, kCFRunLoopCommonModes);
#endif

    UMAShowArrowCursor() ;

    return true;
}
Beispiel #6
0
void
load(CFBundleRef bundle, Boolean bundleVerbose)
{
	CFStringRef		key;
	CFMutableArrayRef	keys		= NULL;
	CFStringRef		pattern;
	CFMutableArrayRef	patterns	= NULL;
	CFRunLoopSourceRef	rls;

	if (bundleVerbose) {
		_verbose = TRUE;
	}

	SCLog(_verbose, LOG_DEBUG, CFSTR("load() called"));
	SCLog(_verbose, LOG_DEBUG, CFSTR("  bundle ID = %@"), CFBundleGetIdentifier(bundle));

	/* initialize a few globals */

	curGlobals    = CFDictionaryCreateMutable(NULL,
						  0,
						  &kCFTypeDictionaryKeyCallBacks,
						  &kCFTypeDictionaryValueCallBacks);
	curConfigFile = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
	curDefaults   = CFDictionaryCreateMutable(NULL,
						  0,
						  &kCFTypeDictionaryKeyCallBacks,
						  &kCFTypeDictionaryValueCallBacks);
	curStartup    = CFDictionaryCreateMutable(NULL,
						  0,
						  &kCFTypeDictionaryKeyCallBacks,
						  &kCFTypeDictionaryValueCallBacks);

	/* open a "configd" store to allow cache updates */
	store = SCDynamicStoreCreate(NULL,
				     CFSTR("AppleTalk Configuraton plug-in"),
				     atConfigChangedCallback,
				     NULL);
	if (!store) {
		SCLog(TRUE, LOG_ERR, CFSTR("SCDynamicStoreCreate() failed: %s"), SCErrorString(SCError()));
		goto error;
	}

	/* establish notificaiton keys and patterns */

	keys     = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
	patterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);

	/* ...watch for (global) AppleTalk configuration changes */
	key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
							 kSCDynamicStoreDomainSetup,
							 kSCEntNetAppleTalk);
	CFArrayAppendValue(keys, key);
	CFRelease(key);

	/* ...watch for (per-service) AppleTalk configuration changes */
	pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
							      kSCDynamicStoreDomainSetup,
							      kSCCompAnyRegex,
							      kSCEntNetAppleTalk);
	CFArrayAppendValue(patterns, pattern);
	CFRelease(pattern);

	/* ...watch for network interface link status changes */
	pattern = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL,
								kSCDynamicStoreDomainState,
								kSCCompAnyRegex,
								kSCEntNetLink);
	CFArrayAppendValue(patterns, pattern);
	CFRelease(pattern);

	/* ...watch for (per-interface) AppleTalk configuration changes */
	pattern = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL,
								kSCDynamicStoreDomainState,
								kSCCompAnyRegex,
								kSCEntNetAppleTalk);
	CFArrayAppendValue(patterns, pattern);
	CFRelease(pattern);

	/* ...watch for computer name changes */
	key = SCDynamicStoreKeyCreateComputerName(NULL);
	CFArrayAppendValue(keys, key);
	CFRelease(key);

	/* register the keys/patterns */
	if (!SCDynamicStoreSetNotificationKeys(store, keys, patterns)) {
		SCLog(TRUE, LOG_ERR,
		      CFSTR("SCDynamicStoreSetNotificationKeys() failed: %s"),
		      SCErrorString(SCError()));
		goto error;
	}

	rls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0);
	if (!rls) {
		SCLog(TRUE, LOG_ERR,
		      CFSTR("SCDynamicStoreCreateRunLoopSource() failed: %s"),
		      SCErrorString(SCError()));
		goto error;
	}

	CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
	CFRelease(rls);

	CFRelease(keys);
	CFRelease(patterns);
	return;

    error :

	if (curGlobals)		CFRelease(curGlobals);
	if (curConfigFile)	CFRelease(curConfigFile);
	if (curDefaults)	CFRelease(curDefaults);
	if (curStartup)		CFRelease(curStartup);
	if (store) 		CFRelease(store);
	if (keys)		CFRelease(keys);
	if (patterns)		CFRelease(patterns);
	return;
}
static void *hook_thread_proc(void *arg) {
	int *status = (int *) arg;
	*status = UIOHOOK_FAILURE;

	bool accessibilityEnabled = false;

	// FIXME Move to osx_input_helper.h after testing.
	#ifdef USE_WEAK_IMPORT
	// Check and make sure assistive devices is enabled.
	if (AXIsProcessTrustedWithOptions != NULL) {
		// New accessibility API 10.9 and later.
		const void * keys[] = { kAXTrustedCheckOptionPrompt };
		const void * values[] = { kCFBooleanTrue };

		CFDictionaryRef options = CFDictionaryCreate(
				kCFAllocatorDefault,
				keys,
				values,
				sizeof(keys) / sizeof(*keys),
				&kCFCopyStringDictionaryKeyCallBacks,
				&kCFTypeDictionaryValueCallBacks);

		accessibilityEnabled = AXIsProcessTrustedWithOptions(options);
	}
	else {
		// Old accessibility check 10.8 and older.
		accessibilityEnabled = AXAPIEnabled();
	}
	#else
	// Dynamically load the application services framework for examination.
	const char *dlError = NULL;
	void *libApplicaitonServices = dlopen("/System/Library/Frameworks/ApplicationServices.framework/ApplicationServices", RTLD_LAZY);
	dlError = dlerror();
	if (libApplicaitonServices != NULL && dlError == NULL) {
		// Check for the new function AXIsProcessTrustedWithOptions().
		*(void **) (&AXIsProcessTrustedWithOptions_t) = dlsym(libApplicaitonServices, "AXIsProcessTrustedWithOptions");
		dlError = dlerror();
		if (AXIsProcessTrustedWithOptions_t != NULL && dlError == NULL) {
			// Check for property kAXTrustedCheckOptionPrompt
			CFStringRef kAXTrustedCheckOptionPrompt_t = (CFStringRef) dlsym(libApplicaitonServices, "kAXTrustedCheckOptionPrompt");
			dlError = dlerror();
			if (kAXTrustedCheckOptionPrompt_t != NULL && dlError == NULL) {
				// New accessibility API 10.9 and later.
				// FIXME This is causing a segfault on 10.9 probably due to an invalid pointer type.
				const void * keys[] = { kAXTrustedCheckOptionPrompt_t };
				const void * values[] = { kCFBooleanTrue };

				CFDictionaryRef options = CFDictionaryCreate(
						kCFAllocatorDefault,
						keys,
						values,
						sizeof(keys) / sizeof(*keys),
						&kCFCopyStringDictionaryKeyCallBacks,
						&kCFTypeDictionaryValueCallBacks);

				accessibilityEnabled = (*AXIsProcessTrustedWithOptions_t)(options);
			}
		}
		else {
			logger(LOG_LEVEL_DEBUG,	"%s [%u]: Falling back to AXAPIEnabled(). (%s)\n",
					__FUNCTION__, __LINE__, dlError);

			// Check for the fallback function AXAPIEnabled().
			*(void **) (&AXAPIEnabled_t) = dlsym(libApplicaitonServices, "AXAPIEnabled");
			dlError = dlerror();
			if (AXAPIEnabled_t != NULL && dlError == NULL) {
				// Old accessibility check 10.8 and older.
				accessibilityEnabled = (*AXAPIEnabled_t)();
			}
			else {
				// Could not load the AXAPIEnabled function!
				logger(LOG_LEVEL_ERROR,	"%s [%u]: Failed to locate AXAPIEnabled()! (%s)\n",
						__FUNCTION__, __LINE__, dlError);
			}
		}

		dlclose(libApplicaitonServices);
	}
	else {
		// Could not load the ApplicationServices framework!
		logger(LOG_LEVEL_ERROR,	"%s [%u]: Failed to lazy load the ApplicationServices framework! (%s)\n",
				__FUNCTION__, __LINE__, dlError);
	}
	#endif

	if (accessibilityEnabled == true) {
		logger(LOG_LEVEL_DEBUG,	"%s [%u]: Accessibility API is enabled.\n",
				__FUNCTION__, __LINE__);

		// Setup the event mask to listen for.
		CGEventMask event_mask =	CGEventMaskBit(kCGEventKeyDown) |
									CGEventMaskBit(kCGEventKeyUp) |
									CGEventMaskBit(kCGEventFlagsChanged) |

									CGEventMaskBit(kCGEventLeftMouseDown) |
									CGEventMaskBit(kCGEventLeftMouseUp) |
									CGEventMaskBit(kCGEventLeftMouseDragged) |

									CGEventMaskBit(kCGEventRightMouseDown) |
									CGEventMaskBit(kCGEventRightMouseUp) |
									CGEventMaskBit(kCGEventRightMouseDragged) |

									CGEventMaskBit(kCGEventOtherMouseDown) |
									CGEventMaskBit(kCGEventOtherMouseUp) |
									CGEventMaskBit(kCGEventOtherMouseDragged) |

									CGEventMaskBit(kCGEventMouseMoved) |
									CGEventMaskBit(kCGEventScrollWheel);

		#ifdef USE_DEBUG
		event_mask |= CGEventMaskBit(kCGEventNull);
		#endif

		CFMachPortRef event_port = CGEventTapCreate(
										kCGSessionEventTap,				// kCGHIDEventTap
										kCGHeadInsertEventTap,			// kCGTailAppendEventTap
										kCGEventTapOptionListenOnly,	// kCGEventTapOptionDefault See Bug #22
										event_mask,
										hook_event_proc,
										NULL
									);


		if (event_port != NULL) {
			logger(LOG_LEVEL_DEBUG,	"%s [%u]: CGEventTapCreate Successful.\n",
					__FUNCTION__, __LINE__);

			event_source = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, event_port, 0);
			if (event_source != NULL) {
				logger(LOG_LEVEL_DEBUG,	"%s [%u]: CFMachPortCreateRunLoopSource successful.\n",
						__FUNCTION__, __LINE__);

				event_loop = CFRunLoopGetCurrent();
				if (event_loop != NULL) {
					logger(LOG_LEVEL_DEBUG,	"%s [%u]: CFRunLoopGetCurrent successful.\n",
							__FUNCTION__, __LINE__);

					// Initialize Native Input Functions.
					load_input_helper();


					// Create run loop observers.
					CFRunLoopObserverRef observer = CFRunLoopObserverCreate(
														kCFAllocatorDefault,
														kCFRunLoopEntry | kCFRunLoopExit, //kCFRunLoopAllActivities,
														true,
														0,
														hook_status_proc,
														NULL
													);

					if (observer != NULL) {
						// Set the exit status.
						*status = UIOHOOK_SUCCESS;

						start_message_port_runloop();

						CFRunLoopAddSource(event_loop, event_source, kCFRunLoopDefaultMode);
						CFRunLoopAddObserver(event_loop, observer, kCFRunLoopDefaultMode);

						CFRunLoopRun();

						// Lock back up until we are done processing the exit.
						CFRunLoopRemoveObserver(event_loop, observer, kCFRunLoopDefaultMode);
						CFRunLoopRemoveSource(event_loop, event_source, kCFRunLoopDefaultMode);
						CFRunLoopObserverInvalidate(observer);

						stop_message_port_runloop();
					}
					else {
						// We cant do a whole lot of anything if we cant
						// create run loop observer.

						logger(LOG_LEVEL_ERROR,	"%s [%u]: CFRunLoopObserverCreate failure!\n",
								__FUNCTION__, __LINE__);

						// Set the exit status.
						*status = UIOHOOK_ERROR_OBSERVER_CREATE;
					}

					// Cleanup Native Input Functions.
					unload_input_helper();
				}
				else {
					logger(LOG_LEVEL_ERROR,	"%s [%u]: CFRunLoopGetCurrent failure!\n",
							__FUNCTION__, __LINE__);

					// Set the exit status.
					*status = UIOHOOK_ERROR_GET_RUNLOOP;
				}

				// Clean up the event source.
				CFRelease(event_source);
			}
			else {
				logger(LOG_LEVEL_ERROR,	"%s [%u]: CFMachPortCreateRunLoopSource failure!\n",
					__FUNCTION__, __LINE__);

				// Set the exit status.
				*status = UIOHOOK_ERROR_CREATE_RUN_LOOP_SOURCE;
			}

			// Stop the CFMachPort from receiving any more messages.
			CFMachPortInvalidate(event_port);
			CFRelease(event_port);
		}
		else {
			logger(LOG_LEVEL_ERROR,	"%s [%u]: Failed to create event port!\n",
					__FUNCTION__, __LINE__);

			// Set the exit status.
			*status = UIOHOOK_ERROR_EVENT_PORT;
		}
	}
	else {
		logger(LOG_LEVEL_ERROR,	"%s [%u]: Accessibility API is disabled!\n",
				__FUNCTION__, __LINE__);

		// Set the exit status.
		*status = UIOHOOK_ERROR_AXAPI_DISABLED;
	}

	logger(LOG_LEVEL_DEBUG,	"%s [%u]: Something, something, something, complete.\n",
			__FUNCTION__, __LINE__);

	// Make sure we signal that we have passed any exception throwing code.
	pthread_mutex_unlock(&hook_control_mutex);

	pthread_exit(status);
}
Beispiel #8
0
void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)
{
   bd_addr_t event_addr;

   if (packet_type == HCI_EVENT_PACKET)
   {
      switch (packet[0])
      {
         case BTSTACK_EVENT_STATE:
         {
            RARCH_LOG("BTstack: HCI State %d\n", packet[2]);
         
            switch (packet[2])
            {                  
               case HCI_STATE_WORKING:
                  btpad_queue_reset();

                  btpad_queue_hci_read_bd_addr();
                  bt_send_cmd_ptr(l2cap_register_service_ptr, PSM_HID_CONTROL, 672);  // TODO: Where did I get 672 for mtu?
                  bt_send_cmd_ptr(l2cap_register_service_ptr, PSM_HID_INTERRUPT, 672);
                  btpad_queue_hci_inquiry(HCI_INQUIRY_LAP, 3, 1);
               
                  btpad_queue_run(1);
                  break;
                  
               case HCI_STATE_HALTING:
                  btpad_close_all_connections();
                  CFRunLoopStop(CFRunLoopGetCurrent());
                  break;                  
            }
         }
         break;

         case HCI_EVENT_COMMAND_STATUS:
         btpad_queue_run(packet[3]);
         break;

         case HCI_EVENT_COMMAND_COMPLETE:
         {
            btpad_queue_run(packet[2]);

            if (COMMAND_COMPLETE_EVENT(packet, (*hci_read_bd_addr_ptr)))
            {
               bt_flip_addr_ptr(event_addr, &packet[6]);
               if (!packet[5])
                  RARCH_LOG("BTpad: Local address is %s\n", bd_addr_to_str_ptr(event_addr));
               else
                  RARCH_LOG("BTpad: Failed to get local address (Status: %02X)\n", packet[5]);               
            }
         }
         break;

         case HCI_EVENT_INQUIRY_RESULT:
         {
            if (packet[2])
            {
               bt_flip_addr_ptr(event_addr, &packet[3]);

               struct apple_pad_connection* connection = (struct apple_pad_connection*)btpad_find_empty_connection();

               if (connection)
               {
                  RARCH_LOG("BTpad: Inquiry found device\n");
                  memset(connection, 0, sizeof(struct apple_pad_connection));

                  memcpy(connection->address, event_addr, sizeof(bd_addr_t));
                  connection->has_address = true;
                  connection->state = BTPAD_CONNECTING;

                  bt_send_cmd_ptr(l2cap_create_channel_ptr, connection->address, PSM_HID_CONTROL);
                  bt_send_cmd_ptr(l2cap_create_channel_ptr, connection->address, PSM_HID_INTERRUPT);
               }
            }
         }
         break;

         case HCI_EVENT_INQUIRY_COMPLETE:
         {
            // This must be turned off during gameplay as it causes a ton of lag
            inquiry_running = !inquiry_off;

            if (inquiry_running)
               btpad_queue_hci_inquiry(HCI_INQUIRY_LAP, 3, 1);
         }
         break;

         case L2CAP_EVENT_CHANNEL_OPENED:
         {
            bt_flip_addr_ptr(event_addr, &packet[3]);
            const uint16_t handle = READ_BT_16(packet, 9);
            const uint16_t psm = READ_BT_16(packet, 11);
            const uint16_t channel_id = READ_BT_16(packet, 13);

            struct apple_pad_connection* connection = (struct apple_pad_connection*)btpad_find_connection_for(handle, event_addr);

            if (!packet[2])
            {
               if (!connection)
               {
                  RARCH_LOG("BTpad: Got L2CAP 'Channel Opened' event for unrecognized device\n");
                  break;
               }

               RARCH_LOG("BTpad: L2CAP channel opened: (PSM: %02X)\n", psm);
               connection->handle = handle;
            
               if (psm == PSM_HID_CONTROL)
                  connection->channels[0] = channel_id;
               else if (psm == PSM_HID_INTERRUPT)
                  connection->channels[1] = channel_id;
               else
                  RARCH_LOG("BTpad: Got unknown L2CAP PSM, ignoring (PSM: %02X)\n", psm);

               if (connection->channels[0] && connection->channels[1])
               {
                  RARCH_LOG("BTpad: Got both L2CAP channels, requesting name\n");
                  btpad_queue_hci_remote_name_request(connection->address, 0, 0, 0);
               }
            }
            else
               RARCH_LOG("BTpad: Got failed L2CAP 'Channel Opened' event (PSM: %02X, Status: %02X)\n", psm, packet[2]);
         }
         break;

         case L2CAP_EVENT_INCOMING_CONNECTION:
         {
            bt_flip_addr_ptr(event_addr, &packet[2]);
            const uint16_t handle = READ_BT_16(packet, 8);
            const uint32_t psm = READ_BT_16(packet, 10);
            const uint32_t channel_id = READ_BT_16(packet, 12);
      
            struct apple_pad_connection* connection = (struct apple_pad_connection*)btpad_find_connection_for(handle, event_addr);

            if (!connection)
            {
               connection = btpad_find_empty_connection();
               if (connection)
               {
                  RARCH_LOG("BTpad: Got new incoming connection\n");

                  memset(connection, 0, sizeof(struct apple_pad_connection));

                  memcpy(connection->address, event_addr, sizeof(bd_addr_t));
                  connection->has_address = true;
                  connection->handle = handle;
                  connection->state = BTPAD_CONNECTING;
               }
               else break;
            }

            RARCH_LOG("BTpad: Incoming L2CAP connection (PSM: %02X)\n", psm);
            bt_send_cmd_ptr(l2cap_accept_connection_ptr, channel_id);
         }
         break;

         case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE:
         {
            bt_flip_addr_ptr(event_addr, &packet[3]);
            
            struct apple_pad_connection* connection = (struct apple_pad_connection*)btpad_find_connection_for(0, event_addr);

            if (!connection)
            {
               RARCH_LOG("BTpad: Got unexpected remote name, ignoring\n");
               break;
            }

            RARCH_LOG("BTpad: Got %.200s\n", (char*)&packet[9]);
            
            connection->slot = apple_joypad_connect((char*)packet + 9, connection);
            connection->state = BTPAD_CONNECTED;
         }
         break;

         case HCI_EVENT_PIN_CODE_REQUEST:
         RARCH_LOG("BTpad: Sending WiiMote PIN\n");

         bt_flip_addr_ptr(event_addr, &packet[2]);
         btpad_queue_hci_pin_code_request_reply(event_addr, &packet[2]);
         break;

         case HCI_EVENT_DISCONNECTION_COMPLETE:
         {
            const uint32_t handle = READ_BT_16(packet, 3);

            if (!packet[2])
            {
               struct apple_pad_connection* connection = (struct apple_pad_connection*)btpad_find_connection_for(handle, 0);

               if (connection)
               {
                  connection->handle = 0;
               
                  apple_joypad_disconnect(connection->slot);
                  btpad_close_connection(connection);
               }
            }
            else
               RARCH_LOG("BTpad: Got failed 'Disconnection Complete' event (Status: %02X)\n", packet[2]);
         }
         break;

         case L2CAP_EVENT_SERVICE_REGISTERED:
         {
            if (packet[2])
               RARCH_LOG("BTpad: Got failed 'Service Registered' event (PSM: %02X, Status: %02X)\n", READ_BT_16(packet, 3), packet[2]);
         }
         break;
      }
   }
   else if (packet_type == L2CAP_DATA_PACKET)
   {
      int i;
      for (i = 0; i < MAX_PLAYERS; i ++)
      {
         struct apple_pad_connection* connection = (struct apple_pad_connection*)&g_connections[i];
   
         if (connection->state == BTPAD_CONNECTED && (connection->channels[0] == channel || connection->channels[1] == channel))
            apple_joypad_packet(connection->slot, packet, size);
      }
   }
}
PsychError ReceiveReports(int deviceIndex)
{
	long error=0;
	pRecDevice device;
	IOHIDDeviceInterface122** interface=NULL;
	int reason; // kCFRunLoopRunFinished, kCFRunLoopRunStopped, kCFRunLoopRunTimedOut, kCFRunLoopRunHandledSource

	PsychHIDVerifyInit();

	if(deviceIndex < 0 || deviceIndex >= MAXDEVICEINDEXS) PrintfExit("Sorry. Can't cope with deviceNumber %d (more than %d). Please tell [email protected]",deviceIndex,(int)MAXDEVICEINDEXS-1);

    // Allocate report buffers if needed:
    PsychHIDAllocateReports(deviceIndex);

	CountReports("ReceiveReports beginning.");
	if (freeReportsPtr[deviceIndex] == NULL) PrintfExit("No free reports.");

	device=PsychHIDGetDeviceRecordPtrFromIndex(deviceIndex);
	if(!HIDIsValidDevice(device))PrintfExit("PsychHID: Invalid device.\n");

	interface = PsychHIDGetDeviceInterfacePtrFromIndex(deviceIndex);
	if(interface==NULL)PrintfExit("PsychHID: No interface for device.\n");
	CheckRunLoopSource(deviceIndex,"ReceiveReports",__LINE__);
	if(!ready[deviceIndex]){
		// setInterruptReportHandlerCallback
		static unsigned char buffer[MAXREPORTSIZE];
		psych_uint32 bufferSize=MAXREPORTSIZE;
		psych_bool createSource;

		createSource=(source[deviceIndex]==NULL);
		if(createSource){
			if(optionsPrintCrashers && createSource)printf("%d: createAsyncEventSource\n",deviceIndex);
			error=(*interface)->createAsyncEventSource(interface,&(source[deviceIndex]));
			if(error)PrintfExit("ReceiveReports - createAsyncEventSource error 0x%lx.",error);
			if(0 && optionsPrintCrashers && createSource)
				printf("%d: source %4.4lx validity %d, CFRunLoopContainsSource is %d.\n",deviceIndex,(unsigned long)source[deviceIndex]
					   ,CFRunLoopSourceIsValid(source[deviceIndex])
					   ,CFRunLoopContainsSource(CFRunLoopGetCurrent(),source[deviceIndex],myRunLoopMode));
		}
		if(optionsPrintCrashers && createSource)printf("%d: getAsyncEventSource\n",deviceIndex);
		CheckRunLoopSource(deviceIndex,"ReceiveReports",__LINE__);
		if(optionsPrintCrashers && createSource)printf("%d: CFRunLoopAddSource\n",deviceIndex);
		CFRunLoopAddSource(CFRunLoopGetCurrent(),source[deviceIndex],myRunLoopMode);
		if(0 && optionsPrintCrashers && createSource)printf("%d: source %4.4lx validity %d, CFRunLoopContainsSource is %d.\n",deviceIndex,(unsigned long)source[deviceIndex]
			   ,CFRunLoopSourceIsValid(source[deviceIndex])
			   ,CFRunLoopContainsSource(CFRunLoopGetCurrent(),source[deviceIndex],myRunLoopMode));
		ready[deviceIndex]=1;
		CheckRunLoopSource(deviceIndex,"ReceiveReports",__LINE__);
		if(optionsPrintCrashers && createSource)printf("%d: setInterruptReportHandlerCallback\n",deviceIndex);
		error=(*interface)->setInterruptReportHandlerCallback(interface,buffer,bufferSize,ReportCallback,buffer,(void *)(long int) deviceIndex);
		if(error)PrintfExit("ReceiveReports - setInterruptReportHandlerCallback error 0x%lx.",error);
		if(optionsPrintCrashers && createSource)printf("%d: CFRunLoopRunInMode.\n",deviceIndex);
	}
	//printf("%d: CFRunLoopRunInMode\n",deviceIndex);
	reason=CFRunLoopRunInMode(myRunLoopMode,optionsSecs,false);
	if(reason!=kCFRunLoopRunTimedOut && reason!=kCFRunLoopRunHandledSource){
		char *s;
		switch(reason){
			case kCFRunLoopRunFinished: s="kCFRunLoopRunFinished"; break;
			case kCFRunLoopRunStopped: s="kCFRunLoopRunStopped"; break;
			case kCFRunLoopRunTimedOut: s="kCFRunLoopRunTimedOut"; break;
			case kCFRunLoopRunHandledSource: s="kCFRunLoopRunHandledSource"; break;
			default: s="of unknown reason.";
		}
		printf("RunLoop ended at %.3f s because %s.\n",CFAbsoluteTimeGetCurrent()-AInScanStart,s);			
	}
	CountReports("ReceiveReports end.");
	return error;
}
int DeviceManagerThread::Run()
{

    SetThreadName("OVR::DeviceManagerThread");
    LogText("OVR::DeviceManagerThread - running (ThreadId=0x%p).\n", GetThreadId());

    // Store out the run loop ref.
    RunLoop = CFRunLoopGetCurrent();

    // Create a 'source' to enable us to signal the run loop to process the command queue.
    CFRunLoopSourceContext sourceContext;
    memset(&sourceContext, 0, sizeof(sourceContext));
    sourceContext.version = 0;
    sourceContext.info = this;
    sourceContext.perform = &staticCommandQueueSourceCallback;

    CommandQueueSource = CFRunLoopSourceCreate(kCFAllocatorDefault, 0 , &sourceContext);

    CFRunLoopAddSource(RunLoop, CommandQueueSource, kCFRunLoopDefaultMode);


    // Signal to the parent thread that initialization has finished.
    StartupEvent.SetEvent();


    ThreadCommand::PopBuffer command;
   
    while(!IsExiting())
    {
        // PopCommand will reset event on empty queue.
        if (PopCommand(&command))
        {
            command.Execute();
        }
        else
        {
            SInt32 exitReason = 0;
            do {

                UInt32 waitMs = INT_MAX;

                // If devices have time-dependent logic registered, get the longest wait
                // allowed based on current ticks.
                if (!TicksNotifiers.IsEmpty())
                {
                    UInt64 ticksMks = Timer::GetTicks();
                    UInt32  waitAllowed;

                    for (UPInt j = 0; j < TicksNotifiers.GetSize(); j++)
                    {
                        waitAllowed = (UInt32)(TicksNotifiers[j]->OnTicks(ticksMks) / Timer::MksPerMs);
                        if (waitAllowed < waitMs)
                            waitMs = waitAllowed;
                    }
                }
                
                // Enter blocking run loop. We may continue until we timeout in which
                // case it's time to service the ticks. Or if commands arrive in the command
                // queue then the source callback will call 'CFRunLoopStop' causing this
                // to return.
                CFTimeInterval blockInterval = 0.001 * (double) waitMs;
                exitReason = CFRunLoopRunInMode(kCFRunLoopDefaultMode, blockInterval, false);

                if (exitReason == kCFRunLoopRunFinished)
                {
                    // Maybe this will occur during shutdown?
                    break;
                }
                else if (exitReason == kCFRunLoopRunStopped )
                {
                    // Commands need processing or we're being shutdown.
                    break;
                }
                else if (exitReason == kCFRunLoopRunTimedOut)
                {
                    // Timed out so that we can service our ticks callbacks.
                    continue;
                }
                else if (exitReason == kCFRunLoopRunHandledSource)
                {
                    // Should never occur since the last param when we call
                    // 'CFRunLoopRunInMode' is false.
                    OVR_ASSERT(false);
                    break;
                }
                else
                {
                    OVR_ASSERT_LOG(false, ("CFRunLoopRunInMode returned unexpected code"));
                    break;
                }
            }
            while(true);                    
        }
    }

                                   
    CFRunLoopRemoveSource(RunLoop, CommandQueueSource, kCFRunLoopDefaultMode);
    CFRelease(CommandQueueSource);
    
    LogText("OVR::DeviceManagerThread - exiting (ThreadId=0x%p).\n", GetThreadId());

    return 0;
}
Beispiel #11
0
/* Function to scan the system for joysticks.
 * Joystick 0 should be the system default joystick.
 * This function should return the number of available joysticks, or -1
 * on an unrecoverable fatal error.
 */
int
SDL_SYS_JoystickInit(void)
{
    IOReturn result = kIOReturnSuccess;
    mach_port_t masterPort = 0;
    io_iterator_t hidObjectIterator = 0;
    CFMutableDictionaryRef hidMatchDictionary = NULL;
    io_object_t ioHIDDeviceObject = 0;
	io_iterator_t portIterator = 0;

    if (gpDeviceList) {
        SDL_SetError("Joystick: Device list already inited.");
        return -1;
    }

    result = IOMasterPort(bootstrap_port, &masterPort);
    if (kIOReturnSuccess != result) {
        SDL_SetError("Joystick: IOMasterPort error with bootstrap_port.");
        return -1;
    }

    /* Set up a matching dictionary to search I/O Registry by class name for all HID class devices. */
    hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey);
    if (hidMatchDictionary) {
        /* Add key for device type (joystick, in this case) to refine the matching dictionary. */

        /* NOTE: we now perform this filtering later
           UInt32 usagePage = kHIDPage_GenericDesktop;
           UInt32 usage = kHIDUsage_GD_Joystick;
           CFNumberRef refUsage = NULL, refUsagePage = NULL;

           refUsage = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &usage);
           CFDictionarySetValue (hidMatchDictionary, CFSTR (kIOHIDPrimaryUsageKey), refUsage);
           refUsagePage = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &usagePage);
           CFDictionarySetValue (hidMatchDictionary, CFSTR (kIOHIDPrimaryUsagePageKey), refUsagePage);
         */
    } else {
        SDL_SetError
            ("Joystick: Failed to get HID CFMutableDictionaryRef via IOServiceMatching.");
        return -1;
    }

    /*/ Now search I/O Registry for matching devices. */
    result =
        IOServiceGetMatchingServices(masterPort, hidMatchDictionary,
                                     &hidObjectIterator);
    /* Check for errors */
    if (kIOReturnSuccess != result) {
        SDL_SetError("Joystick: Couldn't create a HID object iterator.");
        return -1;
    }
    if (!hidObjectIterator) {   /* there are no joysticks */
        gpDeviceList = NULL;
        return 0;
    }
    /* IOServiceGetMatchingServices consumes a reference to the dictionary, so we don't need to release the dictionary ref. */

    /* build flat linked list of devices from device iterator */

    gpDeviceList = NULL;

    while ((ioHIDDeviceObject = IOIteratorNext(hidObjectIterator))) {
		AddDeviceHelper( ioHIDDeviceObject );
    }
    result = IOObjectRelease(hidObjectIterator);        /* release the iterator */
	
	/* now connect notification for new devices */
	notificationPort = IONotificationPortCreate(masterPort);
	hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey);

	CFRunLoopAddSource(CFRunLoopGetCurrent(), 
					   IONotificationPortGetRunLoopSource(notificationPort), 
					   kCFRunLoopDefaultMode);
	
	// Register for notifications when a serial port is added to the system
	result = IOServiceAddMatchingNotification(notificationPort,
															kIOFirstMatchNotification,
															hidMatchDictionary,
															JoystickDeviceWasAddedCallback,
															NULL,           
															&portIterator);
	while (IOIteratorNext(portIterator)) {}; // Run out the iterator or notifications won't start (you can also use it to iterate the available devices).

    return SDL_SYS_NumJoysticks();
}
void
load(CFBundleRef bundle, Boolean bundleVerbose)
{
	int			so;
	int			status;
	struct kev_request	kev_req;
	CFSocketRef		es;
	CFSocketContext		context = { 0, NULL, NULL, NULL, NULL };
	CFRunLoopSourceRef	rls;

	if (bundleVerbose) {
		_verbose = TRUE;
	}

	SCLog(_verbose, LOG_DEBUG, CFSTR("load() called"));
	SCLog(_verbose, LOG_DEBUG, CFSTR("  bundle ID = %@"), CFBundleGetIdentifier(bundle));

	/* open a "configd" session to allow cache updates */
	store = SCDynamicStoreCreate(NULL,
				     CFSTR("Kernel Event Monitor plug-in"),
				     NULL,
				     NULL);
	if (!store) {
		SCLog(TRUE, LOG_ERR, CFSTR("SCDnamicStoreCreate() failed: %s"), SCErrorString(SCError()));
		SCLog(TRUE, LOG_ERR, CFSTR("kernel event monitor disabled."));
		return;
	}

	/* Open an event socket */
	so = socket(PF_SYSTEM, SOCK_RAW, SYSPROTO_EVENT);
	if (so != -1) {
		/* establish filter to return all events */
		kev_req.vendor_code  = 0;
		kev_req.kev_class    = 0;	/* Not used if vendor_code is 0 */
		kev_req.kev_subclass = 0;	/* Not used if either kev_class OR vendor_code are 0 */
		status = ioctl(so, SIOCSKEVFILT, &kev_req);
		if (status) {
			SCLog(TRUE, LOG_ERR, CFSTR("could not establish event filter, ioctl() failed: %s"), strerror(errno));
			(void) close(so);
			so = -1;
		}
	} else {
		SCLog(TRUE, LOG_ERR, CFSTR("could not open event socket, socket() failed: %s"), strerror(errno));
	}

	if (so != -1) {
		int	yes = 1;

		status = ioctl(so, FIONBIO, &yes);
		if (status) {
			SCLog(TRUE, LOG_ERR, CFSTR("could not set non-blocking io, ioctl() failed: %s"), strerror(errno));
			(void) close(so);
			so = -1;
		}
	}

	if (so == -1) {
		SCLog(TRUE, LOG_ERR, CFSTR("kernel event monitor disabled."));
		CFRelease(store);
		return;
	}

	/* Create a CFSocketRef for the PF_SYSTEM kernel event socket */
	es  = CFSocketCreateWithNative(NULL,
				       so,
				       kCFSocketReadCallBack,
				       eventCallback,
				       &context);

	/* Create and add a run loop source for the event socket */
	rls = CFSocketCreateRunLoopSource(NULL, es, 0);
	CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
	CFRelease(rls);
	CFRelease(es);

	return;
}
Beispiel #13
0
/*------------------------------------ udpPortSetPort ---*/
bool
udpPortSetPort(UdpObjectData * xx,
               const bool      bangOnError)
{
    bool okSoFar = true;

    if (xx)
    {
        if (xx->fSocket)
        {
            CFSocketInvalidate(xx->fSocket);
            CFRelease(xx->fSocket);
            xx->fSocket = NULL;
        }
        int err;
        int sock = socket(AF_INET, SOCK_DGRAM, 0);

        if (0 > sock)
        {
            err = errno;
            okSoFar = false;
        }
        else
        {
            err = 0;
        }
        if (okSoFar)
        {
            sockaddr_in addr;

            memset(&addr, 0, sizeof(addr));
            addr.sin_len = sizeof(addr);
            addr.sin_family = AF_INET;
            addr.sin_port = htons(xx->fSelfPort);
            addr.sin_addr.s_addr = INADDR_ANY;
            err = bind(sock, reinterpret_cast<sockaddr *>(&addr), sizeof(addr));
            if (0 > err)
            {
                err = errno;
                okSoFar = false;
            }
        }
        if (okSoFar)
        {
            int flags = fcntl(sock, F_GETFL);

            err = fcntl(sock, F_SETFL, flags | O_NONBLOCK);
            if (0 > err)
            {
                err = errno;
                okSoFar = false;
            }
        }
        if (okSoFar)
        {
            const CFSocketContext context = { 0, xx, NULL, NULL, NULL };

            xx->fSocket = CFSocketCreateWithNative(kCFAllocatorDefault, sock, kCFSocketReadCallBack,
                                                   socketReadCallback, &context);
            sock = -1;
            CFRunLoopSourceRef rls = CFSocketCreateRunLoopSource(kCFAllocatorDefault, xx->fSocket,
                                                                 0);

            CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
            CFRelease(rls);
            setObjectState(xx, kUdpStateBound);
        }
        if (! okSoFar)
        {
            close(sock);
            LOG_ERROR_2(xx, OUTPUT_PREFIX "set port failed (%ld)", static_cast<long>(err))
            if (bangOnError)
            {
                signalError(xx);
            }
        }
    }
Beispiel #14
0
void FSEventsWatcher::FSEventsThread(const std::shared_ptr<w_root_t>& root) {
  CFFileDescriptorRef fdref;
  CFFileDescriptorContext fdctx;

  w_set_thread_name("fsevents %s", root->root_path.c_str());

  {
    // Block until fsevents_root_start is waiting for our initialization
    auto wlock = items_.wlock();

    attempt_resync_on_drop = root->config.getBool("fsevents_try_resync", true);

    memset(&fdctx, 0, sizeof(fdctx));
    fdctx.info = root.get();

    fdref = CFFileDescriptorCreate(
        nullptr, fse_pipe.read.fd(), true, fse_pipe_callback, &fdctx);
    CFFileDescriptorEnableCallBacks(fdref, kCFFileDescriptorReadCallBack);
    {
      CFRunLoopSourceRef fdsrc;

      fdsrc = CFFileDescriptorCreateRunLoopSource(nullptr, fdref, 0);
      if (!fdsrc) {
        root->failure_reason = w_string_new_typed(
            "CFFileDescriptorCreateRunLoopSource failed", W_STRING_UNICODE);
        goto done;
      }
      CFRunLoopAddSource(CFRunLoopGetCurrent(), fdsrc, kCFRunLoopDefaultMode);
      CFRelease(fdsrc);
    }

    stream = fse_stream_make(
        root, kFSEventStreamEventIdSinceNow, root->failure_reason);
    if (!stream) {
      goto done;
    }

    if (!FSEventStreamStart(stream->stream)) {
      root->failure_reason = w_string::printf(
          "FSEventStreamStart failed, look at your log file %s for "
          "lines mentioning FSEvents and see %s#fsevents for more information\n",
          log_name,
          cfg_get_trouble_url());
      goto done;
    }

    // Signal to fsevents_root_start that we're done initializing
    fse_cond.notify_one();
  }

  // Process the events stream until we get signalled to quit
  CFRunLoopRun();

done:
  if (stream) {
    delete stream;
  }
  if (fdref) {
    CFRelease(fdref);
  }

  w_log(W_LOG_DBG, "fse_thread done\n");
}
Beispiel #15
0
int main(int argc, char *argv[]) {
    static struct option global_longopts[]= {
        { "quiet", no_argument, NULL, 'q' },
        { "verbose", no_argument, NULL, 'v' },
        { "timeout", required_argument, NULL, 't' },

        { "id", required_argument, NULL, 'i' },
        { "bundle", required_argument, NULL, 'b' },
        { "file", required_argument, NULL, 'f' },
        { "target", required_argument, NULL, 1 },
        { "bundle-id", required_argument, NULL, 0 },

        { "debug", no_argument, NULL, 'd' },
        { "args", required_argument, NULL, 'a' },

        { NULL, 0, NULL, 0 },
    };

    char ch;
    while ((ch = getopt_long(argc, argv, "qvi:b:f:da:t:", global_longopts, NULL)) != -1)
    {
        switch (ch) {
            case 0:
                bundle_id = optarg;
                break;
            case 'q':
                quiet = 1;
                break;
            case 'v':
                verbose = 1;
                break;
            case 'd':
                debug = 1;
                break;
            case 't':
                timeout = atoi(optarg);
                break;
            case 'b':
                app_path = optarg;
                break;
            case 'f':
                doc_file_path = optarg;
                break;
            case 1:
                target_filename = optarg;
                break;
            case 'a':
                args = optarg;
                break;
            case 'i':
                device_id = optarg;
                break;

            default:
                usage(argv[0]);
                return 1;
        }
    }

    if (optind >= argc) {
        usage(argv [0]);
        exit(EXIT_SUCCESS);
    }

    operation = OP_NONE;
    if (strcmp (argv [optind], "install") == 0) {
        operation = OP_INSTALL;
    } else if (strcmp (argv [optind], "uninstall") == 0) {
        operation = OP_UNINSTALL;
    } else if (strcmp (argv [optind], "list-devices") == 0) {
        operation = OP_LIST_DEVICES;
    } else if (strcmp (argv [optind], "upload") == 0) {
        operation = OP_UPLOAD_FILE;
    } else if (strcmp (argv [optind], "list-files") == 0) {
        operation = OP_LIST_FILES;
    } else {
        usage (argv [0]);
        exit (0);
    }

    if (!args_are_valid()) {
        usage(argv[0]);
        exit(0);
    }

    if (operation == OP_INSTALL)
        assert(access(app_path, F_OK) == 0);

    AMDSetLogLevel(1+4+2+8+16+32+64+128); // otherwise syslog gets flooded with crap
    if (timeout > 0)
    {
        CFRunLoopTimerRef timer = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent() + timeout, 0, 0, 0, timeout_callback, NULL);
        CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopCommonModes);
        PRINT("[....] Waiting up to %d seconds for iOS device to be connected\n", timeout);
    }
    else
    {
        PRINT("[....] Waiting for iOS device to be connected\n");
    }

    struct am_device_notification *notify;
    AMDeviceNotificationSubscribe(&device_callback, 0, 0, NULL, &notify);

    CFRunLoopRun();
}
Beispiel #16
0
static fse_stream* fse_stream_make(
    const std::shared_ptr<w_root_t>& root,
    FSEventStreamEventId since,
    w_string& failure_reason) {
  FSEventStreamContext ctx;
  CFMutableArrayRef parray = nullptr;
  CFStringRef cpath = nullptr;
  double latency;
  struct stat st;
  auto watcher = watcherFromRoot(root);

  struct fse_stream* fse_stream = new struct fse_stream(root, since);

  // Each device has an optional journal maintained by fseventsd that keeps
  // track of the change events.  The journal may not be available if the
  // filesystem was mounted read-only.  The journal has an associated UUID
  // to track the version of the data.  In some cases the journal can become
  // invalidated and it will have a new UUID generated.  This can happen
  // if the EventId rolls over.
  // We need to lookup up the UUID for the associated path and use that to
  // help decide whether we can use a value of `since` other than SinceNow.
  if (stat(root->root_path.c_str(), &st)) {
    failure_reason = w_string::printf(
        "failed to stat(%s): %s\n", root->root_path.c_str(), strerror(errno));
    goto fail;
  }

  // Obtain the UUID for the device associated with the root
  fse_stream->uuid = FSEventsCopyUUIDForDevice(st.st_dev);
  if (since != kFSEventStreamEventIdSinceNow) {
    CFUUIDBytes a, b;

    if (!fse_stream->uuid) {
      // If there is no UUID available and we want to use an event offset,
      // we fail: a nullptr UUID means that the journal is not available.
      failure_reason = w_string::printf(
          "fsevents journal is not available for dev_t=%d\n", st.st_dev);
      goto fail;
    }
    // Compare the UUID with that of the current stream
    if (!watcher->stream->uuid) {
      failure_reason = w_string(
          "fsevents journal was not available for prior stream",
          W_STRING_UNICODE);
      goto fail;
    }

    a = CFUUIDGetUUIDBytes(fse_stream->uuid);
    b = CFUUIDGetUUIDBytes(watcher->stream->uuid);

    if (memcmp(&a, &b, sizeof(a)) != 0) {
      failure_reason =
          w_string("fsevents journal UUID is different", W_STRING_UNICODE);
      goto fail;
    }
  }

  memset(&ctx, 0, sizeof(ctx));
  ctx.info = fse_stream;

  parray = CFArrayCreateMutable(nullptr, 0, &kCFTypeArrayCallBacks);
  if (!parray) {
    failure_reason = w_string("CFArrayCreateMutable failed", W_STRING_UNICODE);
    goto fail;
  }

  cpath = CFStringCreateWithBytes(
      nullptr,
      (const UInt8*)root->root_path.data(),
      root->root_path.size(),
      kCFStringEncodingUTF8,
      false);
  if (!cpath) {
    failure_reason =
        w_string("CFStringCreateWithBytes failed", W_STRING_UNICODE);
    goto fail;
  }

  CFArrayAppendValue(parray, cpath);

  latency = root->config.getDouble("fsevents_latency", 0.01),
  w_log(
      W_LOG_DBG,
      "FSEventStreamCreate for path %s with latency %f seconds\n",
      root->root_path.c_str(),
      latency);

  fse_stream->stream = FSEventStreamCreate(
      nullptr,
      fse_callback,
      &ctx,
      parray,
      since,
      latency,
      kFSEventStreamCreateFlagNoDefer | kFSEventStreamCreateFlagWatchRoot |
          kFSEventStreamCreateFlagFileEvents);

  if (!fse_stream->stream) {
    failure_reason = w_string("FSEventStreamCreate failed", W_STRING_UNICODE);
    goto fail;
  }

  FSEventStreamScheduleWithRunLoop(fse_stream->stream,
      CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);

#ifdef HAVE_FSEVENTSTREAMSETEXCLUSIONPATHS
  if (!root->ignore.dirs_vec.empty() &&
      root->config.getBool("_use_fsevents_exclusions", true)) {
    CFMutableArrayRef ignarray;
    size_t i, nitems = std::min(root->ignore.dirs_vec.size(), MAX_EXCLUSIONS);

    ignarray = CFArrayCreateMutable(nullptr, 0, &kCFTypeArrayCallBacks);
    if (!ignarray) {
      failure_reason =
          w_string("CFArrayCreateMutable failed", W_STRING_UNICODE);
      goto fail;
    }

    for (i = 0; i < nitems; ++i) {
      const auto& path = root->ignore.dirs_vec[i];
      CFStringRef ignpath;

      ignpath = CFStringCreateWithBytes(
          nullptr,
          (const UInt8*)path.data(),
          path.size(),
          kCFStringEncodingUTF8,
          false);

      if (!ignpath) {
        failure_reason =
            w_string("CFStringCreateWithBytes failed", W_STRING_UNICODE);
        CFRelease(ignarray);
        goto fail;
      }

      CFArrayAppendValue(ignarray, ignpath);
      CFRelease(ignpath);
    }

    if (!FSEventStreamSetExclusionPaths(fse_stream->stream, ignarray)) {
      failure_reason =
          w_string("FSEventStreamSetExclusionPaths failed", W_STRING_UNICODE);
      CFRelease(ignarray);
      goto fail;
    }

    CFRelease(ignarray);
  }
#endif

out:
  if (parray) {
    CFRelease(parray);
  }
  if (cpath) {
    CFRelease(cpath);
  }

  return fse_stream;

fail:
  delete fse_stream;
  fse_stream = nullptr;
  goto out;
}
Beispiel #17
0
static void fse_pipe_callback(CFFileDescriptorRef, CFOptionFlags, void*) {
  w_log(W_LOG_DBG, "pipe signalled\n");
  CFRunLoopStop(CFRunLoopGetCurrent());
}
Beispiel #18
0
GCActivityCallback::GCActivityCallback(Heap* heap)
    : GCActivityCallback(heap->vm(), CFRunLoopGetCurrent())
{
}
void DoAQOfflineRender(CFURLRef sourceURL, CFURLRef destinationURL) 
{
    // main audio queue code
	try {
		AQTestInfo myInfo;
        
		myInfo.mDone = false;
		myInfo.mFlushed = false;
		myInfo.mCurrentPacket = 0;
		
        // get the source file
        XThrowIfError(AudioFileOpenURL(sourceURL, 0x01/*fsRdPerm*/, 0/*inFileTypeHint*/, &myInfo.mAudioFile), "AudioFileOpen failed");
			
		UInt32 size = sizeof(myInfo.mDataFormat);
		XThrowIfError(AudioFileGetProperty(myInfo.mAudioFile, kAudioFilePropertyDataFormat, &size, &myInfo.mDataFormat), "couldn't get file's data format");
		
		printf ("File format: "); myInfo.mDataFormat.Print();

        // create a new audio queue output
		XThrowIfError(AudioQueueNewOutput(&myInfo.mDataFormat,      // The data format of the audio to play. For linear PCM, only interleaved formats are supported.
                                          AQTestBufferCallback,     // A callback function to use with the playback audio queue.
                                          &myInfo,                  // A custom data structure for use with the callback function.
                                          CFRunLoopGetCurrent(),    // The event loop on which the callback function pointed to by the inCallbackProc parameter is to be called.
                                                                    // If you specify NULL, the callback is invoked on one of the audio queue’s internal threads.
                                          kCFRunLoopCommonModes,    // The run loop mode in which to invoke the callback function specified in the inCallbackProc parameter. 
                                          0,                        // Reserved for future use. Must be 0.
                                          &myInfo.mQueue),          // On output, the newly created playback audio queue object.
                                          "AudioQueueNew failed");

		UInt32 bufferByteSize;
		
		// we need to calculate how many packets we read at a time and how big a buffer we need
		// we base this on the size of the packets in the file and an approximate duration for each buffer
		{
			bool isFormatVBR = (myInfo.mDataFormat.mBytesPerPacket == 0 || myInfo.mDataFormat.mFramesPerPacket == 0);
			
			// first check to see what the max size of a packet is - if it is bigger
			// than our allocation default size, that needs to become larger
			UInt32 maxPacketSize;
			size = sizeof(maxPacketSize);
			XThrowIfError(AudioFileGetProperty(myInfo.mAudioFile, kAudioFilePropertyPacketSizeUpperBound, &size, &maxPacketSize), "couldn't get file's max packet size");
			
			// adjust buffer size to represent about a second of audio based on this format
			CalculateBytesForTime(myInfo.mDataFormat, maxPacketSize, 1.0/*seconds*/, &bufferByteSize, &myInfo.mNumPacketsToRead);
			
			if (isFormatVBR) {
				myInfo.mPacketDescs = new AudioStreamPacketDescription [myInfo.mNumPacketsToRead];
			} else {
				myInfo.mPacketDescs = NULL; // we don't provide packet descriptions for constant bit rate formats (like linear PCM)
            }
				
			printf ("Buffer Byte Size: %d, Num Packets to Read: %d\n", (int)bufferByteSize, (int)myInfo.mNumPacketsToRead);
		}

		// if the file has a magic cookie, we should get it and set it on the AQ
		size = sizeof(UInt32);
		OSStatus result = AudioFileGetPropertyInfo (myInfo.mAudioFile, kAudioFilePropertyMagicCookieData, &size, NULL);

		if (!result && size) {
			char* cookie = new char [size];		
			XThrowIfError (AudioFileGetProperty (myInfo.mAudioFile, kAudioFilePropertyMagicCookieData, &size, cookie), "get cookie from file");
			XThrowIfError (AudioQueueSetProperty(myInfo.mQueue, kAudioQueueProperty_MagicCookie, cookie, size), "set cookie on queue");
			delete [] cookie;
		}

		// channel layout?
		OSStatus err = AudioFileGetPropertyInfo(myInfo.mAudioFile, kAudioFilePropertyChannelLayout, &size, NULL);
		AudioChannelLayout *acl = NULL;
		if (err == noErr && size > 0) {
			acl = (AudioChannelLayout *)malloc(size);
			XThrowIfError(AudioFileGetProperty(myInfo.mAudioFile, kAudioFilePropertyChannelLayout, &size, acl), "get audio file's channel layout");
			XThrowIfError(AudioQueueSetProperty(myInfo.mQueue, kAudioQueueProperty_ChannelLayout, acl, size), "set channel layout on queue");
		}

		//allocate the input read buffer
		XThrowIfError(AudioQueueAllocateBuffer(myInfo.mQueue, bufferByteSize, &myInfo.mBuffer), "AudioQueueAllocateBuffer");

		// prepare a canonical interleaved capture format
		CAStreamBasicDescription captureFormat;
		captureFormat.mSampleRate = myInfo.mDataFormat.mSampleRate;
		captureFormat.SetAUCanonical(myInfo.mDataFormat.mChannelsPerFrame, true); // interleaved
		XThrowIfError(AudioQueueSetOfflineRenderFormat(myInfo.mQueue, &captureFormat, acl), "set offline render format");			
		
		ExtAudioFileRef captureFile;
        
		// prepare a 16-bit int file format, sample channel count and sample rate
		CAStreamBasicDescription dstFormat;
		dstFormat.mSampleRate = myInfo.mDataFormat.mSampleRate;
		dstFormat.mChannelsPerFrame = myInfo.mDataFormat.mChannelsPerFrame;
		dstFormat.mFormatID = kAudioFormatLinearPCM;
		dstFormat.mFormatFlags = kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsSignedInteger; // little-endian
		dstFormat.mBitsPerChannel = 16;
		dstFormat.mBytesPerPacket = dstFormat.mBytesPerFrame = 2 * dstFormat.mChannelsPerFrame;
		dstFormat.mFramesPerPacket = 1;
		
		// create the capture file
        XThrowIfError(ExtAudioFileCreateWithURL(destinationURL, kAudioFileCAFType, &dstFormat, acl, kAudioFileFlags_EraseFile, &captureFile), "ExtAudioFileCreateWithURL");
		
        // set the capture file's client format to be the canonical format from the queue
		XThrowIfError(ExtAudioFileSetProperty(captureFile, kExtAudioFileProperty_ClientDataFormat, sizeof(AudioStreamBasicDescription), &captureFormat), "set ExtAudioFile client format");
		
		// allocate the capture buffer, just keep it at half the size of the enqueue buffer
        // we don't ever want to pull any faster than we can push data in for render
        // this 2:1 ratio keeps the AQ Offline Render happy
		const UInt32 captureBufferByteSize = bufferByteSize / 2;
		
        AudioQueueBufferRef captureBuffer;
		AudioBufferList captureABL;
		
		XThrowIfError(AudioQueueAllocateBuffer(myInfo.mQueue, captureBufferByteSize, &captureBuffer), "AudioQueueAllocateBuffer");
		
        captureABL.mNumberBuffers = 1;
		captureABL.mBuffers[0].mData = captureBuffer->mAudioData;
		captureABL.mBuffers[0].mNumberChannels = captureFormat.mChannelsPerFrame;

		// lets start playing now - stop is called in the AQTestBufferCallback when there's
		// no more to read from the file
		XThrowIfError(AudioQueueStart(myInfo.mQueue, NULL), "AudioQueueStart failed");

		AudioTimeStamp ts;
		ts.mFlags = kAudioTimeStampSampleTimeValid;
		ts.mSampleTime = 0;

		// we need to call this once asking for 0 frames
		XThrowIfError(AudioQueueOfflineRender(myInfo.mQueue, &ts, captureBuffer, 0), "AudioQueueOfflineRender");

		// we need to enqueue a buffer after the queue has started
		AQTestBufferCallback(&myInfo, myInfo.mQueue, myInfo.mBuffer);

		while (true) {
			UInt32 reqFrames = captureBufferByteSize / captureFormat.mBytesPerFrame;
			
            XThrowIfError(AudioQueueOfflineRender(myInfo.mQueue, &ts, captureBuffer, reqFrames), "AudioQueueOfflineRender");
			
            captureABL.mBuffers[0].mData = captureBuffer->mAudioData;
			captureABL.mBuffers[0].mDataByteSize = captureBuffer->mAudioDataByteSize;
			UInt32 writeFrames = captureABL.mBuffers[0].mDataByteSize / captureFormat.mBytesPerFrame;
			
            printf("t = %.f: AudioQueueOfflineRender:  req %d fr/%d bytes, got %ld fr/%d bytes\n", ts.mSampleTime, (int)reqFrames, (int)captureBufferByteSize, writeFrames, (int)captureABL.mBuffers[0].mDataByteSize);
            
			XThrowIfError(ExtAudioFileWrite(captureFile, writeFrames, &captureABL), "ExtAudioFileWrite");
			
            if (myInfo.mFlushed) break;
			
			ts.mSampleTime += writeFrames;
		}

		CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, false);

		XThrowIfError(AudioQueueDispose(myInfo.mQueue, true), "AudioQueueDispose(true) failed");
		XThrowIfError(AudioFileClose(myInfo.mAudioFile), "AudioQueueDispose(false) failed");
		XThrowIfError(ExtAudioFileDispose(captureFile), "ExtAudioFileDispose failed");

		if (myInfo.mPacketDescs) delete [] myInfo.mPacketDescs;
		if (acl) free(acl);
	}
	catch (CAXException e) {
		char buf[256];
		fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf));
	}
    
    return;
}
Beispiel #20
0
/**
 * Initialize mmc support
 */
void mmc_init()
{
    da_session = DASessionCreate(kCFAllocatorDefault);
    DASessionScheduleWithRunLoop(da_session, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
}
DefaultGCActivityCallback::DefaultGCActivityCallback(Heap* heap)
{
    commonConstructor(heap, CFRunLoopGetCurrent());
}
Beispiel #22
0
		OSStatus SetupQueue(BG_FileInfo *inFileInfo)
		{
			UInt32 size = 0;
			OSStatus result = AudioQueueNewOutput(&inFileInfo->mFileFormat, QueueCallback, this, CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &mQueue);
					AssertNoError("Error creating queue", end);

			// (2) If the file has a cookie, we should get it and set it on the AQ
			size = sizeof(UInt32);
			result = AudioFileGetPropertyInfo (inFileInfo->mAFID, kAudioFilePropertyMagicCookieData, &size, NULL);

			if (!result && size) {
				char* cookie = new char [size];		
				result = AudioFileGetProperty (inFileInfo->mAFID, kAudioFilePropertyMagicCookieData, &size, cookie);
					AssertNoError("Error getting magic cookie", end);
				result = AudioQueueSetProperty(mQueue, kAudioQueueProperty_MagicCookie, cookie, size);
				delete [] cookie;
					AssertNoError("Error setting magic cookie", end);
			}

			// channel layout
			OSStatus err = AudioFileGetPropertyInfo(inFileInfo->mAFID, kAudioFilePropertyChannelLayout, &size, NULL);
			if (err == noErr && size > 0) {
				AudioChannelLayout *acl = (AudioChannelLayout *)malloc(size);
				result = AudioFileGetProperty(inFileInfo->mAFID, kAudioFilePropertyChannelLayout, &size, acl);
					AssertNoError("Error getting channel layout from file", end);
				result = AudioQueueSetProperty(mQueue, kAudioQueueProperty_ChannelLayout, acl, size);
				free(acl);
					AssertNoError("Error setting channel layout on queue", end);
			}
			
			// add a notification proc for when the queue stops
			result = AudioQueueAddPropertyListener(mQueue, kAudioQueueProperty_IsRunning, QueueStoppedProc, this);
				AssertNoError("Error adding isRunning property listener to queue", end);
				
			// we need to reset this variable so that if the queue is stopped mid buffer we don't dispose it 
			mMakeNewQueueWhenStopped = false;
			
			// volume
			result = SetVolume(mVolume);
			
		//end:
			return result;
		}
Beispiel #23
0
static IOReturn
HIDCreateOpenDeviceInterface(io_object_t hidDevice, recDevice * pDevice)
{
    IOReturn result = kIOReturnSuccess;
    HRESULT plugInResult = S_OK;
    SInt32 score = 0;
    IOCFPlugInInterface **ppPlugInInterface = NULL;

    if (NULL == pDevice->interface) {
        result =
            IOCreatePlugInInterfaceForService(hidDevice,
                                              kIOHIDDeviceUserClientTypeID,
                                              kIOCFPlugInInterfaceID,
                                              &ppPlugInInterface, &score);
        if (kIOReturnSuccess == result) {
            /* Call a method of the intermediate plug-in to create the device interface */
            plugInResult =
                (*ppPlugInInterface)->QueryInterface(ppPlugInInterface,
                                                     CFUUIDGetUUIDBytes
                                                     (kIOHIDDeviceInterfaceID),
                                                     (void *)
                                                     &(pDevice->interface));
            if (S_OK != plugInResult)
                HIDReportErrorNum
                    ("CouldnÕt query HID class device interface from plugInInterface",
                     plugInResult);
            (*ppPlugInInterface)->Release(ppPlugInInterface);
        } else
            HIDReportErrorNum
                ("Failed to create **plugInInterface via IOCreatePlugInInterfaceForService.",
                 result);
    }
    if (NULL != pDevice->interface) {
        result = (*(pDevice->interface))->open(pDevice->interface, 0);
        if (kIOReturnSuccess != result)
            HIDReportErrorNum
                ("Failed to open pDevice->interface via open.", result);
        else
		{
			pDevice->portIterator = 0;

			// It's okay if this fails, we have another detection method below
            (*(pDevice->interface))->setRemovalCallback(pDevice->interface,
                                                        HIDRemovalCallback,
                                                        pDevice, pDevice);
			
			/* now connect notification for new devices */
			pDevice->notificationPort = IONotificationPortCreate(kIOMasterPortDefault);
			
			CFRunLoopAddSource(CFRunLoopGetCurrent(), 
							   IONotificationPortGetRunLoopSource(pDevice->notificationPort), 
							   kCFRunLoopDefaultMode);
			
			// Register for notifications when a serial port is added to the system
			result = IOServiceAddInterestNotification(pDevice->notificationPort,
													  hidDevice,
													  kIOGeneralInterest,
													  JoystickDeviceWasRemovedCallback,
													  pDevice,           
													  &pDevice->portIterator);
        	if (kIOReturnSuccess != result) {
            	HIDReportErrorNum
                	("Failed to register for removal callback.", result);		
			}	
		}

    }
    return result;
}
Beispiel #24
0
void Audio_Queue::init()
{
    OSStatus err = noErr;
    
    cleanup();
        
    // create the audio queue
    err = AudioQueueNewOutput(&m_streamDesc, audioQueueOutputCallback, this, CFRunLoopGetCurrent(), NULL, 0, &m_outAQ);
    if (err) {
        AQ_TRACE("%s: error in AudioQueueNewOutput\n", __PRETTY_FUNCTION__);
        
        m_lastError = err;
        
        if (m_delegate) {
            m_delegate->audioQueueInitializationFailed();
        }
        
        return;
    }
    
    Stream_Configuration *configuration = Stream_Configuration::configuration();
    
    // allocate audio queue buffers
    for (unsigned int i = 0; i < configuration->bufferCount; ++i) {
        err = AudioQueueAllocateBuffer(m_outAQ, configuration->bufferSize, &m_audioQueueBuffer[i]);
        if (err) {
            /* If allocating the buffers failed, everything else will fail, too.
             *  Dispose the queue so that we can later on detect that this
             *  queue in fact has not been initialized.
             */
            
            AQ_TRACE("%s: error in AudioQueueAllocateBuffer\n", __PRETTY_FUNCTION__);
            
            (void)AudioQueueDispose(m_outAQ, true);
            m_outAQ = 0;
            
            m_lastError = err;
            
            if (m_delegate) {
                m_delegate->audioQueueInitializationFailed();
            }
            
            return;
        }
    }
    
    // listen for kAudioQueueProperty_IsRunning
    err = AudioQueueAddPropertyListener(m_outAQ, kAudioQueueProperty_IsRunning, audioQueueIsRunningCallback, this);
    if (err) {
        AQ_TRACE("%s: error in AudioQueueAddPropertyListener\n", __PRETTY_FUNCTION__);
        m_lastError = err;
        return;
    }
    
    if (configuration->enableTimeAndPitchConversion) {
        UInt32 enableTimePitchConversion = 1;
        
        err = AudioQueueSetProperty (m_outAQ, kAudioQueueProperty_EnableTimePitch, &enableTimePitchConversion, sizeof(enableTimePitchConversion));
        if (err != noErr) {
            AQ_TRACE("Failed to enable time and pitch conversion. Play rate setting will fail\n");
        }
    }
    
    if (m_initialOutputVolume != 1.0) {
        setVolume(m_initialOutputVolume);
    }
}
//  open - open 1 or more devices
//
//    Inputs:
//	max = maximum number of devices to open
//	vid = Vendor ID, or -1 if any
//	pid = Product ID, or -1 if any
//	usage_page = top level usage page, or -1 if any
//	usage = top level usage number, or -1 if any
//    Output:
//	actual number of devices opened
//
int pjrc_rawhid::open(int max, int vid, int pid, int usage_page, int usage)
{
    static IOHIDManagerRef hid_manager=NULL;
    CFMutableDictionaryRef dict;
    CFNumberRef num;
    IOReturn ret;
    hid_t *p;
    int count=0;

    if (first_hid) free_all_hid();
    //printf("pjrc_rawhid_open, max=%d\n", max);
    if (max < 1) return 0;
    // Start the HID Manager
    // http://developer.apple.com/technotes/tn2007/tn2187.html
    if (!hid_manager) {
        hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
        if (hid_manager == NULL || CFGetTypeID(hid_manager) != IOHIDManagerGetTypeID()) {
            if (hid_manager) CFRelease(hid_manager);
            return 0;
        }
    }
    if (vid > 0 || pid > 0 || usage_page > 0 || usage > 0) {
        // Tell the HID Manager what type of devices we want
        dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                                         &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
        if (!dict) return 0;
        if (vid > 0) {
            num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &vid);
            CFDictionarySetValue(dict, CFSTR(kIOHIDVendorIDKey), num);
            CFRelease(num);
        }
        if (pid > 0) {
            num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &pid);
            CFDictionarySetValue(dict, CFSTR(kIOHIDProductIDKey), num);
            CFRelease(num);
        }
        if (usage_page > 0) {
            num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage_page);
            CFDictionarySetValue(dict, CFSTR(kIOHIDPrimaryUsagePageKey), num);
            CFRelease(num);
        }
        if (usage > 0) {
            num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage);
            CFDictionarySetValue(dict, CFSTR(kIOHIDPrimaryUsageKey), num);
            CFRelease(num);
        }
        IOHIDManagerSetDeviceMatching(hid_manager, dict);
        CFRelease(dict);
    } else {
        IOHIDManagerSetDeviceMatching(hid_manager, NULL);
    }
    // set up a callbacks for device attach & detach
    IOHIDManagerScheduleWithRunLoop(hid_manager, CFRunLoopGetCurrent(),
                                    kCFRunLoopDefaultMode);
    IOHIDManagerRegisterDeviceMatchingCallback(hid_manager, attach_callback, NULL);
    IOHIDManagerRegisterDeviceRemovalCallback(hid_manager, detach_callback, NULL);
    ret = IOHIDManagerOpen(hid_manager, kIOHIDOptionsTypeNone);
    if (ret != kIOReturnSuccess) {
        printf("Could not start IOHIDManager");
        IOHIDManagerUnscheduleFromRunLoop(hid_manager,
                                          CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
        CFRelease(hid_manager);
        return 0;
    }
    // Set the run loop reference:
    the_correct_runloop = CFRunLoopGetCurrent();
    printf("run loop\n");
    // let it do the callback for all devices
    while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) == kCFRunLoopRunHandledSource) ;
    // count up how many were added by the callback
    for (p = first_hid; p; p = p->next) count++;
    return count;
}
Beispiel #26
0
FskErr FskFSDirectoryChangeNotifierNew(const char *path, UInt32 flags, FskDirectoryChangeNotifierCallbackProc callback, void *refCon, FskDirectoryChangeNotifier *dirChangeNotifier)
{
	FskErr err = kFskErrNone;
	FskFSDirectoryChangeNotifier directoryChangeNotifier;
	struct kevent eventToAdd;
	int errNum;
	CFFileDescriptorContext context = {0, NULL, NULL, NULL, NULL};
	CFRunLoopSourceRef rls;

	err = FskMemPtrNewClear(sizeof(FskFSDirectoryChangeNotifierRecord), (FskMemPtr *)(&directoryChangeNotifier));
	BAIL_IF_ERR(err);

	directoryChangeNotifier->base.dispatch.dispatch = &gFSDispatch;
	directoryChangeNotifier->callback = callback;
	directoryChangeNotifier->refCon = refCon;
	directoryChangeNotifier->path = FskStrDoCopy(path);
	directoryChangeNotifier->dirFD = -1;
	directoryChangeNotifier->kq = -1;
	directoryChangeNotifier->dirKQRef = NULL;

	directoryChangeNotifier->dirFD = open(path, O_EVTONLY);
	if (directoryChangeNotifier->dirFD < 0)
	{
		BAIL(kFskErrFileNotFound);
	}
    
	directoryChangeNotifier->kq = kqueue();
	if (directoryChangeNotifier->kq < 0)
	{
		BAIL(kFskErrOperationFailed);
	}
    
	eventToAdd.ident = directoryChangeNotifier->dirFD;
	eventToAdd.filter = EVFILT_VNODE;
	eventToAdd.flags = EV_ADD | EV_CLEAR;
	eventToAdd.fflags = NOTE_WRITE;
	eventToAdd.data = 0;
	eventToAdd.udata = NULL;

	errNum = kevent(directoryChangeNotifier->kq, &eventToAdd, 1, NULL, 0, NULL);
	if (errNum != 0)
	{
		BAIL(kFskErrOperationFailed);
	}

	context.info = directoryChangeNotifier;
	directoryChangeNotifier->dirKQRef = CFFileDescriptorCreate(NULL, directoryChangeNotifier->kq, true, KQCallback, &context);
	if (directoryChangeNotifier->dirKQRef == NULL)
	{
		BAIL(kFskErrOperationFailed);
	}

	rls = CFFileDescriptorCreateRunLoopSource(NULL, directoryChangeNotifier->dirKQRef, 0);
	if (rls == NULL)
	{
		BAIL(kFskErrOperationFailed);
	}

	CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
	CFRelease(rls);
	CFFileDescriptorEnableCallBacks(directoryChangeNotifier->dirKQRef, kCFFileDescriptorReadCallBack);

bail:
	if (err)
	{
		FskFSDirectoryChangeNotifierDispose((FskDirectoryChangeNotifier)directoryChangeNotifier);
		directoryChangeNotifier = NULL;
	}

	*dirChangeNotifier = (FskDirectoryChangeNotifier)directoryChangeNotifier;
	return err;
}
Beispiel #27
0
static int ListenUsingCoreFoundation(size_t noteCount, const char **noteNames)
    // Implements the "listenCF" command.  Register for the noteCount 
    // notifications whose names are in the noteNames array.  Then wrap the 
    // notification Mach port in a CFMachPort and use CF to read the notification 
    // messages, printing the information about any notifications that arrive 
    // from our CFMachPort callback.
{
    int         retVal;
    uint32_t    noteErr;
    size_t      noteIndex;
    int         noteTokens[noteCount];
    mach_port_t port = MACH_PORT_NULL;
    
    // Register.  The first time around this loop fd == -1 and so we don't 
    // specify NOTIFY_REUSE.  notify_register_mach_port then allocates 
    // a Mach port and returns it in port.  For subsequent iterations 
    // we /do/ specify NOTIFY_REUSE and notify_register_mach_port just 
    // reuses the existing port.

    noteErr = NOTIFY_STATUS_OK;
    for (noteIndex = 0; noteIndex < noteCount; noteIndex++) {
        noteErr = notify_register_mach_port(
            noteNames[noteIndex], 
            &port, 
            (port == MACH_PORT_NULL) ? 0 : NOTIFY_REUSE, 
            &noteTokens[noteIndex]
        );
        if (noteErr != NOTIFY_STATUS_OK) {
            break;
        }
    }
    if (noteErr != NOTIFY_STATUS_OK) {
        PrintNotifyError("registration failed", noteNames[noteIndex], noteErr);
        retVal = EXIT_FAILURE;
    } else {
        MyCFMachPortCallBackInfo    myInfo;
        CFMachPortContext           context = { 0 , NULL, NULL, NULL, NULL };
        CFMachPortRef               cfPort;
        Boolean                     shouldFreeInfo;
        CFRunLoopSourceRef          rls;
        
        // Set up the context structure for MyCFMachPortCallBack.
        
        myInfo.magic      = 'CFpI';
        myInfo.noteCount  = noteCount;
        myInfo.noteTokens = noteTokens;
        myInfo.noteNames  = noteNames;
        
        // Create the CFMachPort.
        
        context.info = &myInfo;
        cfPort = CFMachPortCreateWithPort(
            NULL, 
            port, 
            MyCFMachPortCallBack, 
            &context, 
            &shouldFreeInfo
        );
        assert(cfPort != NULL);
        
        // There can only be one CFMachPort for a given Mach port name.  Thus, 
        // if someone had already created a CFMachPort for "port", CFMachPort 
        // would not create a new CFMachPort but, rather, return the existing 
        // CFMachPort with the retain count bumped.  In that case it hasn't 
        // taken any 'reference' on the data in context; the context.info 
        // on the /previous/ CFMachPort is still in use, but the context.info 
        // that we supply is now superfluous.  In that case it returns 
        // shouldFreeInfo, telling us that we don't need to hold on to this 
        // information.
        //
        // In this specific case no one should have already created a CFMachPort 
        // for "port", so shouldFreeInfo should never be true.  If it is, it's 
        // time to worry!
        
        assert( ! shouldFreeInfo );
        
        // Add it to the run loop.
        
        rls = CFMachPortCreateRunLoopSource(NULL, cfPort, 0);
        assert(rls != NULL);

        CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
        
        CFRelease(rls);
        
        // Run the run loop.
        
        fprintf(stdout, "Listening using Core Foundation:\n");
        fflush(stdout);
        
        CFRunLoopRun();

        fprintf(stderr, "CFRunLoopRun returned\n");
        retVal = EXIT_FAILURE;
    }
    
    return retVal;
}
Beispiel #28
0
static void *read_thread(void *param)
{
	hid_device *dev = param;
	
	/* Move the device's run loop to this thread. */
	IOHIDDeviceScheduleWithRunLoop(dev->device_handle, CFRunLoopGetCurrent(), dev->run_loop_mode);

	/* Create the RunLoopSource which is used to signal the
	   event loop to stop when hid_close() is called. */
	CFRunLoopSourceContext ctx;
	memset(&ctx, 0, sizeof(ctx));
	ctx.version = 0;
	ctx.info = dev;
	ctx.perform = &perform_signal_callback;
	dev->source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0/*order*/, &ctx);
	CFRunLoopAddSource(CFRunLoopGetCurrent(), dev->source, dev->run_loop_mode);
	
	/* Store off the Run Loop so it can be stopped from hid_close()
	   and on device disconnection. */
	dev->run_loop = CFRunLoopGetCurrent();

	/* Notify the main thread that the read thread is up and running. */
	pthread_barrier_wait(&dev->barrier);

	/* Run the Event Loop. CFRunLoopRunInMode() will dispatch HID input
	   reports into the hid_report_callback(). */
	SInt32 code;
	while (!dev->shutdown_thread && !dev->disconnected) {
		code = CFRunLoopRunInMode(dev->run_loop_mode, 1000/*sec*/, FALSE);
		/* Return if the device has been disconnected */
		if (code == kCFRunLoopRunFinished) {
			dev->disconnected = 1;
			break;
		}


		/* Break if The Run Loop returns Finished or Stopped. */
		if (code != kCFRunLoopRunTimedOut &&
		    code != kCFRunLoopRunHandledSource) {
			/* There was some kind of error. Setting
			   shutdown seems to make sense, but
			   there may be something else more appropriate */
			dev->shutdown_thread = 1;
			break;
		}
	}

	/* Now that the read thread is stopping, Wake any threads which are
	   waiting on data (in hid_read_timeout()). Do this under a mutex to
	   make sure that a thread which is about to go to sleep waiting on
	   the condition acutally will go to sleep before the condition is
	   signaled. */
	pthread_mutex_lock(&dev->mutex);
	pthread_cond_broadcast(&dev->condition);
	pthread_mutex_unlock(&dev->mutex);

	/* Wait here until hid_close() is called and makes it past
	   the call to CFRunLoopWakeUp(). This thread still needs to
	   be valid when that function is called on the other thread. */
	pthread_barrier_wait(&dev->shutdown_barrier);

	return NULL;
}
DefaultGCActivityCallback::DefaultGCActivityCallback(Heap* heap)
    : GCActivityCallback(heap->vm(), CFRunLoopGetCurrent())
    , m_delay(s_decade)
{
}
Beispiel #30
-1
int main (int argc, const char * argv[])
    // This program finds the first PPP connection service in the 
    // current network configuration and then connects and 
    // disconnects that service.
{
    int                     err;
    Boolean                 ok;
    CFStringRef             serviceToDial;
    CFDictionaryRef         optionsForDial;
    SCNetworkConnectionRef  connection;
    CallbackParams          params;
    
    serviceToDial  = NULL;
    optionsForDial = NULL;
    connection     = NULL;
    
    // If we're run without an argument, just print the usage.
    
    err = 0;
    if (argc != 1) {
        const char *programName;
        
        programName = strrchr(argv[0], '/');
        if (programName == NULL) {
            programName = argv[0];
        } else {
            programName += 1;
        }
        fprintf(stderr, "Usage: %s\n", programName);
        err = ECANCELED;
    }

    // Find the serviceID of the PPP service to dial and the user's 
    // preferred dialling options.  This routine picks up the last 
    // service dialled using Internet Connect (and the associated 
    // options) or, if Internet Connect has not been used, returns 
    // the first PPP service listed in the Network preferences pane.
    
    if (err == 0) {
        ok = SCNetworkConnectionCopyUserPreferences(
            NULL, 
            &serviceToDial,
            &optionsForDial
        );
        if ( ! ok ) {
            err = SCError();
        }
    }
    
    // Create a SCNetworkConnectionRef for it.
    
    if (err == 0) {
        SCNetworkConnectionContext context;

        // Set up the parameters to our callback function.
        
        params.magic            = kCallbackParamsMagic;
        params.forcePrintStatus = true;
        params.lastMinorStatus  = kSCNetworkConnectionDisconnected;
        params.lastMinorStatus  = kSCNetworkConnectionPPPDisconnected;
        
        // Set up the context to reference those parameters.
        
        context.version         = 0;
        context.info            = (void *) &params;
        context.retain          = NULL;
        context.release         = NULL;
        context.copyDescription = NULL;
        
        connection = SCNetworkConnectionCreateWithServiceID(
            NULL,
            serviceToDial, 
            MyNetworkConnectionCallBack,
            &context
        );
        if (connection == NULL) {
            err = SCError();
        }
    }

    // Schedule our callback with the runloop.
    
    if (err == 0) {
        ok = SCNetworkConnectionScheduleWithRunLoop(
            connection,
            CFRunLoopGetCurrent(),
            kCFRunLoopDefaultMode
        );
        if ( ! ok ) {
            err = SCError();
        }
    }
    
    // Check the status.  If we're already connected tell the user. 
    // If we're not connected, initiate the connection.
    
    if (err == 0) {
        err = ECANCELED;    // Most cases involve us bailing out, 
                            // so set the error here.
        
        switch ( SCNetworkConnectionGetStatus(connection) ) {
            case kSCNetworkConnectionDisconnected:
                err = 0;
                break;
            case kSCNetworkConnectionConnecting:
                fprintf(stderr, "Service is already connecting.\n");
                break;
            case kSCNetworkConnectionDisconnecting:
                fprintf(stderr, "Service is disconnecting.\n");
                break;
            case kSCNetworkConnectionConnected:
                fprintf(stderr, "Service is already connected.\n");
                break;
            case kSCNetworkConnectionInvalid:
                fprintf(stderr, "Service is invalid.  Weird.\n");
                break;
            default:
                fprintf(stderr, "Unexpected status.\n");
                break;
        }
    }
    
    // Initiate the connection.
    
    if (err == 0) {
        fprintf(stderr, "Connecting...\n");

        ok = SCNetworkConnectionStart(
            connection,
            optionsForDial,
            false
        );
        if ( ! ok ) {
            err = SCError();
        }
    }
    
    // Run the runloop and wait for our connection attempt to be resolved. 
    // Once that happens, print the result.
    
    if (err == 0) {
        CFRunLoopRun();
        
        switch (params.lastMinorStatus) {
            case kSCNetworkConnectionPPPConnected:
                fprintf(stderr, "Connection succeeded\n");
                break;
            case kSCNetworkConnectionPPPDisconnected:
                fprintf(stderr, "Connection failed\n");
                err = ECANCELED;
                break;
            default:
                fprintf(
                    stderr, 
                    "Bad params.lastMinorStatus (%ld)\n", 
                    (long) params.lastMinorStatus
                );
                err = EINVAL;
                break;
        }
    }
    
    // Wait for a few seconds.
    
    if (err == 0) {
        fprintf(stderr, "Waiting for a few seconds...\n");
        
        (void) sleep(5);
    
    // Initiate a disconnect.

        params.forcePrintStatus = true;

        fprintf(stderr, "Disconnecting...\n");

        ok = SCNetworkConnectionStop(
            connection,
            true
        );
        if ( ! ok ) {
            err = SCError();
        }
    }
    
    // Run the runloop and wait for our disconnection attempt to be 
    // resolved.  Once that happens, print the result.

    if (err == 0) {
        CFRunLoopRun();
        
        switch (params.lastMinorStatus) {
            case kSCNetworkConnectionPPPDisconnected:
                fprintf(stderr, "Disconnection succeeded\n");
                break;
            case kSCNetworkConnectionPPPConnected:
                fprintf(stderr, "Disconnection failed\n");
                err = ECANCELED;
                break;
            default:
                fprintf(
                    stderr, 
                    "Bad params.lastMinorStatus (%ld)\n", 
                    (long) params.lastMinorStatus
                );
                err = EINVAL;
                break;
        }
    }

    // Clean up.
    
    if (serviceToDial != NULL) {
        CFRelease(serviceToDial);
    }
    if (optionsForDial != NULL) {
        CFRelease(optionsForDial);
    }
    if (connection != NULL) {
        (void) SCNetworkConnectionUnscheduleFromRunLoop(
            connection,
            CFRunLoopGetCurrent(),
            kCFRunLoopDefaultMode
        );
        CFRelease(connection);
    }
    
    if (err == 0) {
        return EXIT_SUCCESS;
    } else {
        if (err != ECANCELED) {
            fprintf(stderr, "Failed with error %d\n.", err);
        }
        return EXIT_FAILURE;
    }
}