//
// port.m
// AT
//
// Created by skysolf on 11-6-1.
// Copyright 2011 __HuaMobile__. All rights reserved.
//
@interface UIApplication(extended)
- (void) addStatusBarImageNamed:(NSString *) name;
- (void) removeStatusBarImageNamed:(NSString *) name;
@end
#import "port.h"
#include <stdio.h> /* Standard input/output definitions */
#include <string.h> /* String function definitions */
#include <unistd.h> /* UNIX standard function definitions */
#include <fcntl.h> /* File control definitions */
#include <errno.h> /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
#import <SpringBoard/SpringBoard.h>
#import <sys/sysctl.h>
#define APP_ID "com.huamobile.AppToBackground"
#define MACH_PORT_NAME APP_ID
#define APP_ID2 "com.huamobile.BackgroundToApp"
#define MACH_PORT_NAME2 APP_ID2
#define LOCAL_ECHO
#define kATCommandString "ATD112\r\n"
#ifdef LOCAL_ECHO
#define kOKResponseString "AT112\r\n"
#else
#define kOKResponseString "\r\nOK\r\n"
#endif
enum {
kNumRetries = 3
};
@implementation port
//extern double lastCallTime;
static struct termios gOriginalTTYAttrs;
int fileDescriptor;
int lines=0;
int fileDescriptor=-1;
static char *LogString(char *str);
char returnData[2048];
char keepReadingData[2048];
char lastMsg[2048];
NSObject *myself;
int isMyAppRun=0;
-(void) pop:(NSString *)msg
{
UIAlertView *alert=[[UIAlertView alloc]
initWithTitle:@"通知"
message:msg
delegate:nil
cancelButtonTitle:@"确定"
otherButtonTitles:nil];
[alert show];
[alert release];
}
-(void)readPort
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
char buffer[2048]; // Input buffer
char *bufPtr; // Current char in buffer
ssize_t numBytes; // Number of bytes read or written
//NSLog(@"reading...");
bufPtr = buffer;
do
{
numBytes = read(fileDescriptor, bufPtr, &buffer[sizeof(buffer)] - bufPtr - 1);
if (numBytes == -1)
{
NSLog(@"Error reading from modem - %s(%d).\n", strerror(errno), errno);
}
else if (numBytes > 0)
{
bufPtr += numBytes;
if (*(bufPtr - 1) == '\n' || *(bufPtr - 1) == '\r')
{
break;
}
}
else {
//NSLog(@"Nothing read.\n");
}
} while (numBytes > 0);
returnData[strlen(returnData)]='\0';
// NUL terminate the string and see if we got an OK response
*bufPtr = '\0';
//strcpy(returnData, "RING +CLIP:\"18602160930\",0,22");
strcpy(keepReadingData, buffer);
[pool release];
}
static int OpenSerialPort()
{
int handshake;
struct termios options;
// Open the serial port read/write, with no controlling terminal, and don't wait for a connection.
// The O_NONBLOCK flag also causes subsequent I/O on the device to be non-blocking.
// See open(2) ("man 2 open") for details.
//NSLog(@"准备打开串口dev/tty.iap\n");
fileDescriptor = open("/dev/tty.iap", O_RDWR | O_NOCTTY | O_NONBLOCK);//| O_NONBLOCK);
if (fileDescriptor == -1)
{
NSLog(@"Error opening serial port %s - %s(%d).\n","/dev/tty.iap", strerror(errno), errno);
goto error;
}
//NSLog(@"串口已经打开\n");
// Note that open() follows POSIX semantics: multiple open() calls to the same file will succeed
// unless the TIOCEXCL ioctl is issued. This will prevent additional opens except by root-owned
// processes.
// See tty(4) ("man 4 tty") and ioctl(2) ("man 2 ioctl") for details.
if (ioctl(fileDescriptor, TIOCEXCL) == -1)
{
NSLog(@"Error setting TIOCEXCL on %s - %s(%d).\n",
"/dev/tty.iap", strerror(errno), errno);
goto error;
}
// Now that the device is open, clear the O_NONBLOCK flag so subsequent I/O will block.
// See fcntl(2) ("man 2 fcntl") for details.
if (fcntl(fileDescriptor, F_SETFL, 0) == -1)
{
NSLog(@"Error clearing O_NONBLOCK %s - %s(%d).\n",
"/dev/tty.iap", strerror(errno), errno);
goto error;
}
// Get the current options and save them so we can restore the default settings later.
if (tcgetattr(fileDescriptor, &gOriginalTTYAttrs) == -1)
{
NSLog(@"Error getting tty attributes %s - %s(%d).\n",
"/dev/tty.iap", strerror(errno), errno);
goto error;
}
// The serial port attributes such as timeouts and baud rate are set by modifying the termios
// structure and then calling tcsetattr() to cause the changes to take effect. Note that the
// changes will not become effective without the tcsetattr() call.
// See tcsetattr(4) ("man 4 tcsetattr") for details.
options = gOriginalTTYAttrs;
//cfsetspeed(&options, B19200); // Set 19200 baud
// Print the current input and output baud rates.
// See tcsetattr(4) ("man 4 tcsetattr") for details.
//NSLog(@"Current input baud rate is %d\n", (int) cfgetispeed(&options));
//NSLog(@"Current output baud rate is %d\n", (int) cfgetospeed(&options));
// Set raw input (non-canonical) mode, with reads blocking until either a single character
// has been received or a one second timeout expires.
// See tcsetattr(4) ("man 4 tcsetattr") and termios(4) ("man 4 termios") for details.
cfmakeraw(&options);
options.c_cc[VMIN] = 0.1;
options.c_cc[VTIME] = 1;
// The baud rate, word length, and handshake options can be set as follows:
//NSLog(@"配置数据流比特率为115200\n");
cfsetspeed(&options, B115200); // Set 19200 baud
//NSLog(@"配置数据流选项\n");
options.c_cflag |= (CS8); // RTS flow control of input
options.c_cflag&= ~CRTSCTS;
options.c_cflag&= ~PARENB;
//NSLog(@"Input baud rate changed to %d\n", (int) cfgetispeed(&options));
//NSLog(@"Output baud rate changed to %d\n", (int) cfgetospeed(&options));
// Cause the new options to take effect immediately.
if (tcsetattr(fileDescriptor, TCSANOW, &options) == -1)
{
//NSLog(@"Error setting tty attributes %s - %s(%d).\n",
// "/dev/tty.iap", strerror(errno), errno);
goto error;
}
// Success
return fileDescriptor;
// Failure "/dev/tty.iap"
error:
if (fileDescriptor != -1)
{
close(fileDescriptor);
}
return -1;
}
void CloseSerialPort(int fileDescriptor)
{
// Block until all written output has been sent from the device.
// Note that this call is simply passed on to the serial device driver.
// See tcsendbreak(3) ("man 3 tcsendbreak") for details.
if (tcdrain(fileDescriptor) == -1)
{
NSLog(@"Error waiting for drain - %s(%d).\n",
strerror(errno), errno);
}
// Traditionally it is good practice to reset a serial port back to
// the state in which you found it. This is why the original termios struct
// was saved.
if (tcsetattr(fileDescriptor, TCSANOW, &gOriginalTTYAttrs) == -1)
{
NSLog(@"Error resetting tty attributes - %s(%d).\n",
strerror(errno), errno);
}
close(fileDescriptor);
}
static char *LogString(char *str)
{
static char buf[2048];
char *ptr = buf;
int i;
*ptr = '\0';
while (*str)
{
if (isprint(*str))
{
*ptr++ = *str++;
}
else {
switch(*str)
{
case ' ':
*ptr++ = *str;
break;
case 27:
*ptr++ = '\\';
*ptr++ = 'e';
break;
case '\t':
*ptr++ = '\\';
*ptr++ = 't';
break;
case '\n':
*ptr++ = '\\';
*ptr++ = 'n';
break;
case '\r':
*ptr++ = '\\';
*ptr++ = 'r';
break;
default:
i = *str;
(void)sprintf(ptr, "\\%03o", i);
ptr += 4;
break;
}
str++;
}
*ptr = '\0';
}
return buf;
}
-(void)writeAndReadPort:(NSString*)AtCmd
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
char buffer[2048]; // Input buffer
char *bufPtr; // Current char in buffer
ssize_t numBytes; // Number of bytes read or written
int tries; // Number of tries so far
Boolean result = false;
char cmd[255];
//cmd=[AtCmd UTF8String];
strcpy(cmd, [AtCmd UTF8String]);
strcat(cmd, "\r\n");
//NSLog(@"fileDescriptor=%d",fileDescriptor);
for (tries = 1; tries <= kNumRetries; tries++)
{
//NSLog(@"Try #%d\n", tries);
// Send an AT command to the modem
numBytes = write(fileDescriptor, cmd, strlen(cmd));
if (numBytes == -1)
{
printf("Error writing to modem - %s(%d).\n", strerror(errno), errno);
NSLog(@"Error writing to modem - %s(%d).\n", strerror(errno), errno);
continue;
}
else {
//printf("Wrote %ld bytes \"%s\"\n", numBytes, LogString(kATCommandString));
NSLog(@"Wrote %ld bytes \"%s\"\n", numBytes, LogString(cmd));
}
if (numBytes < strlen(cmd))
{
continue;
}
//printf("Looking for \"%s\"\n", LogString(cmd));
//NSLog(@"Looking for \"%s\"\n", LogString(cmd));
// Read characters into our buffer until we get a CR or LF
//read(fileDescriptor, returnData, 1024);
//printf("Read \"%s\"\n", LogString(returnData));
//NSLog(@"Read \"%s\"\n", LogString(returnData));
//if (strncmp(buffer, kOKResponseString, strlen(kOKResponseString)) == 0)
//{
// result = true;
// break;
//}\
bufPtr = buffer;
do
{
numBytes = read(fileDescriptor, bufPtr, &buffer[sizeof(buffer)] - bufPtr - 1);
if (numBytes == -1)
{
NSLog(@"Error reading from modem - %s(%d).\n", strerror(errno), errno);
}
else if (numBytes > 0)
{
bufPtr += numBytes;
if (*(bufPtr - 1) == '\n' || *(bufPtr - 1) == '\r')
{
break;
}
}
else {
NSLog(@"Nothing read.\n");
}
} while (numBytes > 0);
//strcpy(returnData, LogString(buffer));
returnData[strlen(returnData)]='\0';
// NUL terminate the string and see if we got an OK response
*bufPtr = '\0';
//NSLog(@"BUFFER IS %s , cmd is %s\n",LogString(buffer),LogString(cmd));
//returnData="AT\r\n";
//*returnData='test';
//strcpy(**returnData, "buffer");
//strcpy(test, test2);
//NSLog(@"test is %s",test);
//strcpy(test, buffer);
//NSLog(@"test is %s",test);
//*returnData= bufPtr;
strcpy(returnData, buffer);
//NSLog(@"returndate is %s",returnData);
//NSLog(@"returndate is %s",LogString(returnData));
if (strncmp(buffer, cmd, strlen(cmd)) == 0)
{
//NSLog(@"BUFFER is %s , cmd is %s\n",LogString(buffer),LogString(cmd));
result = true;
//NSString *tempstr=[[NSString alloc]initWithFormat:@"%s",LogString(buffer)];
//strcpy(*returnData, LogString(buffer));
break;
}
else {
//strcpy(*returnData, "empty");
}
}
//returnData="NULL";
return result;
[pool release];
}
static void InitializeModem(NSString *AtCmd)
{
//NSArray *dataArray=[[NSArray alloc]initWithObjects:fileDescriptor,AtCmd,returnData,nil];
[NSThread detachNewThreadSelector:@selector(writeAndReadPort:) toTarget:myself withObject:AtCmd];
}
- (void)dealloc {
[super dealloc];
}
@end