Implement codeplug read and write functions

Implemented remaining codeplug functions to read, write and insert
codeplug entries. Fix bugs in ui code. Add unit tests.

TG-428
pull/68/head
Niccolò Izzo 2022-04-04 19:43:21 +02:00 zatwierdzone przez Silvano Seva
rodzic dc250a25d6
commit ae12a2126a
14 zmienionych plików z 668 dodań i 75 usunięć

Wyświetl plik

@ -80,7 +80,7 @@ typedef struct
txColorCode : 4; //< Color code sent during transmission
uint8_t dmr_timeslot; //< DMR timeslot, either 1 or 2
uint16_t contactName_index; //< Index to retrieve contact from list
uint16_t contact_index; //< Index to retrieve contact from list
}
__attribute__((packed)) dmrInfo_t; // 4B
@ -152,7 +152,7 @@ typedef struct
uint8_t mode : 4, //< Channel operation mode
encr : 4; //< Encryption mode
uint8_t gps_mode; //< Channel GPS mode
uint16_t contactName_index; //< Index to retrieve data from contact list
uint16_t contact_index; //< Index to retrieve data from contact list
}
__attribute__((packed)) m17Info_t; // 5B
@ -203,8 +203,8 @@ typedef struct
uint8_t scanList_index; //< Scan List: None, ScanList1...250
uint8_t groupList_index; //< Group List: None, GroupList1...128
char name[CPS_STR_SIZE]; //< Channel name
char descr[CPS_STR_SIZE]; //< Description of the channel
char name[CPS_STR_SIZE]; //< Channel name
char descr[CPS_STR_SIZE]; //< Description of the channel
geo_t ch_location; //< Transmitter geolocation
union
@ -221,7 +221,7 @@ __attribute__((packed)) channel_t; // 59B
*/
typedef struct
{
char name[CPS_STR_SIZE]; //< Display name of the contact
char name[CPS_STR_SIZE]; //< Display name of the contact
uint8_t mode; //< Operating mode
union
@ -231,7 +231,7 @@ typedef struct
}
info; // 6B
}
__attribute__((packed)) contact_t; // 23B
__attribute__((packed)) contact_t; // 39B
/**
* Data structure describing a bank header.
@ -241,7 +241,7 @@ __attribute__((packed)) contact_t; // 23B
typedef struct
{
char name[CPS_STR_SIZE];
uint16_t ch_count; //< Count of all the channels in this bank
uint16_t ch_count; //< Count of all the channels in this bank
}
__attribute__((packed)) bankHdr_t; // 18B + 2 * ch_count
@ -255,17 +255,17 @@ __attribute__((packed)) bankHdr_t; // 18B + 2 * ch_count
*/
typedef struct
{
uint64_t magic; //< Magic number "RTXC"
uint16_t version_number; //< Version number for the cps structure
char author[CPS_STR_SIZE]; //< Author of the codeplug
char descr[CPS_STR_SIZE]; //< Description of the codeplug
uint64_t timestamp; //< unix timestamp of the codeplug
uint64_t magic; //< Magic number "RTXC"
uint16_t version_number; //< Version number for the cps structure
char author[CPS_STR_SIZE]; //< Author of the codeplug
char descr[CPS_STR_SIZE]; //< Description of the codeplug
uint64_t timestamp; //< unix timestamp of the codeplug
uint16_t ct_count; //< Number of stored contacts
uint16_t ch_count; //< Number of stored channels
uint16_t b_count; //< Number of stored banks
uint16_t ct_count; //< Number of stored contacts
uint16_t ch_count; //< Number of stored channels
uint16_t b_count; //< Number of stored banks
}
__attribute__((packed)) cps_header_t; // 52B
__attribute__((packed)) cps_header_t; // 88B
/**
* Create and return a viable channel for this radio.

Wyświetl plik

@ -60,7 +60,7 @@ int cps_create(char *cps_name);
* @param pos: position, inside the bank table, from which read data.
* @return 0 on success, -1 on failure
*/
int cps_readContactData(contact_t *contact, uint16_t pos);
int cps_readContact(contact_t *contact, uint16_t pos);
/**
* Read one channel entry from table stored in nonvolatile memory.
@ -69,7 +69,7 @@ int cps_readContactData(contact_t *contact, uint16_t pos);
* @param pos: position, inside the channel table, from which read data.
* @return 0 on success, -1 on failure
*/
int cps_readChannelData(channel_t *channel, uint16_t pos);
int cps_readChannel(channel_t *channel, uint16_t pos);
/**
* Read one bank header from the codeplug stored in the radio's filesystem.
@ -84,10 +84,121 @@ int cps_readBankHeader(bankHdr_t *b_header, uint16_t pos);
* Read one channel index from a bank of the codeplug stored in NVM.
*
* @param bank_pos: position of the bank inside the cps.
* @param ch_pos: position of the channel index inside the bank.
* @param pos: position of the channel index inside the bank.
* @return the retrieved channel index on success, -1 on failure
*/
int32_t cps_readBankData(uint16_t bank_pos, uint16_t ch_pos);
int32_t cps_readBankData(uint16_t bank_pos, uint16_t pos);
/**
* Overwrite one contact to the codeplug stored in nonvolatile memory.
*
* @param contact: data structure to be written.
* @param pos: position, inside the contact table, in which to insert data.
* @return 0 on success, -1 on failure
*/
int cps_writeContact(contact_t contact, uint16_t pos);
/**
* Overwrite one channel to the codeplug stored in nonvolatile memory.
*
* @param channel: data structure to be written.
* @param pos: position, inside the channel table, in which to insert data.
* @return 0 on success, -1 on failure
*/
int cps_writeChannel(channel_t channel, uint16_t pos);
/**
* Overwrite one bank header to the codeplug stored in nonvolatile memory.
*
* @param b_header: data structure to be written.
* @param pos: position, inside the bank table, in which to insert data.
* @return 0 on success, -1 on failure
*/
int cps_writeBankHeader(bankHdr_t b_header, uint16_t pos);
/**
* Write one channel index in a bank entry stored in the codeplug.
*
* @param ch: index of the new channel to be written
* @param bank_pos: index of the bank to be written.
* @param pos: position, inside the bank table, in which to write data.
* @return 0 on success, -1 on failure
*/
int cps_writeBankData(uint32_t ch, uint16_t bank_pos, uint16_t pos);
/**
* Insert one contact to the codeplug stored in nonvolatile memory,
* updating channels accordingly.
*
* @param contact: data structure to be written.
* @param pos: position, inside the contact table, in which to insert data.
* @return 0 on success, -1 on failure
*/
int cps_insertContact(contact_t contact, uint16_t pos);
/**
* Insert one channel to the codeplug stored in nonvolatile memory,
* updating banks accordingly.
*
* @param channel: data structure to be written.
* @param pos: position, inside the channel table, in which to insert data.
* @return 0 on success, -1 on failure
*/
int cps_insertChannel(channel_t channel, uint16_t pos);
/**
* Insert one bank header to the codeplug stored in nonvolatile memory.
*
* @param bank: data structure to be written.
* @param pos: position, inside the bank table, in which to insert data.
* @return 0 on success, -1 on failure
*/
int cps_insertBankHeader(bankHdr_t b_header, uint16_t pos);
/**
* Insert one channel index in a bank entry stored in the codeplug.
*
* @param ch: index of the new channel to be written
* @param bank_pos: index of the bank to be written.
* @param pos: position, inside the bank table, in which to insert data.
* @return 0 on success, -1 on failure
*/
int cps_insertBankData(uint32_t ch, uint16_t bank_pos, uint16_t pos);
/**
* Delete one contact to the codeplug stored in nonvolatile memory,
* updating channels accordingly.
*
* @param pos: position, inside the contact table, to delete
* @return 0 on success, -1 on failure
*/
int cps_deleteContact(uint16_t pos);
/**
* Delete one channel to the codeplug stored in nonvolatile memory,
* updating banks accordingly.
*
* @param pos: position, inside the channel table, to delete
* @return 0 on success, -1 on failure
*/
int cps_deleteChannel(channel_t channel, uint16_t pos);
/**
* Delete one bank header to the codeplug stored in nonvolatile memory.
*
* @param pos: position, inside the bank table, to delete
* @return 0 on success, -1 on failure
*/
int cps_deleteBankHeader(uint16_t pos);
/**
* Delete one bank entry to the codeplug stored in nonvolatile memory.
*
* @param bank_pos: index of the bank to be deleted
* @param pos: position, inside the bank table, to delete
* @return 0 on success, -1 on failure
*/
int cps_deleteBankData(uint16_t bank_pos, uint16_t pos);
#ifdef __cplusplus
}

Wyświetl plik

@ -3,6 +3,8 @@
#include <stdio.h>
#include <time.h>
#define CPS_CHUNK_SIZE 1024
static FILE *cps_file = NULL;
const char *default_author = "Codeplug author.";
const char *default_descr = "Codeplug description.";
@ -13,7 +15,8 @@ const char *default_descr = "Codeplug description.";
* @param header: pointer to the header struct to be populated
* @return 0 on success, -1 on failure
*/
bool _readHeader(cps_header_t *header) {
int _readHeader(cps_header_t *header)
{
fseek(cps_file, 0L, SEEK_SET);
fread(header, sizeof(cps_header_t), 1, cps_file);
// Validate magic number
@ -26,6 +29,19 @@ bool _readHeader(cps_header_t *header) {
return 0;
}
/**
* Internal: write codeplug header
*
* @param header: header struct to be written
* @return 0 on success, -1 on failure
*/
int _writeHeader(cps_header_t header)
{
fseek(cps_file, 0L, SEEK_SET);
fwrite(&header, sizeof(cps_header_t), 1, cps_file);
return 0;
}
/**
* Internal: push down data at a given offset by a given amount
*
@ -33,12 +49,122 @@ bool _readHeader(cps_header_t *header) {
* @param amount: amount of free space to be created
* @return 0 on success, -1 on failure
*/
int _pushDown(uint32_t offset, uint32_t amount) {
int _pushDown(uint32_t offset, uint32_t amount)
{
// Start from the end of the codeplug
cps_header_t header = { 0 };
if (_readHeader(&header))
return -1;
fseek(cps_file,
header.ct_count * sizeof(contact_t) +
header.ch_count * sizeof(channel_t),
SEEK_CUR);
// If banks are present skip those
if (header.b_count != 0) {
fseek(cps_file,
(header.b_count - 1) * sizeof(uint32_t),
SEEK_CUR);
uint32_t b_offset = 0;
bankHdr_t b_header = { 0 };
fread(&b_offset, sizeof(uint32_t), 1, cps_file);
fseek(cps_file, b_offset, SEEK_CUR);
fread(&b_header, sizeof(bankHdr_t), 1, cps_file);
fseek(cps_file, b_header.ch_count * sizeof(uint32_t), SEEK_CUR);
}
// Move data downwards in chunks of fixed size
long end = ftell(cps_file);
// If offset equals end, just return
if (offset == end)
return 0;
char buffer[CPS_CHUNK_SIZE] = { 0 };
for(int i = 1; i <= ((end - offset) / CPS_CHUNK_SIZE); i++)
{
fseek(cps_file, end - i * CPS_CHUNK_SIZE, SEEK_SET);
fread(buffer, CPS_CHUNK_SIZE, 1, cps_file);
fseek(cps_file, end - i * CPS_CHUNK_SIZE + amount, SEEK_SET);
fwrite(buffer, CPS_CHUNK_SIZE, 1, cps_file);
}
// Once initial offset is reached, move the last incomplete block
fseek(cps_file, offset, SEEK_SET);
fread(buffer, (end - offset) % CPS_CHUNK_SIZE, 1, cps_file);
fseek(cps_file, offset + amount, SEEK_SET);
fwrite(buffer, (end - offset) % CPS_CHUNK_SIZE, 1, cps_file);
fseek(cps_file, offset, SEEK_SET);
return 0;
}
int cps_open(char *cps_name) {
/**
* Internal: updates the contact numbering after a contact addition or removal
*
* @param pos: position at which the new contact was inserted or removed
* @param add: if true a contact was inserted, otherwise it was removed
* @return 0 on success, -1 on failure
*/
int _updateCtNumbering(uint16_t pos, bool add)
{
cps_header_t header = { 0 };
if (_readHeader(&header))
return -1;
for(int i = 0; i < header.ch_count; i++)
{
channel_t c = { 0 };
cps_readChannel(&c, i);
if (c.mode == OPMODE_M17 && c.m17.contact_index >= pos)
{
if (add)
c.m17.contact_index++;
else
c.m17.contact_index--;
cps_writeChannel(c, i);
}
if (c.mode == OPMODE_DMR && c.dmr.contact_index >= pos)
{
if (add)
c.dmr.contact_index++;
else
c.dmr.contact_index--;
cps_writeChannel(c, i);
}
}
return 0;
}
/**
* Internal: updates the channel numbering after a channel addition or removal
*
* @param pos: position at which the new channel was inserted or removed
* @param add: if true a channel was inserted, otherwise it was removed
* @return 0 on success, -1 on failure
*/
int _updateChNumbering(uint16_t pos, bool add)
{
cps_header_t header = { 0 };
if (_readHeader(&header))
return -1;
for(int i = 0; i < header.b_count; i++)
{
bankHdr_t b_header = { 0 };
cps_readBankHeader(&b_header, i);
for(int j = 0; j < b_header.ch_count; j++)
{
int32_t ch = cps_readBankData(i, j);
if (ch >= pos)
{
if (add)
ch++;
else
ch--;
cps_writeBankData(ch, i, j);
}
}
}
return 0;
}
int cps_open(char *cps_name)
{
if (!cps_name)
cps_name = "default.rtxc";
cps_file = fopen(cps_name, "r+");
@ -47,11 +173,13 @@ int cps_open(char *cps_name) {
return 0;
}
void cps_close() {
void cps_close()
{
fclose(cps_file);
}
int cps_create(char *cps_name) {
int cps_create(char *cps_name)
{
// Clear or create cps file
FILE *new_cps = NULL;
if (!cps_name)
@ -75,9 +203,10 @@ int cps_create(char *cps_name) {
return 0;
}
int cps_readContactData(contact_t *contact, uint16_t pos) {
int cps_readContact(contact_t *contact, uint16_t pos)
{
cps_header_t header = { 0 };
if (!_readHeader(&header))
if (_readHeader(&header))
return -1;
if (pos >= header.ct_count)
return -1;
@ -86,9 +215,10 @@ int cps_readContactData(contact_t *contact, uint16_t pos) {
return 0;
}
int cps_readChannelData(channel_t *channel, uint16_t pos) {
int cps_readChannel(channel_t *channel, uint16_t pos)
{
cps_header_t header = { 0 };
if (!_readHeader(&header))
if (_readHeader(&header))
return -1;
if (pos >= header.ch_count)
return -1;
@ -100,9 +230,10 @@ int cps_readChannelData(channel_t *channel, uint16_t pos) {
return 0;
}
int cps_readBankHeader(bankHdr_t *b_header, uint16_t pos) {
int cps_readBankHeader(bankHdr_t *b_header, uint16_t pos)
{
cps_header_t header = { 0 };
if (!_readHeader(&header))
if (_readHeader(&header))
return -1;
if (pos >= header.b_count)
return -1;
@ -113,14 +244,15 @@ int cps_readBankHeader(bankHdr_t *b_header, uint16_t pos) {
SEEK_CUR);
uint32_t offset = 0;
fread(&offset, sizeof(uint32_t), 1, cps_file);
fseek(cps_file, header.b_count - pos * sizeof(uint32_t) + offset, SEEK_CUR);
fseek(cps_file, (header.b_count - pos) * sizeof(uint32_t) + offset, SEEK_CUR);
fread(b_header, sizeof(bankHdr_t), 1, cps_file);
return 0;
}
uint32_t cps_readBankData(uint16_t bank_pos, uint16_t ch_pos) {
int32_t cps_readBankData(uint16_t bank_pos, uint16_t pos)
{
cps_header_t header = { 0 };
if (!_readHeader(&header))
if (_readHeader(&header))
return -1;
if (bank_pos >= header.b_count)
return -1;
@ -134,14 +266,195 @@ uint32_t cps_readBankData(uint16_t bank_pos, uint16_t ch_pos) {
fseek(cps_file, header.b_count - bank_pos * sizeof(uint32_t) + offset, SEEK_CUR);
bankHdr_t b_header = { 0 };
fread(&b_header, sizeof(bankHdr_t), 1, cps_file);
if (ch_pos >= b_header.ch_count)
if (pos >= b_header.ch_count)
return -1;
fseek(cps_file, ch_pos * sizeof(uint32_t), SEEK_CUR);
fseek(cps_file, pos * sizeof(uint32_t), SEEK_CUR);
uint32_t ch_index = 0;
fread(&ch_index, sizeof(uint32_t), 1, cps_file);
return ch_index;
}
int cps_writeContactData(contact_t contact, uint16_t pos) {
int cps_writeContact(contact_t contact, uint16_t pos)
{
cps_header_t header = { 0 };
if (_readHeader(&header))
return -1;
if (pos >= header.ct_count)
return -1;
fseek(cps_file, pos * sizeof(contact_t), SEEK_CUR);
fwrite(&contact, sizeof(contact_t), 1, cps_file);
return 0;
}
int cps_writeChannel(channel_t channel, uint16_t pos)
{
cps_header_t header = { 0 };
if (_readHeader(&header))
return -1;
if (pos >= header.ch_count)
return -1;
fseek(cps_file,
header.ct_count * sizeof(contact_t) +
pos * sizeof(channel_t),
SEEK_CUR);
fwrite(&channel, sizeof(channel_t), 1, cps_file);
return 0;
}
int cps_writeBankHeader(bankHdr_t b_header, uint16_t pos)
{
cps_header_t header = { 0 };
if (_readHeader(&header))
return -1;
if (pos >= header.b_count)
return -1;
fseek(cps_file,
header.ct_count * sizeof(contact_t) +
header.ch_count * sizeof(channel_t) +
pos * sizeof(uint32_t),
SEEK_CUR);
uint32_t offset = 0;
fread(&offset, sizeof(uint32_t), 1, cps_file);
fseek(cps_file, header.b_count - pos * sizeof(uint32_t) + offset, SEEK_CUR);
fwrite(&b_header, sizeof(bankHdr_t), 1, cps_file);
return 0;
}
int cps_writeBankData(uint32_t ch, uint16_t bank_pos, uint16_t pos)
{
cps_header_t header = { 0 };
if (_readHeader(&header))
return -1;
if (pos >= header.b_count + 1)
return -1;
fseek(cps_file,
header.ct_count * sizeof(contact_t) +
header.ch_count * sizeof(channel_t) +
bank_pos * sizeof(uint32_t),
SEEK_CUR);
uint32_t offset = 0;
fread(&offset, sizeof(uint32_t), 1, cps_file);
fseek(cps_file, header.b_count - bank_pos * sizeof(uint32_t) + offset, SEEK_CUR);
bankHdr_t b_header = { 0 };
fread(&b_header, sizeof(bankHdr_t), 1, cps_file);
if (pos >= b_header.ch_count)
return -1;
fseek(cps_file, pos * sizeof(uint32_t), SEEK_CUR);
fwrite(&ch, sizeof(uint32_t), 1, cps_file);
return 0;
}
int cps_insertContact(contact_t contact, uint16_t pos)
{
cps_header_t header = { 0 };
if (_readHeader(&header))
return -1;
if (pos >= header.ct_count + 1)
return -1;
long ct_pos = ftell(cps_file) + pos * sizeof(contact_t);
_pushDown(ct_pos, sizeof(contact_t));
fwrite(&contact, sizeof(contact_t), 1, cps_file);
header.ct_count++;
_writeHeader(header);
if (_updateCtNumbering(pos, true))
return -1;
return 0;
}
int cps_insertChannel(channel_t channel, uint16_t pos)
{
cps_header_t header = { 0 };
if (_readHeader(&header))
return -1;
if (pos >= header.ch_count + 1)
return -1;
long ch_pos = ftell(cps_file) +
header.ct_count * sizeof(contact_t) +
pos * sizeof(channel_t);
_pushDown(ch_pos, sizeof(channel_t));
fwrite(&channel, sizeof(channel_t), 1, cps_file);
header.ch_count++;
_writeHeader(header);
_updateChNumbering(pos, true);
return 0;
}
int cps_insertBankHeader(bankHdr_t b_header, uint16_t pos)
{
cps_header_t header = { 0 };
if (_readHeader(&header))
return -1;
if (pos >= header.b_count + 1)
return -1;
// Read old offset
uint32_t b_offset = 0;
fseek(cps_file,
header.ct_count * sizeof(contact_t) +
header.ch_count * sizeof(channel_t) +
pos * sizeof(uint32_t),
SEEK_CUR);
long b_offset_pos = ftell(cps_file);
fread(&b_offset, sizeof(uint32_t), 1, cps_file);
// Write new offset
_pushDown(b_offset_pos, sizeof(uint32_t));
fwrite(&b_offset, sizeof(uint32_t), 1, cps_file);
// Update all the offsets following the moved bank
for(int i = 0; i < header.b_count - pos; i++)
{
long p = ftell(cps_file);
uint32_t o = 0;
fread(&o, sizeof(uint32_t), 1, cps_file);
fseek(cps_file, p, SEEK_SET);
o += sizeof(bankHdr_t);
fwrite(&o, sizeof(uint32_t), 1, cps_file);
}
// Write new bank
fseek(cps_file, b_offset, SEEK_CUR);
long h_pos = ftell(cps_file);
_pushDown(h_pos, sizeof(bankHdr_t));
fwrite(&b_header, sizeof(bankHdr_t), 1, cps_file);
header.b_count++;
_writeHeader(header);
return 0;
}
int cps_insertBankData(uint32_t ch, uint16_t bank_pos, uint16_t pos)
{
cps_header_t header = { 0 };
if (_readHeader(&header))
return -1;
if (bank_pos >= header.b_count + 1)
return -1;
fseek(cps_file,
header.ct_count * sizeof(contact_t) +
header.ch_count * sizeof(channel_t) +
bank_pos * sizeof(uint32_t),
SEEK_CUR);
uint32_t offset = 0;
fread(&offset, sizeof(uint32_t), 1, cps_file);
// Update all the offsets following the moved bank
for(int i = 0; i < header.b_count - bank_pos - 1; i++)
{
long p = ftell(cps_file);
uint32_t o = 0;
fread(&o, sizeof(uint32_t), 1, cps_file);
fseek(cps_file, p, SEEK_SET);
o += sizeof(uint32_t);
fwrite(&o, sizeof(uint32_t), 1, cps_file);
}
// Update bank header
fseek(cps_file, offset, SEEK_CUR);
bankHdr_t b_header = { 0 };
long h_pos = ftell(cps_file);
fread(&b_header, sizeof(bankHdr_t), 1, cps_file);
if (pos >= b_header.ch_count + 1)
return -1;
b_header.ch_count++;
fseek(cps_file, h_pos, SEEK_SET);
fwrite(&b_header, sizeof(bankHdr_t), 1, cps_file);
fseek(cps_file, pos * sizeof(uint32_t), SEEK_CUR);
long p = ftell(cps_file);
_pushDown(p, sizeof(uint32_t));
fwrite(&ch, sizeof(uint32_t), 1, cps_file);
return 0;
}

Wyświetl plik

@ -551,7 +551,7 @@ int _ui_fsm_loadChannel(uint16_t channel_index, bool *sync_rtx) {
// Channel index is 1-based while bank array access is 0-based
channel_index = cps_readBankData(state.bank, channel_index);
}
int result = cps_readChannelData(&channel, channel_index);
int result = cps_readChannel(&channel, channel_index);
// Read successful and channel is valid
if(result != -1 && _ui_channel_valid(&channel))
{
@ -1312,19 +1312,19 @@ void ui_updateFSM(event_t event, bool *sync_rtx)
// manu_selected is 0-based
// bank 0 means "All Channel" mode
// banks (1, n) are mapped to banks (0, n-1)
if(cps_readBankHeader(&bank, ui_state.menu_selected + 1) != -1)
if(cps_readBankHeader(&bank, ui_state.menu_selected) != -1)
ui_state.menu_selected += 1;
}
else if(state.ui_screen == MENU_CHANNEL)
{
channel_t channel;
if(cps_readChannelData(&channel, ui_state.menu_selected + 1) != -1)
if(cps_readChannel(&channel, ui_state.menu_selected + 1) != -1)
ui_state.menu_selected += 1;
}
else if(state.ui_screen == MENU_CONTACTS)
{
contact_t contact;
if(cps_readContactData(&contact, ui_state.menu_selected + 1) != -1)
if(cps_readContact(&contact, ui_state.menu_selected + 1) != -1)
ui_state.menu_selected += 1;
}
}
@ -1359,7 +1359,7 @@ void ui_updateFSM(event_t event, bool *sync_rtx)
// If we were in VFO mode, save VFO channel
if(ui_state.last_main_state == MAIN_VFO)
state.vfo_channel = state.channel;
_ui_fsm_loadChannel(ui_state.menu_selected + 1, sync_rtx);
_ui_fsm_loadChannel(ui_state.menu_selected, sync_rtx);
// Switch to MEM screen
state.ui_screen = MAIN_MEM;
}

Wyświetl plik

@ -19,6 +19,7 @@
***************************************************************************/
#include <interfaces/platform.h>
#include <interfaces/cps_io.h>
#include <stdio.h>
#include <stdint.h>
#include <ui.h>

Wyświetl plik

@ -269,7 +269,7 @@ int _ui_getBankName(char *buf, uint8_t max_len, uint8_t index)
else
{
bankHdr_t bank;
result = cps_readBankHeader(&bank, index);
result = cps_readBankHeader(&bank, index - 1);
if(result != -1)
snprintf(buf, max_len, "%s", bank.name);
}
@ -279,7 +279,7 @@ int _ui_getBankName(char *buf, uint8_t max_len, uint8_t index)
int _ui_getChannelName(char *buf, uint8_t max_len, uint8_t index)
{
channel_t channel;
int result = cps_readChannelData(&channel, index + 1);
int result = cps_readChannel(&channel, index);
if(result != -1)
snprintf(buf, max_len, "%s", channel.name);
return result;
@ -288,7 +288,7 @@ int _ui_getChannelName(char *buf, uint8_t max_len, uint8_t index)
int _ui_getContactName(char *buf, uint8_t max_len, uint8_t index)
{
contact_t contact;
int result = cps_readContactData(&contact, index + 1);
int result = cps_readContact(&contact, index);
if(result != -1)
snprintf(buf, max_len, "%s", contact.name);
return result;

Wyświetl plik

@ -78,7 +78,7 @@ int cps_create(char *cps_name)
return 0;
}
int cps_readChannelData(channel_t *channel, uint16_t pos)
int cps_readChannel(channel_t *channel, uint16_t pos)
{
if(pos >= maxNumChannels)
return -1;
@ -185,7 +185,7 @@ int cps_readChannelData(channel_t *channel, uint16_t pos)
}
else if(channel->mode == OPMODE_DMR)
{
channel->dmr.contactName_index = chData.contact_name_index;
channel->dmr.contact_index = chData.contact_name_index;
channel->dmr.dmr_timeslot = chData.repeater_slot;
channel->dmr.rxColorCode = chData.colorcode_rx;
channel->dmr.txColorCode = chData.colorcode_tx;
@ -241,7 +241,7 @@ int32_t cps_readBankData(uint16_t bank_pos, uint16_t ch_pos)
return zoneData.member[ch_pos];
}
int cps_readContactData(contact_t *contact, uint16_t pos)
int cps_readContact(contact_t *contact, uint16_t pos)
{
if(pos >= maxNumContacts) return -1;

Wyświetl plik

@ -60,7 +60,7 @@ int cps_create(char *cps_name)
return 0;
}
int cps_readChannelData(channel_t *channel, uint16_t pos)
int cps_readChannel(channel_t *channel, uint16_t pos)
{
if(pos >= maxNumChannels) return -1;
@ -131,7 +131,7 @@ int cps_readChannelData(channel_t *channel, uint16_t pos)
}
else if(channel->mode == OPMODE_DMR)
{
channel->dmr.contactName_index = chData.contact_name_index;
channel->dmr.contact_index = chData.contact_name_index;
channel->dmr.dmr_timeslot = chData.repeater_slot;
channel->dmr.rxColorCode = chData.colorcode;
channel->dmr.txColorCode = chData.colorcode;
@ -189,7 +189,7 @@ int32_t cps_readBankData(uint16_t bank_pos, uint16_t ch_pos)
return zoneData.member[ch_pos] - 1;
}
int cps_readContactData(contact_t *contact, uint16_t pos)
int cps_readContact(contact_t *contact, uint16_t pos)
{
if(pos >= maxNumContacts) return -1;

Wyświetl plik

@ -121,7 +121,7 @@ static int _readChannelAtAddress(channel_t *channel, uint32_t addr)
}
else if(channel->mode == OPMODE_DMR)
{
channel->dmr.contactName_index = chData.contact_name_index;
channel->dmr.contact_index = chData.contact_name_index;
channel->dmr.dmr_timeslot = chData.repeater_slot;
channel->dmr.rxColorCode = chData.colorcode;
channel->dmr.txColorCode = chData.colorcode;
@ -157,7 +157,7 @@ int cps_create(char *cps_name)
return 0;
}
int cps_readChannelData(channel_t *channel, uint16_t pos)
int cps_readChannel(channel_t *channel, uint16_t pos)
{
if(pos >= maxNumChannels) return -1;
@ -222,7 +222,7 @@ int32_t cps_readBankData(uint16_t bank_pos, uint16_t ch_pos)
return zoneExtData.ext_a[ch_pos - 16] - 1;
}
int cps_readContactData(contact_t *contact, uint16_t pos)
int cps_readContact(contact_t *contact, uint16_t pos)
{
if(pos >= maxNumContacts) return -1;

Wyświetl plik

@ -120,7 +120,7 @@ static int _readChannelAtAddress(channel_t *channel, uint32_t addr)
}
else if(channel->mode == OPMODE_DMR)
{
channel->dmr.contactName_index = chData.contact_name_index;
channel->dmr.contact_index = chData.contact_name_index;
channel->dmr.dmr_timeslot = chData.repeater_slot;
channel->dmr.rxColorCode = chData.colorcode;
channel->dmr.txColorCode = chData.colorcode;
@ -155,7 +155,7 @@ int cps_create(char *cps_name)
return 0;
}
int cps_readChannelData(channel_t *channel, uint16_t pos)
int cps_readChannel(channel_t *channel, uint16_t pos)
{
if(pos >= maxNumChannels) return -1;
@ -223,7 +223,7 @@ int32_t cps_readBankData(uint16_t bank_pos, uint16_t ch_pos)
return zoneExtData.ext_a[ch_pos - 16] - 1;
}
int cps_readContactData(contact_t *contact, uint16_t pos)
int cps_readContact(contact_t *contact, uint16_t pos)
{
if(pos >= maxNumContacts) return -1;

Wyświetl plik

@ -46,7 +46,7 @@ int cps_create(char *cps_name)
return 0;
}
int cps_readChannelData(channel_t *channel, uint16_t pos)
int cps_readChannel(channel_t *channel, uint16_t pos)
{
(void) channel;
(void) pos;
@ -67,7 +67,7 @@ int32_t cps_readBankData(uint16_t bank_pos, uint16_t ch_pos)
return -1;
}
int cps_readContactData(contact_t *contact, uint16_t pos)
int cps_readContact(contact_t *contact, uint16_t pos)
{
(void) contact;
(void) pos;

Wyświetl plik

@ -34,7 +34,7 @@ int main()
for(int pos=0,result=0; result != -1; pos++)
{
channel_t ch;
result = cps_readChannelData(&ch, pos);
result = cps_readChannel(&ch, pos);
if(result != -1)
{
printf("Channel n.%d:\r\n", pos+1);
@ -71,7 +71,7 @@ int main()
for(int pos=0,result=0; result != -1; pos++)
{
contact_t contact;
result = cps_readContactData(&contact, pos);
result = cps_readContact(&contact, pos);
if(result != -1)
{
printf("Contact n.%d:\r\n", pos+1);

Wyświetl plik

@ -35,7 +35,7 @@ int main()
getchar();
channel_t ch;
cps_readChannelData(&ch, pos);
cps_readChannel(&ch, pos);
printf("Contact entry %d:\r\n", pos+1);
printf(" %s\r\n TX: %ld\r\n RX: %ld\r\n Mode: %s\r\n Bandwidth: %s\r\n",
ch.name,

Wyświetl plik

@ -1,19 +1,187 @@
#include <interfaces/cps_io.h>
#include <string.h>
#include <stdio.h>
int test_initCPS() {
// Initialize a new cps
int err = cps_create("/tmp/test1.rtxc");
if (err)
return -1;
// Re-open it
err = cps_open("/tmp/test1.rtxc");
if (err)
return -1;
return 0;
}
int test_insertContact() {
cps_create("/tmp/test2.rtxc");
cps_open("/tmp/test2.rtxc");
contact_t c1 = { "Test contact 1", 0, {{0}} };
contact_t c2 = { "Test contact 2", 0, {{0}} };
contact_t c3 = { "Test contact 3", 0, {{0}} };
contact_t c4 = { "Test contact 4", 0, {{0}} };
cps_insertContact(c1, 0);
cps_insertContact(c2, 0);
cps_insertContact(c3, 0);
cps_insertContact(c4, 1);
contact_t c = { 0 };
cps_readContact(&c, 0);
if(strncmp(c3.name, c.name, 32L))
return -1;
cps_readContact(&c, 1);
if(strncmp(c4.name, c.name, 32L))
return -1;
cps_readContact(&c, 2);
if(strncmp(c2.name, c.name, 32L))
return -1;
cps_readContact(&c, 3);
if(strncmp(c1.name, c.name, 32L))
return -1;
cps_close();
return 0;
}
int test_insertChannel() {
cps_create("/tmp/test3.rtxc");
cps_open("/tmp/test3.rtxc");
channel_t c1 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, "Test channel 1", "", {0}, {{0}} };
channel_t c2 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, "Test channel 2", "", {0}, {{0}} };
channel_t c3 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, "Test channel 3", "", {0}, {{0}} };
channel_t c4 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, "Test channel 4", "", {0}, {{0}} };
cps_insertChannel(c1, 0);
cps_insertChannel(c2, 0);
cps_insertChannel(c3, 0);
cps_insertChannel(c4, 1);
channel_t c = { 0 };
cps_readChannel(&c, 0);
if(strncmp(c3.name, c.name, 32L))
return -1;
cps_readChannel(&c, 1);
if(strncmp(c4.name, c.name, 32L))
return -1;
cps_readChannel(&c, 2);
if(strncmp(c2.name, c.name, 32L))
return -1;
cps_readChannel(&c, 3);
if(strncmp(c1.name, c.name, 32L))
return -1;
cps_close();
return 0;
}
int test_contactIndexFix() {
cps_create("/tmp/test4.rtxc");
cps_open("/tmp/test4.rtxc");
contact_t ct1 = { "Test contact 1", 0, {{0}} };
contact_t ct2 = { "Test contact 2", 0, {{0}} };
channel_t ch1 = { M17, 0, 0, 0, 0, 0, 0, 0, 0, "Test channel 1", "", {0}, {{0}} };
cps_insertContact(ct1, 0);
cps_insertChannel(ch1, 0);
cps_insertContact(ct2, 0);
channel_t c = { 0 };
cps_readChannel(&c, 0);
if(c.m17.contact_index != 1)
return -1;
cps_close();
return 0;
}
int test_createComplexCPS() {
cps_create("/tmp/test5.rtxc");
cps_open("/tmp/test5.rtxc");
contact_t ct1 = { "Test contact 1", 0, {{0}} };
contact_t ct2 = { "Test contact 2", 0, {{0}} };
channel_t ch1 = { M17, 0, 0, 0, 0, 0, 0, 0, 0, "Test channel 1", "", {0}, {{0}} };
channel_t ch2 = { M17, 0, 0, 0, 0, 0, 0, 0, 0, "Test channel 2", "", {0}, {{0}} };
channel_t ch3 = { M17, 0, 0, 0, 0, 0, 0, 0, 0, "Test channel 3", "", {0}, {{0}} };
channel_t ch4 = { M17, 0, 0, 0, 0, 0, 0, 0, 0, "Test channel 4", "", {0}, {{0}} };
channel_t ch5 = { M17, 0, 0, 0, 0, 0, 0, 0, 0, "Test channel 5", "", {0}, {{0}} };
bankHdr_t b1 = { "Test Bank 1", 0 };
bankHdr_t b2 = { "Test Bank 2", 0 };
cps_insertContact(ct2, 0);
cps_insertContact(ct1, 0);
cps_insertChannel(ch1, 0);
cps_insertChannel(ch2, 1);
cps_insertChannel(ch3, 2);
cps_insertChannel(ch4, 3);
cps_insertChannel(ch5, 4);
cps_insertBankHeader(b2, 0);
cps_insertBankHeader(b1, 0);
cps_insertBankData(0, 0, 0);
cps_insertBankData(1, 0, 1);
cps_insertBankData(2, 1, 0);
cps_insertBankData(3, 1, 1);
cps_insertBankData(4, 1, 2);
cps_insertBankData(5, 1, 3);
cps_close();
return 0;
}
int test_createOOOCPS() {
cps_create("/tmp/test6.rtxc");
cps_open("/tmp/test6.rtxc");
contact_t ct1 = { "Test contact 1", 0, {{0}} };
contact_t ct2 = { "Test contact 2", 0, {{0}} };
channel_t ch1 = { M17, 0, 0, 0, 0, 0, 0, 0, 0, "Test channel 1", "", {0}, {{0}} };
channel_t ch2 = { M17, 0, 0, 0, 0, 0, 0, 0, 0, "Test channel 2", "", {0}, {{0}} };
channel_t ch3 = { M17, 0, 0, 0, 0, 0, 0, 0, 0, "Test channel 3", "", {0}, {{0}} };
channel_t ch4 = { M17, 0, 0, 0, 0, 0, 0, 0, 0, "Test channel 4", "", {0}, {{0}} };
channel_t ch5 = { M17, 0, 0, 0, 0, 0, 0, 0, 0, "Test channel 5", "", {0}, {{0}} };
bankHdr_t b1 = { "Test Bank 1", 0 };
bankHdr_t b2 = { "Test Bank 2", 0 };
cps_insertContact(ct2, 0);
cps_insertContact(ct1, 0);
cps_insertBankHeader(b2, 0);
cps_insertBankHeader(b1, 0);
cps_insertChannel(ch5, 0);
cps_insertBankData(0, 0, 0);
cps_insertChannel(ch4, 0);
cps_insertBankData(0, 0, 1);
cps_insertChannel(ch3, 0);
cps_insertBankData(0, 1, 0);
cps_insertChannel(ch2, 0);
cps_insertBankData(0, 1, 1);
cps_insertChannel(ch1, 0);
cps_insertBankData(0, 1, 2);
cps_close();
return 0;
}
int main() {
// Initialize a new cps
int err = cps_create("test.rtxc");
if (err) {
printf("Error in codeplug initialization!\n");
if (test_initCPS())
{
printf("Error in codeplug initialization and read back!\n");
return -1;
}
// Write data
// Close it
// Re-open it
err = cps_open("test.rtxc");
if (err) {
printf("Error in codeplug reading!\n");
if (test_insertContact())
{
printf("Error in contact insertion!\n");
return -1;
}
if (test_insertChannel())
{
printf("Error in channel insertion!\n");
return -1;
}
if (test_contactIndexFix())
{
printf("Error in contact index fix!\n");
return -1;
}
if (test_createComplexCPS())
{
printf("Error in creation of complex CPS!\n");
return -1;
}
if (test_createOOOCPS())
{
printf("Error in creation of Out-Of-Order CPS!\n");
return -1;
}
// Read data and compare
}