10 #include "auproto-pic.h"
12 #define NMRA_MAX_NARGS 10
14 typedef struct ManualRetransmitNode ManualRetransmitNode;
15 struct ManualRetransmitNode {
16 ManualRetransmitNode *back, *next;
19 RetransmitUrgentNode rn;
22 #define bogus_volatile /*empty*/
26 #define bogus_volatile volatile
30 struct NmraParseEncodeCaller {
32 unsigned long arg[NMRA_MAX_NARGS];
36 static void ouack(const CmdInfo *ci) {
37 oprintf(UPO, "ack %s\n", ci->name);
40 unsigned long nmra_argnumber(NmraParseEncodeCaller *pec, int argi) {
41 return pec->arg[argi];
44 void nmra_problem(NmraParseEncodeCaller *pec, const char *problem) {
45 badcmd(pec->ps,problem);
49 static int cmd_nmra_command(ParseState *ps, PicInsn *pi) {
53 bogus_volatile int argc, checksum;
54 NmraParseEncodeCaller pec;
59 switch (ps->remain[0]) {
60 case '_': ps->remain++; return ps_needhextoend(ps, pi->d, &pi->l);
61 case '=': hex=1; checksum=1; break;
62 case ':': hex=1; checksum=0; break;
63 default: hex=0; checksum=1; break;
68 nmra.l= NMRA_PACKET_MAX - checksum;
69 if (!ps_needhextoend(ps, nmra.d, &nmra.l))
72 if (!ps_needword(ps)) return 0;
74 lcmdarg= ps->lthisword;
79 if (argc >= NMRA_MAX_NARGS) {
80 badcmd(ps,"far too many nmra args");
84 errno=0; pec.arg[argc++]= strtoul(ps->thisword, &ep, 0);
85 if (errno || ep != ps->thisword + ps->lthisword)
86 { badcmd(ps,"bad numeric argument for nmra"); return 0; }
91 nmra_parse_encode(&nmra, cmdarg,lcmdarg, argc, &pec);
94 nmra_addchecksum(&nmra);
96 nmra_encodeforpic(&nmra, pi);
100 static void cmd_nmra(ParseState *ps, const CmdInfo *ci) {
101 static struct { ManualRetransmitNode *head, *tail; } mrns;
104 ManualRetransmitNode *mrn=0;
105 void (*retrans)(RetransmitUrgentNode *urg, const Nmra *n)= 0;
108 if (ps->remain[0]=='*') retrans= retransmit_urgent_queue;
109 else if (ps->remain[0]=='%') retrans= retransmit_urgent_queue_relaxed;
116 mrname= ps->thisword+1;
117 lmrname= ps->lthisword-1;
120 !(mrn->lname == lmrname &&
121 !memcmp(mrn->name, mrname, lmrname));
124 retransmit_urgent_cancel(&mrn->rn);
126 mrn= mmalloc(sizeof(*mrn));
127 mrn->name= mmalloc(lmrname);
128 memcpy(mrn->name, mrname, lmrname);
135 badcmd(ps,"nmra must have slot to cancel or data to send");
144 pi= retrans ? &mrn->rn.pi : &pi_buf;
146 if (!cmd_nmra_command(ps, pi)) {
147 if (retrans) { free(mrn->name); free(mrn); }
152 retrans(&mrn->rn, 0);
158 static void cmd_noop(ParseState *ps, const CmdInfo *ci) {
162 static void cmd_pic(ParseState *ps, const CmdInfo *ci) {
163 const PicInsnInfo *pii;
167 if (ps->remain && ps->remain[0]=='=') {
170 if (!ps_needhextoend(ps, pi.d, &pi.l)) return;
172 pii= some_needword_lookup(ps,pic_command_infos,"pic command");
176 if (!ps_neednumber(ps, &arg, 0, (1L << pii->argbits) - 1,
177 "pic object number"))
182 if (!ps_neednoargs(ps))
184 enco_pic_pii(&pi, pii, arg);
186 serial_transmit(&pi);
190 const CmdInfo toplevel_cmds[]= {
192 { "nmra", cmd_nmra, },
193 { "noop", cmd_noop },