Writing an "AT-Command" to a Modem

  • Hi Folks,

    what is the best way to send an "AT-Command" to a Modem?

    I found several ways on the Internet:

    1) SerialPort Sample of Apple

    // Now open the modem port we found, initialize the modem, then close it
        if (!bsdPath[0])
        {
            printf("No modem port found.\n");
            return EX_UNAVAILABLE;
        }

        fileDescriptor = OpenSerialPort(bsdPath);
        if (-1 == fileDescriptor)
        {
            return EX_IOERR;
        }

        if (InitializeModem(fileDescriptor))
        {
            printf("Modem initialized successfully.\n");
        }
        else {
            printf("Could not initialize modem.\n");
        }

    2) AMSerialTest

    NSString *sendString = [[inputTextField stringValue] stringByAppendingString:@"\r"];

    if(!port) {
      // open a new port if we don't already have one
      [self initPort];
    }

    if([port isOpen]) { // in case an error occured while opening the port
      [port writeString:sendString usingEncoding:NSUTF8StringEncoding error:NULL];
    }

    3) NSFileHandle

    myPath = modempath;
      writeFile = [NSFileHandle fileHandleForUpdatingAtPath];
      [writeFile writeData:myPath];

    It looks like, that the 3rd one would be the easiest way - but where shall I put the "at-commands" there?

    Thanks for your hints and tipps...

    BR

    Stefan
  • Hi Stefan,

    there's something wrong in your third choice.
    this should be something like that:

    NSData *yourData;
    NSString *yourPath = ...;

    NSFileHandle *fileHandle = [ NSFileHandle
    fileHandleForUpdatingAtPath: yourPath ];

    ... fill/create a valid NSData instance ...

    [ fileHandle writeData: yourData ];

    ...

    [ fileHandle closeFile ];

    Regards

    On Oct 23, 2007, at 9:11 AM, Stefan Lehrner wrote:

    > Hi Folks,
    >
    > what is the best way to send an "AT-Command" to a Modem?
    >
    > I found several ways on the Internet:
    >
    > 1) SerialPort Sample of Apple
    >
    > // Now open the modem port we found, initialize the modem, then
    > close it
    > if (!bsdPath[0])
    > {
    > printf("No modem port found.\n");
    > return EX_UNAVAILABLE;
    > }
    >
    > fileDescriptor = OpenSerialPort(bsdPath);
    > if (-1 == fileDescriptor)
    > {
    > return EX_IOERR;
    > }
    >
    > if (InitializeModem(fileDescriptor))
    > {
    > printf("Modem initialized successfully.\n");
    > }
    > else {
    > printf("Could not initialize modem.\n");
    > }
    >
    > 2) AMSerialTest
    >
    > NSString *sendString = [[inputTextField stringValue]
    > stringByAppendingString:@"\r"];
    >
    > if(!port) {
    > // open a new port if we don't already have one
    > [self initPort];
    > }
    >
    > if([port isOpen]) { // in case an error occured while opening the
    > port
    > [port writeString:sendString usingEncoding:NSUTF8StringEncoding
    > error:NULL];
    > }
    >
    > 3) NSFileHandle
    >
    > myPath = modempath;
    > writeFile = [NSFileHandle fileHandleForUpdatingAtPath];
    > [writeFile writeData:myPath];
    >
    > It looks like, that the 3rd one would be the easiest way - but
    > where shall I put the "at-commands" there?
    >
    > Thanks for your hints and tipps...
    >
    > BR
    >
    > Stefan
  • Hi Half Activist,

    thanks for your help! So you would suggest me, to use the 3rd choice?

    Thanks again for your help!

    Stefan

    Half Activist wrote:

    Hi Stefan,

    there's something wrong in your third choice.
    this should be something like that:

    NSData *yourData;
    NSString *yourPath = ...;

    NSFileHandle *fileHandle = [ NSFileHandle
    fileHandleForUpdatingAtPath: yourPath ];

    ... fill/create a valid NSData instance ...

    [ fileHandle writeData: yourData ];

    ...

    [ fileHandle closeFile ];

    Regards
  • Stefan,

    I never wrote to a serial port (except a very long time ago in BASIC),
    but actually I'd do everything with POSIX file descriptor based IO
    functions:
    open, read, write essentially.
    Because I suppose you'll come across buffer problems with other
    methods and you'd run into data you write but never comes out to the
    serial port, and do quite a lot of flushing.

    This would be something like:

    NSData *yourData;
    NSString *yourPath = ...;

    int fd = open( [ yourPath UTF8String ], O_WRONLY, S_IRUSR );
    if( fd == -1 ){
    ... something wrong happened ... check for errno
    }

    ... fill/create a valid NSData instance ...

    write( fd, [ yourData bytes ], [ yourData length ] );

    ...

    close( fd );

    Regards.

    On Oct 23, 2007, at 9:45 AM, Stefan Lehrner wrote:

    > Hi Half Activist,
    >
    > thanks for your help! So you would suggest me, to use the 3rd choice?
    >
    > Thanks again for your help!
    >
    > Stefan
    >
    > On Tuesday, October 23, 2007, at 12:36AM, "Half Activist"
    > <halfactivist...> wrote:
    >> Hi Stefan,
    >>
    >> there's something wrong in your third choice.
    >> this should be something like that:
    >>
    >> NSData *yourData;
    >> NSString *yourPath = ...;
    >>
    >> NSFileHandle *fileHandle = [ NSFileHandle
    >> fileHandleForUpdatingAtPath: yourPath ];
    >>
    >> ... fill/create a valid NSData instance ...
    >>
    >> [ fileHandle writeData: yourData ];
    >>
    >> ...
    >>
    >> [ fileHandle closeFile ];
    >>
    >> Regards
    >>
    >>
    >> On Oct 23, 2007, at 9:11 AM, Stefan Lehrner wrote:
    >>
    >>> Hi Folks,
    >>>
    >>> what is the best way to send an "AT-Command" to a Modem?
    >>>
    >>> I found several ways on the Internet:
    >>>
    >>> 1) SerialPort Sample of Apple
    >>>
    >>> // Now open the modem port we found, initialize the modem, then
    >>> close it
    >>> if (!bsdPath[0])
    >>> {
    >>> printf("No modem port found.\n");
    >>> return EX_UNAVAILABLE;
    >>> }
    >>>
    >>> fileDescriptor = OpenSerialPort(bsdPath);
    >>> if (-1 == fileDescriptor)
    >>> {
    >>> return EX_IOERR;
    >>> }
    >>>
    >>> if (InitializeModem(fileDescriptor))
    >>> {
    >>> printf("Modem initialized successfully.\n");
    >>> }
    >>> else {
    >>> printf("Could not initialize modem.\n");
    >>> }
    >>>
    >>> 2) AMSerialTest
    >>>
    >>> NSString *sendString = [[inputTextField stringValue]
    >>> stringByAppendingString:@"\r"];
    >>>
    >>> if(!port) {
    >>> // open a new port if we don't already have one
    >>> [self initPort];
    >>> }
    >>>
    >>> if([port isOpen]) { // in case an error occured while opening the
    >>> port
    >>> [port writeString:sendString usingEncoding:NSUTF8StringEncoding
    >>> error:NULL];
    >>> }
    >>>
    >>> 3) NSFileHandle
    >>>
    >>> myPath = modempath;
    >>> writeFile = [NSFileHandle fileHandleForUpdatingAtPath];
    >>> [writeFile writeData:myPath];
    >>>
    >>> It looks like, that the 3rd one would be the easiest way - but
    >>> where shall I put the "at-commands" there?
    >>>
    >>> Thanks for your hints and tipps...
    >>>
    >>> BR
    >>>
    >>> Stefan
    >>
    >>
    >>
  • Hi HalfActivist,

    thanks - that sounds plausible!

    thanks  a lot for your help!

    Stefan

    On Tuesday, October 23, 2007, at 01:14AM, "Half Activist" <halfactivist...> wrote:
    > Stefan,
    >
    > I never wrote to a serial port (except a very long time ago in BASIC),
    > but actually I'd do everything with POSIX file descriptor based IO
    > functions:
    > open, read, write essentially.
    > Because I suppose you'll come across buffer problems with other
    > methods and you'd run into data you write but never comes out to the
    > serial port, and do quite a lot of flushing.
    >
    > This would be something like:
    >
    > NSData *yourData;
    > NSString *yourPath = ...;
    >
    > int fd = open( [ yourPath UTF8String ], O_WRONLY, S_IRUSR );
    > if( fd == -1 ){
    > ... something wrong happened ... check for errno
    > }
    >
    > ... fill/create a valid NSData instance ...
    >
    > write( fd, [ yourData bytes ], [ yourData length ] );
    >
    > ...
    >
    > close( fd );
    >
    > Regards.
    >
    >
    >
    > On Oct 23, 2007, at 9:45 AM, Stefan Lehrner wrote:
    >
    >> Hi Half Activist,
    >>
    >> thanks for your help! So you would suggest me, to use the 3rd choice?
    >>
    >> Thanks again for your help!
    >>
    >> Stefan
    >>
    >> On Tuesday, October 23, 2007, at 12:36AM, "Half Activist"
    >> <halfactivist...> wrote:
    >>> Hi Stefan,
    >>>
    >>> there's something wrong in your third choice.
    >>> this should be something like that:
    >>>
    >>> NSData *yourData;
    >>> NSString *yourPath = ...;
    >>>
    >>> NSFileHandle *fileHandle = [ NSFileHandle
    >>> fileHandleForUpdatingAtPath: yourPath ];
    >>>
    >>> ... fill/create a valid NSData instance ...
    >>>
    >>> [ fileHandle writeData: yourData ];
    >>>
    >>> ...
    >>>
    >>> [ fileHandle closeFile ];
    >>>
    >>> Regards
    >>>
    >>>
    >>> On Oct 23, 2007, at 9:11 AM, Stefan Lehrner wrote:
    >>>
    >>>> Hi Folks,
    >>>>
    >>>> what is the best way to send an "AT-Command" to a Modem?
    >>>>
    >>>> I found several ways on the Internet:
    >>>>
    >>>> 1) SerialPort Sample of Apple
    >>>>
    >>>> // Now open the modem port we found, initialize the modem, then
    >>>> close it
    >>>> if (!bsdPath[0])
    >>>> {
    >>>> printf("No modem port found.\n");
    >>>> return EX_UNAVAILABLE;
    >>>> }
    >>>>
    >>>> fileDescriptor = OpenSerialPort(bsdPath);
    >>>> if (-1 == fileDescriptor)
    >>>> {
    >>>> return EX_IOERR;
    >>>> }
    >>>>
    >>>> if (InitializeModem(fileDescriptor))
    >>>> {
    >>>> printf("Modem initialized successfully.\n");
    >>>> }
    >>>> else {
    >>>> printf("Could not initialize modem.\n");
    >>>> }
    >>>>
    >>>> 2) AMSerialTest
    >>>>
    >>>> NSString *sendString = [[inputTextField stringValue]
    >>>> stringByAppendingString:@"\r"];
    >>>>
    >>>> if(!port) {
    >>>> // open a new port if we don't already have one
    >>>> [self initPort];
    >>>> }
    >>>>
    >>>> if([port isOpen]) { // in case an error occured while opening the
    >>>> port
    >>>> [port writeString:sendString usingEncoding:NSUTF8StringEncoding
    >>>> error:NULL];
    >>>> }
    >>>>
    >>>> 3) NSFileHandle
    >>>>
    >>>> myPath = modempath;
    >>>> writeFile = [NSFileHandle fileHandleForUpdatingAtPath];
    >>>> [writeFile writeData:myPath];
    >>>>
    >>>> It looks like, that the 3rd one would be the easiest way - but
    >>>> where shall I put the "at-commands" there?
    >>>>
    >>>> Thanks for your hints and tipps...
    >>>>
    >>>> BR
    >>>>
    >>>> Stefan
    >>>
    >>>
    >>>
    >
    >
    >
  • On 23 Oct 2007, at 09:20, Stefan Lehrner wrote:

    > Hi HalfActivist,
    >
    > thanks - that sounds plausible!

    In addition to using the normal BSD APIs (open, close, read, write et
    al.), or their Cocoa equivalents, you'll probably need to configure
    the serial port (or, for "internal" modems, the pretend serial port)
    to the settings you need.

    To do that, you'll probably want to use the POSIX terminal functions
    (defined in the header <termios.h>).  See

      <http://www.opengroup.org/onlinepubs/009695399/basedefs/
    xbd_chap11.html
    >
      <http://www.opengroup.org/onlinepubs/009695399/basedefs/
    termios.h.html
    >

    for more information.

    I also recall seeing that someone had written some Cocoa classes to
    help with serial ports; you can find them here:

      <http://www.harmless.de/cocoa.php>

    Kind regards,

    Alastair.

    --
    http://alastairs-place.net
  • Am 23.10.2007 um 09:11 Uhr schrieb Stefan Lehrner:

    > what is the best way to send an "AT-Command" to a Modem?

    There is no "best way". It depends on what you need.

    Also, all “three ways“ you listed are very similar. AMSerialPort ist
    based on Apple's SerialPort sample. It just wraps the necessary
    procedures in Cocoa classes. And you can, of course, use the file
    handle returned from AMSerialPort -open to directly write to the
    serial device.

    Am 23.10.2007 um 10:14 Uhr schrieb Half Activist:

    > Because I suppose you'll come across buffer problems with other
    > methods and you'd run into data you write but never comes out to
    > the serial port, and do quite a lot of flushing.

    Why do you think so?

    > write( fd, [ yourData bytes ], [ yourData length ] );

    Well, that's what AMSerialPort does:

    > - (BOOL)writeData:(NSData *)data error:(NSError **)error
    > {
    > BOOL result = NO;
    >
    > const char *dataBytes = [data bytes];
    > unsigned dataLen = [data length];
    > ssize_t bytesWritten = 0;
    > int errorCode = kAMSerialErrorNone;
    > if (dataBytes && (dataLen > 0)) {
    > bytesWritten = write(fileDescriptor, dataBytes, dataLen);

    As I said: These “different ways“ are actually quite similar.

    Andreas
previous month october 2007 next month
MTWTFSS
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
Go to today