Fbus 3310 Nokia

KOCT9I
Offline
Зарегистрирован: 20.03.2015

Помогите подключить терминал и отправить смс по Fbus  c помощью библиотеки.

Интерестная статья с устройством которое мониторит входное напряжение при потери переключаеться на крону и отправляет смс.  http://lauters.fr/blog/arduino-power-failure-alarm/   проэкт на Github 

Доработаная  автором библитека 

/**************************************************************************

  Nokia 61xx SMS send/receive functions

  Version 1.0

  Justin Karneges
  infiniti@affinix.com
  June 2000

  Thanks goes to the gnokii team for figuring out the frame format, among
  many other things!  These guys did all the hard work.  Although this file
  was written from scratch, it was heavily based on their research.

  http://www.gnokii.org/

  Overview:

    This file contains a set of functions for sending and receiving SMS
    (short message service) text messages across a GSM network with a
    Nokia 61xx series phone.  I've only tested it with my phone (a 6190),
    however it should work fine with any GSM phone in the series.  It
    should also work with the 51xx series phones.

    These functions were meant to be as portable as possible (they contain
    no serial communications code), and to perform two simple things: send
    and receive SMS.  That's all.  If you want a full program to control
    all the aspects of the Nokia 61xx, then I suggest checking out gnokii.
    This code was meant to be small, so that it could be used in small
    devices/applications.


  To use:

    Setup the serial port and call n61_init().  Then use n61_smssend() and
    n61_smsrecv() to send/recv SMS messages.  Call n61_update() as often
    as possible (possibly by having a timer ISR call it) so that the driver
    stays in sync with the phone.  All incoming SMS messages are deleted
    from the phone's inbox (you want this).


  ------------------------------------------------------------------------
  Functions:

    +---------------------------------------------------------+
    |  void n61_init(int (*func)(int cmd, unsigned char c));  |
    +---------------------------------------------------------+

      Before calling this function, do everything necessary to have the
      serial port ready.  The port MUST be set as follows:

        Baud rate: 115200
        Parity: None
        Bits: 8
        Stop bits: 1
        DTR: set
        RTS: cleared

      Since this driver does not contain any serial communications
      functionality, you must supply it.  An interrupt driven / threaded
      serial interface MUST be used.  This driver does not poll the port,
      and so it is completely dependant on a background serial driver
      keeping a queue of all incoming data (so that no data is lost).

      To give the serial functionality to this nokia driver, write a simple
      function to perform the four types of requests that this driver will
      need handled.  Pass this function as the argument to init:

        n61_init(myhandler);

      The myhandler() function should look like this:

        int myhandler(int cmd, unsigned char c)
        {
            if(cmd == 0) {
                serial_send(c);          // send c out the port
                return;
            }
            else if(cmd == 1)
                return serial_recv();    // return the next byte in queue
            else if(cmd == 2)
                return serial_isdata();  // return zero if queue is empty
            else if(cmd == 3)
                msleep(1);               // delay for 1 millisecond
        }

      0 means send "c" out the serial port.  1 means return a byte from the
      serial port.  2 means return true/false if there is data waiting.
      Simple enough!

      This driver also requires a millisecond resolution timer, which is
      what the last request is for.  Most platforms include some sort of
      millisecond (or less) delay function.  For MSVC++ there is Sleep(),
      Unix has usleep() and DOS has delay().  If you're not using such a
      platform, then you'll have to time it yourself.  The driver doesn't
      specify how many milliseconds to wait, your function should wait
      just one millisecond.  So just do Sleep(1), usleep(1000), delay(1),
      or whatever your homebrew method is.  Easy!

      Lastly, n61_init() also queries the phone for the SMSC number to be
      used when sending SMS.

      Whew!  If you got past n61_init(), then the rest is easy as cake.

    +--------------------------------------------+
    |  int n61_smssend(char *dest, char *msg);  |
    +--------------------------------------------+

      Sends "msg" to "dest".  Returns 1 if sent, 0 if not.


    +---------------------------------------------+
    |  int n61_smsrecv(char *source, char *msg);  |
    +---------------------------------------------+

      Copies a received message into "msg", stores the source phone number
      in "source" and returns 1.  Returns 0 if no messages are in the queue.
      "msg" will not be larger than 161 bytes (including null byte).
      "source" will not be larger than 17 bytes (including null byte).


    +-----------------------+
    |  int n61_smsqueue();  |
    +-----------------------+

      Returns the number of messages in the incoming queue.


    +---------------------+
    |  int n61_update();  |
    +---------------------+

      This must be called as often as possible.  If it's not called, then
      you won't be able to receive messages.  This might be something good
      to put in a timer interrupt if possible (yes, it's safe).


  That's all you need to know!

  ------------------------------------------------------------------------

  Nokia 6190 message format:

    1 byte = start byte (0x1e)
    1 byte = message destination
    1 byte = message source
    1 byte = message type
    1 byte = ???
    1 byte = message size

    X bytes = message data (X = message size)

    1 byte = filler byte (exists only if needed to make message size even)

    2 byte = result of all 16bit words XOR'ed together

**************************************************************************/

#include <string.h>
#include <stdlib.h>


#define NB_SMS_TRIES 1

#define NB6_HEADER_SIZE 6


#define N61MODE_SYNC  0
#define N61MODE_DEST  1
#define N61MODE_SOURCE  2
#define N61MODE_TYPE  3
#define N61MODE_UNKNOWN  4
#define N61MODE_SIZE  5
#define N61MODE_DATA  6

#define N61STATE_WAIT  0
#define N61STATE_PROC  1
#define N61STATE_GOOD  2
#define N61STATE_BAD  3

#define N61MAXSIZE  120

#define N61VALID_1H  0x0b
#define N61VALID_6H  0x47
#define N61VALID_24H  0xa7
#define N61VALID_72H  0xa9
#define N61VALID_1W  0xad
#define N61VALID_MAX  0xff

struct N61_MESSAGE
{
  int dest;
  int source;
  int type;
  int unknown;
  int size;
  unsigned char dat[256];
  int cs[2];
};

struct N61_MESSAGE n61_tmp, n61_buf;
int n61_seqnum = 0;
int n61_prevseq = 0;
int (*n61_serial)(int cmd, unsigned char c);
int n61_mode = 0;
int n61_atbyte = 0;
int n61_datp = 0;
int n61_readsize = 0;
int n61_readbase = 0;
int n61_state;
int n61_multiple;
char n61_smsc[32];
int n61_msgqueuesize;
// TODO
//char n61_msgqueue[4][161];
//char n61_msgqueue2[4][17];
int n61_ack, n61_gotmsg, n61_waittype;
int n61_blocked;


// ** translate table taken directly from gnokii **

unsigned char n61_transtable[] = {

  /* ETSI GSM 03.38, version 6.0.1, section 6.2.1; Default alphabet */
  /* Characters in hex position 10, [12 to 1a] and 24 are not present on
    latin1 charset, so we cannot reproduce on the screen, however they are
    greek symbol not present even on my Nokia */

  '@',  0xa3, '$',  0xa5, 0xe8, 0xe9, 0xf9, 0xec,
  0xf2, 0xc7, '\n', 0xd8, 0xf8, '\r', 0xc5, 0xe5,
  '?',  '_',  '?',  '?',  '?',  '?',  '?',  '?',
  '?',  '?',  '?',  '?',  0xc6, 0xe6, 0xdf, 0xc9,
  ' ',  '!',  '\"', '#',  0xa4,  '%',  '&',  '\'',
  '(',  ')',  '*',  '+',  ',',  '-',  '.',  '/',
  '0',  '1',  '2',  '3',  '4',  '5',  '6',  '7',
  '8',  '9',  ':',  ';',  '<',  '=',  '>',  '?',
  0xa1, 'A',  'B',  'C',  'D',  'E',  'F',  'G',
  'H',  'I',  'J',  'K',  'L',  'M',  'N',  'O',
  'P',  'Q',  'R',  'S',  'T',  'U',  'V',  'W',
  'X',  'Y',  'Z',  0xc4, 0xd6, 0xd1, 0xdc, 0xa7,
  0xbf, 'a',  'b',  'c',  'd',  'e',  'f',  'g',
  'h',  'i',  'j',  'k',  'l',  'm',  'n',  'o',
  'p',  'q',  'r',  's',  't',  'u',  'v',  'w',
  'x',  'y',  'z',  0xe4, 0xf6, 0xf1, 0xfc, 0xe0
};



// **** Functions            ****

void n61_init(int (*func)(int cmd, unsigned char c));  // initialize the driver
int n61_smssend(char *dest, char *msg);      // send SMS
int n61_smsrecv(char *dest, char *msg);      // recv SMS
int n61_smsqueue();          // check the recv queue
void n61_update();          // keep the driver in sync

// **** Functions - internal ****

void n61_block();            // protect during update
void n61_unblock();            // unprotect

void n61_update_main();            // main update
void n61_update_internal();          // internal version of
                //   n61_update()

void n61_serial_send(unsigned char c);        // send byte
unsigned char n61_serial_recv();        // recv byte
unsigned char n61_serial_isdata();        // check for serial data
void n61_serial_delay();          // wait 1 millisecond

int n61_nextseq();            // get next sequence number
int n61_sendframe(int type, int size, unsigned char *data);  // send frame
int n61_sendmsg(int type, int size, unsigned char *data);  // send message
void n61_sendack(int type, int seqnum);        // send acknowledgement

void n61_ackwait(int x);          // wait for ack
void n61_wait(int x);            // wait for a message

void n61_addchar(char *str, char c);        // strcat() but for chars
void n61_bcd(unsigned char *dest, char *s);        // encode SMSC number
void n61_bcd2(unsigned char *dest, char *s);        // encode phone number
char *n61_unbcd(unsigned char *dat);        // decode SMSC number
char *n61_unbcd2(unsigned char *dat);        // decode phone number

void n61_pack7(unsigned char *dest, char *s);        // pack when sending
char *n61_unpack7(unsigned char *dat, int len);      // unpack when received

unsigned char n61_gettrans(unsigned char c);      // translate char
void n61_addmsg(char *dest, char *msg);        // add a received SMS
                //   to the queue

void n61_procmsg(struct N61_MESSAGE *msg);      // process incoming message

void n61_getstatus();            // request phone status
void n61_getsmsc();            // request SMSC
void n61_delsms(int x);            // delete SMS message
int n61_smssendfull(char *smsc, char *dest, char *msg);    // send SMS via SMSC


// ** Code **
unsigned char n61_gettrans(unsigned char c)
{
  unsigned char n;

  if(c == '?')
    return 0x3f;

  for(n = 0; n < 128; ++n) {
    if(n61_transtable[n] == c)
      return n;
  }

  return 0x3f;
}

void n61_block()
{
  n61_blocked = 1;
}

void n61_unblock()
{
  n61_blocked = 0;
}

void n61_update()
{
  if(!n61_blocked) {
    n61_block();
    n61_update_main();
    n61_unblock();
  }
}

void n61_update_internal()
{
  n61_update_main();
}

void n61_serial_send(unsigned char c)
{
  n61_serial(0, c);
}

unsigned char n61_serial_recv()
{
  return n61_serial(1, 0);
}

unsigned char n61_serial_isdata()
{
  return n61_serial(2, 0);
}

void n61_serial_delay()
{
  n61_serial(3, 0);
}

void n61_ackwait(int x)
{
  int n;

  for(n = 0; n < x; ++n) {
    n61_update_internal();
    n61_serial_delay();
    if(n61_ack)
      return;
  }
}

void n61_wait(int x)
{
  int n;

  for(n = 0; n < x; ++n) {
    n61_update_internal();
    n61_serial_delay();
    if(n61_gotmsg)
      return;
  }
}

void n61_addmsg(char *dest, char *msg)
{
  // TODO
  /*
  int n;

  // clip args for safety. in theory not necessary
  msg[160] = 0;
  dest[16] = 0;

  // add the message
  n = n61_msgqueuesize;
  strcpy(n61_msgqueue[n], msg);
  strcpy(n61_msgqueue2[n], dest);
  ++n61_msgqueuesize;
  */
}

int n61_smsrecv(char *dest, char *msg)
{
  // TODO
  /*
  int n;

  n61_block();
  n = n61_msgqueuesize;

  if(n <= 0) {
    n61_unblock();
    return 0;
  }

  strcpy(msg, n61_msgqueue[0]);
  strcpy(dest, n61_msgqueue2[0]);
  --n61_msgqueuesize;

  for(n = 0; n < n61_msgqueuesize; ++n) {
    strcpy(n61_msgqueue[n], n61_msgqueue[n+1]);
    strcpy(n61_msgqueue2[n], n61_msgqueue2[n+1]);
  }

  n61_unblock();

  return 1;
  */
}

int n61_smsqueue()
{
  return n61_msgqueuesize;
}

int n61_sendframe(int type, int size, unsigned char *data)
{
  //unsigned char buf[256];

  unsigned char header[NB6_HEADER_SIZE];

  int at =0, n, check, check1;


  // build header
  header[at++] = 0x1e;    // message startbyte
  header[at++] = 0x00;    // dest: phone
  header[at++] = 0x0c;    // source: PC
  header[at++] = type;
  header[at++] = 0x00;
  header[at++] = size;

  // calculate checksums
  check = 0;
  check1 = 0;

  at = 0;

  //send header
  for(n = 0; n < NB6_HEADER_SIZE; ++n) {
    n61_serial_send(header[n]);
    if( at % 2 == 0)
        check ^= header[n];
    else
        check1 ^= header[n];
    at++;
  }

  //send data
  for(n = 0; n < size; ++n) {
    n61_serial_send(data[n]);
    if( at % 2 == 0)
        check ^= data[n];
    else
        check1 ^= data[n];
    at++;
  }

  // send data filler if needed
  if(size % 2) {
    n61_serial_send(0x00);
    if( at % 2 == 0)
        check ^= 0x00;
    else
        check1 ^= 0x00;
    at++;
  }

  //send checksums
  n61_serial_send(check);
  at++;

  if( at % 2 == 0)
        check1 ^= check;

  n61_serial_send(check1);

  return 0;
}

int n61_nextseq()
{
  int n;

  n = n61_seqnum;
  n61_prevseq = n;

  ++n61_seqnum;
  n61_seqnum &= 7;

  return (n + 0x40);
}

int n61_sendmsg(int type, int size, unsigned char *data)
{
  //unsigned char buf[N61MAXSIZE + 2];
  unsigned char *buf;
  unsigned char num, lastsize;
  int n;
  int len;
  int msgSize = 0;
  num = (size + N61MAXSIZE - 1) / N61MAXSIZE;
  lastsize = size % N61MAXSIZE;

  for(n = 0; n < num;) {
    if(n + 1 == num)
      len = lastsize;
    else
      len = N61MAXSIZE;

    msgSize = len + 2;
    buf = (unsigned char*) malloc( msgSize * sizeof(char) );
    // get current chunk
    memcpy(buf, data + (n * N61MAXSIZE), len);


    buf[len] = num - n;
    buf[len+1] = n61_nextseq();
    if(n)
      buf[len+1] &= 7;

    n61_ack = 0;
    n61_sendframe(type, msgSize, buf);
    free(buf);

    n61_ackwait(1000);
    if(n61_ack)
      ++n;
  }
  return 0;
}

void n61_sendack(int type, int seqnum)
{
  unsigned char buf[2];

  buf[0] = type;
  buf[1] = seqnum;

  n61_sendframe(0x7f, 2, buf);
}

void n61_update_main()
{
  int n;
  unsigned char c;

  while(n61_serial_isdata()) {
    c = n61_serial_recv();

    // calculate the checksums
    n61_tmp.cs[n61_atbyte & 1] ^= c;

    // act on the byte
    switch(n61_mode) {
      case N61MODE_SYNC:
        if(c == 0x1e) {
          if(!n61_multiple) {
            memset(n61_tmp.dat, 0, 256);
            n61_atbyte = 0;
          }

          n61_tmp.cs[0] = 0x1e;
          n61_tmp.cs[1] = 0;

          n61_mode = N61MODE_DEST;
        }
        break;

      case N61MODE_DEST:
        n61_tmp.dest = c;
        n61_mode = N61MODE_SOURCE;
        break;

      case N61MODE_SOURCE:
        n61_tmp.source = c;
        n61_mode = N61MODE_TYPE;
        break;

      case N61MODE_TYPE:
        n61_tmp.type = c;
        n61_mode = N61MODE_UNKNOWN;
        break;

      case N61MODE_UNKNOWN:
        n61_tmp.unknown = c;
        n61_mode = N61MODE_SIZE;
        break;

      case N61MODE_SIZE:
        if(n61_multiple)
          n61_tmp.size += c - 2;
        else {
          n61_tmp.size = c;
          n61_datp = 0;
        }

        n61_mode = N61MODE_DATA;

        // calculate the number of bytes to read
        n = n61_tmp.size % 2;

        // message size + filler + checksums
        n61_readsize = n61_tmp.size + n + 2;

        break;

      case N61MODE_DATA:
        n = n61_datp++;
        if(n > 255) {
          n61_multiple = 0;
          n61_mode = N61MODE_SYNC;
          break;
        }

        n61_tmp.dat[n] = c;  // get the byte

        // are we done yet?
        if(n >= n61_readsize - 1) {
          // checksums ok?
          if(n61_tmp.cs[0] == n61_tmp.cs[1] && n61_tmp.cs[0] == 0) {
            // don't want to ACK on an ACK
            if(n61_tmp.type != 0x7f) {
              n61_sendack(n61_tmp.type, n61_tmp.dat[n61_tmp.size-1] & 0x0f);

              if(n61_tmp.size > 1 && n61_tmp.dat[n61_tmp.size-2] != 0x01) {
                n61_datp -= 4;  // back up past checksums and seqinfo
                ++n61_multiple;
              }
              else
                n61_multiple = 0;
            }

            if(!n61_multiple || n61_tmp.type == 0x7f) {
              n61_multiple = 0;
              memcpy(&n61_buf, &n61_tmp, sizeof(struct N61_MESSAGE));
              n61_procmsg(&n61_buf);
            }
          }
          else {
            // bad!
            n61_multiple = 0;
          }
          n61_mode = N61MODE_SYNC;
        }

      default:
        break;
    }

    ++n61_atbyte;
  }
}

void n61_getstatus()
{
  unsigned char buf[32];

  buf[0] = 0x00;
  buf[1] = 0x01;
  buf[2] = 0x00;

  buf[3] = 0x6d;

  n61_sendmsg(0x11, 4, buf);
}

void n61_getsmsc()
{
  unsigned char buf[32];

  buf[0] = 0x00;
  buf[1] = 0x01;
  buf[2] = 0x00;

  buf[3] = 0x33;
  buf[4] = 0x64;

  buf[5] = 0x01;

  // "do" or "try", there is no "do not"
  while(1) {
    // send off the request
    n61_state = N61STATE_PROC;

    n61_gotmsg = 0;
    n61_waittype = 2;

    n61_sendmsg(0x02, 6, buf);

    n61_wait(1000);
    if(n61_state == N61STATE_GOOD)
      break;
  }
}

void n61_delsms(int x)
{
  unsigned char buf[32];

  buf[0] = 0x00;
  buf[1] = 0x01;
  buf[2] = 0x00;

  buf[3] = 0x0a;
  buf[4] = 0x02;
  buf[5] = x;

  n61_sendmsg(0x14, 6, buf);
}

void n61_bcd(unsigned char *dest, char *s)
{
  int x, y, n, hi, lo;

  if(s[0] == '+') {
    dest[1] = 0x91;
    ++s;
  }
  else
    dest[1] = 0x81;

  x = 0;
  y = 2;
  while(s[x]) {
    lo = s[x++] - '0';
    if(s[x])
      hi = s[x++] - '0';
    else
      hi = 0x0f;

    n = (hi << 4) + lo;
    dest[y++] = n;
  }
  dest[0] = y - 1;
}

void n61_bcd2(unsigned char *dest, char *s)
{
  int x, y, n, hi, lo;

  if(s[0] == '+') {
    dest[1] = 0x91;
    ++s;
  }
  else
    dest[1] = 0x81;

  x = 0;
  y = 2;
  while(s[x]) {
    lo = s[x++] - '0';
    if(s[x])
      hi = s[x++] - '0';
    else
      hi = 0x0f;

    n = (hi << 4) + lo;
    dest[y++] = n;
  }
  dest[0] = strlen(s);
}

void n61_pack7(unsigned char *dest, char *s)
{
  int len;
  unsigned short *p, w;
  int at;
  int shift;
  int n, x;

  len = strlen(s);
  x = (len * 8) / 7;
  for(n = 0; n < x; ++n)
    dest[n] = 0;

  shift = 0;
  at = 0;
  w = 0;
  for(n = 0; n < len; ++n) {
    p = (unsigned short *)(dest + at);
    w = n61_gettrans(s[n]) & 0x7f;
    w <<= shift;

    *p |= w;

    shift += 7;
    if(shift >= 8) {
      shift &= 7;
      ++at;
    }
  }
}

int n61_smssendfull(char *smsc, char *dest, char *msg)
{
  //unsigned char buf[256];
  unsigned char *buf;
  int n, smsFrameSize, msgLen;

  msgLen = strlen(msg);
  smsFrameSize = 42 + msgLen;
  buf = (unsigned char *) malloc( smsFrameSize * sizeof(char));
  // standard frame data header
  buf[0] = 0x00;
  buf[1] = 0x01;
  buf[2] = 0x00;

  // send sms ?
  buf[3] = 0x01;
  buf[4] = 0x02;
  buf[5] = 0x00;

  // smsc
  memset(buf + 6, 0, 12);
  n61_bcd(buf + 6, smsc);

  // TPDU ?
  buf[18] = 0x11;

  // misc
  buf[19] = 0x00;  // message ref
  buf[20] = 0x00;  // protocol ID
  buf[21] = 0xf1;  // data coding scheme (non-flash)

  // message size
  buf[22] = msgLen;

  // destination
  memset(buf + 23, 0, 12);
  n61_bcd2(buf + 23, dest);

  // validity period
  buf[35] = N61VALID_24H;

  // filler
  buf[36] = 0;
  buf[37] = 0;
  buf[38] = 0;
  buf[39] = 0;
  buf[40] = 0;
  buf[41] = 0;

  // the string
  n61_pack7(buf + 42, msg);

  // try till we get some response
  for(n = 0; n< NB_SMS_TRIES; n++) {
    n61_state = N61STATE_PROC;

    n61_gotmsg = 0;
    n61_waittype = 1;
    n61_sendmsg(0x02, smsFrameSize, buf);

    n61_wait(5000);
    if(n61_state != N61STATE_PROC)
      break;
  }
  free(buf);
  if(n61_state == N61STATE_GOOD)
    return 1;

  return 0;
}

int n61_smssend(char *dest, char *msg)
{
  int n;

  n61_block();
  n = n61_smssendfull(n61_smsc, dest, msg);
  n61_unblock();

  return n;
}

void n61_addchar(char *str, char c)
{
  int n;

  n = strlen(str);
  str[n] = c;
  str[n+1] = 0;
}

char *n61_unbcd(unsigned char *dat)
{
  static char buf[32];
  int len;
  int n, x;

  buf[0] = 0;
  len = dat[0];

  if(dat[1] == 0x91) {
    n61_addchar(buf, '+');
  }

  for(n = 0; n < len-1; ++n) {
    x = dat[n+2] & 0x0f;
    if(x < 10)
      n61_addchar(buf, '0' + x);
    x = (dat[n+2] >> 4) & 0x0f;
    if(x < 10)
      n61_addchar(buf, '0' + x);
  }

  return buf;
}

char *n61_unbcd2(unsigned char *dat)
{
  static char buf[32];
  int len;
  int n, x;
  int at;

  buf[0] = 0;
  len = dat[0];

  if(dat[1] == 0x6f || dat[1] == 0x91) {
    n61_addchar(buf, '+');
  }

  at = 2;
  for(n = 0; n < len; ++n) {
    x = dat[at] & 0x0f;
    if(x < 10)
      n61_addchar(buf, '0' + x);
    ++n;
    if(!(n < len))
      break;
    x = (dat[at] >> 4) & 0x0f;
    if(x < 10)
      n61_addchar(buf, '0' + x);
    ++at;
  }

  return buf;
}

char *n61_unpack7(unsigned char *dat, int len)
{
  static char buf[256];
  unsigned short *p, w;
  unsigned char c;
  int n;
  int shift;
  int at;

  shift = 0;
  at = 0;
  buf[0] = 0;
  for(n = 0; n < len; ++n) {
    p = (unsigned short *)(dat + at);
    w = *p;
    w >>= shift;
    c = w & 0x7f;

    shift += 7;
    if(shift & 8) {
      shift &= 0x07;
      ++at;
    }

    n61_addchar(buf, n61_transtable[c]);
  }

  return buf;
}

void n61_procmsg(struct N61_MESSAGE *msg)
{
  int subtype;

  // check if this is a msg of interest
  subtype = 0;
  if(msg->type != 0x7f) {
    if(msg->type == 0x02) {
      if(msg->dat[3] == 0x02 || msg->dat[3] == 0x03)
        subtype = 1;
      if(msg->dat[3] == 0x10)
        subtype = 2;
      if(msg->dat[3] == 0x34)
        subtype = 3;
    }
    if(subtype == n61_waittype)
      n61_gotmsg = 1;
  }

  // act on it
  switch(msg->type) {
    // SMS
    case  0x02:
      if(msg->dat[3] == 0x02) {
        n61_state = N61STATE_GOOD;
      }
      if(msg->dat[3] == 0x03) {
        n61_state = N61STATE_BAD;
      }
      if(msg->dat[3] == 0x10) {
        n61_addmsg(n61_unbcd2(msg->dat + 23), n61_unpack7(msg->dat + 42, msg->dat[22]));

        // now delete the msg
        if(msg->dat[5])
          n61_delsms(msg->dat[5]);
      }

      // SMSC
      if(msg->dat[3] == 0x34) {
        n61_state = N61STATE_GOOD;
        strcpy(n61_smsc, n61_unbcd(msg->dat+21));
      }
      break;

    case  0x7f:
      if((msg->dat[1] & 7) == n61_prevseq)
        n61_ack = 1;
      break;

    default:
      break;
  }
}

void n61_init(int (*func)(int cmd, unsigned char c))
{

  n61_seqnum = 0;
  n61_serial = func;
  n61_blocked = 0;
  n61_msgqueuesize = 0;
  n61_multiple = 0;
  n61_readbase = 0;

  // getsmsc
  n61_getsmsc();
}

Программа для отправки сообщений из под linux 

/**
*	Mehdi Lauters
*
*	This program is designed to send an sms from a nokia through the FBUS protocol, through a serial port in a Linux computer or from a recorded input file
*	It used a modified version of the n61sms library which can be found at http://www.affinix.com/~justin/nokia/n61sms.c
*	Modification done are around memory managment to decrease the memory consumption in order to be used in an embedded system
*	such as an arduino (tested on UNO and MICRO)
*   Please find more information on http://lauters.fr/blog/?p=167
*
*	to compile this test code, please use 
*	gcc main.c -o main -lpthread
*
*/

 #include "n61sms.c"
//#define USE_FILES 1
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>

#ifndef USE_FILES
#include <termios.h>
#endif


#define MAX 1000
int fd = 0;
int logI, logO;
char buffer[MAX];
int readed = 0;
int written = 0;

#ifndef USE_FILES

int set_interface_attribs (int fd, int speed, int parity)
{
        struct termios tty;
        memset (&tty, 0, sizeof tty);
        if (tcgetattr (fd, &tty) != 0)
        {
                printf ("error %d from tcgetattr\n", errno);
                return -1;
        }

        cfsetospeed (&tty, speed);
        cfsetispeed (&tty, speed);

        tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;     // 8-bit chars
        // disable IGNBRK for mismatched speed tests; otherwise receive break
        // as \000 chars
        tty.c_iflag &= ~IGNBRK;         // ignore break signal
        tty.c_lflag = 0;                // no signaling chars, no echo,
                                        // no canonical processing
        tty.c_oflag = 0;                // no remapping, no delays
        tty.c_cc[VMIN]  = 0;            // read doesn't block
        tty.c_cc[VTIME] = 5;            // 0.5 seconds read timeout

        tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl

        tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
                                        // enable reading
        tty.c_cflag &= ~(PARENB | PARODD);      // shut off parity
        tty.c_cflag |= parity;
        tty.c_cflag &= ~CSTOPB;
        tty.c_cflag &= ~CRTSCTS;

        if (tcsetattr (fd, TCSANOW, &tty) != 0)
        {
                printf ("error %d from tcsetattr\n", errno);
                return -1;
        }
        return 0;
}

void set_blocking (int fd, int should_block)
{
        struct termios tty;
        memset (&tty, 0, sizeof tty);
        if (tcgetattr (fd, &tty) != 0)
        {
                printf("error %d from tggetattr\n", errno);
                return;
        }

        tty.c_cc[VMIN]  = should_block ? 1 : 0;
        tty.c_cc[VTIME] = 5;            // 0.5 seconds read timeout

        if (tcsetattr (fd, TCSANOW, &tty) != 0)
                printf("error %d setting term attributes\n", errno);
}


#endif



/**
*
*	Serial read handler (called within a new thread)
*
*/
int readStarted = 1;
void * readFunction( void* _param)
{
  while(1)
  {
    char c;
    int n = read (fd, &c, 1);  // read up to 100 characters if ready to read
    if( n != 0 )
    {
      if( readStarted == 0 )
      {
	buffer[written++] = c;
	printf("%x ", buffer[written-1]);
	write (logI, &(buffer[written-1]), 1);
	if(written > MAX)
	  written = 0;
      }
    }
  }
  return NULL;
}

/**
*   IO handler
*/
int myhandler(int cmd, unsigned char c)
        {
           if(cmd == 0) {
				int res = write (fd, &c, 1);
				write (logO, &c, 1);
				return 0;
			}
            else if(cmd == 1)
			{
				if(readed > MAX)
				{
					readed = 0;
				}
                return buffer[readed++];    // return the next byte in queue
			}
            else if(cmd == 2)
                return written > readed;  // return zero if queue is empty
            else if(cmd == 3)
                usleep(100);               // delay for 1 millisecond
        }




int main(void)
{
pthread_t readThread = -1;
logI = open("logI.dat", O_RDWR | O_CREAT);
logO = open("logO.dat", O_RDWR | O_CREAT);
char * filename;
#ifndef USE_FILES
  filename = "/dev/ttyACM0";
  sleep(2);
  fd = open (filename, O_RDWR | O_NOCTTY | O_SYNC);
  #else
  filename = "output.dat";
   fd = open(filename, O_RDWR | O_CREAT);
#endif
  if (fd < 0)
  {
    printf("error %d opening %s: %s\n", errno, filename, strerror (errno));
    return -1;
  }
printf("%s opened\n",filename);
  #ifndef USE_FILES
  set_interface_attribs (fd, B115200, 0);  // set speed to 115,200 bps, 8n1 (no parity)
  set_blocking (fd, 0);                // set no blocking
#endif
  int err;
   err = pthread_create(&readThread, NULL, &readFunction, NULL);
        if (err != 0)
            printf("\ncan't create thread :[%s]", strerror(err));
        else
            printf("\n Thread created successfully\n");

int i;

   
  for(i=0;i<5000;i++);
  readStarted = 0;

  // not required
  for(i=0;i<127;i++)
  {
    myhandler(0,'U');
  }
	// ugly active wait
	for(i=0;i<5000;i++);
	printf("fbus initialized\n");

	n61_init(myhandler);
	
	// ugly active wait
	for(i=0;i<5000;i++);
	
	printf("init Ok\n");
	
	int res;
	char num[12] = "33687762785";
	
	res = n61_smssend(num, "Hi I a m your first SMS");
    
	if(res == 1 )
      printf("message sent to %s\n", num);
    else
      printf("message maybe sent to %s\n", num);

    
while(1);
}

 

KOCT9I
Offline
Зарегистрирован: 20.03.2015

Нашел еще один пример, тут вобще ступор, если с Recipient SMS Number все понятно переворачиваем 0684 в 0х60, 0х48 и тдд, то с  как сфломировать SMS Center number вобще завис второй день, помогите у кого будет время, зарание благодарен!

Статья с описанием процесса : 

https://www.insidegadgets.com/2013/01/12/how-to-use-nokia-f-bus-to-send-an-sms-message/

Исходник, который пытаюсь запустить:  https://www.insidegadgets.com/wp-content/uploads/2013/01/fbus_send_sms.zip

koljan
Offline
Зарегистрирован: 24.01.2015




#include <Adafruit_GFX.h>    // Core graphics library
#include <SWTFT.h> // Hardware-specific library
#include <TouchScreen.h>
#include <OneWire.h>
#include <Time.h>
#include <Wire.h>
#include <DS1307RTC.h>
#include <DallasTemperature.h>



#define YP A1  // must be an analog pin, use "An" notation!
#define XM A2  // must be an analog pin, use "An" notation!
#define YM 7   // can be a digital pin
#define XP 6   // can be a digital pin
#define TS_MINX 930
#define TS_MINY 940
#define TS_MAXX 110
#define TS_MAXY 120

// For better pressure precision, we need to know the resistance
// between X+ and X- Use any multimeter to read it
// For the one we're using, its 300 ohms across the X plate
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 150);

// Assign human-readable names to some common 16-bit color values:
#define	BLACK   0x0000
#define	BLUE    0x001F
#define	RED     0xF800
#define	GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF


SWTFT tft;

#define GR tft.color565(205,205,193)//заливка
#define MINC tft.color565(233,9,10)//минус
#define MINCC tft.color565(241,222,218)//обводка знаков

#define BOXSIZE 40
#define PENRADIUS 3
int oldcolor, currentcolor;
int nado = 22;
int nado1;
boolean otchet = false;
unsigned char FBusFrame[200];
byte otvet[250];
byte otvet2[250];
boolean compoluchena = false;
unsigned char SeqNo = 0x60;
int kolsms;
int oldminut = 0;
long On_Time1 =0;
long Off_Time1 =0;
long On_Time2 =0;
long Off_Time2 =0;
long minut;
int tempC;
boolean blok = false;
unsigned long currentTime;
unsigned long loopTime;
unsigned long currentTime1;
unsigned long loopTime1;
unsigned long currentTime2;
unsigned long loopTime2;
unsigned long currentTime3;
unsigned long loopTime3;
unsigned long currentTime4;
unsigned long loopTime4;
int optPin = 11;
int sch = 0;
int oldtemp;
int oldtemp2;
int oldday;
boolean dblok = false;
boolean disableblok = false;
// удаляет только по номеру, перед удалением проверять кол-во смс и возможно читать их
byte msgdel2[] = {   // удаление (№18-00 №19-0B - подтверждение удаления)
0x1E, 0x00, 0x0C, 0x14, 0x00, 0x08, 0x00, 0x01, 0x00, 0x0A, 0x02, 0x02, 0x01, 0x60, 0x11, 0x75};
byte msgdel[] = {   // удаление (№18-00 №19-0B - подтверждение удаления)
0x1E, 0x00, 0x0C, 0x14, 0x00, 0x08, 0x00, 0x01, 0x00, 0x0A, 0x02, 0x01, 0x01, 0x60, 0x11, 0x76};
byte msgstat[] = {   // байт №27 - непрочитанные ,26-ой - кол-во смс(во всех папках)
0x1E, 0x00, 0x0C, 0x14, 0x00, 0x07, 0x00, 0x01, 0x00, 0x36, 0x64, 0x01, 0x60, 0x00, 0x16, 0x25}; 
byte msgr[] = { //чтение второй смс
0x1E, 0x00, 0x0C, 0x02, 0x00, 0x0A, 0x00, 0x01, 0x00, 0x07, 0x02, 0x01, 0x01, 0x64, 0x01, 0x60, 0x10, 0x0B};
byte msg[] = {
0x1E, 0x00, 0x0C, 0xD1, 0x00, 0x07, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x60, 0x00, 0x72, 0xD5};
// SMS Center number (your mobile phone provider should provide this)
unsigned char SMSC[] = {0x07, 0x91, 0x97, 0x20, 0x74, 0x00, 0x20, 0xF2, 0x00, 0x00, 0x00, 0x00};

// Recipient SMS Number. After the 0x81, you insert the phone number with the numbers flipped
// E.g to insert 0412345678+79193600309 you would write it as below, 0x40 becomes 04, 0x21 becomes 12, etc
unsigned char RecipientNo[] = {0x0B, 0x91, 0x97, 0x91, 0x63, 0x00, 0x03, 0xF9};
boolean bo = true;

#define ONE_WIRE_BUS 10
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress insideThermometer;
  

  
void setup(void) {
  Serial.begin(115200);
  delay(1000);
    setSyncProvider(RTC.get);
   if(timeStatus()!= timeSet)
   Serial.println("Unable to sync with the RTC");
   else
   Serial.println("RTC has set the system time");
   
  
//  Serial.println(F("Paint!"));
  
 // tft.reset();
  uint16_t identifier = tft.readID();
  Serial.print(F("LCD driver chip: "));
  Serial.println(identifier, HEX);
  tft.begin(identifier);
  


  
  tft.fillScreen(GR);
 // tft.fillRect(0, BOXSIZE, tft.width(), tft.height()-BOXSIZE, BLACK);
 // tft.fillRect(0, 0, BOXSIZE, BOXSIZE, RED);
 
 //**** рисуем минус
 tft.fillCircle(125, 275, 30, MINC);
 tft.drawCircle(125,275,30,tft.color565(195,186,187));
 tft.drawCircle(125,275,31,tft.color565(110,109,114));
 tft.drawCircle(125,275,32,tft.color565(206,206,206));
 tft.drawCircle(125,275,29,tft.color565(206,206,206));
 tft.fillRect(120,255,10,40,WHITE);
 tft.drawRect(120,255,10,40,tft.color565(206,130,132));
 tft.drawRect(120,255,11,41,tft.color565(189,14,19));
 // bmpDraw("minus.bmp", 90, 250);
 //**** рисуем плюс
 tft.fillCircle(125, 40, 30, tft.color565(77,243,9));
 tft.drawCircle(125,40,30,tft.color565(195,186,187));
 tft.drawCircle(125,40,31,tft.color565(110,109,114));
 tft.drawCircle(125,40,32,tft.color565(206,206,206));
 tft.drawCircle(125,40,29,tft.color565(206,206,206));
 tft.fillRect(120,23,10,34,WHITE);
 tft.fillRect(108,35,34,10,WHITE);
 // рисуем значек настройки
// tft.fillRect(200,0,40,60,tft.color565(195,21,230));
 
 // bmpDraw("plus.bmp", 90, 10);
 // tft.fillRect(80, 250, 80, 60, RED);//высота, лево-право, высота бокса, ширина бокса, цвет
 // tft.fillRect(80, 10, 80, 60, RED);
 
//  tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, YELLOW);
//  tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, GREEN);
//  tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, CYAN);
//  tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, BLUE);
//  tft.fillRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, MAGENTA);
  // tft.fillRect(BOXSIZE*6, 0, BOXSIZE, BOXSIZE, WHITE);
 
  
  tft.setRotation(3); // отображение первоначального значения temp
  tft.setCursor(90, 70);
  tft.setTextColor(RED);  tft.setTextSize(13);
  tft.println(nado);
  tft.setRotation(0);
  
  pinMode(13, OUTPUT);
  pinMode(optPin, OUTPUT);
  digitalWrite(optPin, LOW);
On_Time1=(22*60*60); //включение   (приводим к секундам)
Off_Time1=(22*60*60+20); //выключение  (приводим к секундам)
On_Time2=(6*60*60)-1; //включение   (приводим к секундам)
Off_Time2=(6*60*60+20)-1; //выключение  (приводим к секундам)
currentTime = millis();       // считываем время, прошедшее с момента запуска программы
currentTime1 = millis();
currentTime4 = millis();
loopTime = currentTime; 
loopTime1 = currentTime1; 
loopTime4 = currentTime4;
  sensors.begin(); 
if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0"); 
timed();
}
   
#define MINPRESSURE 10
#define MAXPRESSURE 1000

void(* resetFunc) (void) = 0; // ресет

void timed() // отображение времени
{
          tft.setRotation(3);
          tft.fillRect(90, 200, 150, 40, GR);
          tft.setCursor(90, 200);
          tft.setTextColor(BLACK);  tft.setTextSize(5);
          if (hour()>9){
            tft.print(hour());
          }
          else {
            tft.print("0");
            tft.print(hour());
          }
          tft.print(":");
          if (minute() > 9){
            tft.print(minute());
          }
          else{
            tft.print("0");
            tft.print(minute());
          }
          oldminut = minute();
          //Serial.println(oldminut);
          if (oldday != day()){
            tft.fillRect(70, 10, 180, 30, GR);
            tft.setTextColor(BLACK);  tft.setTextSize(2);
            tft.setCursor(70, 10);
            tft.print(day());
            tft.print(" ");
            tft.print(monthStr(month()));
            tft.print(" ");
            tft.print(year());
          }
          
          tft.setRotation(0);
          
}

void printnado(int xs){
                  tft.setRotation(3);
                tft.fillRect(145, 40, 40, 30, GR);
                tft.setCursor(145, 40);
                tft.setTextColor(BLUE);  tft.setTextSize(3);
                tft.print(xs);
                tft.setRotation(0);
}           
void loop()
{
//  if (dblok == false);{              
              if (millis() >= (currentTime + 5000))
              {
                blok = false;
              }
              else {
                blok = true;
                sch = sch + 1;
              }
            if (blok == false){
              if (sch != 0) {
                printnado(nado);
                sch = 0;
                  if (digitalRead(optPin) == HIGH)
                  {
                    if (nado < tempC){
                      digitalWrite(optPin, LOW); 
                      delay(100);                  // ждет секунду
                      tft.setRotation(3);
                      tft.fillRect(120, 170, 70, 30, GR);
                      tft.setRotation(0);
                      disableblok = false;
                      }
                    }
                }
              currentTime1 = millis();               //задержка 3сек опроса датчика
              if(currentTime1 >= (loopTime1 + 5000)){
                sensors.requestTemperatures(); 
                oldtemp2 = sensors.getTempC(insideThermometer);
                if (oldtemp2 != -127) tempC = oldtemp2;
            //    Serial.println(tempC);
                loopTime1 = currentTime1;
            //    Serial.print(oldtemp);
            //    Serial.print("-");
            //    Serial.println(tempC);
                  if (oldtemp != tempC){
                      tft.fillRect(70, 80, 100, 160, GR);
                      tft.setRotation(3);
                      tft.setCursor(90, 70);
                      tft.setTextColor(RED);  tft.setTextSize(13);
                      tft.println(tempC);
                      tft.setRotation(0);
                      oldtemp = tempC;
                      //Serial.println("ok");
                  }
              }
            }
            
              //digitalWrite(13, HIGH);
              // Recently Point was renamed TSPoint in the TouchScreen library
              // If you are using an older version of the library, use the
              // commented definition instead.
              // Point p = ts.getPoint();
              TSPoint p = ts.getPoint();
              //digitalWrite(13, LOW);
            
              // if sharing pins, you'll need to fix the directions of the touchscreen pins
              //pinMode(XP, OUTPUT);
              pinMode(XM, OUTPUT);
              pinMode(YP, OUTPUT);
              //pinMode(YM, OUTPUT);
            
              // we have some minimum pressure we consider 'valid'
              // pressure of 0 means no pressing!
            
              if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
                
                Serial.print("X = "); Serial.print(p.x);
                Serial.print("\tY = "); Serial.print(p.y);
                Serial.print("\tPressure = "); Serial.println(p.z);
                
            //    
            //    if (p.y > (TS_MINY-5)) {
            //      Serial.println("erase");
            //      // press the bottom of the screen to erase 
            //      tft.fillRect(0, BOXSIZE, tft.width(), tft.height()-BOXSIZE, BLACK);
            //    }
                // scale from 0->1023 to tft.width
                p.x = tft.width()-(map(p.x, TS_MINX, TS_MAXX, tft.width(), 0));
                p.y = tft.height()-(map(p.y, TS_MINY, TS_MAXY, tft.height(), 0));
                
                Serial.print("("); Serial.print(p.x);
                Serial.print(", "); Serial.print(p.y);
                Serial.println(")");
            
                if (p.y <310 && p.y >250) {         //минус
                    if (p.x < 150 && p.x > 80) {
                      currentTime = millis(); 
                      //tft.drawRect(80, 250, 80, 60, WHITE);
                      tft.fillRect(70, 80, 100, 160, GR);
                      tft.setRotation(3);
                      tft.setCursor(90, 70);
                      tft.setTextColor(RED);  tft.setTextSize(13);
                      nado = nado-1;
                      tft.println(nado);
                      oldtemp = nado;
                      tft.setRotation(0);
                      //tft.drawRect(80, 250, 80, 60, RED);
                      //Serial.println(nado);
                    }
                }
                 if (p.y <80 && p.y >30) {         //плюс
                    if (p.x < 150 && p.x > 80) {
                      currentTime = millis();
                      //tft.drawRect(80, 10, 80, 60, WHITE);
                      tft.fillRect(70, 80, 100, 160, GR);
                      tft.setRotation(3);
                      tft.setCursor(90, 70);
                      tft.setTextColor(RED);  tft.setTextSize(13);
                      nado = nado+1;
                      tft.println(nado);
                      tft.setRotation(0);
                      oldtemp = nado;
                      //Serial.println(nado);
                      //tft.drawRect(80, 10, 80, 60, RED);
                    }
                 }
//                  if (p.y <60 && p.y >0) {
//                    if (p.x < 240 && p.x > 200) {
//                      dblok = true;
//                      resetFunc();
//                    }
//                 }
              }    // конец проверки нажатия
                      
                    if (oldminut < minute() || oldminut == 59 && minute() == 0) { //отображение времени
                      timed();
                      oldminut = minute();
                      //Serial.println(oldminut);
                    }
                    
               minut = (hour()*60+minute())*60+second();                      // изменение нужной темп по времени
                  if (minut >= On_Time1 && minut < Off_Time1)
                  {
                    nado = 24;
                    sch = 1;
                   // blok = false;
                  }
                  if (minut >= On_Time2 && minut < Off_Time2)
                  {
                    nado = 22;
                    sch = 1;
                  }
            if (blok == false){      
              if (tempC < nado)
                {
                if (digitalRead(optPin) == LOW)
                {
                  digitalWrite(optPin, HIGH);  
                  delay(100);       // ждет секунду
                    tft.setRotation(3);
                    tft.fillRect(120, 170, 70, 30, GR);
                    tft.setCursor(120, 170);
                    tft.setTextColor(BLUE);  tft.setTextSize(3);
                    tft.println("FIRE");
                    tft.setRotation(0);    
                }
              }
              else
              {
                if (digitalRead(optPin) == HIGH)
                {
                                   //Serial.print("vhod v zaderzhku otkl pervoe");
                 //Serial.println(disableblok);
                  if (disableblok == false){
                    loopTime2 = millis();
                    disableblok = true;
                  }
                }
              }
            }
            if (disableblok == true){
              if (millis() > loopTime2 + 300000){
                  digitalWrite(optPin, LOW); 
                  delay(100);                  // ждет секунду
                    tft.setRotation(3);
                    tft.fillRect(120, 170, 70, 30, GR);
                    tft.setRotation(0);
                  disableblok = false;
              }
            }
      if(millis() >= (loopTime4 + 300000)){
                    tft.setRotation(3);
                    tft.setCursor(0, 230);
                    tft.setTextColor(BLACK);  tft.setTextSize(2);
                    tft.print("SMS");
                    tft.setRotation(0);
         int pho = phone();
         if (pho==0);
         else if (pho>0 && pho<=26){
           nado = pho;
           printnado(nado);
         }
         loopTime4 = millis();
                    tft.setRotation(3);
                    tft.fillRect(0, 230, 40, 10, GR);
                    tft.setRotation(0);
      }
      
      
  }

//  else {
//              tft.fillScreen(GR);
//              TSPoint p = ts.getPoint();
//
//              pinMode(XM, OUTPUT);
//              pinMode(YP, OUTPUT);
//              
//              if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
//                
//                Serial.print("X = "); Serial.print(p.x);
//                Serial.print("\tY = "); Serial.print(p.y);
//                Serial.print("\tPressure = "); Serial.println(p.z);
//                
//
//                // scale from 0->1023 to tft.width
//                p.x = tft.width()-(map(p.x, TS_MINX, TS_MAXX, tft.width(), 0));
//                p.y = tft.height()-(map(p.y, TS_MINY, TS_MAXY, tft.height(), 0));
//                
//                Serial.print("("); Serial.print(p.x);
//                Serial.print(", "); Serial.print(p.y);
//                Serial.println(")");
//            
//                if (p.y <310 && p.y >250) {         //минус
//                    if (p.x < 150 && p.x > 80) {
////                      currentTime = millis(); 
////                      //tft.drawRect(80, 250, 80, 60, WHITE);
////                      tft.fillRect(70, 80, 100, 160, GR);
////                      tft.setRotation(3);
////                      tft.setCursor(90, 70);
////                      tft.setTextColor(RED);  tft.setTextSize(13);
////                      nado = nado-1;
////                      tft.println(nado);
////                      oldtemp = nado;
////                      tft.setRotation(0);
////                      //tft.drawRect(80, 250, 80, 60, RED);
////                      //Serial.println(nado);
//                    }
//                }
//                 if (p.y <80 && p.y >30) {         //плюс
//                    if (p.x < 150 && p.x > 80) {
////                      currentTime = millis();
////                      //tft.drawRect(80, 10, 80, 60, WHITE);
////                      tft.fillRect(70, 80, 100, 160, GR);
////                      tft.setRotation(3);
////                      tft.setCursor(90, 70);
////                      tft.setTextColor(RED);  tft.setTextSize(13);
////                      nado = nado+1;
////                      tft.println(nado);
////                      tft.setRotation(0);
////                      oldtemp = nado;
////                      //Serial.println(nado);
////                      //tft.drawRect(80, 10, 80, 60, RED);
//                    }
//                 }
//                  if (p.y <60 && p.y >0) {
//                    if (p.x < 240 && p.x > 200) {
////                      dblok = true;
////                      resetFunc();
//                    }
//                 }
//              }    // конец проверки нажатия
//}

int comanda(byte b1,byte b2){ //команда из смс
  int result;
  if (b1 == 0x35) result=5;
  else if (b1==0x3F) result=1;
  else if (b1==0x36) result=6;
  else if (b1==0x37) result=7;
  else if (b1==0x38) result=8;
  else if (b1==0x39) result=9;
  else if (b1==0x31 && b2==0x18) result=10;
  else if (b1==0xB1 && b2==0x18) result=11;
  else if (b1==0x31 && b2==0x19) result=12;
  else if (b1==0xB1 && b2==0x19) result=13;
  else if (b1==0x31 && b2==0x1A) result=14;
  else if (b1==0xB1 && b2==0x1A) result=15;
  else if (b1==0x31 && b2==0x1B) result=16;
  else if (b1==0xB1 && b2==0x1B) result=17;
  else if (b1==0x31 && b2==0x1C) result=18;
  else if (b1==0xB1 && b2==0x1C) result=19;
  else if (b1==0x32 && b2==0x18) result=20;
  else if (b1==0xB2 && b2==0x18) result=21;
  else if (b1==0x32 && b2==0x19) result=22;
  else if (b1==0xB2 && b2==0x19) result=23;
  else if (b1==0x32 && b2==0x1A) result=24;
  else if (b1==0xB2 && b2==0x1A) result=25;
  else if (b1==0x32 && b2==0x1B) result=26;
  else result = 0;
  return result;
}
byte seq(){                  //получение SeqNo
  byte result;
  memset(&otvet2[0], 0, sizeof(otvet2));
    for (int x = 0; x < 128; x++) {
    Serial.write("U");
  } 
  Serial.println ("");
  
      for (int x = 0; x < (sizeof(msg) / sizeof(byte)); x++) {
      Serial.write(msg[x]);
      }
      Serial.println ("");
      currentTime3 = millis();
          
          int r = 0;
                                  // получение ответа
          while (1) {
            //loopTime3 = millis();
          while (Serial.available() > 0) {
             int incomingByte = Serial.read();
             otvet2[r] = incomingByte;
             r = r++;
            //      Serial.print(incomingByte, HEX);
            // Serial.print(" ");
             if (millis() >= (currentTime3 + 7000)){
               break;
             }
           }
                if (millis() >= (currentTime3 + 7000)){
               break;
             }
          }
          if (otvet2[40]==40) result = 0x41;
          else if (otvet2[40]==41) result = 0x42;
          else if (otvet2[40]==42) result = 0x43;
          else if (otvet2[40]==43) result = 0x44;
          else if (otvet2[40]==44) result = 0x45;
          else if (otvet2[40]==45) result = 0x46;
          else if (otvet2[40]==46) result = 0x47;
          else if (otvet2[40]==47) result = 0x40;
     
   return result;
}
void u()            //инициализация
{
    for (int z = 0; z < 128; z++) {
    Serial.write(0x55);
  }
  Serial.println("");
}
void readserial()
{
  currentTime3 = millis();
  int i = 0;
  while (1) {

  while (Serial.available() > 0) {
  
     int incomingByte = Serial.read();
     otvet[i] = incomingByte;
     i = i++;
          Serial.print(incomingByte, HEX);
         Serial.print(" ");

   }
        if (millis() >= (currentTime3 + 5000)){
       break;
     }
  }
}

void msgread(int ksms){
      int chotvet = 0;
      if (ksms == 1) msgr[11]=0x01; 
      else if (ksms==2) msgr[11]=0x02; 
      else if (ksms==3) msgr[11]=0x03; 
      else if (ksms==4) msgr[11]=0x04; 
      else if (ksms==5) msgr[11]=0x05; 
      else if (ksms==6) msgr[11]=0x06; 
      else if (ksms==7) msgr[11]=0x07; 
      else if (ksms==8) msgr[11]=0x08; 
      else if (ksms==9) msgr[11]=0x09; 
      else if (ksms==10) msgr[11]=0x0A; 
      else if (ksms==11) msgr[11]=0x0B;
      else if (ksms==12) msgr[11]=0x0C;
      else if (ksms==13) msgr[11]=0x0D;
      unsigned char evenChSum;
        for (unsigned char i = 1; i <= 15; i += 2) {
          evenChSum ^= msgr[i];
        }
      msgr[17] = evenChSum;
      povtorpol:
      memset(&otvet[0], 0, sizeof(otvet));
      u();
      for (int x = 0; x < (sizeof(msgr) / sizeof(byte)); x++) {
      Serial.write(msgr[x]);
      }
      Serial.println("");
      readserial();
      chotvet = chotvet++;
      if (otvet[0]==0 && otvet[1]==0 && otvet[2]==0 && otvet[3]==0){
       // Serial.println("");
       // Serial.print("povtor chtenia");
       // Serial.println(chotvet);
        if (chotvet<4) goto povtorpol;
      }
}
boolean delmsg(int n){                      //удаление смс
  boolean result;
  int chstat1 = 0;
  unsigned char evenChSum;
  memset(&otvet[0], 0, sizeof(otvet));
  while (otvet[0]==0x00){
  u();
  for (int x = 0; x < (sizeof(msgstat) / sizeof(byte)); x++) {
    Serial.write(msgstat[x]);
  }
  Serial.println("");
  readserial();
  chstat1 = chstat1++;
  if (chstat1>=4) break;
  }
//            if (otvet[29]==40) msgdel[13] = 0x41;
//          else if (otvet[29]==41) msgdel[13] = 0x42;
//          else if (otvet[29]==42) msgdel[13] = 0x43;
//          else if (otvet[29]==43) msgdel[13] = 0x44;
//          else if (otvet[29]==44) msgdel[13] = 0x45;
//          else if (otvet[29]==45) msgdel[13] = 0x46;
//          else if (otvet[29]==46) msgdel[13] = 0x47;
//          else if (otvet[29]==47) msgdel[13] = 0x40;
 
  int res1 = otvet[26];
  //Serial.print("pervaya - ");
  //Serial.println(res1);
  
  if (n == 1) msgdel[15] = 0x76;
  else if (n == 2) msgdel[15] = 0x75;
  else if (n == 3) msgdel[15] = 0x74;
  else if (n == 4) msgdel[15] = 0x73;
  else if (n == 5) msgdel[15] = 0x72;
  else if (n == 6) msgdel[15] = 0x71;
  else if (n == 7) msgdel[15] = 0x70;
  else if (n == 8) msgdel[15] = 0x7F;
  else if (n == 9) msgdel[15] = 0x7E;
  else if (n == 10) msgdel[15] = 0x67;
  else if (n == 11) msgdel[15] = 0x66;
  else if (n == 12) msgdel[15] = 0x65;
  else if (n == 13) msgdel[15] = 0x64;
    
    msgdel[11] = byte(n);
    
//  for (unsigned char i = 1; i <= 13; i += 2) {
//    evenChSum ^= msgdel[i];
//  }
//  msgdel[15] = evenChSum;
//  
  memset(&otvet[0], 0, sizeof(otvet));
  chstat1 = 0;
  while (otvet[0]==0x00){
    delay(1000);
  u();
  for (int x = 0; x < (sizeof(msgdel) / sizeof(byte)); x++) {
    Serial.write(msgdel[x]);
  }
  Serial.println("");
  readserial();
  Serial.println("");
  chstat1 = chstat1++;
  if (chstat1>=4){
   u();                   // отправка смс
   SendSMS("otveta net");
   break;
  }
  Serial.println("delete - ");                                  //вывод строки удаления
  for (int x1 = 0; x1 < (sizeof(msgdel) / sizeof(byte)); x1++) {
    Serial.print(msgdel[x1], HEX);
  }
  }
  memset(&otvet[0], 0, sizeof(otvet));
  chstat1 = 0;
  while (otvet[0]==0x00){
  u();
  for (int x = 0; x < (sizeof(msgstat) / sizeof(byte)); x++) {
    Serial.write(msgstat[x]);
  }
  Serial.println("");
  readserial();
  chstat1 = chstat1++;
  if (chstat1>=4) break;
  }
  int res2 = otvet[26];
//Serial.print("vtoraya - ");
  //Serial.println(res2);
  if (res2 < res1) result = true;
  else result = false;
  return result;
}

int phone()
{
 int result;

nado1 = 0;
  int chstat = 0;
  povtorstat:
  memset(&otvet[0], 0, sizeof(otvet));
  u();
  for (int x = 0; x < (sizeof(msgstat) / sizeof(byte)); x++) {
    Serial.write(msgstat[x]);
  }
  Serial.println("");
  readserial();
  chstat = chstat++;
  if (otvet[13]==0x14 && otvet[19]==0x37 && otvet[23]==0x0A && otvet[24]==0x00){
    kolsms = int(otvet[26]);
  Serial.println("");
  Serial.print("kolsms-");
  Serial.println(kolsms);
  if (kolsms > 0){
    for (int t=kolsms; t>0; t--){
     msgread(t);

      if ((otvet[43]==0x05 && otvet[44]==0x45 && otvet[45]==0x26 && otvet[46]==0x67 && otvet[47]==0xF9) || (otvet[43]==0x91 && otvet[44]==0x63 && otvet[45]==0x00 && otvet[46]==0x03 && otvet[47]==0xF9) || (otvet[43]==0x35 && otvet[44]==0x00 && otvet[45]==0x35 && otvet[46]==0x00 && otvet[47]==0xF3) || (otvet[43]==0x35 && otvet[44]==0x06 && otvet[45]==0x31 && otvet[46]==0x47 && otvet[47]==0xF0)){
      //  Serial.println("");
     //   Serial.print("nomer sovpadaet");
       // Serial.println(nomer);
        RecipientNo[3] = otvet[43];
        RecipientNo[4] = otvet[44];
        RecipientNo[5] = otvet[45];
        RecipientNo[6] = otvet[46];
        RecipientNo[7] = otvet[47];
        int com = comanda(otvet[59],otvet[60]);
        if (com >= 5 && com <= 26){  //задание температуры
          nado1 = com;
          otchet = true;
     //   Serial.println("");
      //  Serial.print("zadanie temp");
     //   Serial.println(nado1);
        compoluchena = true;
        int chotpr = 0;
        povtor1:
          
            SeqNo = seq();
       //     Serial.println("");
       //     Serial.print(SeqNo, HEX);    
          memset(&otvet2[0], 0, sizeof(otvet2));            
          u();                   // отправка смс
          SendSMS("polucheno");
          
          currentTime3 = millis();
          int r = 0;
                                  // получение ответа
          while (1) {
            //loopTime3 = millis();
          while (Serial.available() > 0) {
             int incomingByte = Serial.read();
             otvet2[r] = incomingByte;
             r = r++;
                  //Serial.print(incomingByte, HEX);
             //Serial.print(" ");
             if (millis() >= (currentTime3 + 7000)){
               break;
             }
           }
                if (millis() >= (currentTime3 + 7000)){
               break;
             }
          }
                                    //конец получения ответа
          chotpr = chotpr++;
          //проверка отправки
          if (otvet2[10] == 0x1E && otvet2[11] == 0x0C && otvet2[19] == 0x02){
          }
          else {
                   // Serial.println("");
      //  Serial.print("povtor otpravki");
       // Serial.println(chotpr);
            if (chotpr < 9) goto povtor1;
          }
        }
        else if (com == 1){        //запрос температуры
        compoluchena = true;
          int chotpr = 0;
          char buff[15];         //создание строки для смс
          itoa(tempC, buff, 10);
          String temp;
          temp = "tek temp - ";
          String temp2 = String(buff);
          temp.concat(temp2);
          char ch[14];
          temp.toCharArray(ch,14);
          
          povtor:
          
            SeqNo = seq();
         //   Serial.println("");
         //   Serial.print(SeqNo, HEX);    
          memset(&otvet2[0], 0, sizeof(otvet2));            
          u();                   // отправка смс
          SendSMS(ch);
          
          currentTime3 = millis();
          int r = 0;
                                  // получение ответа
          while (1) {
            loopTime3 = millis();
          while (Serial.available() > 0) {
             int incomingByte = Serial.read();
             otvet2[r] = incomingByte;
             r = r++;
                  Serial.print(incomingByte, HEX);
             Serial.print(" ");
             if (millis() >= (currentTime3 + 7000)){
               break;
             }
           }
                if (millis() >= (currentTime3 + 7000)){
               break;
             }
          }
                                    //конец получения
          chotpr = chotpr++;
          //проверка отправки
          if (otvet2[10] == 0x1E && otvet2[11] == 0x0C && otvet2[19] == 0x02){
          }
          else {
                   // Serial.println("");
       // Serial.print("povtor otpravki");
       // Serial.println(chotpr);
            if (chotpr < 9) goto povtor;
          
       //   Serial.println("");
        //  Serial.print(tempC);
       //   Serial.print("zapros temp");
          
        }
      }
      else{
        boolean prdel;
         int c = 0;
         do
        {
         prdel = delmsg(t);
         delay(3000);
         c = c++;
         if (prdel == true) break;
        }while(c < 3);
      }
     if (compoluchena == true){
       boolean prdel;
       for (int k=t; k>0; k--){
       //  Serial.println("");
       //  Serial.print("popitka udalit sms #");
       //  Serial.println(k);
         int c1 = 0;
         do
        {
         prdel = delmsg(k);
         delay(1000);
         c1 = c1++;
         
      //  Serial.println("");
      //  Serial.print("udalenie posle poluchenia");
      //  Serial.println(c);
        if (prdel == true) break;
        }while(c1 < 3);
       }
       compoluchena = false;
      break;
     }
    }
    else if (otvet[13]==0x14 && otvet[15]==0x07 && otvet[19]==0x09 && otvet[20]==0x07){ //если нет сообщения по адресу равному количеству смс
      for (int l=1; l<=12; l++){
        delmsg(l);
      }
      break;
    }
    else{//если номер не совпадает
        boolean prdel;
         int c1 = 0;
         do
        {
         prdel = delmsg(t);
         delay(1000);
         c1 = c1++;
         if (prdel == true) break;
        }while(c1 < 3);
      }
      
  }//конец перебора по кол-ву смс
  }
  }
  else{
    if (chstat<4) goto povtorstat;
  }
  
       
  result = nado1;
return result;  
} 


unsigned char SendSMS(const char *Message) {
  // Clear buffer
  unsigned char j = 0;
  memset(FBusFrame, 0, sizeof(FBusFrame));

  unsigned char MsgLen = strlen(Message), FrameSize = 0;
  unsigned char c, w, n, shift = 0, frameIndex = 0;
  unsigned char oddCheckSum, evenCheckSum = 0;
  unsigned char MsgStartIndex = 48; // Message will always start here

  // Encode the message into 7 bit characters
  for (n = 0; n < MsgLen; n++) {
    c = Message[n] & 0x7f;
    c >>= shift;
    w = Message[n+1] & 0x7f;
    w <<= (7-shift);
    shift += 1;
    c = c | w;
    if (shift == 7) {
      shift = 0x00;
      n++;
    }
    FBusFrame[frameIndex + MsgStartIndex] = c;
    frameIndex++;
  }

  FBusFrame[frameIndex + MsgStartIndex] = 0x01;
  FrameSize = frameIndex + 44; // The size of the frame is frameIndex+48 (FrameIndex + 48 + 1 - 5)

  // Insert the frame values to prepare to send an SMS 
  FBusFrame[0] = 0x1E;
  FBusFrame[1] = 0x00;
  FBusFrame[2] = 0x0C;
  FBusFrame[3] = 0x02;
  FBusFrame[4] = 0x00;
  FBusFrame[5] = FrameSize;
  FBusFrame[6] = 0x00;
  FBusFrame[7] = 0x01;
  FBusFrame[8] = 0x00;
  FBusFrame[9] = 0x01;
  FBusFrame[10] = 0x02;
  FBusFrame[11] = 0x00;

  // Insert the SMS Center number
  for (j = 0; j < sizeof(SMSC); j++) {
    FBusFrame[12 + j] = SMSC[j];
  }

  FBusFrame[24] = 0x15; //Message type??
  FBusFrame[28] = MsgLen; //Message length (uncompressed)

  // Insert the Recipient number
  for (j = 0; j < sizeof(RecipientNo); j++) {
    FBusFrame[j + 29] = RecipientNo[j];
  }

  FBusFrame[41] = 0xA7; // Validity period

  // Check if the Framesize is odd or even
  if (FrameSize & 0x01) {
    frameIndex = FrameSize + 5;
    FBusFrame[frameIndex] = SeqNo;
    frameIndex++;
    FBusFrame[frameIndex] = 0; // Insert to make the Frame even
    frameIndex++;
  }
  else {
    frameIndex = FrameSize + 5;
    FBusFrame[frameIndex] = SeqNo;
    frameIndex++;
  }

  // Calculate the checksum from the start of the frame to the end of the frame
  for (unsigned char i = 0; i < frameIndex+2; i += 2) {
    oddCheckSum ^= FBusFrame[i];
    evenCheckSum ^= FBusFrame[i+1];
  }
  FBusFrame[frameIndex] = oddCheckSum;
  FBusFrame[frameIndex+1] = evenCheckSum;

  // Send the full frame to the phone
  for (unsigned char j = 0; j < (frameIndex+2); j++) {
    // Debug to check in hex what we are sending
    //Serial.print(FBusFrame [j], HEX);
    //Serial.print(" ");

    Serial.write(FBusFrame [j]);
  }
}


int freeRam () {
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}

Можете глянуть мой проект, в отдельные функции вынесена работа по fbus.