From a6bd8412478126961b60e166d74044048cd18d04 Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Sun, 10 Jul 2016 11:15:29 +0200 Subject: [PATCH] NMT: Various fixes for SMS support --- src/nmt/main.c | 42 ++++++++++++++++++++++++++++++------------ src/nmt/nmt.c | 10 +++++++++- src/nmt/nmt.h | 1 + src/nmt/sms.c | 43 ++++++++++++++++++++++++------------------- src/nmt/sms.h | 2 +- src/test/test_dms.c | 2 ++ src/test/test_sms.c | 22 ++++++++++++++++++---- 7 files changed, 85 insertions(+), 37 deletions(-) diff --git a/src/nmt/main.c b/src/nmt/main.c index 352545d..56470db 100644 --- a/src/nmt/main.c +++ b/src/nmt/main.c @@ -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(); diff --git a/src/nmt/nmt.c b/src/nmt/nmt.c index 89503f4..295ffed 100644 --- a/src/nmt/nmt.c +++ b/src/nmt/nmt.c @@ -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) diff --git a/src/nmt/nmt.h b/src/nmt/nmt.h index 2ef1ba8..8b5b9a4 100644 --- a/src/nmt/nmt.h +++ b/src/nmt/nmt.h @@ -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); diff --git a/src/nmt/sms.c b/src/nmt/sms.c index 484b68e..12dfd3d 100644 --- a/src/nmt/sms.c +++ b/src/nmt/sms.c @@ -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); } diff --git a/src/nmt/sms.h b/src/nmt/sms.h index f7fcc10..e25dca3 100644 --- a/src/nmt/sms.h +++ b/src/nmt/sms.h @@ -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); diff --git a/src/test/test_dms.c b/src/test/test_dms.c index c773cfc..677b78e 100644 --- a/src/test/test_dms.c +++ b/src/test/test_dms.c @@ -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); } diff --git a/src/test/test_sms.c b/src/test/test_sms.c index 917f10e..fb63ba0 100644 --- a/src/test/test_sms.c +++ b/src/test/test_sms.c @@ -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;