/** * \brief Command result formatting and printing. * * Prints out on device fd the values contained * in the array result, using the format specified * in fmt. * * \param ch Channel handle. * \param fmt Values format string. * \param result Array containing result to be printed. * * \return -1 in case of errors, otherwise 0. */ static int printResult(KFile *ch, const char *fmt, parms result[]) { long n; char repeat_cnt = 0; while (*fmt) { if (*fmt >= '0' && *fmt <= '9') { /* Collect repeat count digit (left to right order) */ repeat_cnt = (repeat_cnt * 10) + (*fmt - '0'); } else { /* Set default repeat cnt of 1 when not specified */ if (repeat_cnt == 0) repeat_cnt = 1; /* Loop repeat_cnt times */ do { switch (*fmt) { case 'd': kfile_printf(ch, ARG_SEP_S "%ld", (*result).l); result++; break; case 'c': kfile_print(ch, ARG_SEP_S); kfile_print(ch, (*result).s); result++; break; case 's': kfile_printf(ch, ARG_SEP_S "%s", (*result).s); result++; break; case 'n': n = (*result++).l; kfile_printf(ch, ARG_SEP_S "%ld", n); while (n--) { kfile_printf(ch, ARG_SEP_S "%ld", (*result).l); result++; } break; default: break; } } while (--repeat_cnt); } /* Skip to next format char */ ++fmt; } /* while (*fmt) */ kfile_print(ch, "\r\n"); return 0; }
/** * Read a line long at most as size and put it * in buf, with optional echo. * * \return number of chars read, or EOF in case * of error. */ int kfile_gets_echo(struct KFile *fd, char *buf, int size, bool echo) { int i = 0; int c; for (;;) { if ((c = kfile_getc(fd)) == EOF) { buf[i] = '\0'; return -1; } /* FIXME */ if (c == '\r' || c == '\n' || i >= size-1) { buf[i] = '\0'; if (echo) kfile_print(fd, "\r\n"); break; } buf[i++] = c; if (echo) kfile_putc(c, fd); } return i; }
static void protocol_parse(KFile *fd, const char *buf) { const struct CmdTemplate *templ; /* Command check. */ templ = parser_get_cmd_template(buf); if (!templ) { kfile_print(fd, "-1 Invalid command.\r\n"); protocol_prompt(fd); return; } parms args[PARSER_MAX_ARGS]; /* Args Check. TODO: Handle different case. see doc/PROTOCOL . */ if (!parser_get_cmd_arguments(buf, templ, args)) { kfile_print(fd, "-2 Invalid arguments.\r\n"); protocol_prompt(fd); return; } /* Execute. */ if(!parser_execute_cmd(templ, args)) { NAK(fd, "Error in executing command."); } if (!protocol_reply(fd, templ, args)) { NAK(fd, "Invalid return format."); } protocol_prompt(fd); return; }
static bool cmd_settings_beacon_text(Serial* pSer, char* value, size_t valueLen) { if(valueLen > 0) { // set the beacon text settings_set_beacon_text(value,valueLen); //SERIAL_PRINT_P(pSer, "OK\n\r"); //return true; } #define DEBUG_BEACON_TEXT 1 #if DEBUG_BEACON_TEXT #define BUF_LEN SETTINGS_BEACON_TEXT_MAX + 4 char buf[BUF_LEN]; buf[0] = '>'; uint8_t bytesRead = settings_get_beacon_text(buf+1,BUF_LEN - 4); buf[bytesRead + 1] = '\n'; buf[bytesRead+2] = '\r'; buf[bytesRead+3] = 0; kfile_print((&(pSer->fd)),buf); uint16_t free = freeRam(); SERIAL_PRINTF_P(pSer, PSTR("free mem: %d\n\r"),free) #endif return true; }
static void protocol_prompt(KFile *fd) { kfile_print(fd, ">> "); }
/* * Print on console the message that we have received. */ static void message_callback(struct AX25Msg *msg) { int i, k; static AX25Call tmp_path[AX25_MAX_RPT + 2]; static uint8_t tmp_path_size; static const char* relay_calls[] = {"RELAY\x0", "WIDE\x0\x0", "TRACE\x0", 0}; #if 1 kfile_printf(&ser.fd, "\n\nSRC[%.6s-%d], DST[%.6s-%d]\r\n", msg->src.call, msg->src.ssid, msg->dst.call, msg->dst.ssid); for (i = 0; i < msg->rpt_cnt; i++) kfile_printf(&ser.fd, "via: [%.6s-%d%s]\r\n", msg->rpt_lst[i].call, msg->rpt_lst[i].ssid, msg->rpt_lst[i].h_bit?"*":""); kfile_printf(&ser.fd, "DATA: %.*s\r\n", msg->len, msg->info); #endif if (1) { uint8_t repeat = 0; uint8_t is_wide = 0, is_trace = 0; msg->dst.ssid = 0; msg->dst.h_bit = 0; memcpy(msg->dst.call, CALL_BERTOS_APRS, 6); tmp_path[0] = msg->dst; tmp_path[1] = msg->src; for (i = 0; i < msg->rpt_cnt; ++i) tmp_path[i + 2] = msg->rpt_lst[i]; tmp_path_size = 2 + msg->rpt_cnt; /* Should we repeat the packet? * http://wa8lmf.net/DigiPaths/ */ /* * This works as follows: for every call on the repeaters list from first to last, find the first * call with the H bit (has-been-repeated) set to false. If this call is RELAY, WIDE or TRACE then * we sould repeat the packet. */ for (i = 2; i < tmp_path_size; ++i) { if (!tmp_path[i].h_bit) { AX25Call* c = &tmp_path[i]; if ((memcmp(tmp_path[i].call, MYCALL, 6) == 0) && (tmp_path[i].ssid == MYCALL_SSID)) { repeat = 0; break; } for (k=0; relay_calls[k]; ++k) { if (memcmp(relay_calls[k], c->call, 6) == 0) { repeat = 1; tmp_path[i].h_bit = 1; break; } } if (repeat) break; if (tmp_path[i].ssid > 0) { is_wide = memcmp("WIDE", c->call, 4) == 0; is_trace = memcmp("TRACE", c->call, 5) == 0; if (is_wide || is_trace) { repeat = 1; tmp_path[i].ssid--; if (tmp_path[i].ssid == 0) tmp_path[i].h_bit = 1; /* Add the Digi Call to the path*/ if (is_trace && (tmp_path_size < (AX25_MAX_RPT + 2))) { for (k = tmp_path_size; k > i; --k) { tmp_path[k] = tmp_path[k - 1]; } memcpy(tmp_path[i].call, MYCALL, 6); tmp_path[i].ssid = MYCALL_SSID; tmp_path[i].h_bit = 1; tmp_path_size++; i++; } break; } } } else { if ((memcmp(tmp_path[i].call, MYCALL, 6) == 0) && (tmp_path[i].ssid == MYCALL_SSID)) { repeat = 1; tmp_path[i].h_bit = 1; break; } } } if ((memcmp(tmp_path[1].call, MYCALL, 6) == 0) && (tmp_path[i].ssid == MYCALL_SSID)) { repeat = 0; } if (repeat) { ax25_sendVia(&ax25, tmp_path, tmp_path_size, msg->info, msg->len); kfile_print(&ser.fd, "REPEATED\n"); } else { kfile_print(&ser.fd, "NOT REPEATED\n"); } } }