Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /***************************************************************************/
- /*
- * main.c
- *
- * Created on: Apr 16, 2012
- * Author: carlos
- */
- #include <errno.h>
- #include <string.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include "util.h"
- #include "huawei/modem.h"
- #include "huawei/at/at_clcc.h"
- #include "huawei/at/at_a.h"
- #include "huawei/at/at_cvoice.h"
- #include "huawei/at/at_ddsetex.h"
- #include "huawei/at/at_chup.h"
- pthread_t threads[2];
- port_t data_port, audio_port;
- int fifo_in, fifo_out;
- /***************************************************************************/
- static void print_usage()
- {
- }
- /***************************************************************************/
- /*
- static _bool get_modem_info(port_t *data_port)
- {
- at_io_t io;
- at_cvoice_resp_t cvoice;
- if (!get_pcm_frames(data_port))
- return FALSE;
- }*/
- /***************************************************************************/
- /* This loads up a large buffer with the contents of a recorded audio file.*/
- /***************************************************************************/
- static _bool get_pcm_frames(char *audio_file, pcm_data_t *audio)
- {
- int file_length = 0, silent_frame = 0, bytes_read = 0;
- FILE *file = fopen(audio_file, "rb");
- if (file == NULL)
- {
- LOG(L_ERROR, "%s: error opening file %s. %s\n", __FUNCTION__, audio_file, strerror(errno));
- return FALSE;
- }
- fseek(file, 0, SEEK_END);
- file_length = ftell(file);
- rewind(file);
- // file_length = 252000;
- silent_frame = FRAME_SIZE - (file_length % FRAME_SIZE);
- audio->data = malloc(file_length + silent_frame);
- audio->length = file_length + silent_frame;
- if ((bytes_read = fread(audio->data, 1, file_length, file)) != file_length)
- {
- //printf("br %d, l %d\n", bytes_read, file_length);
- LOG(L_ERROR, "%s: couldn't read the whole audio file. %s\n", __FUNCTION__, strerror(errno));
- return FALSE;
- }
- memset(&audio->data[file_length], '\0', silent_frame);
- return TRUE;
- }
- /***************************************************************************/
- static _bool get_modem_frame_rate(port_t *port)
- {
- at_io_t io;
- at_cvoice_resp_t cvoice;
- at_cvoice_query_all(&io.at_cmd);
- if (!modem_write(port, &io))
- {
- LOG(L_ERROR, "%s: error writing to modem\n", __FUNCTION__);
- return FALSE;
- }
- printf("response: %s\n", io.response.s);
- if (!at_cvoice_parse_response(&io, &cvoice))
- {
- LOG(L_ERROR, "%s: error getting frame rate\n", __FUNCTION__);
- return FALSE;
- }
- port->frame_period = cvoice.ptime;
- return TRUE;
- }
- /***************************************************************************/
- /* Play frames of the recorded message into the */
- /***************************************************************************/
- static void play_message(port_t *port, pcm_data_t *audio)
- {
- int n = 0, offset = 0, i = 0;
- for(i = 0; i <= audio->length; i += FRAME_SIZE)
- {
- n = write(port->fd, &audio->data[offset], FRAME_SIZE);
- if (n < FRAME_SIZE)
- LOG(L_DEBUG, "%s: wrote only %d of %d bytes\n", __FUNCTION__, n, FRAME_SIZE);
- offset += FRAME_SIZE;
- usleep(20000); //usleep(port->frame_period * 10000);
- }
- }
- /***************************************************************************/
- void *write_thread(void *arg)
- {
- char buf[FRAME_SIZE];
- int nwant = FRAME_SIZE;
- int i;
- char *p = buf;
- while(1)
- {
- i = read(fifo_out, p, nwant);
- if (i > 0) {
- nwant -= i;
- p += i;
- if (nwant <= 0) {
- write(audio_port.fd, &buf, FRAME_SIZE);
- nwant = FRAME_SIZE;
- p = buf;
- }
- }
- }
- }
- /***************************************************************************/
- void *read_thread(void *arg)
- {
- char buf[FRAME_SIZE];
- int nchars;
- while(1)
- {
- nchars=read(audio_port.fd, &buf, sizeof(buf));
- if (nchars > 0)
- write(fifo_in, &buf, nchars);
- }
- }
- /***************************************************************************/
- int main(int argc, char **argv)
- {
- at_cvoice_resp_t *cvoice = malloc(sizeof(at_cvoice_resp_t));
- at_io_t io;
- pcm_data_t audio;
- _bool incoming = FALSE;
- sscanf("AT^CVOICE\r\n^CVOICE:0,8000,16,20\r\nOK\r\n\0", "AT^CVOICE\r\n^CVOICE:%d,%d,%d,%d",
- &cvoice->mode,
- &cvoice->sampling_rate,
- &cvoice->data_bit,
- &cvoice->ptime);
- LOG(L_DEBUG, "%s: CVOICE -> sampling rate=%d data_bit=%d frame_period=%d\n", __FUNCTION__,
- cvoice->sampling_rate,
- cvoice->data_bit,
- cvoice->ptime);
- at_cvoice_query_all(&io.at_cmd);
- /*io.response.s = "AT^CVOICE\r\n^CVOICE:0,8000,16,20\r\nOK\r\n";
- io.response.len = 44;
- at_cvoice_parse_response(&io, cvoice);
- //return 0;*/
- if ((argc > 4) || argc < 3)
- {
- print_usage();
- exit(1);
- }
- if (!modem_open_datafile(argv[1], &data_port)) // Open the Command control port.
- exit(1);
- if (!modem_open_audio(argv[2], &audio_port)) // Open the audio data port.
- exit(1);
- if (!get_modem_frame_rate(&data_port))
- exit(1);
- // The answering machine recorded file is now optional.
- if (argc == 4) {
- if (!get_pcm_frames(argv[3], &audio)) // Read the recorded audio file.
- exit(1);
- }
- /*******************************************/
- // Make fifos and start the read and write threads
- mkfifo ("/tmp/telein", S_IRUSR| S_IWUSR);
- fifo_in = open("/tmp/telein", O_RDONLY);
- pthread_create(&threads[0], NULL, read_thread, NULL);
- // If not answering machine, then open write fifo and thread.
- if (argc != 4) {
- mkfifo ("/tmp/telout", S_IRUSR| S_IWUSR);
- fifo_out = open("/tmp/telout", O_WRONLY);
- pthread_create(&threads[1], NULL, write_thread, NULL);
- }
- /*******************************************/
- for(;;) // Loop, handling incoming calls.
- {
- at_io_t io;
- at_clcc_resp_t clcc;
- sleep(1);
- at_clcc_query_all(&io.at_cmd);
- if (!modem_write(&data_port, &io))
- {
- LOG(L_ERROR, "%s: error writing to modem\n", __FUNCTION__);
- continue;
- }
- if (!at_clcc_parse_response(&io, &clcc))
- {
- LOG(L_ERROR, "%s: error parsing response\n", __FUNCTION__);
- continue;
- }
- if (clcc.status == CS_INCOMING)
- {
- str_t a_port = {"2", 1};
- LOG(L_DEBUG, "%s: incoming call. Preparing to answer.\n", __FUNCTION__);
- incoming = TRUE;
- STR_FREE(io.at_cmd.str_cmd);
- at_a_assign(NULL, &io.at_cmd);
- if (!modem_write(&data_port, &io))
- continue;
- at_ddsetex_assign(&a_port, &io.at_cmd);
- if (!modem_write(&data_port, &io))
- continue;
- }
- else if(clcc.status == CS_ACTIVE)
- {
- if (!incoming)
- {
- LOG(L_DEBUG, "%s: active call not originated by modem, ignoring\n", __FUNCTION__);
- continue;
- }
- else
- LOG(L_DEBUG, "%s: call was answered\n", __FUNCTION__);
- incoming = FALSE;
- if (argc == 4) { // The answering machine recorded file is now optional.
- play_message(&audio_port, &audio);
- // If not answering machine, need to monitor stdin to see if the user wants to hang up.
- at_chup_assign(NULL, &io.at_cmd);
- if (!modem_write(&data_port, &io))
- continue;
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement