Creating and binding socket on Mac OS Hight Sierra - objective-c

I have serious and strange problem with creating socket in my application for Hight Sierra. If I create command Line tool, everything is ok! I create socket, bind socket. But If I trying to create Cocoa App, I can't binding my socket! :(
If I use CFSockets in Cocoa App,
char punchline[] = "MESSAGE from Server!";
int yes = 1;
CFSocketContext CTX = {0, punchline, NULL, NULL, NULL};
CFSocketRef TCPServer = CFSocketCreate(kCFAllocatorDefault, PF_INET, SOCK_STREAM, IPPROTO_TCP, kCFSocketAcceptCallBack, (CFSocketCallBack) &AcceptCallBack, &CTX);
if (TCPServer == NULL) return;
setsockopt(CFSocketGetNative(TCPServer), SOL_SOCKET, SO_REUSEADDR, (void *) &yes, sizeof(yes));
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_len = sizeof(addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(33000);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
NSData *address = [NSData dataWithBytes:&addr length:sizeof(addr)];
if (CFSocketSetAddress(TCPServer, (CFDataRef) address) != kCFSocketSuccess) {
CFRelease(TCPServer);
return;
}
I get this message:
CFSocketSetAddress bind failure: 1
If I use low level C function in Cocoa App, like this:
sockfd = socket(AF_INET, SOCK_STREAM, 0);
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0) error("ERROR on binding");
listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
...it's not work too, and I get error on binding and also this message in console:
ERROR: Operation not permitted
But in command line tool everything is working well!
What kind of project settings (may be in info.plist) I need to fix?
Where is a trouble? :(
Help me! :(((

The problem was that the application was sandboxed and did not have the Network: Incoming Connections entitlement. That entitlement can be added in Xcode under the App Sandbox details in the Capabilities tab of the target settings.

To Fix it in macOS Catalina Version 10.15.3:

Related

IPv6 Compatibility Issues with Low-Level C API's [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
Apple requires IPv6 Compatibility. Seems a little premature, but I suppose someone has to force it's wide adoption.
I have a client who has some legacy code that will no longer be approved for the App Store because of this incompatibility. I did not write the software by myself, and specifically have never touched this part of the code. I am not much of a ninja when it comes to low-level C networking.
I told the client that part of the problem was that they had an IPv4-only server and had us hardcode an IPv4 address to that server. I updated the IPv4 address to a domain name and told them their servers had to support IPv6. So, they moved them all over, and flipped the switch before any testing could be done. I was notified a few days ago that all their software on the store no longer worked. That's the predicament we are in.
Here is one of potentially many issues that I could use some help on.
Not only does the server that is connected to the port not respond to IPv6, but there are some lower level APIs that are being used that are incompatible.
The first thing I encountered is the use of gethostbyname(). Apparently this is not IPv6 capable. I have been trying to fix it with getaddrinfo() but my sockaddr's are not quite the same.
The second issue I can see is that apparently I need to be using AF_UNSPEC instead of AF_INET. So I am attempting to open a socket in the following way:
int sockfd = socket(AF_UNSPEC, SOCK_STREAM, 0);
I always get -1.
If I open a sock using AF_INET I get further, but then I have this issues:
otherAddr sockaddr * 0x618000220680 0x0000618000220680
sa_len __uint8_t '\x1c'
sa_family sa_family_t '\x1e'
sa_data char [14] "\x13\x88"
otherAddrCast sockaddr * 0x7000052d3c28 0x00007000052d3c28
sa_len __uint8_t '\0'
sa_family sa_family_t '\0'
sa_data char [14] "\x13\x88\"Ԛ\\"
So some of the sa_data is the same. and if I don't cast the sockaddr_in to a struct sockaddr* then the sa_data is the same.
Problem is I don't know what most of this means. Help?
EDIT: Here is my code. Assume that I am only getting 1 addr back (because I am)
struct hostent* server = gethostbyname([_hostname UTF8String]);
struct addrinfo *ai;
struct addrinfo hints;
memset(&hints, 0x00, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
NSString* portString = [NSString stringWithFormat:#"%d", _port];
getaddrinfo([_hostname UTF8String], [portString cStringUsingEncoding:kCFStringEncodingASCII] , &hints, &ai);
struct sockaddr_in addr = {0};
addr.sin_family = AF_INET;
bcopy(server->h_addr, &addr.sin_addr.s_addr, server->h_length);
addr.sin_port = htons(_port);
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
_addr = (struct sockaddr*)&addr;
int status = connect(sockfd, (struct sockaddr*)&addr, sizeof(addr));
int status2 = connect(socket(ai->ai_family,ai->ai_socktype,0), ai->ai_addr, ai->ai_addrlen);
You are NOT supposed to use AF_UNSPEC with socket() at all. You MUST use either AF_INET (IPv4) or AF_INET6 (IPv6).
You can use AF_UNSPEC with the hints input parameter of getaddrinfo() to indicate that you are willing to accept both IPv4 and IPv6 addresses as output. The actual addresses in the output will be either AF_INET or AF_INET6. Or, you can set the hints to AF_INET for IPv4-only output. Or AF_INET6 for IPv6-only output.
You are supposed to loop through the list that is returned by getaddrinfo(). For each address in the list:
pass its ai_family, ai_socktype, and ai_protocol fields to socket()
then pass its ai_addr and ai_addrlen fields to bind() (servers) or connect() (clients).
Repeat this for all addresses reported for a listening server, and for all addresses reported for a client until one successfully connects.
This way, each socket you create matches the IP version of the address it is working with, and you are passing an appropriate matching sockaddr_in (IPv4) or sockaddr_in6 (IPv6) to bind()/connect().
Once you have successful listening server socket(s), or a successfully connected client socket, if you need to retrieve an IP from a socket using accept(), getsockname() or getpeername(), be sure to pass it a sockaddr_storage struct to fill in. sockaddr_storage is large enough to hold all defined sockaddr-based structures (and there are many). If successful, you can then type-cast it to a sockaddr_in or sockaddr_in6 based on its sa_family field (AF_INET or AF_INET6, respectively). Same goes for other similar functions, like inet_pton() and inet_ntop().
Update: given the client code you have shown, try this instead:
struct addrinfo hints = {0};
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
NSString* portString = [NSString stringWithFormat:#"%d", _port];
struct addrinfo *ai;
int sockfd = -1;
int status = getaddrinfo([_hostname UTF8String], [portString cStringUsingEncoding:kCFStringEncodingASCII] , &hints, &ai);
if (status == 0) {
sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (sockfd == -1) {
status = errno;
}
else if (connect(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) {
status = errno;
close(sockfd);
sockfd = -1;
}
freeaddrinfo(ai);
}
if (sockfd == -1) {
// handle status error as needed...
}
else {
// use sockfd as needed...
close(sockfd);
}

MIDISend: to play a musical note on iPhone

I am trying to generate a musical note that will play through the iPhone speakers using Objective-C and MIDI. I have the code below but it is not doing anything. What am I doing wrong?
MIDIPacketList packetList;
packetList.numPackets = 1;
MIDIPacket* firstPacket = &packetList.packet[0];
firstPacket->timeStamp = 0; // send immediately
firstPacket->length = 3;
firstPacket->data[0] = 0x90;
firstPacket->data[1] = 80;
firstPacket->data[2] = 120;
MIDIPacketList pklt=packetList;
MIDISend(MIDIGetSource(0), MIDIGetDestination(0), &pklt);
You've got three problems:
Declaring a MIDIPacketList doesn't allocate memory or initialize the structure
You're passing the results of MIDIGetSource (which returns a MIDIEndpointRef) as the first parameter to MIDISend where it is expecting a MIDIPortRef instead. (You probably ignored a compiler warning about this. Never ignore compiler warnings.)
Sending a MIDI note in iOS doesn't make any sound. If you don't have an external MIDI device connected to your iOS device, you need to set up something with CoreAudio that will generate sounds. That's beyond the scope of this answer.
So this code will run, but it won't make any sounds unless you've got external hardware:
//Look to see if there's anything that will actually play MIDI notes
NSLog(#"There are %lu destinations", MIDIGetNumberOfDestinations());
// Prepare MIDI Interface Client/Port for writing MIDI data:
MIDIClientRef midiclient = 0;
MIDIPortRef midiout = 0;
OSStatus status;
status = MIDIClientCreate(CFSTR("Test client"), NULL, NULL, &midiclient);
if (status) {
NSLog(#"Error trying to create MIDI Client structure: %d", (int)status);
}
status = MIDIOutputPortCreate(midiclient, CFSTR("Test port"), &midiout);
if (status) {
NSLog(#"Error trying to create MIDI output port: %d", (int)status);
}
Byte buffer[128];
MIDIPacketList *packetlist = (MIDIPacketList *)buffer;
MIDIPacket *currentpacket = MIDIPacketListInit(packetlist);
NSInteger messageSize = 3; //Note On is a three-byte message
Byte msg[3] = {0x90, 80, 120};
MIDITimeStamp timestamp = 0;
currentpacket = MIDIPacketListAdd(packetlist, sizeof(buffer), currentpacket, timestamp, messageSize, msg);
MIDISend(midiout, MIDIGetDestination(0), packetlist);

libusb_open returns 'LIBUSB_ERROR_NOT_SUPPORTED' on Windows 7

I have been developing USB drivers using LibUSB on Linux, but now I want to have one of my drivers compiled for Windows (this is the first time I am doing it).
My environment
I am working on Windows 7 using the MinGW compiler (also using Dev-cpp IDE), and I am using a pre-compiled libusb library downloaded from this link.
My device: It's a HID touch device. So no drivers are required for Windows. I have an additional endpoint to get certain debug data.
My code:
I have compiled code to list all the devices and USB devices connected to my machine, and the code works. Now I add code to open the device so that I get a device handle and start communication. But the function returns -12 That is, LIBUSB_ERROR_NOT_SUPPORTED.
How can I fix this problem?
I searched through the Internet and did not find a definite solution for this problem. While it's code which works beautifully on Linux.
P.S.: I have added the whole code below. The DoList(); function works fine, but the GetTRSDevice(); function fails at libusb_open(dev, &handle);.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libusb.h>
libusb_device_handle* deviceHandle = NULL;
int DoList();
libusb_device_handle* GetTRSDevice(void);
int main()
{
int ret = libusb_init(NULL);
if (ret < 0) {
printf("Failed to init libusb");
return ret;
}
DoList();
deviceHandle = GetTRSDevice();
if(!deviceHandle) {
printf("Failed to locate device");
goto fail_dev_open;
}
printf("Device opened");
libusb_close(deviceHandle);
fail_dev_open:
libusb_exit(NULL);
return(ret);
}
int DoList()
{
libusb_device **devs;
ssize_t cnt;
cnt = libusb_get_device_list(NULL, &devs);
if (cnt < 0)
return (int) cnt;
libusb_device *dev;
int i = 0;
while ((dev = devs[i++]) != NULL) {
struct libusb_device_descriptor desc;
int r = libusb_get_device_descriptor(dev, &desc);
if (r < 0) {
fprintf(stderr, "failed to get device descriptor");
return(-1);
}
printf("%04x:%04x (bus %d, device %d)\n",
desc.idVendor, desc.idProduct,
libusb_get_bus_number(dev), libusb_get_device_address(dev));
}
libusb_free_device_list(devs, 1);
return 0;
}
libusb_device_handle* GetTRSDevice(void)
{
int i = 0;
ssize_t cnt;
libusb_device *dev;
libusb_device **devs;
libusb_device_handle* handle = NULL;
cnt = libusb_get_device_list(NULL, &devs);
if (cnt < 0) {
printf("Failed libusb_get_device_list");
return(0);
}
while ((dev = devs[i++]) != NULL) {
struct libusb_device_descriptor desc;
int ret = libusb_get_device_descriptor(dev, &desc);
if (ret < 0) {
printf("Failed libusb_get_device_descriptor");
continue;
}
if(desc.idVendor == 0X238f && desc.idProduct == 1) {
int ret = libusb_open(dev, &handle);
if (ret < 0) {
printf("Failed libusb_open: %d\n\r",ret);
break;
}
#ifndef WIN32
libusb_detach_kernel_driver(handle, 0);
#endif
ret = libusb_claim_interface(handle,0);
if (ret < 0) {
libusb_close(handle);
handle=NULL;
break;
}
break;
}
}
libusb_free_device_list(devs, 1);
return(handle);
}
You can easily install the WinUSB driver or the other drivers which libusb supports (libusb-win32 and libusbK) through the use of Zadig, an application that was developed just to solve this problem.
See https://zadig.akeo.ie.
One thing to keep in mind, though, is that if you replace a Mass Storage driver or HID driver (which Windows installs automatically) with WinUSB, you will only be able to access your device through libusb and won't be able to access your device as Mass Storage or HID until you uninstall the WinUSB driver.
Finally, if you have control of the firmware for your device, it is also possible to create devices that will automatically install the WinUSB driver on Vista or later, so that users don't have to go through a manual driver installation (this may require a connection to Windows Update for Windows 7 or earlier, but should work even without an internet connection for Windows 8 or later). See https://github.com/pbatard/libwdi/wiki/WCID-Devices.
[DISCLAIMER] I am the author of Zadig/libwi, the WCID wiki pages as well as a contributor to the libusb Windows backend.
It seems you need to install the winusb driver - libusb can get information about devices without this driver, but it cannot open them.
http://libusb.6.n5.nabble.com/LIBUSB-ERROR-NOT-SUPPORTED-td5617169.html:
On Wed, Apr 4, 2012 at 11:52 PM, Quân Phạm Minh <[hidden email]>
wrote:
although I never install winusb driver but I use libusb to get
information of my usb (kingston usb, and already
recognize by system)
Yes that is possible. But you can not open the device and do further
things. That is the confusing part for new users with regard to
libusb Windows backend, and similarly for Mac OS X as well. libusb
can get some basic information for device with a non-proper driver
(e.g.: USB mass storage device), but will not be able to open the
device without changing the driver to a supported one.
-- Xiaofan
I had this same issue and it was not solved by installing WinUSB drivers with Zadig.
Consistently I found that libusb_open() returns LIBUSB_ERROR_NOT_SUPPORTED if and only if I have a Logitech Unifying Receiver plugged into another USB port. This causes the pyusb libusb1 backend to raise an exception like "NotImplementedError: Operation not supported or unimplemented on this platform".
I have removed the Logitech receiver (so I am using a wired keyboard) and the problem is solved for me. I would love to know why or how the Logitech receiver can cause this error on another USB port, but I don't.
I had the same issue with Zadig not working. I fixed it my connection the device directly to my laptop not through a USB-C hub
I had the same issue. But to my surprize, ignoring the error and continuing the execution of the rest of the code, send the data as normal. So the device was supported and could communicate as normal. And for some reason, libUSB-1.0 thought it could not support the device.
My code example:
#include <libusb.h>
#include <stdio.h>
#include <unistd.h>
libusb_context* context = NULL;
int main(void)
{
int kernelDriverDetached = 0; /* Set to 1 if kernel driver detached*/
uint8_t buffer[64]; /* 64 byte transfer buffer */
int numBytes = 0; /* Actual bytes transferred. */
libusb_device_handle* handle = NULL;
int res = libusb_init(&context); //initialize the library using libusb_init
if (res != 0)
{
fprintf(stderr, "Error initialising libusb.\n");
}
/* Get the first device with the matching Vendor ID and Product ID.If
* intending to allow multiple demo boards to be connected at once,you
* will need to use libusb_get_device_list() instead. Refer to the libusb
* documentation for details. */
handle = libusb_open_device_with_vid_pid(0, 0x1cbe, 0x0003);
if (!handle)
{
fprintf(stderr, "Unable to open device.\n");
}
/* Check whether a kernel driver is attached to interface #0. If so, we'll
* need to detach it.*/
if (libusb_kernel_driver_active(handle, 0))
{
res = libusb_detach_kernel_driver(handle, 0);
if (res == 0)
{
kernelDriverDetached = 1;
}
else
{
fprintf(stderr, "Error detaching kernel driver. %s\n", libusb_error_name(res));
}
}
/* Claim interface #0. */
res = libusb_claim_interface(handle, 0);
if (res != 0)
{
fprintf(stderr, "Error claiming interface.\n");
}
memset(buffer, 0, 12);
buffer[0] = 0x55;
buffer[1] = 0xAA;
buffer[2] = 0x01;
buffer[3] = 0x00;
buffer[4] = 0x00;
buffer[5] = 0x00;
buffer[6] = 0x00;
buffer[7] = 0x00;
buffer[8] = 0x01;
buffer[9] = 0x00;
buffer[10] = 0x01;
buffer[11] = 0x01;
res = libusb_bulk_transfer(handle, 0x01, buffer, 12, &numBytes, 100);
if (res == 0)
{
printf("%d bytes transmitted successfully.\n", numBytes);
}
else
{
fprintf(stderr, "Error during send message: %s\n",libusb_error_name(res));
}
memset(buffer, 0, 12);
res = libusb_bulk_transfer(handle, 0x81, buffer, 12, &numBytes, 100);
if (res == 0)
{
printf("%d bytes receibed successfully.\n", numBytes);
}
else
{
fprintf(stderr, "Error during receibe response:%s\n",libusb_error_name(res));
}
/* Release interface #0. */
res = libusb_release_interface(handle, 0);
if (0 != res)
{
fprintf(stderr, "Error releasing interface.\n");
}
/* If we detached a kernel driver from interface #0 earlier, we'll now
* need to attach it again. */
if (kernelDriverDetached)
{
libusb_attach_kernel_driver(handle, 0);
}
/* Shutdown libusb. */
libusb_exit(0);
system("pause");
return 0;
}

Getting ARP table on iPhone/iPad

I am trying to get the ARP entries on my iPad like here.
When compiling the code to run on my iPad (so not the simulator) I am getting missing header error messages. You can resolve them by copying the header files into you project locally as mentioned in this post.
The problem lies in the line
sdl = (struct sockaddr_dl *)(sin + 1);
in this piece of code:
-(NSString*) ip2mac: (char*) ip
{
int expire_time, flags, export_only, doing_proxy, found_entry;
NSString *mAddr = nil;
u_long addr = inet_addr(ip);
int mib[6];
size_t needed;
char *host, *lim, *buf, *next;
struct rt_msghdr *rtm;
struct sockaddr_inarp *sin;
struct sockaddr_dl *sdl;
extern int h_errno;
struct hostent *hp;
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
mib[2] = 0;
mib[3] = AF_INET;
mib[4] = NET_RT_FLAGS;
mib[5] = RTF_LLINFO;
if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
err(1, "route-sysctl-estimate");
if ((buf = malloc(needed)) == NULL)
err(1, "malloc");
if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
err(1, "actual retrieval of routing table");
lim = buf + needed;
for (next = buf; next < lim; next += rtm->rtm_msglen) {
rtm = (struct rt_msghdr *)next;
sin = (struct sockaddr_inarp *)(rtm + 1);
sdl = (struct sockaddr_dl *)(sin + 1);
if (addr) {
if (addr != sin->sin_addr.s_addr)
continue;
found_entry = 1;
}
if (nflag == 0)
hp = gethostbyaddr((caddr_t)&(sin->sin_addr),
sizeof sin->sin_addr, AF_INET);
else
hp = 0;
if (hp)
host = hp->h_name;
else {
host = "?";
if (h_errno == TRY_AGAIN)
nflag = 1;
}
if (sdl->sdl_alen) {
u_char *cp = LLADDR(sdl);
mAddr = [NSString stringWithFormat:#"%x:%x:%x:%x:%x:%x", cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]];
// ether_print((u_char *)LLADDR(sdl));
}
else
mAddr = nil;
}
if (found_entry == 0) {
return nil;
} else {
return mAddr;
}
}
It gives the following error message:
Arithmetic on pointer to incomplete type 'struct sockaddr_inarp*'
When you compile the code for the iPad simulator everything runs fine.
Does anyone have an idea how to solve this?
A similar question (but not solved) is asked here.
After importing <netinet/if_ether.h>, you should edit it and change the line
#include <net/if_arp.h>
to
#include "if_arp.h"
and then import <net/if_arp.h> in your project as well. This should fix that error.
Anyway the headers you need to import to compile the code you posted are:
#include "if_ether.h"
#include "route.h"
#include "if_arp.h"
#include "if_dl.h"
Hope this helps =)
EDIT:
You need to "Add files to project", not simply importing it with #import or #include.
You can find above files from following links:
Files under "netinet"
Files under "net"
#include <net/ethernet.h>
instead of messing with the original headers. More info here: Implicit declaration of function 'ether_ntoa' is invalid in C99

Sandboxing turned on and is there a more Objective-C way to go about opening a com port?

Right now I got the following class and its not working. It fails at the open call. I think this is because of sandboxing but I'm not sure how to move forward. Also this seems ver C like, is there a better more Objective-C (IOKIT?) way to fo this?
The device itself is a USB serial port.
Error given:
Failed to open device: Operation not permitted
Current code:
#include <termios.h>
#import "Com.h"
#define BAUDCOUNT 17
speed_t baud_const[BAUDCOUNT] = { B50, B75, B110, B134, B150, B200,
B300, B600, B1200, B1800, B2400, B4800,
B9600, B19200, B38400, B57600, B115200 };
unsigned long baud_value[BAUDCOUNT] = { 50, 75, 110, 134, 150, 200,
300, 600, 1200, 1800, 2400, 4800,
9600, 19200, 38400, 57600, 115200 };
#interface Com()
#property (assign) int fd;
#property (assign) struct termios oldio;
#end
#implementation Com
#synthesize fd = _fd;
#synthesize oldio = _oldio;
- (id)init
{
self = [super init];
if (self)
{
self.fd = -1;
return self;
}
return nil;
}
- (BOOL)open:(NSString*)device withBaud:(int)baud
{
struct termios oldio;
struct termios newtio;
// Find the correct baud rate
int baudid = -1;
for(int i = 0; i < BAUDCOUNT; i++) {
if (baud_value[i] == baud) {
baudid = i;
break;
}
}
if(baudid == -1)
{
NSLog(#"Invlaid baud rate: %d", baud);
return NO;
}
// Open the device
self.fd = open([device UTF8String], O_RDWR | O_NOCTTY | O_NDELAY);
if (self.fd < 0)
{
NSLog(#"Failed to open device: %s", strerror(errno));
return NO;
}
// Save old settings
tcgetattr(self.fd, &oldio);
self.oldio = oldio;
// Init memory
memset(&newtio, 0x00 , sizeof(newtio));
cfmakeraw(&newtio);
// settings flags
newtio.c_cflag |= CS8;
newtio.c_cflag |= CLOCAL;
newtio.c_cflag |= CREAD;
newtio.c_iflag = IGNPAR | IGNBRK;
newtio.c_oflag = 0;
newtio.c_lflag = 0;
// Timeout in 100ms
newtio.c_cc[VTIME] = 0;
// read 1 character
newtio.c_cc[VMIN] = 0;
// Setting baudrate
cfsetispeed (&newtio, baud_const[baudid]);
cfsetospeed (&newtio, baud_const[baudid]);
// Flushing buffer
tcflush(self.fd, TCIOFLUSH);
// aplying new configuration
tcsetattr(self.fd, TCSANOW, &newtio);
return YES;
}
#end
Current Entitlements:
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.device.usb</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
There are a couple of Objective C frameworks for handling the serial port.
AMSerialPort
SerialConnect
Update: It looks to me like you might need the com.apple.security.device.serial entitlement. Despite the fact you are using a USB Serial adapter I believe the OS device drivers make all serial ports appear the same, i.e. not USB devices. I suspect the com.apple.security.device.usb entitlement that you do have doesn't apply to USB serial devices.
Update 2: I've just found this Open Radar from August last year which reports your problem. So it looks like the com.apple.security.device.serial entitlement doesn't work (or certainly didn't work back in August).
Update 3: If you do need to access the USB device directly (and assuming this works with the com.apple.security.device.usb entitlement) then you probably want to look at the IOSerialFamily source code which is available at http://opensource.apple.com/source/IOSerialFamily/IOSerialFamily-59/.
Source tarball: http://opensource.apple.com/tarballs/IOSerialFamily/IOSerialFamily-59.tar.gz
you are doing some kernel programming which may be what you are wanting to do, but if you can use the IOKit then I do recommend that. In short doing anything with the kernel + sandboxing I simply do not recommend as you have found out.
The IOKit is another type of animal and really isn't too bad. Here is an example with a quick snippet that will disable the system from sleeping. This demonstrates how you can use the IOKit and I do believe it does work with a Sandboxed app.
IOPMAssertionID assertionID;
IOReturn err = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, CFSTR("Add Reason Here"), &assertionID);
if ( err == kIOReturnSuccess ) {
// Do stuff here while system is unable to sleep
// Let the system resume ability to sleep
err = IOPMAssertionRelease(assertionID);
}
This documentation should also help: link
Note: "Important If your application is sandboxed, it must request the com.apple.security.device.usb entitlement in order to access USB devices."