jumpjack

Arduino FBUS Nokia

Apr 16th, 2011
1,788
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 21.01 KB | None | 0 0
  1. /**************************************************************************
  2.  
  3.   Nokia 61xx SMS send/receive functions
  4.  
  5.   Version 1.0
  6.  
  7.   Justin Karneges
  8.   June 2000
  9.  
  10.   Thanks goes to the gnokii team for figuring out the frame format, among
  11.   many other things!  These guys did all the hard work.  Although this file
  12.   was written from scratch, it was heavily based on their research.
  13.  
  14.   http://www.gnokii.org/
  15.  
  16.   Overview:
  17.  
  18.     This file contains a set of functions for sending and receiving SMS
  19.     (short message service) text messages across a GSM network with a
  20.     Nokia 61xx series phone.  I've only tested it with my phone (a 6190),
  21.     however it should work fine with any GSM phone in the series.  It
  22.     should also work with the 59xx series phones.
  23.  
  24.     These functions were meant to be as portable as possible (they contain
  25.     no serial communications code), and to perform two simple things: send
  26.     and receive SMS.  That's all.  If you want a full program to control
  27.     all the aspects of the Nokia 61xx, then I suggest checking out gnokii.
  28.     This code was meant to be small, so that it could be used in small
  29.     devices/applications.
  30.  
  31.  
  32.   To use:
  33.  
  34.     Setup the serial port and call n61_init().  Then use n61_smssend() and
  35.     n61_smsrecv() to send/recv SMS messages.  Call n61_update() as often
  36.     as possible (possibly by having a timer ISR call it) so that the driver
  37.     stays in sync with the phone.  All incoming SMS messages are deleted
  38.     from the phone's inbox (you want this).
  39.  
  40.  
  41.   ------------------------------------------------------------------------
  42.   Functions:
  43.  
  44.     +---------------------------------------------------------+
  45.     |  void n61_init(int (*func)(int cmd, unsigned char c));  |
  46.     +---------------------------------------------------------+
  47.  
  48.       Before calling this function, do everything necessary to have the
  49.       serial port ready.  The port MUST be set as follows:
  50.  
  51.         Baud rate: 115200
  52.         Parity: None
  53.         Bits: 8
  54.         Stop bits: 1
  55.         DTR: set
  56.         RTS: cleared
  57.  
  58.       Since this driver does not contain any serial communications
  59.       functionality, you must supply it.  An interrupt driven / threaded
  60.       serial interface MUST be used.  This driver does not poll the port,
  61.       and so it is completely dependant on a background serial driver
  62.       keeping a queue of all incoming data (so that no data is lost).
  63.  
  64.       To give the serial functionality to this nokia driver, write a simple
  65.       function to perform the four types of requests that this driver will
  66.       need handled.  Pass this function as the argument to init:
  67.  
  68.         n61_init(myhandler);
  69.  
  70.       The myhandler() function should look like this:
  71.  
  72.         int myhandler(int cmd, unsigned char c)
  73.         {
  74.             if(cmd == 0) {
  75.                 serial_send(c);          // send c out the port
  76.                 return;
  77.             }
  78.             else if(cmd == 1)
  79.                 return serial_recv();    // return the next byte in queue
  80.             else if(cmd == 2)
  81.                 return serial_isdata();  // return zero if queue is empty
  82.             else if(cmd == 3)
  83.                 msleep(1);               // delay for 1 millisecond
  84.         }
  85.  
  86.       0 means send "c" out the serial port.  1 means return a byte from the
  87.       serial port.  2 means return true/false if there is data waiting.
  88.       Simple enough!
  89.  
  90.       This driver also requires a millisecond resolution timer, which is
  91.       what the last request is for.  Most platforms include some sort of
  92.       millisecond (or less) delay function.  For MSVC++ there is Sleep(),
  93.       Unix has usleep() and DOS has delay().  If you're not using such a
  94.       platform, then you'll have to time it yourself.  The driver doesn't
  95.       specify how many milliseconds to wait, your function should wait
  96.       just one millisecond.  So just do Sleep(1), usleep(1000), delay(1),
  97.       or whatever your homebrew method is.  Easy!
  98.  
  99.       Lastly, n61_init() also queries the phone for the SMSC number to be
  100.       used when sending SMS.
  101.  
  102.       Whew!  If you got past n61_init(), then the rest is easy as cake.
  103.  
  104.     +--------------------------------------------+
  105.     |  int n61_smssend(char *dest, char *msg);  |
  106.     +--------------------------------------------+
  107.  
  108.       Sends "msg" to "dest".  Returns 1 if sent, 0 if not.
  109.  
  110.  
  111.     +---------------------------------------------+
  112.     |  int n61_smsrecv(char *source, char *msg);  |
  113.     +---------------------------------------------+
  114.  
  115.       Copies a received message into "msg", stores the source phone number
  116.       in "source" and returns 1.  Returns 0 if no messages are in the queue.
  117.       "msg" will not be larger than 161 bytes (including null byte).
  118.       "source" will not be larger than 17 bytes (including null byte).
  119.  
  120.  
  121.     +-----------------------+
  122.     |  int n61_smsqueue();  |
  123.     +-----------------------+
  124.  
  125.       Returns the number of messages in the incoming queue.
  126.  
  127.  
  128.     +---------------------+
  129.     |  int n61_update();  |
  130.     +---------------------+
  131.  
  132.       This must be called as often as possible.  If it's not called, then
  133.       you won't be able to receive messages.  This might be something good
  134.       to put in a timer interrupt if possible (yes, it's safe).
  135.  
  136.  
  137.   That's all you need to know!
  138.  
  139.   ------------------------------------------------------------------------
  140.  
  141.   Nokia 6190 message format:
  142.  
  143.     1 byte = start byte (0x1e)
  144.     1 byte = message destination
  145.     1 byte = message source
  146.     1 byte = message type
  147.     1 byte = ???
  148.     1 byte = message size
  149.  
  150.     X bytes = message data (X = message size)
  151.  
  152.     1 byte = filler byte (exists only if needed to make message size even)
  153.  
  154.     2 byte = result of all 16bit words XOR'ed together
  155.  
  156. **************************************************************************/
  157.  
  158. //#include <string.h>
  159.  
  160. #define N61MODE_SYNC    0
  161. #define N61MODE_DEST    1
  162. #define N61MODE_SOURCE  2
  163. #define N61MODE_TYPE    3
  164. #define N61MODE_UNKNOWN 4
  165. #define N61MODE_SIZE    5
  166. #define N61MODE_DATA    6
  167.  
  168. #define N61STATE_WAIT   0
  169. #define N61STATE_PROC   1
  170. #define N61STATE_GOOD   2
  171. #define N61STATE_BAD    3
  172.  
  173. #define N61MAXSIZE  120
  174.  
  175. #define N61VALID_1H 0x0b
  176. #define N61VALID_6H 0x47
  177. #define N61VALID_24H    0xa7
  178. #define N61VALID_72H    0xa9
  179. #define N61VALID_1W 0xad
  180. #define N61VALID_MAX    0xff
  181.  
  182. struct MESSAGE
  183. {
  184.     int dest;
  185.     int source;
  186.     int type;
  187.     int unknown;
  188.     int size;
  189.     unsigned char dat[256];
  190.     int cs[2];
  191. };
  192.  
  193. struct MESSAGE tmp, buf;
  194. int seqnum = 0;
  195. int prevseq = 0;
  196. int (*serial)(int cmd, unsigned char c);
  197. int mode = 0;
  198. int atbyte = 0;
  199. int datp = 0;
  200. int readsize = 0;
  201. int readbase = 0;
  202. int state;
  203. int multiple;
  204. char smsc[32];
  205. int msgqueuesize;
  206. char msgqueue[4][161];
  207. char msgqueue2[4][17];
  208. int ack, gotmsg, waittype;
  209. int blocked;
  210.  
  211.  
  212. // ** translate table taken directly from gnokii **
  213.  
  214. unsigned char transtable[] = {
  215.  
  216.     /* ETSI GSM 03.38, version 6.0.1, section 6.2.1; Default alphabet */
  217.     /* Characters in hex position 10, [12 to 1a] and 24 are not present on
  218.         latin1 charset, so we cannot reproduce on the screen, however they are
  219.         greek symbol not present even on my Nokia */
  220.  
  221.     '@',  0xa3, '$',  0xa5, 0xe8, 0xe9, 0xf9, 0xec,
  222.     0xf2, 0xc7, '\n', 0xd8, 0xf8, '\r', 0xc5, 0xe5,
  223.     '?',  '_',  '?',  '?',  '?',  '?',  '?',  '?',
  224.     '?',  '?',  '?',  '?',  0xc6, 0xe6, 0xdf, 0xc9,
  225.     ' ',  '!',  '"', '#',  0xa4,  '%',  '&',  '\'',
  226.     '(',  ')',  '*',  '+',  ',',  '-',  '.',  '/',
  227.     '0',  '1',  '2',  '3',  '4',  '5',  '6',  '7',
  228.     '8',  '9',  ':',  ';',  '<',  '=',  '>',  '?',
  229.     0xa1, 'A',  'B',  'C',  'D',  'E',  'F',  'G',
  230.     'H',  'I',  'J',  'K',  'L',  'M',  'N',  'O',
  231.     'P',  'Q',  'R',  'S',  'T',  'U',  'V',  'W',
  232.     'X',  'Y',  'Z',  0xc4, 0xd6, 0xd1, 0xdc, 0xa7,
  233.     0xbf, 'a',  'b',  'c',  'd',  'e',  'f',  'g',
  234.     'h',  'i',  'j',  'k',  'l',  'm',  'n',  'o',
  235.     'p',  'q',  'r',  's',  't',  'u',  'v',  'w',
  236.     'x',  'y',  'z',  0xe4, 0xf6, 0xf1, 0xfc, 0xe0
  237. };
  238.  
  239. // **** Functions            ****
  240.  
  241. void init(int (*func)(int cmd, unsigned char c));   // initialize the driver
  242. int smssend(char *dest, char *msg);         // send SMS
  243. int smsrecv(char *dest, char *msg);         // recv SMS
  244. int smsqueue();                 // check the recv queue
  245. void update();                  // keep the driver in sync
  246.  
  247. // **** Functions - internal ****
  248.  
  249. void block();                       // protect during update
  250. void unblock();                     // unprotect
  251.  
  252. void update_main();                     // main update
  253. void update_internal();                 // internal version of
  254.                                 //   update()
  255.  
  256. void serial_send(unsigned char c);              // send byte
  257. unsigned char serial_recv();                // recv byte
  258. unsigned char serial_isdata();              // check for serial data
  259. void serial_delay();                    // wait 1 millisecond
  260.  
  261. int nextseq();                      // get next sequence number
  262. int sendframe(int type, int size, unsigned char *data); // send frame
  263. int sendmsg(int type, int size,  char *data);   // send message
  264. void sendack(int type, int seqnum);             // send acknowledgement
  265.  
  266. void ackwait(int x);                    // wait for ack
  267. void wait(int x);                       // wait for a message
  268.  
  269. void addchar(char *str, char c);                // strcat() but for chars
  270. void bcd(char *dest, char *s);              // encode SMSC number
  271. void bcd2(char *dest, char *s);             // encode phone number
  272. char *unbcd(unsigned char *dat);                // decode SMSC number
  273. char *unbcd2(unsigned char *dat);               // decode phone number
  274.  
  275. void pack7(char *dest, char *s);                // pack when sending
  276. char *unpack7(unsigned char *dat, int len);         // unpack when received
  277.  
  278. unsigned char gettrans(unsigned char c);            // translate char
  279. void addmsg(char *dest, char *msg);             // add a received SMS
  280.                                 //   to the queue
  281.  
  282. void procmsg(struct MESSAGE *msg);          // process incoming message
  283.  
  284. void getstatus();                       // request phone status
  285. void getsmsc();                     // request SMSC
  286. void delsms(int x);                     // delete SMS message
  287. int smssendfull(char *smsc, char *dest, char *msg);     // send SMS via SMSC
  288.  
  289.  
  290. // ** Code **
  291.         int myhandler(int cmd, unsigned char c)
  292.         {
  293.             if(cmd == 0) {
  294.                 serial_send(c);          // send c out the port
  295.                 return 0;
  296.             }
  297.             else if(cmd == 1)
  298.                 return serial_recv();    // return the next byte in queue
  299.             else if(cmd == 2)
  300.                 return serial_isdata();  // return zero if queue is empty
  301.             else if(cmd == 3)
  302.                 delay(1);               // delay for 1 millisecond
  303.         }
  304.  
  305. unsigned char gettrans(unsigned char c)
  306. {
  307.     unsigned char n;
  308.  
  309.     if(c == '?')
  310.         return 0x3f;
  311.  
  312.     for(n = 0; n < 128; ++n) {
  313.         if(transtable[n] == c)
  314.             return n;
  315.     }
  316.  
  317.     return 0x3f;
  318. }
  319.  
  320. void block()
  321. {
  322.     blocked = 1;
  323. }
  324.  
  325. void unblock()
  326. {
  327.     blocked = 0;
  328. }
  329.  
  330. void update()
  331. {
  332.     if(!blocked) {
  333.         block();
  334.         update_main();
  335.         unblock();
  336.     }
  337. }
  338.  
  339. void update_internal()
  340. {
  341.     update_main();
  342. }
  343.  
  344. void serial_send(unsigned char c)
  345. {
  346.     //serial(0, c);
  347. Serial.print(c);
  348. }
  349.  
  350. unsigned char serial_recv()
  351. {
  352. return Serial.read();  
  353.   //return serial(1, 0);
  354. }
  355.  
  356. unsigned char serial_isdata()
  357. {
  358.         return Serial.available();
  359.     //return serial(2, 0);
  360. }
  361.  
  362. void serial_delay()
  363. {
  364.   delay(1);
  365.     //serial(3, 0);
  366. }
  367.  
  368. void ackwait(int x)
  369. {
  370.     int n;
  371.  
  372.     for(n = 0; n < x; ++n) {
  373.         update_internal();
  374.         serial_delay();
  375.         if(ack)
  376.             return;
  377.     }
  378. }
  379.  
  380. void wait(int x)
  381. {
  382.     int n;
  383.  
  384.     for(n = 0; n < x; ++n) {
  385.         update_internal();
  386.         serial_delay();
  387.         if(gotmsg)
  388.             return;
  389.     }
  390. }
  391.  
  392. void addmsg(char *dest, char *msg)
  393. {
  394.     int n;
  395.  
  396.     // clip args for safety. in theory not necessary
  397.     msg[160] = 0;
  398.     dest[16] = 0;
  399.  
  400.     // add the message
  401.     n = msgqueuesize;
  402.     strcpy(msgqueue[n], msg);
  403.     strcpy(msgqueue2[n], dest);
  404.     ++msgqueuesize;
  405. }
  406.  
  407. int smsrecv(char *dest, char *msg)
  408. {
  409.     int n;
  410.  
  411.     block();
  412.     n = msgqueuesize;
  413.  
  414.     if(n <= 0) {
  415.         unblock();
  416.         return 0;
  417.     }
  418.  
  419.     strcpy(msg, msgqueue[0]);
  420.     strcpy(dest, msgqueue2[0]);
  421.     --msgqueuesize;
  422.  
  423.     for(n = 0; n < msgqueuesize; ++n) {
  424.         strcpy(msgqueue[n], msgqueue[n+1]);
  425.         strcpy(msgqueue2[n], msgqueue2[n+1]);
  426.     }
  427.  
  428.     unblock();
  429.  
  430.     return 1;
  431. }
  432.  
  433. int smsqueue()
  434. {
  435.     return msgqueuesize;
  436. }
  437.  
  438. int sendframe(int type, int size, unsigned char *data)
  439. {
  440.     unsigned char buf[256];
  441.     int at, n, check, len;
  442.     unsigned short *p;
  443.  
  444.     at = 0;
  445.  
  446.     // build header
  447.     buf[at++] = 0x1e;       // message startbyte
  448.     buf[at++] = 0x00;       // dest: phone
  449.     buf[at++] = 0x0c;       // source: PC
  450.     buf[at++] = type;
  451.     buf[at++] = 0x00;
  452.     buf[at++] = size;
  453.  
  454.     // add data
  455.     for(n = 0; n < size; ++n)
  456.         buf[at++] = data[n];
  457.  
  458.     // if odd numbered, add filler byte
  459.     if(size % 2) {
  460.         buf[at++] = 0x00;
  461.     }
  462.  
  463.     // calculate checksums
  464.     check = 0;
  465.     p = (unsigned short *)buf;
  466.     len = at / 2;
  467.     for(n = 0; n < len; ++n)
  468.         check ^= p[n];
  469.     p[n] = check;
  470.     at += 2;
  471.  
  472.     // send the message!
  473.     for(n = 0; n < at; ++n) {
  474.         serial_send(buf[n]);
  475.     }
  476. }
  477.  
  478. int nextseq()
  479. {
  480.     int n;
  481.  
  482.     n = seqnum;
  483.     prevseq = n;
  484.  
  485.     ++seqnum;
  486.     seqnum &= 7;
  487.  
  488.     return (n + 0x40);
  489. }
  490.  
  491. int sendmsg(int type, int size,  char *data)
  492. {
  493.     unsigned char buf[N61MAXSIZE + 2];
  494.     unsigned char num, lastsize;
  495.     int n;
  496.     int len;
  497.  
  498.     num = (size + N61MAXSIZE - 1) / N61MAXSIZE;
  499.     lastsize = size % N61MAXSIZE;
  500.  
  501.     for(n = 0; n < num;) {
  502.         if(n + 1 == num)
  503.             len = lastsize;
  504.         else
  505.             len = N61MAXSIZE;
  506.  
  507.         // get current chunk
  508.         memcpy(buf, data + (n * N61MAXSIZE), len);
  509.         buf[len] = num - n;
  510.         buf[len+1] = nextseq();
  511.         if(n)
  512.             buf[len+1] &= 7;
  513.  
  514.         ack = 0;
  515.         sendframe(type, len + 2, buf);
  516.         ackwait(1000);
  517.         if(ack)
  518.             ++n;
  519.     }
  520. }
  521.  
  522. void sendack(int type, int seqnum)
  523. {
  524.     unsigned char buf[2];
  525.  
  526.     buf[0] = type;
  527.     buf[1] = seqnum;
  528.  
  529.     sendframe(0x7f, 2, buf);
  530. }
  531.  
  532. void update_main()
  533. {
  534.     int n;
  535.     unsigned char c;
  536.  
  537.     while(serial_isdata()) {
  538.         c = serial_recv();
  539.  
  540.         // calculate the checksums
  541.         tmp.cs[atbyte & 1] ^= c;
  542.  
  543.         // act on the byte
  544.         switch(mode) {
  545.             case N61MODE_SYNC:
  546.                 if(c == 0x1e) {
  547.                     if(!multiple) {
  548.                         memset(tmp.dat, 0, 256);
  549.                         atbyte = 0;
  550.                     }
  551.  
  552.                     tmp.cs[0] = 0x1e;
  553.                     tmp.cs[1] = 0;
  554.  
  555.                     mode = N61MODE_DEST;
  556.                 }
  557.                 break;
  558.  
  559.             case N61MODE_DEST:
  560.                 tmp.dest = c;
  561.                 mode = N61MODE_SOURCE;
  562.                 break;
  563.  
  564.             case N61MODE_SOURCE:
  565.                 tmp.source = c;
  566.                 mode = N61MODE_TYPE;
  567.                 break;
  568.  
  569.             case N61MODE_TYPE:
  570.                 tmp.type = c;
  571.                 mode = N61MODE_UNKNOWN;
  572.                 break;
  573.  
  574.             case N61MODE_UNKNOWN:
  575.                 tmp.unknown = c;
  576.                 mode = N61MODE_SIZE;
  577.                 break;
  578.  
  579.             case N61MODE_SIZE:
  580.                 if(multiple)
  581.                     tmp.size += c - 2;
  582.                 else {
  583.                     tmp.size = c;
  584.                     datp = 0;
  585.                 }
  586.  
  587.                 mode = N61MODE_DATA;
  588.  
  589.                 // calculate the number of bytes to read
  590.                 n = tmp.size % 2;
  591.  
  592.                 // message size + filler + checksums
  593.                 readsize = tmp.size + n + 2;
  594.  
  595.                 break;
  596.  
  597.             case N61MODE_DATA:
  598.                 n = datp++;
  599.                 if(n > 255) {
  600.                     multiple = 0;
  601.                     mode = N61MODE_SYNC;
  602.                     break;
  603.                 }
  604.  
  605.                 tmp.dat[n] = c; // get the byte
  606.  
  607.                 // are we done yet?
  608.                 if(n >= readsize - 1) {
  609.                     // checksums ok?
  610.                     if(tmp.cs[0] == tmp.cs[1] && tmp.cs[0] == 0) {
  611.                         // don't want to ACK on an ACK
  612.                         if(tmp.type != 0x7f) {
  613.                             sendack(tmp.type, tmp.dat[tmp.size-1] & 0x0f);
  614.  
  615.                             if(tmp.size > 1 && tmp.dat[tmp.size-2] != 0x01) {
  616.                                 datp -= 4;  // back up past checksums and seqinfo
  617.                                 ++multiple;
  618.                             }
  619.                             else
  620.                                 multiple = 0;
  621.                         }
  622.  
  623.                         if(!multiple || tmp.type == 0x7f) {
  624.                             multiple = 0;
  625.                             memcpy(&buf, &tmp, sizeof(struct MESSAGE));
  626.                             procmsg(&buf);
  627.                         }
  628.                     }
  629.                     else {
  630.                         // bad!
  631.                         multiple = 0;
  632.                     }
  633.                     mode = N61MODE_SYNC;
  634.                 }
  635.  
  636.             default:
  637.                 break;
  638.         }
  639.  
  640.         ++atbyte;
  641.     }
  642. }
  643.  
  644. void getstatus()
  645. {
  646.      char buf[32];
  647.  
  648.     buf[0] = 0x00;
  649.     buf[1] = 0x01;
  650.     buf[2] = 0x00;
  651.  
  652.     buf[3] = 0x6d;
  653.  
  654.     sendmsg(0x11, 4, buf);
  655. }
  656.  
  657. void getsmsc()
  658. {
  659.      char buf[32];
  660.     int x, n;
  661.  
  662.     buf[0] = 0x00;
  663.     buf[1] = 0x01;
  664.     buf[2] = 0x00;
  665.  
  666.     buf[3] = 0x33;
  667.     buf[4] = 0x64;
  668.  
  669.     buf[5] = 0x01;
  670.  
  671.     // "do" or "try", there is no "do not"
  672.     while(1) {
  673.         // send off the request
  674.         state = N61STATE_PROC;
  675.  
  676.         gotmsg = 0;
  677.         waittype = 2;
  678.         sendmsg(0x02, 6, buf);
  679.  
  680.         wait(1000);
  681.         if(state == N61STATE_GOOD)
  682.             break;
  683.     }
  684. }
  685.  
  686. void delsms(int x)
  687. {
  688.      char buf[32];
  689.  
  690.     buf[0] = 0x00;
  691.     buf[1] = 0x01;
  692.     buf[2] = 0x00;
  693.  
  694.     buf[3] = 0x0a;
  695.     buf[4] = 0x02;
  696.     buf[5] = x;
  697.  
  698.     sendmsg(0x14, 6, buf);
  699. }
  700.  
  701. void bcd(char *dest, char *s)
  702. {
  703.     int size, x, y, n, hi, lo;
  704.  
  705.     if(s[0] == '+') {
  706.         dest[1] = 0x91;
  707.         ++s;
  708.     }
  709.     else
  710.         dest[1] = 0x81;
  711.  
  712.     x = 0;
  713.     y = 2;
  714.     while(s[x]) {
  715.         lo = s[x++] - '0';
  716.         if(s[x])
  717.             hi = s[x++] - '0';
  718.         else
  719.             hi = 0x0f;
  720.  
  721.         n = (hi << 4) + lo;
  722.         dest[y++] = n;
  723.     }
  724.     dest[0] = y - 1;
  725. }
  726.  
  727. void bcd2(char *dest, char *s)
  728. {
  729.     int size, x, y, n, hi, lo;
  730.  
  731.     if(s[0] == '+') {
  732.         dest[1] = 0x91;
  733.         ++s;
  734.     }
  735.     else
  736.         dest[1] = 0x81;
  737.  
  738.     x = 0;
  739.     y = 2;
  740.     while(s[x]) {
  741.         lo = s[x++] - '0';
  742.         if(s[x])
  743.             hi = s[x++] - '0';
  744.         else
  745.             hi = 0x0f;
  746.  
  747.         n = (hi << 4) + lo;
  748.         dest[y++] = n;
  749.     }
  750.     dest[0] = strlen(s);
  751. }
  752.  
  753. void pack7(char *dest, char *s)
  754. {
  755.     int len;
  756.     unsigned char c;
  757.     unsigned short *p, w;
  758.     int at;
  759.     int shift;
  760.     int n, x;
  761.  
  762.     len = strlen(s);
  763.     x = (len * 8) / 7;
  764.     for(n = 0; n < x; ++n)
  765.         dest[n] = 0;
  766.  
  767.     shift = 0;
  768.     at = 0;
  769.     w = 0;
  770.     for(n = 0; n < len; ++n) {
  771.         p = (unsigned short *)(dest + at);
  772.         w = gettrans(s[n]) & 0x7f;
  773.         w <<= shift;
  774.  
  775.         *p |= w;
  776.  
  777.         shift += 7;
  778.         if(shift >= 8) {
  779.             shift &= 7;
  780.             ++at;
  781.         }
  782.     }
  783. }
  784.  
  785. int smssendfull(char *smsc, char *dest, char *msg)
  786. {
  787.      char buf[256];
  788.     int n;
  789.  
  790.     // standard frame data header
  791.     buf[0] = 0x00;
  792.     buf[1] = 0x01;
  793.     buf[2] = 0x00;
  794.  
  795.     // send sms ?
  796.     buf[3] = 0x01;
  797.     buf[4] = 0x02;
  798.     buf[5] = 0x00;
  799.  
  800.     // smsc
  801.     memset(buf + 6, 0, 12);
  802.     bcd(buf + 6, smsc);
  803.  
  804.     // TPDU ?
  805.     buf[18] = 0x11;
  806.  
  807.     // misc
  808.     buf[19] = 0x00; // message ref
  809.     buf[20] = 0x00; // protocol ID
  810.     buf[21] = 0xf1; // data coding scheme (non-flash)
  811.  
  812.     // message size
  813.     buf[22] = strlen(msg);
  814.  
  815.     // destination
  816.     memset(buf + 23, 0, 12);
  817.     bcd2(buf + 23, dest);
  818.  
  819.     // validity period
  820.     buf[35] = N61VALID_24H;
  821.  
  822.     // filler
  823.     buf[36] = 0;
  824.     buf[37] = 0;
  825.     buf[38] = 0;
  826.     buf[39] = 0;
  827.     buf[40] = 0;
  828.     buf[41] = 0;
  829.  
  830.     // the string
  831.     pack7(buf + 42, msg);
  832.  
  833.     // try till we get some response
  834.     while(1) {
  835.         state = N61STATE_PROC;
  836.  
  837.         gotmsg = 0;
  838.         waittype = 1;
  839.         sendmsg(0x02, 42 + strlen(msg), buf);
  840.  
  841.         wait(5000);
  842.         if(state != N61STATE_PROC)
  843.             break;
  844.     }
  845.  
  846.     if(state == N61STATE_GOOD)
  847.         return 1;
  848.  
  849.     return 0;
  850. }
  851.  
  852. int smssend(char *dest, char *msg)
  853. {
  854.     int n;
  855.  
  856.     block();
  857.     n = smssendfull(smsc, dest, msg);
  858.     unblock();
  859.  
  860.     return n;
  861. }
  862.  
  863. void addchar(char *str, char c)
  864. {
  865.     int n;
  866.  
  867.     n = strlen(str);
  868.     str[n] = c;
  869.     str[n+1] = 0;
  870. }
  871.  
  872. char *unbcd(unsigned char *dat)
  873. {
  874.     static char buf[32];
  875.     int len;
  876.     int n, x;
  877.  
  878.     buf[0] = 0;
  879.     len = dat[0];
  880.  
  881.     if(dat[1] == 0x91) {
  882.         addchar(buf, '+');
  883.     }
  884.  
  885.     for(n = 0; n < len-1; ++n) {
  886.         x = dat[n+2] & 0x0f;
  887.         if(x < 10)
  888.             addchar(buf, '0' + x);
  889.         x = (dat[n+2] >> 4) & 0x0f;
  890.         if(x < 10)
  891.             addchar(buf, '0' + x);
  892.     }
  893.  
  894.     return buf;
  895. }
  896.  
  897. char *unbcd2(unsigned char *dat)
  898. {
  899.     static char buf[32];
  900.     int len;
  901.     int n, x;
  902.     int at;
  903.  
  904.     buf[0] = 0;
  905.     len = dat[0];
  906.  
  907.     if(dat[1] == 0x6f || dat[1] == 0x91) {
  908.         addchar(buf, '+');
  909.     }
  910.  
  911.     at = 2;
  912.     for(n = 0; n < len; ++n) {
  913.         x = dat[at] & 0x0f;
  914.         if(x < 10)
  915.             addchar(buf, '0' + x);
  916.         ++n;
  917.         if(!(n < len))
  918.             break;
  919.         x = (dat[at] >> 4) & 0x0f;
  920.         if(x < 10)
  921.             addchar(buf, '0' + x);
  922.         ++at;
  923.     }
  924.  
  925.     return buf;
  926. }
  927.  
  928. char *unpack7(unsigned char *dat, int len)
  929. {
  930.     static char buf[256];
  931.     unsigned short *p, w;
  932.     unsigned char c;
  933.     int n;
  934.     int shift;
  935.     int at;
  936.  
  937.     shift = 0;
  938.     at = 0;
  939.     buf[0] = 0;
  940.     for(n = 0; n < len; ++n) {
  941.         p = (unsigned short *)(dat + at);
  942.         w = *p;
  943.         w >>= shift;
  944.         c = w & 0x7f;
  945.  
  946.         shift += 7;
  947.         if(shift & 8) {
  948.             shift &= 0x07;
  949.             ++at;
  950.         }
  951.  
  952.         addchar(buf, transtable[c]);
  953.     }
  954.  
  955.     return buf;
  956. }
  957.  
  958. void procmsg(struct MESSAGE *msg)
  959. {
  960.     int n, subtype;
  961.  
  962.     // check if this is a msg of interest
  963.     subtype = 0;
  964.     if(msg->type != 0x7f) {
  965.         if(msg->type == 0x02) {
  966.             if(msg->dat[3] == 0x02 || msg->dat[3] == 0x03)
  967.                 subtype = 1;
  968.             if(msg->dat[3] == 0x10)
  969.                 subtype = 2;
  970.             if(msg->dat[3] == 0x34)
  971.                 subtype = 3;
  972.         }
  973.         if(subtype == waittype)
  974.             gotmsg = 1;
  975.     }
  976.  
  977.     // act on it
  978.     switch(msg->type) {
  979.         // SMS
  980.         case    0x02:
  981.             if(msg->dat[3] == 0x02) {
  982.                 state = N61STATE_GOOD;
  983.             }
  984.             if(msg->dat[3] == 0x03) {
  985.                 state = N61STATE_BAD;
  986.             }
  987.             if(msg->dat[3] == 0x10) {
  988.                 addmsg(unbcd2(msg->dat + 23), unpack7(msg->dat + 42, msg->dat[22]));
  989.  
  990.                 // now delete the msg
  991.                 if(msg->dat[5])
  992.                     delsms(msg->dat[5]);
  993.             }
  994.  
  995.             // SMSC
  996.             if(msg->dat[3] == 0x34) {
  997.                 state = N61STATE_GOOD;
  998.                 strcpy(smsc, unbcd(msg->dat+21));
  999.             }
  1000.             break;
  1001.  
  1002.         case    0x7f:
  1003.             if((msg->dat[1] & 7) == prevseq)
  1004.                 ack = 1;
  1005.             break;
  1006.  
  1007.         default:
  1008.             break;
  1009.     }
  1010. }
  1011.  
  1012. void init(int (*func)(int cmd, unsigned char c))
  1013. {
  1014.     int n;
  1015.  
  1016.     seqnum = 0;
  1017.     serial = func;
  1018.     blocked = 0;
  1019.     msgqueuesize = 0;
  1020.     multiple = 0;
  1021.     readbase = 0;
  1022.  
  1023.     // getsmsc
  1024.     getsmsc();
  1025. }
  1026.  
  1027. void setup() {
  1028.   char * destinatario = "+3900000000";
  1029.   char * messaggio = "Incredible, it works!";
  1030.   Serial.begin(115200);
  1031.   init(myhandler);
  1032.   smssend(destinatario,messaggio);
  1033. }
  1034.  
  1035. void loop() {
  1036. }
Advertisement
Add Comment
Please, Sign In to add comment