📄 ucp.c
字号:
/* -*- mode: c; mode: fold -*- */# include "config.h"# include <stdlib.h># include <string.h># include <time.h># include "pager.h"/*{{{ typedefs */typedef struct {# ifndef NDEBUG# define MAGIC MKMAGIC ('u', 'c', 'p', '\0') long magic;# endif /* NDEBUG */ void *sp; /* the serial connection */ void *ctab; /* the conversion table */ void (*logger) (char, char *, ...); char *uline; /* received input line */ string_t *callid; /* caller id */ Bool xtend; /* use extended UCP version */ int send_tout; /* timeout during sending */ int send_retry; /* # of retries to send a message */ int rds_tout; /* timeout for status report */ date_t delay; /* delay message */ date_t expire; /* expire message */ Bool rds; /* request delivery status */ int cnr; /* current transaction number */} ucp;typedef struct { char *AdC; char *OAdC; char *PID; char *na; char *MT; char *Msg; char *adc; char *oadc; int pid; int mt; string_t *msg;} bsimple;typedef struct { char *AdC; char *OAdC; char *AC; char *NRq; char *NAdC; char *NT; char *NPID; char *na1; char *na2; char *na3; char *DD; char *DDT; char *VP; char *RPID; char *SCTS; char *DSt; char *Rsn; char *DSCTS; char *MT; char *NB; char *Msg; char *MMS; char *na4; char *DCS; char *MCL; char *RPI; char *na5; char *na6; char *res1; char *res2; char *res3; char *res4; char *res5; char *adc; char *oadc; char *ac; Bool nrq; char *nadc; int nt; int npid; Bool dd; date_t ddt; date_t vp; int rpid; date_t scts; int dst; int rsn; date_t dscts; int mt; int nb; string_t *msg; Bool mms; Bool dcs; int mcl; int rpi;} bextend;typedef struct { char *Res; char *MVP; char *EC; char *MSG; Bool ack; date_t mvp; int ec; char *adc; date_t scts;} banswer;typedef struct { int trn; int len; char ttyp; int ot; char *data; int cnt; union { bsimple s; bextend e; banswer a; } b; int chksum;} frame;/*}}}*//*{{{ support routines */static char_thex (int val){ switch (val) { default: case 0: return (char_t) '0'; case 1: return (char_t) '1'; case 2: return (char_t) '2'; case 3: return (char_t) '3'; case 4: return (char_t) '4'; case 5: return (char_t) '5'; case 6: return (char_t) '6'; case 7: return (char_t) '7'; case 8: return (char_t) '8'; case 9: return (char_t) '9'; case 10: return (char_t) 'A'; case 11: return (char_t) 'B'; case 12: return (char_t) 'C'; case 13: return (char_t) 'D'; case 14: return (char_t) 'E'; case 15: return (char_t) 'F'; }}static intunhex (char ch){ switch (ch) { default: case '0': return 0; case '1': return 1; case '2': return 2; case '3': return 3; case '4': return 4; case '5': return 5; case '6': return 6; case '7': return 7; case '8': return 8; case '9': return 9; case 'A': case 'a': return 10; case 'B': case 'b': return 11; case 'C': case 'c': return 12; case 'D': case 'd': return 13; case 'E': case 'e': return 14; case 'F': case 'f': return 15; }}/*}}}*//*{{{ frame basics */static frame *new_frame (char ttyp, int ot){ frame *f; bsimple *s; bextend *e; banswer *a; if (f = (frame *) malloc (sizeof (frame))) { f -> trn = 0; f -> len = 0; f -> ttyp = ttyp; f -> ot = ot; f -> data = NULL; f -> cnt = 0; memset (& f -> b, 0, sizeof (f -> b)); f -> chksum = 0; if (f -> ttyp == 'R') switch (f -> ot) { case 1: case 31: case 51: case 52: case 53: case 55: case 56: case 57: case 58: a = & f -> b.a; a -> Res = NULL; a -> MVP = NULL; a -> EC = NULL; a -> MSG = NULL; a -> ack = False; dat_clear (& a -> mvp); a -> ec = -1; a -> adc = NULL; dat_clear (& a -> scts); break; } else if (f -> ttyp == 'O') switch (f -> ot) { case 1: case 31: s = & f -> b.s; s -> AdC = NULL; s -> OAdC = NULL; s -> PID = NULL; s -> na = NULL; s -> MT = NULL; s -> Msg = NULL; s -> adc = NULL; s -> oadc = NULL; s -> pid = -1; s -> mt = -1; s -> msg = NULL; break; case 51: case 52: case 53: case 55: case 56: case 57: case 58: e = & f -> b.e; e -> AdC = NULL; e -> OAdC = NULL; e -> AC = NULL; e -> NRq = NULL; e -> NAdC = NULL; e -> NT = NULL; e -> NPID = NULL; e -> na1 = NULL; e -> na2 = NULL; e -> na3 = NULL; e -> DD = NULL; e -> DDT = NULL; e -> VP = NULL; e -> RPID = NULL; e -> SCTS = NULL; e -> DSt = NULL; e -> Rsn = NULL; e -> DSCTS = NULL; e -> MT = NULL; e -> NB = NULL; e -> Msg = NULL; e -> MMS = NULL; e -> na4 = NULL; e -> DCS = NULL; e -> MCL = NULL; e -> RPI = NULL; e -> na5 = NULL; e -> na6 = NULL; e -> res1 = NULL; e -> res2 = NULL; e -> res3 = NULL; e -> res4 = NULL; e -> res5 = NULL; e -> adc = NULL; e -> oadc = NULL; e -> ac = NULL; e -> nrq = False; e -> nadc = NULL; e -> nt = -1; e -> npid = -1; e -> dd = False; dat_clear (& e -> ddt); dat_clear (& e -> vp); e -> rpid = -1; dat_clear (& e -> scts); e -> dst = -1; e -> rsn = -1; dat_clear (& e -> dscts); e -> mt = -1; e -> nb = -1; e -> msg = NULL; e -> mms = False; e -> dcs = False; e -> mcl = -1; e -> rpi = -1; break; } } return f;}static voidfree_body (frame *f){# define dfr(xxx) if (xxx) free (xxx) bsimple *s; bextend *e; banswer *a; s = NULL; e = NULL; a = NULL; if (f -> ttyp == 'O') switch (f -> ot) { case 1: case 31: s = & f -> b.s; break; case 51: case 52: case 53: case 55: case 56: case 57: case 58: e = & f -> b.e; break; } else if (f -> ttyp == 'R') switch (f -> ot) { case 1: case 31: case 51: case 52: case 53: case 55: case 56: case 57: case 58: a = & f -> b.a; break; } if (s) { dfr (s -> AdC); dfr (s -> OAdC); dfr (s -> PID); dfr (s -> na); dfr (s -> MT); dfr (s -> Msg); dfr (s -> adc); dfr (s -> oadc); sfree (s -> msg); } else if (e) { dfr (e -> AdC); dfr (e -> OAdC); dfr (e -> AC); dfr (e -> NRq); dfr (e -> NAdC); dfr (e -> NT); dfr (e -> NPID); dfr (e -> na1); dfr (e -> na2); dfr (e -> na3); dfr (e -> DD); dfr (e -> DDT); dfr (e -> VP); dfr (e -> RPID); dfr (e -> SCTS); dfr (e -> DSt); dfr (e -> Rsn); dfr (e -> DSCTS); dfr (e -> MT); dfr (e -> NB); dfr (e -> Msg); dfr (e -> MMS); dfr (e -> na4); dfr (e -> DCS); dfr (e -> MCL); dfr (e -> RPI); dfr (e -> na5); dfr (e -> na6); dfr (e -> res1); dfr (e -> res2); dfr (e -> res3); dfr (e -> res4); dfr (e -> res5); dfr (e -> adc); dfr (e -> oadc); dfr (e -> ac); dfr (e -> nadc); sfree (e -> msg); } else if (a) { dfr (a -> Res); dfr (a -> MVP); dfr (a -> EC); dfr (a -> MSG); dfr (a -> adc); }# undef dfr } static voidfree_frame (frame *f){ if (f) { if (f -> data) free (f -> data); free_body (f); free (f); }}/*}}}*//*{{{ assemble */static char *encode (ucp *u, string_t *s, Bool docv){ char *ret; char_t ch; int c; int len; int n, m; len = s ? (s -> len * 2) : 0; if (ret = malloc (len + 2)) { for (n = 0, m = 0; n < len; ++m) { if (docv) { if ((c = cv_conv (u -> ctab, s -> str[m])) < 0) continue; ch = (char_t) c; } else ch = s -> str[m]; ret[n++] = hex ((ch >> 4) & 0xf); ret[n++] = hex (ch & 0xf); } ret[n] = '\0'; } return ret;}static inline voidgbool (char **ptr, Bool what, char *t, char *f){ if (*ptr) free (*ptr); if (what) *ptr = t ? strdup (t) : NULL; else *ptr = f ? strdup (f) : NULL;}static inline voidgdate (char **ptr, date_t *d, int len){ if (*ptr) free (*ptr); if (d -> day > 0) { if (*ptr = malloc (14)) { sprintf (*ptr, "%02d%02d%02d%02d%02d%02d", d -> day, d -> mon, d -> year % 100, d -> hour, d -> min, d -> sec); if (len < 12) (*ptr)[len] = '\0'; } } else *ptr = NULL;}static inline voidgint (char **ptr, int val, char *fmt, int def){ if (*ptr) free (*ptr); if (val == -1) val = def; if (val != -1) { if (*ptr = malloc (32)) sprintf (*ptr, (fmt ? fmt : "%d"), val); } else *ptr = NULL;}static inline voidgstr (char **ptr, char *str){ if (*ptr) free (*ptr); *ptr = str ? strdup (str) : NULL;}static string_t *assemble_frame (ucp *u, frame *f){ bsimple *s; bextend *e; banswer *a; string_t *ret; Bool fail; char buf[64], *ptr; int len, n; unsigned long chk; if (! (ret = snew (NULL, 128))) return NULL; if (! (scopyc (ret, "\x02") && scatc (ret, "00/00000/"))) return sfree (ret); sprintf (buf, "%c/%02d/", f -> ttyp, f -> ot); if (! scatc (ret, buf)) return sfree (ret); fail = False; if (f -> ttyp == 'R') { a = & f -> b.a; switch (f -> ot) { default: fail = True; break; case 1: case 31: case 51: case 52: case 53: case 55: case 56: case 57: case 58: gbool (& a -> Res, a -> ack, "A", "N"); if (a -> MSG) { free (a -> MSG); a -> MSG = NULL; } if (a -> ack) { gdate (& a -> MVP, & a -> mvp, 10); ptr = NULL; gdate (& ptr, & a -> scts, 12); if (ptr) { if (a -> adc) { if (a -> MSG = malloc (strlen (ptr) + strlen (a -> adc) + 4)) sprintf (a -> MSG, "%s:%s", a -> adc, ptr); free (ptr); } else a -> MSG = ptr; } else if (a -> adc) a -> MSG = strdup (a -> adc); } else gint (& a -> EC, a -> ec, NULL, 3); if (((f -> ot == 1) || (f -> ot == 31)) && a -> ack) { if (! (scatc (ret, a -> Res) && scatc (ret, "/") && scatc (ret, a -> MSG) && scatc (ret, "/"))) fail = True; } else if (! (scatc (ret, a -> Res) && scatc (ret, "/") && scatc (ret, (a -> ack ? a -> MVP : a -> EC)) && scatc (ret, "/") && scatc (ret, a -> MSG) && scatc (ret, "/"))) fail = True; break; } } else if (f -> ttyp == 'O') { s = & f -> b.s; e = & f -> b.e; switch (f -> ot) { default: fail = True; break; case 1: gstr (& s -> AdC, s -> adc); gstr (& s -> OAdC, s -> oadc); gstr (& s -> na, NULL); gint (& s -> MT, s -> mt, NULL, 3); if (s -> Msg) free (s -> Msg); s -> Msg = encode (u, s -> msg, True); if (! (scatc (ret, s -> AdC) && scatc (ret, "/") && scatc (ret, s -> OAdC) && scatc (ret, "/") && scatc (ret, s -> na) && scatc (ret, "/") && scatc (ret, s -> MT) && scatc (ret, "/") && scatc (ret, s -> Msg) && scatc (ret, "/"))) fail = True; break; case 31: gstr (& s -> AdC, s -> adc); gint (& s -> PID, s -> pid, "%04d", -1); if (! (scatc (ret, s -> AdC) && scatc (ret, "/") && scatc (ret, s -> PID) && scatc (ret, "/"))) fail = True; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -