11 #define NMRA_MAX_NARGS 10
13 typedef struct ManualRetransmitNode ManualRetransmitNode;
14 struct ManualRetransmitNode {
15 ManualRetransmitNode *back, *next;
21 #define bogus_volatile /*empty*/
25 #define bogus_volatile volatile
29 struct NmraParseEncodeCaller {
31 unsigned long arg[NMRA_MAX_NARGS];
35 unsigned long nmra_argnumber(NmraParseEncodeCaller *pec, int argi) {
36 return pec->arg[argi];
39 void nmra_problem(NmraParseEncodeCaller *pec, const char *problem) {
40 badcmd(pec->ps,problem);
44 static int cmd_nmra_command(ParseState *ps, RetransmitNode *rn) {
48 bogus_volatile int argc, checksum;
49 NmraParseEncodeCaller pec;
54 switch (ps->remain[0]) {
55 case '_': ps->remain++; return ps_needhextoend(ps, rn->d, &rn->l);
56 case '=': hex=1; checksum=1; break;
57 case ':': hex=1; checksum=0; break;
58 default: hex=0; checksum=1; break;
63 nmra.l= NMRA_PACKET_MAX - checksum;
64 if (!ps_needhextoend(ps, nmra.d, &nmra.l))
67 if (!ps_needword(ps)) return 0;
69 lcmdarg= ps->lthisword;
74 if (argc >= NMRA_MAX_NARGS) {
75 badcmd(ps,"far too many nmra args");
79 errno=0; pec.arg[argc++]= strtoul(ps->thisword, &ep, 0);
80 if (errno || ep != ps->thisword + ps->lthisword)
81 { badcmd(ps,"bad numeric argument for nmra"); return 0; }
86 nmra_parse_encode(&nmra, cmdarg,lcmdarg, argc, &pec);
89 nmra_addchecksum(&nmra);
91 nmra_encodeforpic(&nmra, rn->d, &rn->l);
95 static void cmd_nmra(ParseState *ps, const CmdInfo *ci) {
96 static struct { ManualRetransmitNode *head, *tail; } mrns;
98 ManualRetransmitNode *mrn;
99 RetransmitNode *rn, rn_buf;
101 if (ps->remain && ps->remain[0]=='*') {
106 mrname= ps->thisword+1;
107 lmrname= ps->lthisword-1;
110 !(mrn->lname == lmrname &&
111 !memcmp(mrn->name, mrname, lmrname));
114 retransmit_cancel(&mrn->rn);
116 mrn= mmalloc(sizeof(*mrn));
117 mrn->name= mmalloc(lmrname);
118 memcpy(mrn->name, mrname, lmrname);
127 badcmd(ps,"nmra must have slot to cancel or data to send");
135 rn= mrn ? &mrn->rn : &rn_buf;
136 rn->l= sizeof(rn->d);
138 if (!cmd_nmra_command(ps, rn)) {
139 if (mrn) { free(mrn->name); free(mrn); }
144 retransmit_queue(&mrn->rn);
146 serial_transmit(rn->d, rn->l);
149 static void cmd_noop(ParseState *ps, const CmdInfo *ci) {
150 oprintf(&ps->cl->ch,"noop successful\n");
153 typedef struct PicCmdInfo PicCmdInfo;
160 static void cmd_pic(ParseState *ps, const CmdInfo *ci) {
161 if (!ps_needword(ps)) return;
164 const CmdInfo toplevel_cmds[]= {
166 { "nmra", cmd_nmra, },
167 { "noop", cmd_noop },