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

手机WAP编程

开发平台:

WINDOWS

  1. /*
  2.  * smsc_smasi.c - parse and generate SMASI PDUs
  3.  *
  4.  * Stipe Tolj <tolj@wapme-systems.de>
  5.  */
  6. #include <string.h>
  7. #include "smasi_pdu.h"
  8. static Octstr *decode_type(Octstr *os)
  9. {
  10.     long p1, p2;
  11.     Octstr *temp;
  12.     if ((p2 = octstr_search_char(os, ':', 0)) == -1)
  13.         return NULL;
  14.     if ((p1 = octstr_search_char(os, '!', 0)) != -1 && p1 < p2) {
  15.         p1++;
  16.     } else {
  17.         p1 = 0;
  18.     }
  19.     temp = octstr_copy(os, p1, p2 - p1);
  20.     return temp;
  21. }
  22. static Octstr *copy_until_coma(Octstr *os, long *pos)
  23. {
  24.     long nul;
  25.     Octstr *data;
  26.     nul = octstr_search_char(os, ',', *pos);
  27.     if (nul == -1) {
  28.         warning(0, "SMASI: Parameter without value or value not properly terminated: %s", octstr_get_cstr(os));
  29.         return NULL;
  30.     }
  31.     data = octstr_copy(os, *pos, nul - *pos);
  32.     *pos = nul + 1;
  33.     return data;
  34. }
  35. static Octstr *copy_until_assign(Octstr *os, long *pos) 
  36. {
  37.     long nul;
  38.     Octstr *data;
  39.     nul = octstr_search_char(os, '=', *pos);
  40.     if (nul == -1 && (octstr_len(os) - *pos) > 1) {
  41.         warning(0, "SMASI: Garbage at end of parameter list: %s", octstr_get_cstr(os));
  42.         *pos = octstr_len(os);
  43.         return NULL;
  44.     }
  45.     data = octstr_copy(os, *pos, nul - *pos);
  46.     *pos = nul + 1;
  47.     return data;
  48. }
  49. static void skip_until_after_colon(Octstr *os, long *pos) 
  50. {
  51.     long colon = octstr_search_char(os, ':', *pos);
  52.     if (colon == -1) warning(0, "SMASI: No colon after SMASI PDU name: %s", octstr_get_cstr(os));
  53.     *pos = colon + 1;
  54. }
  55. SMASI_PDU *smasi_pdu_create(unsigned long type) 
  56. {
  57.     SMASI_PDU *pdu;
  58.     pdu = gw_malloc(sizeof(*pdu));
  59.     pdu->type = type;
  60.     switch (type) {
  61.     #define NONTERMINATED(name) p->name = NULL;
  62.     #define COMATERMINATED(name) p->name = NULL;
  63.     #define PDU(name, id, fields) 
  64.         case id: { 
  65.         struct name *p = &pdu->u.name; 
  66.         pdu->type_name = #name; 
  67.         pdu->needs_hyphen = (id < SMASI_HYPHEN_ID ? 1 : 0); 
  68.         fields 
  69.     } break;
  70.     #include "smasi_pdu.def"
  71.     default:
  72.         warning(0, "Unknown SMASI_PDU type, internal error.");
  73.         gw_free(pdu);
  74.     return NULL;
  75.     }
  76.     return pdu;
  77. }
  78. void smasi_pdu_destroy(SMASI_PDU *pdu)
  79. {
  80.     if (pdu == NULL)
  81.         return;
  82.     switch (pdu->type) {
  83.     #define NONTERMINATED(name) octstr_destroy(p->name);
  84.     #define COMATERMINATED(name) octstr_destroy(p->name);
  85.     #define PDU(name, id, fields) 
  86.         case id: { struct name *p = &pdu->u.name; fields } break;
  87.     #include "smasi_pdu.def"
  88.     default:
  89.         error(0, "Unknown SMASI_PDU type, internal error while destroying.");
  90.     }
  91.     gw_free(pdu);
  92. }
  93. Octstr *smasi_pdu_pack(SMASI_PDU *pdu)
  94. {
  95.     Octstr *os;
  96.     Octstr *temp;
  97.     os = octstr_create("");
  98.     /*
  99.      * Fix lengths of octet string fields.
  100.      */
  101.     switch (pdu->type) {
  102.     #define NONTERMINATED(name) p = *(&p);
  103.     #define COMATERMINATED(name) p = *(&p);
  104.     #define PDU(name, id, fields) 
  105.         case id: { struct name *p = &pdu->u.name; fields } break;
  106.     #include "smasi_pdu.def"
  107.     default:
  108.         error(0, "Unknown SMASI_PDU type, internal error while packing.");
  109.     }
  110.     switch (pdu->type) {
  111.     #define NONTERMINATED(name) p = *(&p);
  112.     #define COMATERMINATED(name) 
  113.     if (p->name != NULL) { octstr_append_cstr(os, #name); 
  114.     octstr_append_char(os, '='); 
  115.     octstr_append(os, p->name); 
  116.     octstr_append_char(os, ','); }
  117.     #define PDU(name, id, fields) 
  118.         case id: { struct name *p = &pdu->u.name; fields } break;
  119.     #include "smasi_pdu.def"
  120.     default:
  121.         error(0, "Unknown SMASI_PDU type, internal error while packing.");
  122.     }
  123.     octstr_append_char(os, 'n');
  124.     temp = pdu->needs_hyphen ? octstr_create("!") : octstr_create("");
  125.     octstr_append_cstr(temp, pdu->type_name); 
  126.     octstr_append_char(temp, ':');
  127.     octstr_insert(os, temp, 0);
  128.     octstr_destroy(temp);
  129.     return os;
  130. }
  131. SMASI_PDU *smasi_pdu_unpack(Octstr *data_without_len)
  132. {
  133.     SMASI_PDU *pdu;
  134.     char *type_name;
  135.     Octstr *temp;
  136.     long pos;
  137.     unsigned long type = 0;
  138.     /* extract the PDU type identifier */
  139.     temp = decode_type(data_without_len);
  140.     type_name = (temp ? octstr_get_cstr(temp) : "");
  141.     if (strcmp(type_name, "dummy") == 0) type = 0;
  142.     #define NONTERMINATED(name) p = *(&p);
  143.     #define COMATERMINATED(name) p = *(&p);
  144.     #define PDU(name, id, fields) 
  145.     else if (strcmp(type_name, #name) == 0) type = id;
  146.     #include "smasi_pdu.def"
  147.     else warning(0, "unknown SMASI PDU type");
  148.     pdu = smasi_pdu_create(type);
  149.     if (pdu == NULL) return NULL;
  150.     pos = 0;
  151.     skip_until_after_colon(data_without_len, &pos);
  152.     switch (type) {
  153.     #define NONTERMINATED(name) p = *(&p);
  154.     #define COMATERMINATED(name) 
  155.                 if (octstr_str_compare(field_name, #name) == 0 && field_value != NULL) 
  156.                     p->name = octstr_duplicate(field_value);
  157.     #define PDU(name, id, fields) 
  158.         case id: { 
  159.             Octstr * field_name = NULL; 
  160.             Octstr * field_value = NULL; 
  161.             struct name *p = &pdu->u.name; 
  162.             while (pos < octstr_len(data_without_len)) { 
  163.                 field_name = copy_until_assign(data_without_len, &pos); 
  164.                 if (field_name == NULL) break; 
  165.                 field_value = copy_until_coma(data_without_len, &pos); 
  166.                 if (field_value == NULL) continue; 
  167.                 fields 
  168.                 octstr_destroy(field_name); 
  169.                 octstr_destroy(field_value); 
  170.             } 
  171.         } break;
  172.     #include "smasi_pdu.def"
  173.     default:
  174.         warning(0, "Unknown SMASI_PDU type, internal error while unpacking.");
  175.     }
  176.     octstr_destroy(temp);
  177.     return pdu;
  178. }
  179. void smasi_pdu_dump(SMASI_PDU *pdu)
  180. {
  181.     debug("sms.smasi", 0, "SMASI PDU %p dump:", (void *) pdu);
  182.     debug("sms.smasi", 0, "  type_name: %s", pdu->type_name);
  183.     switch (pdu->type) {
  184.     #define NONTERMINATED(name) p = *(&p);
  185.     #define COMATERMINATED(name) 
  186.     octstr_dump_short(p->name, 2, #name);
  187.     #define PDU(name, id, fields) 
  188.         case id: { struct name *p = &pdu->u.name; fields } break;
  189.     #include "smasi_pdu.def"
  190.     default:
  191.         warning(0, "Unknown SMASI_PDU type, internal error.");
  192.     break;
  193.     }
  194.     debug("sms.smasi", 0, "SMASI PDU dump ends.");
  195. }
  196. Octstr *smasi_pdu_read(Connection *conn)
  197. {
  198.     Octstr *line;
  199.     line = conn_read_line(conn);    /* read one line */
  200.     return line;
  201. }