/* * Interface to Anytone D868UV. * * Copyright (C) 2018 Serge Vakulenko, KK6ABQ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include "radio.h" #include "util.h" #define NCHAN 4000 #define NCONTACTS 10000 #define NZONES 250 #define NGLISTS 250 #define NSCANL 250 #define NMESSAGES 100 #define MEMSZ 0x10000 //#define MEMSZ 0x4300000 // // Print a generic information about the device. // static void d868uv_print_version(radio_device_t *radio, FILE *out) { //TODO #if 0 unsigned char *timestamp = GET_TIMESTAMP(); static const char charmap[16] = "0123456789:;<=>?"; if (*timestamp != 0xff) { fprintf(out, "Last Programmed Date: %d%d%d%d-%d%d-%d%d", timestamp[0] >> 4, timestamp[0] & 15, timestamp[1] >> 4, timestamp[1] & 15, timestamp[2] >> 4, timestamp[2] & 15, timestamp[3] >> 4, timestamp[3] & 15); fprintf(out, " %d%d:%d%d:%d%d\n", timestamp[4] >> 4, timestamp[4] & 15, timestamp[5] >> 4, timestamp[5] & 15, timestamp[6] >> 4, timestamp[6] & 15); fprintf(out, "CPS Software Version: V%c%c.%c%c\n", charmap[timestamp[7] & 15], charmap[timestamp[8] & 15], charmap[timestamp[9] & 15], charmap[timestamp[10] & 15]); } #endif } // // Read memory image from the device. // static void d868uv_download(radio_device_t *radio) { int addr; for (addr = 0x00000000; addr < MEMSZ; addr += 1024) { serial_read_region(addr, &radio_mem[addr], 1024); ++radio_progress; if (radio_progress % 32 == 0) { fprintf(stderr, "#"); fflush(stderr); } } } // // Write memory image to the device. // static void d868uv_upload(radio_device_t *radio, int cont_flag) { //TODO #if 0 int bno; for (bno=0; bnoscan_list_index != 0) { scanlist_t *sl = GET_SCANLIST(ch->scan_list_index - 1); if (!VALID_SCANLIST(sl)) { fprintf(stderr, "Channel %d '", i+1); print_unicode(stderr, ch->name, 16, 0); fprintf(stderr, "': scanlist %d not found.\n", ch->scan_list_index); nerrors++; } } if (ch->contact_name_index != 0) { contact_t *ct = GET_CONTACT(ch->contact_name_index - 1); if (!VALID_CONTACT(ct)) { fprintf(stderr, "Channel %d '", i+1); print_unicode(stderr, ch->name, 16, 0); fprintf(stderr, "': contact %d not found.\n", ch->contact_name_index); nerrors++; } } if (ch->group_list_index != 0) { grouplist_t *gl = GET_GROUPLIST(ch->group_list_index - 1); if (!VALID_GROUPLIST(gl)) { fprintf(stderr, "Channel %d '", i+1); print_unicode(stderr, ch->name, 16, 0); fprintf(stderr, "': grouplist %d not found.\n", ch->group_list_index); nerrors++; } } } // Zones: check references to channels. for (i=0; imember_a[k]; if (cnum != 0) { channel_t *ch = GET_CHANNEL(cnum - 1); if (!VALID_CHANNEL(ch)) { fprintf(stderr, "Zone %da '", i+1); print_unicode(stderr, z->name, 16, 0); fprintf(stderr, "': channel %d not found.\n", cnum); nerrors++; } } } for (k=0; k<48; k++) { int cnum = zext->ext_a[k]; if (cnum != 0) { channel_t *ch = GET_CHANNEL(cnum - 1); if (!VALID_CHANNEL(ch)) { fprintf(stderr, "Zone %da '", i+1); print_unicode(stderr, z->name, 16, 0); fprintf(stderr, "': channel %d not found.\n", cnum); nerrors++; } } } // Zone B for (k=0; k<64; k++) { int cnum = zext->member_b[k]; if (cnum != 0) { channel_t *ch = GET_CHANNEL(cnum - 1); if (!VALID_CHANNEL(ch)) { fprintf(stderr, "Zone %db '", i+1); print_unicode(stderr, z->name, 16, 0); fprintf(stderr, "': channel %d not found.\n", cnum); nerrors++; } } } } // Scanlists: check references to channels. for (i=0; imember[k]; if (cnum != 0) { channel_t *ch = GET_CHANNEL(cnum - 1); if (!VALID_CHANNEL(ch)) { fprintf(stderr, "Scanlist %d '", i+1); print_unicode(stderr, sl->name, 16, 0); fprintf(stderr, "': channel %d not found.\n", cnum); nerrors++; } } } } // Grouplists: check references to contacts. for (i=0; imember[k]; if (cnum != 0) { contact_t *ct = GET_CONTACT(cnum - 1); if (!VALID_CONTACT(ct)) { fprintf(stderr, "Grouplist %d '", i+1); print_unicode(stderr, gl->name, 16, 0); fprintf(stderr, "': contact %d not found.\n", cnum); nerrors++; } } } } // Count contacts. for (i=0; i 0) { fprintf(stderr, "Total %d errors.\n", nerrors); return 0; } fprintf(stderr, "Total %d channels, %d zones, %d scanlists, %d contacts, %d grouplists.\n", nchannels, nzones, nscanlists, ncontacts, ngrouplists); #endif return 1; } // // TYT MD-UV380 // radio_device_t radio_d868uv = { "Anytone AT-D868UV", d868uv_download, d868uv_upload, d868uv_is_compatible, d868uv_read_image, d868uv_save_image, d868uv_print_version, d868uv_print_config, d868uv_verify_config, d868uv_parse_parameter, d868uv_parse_header, d868uv_parse_row, d868uv_update_timestamp, //d868uv_write_csv, };