Nfcd: Difference between revisions

From iPhone Development Wiki
No edit summary
(Formatting and memory leak fix.)
 
Line 1: Line 1:
nfcd is a daemon running under the ''mobile'' user. It handles the communications between PassKit and the underlying hardware and libraries.
nfcd is a daemon running under the ''mobile'' user. It handles the communications between PassKit and the underlying hardware and libraries.


The core objects in it are:
== Core objects ==
 
* NFDaemon
* NFDaemon
* NFFieldDetectController
* NFFieldDetectController
Line 9: Line 10:
* NFCardEmulationController
* NFCardEmulationController
* NFSecureElementController
* NFSecureElementController
NFDaemon - (void)XPCConnection:(id) didReceiveCommand:(id)


== Launchd plist ==
== Launchd plist ==
Line 64: Line 63:
| >247 || throw error
| >247 || throw error
|}
|}
==Sending XPC Commands==
 
Four XPC keys are send for the XPC command:
== Sending XPC Commands ==
*NFMsgObject - dictionary containing values to sent to receiving objects
 
*NFMsgType - uint64, sending is a 0, receiving a 1
Four XPC keys are sent for the XPC command:
*NFMsgCode - uint64, "command" as described above
* NFMsgObject - dictionary containing values to sent to receiving objects
*NFMsgId - uint64, no idea at the moment
* NFMsgType - uint64, sending is a 0, receiving a 1
* NFMsgCode - uint64, "command" as described above
* NFMsgId - uint64, undetermined


Example of XPC command to the nfcd:
Example of XPC command to the nfcd:
<source lang='javascript'>
<source lang='c'>
#include <xpc/xpc.h>
#include <xpc/xpc.h>


int main(int argc, char **argv, char **envp) {
int main(int argc, char **argv, char **envp) {
    // Create connection to mach service
// Create connection to mach service
    xpc_connection_t connection = xpc_connection_create_mach_service("com.apple.nfcd", NULL, 0);
xpc_connection_t connection = xpc_connection_create_mach_service("com.apple.nfcd", NULL, 0);
    xpc_connection_set_event_handler(connection, ^(xpc_object_t some_object) { });
xpc_connection_set_event_handler(connection, ^(xpc_object_t object) {
    xpc_connection_resume(connection);
char *description = xpc_copy_description(object);
printf("Sending object: %s\n", description);
free(description);
});
xpc_connection_resume(connection);


    while (true) {
while (true) {
        // Send message to mach service, and wait for a response
// Send message to mach service, and wait for a response
      xpc_object_t msgobject = xpc_dictionary_create(NULL,NULL,0);  
xpc_object_t msgobject = xpc_dictionary_create(NULL,NULL,0);  
xpc_object_t object = xpc_dictionary_create(NULL, NULL, 0);
xpc_object_t object = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_int64(msgobject, "Controller",6);
xpc_dictionary_set_int64(msgobject, "Controller", 6);
xpc_dictionary_set_value(object, "NFMsgObject", msgobject);
xpc_dictionary_set_value(object, "NFMsgObject", msgobject);
xpc_dictionary_set_uint64(object, "NFMsgType" ,0x00);  
xpc_dictionary_set_uint64(object, "NFMsgType", 0x00);  
      xpc_dictionary_set_uint64(object, "NFMsgCode" ,0x01);  
xpc_dictionary_set_uint64(object, "NFMsgCode", 0x01);  
      xpc_dictionary_set_uint64(object, "NFMsgId" ,17);  
xpc_dictionary_set_uint64(object, "NFMsgId", 17);
printf("Sending object: %s\n", xpc_copy_description(object));
        xpc_object_t reply = xpc_connection_send_message_with_reply_sync(connection, object);
        printf("Received reply object: %s\n\n", xpc_copy_description(reply));
        sleep(1);
    }


    return 0;
char *description = xpc_copy_description(object);
printf("Sending object: %s\n", description);
free(description);
 
xpc_object_t reply = xpc_connection_send_message_with_reply_sync(connection, object);
description = xpc_copy_description(object);
printf("Received reply object: %s\n\n", description);
free(description);
sleep(1);
}
 
return 0;
}
}
</source>
</source>
see https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/xpc_dictionary_set_uint64.3.html
see https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/xpc_dictionary_set_uint64.3.html


==NFDaemon - (int)q_registerConnection:(XPCConnection) info:()==
== NFDaemon methods ==
 
{{Function signature|signature=-(void)XPCConnection:(id)connection didReceiveCommand:(id)command;|firmware=8.0 - 9.0.1}}
 
{{Function signature|signature=-(int)q_registerConnection:(id)connection info:(id)info;|firmware=8.0 - 9.0.1}}
 
This function checks for an existing controller
 
* [NFCardEmulationController embeddedCardEmulationController]
* [NFCardEmulationController UICCCardEmulationController]
* [NFSecureElementController seController]
* [NFFieldDetectController fieldDetectController]
 
When it finds the appropriate controller it calls the unregister function for it.


==NFDaemon - (unsigned int)q_unregisterConnection:(XPCConnection)==
{{Function signature|signature=-(unsigned int)q_unregisterConnection:(id)connection;|firmware=8.0 - 9.0.1}}
This functions checks for an existing controller for the
*[NFCardEmulationController embeddedCardEmulationController]
*[NFCardEmulationController UICCCardEmulationController]
*[NFSecureElementController seController]
*[NFFieldDetectController fieldDetectController]
Then when it finds the appropriate controller then calls the unregister function for it.

Latest revision as of 14:48, 29 September 2015

nfcd is a daemon running under the mobile user. It handles the communications between PassKit and the underlying hardware and libraries.

Core objects

  • NFDaemon
  • NFFieldDetectController
  • NFCoreTelephonyConnection
  • NFPowerManager
  • NFAbstractController
  • NFCardEmulationController
  • NFSecureElementController

Launchd plist

{
    EnablePressuredExit = 1;
    EnableTransactions = 1;
    ExitTimeOut = 45;
    Label = "com.apple.nfcd";
    MachServices =     {
        "com.apple.nfcd" = 1;
    };
    ProcessType = Interactive;
    Program = "/usr/libexec/nfcd";
    UserName = mobile;
}

Where the XPC service is registered under the "com.apple.nfcd" name

Supported XPC Commands

ID Command
1 q_registerConnection:info:
2 q_unregisterConnection:
3-64 send command to SE controller
65 q_updateSecureElementPowerState
66 _seIsInRestrictedMode
67 restrictedModeChanged
68-239 callSEContoller
240 setDeviceString
241 q_getControllerInfo
242 q_getSecureElementInfo
243 q_getBoosterInfo
244 q_readBoosterRegister
245 q_sendBoosterCommand
246 q_triggerAssertion
>247 throw error

Sending XPC Commands

Four XPC keys are sent for the XPC command:

  • NFMsgObject - dictionary containing values to sent to receiving objects
  • NFMsgType - uint64, sending is a 0, receiving a 1
  • NFMsgCode - uint64, "command" as described above
  • NFMsgId - uint64, undetermined

Example of XPC command to the nfcd:

#include <xpc/xpc.h>

int main(int argc, char **argv, char **envp) {
	// Create connection to mach service
	xpc_connection_t connection = xpc_connection_create_mach_service("com.apple.nfcd", NULL, 0);
	xpc_connection_set_event_handler(connection, ^(xpc_object_t object) {
		char *description = xpc_copy_description(object);
		printf("Sending object: %s\n", description);
		free(description);
	});
	xpc_connection_resume(connection);

	while (true) {
		// Send message to mach service, and wait for a response
		xpc_object_t msgobject = xpc_dictionary_create(NULL,NULL,0); 
		xpc_object_t object = xpc_dictionary_create(NULL, NULL, 0);
		xpc_dictionary_set_int64(msgobject, "Controller", 6);
		xpc_dictionary_set_value(object, "NFMsgObject", msgobject);
		xpc_dictionary_set_uint64(object, "NFMsgType", 0x00); 
		xpc_dictionary_set_uint64(object, "NFMsgCode", 0x01); 
		xpc_dictionary_set_uint64(object, "NFMsgId", 17);

		char *description = xpc_copy_description(object);
		printf("Sending object: %s\n", description);
		free(description);

		xpc_object_t reply = xpc_connection_send_message_with_reply_sync(connection, object);
		description = xpc_copy_description(object);
		printf("Received reply object: %s\n\n", description);
		free(description);
		sleep(1);
	}

	return 0;
}

see https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/xpc_dictionary_set_uint64.3.html

NFDaemon methods

Signature -(void)XPCConnection:(id)connection didReceiveCommand:(id)command;
Available in 8.0 - 9.0.1
Signature -(int)q_registerConnection:(id)connection info:(id)info;
Available in 8.0 - 9.0.1

This function checks for an existing controller

  • [NFCardEmulationController embeddedCardEmulationController]
  • [NFCardEmulationController UICCCardEmulationController]
  • [NFSecureElementController seController]
  • [NFFieldDetectController fieldDetectController]

When it finds the appropriate controller it calls the unregister function for it.

Signature -(unsigned int)q_unregisterConnection:(id)connection;
Available in 8.0 - 9.0.1