NMT: Various fixes for SMS support
This commit is contained in:
parent
3ef9ef88bd
commit
a6bd841247
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue