NMT: Various fixes for SMS support

This commit is contained in:
Andreas Eversberg 2016-07-10 11:15:29 +02:00
parent 3ef9ef88bd
commit a6bd841247
7 changed files with 85 additions and 37 deletions

View File

@ -40,8 +40,9 @@
#include "tones.h"
#include "announcement.h"
#define SMS_FIFO "/tmp/nmt_sms_deliver"
static int sms_fd = -1;
#define SMS_DELIVER "/tmp/nmt_sms_deliver"
#define SMS_SUBMIT "/tmp/nmt_sms_submit"
static int sms_deliver_fd = -1;
/* settings */
int num_chan_type = 0;
@ -208,7 +209,7 @@ static void myhandler(void)
static int pos = 0, rc, i;
int space = sizeof(buffer) - pos;
rc = read(sms_fd, buffer + pos, space);
rc = read(sms_deliver_fd, buffer + pos, space);
if (rc > 0) {
pos += rc;
if (pos == space) {
@ -229,6 +230,23 @@ static void myhandler(void)
}
}
int submit_sms(const char *sms)
{
FILE *fp;
fp = fopen(SMS_SUBMIT, "a");
if (!fp) {
fprintf(stderr, "Failed to open SMS submit file '%s'!\n", SMS_SUBMIT);
return -1;
}
fprintf(fp, "%s\n", sms);
fclose(fp);
return 0;
}
int main(int argc, char *argv[])
{
int rc;
@ -281,15 +299,15 @@ int main(int argc, char *argv[])
}
/* create pipe for SMS delivery */
unlink(SMS_FIFO);
rc = mkfifo(SMS_FIFO, 0666);
unlink(SMS_DELIVER);
rc = mkfifo(SMS_DELIVER, 0666);
if (rc < 0) {
fprintf(stderr, "Failed to create SMS deliver FIFO!\n");
fprintf(stderr, "Failed to create SMS deliver FIFO '%s'!\n", SMS_DELIVER);
goto fail;
} else {
sms_fd = open(SMS_FIFO, O_RDONLY | O_NONBLOCK);
if (sms_fd < 0) {
fprintf(stderr, "Failed to open SMS deliver FIFO!\n");
sms_deliver_fd = open(SMS_DELIVER, O_RDONLY | O_NONBLOCK);
if (sms_deliver_fd < 0) {
fprintf(stderr, "Failed to open SMS deliver FIFO! '%s'\n", SMS_DELIVER);
goto fail;
}
}
@ -355,9 +373,9 @@ int main(int argc, char *argv[])
fail:
/* fifo */
if (sms_fd > 0)
close(sms_fd);
unlink(SMS_FIFO);
if (sms_deliver_fd > 0)
close(sms_deliver_fd);
unlink(SMS_DELIVER);
/* cleanup functions */
call_cleanup();

View File

@ -1570,11 +1570,19 @@ void sms_release(nmt_t *nmt)
nmt_release(nmt);
}
void sms_submit(nmt_t *nmt, uint8_t ref, const char *orig_address, uint8_t orig_type, uint8_t orig_plan, int msg_ref, const char *dest_address, uint8_t dest_type, uint8_t dest_plan, const char *message)
int sms_submit(nmt_t *nmt, uint8_t ref, const char *orig_address, uint8_t orig_type, uint8_t orig_plan, int msg_ref, const char *dest_address, uint8_t dest_type, uint8_t dest_plan, const char *message)
{
char sms[512];
if (!orig_address[0])
orig_address = &nmt->subscriber.country;
PDEBUG(DNMT, DEBUG_NOTICE, "Received SMS from '%s' to '%s'\n", orig_address, dest_address);
printf("SMS received '%s' -> '%s': %s\n", orig_address, dest_address, message);
snprintf(sms, sizeof(sms) - 1, "%s,%s,%s", orig_address, dest_address, message);
sms[sizeof(sms) - 1] = '\0';
return submit_sms(sms);
}
void sms_deliver_report(nmt_t *nmt, uint8_t ref, int error, uint8_t cause)

View File

@ -156,4 +156,5 @@ void nmt_receive_frame(nmt_t *nmt, const char *bits, double quality, double leve
const char *nmt_get_frame(nmt_t *nmt);
void nmt_rx_super(nmt_t *nmt, int tone, double quality);
void deliver_sms(const char *sms);
int submit_sms(const char *sms);

View File

@ -106,8 +106,8 @@ int sms_init_sender(nmt_t *nmt)
/* Cleanup transceiver instance. */
void sms_cleanup_sender(nmt_t *nmt)
{
timer_exit(&nmt->sms_timer);
sms_reset(nmt);
timer_exit(&nmt->sms_timer);
}
/*
@ -292,7 +292,7 @@ int sms_deliver(nmt_t *nmt, uint8_t ref, const char *orig_address, uint8_t orig_
int orig_len;
int msg_len;
PDEBUG(DSMS, DEBUG_DEBUG, "Delivering SMS from upper layer\n");
PDEBUG(DSMS, DEBUG_INFO, "Delivering SMS from upper layer\n");
orig_len = strlen(orig_address);
msg_len = strlen(message);
@ -339,7 +339,7 @@ static void sms_submit_report(nmt_t *nmt, uint8_t ref, int error)
uint8_t data[64];
int length = 0;
PDEBUG(DSMS, DEBUG_DEBUG, "Sending Submit Report (%s)\n", (error) ? "error" : "ok");
PDEBUG(DSMS, DEBUG_INFO, "Sending Submit Report (%s)\n", (error) ? "error" : "ok");
/* HEADER */
length = encode_header(data);
@ -403,6 +403,7 @@ static int decode_sms_submit(nmt_t *nmt, const uint8_t *data, int length)
int orig_digits, dest_digits, msg_chars;
uint8_t orig_type, orig_plan, dest_type, dest_plan;
int tp_vpf_present = 0;
int rc;
/* decode ref */
ref = data[1];
@ -433,7 +434,7 @@ static int decode_sms_submit(nmt_t *nmt, const uint8_t *data, int length)
}
if (data[0] != RP_IE_USER_DATA) {
PDEBUG(DSMS, DEBUG_NOTICE, "missing user data IE\n");
return -1;
return -FSC_ERROR_IN_MS;
}
tpdu_len = data[1];
tpdu_data = 2 + data;
@ -456,11 +457,11 @@ static int decode_sms_submit(nmt_t *nmt, const uint8_t *data, int length)
/* check msg_type */
if (length < 1) {
PDEBUG(DSMS, DEBUG_NOTICE, "short read user data IE\n");
return -1;
return -FSC_ERROR_IN_MS;
}
if ((data[0] & MTI_MASK) != MTI_SMS_SUBMIT) {
PDEBUG(DSMS, DEBUG_NOTICE, "especting SUBMIT MTI, but got 0x%02x\n", data[0]);
return -1;
return -FSC_ERROR_IN_MS;
}
if ((data[0] & VPF_MASK))
tp_vpf_present = 1;
@ -470,7 +471,7 @@ static int decode_sms_submit(nmt_t *nmt, const uint8_t *data, int length)
/* decode msg ref */
if (length < 1) {
PDEBUG(DSMS, DEBUG_NOTICE, "short read user data IE\n");
return -1;
return -FSC_ERROR_IN_MS;
}
msg_ref = data[0];
data++;
@ -479,7 +480,7 @@ static int decode_sms_submit(nmt_t *nmt, const uint8_t *data, int length)
/* decode dest address */
if (length < 2) {
PDEBUG(DSMS, DEBUG_NOTICE, "short read user data IE\n");
return -1;
return -FSC_ERROR_IN_MS;
}
dest_data = 2 + data;
dest_digits = data[0];
@ -488,7 +489,7 @@ static int decode_sms_submit(nmt_t *nmt, const uint8_t *data, int length)
dest_len = (dest_digits + 1) >> 1;
if (length < 2 + dest_len) {
PDEBUG(DSMS, DEBUG_NOTICE, "short read user data IE\n");
return -1;
return -FSC_ERROR_IN_MS;
}
data += 2 + dest_len;
length -= 2 + dest_len;
@ -499,7 +500,7 @@ static int decode_sms_submit(nmt_t *nmt, const uint8_t *data, int length)
/* skip above protocol identifier */
if (length < 1) {
PDEBUG(DSMS, DEBUG_NOTICE, "short read above protocol identifier IE\n");
return -1;
return -FSC_ERROR_IN_MS;
}
data++;
length--;
@ -507,11 +508,11 @@ static int decode_sms_submit(nmt_t *nmt, const uint8_t *data, int length)
/* decode data coding scheme */
if (length < 1) {
PDEBUG(DSMS, DEBUG_NOTICE, "short data coding scheme IE\n");
return -1;
return -FSC_ERROR_IN_MS;
}
if (data[0] != 0) {
PDEBUG(DSMS, DEBUG_NOTICE, "SMS coding unsupported (got 0x%02x)\n", data[0]);
return -1;
return -FSC_ERROR_IN_MS;
}
data++;
length--;
@ -520,7 +521,7 @@ static int decode_sms_submit(nmt_t *nmt, const uint8_t *data, int length)
if (tp_vpf_present) {
if (length < 1) {
PDEBUG(DSMS, DEBUG_NOTICE, "short read validity period IE\n");
return -1;
return -FSC_ERROR_IN_MS;
}
data++;
length--;
@ -529,20 +530,24 @@ static int decode_sms_submit(nmt_t *nmt, const uint8_t *data, int length)
/* decode data message text */
if (length < 1) {
PDEBUG(DSMS, DEBUG_NOTICE, "short read user data IE\n");
return -1;
return -FSC_ERROR_IN_MS;
}
msg_data = data + 1;
msg_chars = data[0];
msg_len = (msg_chars * 7 + 7) / 8;
if (length < 1 + msg_len) {
PDEBUG(DSMS, DEBUG_NOTICE, "short read user data IE\n");
return -1;
return -FSC_ERROR_IN_MS;
}
char message[msg_chars + 1];
decode_message(msg_data, msg_len, message);
PDEBUG(DSMS, DEBUG_DEBUG, "Decoded message: '%s'\n", message);
sms_submit(nmt, ref, orig_address, orig_type, orig_plan, msg_ref, dest_address, dest_type, dest_plan, message);
PDEBUG(DSMS, DEBUG_INFO, "Submitting SMS to upper layer\n");
rc = sms_submit(nmt, ref, orig_address, orig_type, orig_plan, msg_ref, dest_address, dest_type, dest_plan, message);
if (rc < 0)
return -FSC_SC_SYSTEM_FAILURE;
return 1;
}
@ -568,9 +573,9 @@ static int decode_deliver_report(nmt_t *nmt, const uint8_t *data, int length)
}
if (data[2] == RP_IE_CAUSE && data[3] > 0)
cause = data[4];
PDEBUG(DSMS, DEBUG_DEBUG, "Decoded delivery report: ERROR, cause=%d\n", cause);
PDEBUG(DSMS, DEBUG_INFO, "Received Delivery report: ERROR, cause=%d\n", cause);
} else
PDEBUG(DSMS, DEBUG_DEBUG, "Decoded delivery report: OK\n");
PDEBUG(DSMS, DEBUG_INFO, "Received Delivery report: OK\n");
sms_deliver_report(nmt, ref, error, cause);
@ -625,7 +630,7 @@ release:
case RP_MO_DATA:
rc = decode_sms_submit(nmt, data, length);
if (rc < 0)
sms_submit_report(nmt, data[1], FSC_UNSPECIFIED_ERROR);
sms_submit_report(nmt, data[1], -rc);
else if (rc > 0) {
sms_submit_report(nmt, data[1], 0);
}

View File

@ -26,7 +26,7 @@ typedef struct sms {
int sms_init_sender(nmt_t *nmt);
void sms_cleanup_sender(nmt_t *nmt);
void sms_submit(nmt_t *nmt, uint8_t ref, const char *orig_address, uint8_t orig_type, uint8_t orig_plan, int msg_ref, const char *dest_address, uint8_t dest_type, uint8_t dest_plan, const char *message);
int sms_submit(nmt_t *nmt, uint8_t ref, const char *orig_address, uint8_t orig_type, uint8_t orig_plan, int msg_ref, const char *dest_address, uint8_t dest_type, uint8_t dest_plan, const char *message);
void sms_deliver_report(nmt_t *nmt, uint8_t ref, int error, uint8_t cause);
int sms_deliver(nmt_t *nmt, uint8_t ref, const char *orig_address, uint8_t type, uint8_t plan, time_t timestamp, const char *message);
void sms_release(nmt_t *nmt);

View File

@ -68,6 +68,7 @@ nmt_t *alloc_nmt(void)
nmt_t *nmt;
nmt = calloc(sizeof(*nmt), 1);
dms_init_sender(nmt);
nmt->dms.frame_spl = calloc(1000000, 1);
nmt->samples_per_bit = 40;
@ -78,6 +79,7 @@ nmt_t *alloc_nmt(void)
void free_nmt(nmt_t *nmt)
{
dms_cleanup_sender(nmt);
free(nmt->dms.frame_spl);
free(nmt);
}

View File

@ -55,10 +55,15 @@ static uint8_t dms_buffer[256];
static int dms_buffer_count;
void dms_send(nmt_t *nmt, const uint8_t *data, int length, int eight_bits)
{
memcpy(dms_buffer, data, length);
dms_buffer_count = length;
// int i;
/* skip deliver report */
if (length == 13)
return;
dms_buffer_count = length;
memcpy(dms_buffer, data, length);
assert(length == sizeof(test_mt_sms_data), "Expecting SMS binary data length to match");
assert(!memcmp(data, test_mt_sms_data, length), "Expecting SMS binary data to match");
// for (i = 0; i < length; i++) {
@ -71,10 +76,12 @@ void sms_release(nmt_t *nmt)
printf("(got release from SMS layer)\n");
}
void sms_submit(nmt_t *nmt, uint8_t ref, const char *orig_address, uint8_t orig_type, uint8_t orig_plan, int msg_ref, const char *dest_address, uint8_t dest_type, uint8_t dest_plan, const char *message)
int sms_submit(nmt_t *nmt, uint8_t ref, const char *orig_address, uint8_t orig_type, uint8_t orig_plan, int msg_ref, const char *dest_address, uint8_t dest_type, uint8_t dest_plan, const char *message)
{
strcpy((char *)dms_buffer, message);
dms_buffer_count = strlen(message);
return 0;
}
void sms_deliver_report(nmt_t *nmt, uint8_t ref, int error, uint8_t cause)
@ -92,6 +99,7 @@ int main(void)
debuglevel = DEBUG_DEBUG;
nmt = calloc(sizeof(*nmt), 1);
sms_init_sender(nmt);
sms_reset(nmt);
/* deliver */
@ -99,10 +107,13 @@ int main(void)
rc = sms_deliver(nmt, 1, test_mt_sms_tel, SMS_TYPE_INTERNATIONAL, SMS_PLAN_ISDN_TEL, test_mt_sms_time, test_mt_sms_text);
assert(rc == 0, "Expecting sms_deliver() to return 0");
sms_cleanup_sender(nmt);
free(nmt);
ok();
free(nmt);
nmt = calloc(sizeof(*nmt), 1);
sms_init_sender(nmt);
sms_reset(nmt);
printf("(submitting SMS)\n");
@ -113,6 +124,9 @@ int main(void)
assert(dms_buffer_count == strlen(test_mo_sms_text), "Expecting SMS text length to match");
assert(!memcmp(dms_buffer, test_mo_sms_text, dms_buffer_count), "Expecting SMS text to match");
sms_cleanup_sender(nmt);
free(nmt);
ok();
return 0;