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_s2 = NULL;
|
||||
const pa_sample_spec pa_ss = {
|
||||
.format = PA_SAMPLE_S16LE,
|
||||
.rate = 9600,
|
||||
.channels = 1
|
||||
.format = PA_SAMPLE_S16LE,
|
||||
.rate = 9600,
|
||||
.channels = 1
|
||||
};
|
||||
#endif
|
||||
#ifdef PCM_FILE
|
||||
|
@ -54,6 +54,7 @@ int wave_transmit = -1;
|
|||
uint8_t mode = DMODEM_DIAL_MODE;
|
||||
uint8_t ringing = 0;
|
||||
uint8_t answered = 0;
|
||||
int ppid;
|
||||
pjsua_call_id incoming;
|
||||
|
||||
struct dmodem {
|
||||
|
@ -72,65 +73,65 @@ static void error_exit(const char *title, pj_status_t status) {
|
|||
if (!destroying) {
|
||||
destroying = true;
|
||||
pjsua_destroy();
|
||||
stop_pa();
|
||||
if (answered)
|
||||
execl("/bin/sh", "/bin/sh", "-cx", "kill -INT $PPID", NULL);
|
||||
stop_pa();
|
||||
if (answered)
|
||||
kill(ppid, SIGINT);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void start_pa() {
|
||||
#ifdef PCM_FILE
|
||||
char _wavbuf[50];
|
||||
sprintf(_wavbuf, PCM_FILE, "recv");
|
||||
wave_recv = open(_wavbuf, O_WRONLY | O_CREAT, 00644);
|
||||
sprintf(_wavbuf, PCM_FILE, "transmit");
|
||||
wave_recv = open(_wavbuf, O_WRONLY | O_CREAT, 00644);
|
||||
if (wave_recv <= 0 || wave_transmit <= 0)
|
||||
error_exit("open wave files", 1);
|
||||
char _wavbuf[50];
|
||||
sprintf(_wavbuf, PCM_FILE, "recv");
|
||||
wave_recv = open(_wavbuf, O_WRONLY | O_CREAT, 00644);
|
||||
sprintf(_wavbuf, PCM_FILE, "transmit");
|
||||
wave_recv = open(_wavbuf, O_WRONLY | O_CREAT, 00644);
|
||||
if (wave_recv <= 0 || wave_transmit <= 0)
|
||||
error_exit("open wave files", 1);
|
||||
#endif
|
||||
#ifdef HAS_PULSE
|
||||
pa_s1 = pa_simple_new(NULL, // Use the default server.
|
||||
"dmodem", // Our application's name.
|
||||
PA_STREAM_PLAYBACK,
|
||||
NULL, // Use the default device.
|
||||
"recv", // Description of our stream.
|
||||
&pa_ss, // Our sample format.
|
||||
NULL, // Use default channel map
|
||||
NULL, // Use default buffering attributes.
|
||||
NULL // Ignore error code.
|
||||
);
|
||||
pa_s2 = pa_simple_new(NULL, // Use the default server.
|
||||
"dmodem", // Our application's name.
|
||||
PA_STREAM_PLAYBACK,
|
||||
NULL, // Use the default device.
|
||||
"transmit", // Description of our stream.
|
||||
&pa_ss, // Our sample format.
|
||||
NULL, // Use default channel map
|
||||
NULL, // Use default buffering attributes.
|
||||
NULL // Ignore error code.
|
||||
);
|
||||
if (!pa_s1 || !pa_s2)
|
||||
error_exit("pulseaudio", 1);
|
||||
pa_s1 = pa_simple_new(NULL, // Use the default server.
|
||||
"dmodem", // Our application's name.
|
||||
PA_STREAM_PLAYBACK,
|
||||
NULL, // Use the default device.
|
||||
"recv", // Description of our stream.
|
||||
&pa_ss, // Our sample format.
|
||||
NULL, // Use default channel map
|
||||
NULL, // Use default buffering attributes.
|
||||
NULL // Ignore error code.
|
||||
);
|
||||
pa_s2 = pa_simple_new(NULL, // Use the default server.
|
||||
"dmodem", // Our application's name.
|
||||
PA_STREAM_PLAYBACK,
|
||||
NULL, // Use the default device.
|
||||
"transmit", // Description of our stream.
|
||||
&pa_ss, // Our sample format.
|
||||
NULL, // Use default channel map
|
||||
NULL, // Use default buffering attributes.
|
||||
NULL // Ignore error code.
|
||||
);
|
||||
if (!pa_s1 || !pa_s2)
|
||||
error_exit("pulseaudio", 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
void stop_pa() {
|
||||
#ifdef HAS_PULSE
|
||||
if(pa_s1)
|
||||
pa_simple_free(pa_s1);
|
||||
if(pa_s2)
|
||||
pa_simple_free(pa_s2);
|
||||
pa_s1 = 0;
|
||||
pa_s1 = 0;
|
||||
if(pa_s1)
|
||||
pa_simple_free(pa_s1);
|
||||
if(pa_s2)
|
||||
pa_simple_free(pa_s2);
|
||||
pa_s1 = 0;
|
||||
pa_s1 = 0;
|
||||
#endif
|
||||
#ifdef PCM_FILE
|
||||
if (wave_recv >= 0)
|
||||
close(wave_recv);
|
||||
if (wave_transmit >= 0)
|
||||
close(wave_transmit);
|
||||
wave_recv = -1;
|
||||
wave_transmit = -1;
|
||||
if (wave_recv >= 0)
|
||||
close(wave_recv);
|
||||
if (wave_transmit >= 0)
|
||||
close(wave_transmit);
|
||||
wave_recv = -1;
|
||||
wave_transmit = -1;
|
||||
#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) {
|
||||
#ifdef HAS_PULSE
|
||||
pa_simple_write(pa_s1, frame->buf, frame->size, NULL);
|
||||
pa_simple_write(pa_s1, frame->buf, frame->size, NULL);
|
||||
#endif
|
||||
#ifdef PCM_FILE
|
||||
write(wave_recv, frame->buf, frame->size);
|
||||
write(wave_recv, frame->buf, frame->size);
|
||||
#endif
|
||||
if ((len=write(sm->sock, frame->buf, frame->size)) != frame->size) {
|
||||
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;
|
||||
sm->timestamp.u64 += PJMEDIA_PIA_SPF(&this_port->info);
|
||||
#ifdef HAS_PULSE
|
||||
pa_simple_write(pa_s2, frame->buf, frame->size, NULL);
|
||||
pa_simple_write(pa_s2, frame->buf, frame->size, NULL);
|
||||
#endif
|
||||
#ifdef PCM_FILE
|
||||
write(wave_transmit, frame->buf, frame->size);
|
||||
write(wave_transmit, frame->buf, frame->size);
|
||||
#endif
|
||||
|
||||
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) {
|
||||
printf("destroy\n");
|
||||
if (answered)
|
||||
execl("/bin/sh", "/bin/sh", "-cx", "kill -INT $PPID", NULL);
|
||||
if (answered)
|
||||
kill(ppid, SIGINT);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
@ -199,8 +200,8 @@ static void on_call_state(pjsua_call_id call_id, pjsip_event *e) {
|
|||
destroying = true;
|
||||
pjsua_destroy();
|
||||
stop_pa();
|
||||
if (answered)
|
||||
execl("/bin/sh", "/bin/sh", "-cx", "kill -INT $PPID", NULL);
|
||||
if (answered)
|
||||
kill(ppid, SIGINT);
|
||||
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);
|
||||
strcpy(tmp, ci.remote_contact.ptr);
|
||||
tmp[pj_strlen(&ci.remote_contact)] = '\0';
|
||||
if (answered) {
|
||||
printf("Incoming call rejected from: %s\n", tmp);
|
||||
pjsua_call_hangup(call_id, 0u, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
printf("Incoming call from: %s\n", tmp);
|
||||
if (answered) {
|
||||
PJ_LOG(2,(__FILE__, "Incoming call rejected from: %s", tmp));
|
||||
pjsua_call_hangup(call_id, 0u, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
PJ_LOG(2,(__FILE__, "Incoming call from: %s", tmp));
|
||||
free(tmp);
|
||||
incoming = call_id;
|
||||
ringing = 1;
|
||||
|
@ -247,23 +248,35 @@ static void on_call_media_state(pjsua_call_id call_id) {
|
|||
int main(int argc, char *argv[]) {
|
||||
pjsua_acc_id acc_id;
|
||||
pj_status_t status;
|
||||
if (argc != 3) {
|
||||
if (argc != 5) {
|
||||
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)) {
|
||||
mode = DMODEM_ANSWER_MODE;
|
||||
}
|
||||
signal(SIGPIPE,SIG_IGN);
|
||||
char *dialstr = argv[1];
|
||||
|
||||
int has_sip_user = 1;
|
||||
int has_sip_user = 1;
|
||||
char *sip_user = getenv("SIP_LOGIN");
|
||||
if (!sip_user) {
|
||||
has_sip_user = 0;
|
||||
printf("[!] SIP_LOGIN is empty, no registration will be attempted\n");
|
||||
char sip_user_buf[40];
|
||||
strcpy(sip_user_buf, "placeholder:placeholder@placeholder");
|
||||
sip_user = sip_user_buf;
|
||||
has_sip_user = 0;
|
||||
printf("[!] SIP_LOGIN is empty, no registration will be attempted\n");
|
||||
char sip_user_buf[40];
|
||||
strcpy(sip_user_buf, "placeholder:placeholder@placeholder");
|
||||
sip_user = sip_user_buf;
|
||||
}
|
||||
if (!sip_user) {
|
||||
return -1;
|
||||
|
@ -297,17 +310,16 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
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);
|
||||
med_cfg.no_vad = true;
|
||||
med_cfg.ec_tail_len = 0;
|
||||
med_cfg.jb_max = 2000;
|
||||
// med_cfg.jb_init = 200;
|
||||
/* // med_cfg.jb_init = 200 */
|
||||
// med_cfg.jb_init = 0;
|
||||
/* med_cfg.audio_frame_ptime = 5; */
|
||||
med_cfg.jb_max = -1;
|
||||
med_cfg.jb_init = -1;
|
||||
med_cfg.audio_frame_ptime = 10;
|
||||
med_cfg.quality = 10;
|
||||
|
||||
status = pjsua_init(&cfg, &log_cfg, &med_cfg);
|
||||
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);
|
||||
}
|
||||
|
||||
pjsua_transport_id transport_id;
|
||||
pjsua_transport_id transport_id;
|
||||
/* Add UDP transport. */
|
||||
{
|
||||
pjsua_transport_config cfg;
|
||||
|
||||
pjsua_transport_config_default(&cfg);
|
||||
if (mode)
|
||||
cfg.port = 5160;
|
||||
if (getenv("PJSIP_IPV6"))
|
||||
cfg.port = sip_port;
|
||||
if (getenv("PJSIP_IPV6"))
|
||||
status = pjsua_transport_create(PJSIP_TRANSPORT_UDP6, &cfg, &transport_id);
|
||||
else
|
||||
else
|
||||
status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &cfg, &transport_id);
|
||||
if (status != PJ_SUCCESS) error_exit("Error creating transport", status);
|
||||
}
|
||||
char buf[384];
|
||||
printf("Initializing pool\n");
|
||||
//printf("Initializing pool\n");
|
||||
pj_caching_pool cp;
|
||||
pj_caching_pool_init(&cp, NULL, 1024*1024);
|
||||
pool = pj_pool_create(&cp.factory, "pool1", 4000, 4000, NULL);
|
||||
|
@ -366,7 +378,7 @@ int main(int argc, char *argv[]) {
|
|||
status = pjsua_start();
|
||||
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_default(&cfg);
|
||||
|
@ -387,21 +399,20 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
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);
|
||||
}
|
||||
pjsua_get_var()->tpdata[transport_id].has_bound_addr = PJ_TRUE;
|
||||
if (getenv("PJSIP_IPV6"))
|
||||
pjsua_get_var()->acc[acc_id].cfg.ipv6_media_use = PJSUA_IPV6_ENABLED;
|
||||
if (getenv("PJSIP_IPV6"))
|
||||
pjsua_get_var()->acc[acc_id].cfg.ipv6_media_use = PJSUA_IPV6_ENABLED;
|
||||
|
||||
start_pa();
|
||||
start_pa();
|
||||
if(mode == DMODEM_DIAL_MODE) {
|
||||
if (has_sip_user)
|
||||
snprintf(buf,sizeof(buf),"sip:%s@%s",dialstr,sip_domain);
|
||||
else
|
||||
snprintf(buf,sizeof(buf),"sip:%s",dialstr);
|
||||
printf("calling %s\n",buf);
|
||||
if (has_sip_user)
|
||||
snprintf(buf,sizeof(buf),"sip:%s@%s",dialstr,sip_domain);
|
||||
else
|
||||
snprintf(buf,sizeof(buf),"sip:%s",dialstr);
|
||||
PJ_LOG(2,(__FILE__, "calling %s\n",buf));
|
||||
pj_str_t uri = pj_str(buf);
|
||||
pjsua_call_id 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) {
|
||||
if(mode == DMODEM_ANSWER_MODE) {
|
||||
if(ringing) {
|
||||
status = pjsua_call_answer(incoming, 200, NULL, NULL);
|
||||
if (status != PJ_SUCCESS) error_exit("Error answering call", status);
|
||||
ringing = 0;
|
||||
answered = 1;
|
||||
status = pjsua_call_answer(incoming, 200, NULL, NULL);
|
||||
if (status != PJ_SUCCESS) error_exit("Error answering call", status);
|
||||
ringing = 0;
|
||||
answered = 1;
|
||||
}
|
||||
}
|
||||
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);
|
||||
if(ret < 0) {
|
||||
ERR("alsa setup: cannot open playback device '%s': %s\n",
|
||||
dev_name, snd_strerror(ret));
|
||||
dev_name, snd_strerror(ret));
|
||||
return -1;
|
||||
}
|
||||
ret = snd_pcm_open(&dev->chandle, dev_name, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
|
||||
if(ret < 0) {
|
||||
ERR("alsa setup: cannot open playback device '%s': %s\n",
|
||||
dev_name, snd_strerror(ret));
|
||||
dev_name, snd_strerror(ret));
|
||||
return -1;
|
||||
}
|
||||
ret = snd_pcm_poll_descriptors(dev->chandle, &pfd, 1);
|
||||
if(ret <= 0) {
|
||||
ERR("alsa setup: cannot get poll descriptors of '%s': %s\n",
|
||||
dev_name, snd_strerror(ret));
|
||||
dev_name, snd_strerror(ret));
|
||||
return -1;
|
||||
}
|
||||
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)
|
||||
continue;
|
||||
if (ret == -EPIPE) {
|
||||
ret = alsa_xrun_recovery(dev);
|
||||
ret = alsa_xrun_recovery(dev);
|
||||
}
|
||||
written = ret;
|
||||
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));
|
||||
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) {
|
||||
ERR("cannot set channels for %s: %s\n", stream_name, snd_strerror(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 ) {
|
||||
ERR("rate %d is not supported by %s (%d).\n",
|
||||
rate, stream_name, rrate);
|
||||
rate, stream_name, rrate);
|
||||
return -1;
|
||||
}
|
||||
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 ) {
|
||||
ERR("period size %ld is not supported by %s (%ld).\n",
|
||||
size, stream_name, rsize);
|
||||
size, stream_name, rsize);
|
||||
return -1;
|
||||
}
|
||||
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 ) {
|
||||
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);
|
||||
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;
|
||||
DBG("alsa_ioctl: cmd %x, arg %lx...\n",cmd,arg);
|
||||
switch(cmd) {
|
||||
case MDMCTL_CAPABILITIES:
|
||||
return -EINVAL;
|
||||
case MDMCTL_HOOKSTATE:
|
||||
case MDMCTL_CAPABILITIES:
|
||||
return -EINVAL;
|
||||
case MDMCTL_HOOKSTATE:
|
||||
return (dev->hook_off_elem) ?
|
||||
snd_mixer_selem_set_playback_switch_all(
|
||||
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) ?
|
||||
snd_mixer_selem_set_playback_volume_all(
|
||||
dev->speaker_elem, arg) : 0 ;
|
||||
case MDMCTL_CODECTYPE:
|
||||
return CODEC_SILABS;
|
||||
case MDMCTL_IODELAY:
|
||||
case MDMCTL_CODECTYPE:
|
||||
return CODEC_SILABS;
|
||||
case MDMCTL_IODELAY:
|
||||
DBG("delay = %d\n", dev->delay);
|
||||
return dev->delay;
|
||||
default:
|
||||
|
@ -547,10 +547,10 @@ static int alsa_ioctl(struct modem *m, unsigned int cmd, unsigned long arg)
|
|||
|
||||
|
||||
struct modem_driver alsa_modem_driver = {
|
||||
.name = "alsa modem driver",
|
||||
.start = alsa_start,
|
||||
.stop = alsa_stop,
|
||||
.ioctl = alsa_ioctl,
|
||||
.name = "alsa modem driver",
|
||||
.start = alsa_start,
|
||||
.stop = alsa_stop,
|
||||
.ioctl = alsa_ioctl,
|
||||
};
|
||||
|
||||
|
||||
|
@ -568,7 +568,7 @@ static int modemap_start (struct modem *m)
|
|||
int ret;
|
||||
DBG("modemap_start...\n");
|
||||
dev->delay = 0;
|
||||
ret = ioctl(dev->fd,100000+MDMCTL_START,0);
|
||||
ret = ioctl(dev->fd,100000+MDMCTL_START,0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = 192*2;
|
||||
|
@ -586,7 +586,7 @@ static int modemap_stop (struct modem *m)
|
|||
{
|
||||
struct device_struct *dev = m->dev_data;
|
||||
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)
|
||||
|
@ -607,10 +607,10 @@ static int modemap_ioctl(struct modem *m, unsigned int cmd, unsigned long arg)
|
|||
|
||||
|
||||
struct modem_driver mdm_modem_driver = {
|
||||
.name = "modemap driver",
|
||||
.start = modemap_start,
|
||||
.stop = modemap_stop,
|
||||
.ioctl = modemap_ioctl,
|
||||
.name = "modemap driver",
|
||||
.start = modemap_start,
|
||||
.stop = modemap_stop,
|
||||
.ioctl = modemap_ioctl,
|
||||
};
|
||||
|
||||
static int socket_start (struct modem *m)
|
||||
|
@ -626,22 +626,27 @@ static int socket_start (struct modem *m)
|
|||
exit(-1);
|
||||
}
|
||||
|
||||
pid_t ppid = getpid();
|
||||
pid_t pid = fork();
|
||||
if (pid == -1) {
|
||||
perror("fork");
|
||||
exit(-1);
|
||||
}
|
||||
if (pid == 0) { // child
|
||||
char str[16];
|
||||
snprintf(str,sizeof(str),"%d",sockets[0]);
|
||||
char _str[12];
|
||||
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]);
|
||||
if(_MODEM_DO_ANSWER) {
|
||||
DBG("MODEM_ANSW execl arg: %s, %s, %s\n",modem_exec,"rr",str);
|
||||
ret = execl(modem_exec,modem_exec,"rr",str,NULL);
|
||||
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,_parent,_modem_path,NULL);
|
||||
}
|
||||
else {
|
||||
DBG("MODEM_DIAL execl arg: %s, %s, %s\n",modem_exec,m->dial_string,str);
|
||||
ret = execl(modem_exec,modem_exec,m->dial_string,str,NULL);
|
||||
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,_parent,_modem_path,NULL);
|
||||
}
|
||||
if (ret == -1) {
|
||||
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 = {
|
||||
.name = "socket driver",
|
||||
.start = socket_start,
|
||||
.stop = socket_stop,
|
||||
.ioctl = socket_ioctl,
|
||||
.name = "socket driver",
|
||||
.start = socket_start,
|
||||
.stop = socket_stop,
|
||||
.ioctl = socket_ioctl,
|
||||
};
|
||||
|
||||
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)
|
||||
close(m->pty);
|
||||
|
||||
pty = getpt();
|
||||
if (pty < 0 || grantpt(pty) < 0 || unlockpt(pty) < 0) {
|
||||
ERR("getpt: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
pty = getpt();
|
||||
if (pty < 0 || grantpt(pty) < 0 || unlockpt(pty) < 0) {
|
||||
ERR("getpt: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(m->pty) {
|
||||
termios = m->termios;
|
||||
|
@ -807,11 +812,11 @@ int create_pty(struct modem *m)
|
|||
cfsetospeed(&termios, B115200);
|
||||
}
|
||||
|
||||
ret = tcsetattr(pty, TCSANOW, &termios);
|
||||
if (ret) {
|
||||
ERR("tcsetattr: %s\n",strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
ret = tcsetattr(pty, TCSANOW, &termios);
|
||||
if (ret) {
|
||||
ERR("tcsetattr: %s\n",strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
fcntl(pty,F_SETFL,O_NONBLOCK);
|
||||
|
||||
|
@ -822,18 +827,18 @@ int create_pty(struct modem *m)
|
|||
|
||||
modem_update_termios(m,&termios);
|
||||
|
||||
modem_group = NULL;
|
||||
modem_group = NULL;
|
||||
if(modem_group && *modem_group) {
|
||||
struct group *grp = getgrnam(modem_group);
|
||||
if(!grp) {
|
||||
ERR("cannot find group '%s': %s\n", modem_group,
|
||||
strerror(errno));
|
||||
strerror(errno));
|
||||
}
|
||||
else {
|
||||
ret = chown(pty_name, -1, grp->gr_gid);
|
||||
if(ret < 0) {
|
||||
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);
|
||||
if (ret < 0) {
|
||||
ERR("cannot chmod '%s' to %o: %s\n",
|
||||
pty_name, modem_perm, strerror(errno));
|
||||
pty_name, modem_perm, strerror(errno));
|
||||
}
|
||||
|
||||
if(*link_name) {
|
||||
unlink(link_name);
|
||||
if(symlink(pty_name,link_name)) {
|
||||
ERR("cannot create symbolink link `%s' -> `%s': %s\n",
|
||||
link_name,pty_name,strerror(errno));
|
||||
link_name,pty_name,strerror(errno));
|
||||
*link_name = '\0';
|
||||
}
|
||||
else {
|
||||
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);
|
||||
#endif
|
||||
|
||||
tmo.tv_sec = 1;
|
||||
tmo.tv_usec= 0;
|
||||
FD_ZERO(&rset);
|
||||
tmo.tv_sec = 1;
|
||||
tmo.tv_usec= 0;
|
||||
FD_ZERO(&rset);
|
||||
FD_ZERO(&eset);
|
||||
if(m->started)
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
continue;
|
||||
ERR("select: %s\n",strerror(errno));
|
||||
return ret;
|
||||
}
|
||||
ERR("select: %s\n",strerror(errno));
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ( ret == 0 )
|
||||
continue;
|
||||
|
@ -1005,7 +1010,7 @@ static int modem_run(struct modem *m, struct device_struct *dev)
|
|||
}
|
||||
if(count != m->update_delay) {
|
||||
ERR("cannot update delay: %d instead of %d.\n",
|
||||
count, m->update_delay);
|
||||
count, m->update_delay);
|
||||
return -1;
|
||||
}
|
||||
dev->delay += m->update_delay;
|
||||
|
@ -1106,7 +1111,7 @@ int modem_main(const char *dev_name)
|
|||
}
|
||||
|
||||
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));
|
||||
// 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) ||
|
||||
setgid(pwd->pw_gid) ||
|
||||
setuid(pwd->pw_uid));
|
||||
setgid(pwd->pw_gid) ||
|
||||
setuid(pwd->pw_uid));
|
||||
if (ret) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -1163,11 +1168,11 @@ int modem_main(const char *dev_name)
|
|||
exit(-1);
|
||||
}
|
||||
DBG("dropped privileges to %ld.%ld\n",
|
||||
(long)pwd->pw_gid,(long)pwd->pw_uid);
|
||||
(long)pwd->pw_gid,(long)pwd->pw_uid);
|
||||
#endif
|
||||
|
||||
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 */
|
||||
ret = modem_run(m,&device);
|
||||
|
|
Loading…
Reference in a new issue