shared.c
上传用户:gzpyjq
上传日期:2013-01-31
资源大小:1852k
文件大小:10k
源码类别:

手机WAP编程

开发平台:

WINDOWS

  1. /*
  2.  * shared.c - some utility routines shared by all Kannel boxes
  3.  *
  4.  * Lars Wirzenius
  5.  */
  6. #include <sys/utsname.h>
  7. #include <libxml/xmlversion.h>
  8. #include "gwlib/gwlib.h"
  9. #include "shared.h"
  10. #include "sms.h"
  11. #if defined(HAVE_LIBSSL) || defined(HAVE_WTLS_OPENSSL) 
  12. #include <openssl/opensslv.h>
  13. #endif
  14. #ifdef HAVE_MYSQL 
  15. #include <mysql_version.h>
  16. #endif
  17. enum program_status program_status = starting_up;
  18. void report_versions(const char *boxname)
  19. {
  20.     Octstr *os;
  21.     
  22.     os = version_report_string(boxname);
  23.     debug("gwlib.gwlib", 0, "%s", octstr_get_cstr(os));
  24.     octstr_destroy(os);
  25. }
  26. Octstr *version_report_string(const char *boxname)
  27. {
  28.     struct utsname u;
  29.     uname(&u);
  30.     return octstr_format(GW_NAME " %s version `%s'.n"
  31.                 "System %s, release %s, version %s, machine %s.n"
  32.  "Hostname %s, IP %s.n"
  33.  "Libxml version %s.n"
  34. #ifdef HAVE_LIBSSL
  35.              "Using "
  36. #ifdef HAVE_WTLS_OPENSSL
  37.              "WTLS library "
  38. #endif
  39.              "%s.n"
  40. #endif
  41. #ifdef HAVE_MYSQL
  42.              "Using MySQL %s.n"
  43. #endif
  44. #ifdef HAVE_SDB
  45.              "Using LibSDB %s.n"
  46. #endif
  47.              "Using %s malloc.n",
  48.  boxname, VERSION,
  49.  u.sysname, u.release, u.version, u.machine,
  50.  octstr_get_cstr(get_official_name()),
  51.  octstr_get_cstr(get_official_ip()),
  52.  LIBXML_VERSION_STRING,
  53. #ifdef HAVE_LIBSSL
  54.              OPENSSL_VERSION_TEXT,
  55. #endif
  56. #ifdef HAVE_MYSQL
  57.              MYSQL_SERVER_VERSION,
  58. #endif
  59. #ifdef HAVE_SDB
  60.              LIBSDB_VERSION,
  61. #endif
  62.              octstr_get_cstr(gwmem_type()));
  63. }
  64. /***********************************************************************
  65.  * Communication with the bearerbox.
  66.  */
  67. static Connection *bb_conn;
  68. void connect_to_bearerbox(Octstr *host, int port, int ssl, Octstr *our_host)
  69. {
  70. #ifdef HAVE_LIBSSL
  71. if (ssl) 
  72.     bb_conn = conn_open_ssl(host, port, NULL, our_host);
  73.         /* XXX add certkeyfile to be given to conn_open_ssl */
  74. else
  75. #endif /* HAVE_LIBSSL */
  76.     bb_conn = conn_open_tcp(host, port, our_host);
  77.     if (bb_conn == NULL)
  78.      panic(0, "Couldn't connect to the bearerbox.");
  79.     if (ssl)
  80.         info(0, "Connected to bearerbox at %s port %d using SSL.",
  81.          octstr_get_cstr(host), port);
  82.     else
  83.         info(0, "Connected to bearerbox at %s port %d.",
  84.          octstr_get_cstr(host), port);
  85. }
  86. void close_connection_to_bearerbox(void)
  87. {
  88.     conn_destroy(bb_conn);
  89.     bb_conn = NULL;
  90. }
  91. void write_to_bearerbox(Msg *pmsg)
  92. {
  93.     Octstr *pack;
  94.     pack = msg_pack(pmsg);
  95.     if (conn_write_withlen(bb_conn, pack) == -1)
  96.      error(0, "Couldn't write Msg to bearerbox.");
  97.     msg_destroy(pmsg);
  98.     octstr_destroy(pack);
  99. }
  100. int deliver_to_bearerbox(Msg *msg) 
  101. {
  102.      
  103.     Octstr *pack;
  104.     
  105.     pack = msg_pack(msg);
  106.     if (conn_write_withlen(bb_conn, pack) == -1) {
  107.      error(0, "Couldn't deliver Msg to bearerbox.");
  108.         octstr_destroy(pack);
  109.         return -1;
  110.     }
  111.                                    
  112.     octstr_destroy(pack);
  113.     msg_destroy(msg);
  114.     return 0;
  115. }
  116.                                                
  117. Msg *read_from_bearerbox(void)
  118. {
  119.     int ret;
  120.     Octstr *pack;
  121.     Msg *msg;
  122.     pack = NULL;
  123.     while (program_status != shutting_down) {
  124. pack = conn_read_withlen(bb_conn);
  125. gw_claim_area(pack);
  126. if (pack != NULL)
  127.     break;
  128. if (conn_read_error(bb_conn)) {
  129.     info(0, "Error reading from bearerbox, disconnecting");
  130.     return NULL;
  131. }
  132. if (conn_eof(bb_conn)) {
  133.     info(0, "Connection closed by the bearerbox");
  134.     return NULL;
  135. }
  136. ret = conn_wait(bb_conn, -1.0);
  137. if (ret < 0) {
  138.     error(0, "Connection to bearerbox broke.");
  139.     return NULL;
  140. }
  141.     }
  142.     
  143.     if (pack == NULL)
  144.      return NULL;
  145.     msg = msg_unpack(pack);
  146.     octstr_destroy(pack);
  147.     if (msg == NULL)
  148. error(0, "Failed to unpack data!");
  149.     return msg;
  150. }
  151. /*****************************************************************************
  152.  *
  153.  * Function validates an OSI date. Return unmodified octet string date when it
  154.  * is valid, NULL otherwise.
  155.  */
  156. Octstr *parse_date(Octstr *date)
  157. {
  158.     long date_value;
  159.     if (octstr_get_char(date, 4) != '-')
  160.         goto error;
  161.     if (octstr_get_char(date, 7) != '-')
  162.         goto error;
  163.     if (octstr_get_char(date, 10) != 'T')
  164.         goto error;
  165.     if (octstr_get_char(date, 13) != ':')
  166.         goto error;
  167.     if (octstr_get_char(date, 16) != ':')
  168.         goto error;
  169.     if (octstr_get_char(date, 19) != 'Z')
  170.         goto error;
  171.     if (octstr_parse_long(&date_value, date, 0, 10) < 0)
  172.         goto error;
  173.     if (octstr_parse_long(&date_value, date, 5, 10) < 0)
  174.         goto error;
  175.     if (date_value < 1 || date_value > 12)
  176.         goto error;
  177.     if (octstr_parse_long(&date_value, date, 8, 10) < 0)
  178.         goto error;
  179.     if (date_value < 1 || date_value > 31)
  180.         goto error;
  181.     if (octstr_parse_long(&date_value, date, 11, 10) < 0)
  182.         goto error;
  183.     if (date_value < 0 || date_value > 23)
  184.         goto error;
  185.     if (octstr_parse_long(&date_value, date, 14, 10) < 0)
  186.         goto error;
  187.     if (date_value < 0 || date_value > 59)
  188.         goto error;
  189.     if (date_value < 0 || date_value > 59)
  190.         goto error;
  191.     if (octstr_parse_long(&date_value, date, 17, 10) < 0)
  192.         goto error;
  193.     return date;
  194. error:
  195.     warning(0, "parse_date: not an ISO date");
  196.     return NULL;
  197. }
  198. /*****************************************************************************
  199.  *
  200.  * Split an SMS message into smaller ones.
  201.  */
  202. static void prepend_catenation_udh(Msg *sms, int part_no, int num_messages,
  203.                        int msg_sequence)
  204. {
  205.     if (sms->sms.udhdata == NULL)
  206.         sms->sms.udhdata = octstr_create("");
  207.     if (octstr_len(sms->sms.udhdata) == 0)
  208. octstr_append_char(sms->sms.udhdata, CATENATE_UDH_LEN);
  209.     octstr_format_append(sms->sms.udhdata, "%c3%c%c%c", 
  210.                 0, msg_sequence, num_messages, part_no);
  211.     /* 
  212.      * Now that we added the concatenation information the
  213.      * length is all wrong. we need to recalculate it. 
  214.      */
  215.     octstr_set_char(sms->sms.udhdata, 0, octstr_len(sms->sms.udhdata) - 1 );
  216. }
  217. static Octstr *extract_msgdata_part(Octstr *msgdata, Octstr *split_chars,
  218.                         int max_part_len)
  219. {
  220.     long i, len;
  221.     Octstr *part;
  222.     len = max_part_len;
  223.     if (split_chars != NULL)
  224. for (i = max_part_len; i > 0; i--)
  225.     if (octstr_search_char(split_chars,
  226.    octstr_get_char(msgdata, i - 1), 0) != -1) {
  227. len = i;
  228. break;
  229.     }
  230.     part = octstr_copy(msgdata, 0, len);
  231.     octstr_delete(msgdata, 0, len);
  232.     return part;
  233. }
  234. static Octstr *extract_msgdata_part_by_coding(Msg *msg, Octstr *split_chars,
  235.   int max_part_len)
  236. {
  237. Octstr *temp = NULL;
  238. int pos, esc_count;
  239. if (msg->sms.coding == DC_8BIT || msg->sms.coding == DC_UCS2) {
  240.         /* nothing to do here, just call the original extract_msgdata_part */
  241. return extract_msgdata_part(msg->sms.msgdata, split_chars, max_part_len);
  242. }
  243. /* 
  244.      * else we need to do something special. I'll just get charset_gsm_truncate to
  245.      * cut the string to the required length and then count real characters. 
  246.      */
  247. temp = octstr_duplicate(msg->sms.msgdata);
  248. charset_latin1_to_gsm(temp);
  249. charset_gsm_truncate(temp, max_part_len);
  250. pos = esc_count = 0;
  251. while ((pos = octstr_search_char(temp, 27, pos)) != -1) {
  252. ++pos;
  253.      ++esc_count;
  254. }
  255. octstr_destroy(temp);
  256. /* now just call the original extract_msgdata_part with the new length */
  257. return extract_msgdata_part(msg->sms.msgdata, split_chars, max_part_len - esc_count);
  258. }
  259. List *sms_split(Msg *orig, Octstr *header, Octstr *footer, 
  260.        Octstr *nonlast_suffix, Octstr *split_chars, 
  261.        int catenate, unsigned long msg_sequence,
  262.                        int max_messages, int max_octets)
  263. {
  264.     long max_part_len, udh_len, hf_len, nlsuf_len;
  265.     unsigned long total_messages, msgno;
  266.     long last;
  267.     List *list;
  268.     Msg *part, *temp;
  269.     hf_len = octstr_len(header) + octstr_len(footer);
  270.     nlsuf_len = octstr_len(nonlast_suffix);
  271.     udh_len = octstr_len(orig->sms.udhdata);
  272.     /* First check whether the message is under one-part maximum */
  273.     if (orig->sms.coding == DC_8BIT || orig->sms.coding == DC_UCS2)
  274. max_part_len = max_octets - udh_len - hf_len;
  275.     else
  276. max_part_len = max_octets * 8 / 7 - (udh_len * 8 + 6) / 7 - hf_len;
  277.     if (sms_msgdata_len(orig) > max_part_len && catenate) {
  278. /* Change part length to take concatenation overhead into account */
  279. if (udh_len == 0)
  280.     udh_len = 1;  /* To add the udh total length octet */
  281. udh_len += CATENATE_UDH_LEN;
  282. if (orig->sms.coding == DC_8BIT || orig->sms.coding == DC_UCS2)
  283.     max_part_len = max_octets - udh_len - hf_len;
  284. else
  285.     max_part_len = max_octets * 8 / 7 - (udh_len * 8 + 6) / 7 - hf_len;
  286.     }
  287.     temp = msg_duplicate(orig);
  288.     msgno = 0;
  289.     list = list_create();
  290.     do {
  291. msgno++;
  292.          /* if its a DLR request message getting split, only ask DLR for the first one */
  293.         part = msg_duplicate(orig);
  294. if((msgno > 1) && (part->sms.dlr_mask))
  295.         {
  296.            octstr_destroy(part->sms.dlr_url);
  297.            part->sms.dlr_url = NULL;
  298.            part->sms.dlr_mask = 0;
  299.         }
  300. octstr_destroy(part->sms.msgdata);
  301. if (sms_msgdata_len(temp) <= max_part_len || msgno == max_messages) {
  302.     part->sms.msgdata = octstr_copy(temp->sms.msgdata, 0, max_part_len);
  303.     last = 1;
  304. }
  305. else {
  306.     part->sms.msgdata = extract_msgdata_part_by_coding(temp, split_chars,
  307.      max_part_len - nlsuf_len);
  308.     last = 0;
  309. }
  310. if (header)
  311.     octstr_insert(part->sms.msgdata, header, 0);
  312. if (footer)
  313.     octstr_append(part->sms.msgdata, footer);
  314. if (!last && nonlast_suffix)
  315.     octstr_append(part->sms.msgdata, nonlast_suffix);
  316. list_append(list, part);
  317.     } while (!last);
  318.     total_messages = msgno;
  319.     msg_destroy(temp);
  320.     if (catenate && total_messages > 1) {
  321.         for (msgno = 1; msgno <= total_messages; msgno++) {
  322.     part = list_get(list, msgno - 1);
  323.     prepend_catenation_udh(part, msgno, total_messages, msg_sequence);
  324.         }
  325.     }
  326.     return list;
  327. }