From 71c39a95269f3f25698bf6fb42776c1778dfa5ae Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Fri, 17 Nov 2023 16:20:24 -0700 Subject: [PATCH] Add voice class --- src/sfe_lara_r6.h | 9 +-- src/sfe_ublox_cellular_voice.cpp | 112 +++++++++++++++++++++++++++++++ src/sfe_ublox_cellular_voice.h | 26 +++++++ 3 files changed, 143 insertions(+), 4 deletions(-) create mode 100644 src/sfe_ublox_cellular_voice.cpp create mode 100644 src/sfe_ublox_cellular_voice.h diff --git a/src/sfe_lara_r6.h b/src/sfe_lara_r6.h index 3177346..8349645 100644 --- a/src/sfe_lara_r6.h +++ b/src/sfe_lara_r6.h @@ -2,14 +2,15 @@ #define SFE_LARA_R6_LIBRARY_H #include "sfe_ublox_cellular.h" +#include "sfe_ublox_cellular_voice.h" // Base LARA-R6 class -class LARA_R6: public UBX_CELL +class LARA_R6: virtual public UBX_CELL { }; -class LARA_R6001: public LARA_R6 +class LARA_R6001: public LARA_R6, public UBX_CELL_VOICE { }; @@ -19,7 +20,7 @@ class LARA_R6001D: public LARA_R6 }; -class LARA_R6401: public LARA_R6 +class LARA_R6401: public LARA_R6, public UBX_CELL_VOICE { }; @@ -29,7 +30,7 @@ class LARA_R6401D: public LARA_R6 }; -class LARA_R6801_00B: public LARA_R6 +class LARA_R6801_00B: public LARA_R6, public UBX_CELL_VOICE { }; diff --git a/src/sfe_ublox_cellular_voice.cpp b/src/sfe_ublox_cellular_voice.cpp new file mode 100644 index 0000000..951dc98 --- /dev/null +++ b/src/sfe_ublox_cellular_voice.cpp @@ -0,0 +1,112 @@ +#include "sfe_ublox_cellular_voice.h" + +UBX_CELL_error_t UBX_CELL_VOICE::dial(String number) +{ + char *command; + char *numberCStr; + UBX_CELL_error_t err; + + numberCStr = ubx_cell_calloc_char(number.length() + 1); + if (numberCStr == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + number.toCharArray(numberCStr, number.length() + 1); + + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_DIAL) + strlen(numberCStr) + 3); + if (command != nullptr) + { + // Heads up! The dial command is one of the only commands that requires a + // semicolon at the end of it! + sprintf(command, "%s=%s;", UBX_CELL_COMMAND_DIAL, numberCStr); + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK, + nullptr, UBX_CELL_10_SEC_TIMEOUT); + + free(command); + } + else + { + err = UBX_CELL_ERROR_OUT_OF_MEMORY; + } + + free(numberCStr); + + return err; +} + +UBX_CELL_error_t UBX_CELL_VOICE::answer(void) +{ + return sendCommandWithResponse(UBX_CELL_COMMAND_ANSWER, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); +} + +UBX_CELL_error_t UBX_CELL_VOICE::hangUp(void) +{ + return sendCommandWithResponse(UBX_CELL_COMMAND_HANG_UP, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); +} + +UBX_CELL_error_t UBX_CELL_VOICE::playAudioResource(uint8_t audio_resource, uint8_t tone_id, uint8_t nof_repeat) +{ + UBX_CELL_error_t err; + char *command; + + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_PLAY_AUDIO) + 13); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,%d", UBX_CELL_COMMAND_PLAY_AUDIO, audio_resource, tone_id, nof_repeat); + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} + +UBX_CELL_error_t UBX_CELL_VOICE::stopAudioResource(uint8_t audio_resource) +{ + UBX_CELL_error_t err; + char *command; + + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_STOP_AUDIO) + 5); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_COMMAND_STOP_AUDIO, audio_resource); + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} + +UBX_CELL_error_t UBX_CELL_VOICE::generateToneFreq(uint16_t frequency, uint16_t duration, uint8_t volume) +{ + UBX_CELL_error_t err; + char *command; + char response[] = "\r\nOK\r\n\r\n+UUTGN: 0\r\n"; + + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_GENERATE_TONE) + 15); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,%d", UBX_CELL_COMMAND_GENERATE_TONE, frequency, duration, volume); + + err = sendCommandWithResponse(command, response, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} + +UBX_CELL_error_t UBX_CELL_VOICE::generateToneDTMF(char dtmf_character, uint16_t duration, uint8_t volume) +{ + UBX_CELL_error_t err; + char *command; + char response[] = "\r\nOK\r\n\r\n+UUTGN: 0\r\n"; + + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_GENERATE_TONE) + 14); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=\"%c\",%d,%d", UBX_CELL_COMMAND_GENERATE_TONE, dtmf_character, duration, volume); + + err = sendCommandWithResponse(command, response, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} \ No newline at end of file diff --git a/src/sfe_ublox_cellular_voice.h b/src/sfe_ublox_cellular_voice.h new file mode 100644 index 0000000..7b605e1 --- /dev/null +++ b/src/sfe_ublox_cellular_voice.h @@ -0,0 +1,26 @@ +#ifndef SPARKFUN_UBX_CELL_VOICE_ARDUINO_LIBRARY_H +#define SPARKFUN_UBX_CELL_VOICE_ARDUINO_LIBRARY_H + +#include "sfe_ublox_cellular.h" + +const char UBX_CELL_COMMAND_DIAL[] = "D"; // Dial command +const char UBX_CELL_COMMAND_ANSWER[] = "A"; // Answer call +const char UBX_CELL_COMMAND_HANG_UP[] = "+CHUP"; // Hang up call +const char UBX_CELL_COMMAND_PLAY_AUDIO[] = "+UPAR"; // Play audio resource +const char UBX_CELL_COMMAND_STOP_AUDIO[] = "+USAR"; // Stop audio resource +const char UBX_CELL_COMMAND_GENERATE_TONE[] = "+UTGN"; // Tone generator + +// Base class for any modules supporting voice calls +class UBX_CELL_VOICE: virtual public UBX_CELL +{ +public: + UBX_CELL_error_t dial(String number); + UBX_CELL_error_t answer(void); + UBX_CELL_error_t hangUp(void); + UBX_CELL_error_t playAudioResource(uint8_t audio_resource, uint8_t tone_id, uint8_t nof_repeat); + UBX_CELL_error_t stopAudioResource(uint8_t audio_resource); + UBX_CELL_error_t generateToneFreq(uint16_t frequency, uint16_t duration, uint8_t volume); + UBX_CELL_error_t generateToneDTMF(char dtmf_character, uint16_t duration, uint8_t volume); +}; + +#endif \ No newline at end of file