refine
This commit is contained in:
parent
902e7f8e30
commit
2441e32b79
2 changed files with 175 additions and 159 deletions
199
d-modem.c
199
d-modem.c
|
@ -37,9 +37,9 @@
|
||||||
pa_simple *pa_s1 = NULL;
|
pa_simple *pa_s1 = NULL;
|
||||||
pa_simple *pa_s2 = NULL;
|
pa_simple *pa_s2 = NULL;
|
||||||
const pa_sample_spec pa_ss = {
|
const pa_sample_spec pa_ss = {
|
||||||
.format = PA_SAMPLE_S16LE,
|
.format = PA_SAMPLE_S16LE,
|
||||||
.rate = 9600,
|
.rate = 9600,
|
||||||
.channels = 1
|
.channels = 1
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
#ifdef PCM_FILE
|
#ifdef PCM_FILE
|
||||||
|
@ -54,6 +54,7 @@ int wave_transmit = -1;
|
||||||
uint8_t mode = DMODEM_DIAL_MODE;
|
uint8_t mode = DMODEM_DIAL_MODE;
|
||||||
uint8_t ringing = 0;
|
uint8_t ringing = 0;
|
||||||
uint8_t answered = 0;
|
uint8_t answered = 0;
|
||||||
|
int ppid;
|
||||||
pjsua_call_id incoming;
|
pjsua_call_id incoming;
|
||||||
|
|
||||||
struct dmodem {
|
struct dmodem {
|
||||||
|
@ -72,65 +73,65 @@ static void error_exit(const char *title, pj_status_t status) {
|
||||||
if (!destroying) {
|
if (!destroying) {
|
||||||
destroying = true;
|
destroying = true;
|
||||||
pjsua_destroy();
|
pjsua_destroy();
|
||||||
stop_pa();
|
stop_pa();
|
||||||
if (answered)
|
if (answered)
|
||||||
execl("/bin/sh", "/bin/sh", "-cx", "kill -INT $PPID", NULL);
|
kill(ppid, SIGINT);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void start_pa() {
|
void start_pa() {
|
||||||
#ifdef PCM_FILE
|
#ifdef PCM_FILE
|
||||||
char _wavbuf[50];
|
char _wavbuf[50];
|
||||||
sprintf(_wavbuf, PCM_FILE, "recv");
|
sprintf(_wavbuf, PCM_FILE, "recv");
|
||||||
wave_recv = open(_wavbuf, O_WRONLY | O_CREAT, 00644);
|
wave_recv = open(_wavbuf, O_WRONLY | O_CREAT, 00644);
|
||||||
sprintf(_wavbuf, PCM_FILE, "transmit");
|
sprintf(_wavbuf, PCM_FILE, "transmit");
|
||||||
wave_recv = open(_wavbuf, O_WRONLY | O_CREAT, 00644);
|
wave_recv = open(_wavbuf, O_WRONLY | O_CREAT, 00644);
|
||||||
if (wave_recv <= 0 || wave_transmit <= 0)
|
if (wave_recv <= 0 || wave_transmit <= 0)
|
||||||
error_exit("open wave files", 1);
|
error_exit("open wave files", 1);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAS_PULSE
|
#ifdef HAS_PULSE
|
||||||
pa_s1 = pa_simple_new(NULL, // Use the default server.
|
pa_s1 = pa_simple_new(NULL, // Use the default server.
|
||||||
"dmodem", // Our application's name.
|
"dmodem", // Our application's name.
|
||||||
PA_STREAM_PLAYBACK,
|
PA_STREAM_PLAYBACK,
|
||||||
NULL, // Use the default device.
|
NULL, // Use the default device.
|
||||||
"recv", // Description of our stream.
|
"recv", // Description of our stream.
|
||||||
&pa_ss, // Our sample format.
|
&pa_ss, // Our sample format.
|
||||||
NULL, // Use default channel map
|
NULL, // Use default channel map
|
||||||
NULL, // Use default buffering attributes.
|
NULL, // Use default buffering attributes.
|
||||||
NULL // Ignore error code.
|
NULL // Ignore error code.
|
||||||
);
|
);
|
||||||
pa_s2 = pa_simple_new(NULL, // Use the default server.
|
pa_s2 = pa_simple_new(NULL, // Use the default server.
|
||||||
"dmodem", // Our application's name.
|
"dmodem", // Our application's name.
|
||||||
PA_STREAM_PLAYBACK,
|
PA_STREAM_PLAYBACK,
|
||||||
NULL, // Use the default device.
|
NULL, // Use the default device.
|
||||||
"transmit", // Description of our stream.
|
"transmit", // Description of our stream.
|
||||||
&pa_ss, // Our sample format.
|
&pa_ss, // Our sample format.
|
||||||
NULL, // Use default channel map
|
NULL, // Use default channel map
|
||||||
NULL, // Use default buffering attributes.
|
NULL, // Use default buffering attributes.
|
||||||
NULL // Ignore error code.
|
NULL // Ignore error code.
|
||||||
);
|
);
|
||||||
if (!pa_s1 || !pa_s2)
|
if (!pa_s1 || !pa_s2)
|
||||||
error_exit("pulseaudio", 1);
|
error_exit("pulseaudio", 1);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void stop_pa() {
|
void stop_pa() {
|
||||||
#ifdef HAS_PULSE
|
#ifdef HAS_PULSE
|
||||||
if(pa_s1)
|
if(pa_s1)
|
||||||
pa_simple_free(pa_s1);
|
pa_simple_free(pa_s1);
|
||||||
if(pa_s2)
|
if(pa_s2)
|
||||||
pa_simple_free(pa_s2);
|
pa_simple_free(pa_s2);
|
||||||
pa_s1 = 0;
|
pa_s1 = 0;
|
||||||
pa_s1 = 0;
|
pa_s1 = 0;
|
||||||
#endif
|
#endif
|
||||||
#ifdef PCM_FILE
|
#ifdef PCM_FILE
|
||||||
if (wave_recv >= 0)
|
if (wave_recv >= 0)
|
||||||
close(wave_recv);
|
close(wave_recv);
|
||||||
if (wave_transmit >= 0)
|
if (wave_transmit >= 0)
|
||||||
close(wave_transmit);
|
close(wave_transmit);
|
||||||
wave_recv = -1;
|
wave_recv = -1;
|
||||||
wave_transmit = -1;
|
wave_transmit = -1;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,10 +141,10 @@ static pj_status_t dmodem_put_frame(pjmedia_port *this_port, pjmedia_frame *fram
|
||||||
|
|
||||||
if (frame->type == PJMEDIA_FRAME_TYPE_AUDIO) {
|
if (frame->type == PJMEDIA_FRAME_TYPE_AUDIO) {
|
||||||
#ifdef HAS_PULSE
|
#ifdef HAS_PULSE
|
||||||
pa_simple_write(pa_s1, frame->buf, frame->size, NULL);
|
pa_simple_write(pa_s1, frame->buf, frame->size, NULL);
|
||||||
#endif
|
#endif
|
||||||
#ifdef PCM_FILE
|
#ifdef PCM_FILE
|
||||||
write(wave_recv, frame->buf, frame->size);
|
write(wave_recv, frame->buf, frame->size);
|
||||||
#endif
|
#endif
|
||||||
if ((len=write(sm->sock, frame->buf, frame->size)) != frame->size) {
|
if ((len=write(sm->sock, frame->buf, frame->size)) != frame->size) {
|
||||||
error_exit("error writing frame",0);
|
error_exit("error writing frame",0);
|
||||||
|
@ -166,10 +167,10 @@ static pj_status_t dmodem_get_frame(pjmedia_port *this_port, pjmedia_frame *fram
|
||||||
frame->type = PJMEDIA_FRAME_TYPE_AUDIO;
|
frame->type = PJMEDIA_FRAME_TYPE_AUDIO;
|
||||||
sm->timestamp.u64 += PJMEDIA_PIA_SPF(&this_port->info);
|
sm->timestamp.u64 += PJMEDIA_PIA_SPF(&this_port->info);
|
||||||
#ifdef HAS_PULSE
|
#ifdef HAS_PULSE
|
||||||
pa_simple_write(pa_s2, frame->buf, frame->size, NULL);
|
pa_simple_write(pa_s2, frame->buf, frame->size, NULL);
|
||||||
#endif
|
#endif
|
||||||
#ifdef PCM_FILE
|
#ifdef PCM_FILE
|
||||||
write(wave_transmit, frame->buf, frame->size);
|
write(wave_transmit, frame->buf, frame->size);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return PJ_SUCCESS;
|
return PJ_SUCCESS;
|
||||||
|
@ -177,8 +178,8 @@ static pj_status_t dmodem_get_frame(pjmedia_port *this_port, pjmedia_frame *fram
|
||||||
|
|
||||||
static pj_status_t dmodem_on_destroy(pjmedia_port *this_port) {
|
static pj_status_t dmodem_on_destroy(pjmedia_port *this_port) {
|
||||||
printf("destroy\n");
|
printf("destroy\n");
|
||||||
if (answered)
|
if (answered)
|
||||||
execl("/bin/sh", "/bin/sh", "-cx", "kill -INT $PPID", NULL);
|
kill(ppid, SIGINT);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,8 +200,8 @@ static void on_call_state(pjsua_call_id call_id, pjsip_event *e) {
|
||||||
destroying = true;
|
destroying = true;
|
||||||
pjsua_destroy();
|
pjsua_destroy();
|
||||||
stop_pa();
|
stop_pa();
|
||||||
if (answered)
|
if (answered)
|
||||||
execl("/bin/sh", "/bin/sh", "-cx", "kill -INT $PPID", NULL);
|
kill(ppid, SIGINT);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -212,12 +213,12 @@ static void on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id, pjsip_r
|
||||||
char* tmp = malloc(pj_strlen(&ci.remote_contact)+1);
|
char* tmp = malloc(pj_strlen(&ci.remote_contact)+1);
|
||||||
strcpy(tmp, ci.remote_contact.ptr);
|
strcpy(tmp, ci.remote_contact.ptr);
|
||||||
tmp[pj_strlen(&ci.remote_contact)] = '\0';
|
tmp[pj_strlen(&ci.remote_contact)] = '\0';
|
||||||
if (answered) {
|
if (answered) {
|
||||||
printf("Incoming call rejected from: %s\n", tmp);
|
PJ_LOG(2,(__FILE__, "Incoming call rejected from: %s", tmp));
|
||||||
pjsua_call_hangup(call_id, 0u, NULL, NULL);
|
pjsua_call_hangup(call_id, 0u, NULL, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
printf("Incoming call from: %s\n", tmp);
|
PJ_LOG(2,(__FILE__, "Incoming call from: %s", tmp));
|
||||||
free(tmp);
|
free(tmp);
|
||||||
incoming = call_id;
|
incoming = call_id;
|
||||||
ringing = 1;
|
ringing = 1;
|
||||||
|
@ -247,23 +248,35 @@ static void on_call_media_state(pjsua_call_id call_id) {
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
pjsua_acc_id acc_id;
|
pjsua_acc_id acc_id;
|
||||||
pj_status_t status;
|
pj_status_t status;
|
||||||
if (argc != 3) {
|
if (argc != 5) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
ppid = atoi(argv[3]);
|
||||||
|
char* _modemid_tmp = argv[4];
|
||||||
|
for (size_t i = strlen(_modemid_tmp) - 1 ; ; i--) {
|
||||||
|
if (i < 0 || _modemid_tmp[i] < '0' || _modemid_tmp[i] > '9') {
|
||||||
|
_modemid_tmp += i+1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int sip_port = atoi(_modemid_tmp);
|
||||||
|
sip_port = sip_port >= 0 ? sip_port : 0;
|
||||||
|
sip_port += 5060;
|
||||||
|
sip_port = sip_port <= 65535 ? sip_port : 65535;
|
||||||
if(!strncmp(argv[1], "rr", 2)) {
|
if(!strncmp(argv[1], "rr", 2)) {
|
||||||
mode = DMODEM_ANSWER_MODE;
|
mode = DMODEM_ANSWER_MODE;
|
||||||
}
|
}
|
||||||
signal(SIGPIPE,SIG_IGN);
|
signal(SIGPIPE,SIG_IGN);
|
||||||
char *dialstr = argv[1];
|
char *dialstr = argv[1];
|
||||||
|
|
||||||
int has_sip_user = 1;
|
int has_sip_user = 1;
|
||||||
char *sip_user = getenv("SIP_LOGIN");
|
char *sip_user = getenv("SIP_LOGIN");
|
||||||
if (!sip_user) {
|
if (!sip_user) {
|
||||||
has_sip_user = 0;
|
has_sip_user = 0;
|
||||||
printf("[!] SIP_LOGIN is empty, no registration will be attempted\n");
|
printf("[!] SIP_LOGIN is empty, no registration will be attempted\n");
|
||||||
char sip_user_buf[40];
|
char sip_user_buf[40];
|
||||||
strcpy(sip_user_buf, "placeholder:placeholder@placeholder");
|
strcpy(sip_user_buf, "placeholder:placeholder@placeholder");
|
||||||
sip_user = sip_user_buf;
|
sip_user = sip_user_buf;
|
||||||
}
|
}
|
||||||
if (!sip_user) {
|
if (!sip_user) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -297,17 +310,16 @@ int main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pjsua_logging_config_default(&log_cfg);
|
pjsua_logging_config_default(&log_cfg);
|
||||||
log_cfg.console_level = 4;
|
// log_cfg.console_level = 4;
|
||||||
|
log_cfg.console_level = 2;
|
||||||
|
|
||||||
pjsua_media_config_default(&med_cfg);
|
pjsua_media_config_default(&med_cfg);
|
||||||
med_cfg.no_vad = true;
|
med_cfg.no_vad = true;
|
||||||
med_cfg.ec_tail_len = 0;
|
med_cfg.ec_tail_len = 0;
|
||||||
med_cfg.jb_max = 2000;
|
med_cfg.jb_max = -1;
|
||||||
// med_cfg.jb_init = 200;
|
med_cfg.jb_init = -1;
|
||||||
/* // med_cfg.jb_init = 200 */
|
|
||||||
// med_cfg.jb_init = 0;
|
|
||||||
/* med_cfg.audio_frame_ptime = 5; */
|
|
||||||
med_cfg.audio_frame_ptime = 10;
|
med_cfg.audio_frame_ptime = 10;
|
||||||
|
med_cfg.quality = 10;
|
||||||
|
|
||||||
status = pjsua_init(&cfg, &log_cfg, &med_cfg);
|
status = pjsua_init(&cfg, &log_cfg, &med_cfg);
|
||||||
if (status != PJ_SUCCESS) error_exit("Error in pjsua_init()", status);
|
if (status != PJ_SUCCESS) error_exit("Error in pjsua_init()", status);
|
||||||
|
@ -331,22 +343,22 @@ int main(int argc, char *argv[]) {
|
||||||
// printf("codec: %s %d\n",pj_strbuf(&codecs[i].codec_id),pri);
|
// printf("codec: %s %d\n",pj_strbuf(&codecs[i].codec_id),pri);
|
||||||
}
|
}
|
||||||
|
|
||||||
pjsua_transport_id transport_id;
|
pjsua_transport_id transport_id;
|
||||||
/* Add UDP transport. */
|
/* Add UDP transport. */
|
||||||
{
|
{
|
||||||
pjsua_transport_config cfg;
|
pjsua_transport_config cfg;
|
||||||
|
|
||||||
pjsua_transport_config_default(&cfg);
|
pjsua_transport_config_default(&cfg);
|
||||||
if (mode)
|
if (mode)
|
||||||
cfg.port = 5160;
|
cfg.port = sip_port;
|
||||||
if (getenv("PJSIP_IPV6"))
|
if (getenv("PJSIP_IPV6"))
|
||||||
status = pjsua_transport_create(PJSIP_TRANSPORT_UDP6, &cfg, &transport_id);
|
status = pjsua_transport_create(PJSIP_TRANSPORT_UDP6, &cfg, &transport_id);
|
||||||
else
|
else
|
||||||
status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &cfg, &transport_id);
|
status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &cfg, &transport_id);
|
||||||
if (status != PJ_SUCCESS) error_exit("Error creating transport", status);
|
if (status != PJ_SUCCESS) error_exit("Error creating transport", status);
|
||||||
}
|
}
|
||||||
char buf[384];
|
char buf[384];
|
||||||
printf("Initializing pool\n");
|
//printf("Initializing pool\n");
|
||||||
pj_caching_pool cp;
|
pj_caching_pool cp;
|
||||||
pj_caching_pool_init(&cp, NULL, 1024*1024);
|
pj_caching_pool_init(&cp, NULL, 1024*1024);
|
||||||
pool = pj_pool_create(&cp.factory, "pool1", 4000, 4000, NULL);
|
pool = pj_pool_create(&cp.factory, "pool1", 4000, 4000, NULL);
|
||||||
|
@ -366,7 +378,7 @@ int main(int argc, char *argv[]) {
|
||||||
status = pjsua_start();
|
status = pjsua_start();
|
||||||
if (status != PJ_SUCCESS) error_exit("Error starting pjsua", status);
|
if (status != PJ_SUCCESS) error_exit("Error starting pjsua", status);
|
||||||
|
|
||||||
if (has_sip_user)
|
if (has_sip_user)
|
||||||
{
|
{
|
||||||
pjsua_acc_config cfg;
|
pjsua_acc_config cfg;
|
||||||
pjsua_acc_config_default(&cfg);
|
pjsua_acc_config_default(&cfg);
|
||||||
|
@ -387,21 +399,20 @@ int main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("acc add local\n");
|
status == pjsua_acc_add_local(transport_id, 1, &acc_id);
|
||||||
status == pjsua_acc_add_local(transport_id, 1, &acc_id);
|
|
||||||
if (status != PJ_SUCCESS) error_exit("Error adding local account", status);
|
if (status != PJ_SUCCESS) error_exit("Error adding local account", status);
|
||||||
}
|
}
|
||||||
pjsua_get_var()->tpdata[transport_id].has_bound_addr = PJ_TRUE;
|
pjsua_get_var()->tpdata[transport_id].has_bound_addr = PJ_TRUE;
|
||||||
if (getenv("PJSIP_IPV6"))
|
if (getenv("PJSIP_IPV6"))
|
||||||
pjsua_get_var()->acc[acc_id].cfg.ipv6_media_use = PJSUA_IPV6_ENABLED;
|
pjsua_get_var()->acc[acc_id].cfg.ipv6_media_use = PJSUA_IPV6_ENABLED;
|
||||||
|
|
||||||
start_pa();
|
start_pa();
|
||||||
if(mode == DMODEM_DIAL_MODE) {
|
if(mode == DMODEM_DIAL_MODE) {
|
||||||
if (has_sip_user)
|
if (has_sip_user)
|
||||||
snprintf(buf,sizeof(buf),"sip:%s@%s",dialstr,sip_domain);
|
snprintf(buf,sizeof(buf),"sip:%s@%s",dialstr,sip_domain);
|
||||||
else
|
else
|
||||||
snprintf(buf,sizeof(buf),"sip:%s",dialstr);
|
snprintf(buf,sizeof(buf),"sip:%s",dialstr);
|
||||||
printf("calling %s\n",buf);
|
PJ_LOG(2,(__FILE__, "calling %s\n",buf));
|
||||||
pj_str_t uri = pj_str(buf);
|
pj_str_t uri = pj_str(buf);
|
||||||
pjsua_call_id callid;
|
pjsua_call_id callid;
|
||||||
status = pjsua_call_make_call(acc_id, &uri, 0, NULL, NULL, &callid);
|
status = pjsua_call_make_call(acc_id, &uri, 0, NULL, NULL, &callid);
|
||||||
|
@ -412,10 +423,10 @@ int main(int argc, char *argv[]) {
|
||||||
while(1) {
|
while(1) {
|
||||||
if(mode == DMODEM_ANSWER_MODE) {
|
if(mode == DMODEM_ANSWER_MODE) {
|
||||||
if(ringing) {
|
if(ringing) {
|
||||||
status = pjsua_call_answer(incoming, 200, NULL, NULL);
|
status = pjsua_call_answer(incoming, 200, NULL, NULL);
|
||||||
if (status != PJ_SUCCESS) error_exit("Error answering call", status);
|
if (status != PJ_SUCCESS) error_exit("Error answering call", status);
|
||||||
ringing = 0;
|
ringing = 0;
|
||||||
answered = 1;
|
answered = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nanosleep(&ts,NULL);
|
nanosleep(&ts,NULL);
|
||||||
|
|
|
@ -217,19 +217,19 @@ static int alsa_device_setup(struct device_struct *dev, const char *dev_name)
|
||||||
ret = snd_pcm_open(&dev->phandle, dev_name, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
|
ret = snd_pcm_open(&dev->phandle, dev_name, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
|
||||||
if(ret < 0) {
|
if(ret < 0) {
|
||||||
ERR("alsa setup: cannot open playback device '%s': %s\n",
|
ERR("alsa setup: cannot open playback device '%s': %s\n",
|
||||||
dev_name, snd_strerror(ret));
|
dev_name, snd_strerror(ret));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ret = snd_pcm_open(&dev->chandle, dev_name, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
|
ret = snd_pcm_open(&dev->chandle, dev_name, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
|
||||||
if(ret < 0) {
|
if(ret < 0) {
|
||||||
ERR("alsa setup: cannot open playback device '%s': %s\n",
|
ERR("alsa setup: cannot open playback device '%s': %s\n",
|
||||||
dev_name, snd_strerror(ret));
|
dev_name, snd_strerror(ret));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ret = snd_pcm_poll_descriptors(dev->chandle, &pfd, 1);
|
ret = snd_pcm_poll_descriptors(dev->chandle, &pfd, 1);
|
||||||
if(ret <= 0) {
|
if(ret <= 0) {
|
||||||
ERR("alsa setup: cannot get poll descriptors of '%s': %s\n",
|
ERR("alsa setup: cannot get poll descriptors of '%s': %s\n",
|
||||||
dev_name, snd_strerror(ret));
|
dev_name, snd_strerror(ret));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
dev->fd = pfd.fd;
|
dev->fd = pfd.fd;
|
||||||
|
@ -313,7 +313,7 @@ static int alsa_device_write(struct device_struct *dev, const char *buf, int cou
|
||||||
if (ret == -EAGAIN)
|
if (ret == -EAGAIN)
|
||||||
continue;
|
continue;
|
||||||
if (ret == -EPIPE) {
|
if (ret == -EPIPE) {
|
||||||
ret = alsa_xrun_recovery(dev);
|
ret = alsa_xrun_recovery(dev);
|
||||||
}
|
}
|
||||||
written = ret;
|
written = ret;
|
||||||
break;
|
break;
|
||||||
|
@ -373,7 +373,7 @@ static int setup_stream(snd_pcm_t *handle, struct modem *m, const char *stream_n
|
||||||
ERR("cannot set format for %s: %s\n", stream_name, snd_strerror(err));
|
ERR("cannot set format for %s: %s\n", stream_name, snd_strerror(err));
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
err = snd_pcm_hw_params_set_channels(handle, hw_params, 1);
|
err = snd_pcm_hw_params_set_channels(handle, hw_params, 1);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
ERR("cannot set channels for %s: %s\n", stream_name, snd_strerror(err));
|
ERR("cannot set channels for %s: %s\n", stream_name, snd_strerror(err));
|
||||||
return err;
|
return err;
|
||||||
|
@ -386,7 +386,7 @@ static int setup_stream(snd_pcm_t *handle, struct modem *m, const char *stream_n
|
||||||
}
|
}
|
||||||
if ( rrate != rate ) {
|
if ( rrate != rate ) {
|
||||||
ERR("rate %d is not supported by %s (%d).\n",
|
ERR("rate %d is not supported by %s (%d).\n",
|
||||||
rate, stream_name, rrate);
|
rate, stream_name, rrate);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
rsize = size = dev->period ;
|
rsize = size = dev->period ;
|
||||||
|
@ -397,7 +397,7 @@ static int setup_stream(snd_pcm_t *handle, struct modem *m, const char *stream_n
|
||||||
}
|
}
|
||||||
if ( rsize < size ) {
|
if ( rsize < size ) {
|
||||||
ERR("period size %ld is not supported by %s (%ld).\n",
|
ERR("period size %ld is not supported by %s (%ld).\n",
|
||||||
size, stream_name, rsize);
|
size, stream_name, rsize);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
rsize = size = use_short_buffer ? rsize * dev->buf_periods : rsize * 32;
|
rsize = size = use_short_buffer ? rsize * dev->buf_periods : rsize * 32;
|
||||||
|
@ -408,7 +408,7 @@ static int setup_stream(snd_pcm_t *handle, struct modem *m, const char *stream_n
|
||||||
}
|
}
|
||||||
if ( rsize != size ) {
|
if ( rsize != size ) {
|
||||||
DBG("buffer size for %s is changed %ld -> %ld\n",
|
DBG("buffer size for %s is changed %ld -> %ld\n",
|
||||||
stream_name, size, rsize);
|
stream_name, size, rsize);
|
||||||
}
|
}
|
||||||
err = snd_pcm_hw_params(handle, hw_params);
|
err = snd_pcm_hw_params(handle, hw_params);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
|
@ -523,9 +523,9 @@ static int alsa_ioctl(struct modem *m, unsigned int cmd, unsigned long arg)
|
||||||
struct device_struct *dev = m->dev_data;
|
struct device_struct *dev = m->dev_data;
|
||||||
DBG("alsa_ioctl: cmd %x, arg %lx...\n",cmd,arg);
|
DBG("alsa_ioctl: cmd %x, arg %lx...\n",cmd,arg);
|
||||||
switch(cmd) {
|
switch(cmd) {
|
||||||
case MDMCTL_CAPABILITIES:
|
case MDMCTL_CAPABILITIES:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
case MDMCTL_HOOKSTATE:
|
case MDMCTL_HOOKSTATE:
|
||||||
return (dev->hook_off_elem) ?
|
return (dev->hook_off_elem) ?
|
||||||
snd_mixer_selem_set_playback_switch_all(
|
snd_mixer_selem_set_playback_switch_all(
|
||||||
dev->hook_off_elem,
|
dev->hook_off_elem,
|
||||||
|
@ -534,9 +534,9 @@ static int alsa_ioctl(struct modem *m, unsigned int cmd, unsigned long arg)
|
||||||
return (dev->speaker_elem) ?
|
return (dev->speaker_elem) ?
|
||||||
snd_mixer_selem_set_playback_volume_all(
|
snd_mixer_selem_set_playback_volume_all(
|
||||||
dev->speaker_elem, arg) : 0 ;
|
dev->speaker_elem, arg) : 0 ;
|
||||||
case MDMCTL_CODECTYPE:
|
case MDMCTL_CODECTYPE:
|
||||||
return CODEC_SILABS;
|
return CODEC_SILABS;
|
||||||
case MDMCTL_IODELAY:
|
case MDMCTL_IODELAY:
|
||||||
DBG("delay = %d\n", dev->delay);
|
DBG("delay = %d\n", dev->delay);
|
||||||
return dev->delay;
|
return dev->delay;
|
||||||
default:
|
default:
|
||||||
|
@ -547,10 +547,10 @@ static int alsa_ioctl(struct modem *m, unsigned int cmd, unsigned long arg)
|
||||||
|
|
||||||
|
|
||||||
struct modem_driver alsa_modem_driver = {
|
struct modem_driver alsa_modem_driver = {
|
||||||
.name = "alsa modem driver",
|
.name = "alsa modem driver",
|
||||||
.start = alsa_start,
|
.start = alsa_start,
|
||||||
.stop = alsa_stop,
|
.stop = alsa_stop,
|
||||||
.ioctl = alsa_ioctl,
|
.ioctl = alsa_ioctl,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -568,7 +568,7 @@ static int modemap_start (struct modem *m)
|
||||||
int ret;
|
int ret;
|
||||||
DBG("modemap_start...\n");
|
DBG("modemap_start...\n");
|
||||||
dev->delay = 0;
|
dev->delay = 0;
|
||||||
ret = ioctl(dev->fd,100000+MDMCTL_START,0);
|
ret = ioctl(dev->fd,100000+MDMCTL_START,0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
ret = 192*2;
|
ret = 192*2;
|
||||||
|
@ -586,7 +586,7 @@ static int modemap_stop (struct modem *m)
|
||||||
{
|
{
|
||||||
struct device_struct *dev = m->dev_data;
|
struct device_struct *dev = m->dev_data;
|
||||||
DBG("modemap_stop...\n");
|
DBG("modemap_stop...\n");
|
||||||
return ioctl(dev->fd,100000+MDMCTL_STOP,0);
|
return ioctl(dev->fd,100000+MDMCTL_STOP,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int modemap_ioctl(struct modem *m, unsigned int cmd, unsigned long arg)
|
static int modemap_ioctl(struct modem *m, unsigned int cmd, unsigned long arg)
|
||||||
|
@ -607,10 +607,10 @@ static int modemap_ioctl(struct modem *m, unsigned int cmd, unsigned long arg)
|
||||||
|
|
||||||
|
|
||||||
struct modem_driver mdm_modem_driver = {
|
struct modem_driver mdm_modem_driver = {
|
||||||
.name = "modemap driver",
|
.name = "modemap driver",
|
||||||
.start = modemap_start,
|
.start = modemap_start,
|
||||||
.stop = modemap_stop,
|
.stop = modemap_stop,
|
||||||
.ioctl = modemap_ioctl,
|
.ioctl = modemap_ioctl,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int socket_start (struct modem *m)
|
static int socket_start (struct modem *m)
|
||||||
|
@ -626,22 +626,27 @@ static int socket_start (struct modem *m)
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pid_t ppid = getpid();
|
||||||
pid_t pid = fork();
|
pid_t pid = fork();
|
||||||
if (pid == -1) {
|
if (pid == -1) {
|
||||||
perror("fork");
|
perror("fork");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
if (pid == 0) { // child
|
if (pid == 0) { // child
|
||||||
char str[16];
|
char _str[12];
|
||||||
snprintf(str,sizeof(str),"%d",sockets[0]);
|
char _parent[12];
|
||||||
|
snprintf(_str,sizeof(_str),"%d",sockets[0]);
|
||||||
|
snprintf(_parent,sizeof(_parent),"%d",ppid);
|
||||||
|
char *_modem_path = strrchr(modem_dev_name, '/');
|
||||||
|
_modem_path = _modem_path == NULL ? modem_dev_name : _modem_path + 1;
|
||||||
close(sockets[1]);
|
close(sockets[1]);
|
||||||
if(_MODEM_DO_ANSWER) {
|
if(_MODEM_DO_ANSWER) {
|
||||||
DBG("MODEM_ANSW execl arg: %s, %s, %s\n",modem_exec,"rr",str);
|
DBG("MODEM_ANSW execl arg: %s, %s, %s, %s, %s\n",modem_exec,"rr",_str,_parent,_modem_path);
|
||||||
ret = execl(modem_exec,modem_exec,"rr",str,NULL);
|
ret = execl(modem_exec,modem_exec,"rr",_str,_parent,_modem_path,NULL);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DBG("MODEM_DIAL execl arg: %s, %s, %s\n",modem_exec,m->dial_string,str);
|
DBG("MODEM_DIAL execl arg: %s, %s, %s, %s, %s\n",modem_exec,"rr",_str,_parent,_modem_path);
|
||||||
ret = execl(modem_exec,modem_exec,m->dial_string,str,NULL);
|
ret = execl(modem_exec,modem_exec,m->dial_string,_str,_parent,_modem_path,NULL);
|
||||||
}
|
}
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
ERR("prog: %s\n", modem_exec);
|
ERR("prog: %s\n", modem_exec);
|
||||||
|
@ -715,10 +720,10 @@ static int socket_ioctl(struct modem *m, unsigned int cmd, unsigned long arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct modem_driver socket_modem_driver = {
|
struct modem_driver socket_modem_driver = {
|
||||||
.name = "socket driver",
|
.name = "socket driver",
|
||||||
.start = socket_start,
|
.start = socket_start,
|
||||||
.stop = socket_stop,
|
.stop = socket_stop,
|
||||||
.ioctl = socket_ioctl,
|
.ioctl = socket_ioctl,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int mdm_device_read(struct device_struct *dev, char *buf, int size)
|
static int mdm_device_read(struct device_struct *dev, char *buf, int size)
|
||||||
|
@ -790,11 +795,11 @@ int create_pty(struct modem *m)
|
||||||
if(m->pty)
|
if(m->pty)
|
||||||
close(m->pty);
|
close(m->pty);
|
||||||
|
|
||||||
pty = getpt();
|
pty = getpt();
|
||||||
if (pty < 0 || grantpt(pty) < 0 || unlockpt(pty) < 0) {
|
if (pty < 0 || grantpt(pty) < 0 || unlockpt(pty) < 0) {
|
||||||
ERR("getpt: %s\n", strerror(errno));
|
ERR("getpt: %s\n", strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m->pty) {
|
if(m->pty) {
|
||||||
termios = m->termios;
|
termios = m->termios;
|
||||||
|
@ -807,11 +812,11 @@ int create_pty(struct modem *m)
|
||||||
cfsetospeed(&termios, B115200);
|
cfsetospeed(&termios, B115200);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = tcsetattr(pty, TCSANOW, &termios);
|
ret = tcsetattr(pty, TCSANOW, &termios);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ERR("tcsetattr: %s\n",strerror(errno));
|
ERR("tcsetattr: %s\n",strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fcntl(pty,F_SETFL,O_NONBLOCK);
|
fcntl(pty,F_SETFL,O_NONBLOCK);
|
||||||
|
|
||||||
|
@ -822,18 +827,18 @@ int create_pty(struct modem *m)
|
||||||
|
|
||||||
modem_update_termios(m,&termios);
|
modem_update_termios(m,&termios);
|
||||||
|
|
||||||
modem_group = NULL;
|
modem_group = NULL;
|
||||||
if(modem_group && *modem_group) {
|
if(modem_group && *modem_group) {
|
||||||
struct group *grp = getgrnam(modem_group);
|
struct group *grp = getgrnam(modem_group);
|
||||||
if(!grp) {
|
if(!grp) {
|
||||||
ERR("cannot find group '%s': %s\n", modem_group,
|
ERR("cannot find group '%s': %s\n", modem_group,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ret = chown(pty_name, -1, grp->gr_gid);
|
ret = chown(pty_name, -1, grp->gr_gid);
|
||||||
if(ret < 0) {
|
if(ret < 0) {
|
||||||
ERR("cannot chown '%s' to ':%s': %s\n",
|
ERR("cannot chown '%s' to ':%s': %s\n",
|
||||||
pty_name, modem_group, strerror(errno));
|
pty_name, modem_group, strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -841,19 +846,19 @@ int create_pty(struct modem *m)
|
||||||
ret = chmod(pty_name, modem_perm);
|
ret = chmod(pty_name, modem_perm);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
ERR("cannot chmod '%s' to %o: %s\n",
|
ERR("cannot chmod '%s' to %o: %s\n",
|
||||||
pty_name, modem_perm, strerror(errno));
|
pty_name, modem_perm, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(*link_name) {
|
if(*link_name) {
|
||||||
unlink(link_name);
|
unlink(link_name);
|
||||||
if(symlink(pty_name,link_name)) {
|
if(symlink(pty_name,link_name)) {
|
||||||
ERR("cannot create symbolink link `%s' -> `%s': %s\n",
|
ERR("cannot create symbolink link `%s' -> `%s': %s\n",
|
||||||
link_name,pty_name,strerror(errno));
|
link_name,pty_name,strerror(errno));
|
||||||
*link_name = '\0';
|
*link_name = '\0';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
INFO("symbolic link `%s' -> `%s' created.\n",
|
INFO("symbolic link `%s' -> `%s' created.\n",
|
||||||
link_name, pty_name);
|
link_name, pty_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -901,9 +906,9 @@ static int modem_run(struct modem *m, struct device_struct *dev)
|
||||||
modem_ring_detector_start(m);
|
modem_ring_detector_start(m);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
tmo.tv_sec = 1;
|
tmo.tv_sec = 1;
|
||||||
tmo.tv_usec= 0;
|
tmo.tv_usec= 0;
|
||||||
FD_ZERO(&rset);
|
FD_ZERO(&rset);
|
||||||
FD_ZERO(&eset);
|
FD_ZERO(&eset);
|
||||||
if(m->started)
|
if(m->started)
|
||||||
FD_SET(dev->fd,&rset);
|
FD_SET(dev->fd,&rset);
|
||||||
|
@ -921,14 +926,14 @@ static int modem_run(struct modem *m, struct device_struct *dev)
|
||||||
if(m->pty > max_fd) max_fd = m->pty;
|
if(m->pty > max_fd) max_fd = m->pty;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = select(max_fd + 1,&rset,NULL,&eset,&tmo);
|
ret = select(max_fd + 1,&rset,NULL,&eset,&tmo);
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
continue;
|
continue;
|
||||||
ERR("select: %s\n",strerror(errno));
|
ERR("select: %s\n",strerror(errno));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ret == 0 )
|
if ( ret == 0 )
|
||||||
continue;
|
continue;
|
||||||
|
@ -1005,7 +1010,7 @@ static int modem_run(struct modem *m, struct device_struct *dev)
|
||||||
}
|
}
|
||||||
if(count != m->update_delay) {
|
if(count != m->update_delay) {
|
||||||
ERR("cannot update delay: %d instead of %d.\n",
|
ERR("cannot update delay: %d instead of %d.\n",
|
||||||
count, m->update_delay);
|
count, m->update_delay);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
dev->delay += m->update_delay;
|
dev->delay += m->update_delay;
|
||||||
|
@ -1106,7 +1111,7 @@ int modem_main(const char *dev_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
INFO("modem `%s' created. TTY is `%s'\n",
|
INFO("modem `%s' created. TTY is `%s'\n",
|
||||||
m->name, m->pty_name);
|
m->name, m->pty_name);
|
||||||
|
|
||||||
// sprintf(path_name,"/var/lib/slmodem/data.%s",basename(dev_name));
|
// sprintf(path_name,"/var/lib/slmodem/data.%s",basename(dev_name));
|
||||||
// datafile_load_info(path_name,&m->dsp_info);
|
// datafile_load_info(path_name,&m->dsp_info);
|
||||||
|
@ -1150,11 +1155,11 @@ int modem_main(const char *dev_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = (setgroups(1,&pwd->pw_gid) ||
|
ret = (setgroups(1,&pwd->pw_gid) ||
|
||||||
setgid(pwd->pw_gid) ||
|
setgid(pwd->pw_gid) ||
|
||||||
setuid(pwd->pw_uid));
|
setuid(pwd->pw_uid));
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ERR("setgroups or setgid %ld or setuid %ld failed: %s\n",
|
ERR("setgroups or setgid %ld or setuid %ld failed: %s\n",
|
||||||
(long)pwd->pw_gid,(long)pwd->pw_uid,strerror(errno));
|
(long)pwd->pw_gid,(long)pwd->pw_uid,strerror(errno));
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1163,11 +1168,11 @@ int modem_main(const char *dev_name)
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
DBG("dropped privileges to %ld.%ld\n",
|
DBG("dropped privileges to %ld.%ld\n",
|
||||||
(long)pwd->pw_gid,(long)pwd->pw_uid);
|
(long)pwd->pw_gid,(long)pwd->pw_uid);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
INFO("Use `%s' as modem device, Ctrl+C for termination.\n",
|
INFO("Use `%s' as modem device, Ctrl+C for termination.\n",
|
||||||
*link_name ? link_name : m->pty_name);
|
*link_name ? link_name : m->pty_name);
|
||||||
|
|
||||||
/* main loop here */
|
/* main loop here */
|
||||||
ret = modem_run(m,&device);
|
ret = modem_run(m,&device);
|
||||||
|
|
Loading…
Reference in a new issue