[Freeswitch-branches] [commit] r11719 - freeswitch/branches/gmaruzz/mod_skypiax
FreeSWITCH SVN
gmaruzz at freeswitch.org
Mon Feb 9 11:25:19 PST 2009
Author: gmaruzz
Date: Mon Feb 9 13:25:18 2009
New Revision: 11719
Log:
skypiax: cleaning skypiax_protocol.c
Modified:
freeswitch/branches/gmaruzz/mod_skypiax/mod_skypiax.c
freeswitch/branches/gmaruzz/mod_skypiax/skypiax_protocol.c
Modified: freeswitch/branches/gmaruzz/mod_skypiax/mod_skypiax.c
==============================================================================
--- freeswitch/branches/gmaruzz/mod_skypiax/mod_skypiax.c (original)
+++ freeswitch/branches/gmaruzz/mod_skypiax/mod_skypiax.c Mon Feb 9 13:25:18 2009
@@ -1058,13 +1058,16 @@
if (channel) {
switch_dtmf_t dtmf =
{ (char) value[0], switch_core_default_dtmf_duration(0) };
- DEBUGA_SKYPE("%c DTMF %s\n", SKYPIAX_P_LOG, dtmf.digit,
+ NOTICA("received DTMF %c on channel %s\n", SKYPIAX_P_LOG, dtmf.digit,
switch_channel_get_name(channel));
switch_mutex_lock(tech_pvt->flag_mutex);
+ //FIXME: why sometimes DTMFs from here do not seems to be get by FS?
switch_channel_queue_dtmf(channel, &dtmf);
switch_set_flag(tech_pvt, TFLAG_DTMF);
switch_mutex_unlock(tech_pvt->flag_mutex);
- }
+ } else {
+ WARNINGA("received %c DTMF, but no channel?\n", SKYPIAX_P_LOG, value[0]);
+ }
switch_core_session_rwunlock(session);
return 0;
Modified: freeswitch/branches/gmaruzz/mod_skypiax/skypiax_protocol.c
==============================================================================
--- freeswitch/branches/gmaruzz/mod_skypiax/skypiax_protocol.c (original)
+++ freeswitch/branches/gmaruzz/mod_skypiax/skypiax_protocol.c Mon Feb 9 13:25:18 2009
@@ -23,309 +23,8 @@
#endif /* WIN32 */
/*************************************/
-void *skypiax_do_tcp_srv_thread_func(void *obj)
-{
- private_t *tech_pvt = obj;
- int s;
- unsigned int len;
- unsigned int i;
- unsigned int a;
-#if defined(WIN32) && !defined(__CYGWIN__)
- int sin_size;
-#else /* WIN32 */
- unsigned int sin_size;
-#endif /* WIN32 */
- unsigned int fd;
- short srv_in[SAMPLES_PER_FRAME];
- short srv_out[SAMPLES_PER_FRAME / 2];
- struct sockaddr_in my_addr;
- struct sockaddr_in remote_addr;
- int exit = 0;
- unsigned int kill_cli_size;
- short kill_cli_buff[SAMPLES_PER_FRAME];
- short totalbuf[SAMPLES_PER_FRAME];
-
- memset(&my_addr, 0, sizeof(my_addr));
- my_addr.sin_family = AF_INET;
- my_addr.sin_addr.s_addr = htonl(0x7f000001); /* use the localhost */
- my_addr.sin_port = htons(tech_pvt->tcp_srv_port);
-
- if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- ERRORA("socket Error\n", SKYPIAX_P_LOG);
- return NULL;
- }
-
- if (bind(s, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) < 0) {
- ERRORA("bind Error\n", SKYPIAX_P_LOG);
- return NULL;
- }
- DEBUGA_SKYPE("started tcp_srv_thread thread.\n", SKYPIAX_P_LOG);
-
- listen(s, 6);
-
- sin_size = sizeof(remote_addr);
- while ((fd = accept(s, (struct sockaddr *) &remote_addr, &sin_size)) > 0) {
- DEBUGA_SKYPE("ACCEPTED\n", SKYPIAX_P_LOG);
- if (!running)
- break;
- while (tech_pvt->interface_state != SKYPIAX_STATE_DOWN
- && (tech_pvt->skype_callflow == CALLFLOW_STATUS_INPROGRESS
- || tech_pvt->skype_callflow == SKYPIAX_STATE_UP)) {
-
- unsigned int fdselect;
- int rt;
- fd_set fs;
- struct timeval to;
-
- if (!running)
- break;
- exit = 1;
-
- fdselect = fd;
- FD_ZERO(&fs);
- FD_SET(fdselect, &fs);
- to.tv_usec = 2000000; //2000 msec
- to.tv_sec = 0;
-
- rt = select(fdselect + 1, &fs, NULL, NULL, &to);
- if (rt > 0) {
-
- len = recv(fd, (char *) srv_in, 320, 0); //seems that Skype only sends 320 bytes at time
-
- if (len == 320) {
- unsigned int howmany;
-
- if (SAMPLERATE_SKYPIAX == 8000) {
- /* we're downsampling from 16khz to 8khz, srv_out will contain each other sample from srv_in */
- a = 0;
- for (i = 0; i < len / sizeof(short); i++) {
- srv_out[a] = srv_in[i];
- i++;
- a++;
- }
- } else if (SAMPLERATE_SKYPIAX == 16000) {
- /* we're NOT downsampling, srv_out will contain ALL samples from srv_in */
- for (i = 0; i < len / sizeof(short); i++) {
- srv_out[i] = srv_in[i];
- }
- } else {
- ERRORA("SAMPLERATE_SKYPIAX can only be 8000 or 16000\n", SKYPIAX_P_LOG);
- }
- /* if not yet done, let's store the half incoming frame */
- if (!tech_pvt->audiobuf_is_loaded) {
- for (i = 0; i < SAMPLES_PER_FRAME / 2; i++) {
- tech_pvt->audiobuf[i] = srv_out[i];
- }
- tech_pvt->audiobuf_is_loaded = 1;
- } else {
- /* we got a stored half frame, build a complete frame in totalbuf using the stored half frame and the current half frame */
- for (i = 0; i < SAMPLES_PER_FRAME / 2; i++) {
- totalbuf[i] = tech_pvt->audiobuf[i];
- }
- for (a = 0; a < SAMPLES_PER_FRAME / 2; a++) {
- totalbuf[i] = srv_out[a];
- i++;
- }
- /* send the complete frame through the pipe to our code waiting for incoming audio */
- howmany =
- skypiax_pipe_write(tech_pvt->audiopipe[1], totalbuf,
- SAMPLES_PER_FRAME * sizeof(short));
- if (howmany != SAMPLES_PER_FRAME * sizeof(short)) {
- ERRORA("howmany is %d, but was expected to be %d\n", SKYPIAX_P_LOG, howmany,
- SAMPLES_PER_FRAME * sizeof(short));
- }
- /* done with the stored half frame */
- tech_pvt->audiobuf_is_loaded = 0;
- }
-
- } else if (len == 0) {
- DEBUGA_SKYPE("Skype incoming audio GONE\n", SKYPIAX_P_LOG);
- skypiax_sleep(1000);
- } else {
- ERRORA("len=%d\n", SKYPIAX_P_LOG, len);
- exit = 1;
- break;
- }
-
- } else {
- if (rt)
- ERRORA("SRV rt=%d\n", SKYPIAX_P_LOG, rt);
- skypiax_sleep(10000);
- }
-
- }
-
- /* let's send some frame in the pipes, so both tcp_cli and tcp_srv will have an occasion to die */
- kill_cli_size = SAMPLES_PER_FRAME * sizeof(short);
- len = skypiax_pipe_write(tech_pvt->audiopipe[1], kill_cli_buff, kill_cli_size);
- kill_cli_size = SAMPLES_PER_FRAME * sizeof(short);
- len = skypiax_pipe_write(tech_pvt->audioskypepipe[1], kill_cli_buff, kill_cli_size);
- tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
- kill_cli_size = SAMPLES_PER_FRAME * sizeof(short);
- len = skypiax_pipe_write(tech_pvt->audiopipe[1], kill_cli_buff, kill_cli_size);
- kill_cli_size = SAMPLES_PER_FRAME * sizeof(short);
- len = skypiax_pipe_write(tech_pvt->audioskypepipe[1], kill_cli_buff, kill_cli_size);
-
- DEBUGA_SKYPE("Skype incoming audio GONE\n", SKYPIAX_P_LOG);
- skypiax_close_socket(fd);
- if (exit)
- break;
- }
-
- DEBUGA_SKYPE("incoming audio server (I am it) GONE\n", SKYPIAX_P_LOG);
- skypiax_close_socket(s);
- return NULL;
-}
-
-void *skypiax_do_tcp_cli_thread_func(void *obj)
-{
- private_t *tech_pvt = obj;
- int s;
- struct sockaddr_in my_addr;
- struct sockaddr_in remote_addr;
- unsigned int got;
- unsigned int len;
- unsigned int i;
- unsigned int a;
- unsigned int fd;
- short cli_out[SAMPLES_PER_FRAME * 2];
- short cli_in[SAMPLES_PER_FRAME];
-#ifdef WIN32
- int sin_size;
-#else
- unsigned int sin_size;
-#endif /* WIN32 */
-
- memset(&my_addr, 0, sizeof(my_addr));
- my_addr.sin_family = AF_INET;
- my_addr.sin_addr.s_addr = htonl(0x7f000001); /* use the localhost */
- my_addr.sin_port = htons(tech_pvt->tcp_cli_port);
-
- if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- ERRORA("socket Error\n", SKYPIAX_P_LOG);
- return NULL;
- }
-
- if (bind(s, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) < 0) {
- ERRORA("bind Error\n", SKYPIAX_P_LOG);
- skypiax_close_socket(s);
- return NULL;
- }
- DEBUGA_SKYPE("started tcp_cli_thread thread.\n", SKYPIAX_P_LOG);
-
- listen(s, 6);
-
- sin_size = sizeof(remote_addr);
- while ((fd = accept(s, (struct sockaddr *) &remote_addr, &sin_size)) > 0) {
- DEBUGA_SKYPE("ACCEPTED\n", SKYPIAX_P_LOG);
- if (!running)
- break;
- while (tech_pvt->interface_state != SKYPIAX_STATE_DOWN
- && (tech_pvt->skype_callflow == CALLFLOW_STATUS_INPROGRESS
- || tech_pvt->skype_callflow == SKYPIAX_STATE_UP)) {
- unsigned int fdselect;
- int rt;
- fd_set fs;
- struct timeval to;
-
- if (!running)
- break;
- fdselect = fd;
- FD_ZERO(&fs);
- FD_SET(fdselect, &fs);
- to.tv_usec = 2000000; //2000 msec
- to.tv_sec = 0;
-
- rt = select(fdselect + 1, NULL, &fs, NULL, &to);
-
- if (rt > 0) {
-
- /* read from the pipe the audio frame we are supposed to send out */
- got =
- skypiax_pipe_read(tech_pvt->audioskypepipe[0], cli_in,
- SAMPLES_PER_FRAME * sizeof(short));
- if (got != SAMPLES_PER_FRAME * sizeof(short)) {
- WARNINGA("got is %d, but was expected to be %d\n", SKYPIAX_P_LOG, got,
- SAMPLES_PER_FRAME * sizeof(short));
- }
-
- if (got == SAMPLES_PER_FRAME * sizeof(short)) {
- if (SAMPLERATE_SKYPIAX == 8000) {
-
- /* we're upsampling from 8khz to 16khz, cli_out will contain two times each sample from cli_in */
- a = 0;
- for (i = 0; i < got / sizeof(short); i++) {
- cli_out[a] = cli_in[i];
- a++;
- cli_out[a] = cli_in[i];
- a++;
- }
- got = got * 2;
- } else if (SAMPLERATE_SKYPIAX == 16000) {
- /* we're NOT upsampling, cli_out will contain just ALL samples from cli_in */
- for (i = 0; i < got / sizeof(short); i++) {
- cli_out[i] = cli_in[i];
- }
- } else {
- ERRORA("SAMPLERATE_SKYPIAX can only be 8000 or 16000\n", SKYPIAX_P_LOG);
- }
-
- /* send the 16khz frame to the Skype client waiting for incoming audio */
- len = send(fd, (char *) cli_out, got, 0);
-
- if (len == -1) {
- break;
- } else if (len != got) {
- ERRORA("len=%d\n", SKYPIAX_P_LOG, len);
- skypiax_sleep(1000);
- break;
- }
-
- } else {
-
- WARNINGA("got is %d, but was expected to be %d\n", SKYPIAX_P_LOG, got,
- SAMPLES_PER_FRAME * sizeof(short));
- }
- } else {
- if (rt)
- ERRORA("CLI rt=%d\n", SKYPIAX_P_LOG, rt);
- skypiax_sleep(10000);
- }
-
- }
- DEBUGA_SKYPE("Skype outbound audio GONE\n", SKYPIAX_P_LOG);
- skypiax_close_socket(fd);
- break;
- }
-
- DEBUGA_SKYPE("outbound audio server (I am it) GONE\n", SKYPIAX_P_LOG);
- skypiax_close_socket(s);
- return NULL;
-}
-
-int skypiax_skypeaudio_read(private_t * tech_pvt)
-{
- unsigned int samples;
-
- samples =
- skypiax_pipe_read(tech_pvt->audiopipe[0], tech_pvt->read_frame.data,
- SAMPLES_PER_FRAME * sizeof(short));
-
- if (samples != SAMPLES_PER_FRAME * sizeof(short)) {
- if (samples)
- WARNINGA("read samples=%u expected=%u\n", SKYPIAX_P_LOG, samples,
- SAMPLES_PER_FRAME * sizeof(short));
- return 0;
- } else {
- /* A real frame */
- tech_pvt->read_frame.datalen = samples;
- }
- return 1;
-}
-
int skypiax_skype_read(private_t * tech_pvt)
{
-
char read_from_pipe[4096];
char message[4096];
char message_2[4096];
@@ -361,9 +60,8 @@
skypiax_sleep(10000);
return 0;
}
-
if (!strncasecmp(message, "ERROR 92 CALL", 12)) {
- ERRORA("Skype got ERROR: |||%s|||, the number we called was not recognized\n",
+ ERRORA("Skype got ERROR: |||%s|||, the (skypeout) number we called was not recognized as valid\n",
SKYPIAX_P_LOG, message);
tech_pvt->skype_callflow = CALLFLOW_STATUS_FINISHED;
DEBUGA_SKYPE("skype_call now is DOWN\n", SKYPIAX_P_LOG);
@@ -376,9 +74,7 @@
tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
}
}
-
strncpy(message_2, message, sizeof(message) - 1);
-
buf = message;
stringp = &buf;
where = strsep(stringp, " ");
@@ -386,7 +82,7 @@
WARNINGA("Skype MSG without spaces: %s\n", SKYPIAX_P_LOG, message);
}
if (!strcasecmp(message, "ERROR")) {
- ERRORA("Skype got ERROR: |||%s|||\n", SKYPIAX_P_LOG, message);
+ WARNINGA("Skype got ERROR: |||%s|||\n", SKYPIAX_P_LOG, message);
tech_pvt->skype_callflow = CALLFLOW_STATUS_FINISHED;
DEBUGA_SKYPE("skype_call now is DOWN\n", SKYPIAX_P_LOG);
tech_pvt->skype_call_id[0] = '\0';
@@ -400,11 +96,8 @@
}
if (!strcasecmp(message, "CURRENTUSERHANDLE")) {
strncpy(obj, where, sizeof(obj) - 1);
-
where = strsep(stringp, " ");
-
strncpy(id, where, sizeof(id) - 1);
-
if (!strcasecmp(id, tech_pvt->skype_user)) {
tech_pvt->SkypiaxHandles.api_connected = 1;
DEBUGA_SKYPE
@@ -412,309 +105,557 @@
SKYPIAX_P_LOG, message, obj, id, tech_pvt->skype_user);
}
}
-
if (!strcasecmp(message, "USER")) {
strncpy(obj, where, sizeof(obj) - 1);
-
where = strsep(stringp, " ");
-
strncpy(id, where, sizeof(id) - 1);
-
where = strsep(stringp, " ");
+ strncpy(prop, where, sizeof(prop) - 1);
+ if (!strcasecmp(prop, "RECEIVEDAUTHREQUEST")) {
+ char msg_to_skype[256];
+ DEBUGA_SKYPE("Skype MSG: message: %s, obj: %s, id: %s, prop: %s!\n",
+ SKYPIAX_P_LOG, message, obj, id, prop);
+ //TODO: allow authorization based on config param
+ sprintf(msg_to_skype, "SET USER %s ISAUTHORIZED TRUE", id);
+ skypiax_skype_write(tech_pvt, msg_to_skype);
+ }
+ }
+ if (!strcasecmp(message, "MESSAGE")) {
+ strncpy(obj, where, sizeof(obj) - 1);
+ where = strsep(stringp, " ");
+ strncpy(id, where, sizeof(id) - 1);
+ where = strsep(stringp, " ");
+ strncpy(prop, where, sizeof(prop) - 1);
+ if (!strcasecmp(prop, "STATUS")) {
+ where = strsep(stringp, " ");
+ strncpy(value, where, sizeof(value) - 1);
+ if (!strcasecmp(value, "RECEIVED")) {
+ char msg_to_skype[256];
+ DEBUGA_SKYPE("Skype MSG: message: %s, obj: %s, id: %s, prop: %s value: %s!\n",
+ SKYPIAX_P_LOG, message, obj, id, prop, value);
+ //TODO: authomatically flag messages as read based on config param
+ sprintf(msg_to_skype, "SET MESSAGE %s SEEN", id);
+ skypiax_skype_write(tech_pvt, msg_to_skype);
+ }
+ } else if (!strcasecmp(prop, "BODY")) {
+ char msg_to_skype[256];
+ DEBUGA_SKYPE("Skype MSG: message: %s, obj: %s, id: %s, prop: %s!\n",
+ SKYPIAX_P_LOG, message, obj, id, prop);
+ //TODO: authomatically flag messages as read based on config param
+ sprintf(msg_to_skype, "SET MESSAGE %s SEEN", id);
+ skypiax_skype_write(tech_pvt, msg_to_skype);
+ }
+ }
+ if (!strcasecmp(message, "CALL")) {
+ strncpy(obj, where, sizeof(obj) - 1);
+ where = strsep(stringp, " ");
+ strncpy(id, where, sizeof(id) - 1);
+ where = strsep(stringp, " ");
+ strncpy(prop, where, sizeof(prop) - 1);
+ where = strsep(stringp, " ");
+ strncpy(value, where, sizeof(value) - 1);
+ where = strsep(stringp, " ");
+
+ DEBUGA_SKYPE
+ ("Skype MSG: message: %s, obj: %s, id: %s, prop: %s, value: %s,where: %s!\n",
+ SKYPIAX_P_LOG, message, obj, id, prop, value, where ? where : "NULL");
+
+ if (!strcasecmp(prop, "PARTNER_HANDLE")) {
+ strncpy(tech_pvt->callid_number, value, sizeof(tech_pvt->callid_number) - 1);
+ DEBUGA_SKYPE
+ ("the skype_call %s caller PARTNER_HANDLE (tech_pvt->callid_number) is: %s\n",
+ SKYPIAX_P_LOG, id, tech_pvt->callid_number);
+ return CALLFLOW_INCOMING_RING;
+ }
+ if (!strcasecmp(prop, "PARTNER_DISPNAME")) {
+ snprintf(tech_pvt->callid_name, sizeof(tech_pvt->callid_name) - 1, "%s%s%s",
+ value, where ? " " : "", where ? where : "");
+ DEBUGA_SKYPE
+ ("the skype_call %s caller PARTNER_DISPNAME (tech_pvt->callid_name) is: %s\n",
+ SKYPIAX_P_LOG, id, tech_pvt->callid_name);
+ }
+ if (!strcasecmp(prop, "CONF_ID") && !strcasecmp(value, "0")) {
+ DEBUGA_SKYPE("the skype_call %s is NOT a conference call\n", SKYPIAX_P_LOG, id);
+ if (tech_pvt->interface_state == SKYPIAX_STATE_DOWN)
+ tech_pvt->interface_state = SKYPIAX_STATE_PRERING;
+ }
+ if (!strcasecmp(prop, "CONF_ID") && strcasecmp(value, "0")) {
+ DEBUGA_SKYPE("the skype_call %s is a conference call\n", SKYPIAX_P_LOG, id);
+ if (tech_pvt->interface_state == SKYPIAX_STATE_DOWN)
+ tech_pvt->interface_state = SKYPIAX_STATE_PRERING;
+ }
+ if (!strcasecmp(prop, "DTMF")) {
+ NOTICA("Call %s received a DTMF: %s\n", SKYPIAX_P_LOG, id, value);
+ dtmf_received(tech_pvt, value);
+ }
+ if (!strcasecmp(prop, "FAILUREREASON")) {
+ DEBUGA_SKYPE
+ ("Skype FAILED on skype_call %s. Let's wait for the FAILED message.\n",
+ SKYPIAX_P_LOG, id);
+ }
+ if (!strcasecmp(prop, "DURATION") && (!strcasecmp(value, "1"))) {
+ if (strcasecmp(id, tech_pvt->skype_call_id)) {
+ strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
+ DEBUGA_SKYPE
+ ("We called a Skype contact and he answered us on skype_call: %s.\n",
+ SKYPIAX_P_LOG, id);
+ }
+ }
+ if (!strcasecmp(prop, "STATUS")) {
+
+ if (!strcasecmp(value, "RINGING")) {
+ char msg_to_skype[1024];
+ if (tech_pvt->interface_state != SKYPIAX_STATE_DIALING) {
+ /* we are not calling out */
+ if (!strlen(tech_pvt->skype_call_id)) {
+ /* we are not inside an active call */
+ tech_pvt->skype_callflow = CALLFLOW_STATUS_RINGING;
+ tech_pvt->interface_state = SKYPIAX_STATE_RING;
+ /* no owner, no active call, let's answer */
+ skypiax_skype_write(tech_pvt, "SET AGC OFF");
+ skypiax_sleep(10000);
+ skypiax_skype_write(tech_pvt, "SET AEC OFF");
+ skypiax_sleep(10000);
+ sprintf(msg_to_skype, "GET CALL %s PARTNER_DISPNAME", id);
+ skypiax_skype_write(tech_pvt, msg_to_skype);
+ skypiax_sleep(10000);
+ sprintf(msg_to_skype, "GET CALL %s PARTNER_HANDLE", id);
+ skypiax_skype_write(tech_pvt, msg_to_skype);
+ skypiax_sleep(10000);
+ sprintf(msg_to_skype, "ALTER CALL %s ANSWER", id);
+ skypiax_skype_write(tech_pvt, msg_to_skype);
+ DEBUGA_SKYPE("We answered a Skype RING on skype_call %s\n", SKYPIAX_P_LOG,
+ id);
+ strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
+ } else {
+ /* we're owned, we're in a call, let's refuse */
+ sprintf(msg_to_skype, "ALTER CALL %s END HANGUP", id);
+ skypiax_skype_write(tech_pvt, msg_to_skype);
+ skypiax_sleep(10000);
+ DEBUGA_SKYPE
+ ("We have NOT answered a Skype RING on skype_call %s, because we are already in a skypiax call\n",
+ SKYPIAX_P_LOG, id);
+ }
+ } else {
+ /* we are calling out */
+ tech_pvt->skype_callflow = CALLFLOW_STATUS_RINGING;
+ tech_pvt->interface_state = SKYPIAX_STATE_RINGING;
+ strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
+ DEBUGA_SKYPE("Our remote party in skype_call %s is RINGING\n",
+ SKYPIAX_P_LOG, id);
+ }
+ } else if (!strcasecmp(value, "EARLYMEDIA")) {
+ tech_pvt->skype_callflow = CALLFLOW_STATUS_EARLYMEDIA;
+ tech_pvt->interface_state = SKYPIAX_STATE_DIALING;
+ DEBUGA_SKYPE("Our remote party in skype_call %s is EARLYMEDIA\n",
+ SKYPIAX_P_LOG, id);
+ } else if (!strcasecmp(value, "MISSED")) {
+ DEBUGA_SKYPE("We missed skype_call %s\n", SKYPIAX_P_LOG, id);
+ } else if (!strcasecmp(value, "FINISHED")) {
+ DEBUGA_SKYPE("skype_call %s now is DOWN\n", SKYPIAX_P_LOG, id);
+ tech_pvt->skype_call_id[0] = '\0';
+ if (tech_pvt->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) {
+ //tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
+ return CALLFLOW_INCOMING_HANGUP;
+ } else {
+ tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
+ }
+ } else if (!strcasecmp(value, "CANCELLED")) {
+ tech_pvt->skype_callflow = CALLFLOW_STATUS_CANCELLED;
+ DEBUGA_SKYPE
+ ("we tried to call Skype on skype_call %s and Skype has now CANCELLED\n",
+ SKYPIAX_P_LOG, id);
+ tech_pvt->skype_call_id[0] = '\0';
+ if (tech_pvt->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) {
+ tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
+ return CALLFLOW_INCOMING_HANGUP;
+ } else {
+ tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
+ }
+ } else if (!strcasecmp(value, "FAILED")) {
+ tech_pvt->skype_callflow = CALLFLOW_STATUS_FAILED;
+ DEBUGA_SKYPE
+ ("we tried to call Skype on skype_call %s and Skype has now FAILED\n",
+ SKYPIAX_P_LOG, id);
+ tech_pvt->skype_call_id[0] = '\0';
+ strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
+ tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
+ return CALLFLOW_INCOMING_HANGUP;
+ } else if (!strcasecmp(value, "REFUSED")) {
+ if (!strcasecmp(id, tech_pvt->skype_call_id)) {
+ /* this is the id of the call we are in, probably we generated it */
+ tech_pvt->skype_callflow = CALLFLOW_STATUS_REFUSED;
+ DEBUGA_SKYPE
+ ("we tried to call Skype on skype_call %s and Skype has now REFUSED\n",
+ SKYPIAX_P_LOG, id);
+ strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
+ tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
+ tech_pvt->skype_call_id[0] = '\0';
+ return CALLFLOW_INCOMING_HANGUP;
+ } else {
+ /* we're here because were us that refused an incoming call */
+ DEBUGA_SKYPE("we REFUSED skype_call %s\n", SKYPIAX_P_LOG, id);
+ }
+ } else if (!strcasecmp(value, "ROUTING")) {
+ tech_pvt->skype_callflow = CALLFLOW_STATUS_ROUTING;
+ tech_pvt->interface_state = SKYPIAX_STATE_DIALING;
+ strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
+ DEBUGA_SKYPE("skype_call: %s is now ROUTING\n", SKYPIAX_P_LOG, id);
+ } else if (!strcasecmp(value, "UNPLACED")) {
+ tech_pvt->skype_callflow = CALLFLOW_STATUS_UNPLACED;
+ tech_pvt->interface_state = SKYPIAX_STATE_DIALING;
+ strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
+ DEBUGA_SKYPE("skype_call: %s is now UNPLACED\n", SKYPIAX_P_LOG, id);
+ } else if (!strcasecmp(value, "INPROGRESS")) {
+ char msg_to_skype[1024];
+ tech_pvt->skype_callflow = CALLFLOW_STATUS_INPROGRESS;
+ strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
+ tech_pvt->interface_state = SKYPIAX_STATE_UP;
+ DEBUGA_SKYPE("skype_call: %s is now active\n", SKYPIAX_P_LOG, id);
+ sprintf(msg_to_skype, "ALTER CALL %s SET_INPUT PORT=\"%d\"", id,
+ tech_pvt->tcp_cli_port);
+ skypiax_skype_write(tech_pvt, msg_to_skype);
+ start_audio_threads(tech_pvt);
+ sprintf(msg_to_skype, "ALTER CALL %s SET_OUTPUT PORT=\"%d\"", id,
+ tech_pvt->tcp_srv_port);
+ skypiax_skype_write(tech_pvt, msg_to_skype);
+ tech_pvt->skype_callflow = SKYPIAX_STATE_UP;
+ if (!strlen(tech_pvt->session_uuid_str)) {
+ DEBUGA_SKYPE("New Inbound Channel!\n", SKYPIAX_P_LOG);
+ new_inbound_channel(tech_pvt);
+ } else {
+ DEBUGA_SKYPE("Outbound Channel Answered!\n", SKYPIAX_P_LOG);
+ outbound_channel_answered(tech_pvt);
+ }
+ } else {
+ WARNINGA("skype_call: %s, STATUS: %s is not recognized\n", SKYPIAX_P_LOG, id,
+ value);
+ }
+ } //STATUS
+ } //CALL
+ /* the "numbered" messages that follows are used by the directory application, not yet ported */
+ if (!strcasecmp(message, "#333")) {
+ /* DEBUGA_SKYPE("Skype MSG: message_2: %s, message2[11]: %s\n", SKYPIAX_P_LOG,
+ * message_2, &message_2[11]); */
+ memset(tech_pvt->skype_friends, 0, 4096);
+ strncpy(tech_pvt->skype_friends, &message_2[11], 4095);
+ }
+ if (!strcasecmp(message, "#222")) {
+ /* DEBUGA_SKYPE("Skype MSG: message_2: %s, message2[10]: %s\n", SKYPIAX_P_LOG,
+ * message_2, &message_2[10]); */
+ memset(tech_pvt->skype_fullname, 0, 512);
+ strncpy(tech_pvt->skype_fullname, &message_2[10], 511);
+ }
+ if (!strcasecmp(message, "#765")) {
+ /* DEBUGA_SKYPE("Skype MSG: message_2: %s, message2[10]: %s\n", SKYPIAX_P_LOG,
+ * message_2, &message_2[10]); */
+ memset(tech_pvt->skype_displayname, 0, 512);
+ strncpy(tech_pvt->skype_displayname, &message_2[10], 511);
+ }
+ a = 0;
+ } //message end
+ } //read_from_pipe
+ return 0;
+}
- strncpy(prop, where, sizeof(prop) - 1);
+void *skypiax_do_tcp_srv_thread_func(void *obj)
+{
+ private_t *tech_pvt = obj;
+ int s;
+ unsigned int len;
+ unsigned int i;
+ unsigned int a;
+#if defined(WIN32) && !defined(__CYGWIN__)
+ int sin_size;
+#else /* WIN32 */
+ unsigned int sin_size;
+#endif /* WIN32 */
+ unsigned int fd;
+ short srv_in[SAMPLES_PER_FRAME];
+ short srv_out[SAMPLES_PER_FRAME / 2];
+ struct sockaddr_in my_addr;
+ struct sockaddr_in remote_addr;
+ int exit = 0;
+ unsigned int kill_cli_size;
+ short kill_cli_buff[SAMPLES_PER_FRAME];
+ short totalbuf[SAMPLES_PER_FRAME];
- if (!strcasecmp(prop, "RECEIVEDAUTHREQUEST")) {
- char msg_to_skype[256];
- DEBUGA_SKYPE("Skype MSG: message: %s, obj: %s, id: %s, prop: %s!\n",
- SKYPIAX_P_LOG, message, obj, id, prop);
+ memset(&my_addr, 0, sizeof(my_addr));
+ my_addr.sin_family = AF_INET;
+ my_addr.sin_addr.s_addr = htonl(0x7f000001); /* use the localhost */
+ my_addr.sin_port = htons(tech_pvt->tcp_srv_port);
- //FIXME: TODO: allow authorization based on config param
- sprintf(msg_to_skype, "SET USER %s ISAUTHORIZED TRUE", id);
- skypiax_skype_write(tech_pvt, msg_to_skype);
- }
- }
+ if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ ERRORA("socket Error\n", SKYPIAX_P_LOG);
+ return NULL;
+ }
- if (!strcasecmp(message, "MESSAGE")) {
- strncpy(obj, where, sizeof(obj) - 1);
+ if (bind(s, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) < 0) {
+ ERRORA("bind Error\n", SKYPIAX_P_LOG);
+ return NULL;
+ }
+ DEBUGA_SKYPE("started tcp_srv_thread thread.\n", SKYPIAX_P_LOG);
- where = strsep(stringp, " ");
+ listen(s, 6);
- strncpy(id, where, sizeof(id) - 1);
+ sin_size = sizeof(remote_addr);
+ while ((fd = accept(s, (struct sockaddr *) &remote_addr, &sin_size)) > 0) {
+ DEBUGA_SKYPE("ACCEPTED\n", SKYPIAX_P_LOG);
+ if (!running)
+ break;
+ while (tech_pvt->interface_state != SKYPIAX_STATE_DOWN
+ && (tech_pvt->skype_callflow == CALLFLOW_STATUS_INPROGRESS
+ || tech_pvt->skype_callflow == SKYPIAX_STATE_UP)) {
- where = strsep(stringp, " ");
+ unsigned int fdselect;
+ int rt;
+ fd_set fs;
+ struct timeval to;
- strncpy(prop, where, sizeof(prop) - 1);
+ if (!running)
+ break;
+ exit = 1;
- if (!strcasecmp(prop, "STATUS")) {
+ fdselect = fd;
+ FD_ZERO(&fs);
+ FD_SET(fdselect, &fs);
+ to.tv_usec = 2000000; //2000 msec
+ to.tv_sec = 0;
- where = strsep(stringp, " ");
+ rt = select(fdselect + 1, &fs, NULL, NULL, &to);
+ if (rt > 0) {
- strncpy(value, where, sizeof(value) - 1);
+ len = recv(fd, (char *) srv_in, 320, 0); //seems that Skype only sends 320 bytes at time
- if (!strcasecmp(value, "RECEIVED")) {
- char msg_to_skype[256];
- DEBUGA_SKYPE("Skype MSG: message: %s, obj: %s, id: %s, prop: %s value: %s!\n",
- SKYPIAX_P_LOG, message, obj, id, prop, value);
+ if (len == 320) {
+ unsigned int howmany;
- //FIXME: TODO: allow authorization based on config param
- sprintf(msg_to_skype, "SET MESSAGE %s SEEN", id);
- skypiax_skype_write(tech_pvt, msg_to_skype);
+ if (SAMPLERATE_SKYPIAX == 8000) {
+ /* we're downsampling from 16khz to 8khz, srv_out will contain each other sample from srv_in */
+ a = 0;
+ for (i = 0; i < len / sizeof(short); i++) {
+ srv_out[a] = srv_in[i];
+ i++;
+ a++;
+ }
+ } else if (SAMPLERATE_SKYPIAX == 16000) {
+ /* we're NOT downsampling, srv_out will contain ALL samples from srv_in */
+ for (i = 0; i < len / sizeof(short); i++) {
+ srv_out[i] = srv_in[i];
+ }
+ } else {
+ ERRORA("SAMPLERATE_SKYPIAX can only be 8000 or 16000\n", SKYPIAX_P_LOG);
+ }
+ /* if not yet done, let's store the half incoming frame */
+ if (!tech_pvt->audiobuf_is_loaded) {
+ for (i = 0; i < SAMPLES_PER_FRAME / 2; i++) {
+ tech_pvt->audiobuf[i] = srv_out[i];
+ }
+ tech_pvt->audiobuf_is_loaded = 1;
+ } else {
+ /* we got a stored half frame, build a complete frame in totalbuf using the stored half frame and the current half frame */
+ for (i = 0; i < SAMPLES_PER_FRAME / 2; i++) {
+ totalbuf[i] = tech_pvt->audiobuf[i];
+ }
+ for (a = 0; a < SAMPLES_PER_FRAME / 2; a++) {
+ totalbuf[i] = srv_out[a];
+ i++;
+ }
+ /* send the complete frame through the pipe to our code waiting for incoming audio */
+ howmany =
+ skypiax_pipe_write(tech_pvt->audiopipe[1], totalbuf,
+ SAMPLES_PER_FRAME * sizeof(short));
+ if (howmany != SAMPLES_PER_FRAME * sizeof(short)) {
+ ERRORA("howmany is %d, but was expected to be %d\n", SKYPIAX_P_LOG, howmany,
+ SAMPLES_PER_FRAME * sizeof(short));
+ }
+ /* done with the stored half frame */
+ tech_pvt->audiobuf_is_loaded = 0;
}
- } else if (!strcasecmp(prop, "BODY")) {
- char msg_to_skype[256];
-
- DEBUGA_SKYPE("Skype MSG: message: %s, obj: %s, id: %s, prop: %s!\n",
- SKYPIAX_P_LOG, message, obj, id, prop);
- //FIXME: TODO: on config param ???
- sprintf(msg_to_skype, "SET MESSAGE %s SEEN", id);
- skypiax_skype_write(tech_pvt, msg_to_skype);
+ } else if (len == 0) {
+ DEBUGA_SKYPE("Skype incoming audio GONE\n", SKYPIAX_P_LOG);
+ skypiax_sleep(1000);
+ } else {
+ ERRORA("len=%d\n", SKYPIAX_P_LOG, len);
+ exit = 1;
+ break;
}
+ } else {
+ if (rt)
+ ERRORA("SRV rt=%d\n", SKYPIAX_P_LOG, rt);
+ skypiax_sleep(10000);
}
- if (!strcasecmp(message, "CALL")) {
-
- strncpy(obj, where, sizeof(obj) - 1);
-
- where = strsep(stringp, " ");
-
- strncpy(id, where, sizeof(id) - 1);
-
- where = strsep(stringp, " ");
-
- strncpy(prop, where, sizeof(prop) - 1);
-
- where = strsep(stringp, " ");
-
- strncpy(value, where, sizeof(value) - 1);
-
- where = strsep(stringp, " ");
-
- DEBUGA_SKYPE
- ("Skype MSG: message: %s, obj: %s, id: %s, prop: %s, value: %s,where: %s!\n",
- SKYPIAX_P_LOG, message, obj, id, prop, value, where ? where : "NULL");
-
- if (!strcasecmp(prop, "PARTNER_HANDLE")) {
- strncpy(tech_pvt->callid_number, value, sizeof(tech_pvt->callid_number) - 1);
- DEBUGA_SKYPE
- ("the skype_call %s caller PARTNER_HANDLE (tech_pvt->callid_number) is: %s\n",
- SKYPIAX_P_LOG, id, tech_pvt->callid_number);
- return CALLFLOW_INCOMING_RING;
- }
- if (!strcasecmp(prop, "PARTNER_DISPNAME")) {
- snprintf(tech_pvt->callid_name, sizeof(tech_pvt->callid_name) - 1, "%s%s%s",
- value, where ? " " : "", where ? where : "");
- DEBUGA_SKYPE
- ("the skype_call %s caller PARTNER_DISPNAME (tech_pvt->callid_name) is: %s\n",
- SKYPIAX_P_LOG, id, tech_pvt->callid_name);
- }
- if (!strcasecmp(prop, "CONF_ID") && !strcasecmp(value, "0")) {
- DEBUGA_SKYPE("the skype_call %s is NOT a conference call\n", SKYPIAX_P_LOG, id);
- if (tech_pvt->interface_state == SKYPIAX_STATE_DOWN)
- tech_pvt->interface_state = SKYPIAX_STATE_PRERING;
- }
- if (!strcasecmp(prop, "CONF_ID") && strcasecmp(value, "0")) {
- DEBUGA_SKYPE("the skype_call %s is a conference call\n", SKYPIAX_P_LOG, id);
- if (tech_pvt->interface_state == SKYPIAX_STATE_DOWN)
- tech_pvt->interface_state = SKYPIAX_STATE_PRERING;
- }
+ }
- if (!strcasecmp(prop, "DTMF")) {
+ /* let's send some frame in the pipes, so both tcp_cli and tcp_srv will have an occasion to die */
+ kill_cli_size = SAMPLES_PER_FRAME * sizeof(short);
+ len = skypiax_pipe_write(tech_pvt->audiopipe[1], kill_cli_buff, kill_cli_size);
+ kill_cli_size = SAMPLES_PER_FRAME * sizeof(short);
+ len = skypiax_pipe_write(tech_pvt->audioskypepipe[1], kill_cli_buff, kill_cli_size);
+ tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
+ kill_cli_size = SAMPLES_PER_FRAME * sizeof(short);
+ len = skypiax_pipe_write(tech_pvt->audiopipe[1], kill_cli_buff, kill_cli_size);
+ kill_cli_size = SAMPLES_PER_FRAME * sizeof(short);
+ len = skypiax_pipe_write(tech_pvt->audioskypepipe[1], kill_cli_buff, kill_cli_size);
- DEBUGA_SKYPE("Call %s received a DTMF: %s\n", SKYPIAX_P_LOG, id, value);
+ DEBUGA_SKYPE("Skype incoming audio GONE\n", SKYPIAX_P_LOG);
+ skypiax_close_socket(fd);
+ if (exit)
+ break;
+ }
- dtmf_received(tech_pvt, value);
- }
+ DEBUGA_SKYPE("incoming audio server (I am it) GONE\n", SKYPIAX_P_LOG);
+ skypiax_close_socket(s);
+ return NULL;
+}
- if (!strcasecmp(prop, "FAILUREREASON")) {
- DEBUGA_SKYPE
- ("Skype has FAILED on skype_call %s. Let's wait for the FAILED message.\n",
- SKYPIAX_P_LOG, id);
- }
- if (!strcasecmp(prop, "DURATION") && (!strcasecmp(value, "1"))) {
- if (strcasecmp(id, tech_pvt->skype_call_id)) {
- strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
- DEBUGA_SKYPE
- ("We called a Skype contact and he answered us on skype_call: %s.\n",
- SKYPIAX_P_LOG, id);
- }
- }
+void *skypiax_do_tcp_cli_thread_func(void *obj)
+{
+ private_t *tech_pvt = obj;
+ int s;
+ struct sockaddr_in my_addr;
+ struct sockaddr_in remote_addr;
+ unsigned int got;
+ unsigned int len;
+ unsigned int i;
+ unsigned int a;
+ unsigned int fd;
+ short cli_out[SAMPLES_PER_FRAME * 2];
+ short cli_in[SAMPLES_PER_FRAME];
+#ifdef WIN32
+ int sin_size;
+#else
+ unsigned int sin_size;
+#endif /* WIN32 */
- if (!strcasecmp(prop, "STATUS")) {
+ memset(&my_addr, 0, sizeof(my_addr));
+ my_addr.sin_family = AF_INET;
+ my_addr.sin_addr.s_addr = htonl(0x7f000001); /* use the localhost */
+ my_addr.sin_port = htons(tech_pvt->tcp_cli_port);
- if (!strcasecmp(value, "RINGING")) {
- char msg_to_skype[1024];
- if (tech_pvt->interface_state != SKYPIAX_STATE_DIALING) {
- /* we are not calling out */
+ if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ ERRORA("socket Error\n", SKYPIAX_P_LOG);
+ return NULL;
+ }
- if (!strlen(tech_pvt->skype_call_id)) { //FIXME
- /* we are not inside an active call */
- tech_pvt->skype_callflow = CALLFLOW_STATUS_RINGING;
- tech_pvt->interface_state = SKYPIAX_STATE_RING;
- /* no owner, no active call, let's answer */
- skypiax_skype_write(tech_pvt, "SET AGC OFF");
- skypiax_sleep(10000);
- skypiax_skype_write(tech_pvt, "SET AEC OFF");
- skypiax_sleep(10000);
- sprintf(msg_to_skype, "GET CALL %s PARTNER_DISPNAME", id);
- skypiax_skype_write(tech_pvt, msg_to_skype);
- skypiax_sleep(10000);
- sprintf(msg_to_skype, "GET CALL %s PARTNER_HANDLE", id);
- skypiax_skype_write(tech_pvt, msg_to_skype);
- skypiax_sleep(10000);
- sprintf(msg_to_skype, "ALTER CALL %s ANSWER", id);
- skypiax_skype_write(tech_pvt, msg_to_skype);
- DEBUGA_SKYPE("We answered a Skype RING on skype_call %s\n", SKYPIAX_P_LOG,
- id);
- strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
- } else {
- /* we're owned, we're in a call, let's refuse */
- sprintf(msg_to_skype, "ALTER CALL %s END HANGUP", id);
- skypiax_skype_write(tech_pvt, msg_to_skype);
- skypiax_sleep(10000);
- DEBUGA_SKYPE
- ("We have NOT answered a Skype RING on skype_call %s, because we are already in a skypiax call\n",
- SKYPIAX_P_LOG, id);
+ if (bind(s, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) < 0) {
+ ERRORA("bind Error\n", SKYPIAX_P_LOG);
+ skypiax_close_socket(s);
+ return NULL;
+ }
+ DEBUGA_SKYPE("started tcp_cli_thread thread.\n", SKYPIAX_P_LOG);
- }
- } else {
- /* we are calling out */
- tech_pvt->skype_callflow = CALLFLOW_STATUS_RINGING;
- tech_pvt->interface_state = SKYPIAX_STATE_RINGING;
- //FIXME ast_queue_control(tech_pvt->owner, SKYPIAX_CONTROL_RINGING);
- strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
- DEBUGA_SKYPE("Our remote party in skype_call %s is RINGING\n",
- SKYPIAX_P_LOG, id);
- }
- } else if (!strcasecmp(value, "EARLYMEDIA")) {
- tech_pvt->skype_callflow = CALLFLOW_STATUS_EARLYMEDIA;
- tech_pvt->interface_state = SKYPIAX_STATE_DIALING;
- //FIXME ast_queue_control(tech_pvt->owner, SKYPIAX_CONTROL_RINGING);
- DEBUGA_SKYPE("Our remote party in skype_call %s is EARLYMEDIA\n",
- SKYPIAX_P_LOG, id);
- } else if (!strcasecmp(value, "MISSED")) {
- DEBUGA_SKYPE("We missed skype_call %s\n", SKYPIAX_P_LOG, id);
+ listen(s, 6);
- } else if (!strcasecmp(value, "FINISHED")) {
- //tech_pvt->skype_callflow = CALLFLOW_STATUS_FINISHED;
- DEBUGA_SKYPE("skype_call %s now is DOWN\n", SKYPIAX_P_LOG, id);
- tech_pvt->skype_call_id[0] = '\0';
+ sin_size = sizeof(remote_addr);
+ while ((fd = accept(s, (struct sockaddr *) &remote_addr, &sin_size)) > 0) {
+ DEBUGA_SKYPE("ACCEPTED\n", SKYPIAX_P_LOG);
+ if (!running)
+ break;
+ while (tech_pvt->interface_state != SKYPIAX_STATE_DOWN
+ && (tech_pvt->skype_callflow == CALLFLOW_STATUS_INPROGRESS
+ || tech_pvt->skype_callflow == SKYPIAX_STATE_UP)) {
+ unsigned int fdselect;
+ int rt;
+ fd_set fs;
+ struct timeval to;
- if (tech_pvt->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) {
- //tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
- return CALLFLOW_INCOMING_HANGUP;
- } else {
- tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
- }
+ if (!running)
+ break;
+ fdselect = fd;
+ FD_ZERO(&fs);
+ FD_SET(fdselect, &fs);
+ to.tv_usec = 2000000; //2000 msec
+ to.tv_sec = 0;
- } else if (!strcasecmp(value, "CANCELLED")) {
- tech_pvt->skype_callflow = CALLFLOW_STATUS_CANCELLED;
- DEBUGA_SKYPE
- ("we tried to call Skype on skype_call %s and Skype has now CANCELLED\n",
- SKYPIAX_P_LOG, id);
- tech_pvt->skype_call_id[0] = '\0';
+ rt = select(fdselect + 1, NULL, &fs, NULL, &to);
- if (tech_pvt->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) {
- tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
- return CALLFLOW_INCOMING_HANGUP;
- } else {
- tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
- }
- } else if (!strcasecmp(value, "FAILED")) {
- tech_pvt->skype_callflow = CALLFLOW_STATUS_FAILED;
- DEBUGA_SKYPE
- ("we tried to call Skype on skype_call %s and Skype has now FAILED\n",
- SKYPIAX_P_LOG, id);
- tech_pvt->skype_call_id[0] = '\0';
- strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
- tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
- return CALLFLOW_INCOMING_HANGUP;
- } else if (!strcasecmp(value, "REFUSED")) {
- if (!strcasecmp(id, tech_pvt->skype_call_id)) {
- /* this is the id of the call we are in, probably we generated it */
- tech_pvt->skype_callflow = CALLFLOW_STATUS_REFUSED;
- DEBUGA_SKYPE
- ("we tried to call Skype on skype_call %s and Skype has now REFUSED\n",
- SKYPIAX_P_LOG, id);
- strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
- tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
- tech_pvt->skype_call_id[0] = '\0';
- return CALLFLOW_INCOMING_HANGUP;
- } else {
- /* we're here because were us that refused an incoming call */
- DEBUGA_SKYPE("we REFUSED skype_call %s\n", SKYPIAX_P_LOG, id);
+ if (rt > 0) {
- }
- } else if (!strcasecmp(value, "ROUTING")) {
- tech_pvt->skype_callflow = CALLFLOW_STATUS_ROUTING;
- tech_pvt->interface_state = SKYPIAX_STATE_DIALING;
- strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
- DEBUGA_SKYPE("skype_call: %s is now ROUTING\n", SKYPIAX_P_LOG, id);
- } else if (!strcasecmp(value, "UNPLACED")) {
- tech_pvt->skype_callflow = CALLFLOW_STATUS_UNPLACED;
- tech_pvt->interface_state = SKYPIAX_STATE_DIALING;
- strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
- DEBUGA_SKYPE("skype_call: %s is now UNPLACED\n", SKYPIAX_P_LOG, id);
- } else if (!strcasecmp(value, "INPROGRESS")) {
- char msg_to_skype[1024];
- tech_pvt->skype_callflow = CALLFLOW_STATUS_INPROGRESS;
- strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
- tech_pvt->interface_state = SKYPIAX_STATE_UP;
- DEBUGA_SKYPE("skype_call: %s is now active\n", SKYPIAX_P_LOG, id);
- sprintf(msg_to_skype, "ALTER CALL %s SET_INPUT PORT=\"%d\"", id,
- tech_pvt->tcp_cli_port);
- skypiax_skype_write(tech_pvt, msg_to_skype);
- start_audio_threads(tech_pvt);
- sprintf(msg_to_skype, "ALTER CALL %s SET_OUTPUT PORT=\"%d\"", id,
- tech_pvt->tcp_srv_port);
- skypiax_skype_write(tech_pvt, msg_to_skype);
+ /* read from the pipe the audio frame we are supposed to send out */
+ got =
+ skypiax_pipe_read(tech_pvt->audioskypepipe[0], cli_in,
+ SAMPLES_PER_FRAME * sizeof(short));
+ if (got != SAMPLES_PER_FRAME * sizeof(short)) {
+ WARNINGA("got is %d, but was expected to be %d\n", SKYPIAX_P_LOG, got,
+ SAMPLES_PER_FRAME * sizeof(short));
+ }
- tech_pvt->skype_callflow = SKYPIAX_STATE_UP;
+ if (got == SAMPLES_PER_FRAME * sizeof(short)) {
+ if (SAMPLERATE_SKYPIAX == 8000) {
- if (!strlen(tech_pvt->session_uuid_str)) {
- DEBUGA_SKYPE("New Inbound Channel!\n", SKYPIAX_P_LOG);
- new_inbound_channel(tech_pvt);
- } else {
- DEBUGA_SKYPE("Outbound Channel Answered!\n", SKYPIAX_P_LOG);
- outbound_channel_answered(tech_pvt);
+ /* we're upsampling from 8khz to 16khz, cli_out will contain two times each sample from cli_in */
+ a = 0;
+ for (i = 0; i < got / sizeof(short); i++) {
+ cli_out[a] = cli_in[i];
+ a++;
+ cli_out[a] = cli_in[i];
+ a++;
+ }
+ got = got * 2;
+ } else if (SAMPLERATE_SKYPIAX == 16000) {
+ /* we're NOT upsampling, cli_out will contain just ALL samples from cli_in */
+ for (i = 0; i < got / sizeof(short); i++) {
+ cli_out[i] = cli_in[i];
}
-
} else {
- WARNINGA("skype_call: %s, STATUS: %s is not recognized\n", SKYPIAX_P_LOG, id,
- value);
+ ERRORA("SAMPLERATE_SKYPIAX can only be 8000 or 16000\n", SKYPIAX_P_LOG);
+ }
+ /* send the 16khz frame to the Skype client waiting for incoming audio */
+ len = send(fd, (char *) cli_out, got, 0);
+
+ if (len == -1) {
+ break;
+ } else if (len != got) {
+ ERRORA("len=%d\n", SKYPIAX_P_LOG, len);
+ skypiax_sleep(1000);
+ break;
}
- } //STATUS
- } //CALL
+ } else {
- /* the "numbered" messages that follows are used by the directory application, not yet ported */
- if (!strcasecmp(message, "#333")) {
- /* DEBUGA_SKYPE("Skype MSG: message_2: %s, message2[11]: %s\n", SKYPIAX_P_LOG,
- * message_2, &message_2[11]); */
- memset(tech_pvt->skype_friends, 0, 4096);
- strncpy(tech_pvt->skype_friends, &message_2[11], 4095);
- }
- if (!strcasecmp(message, "#222")) {
- /* DEBUGA_SKYPE("Skype MSG: message_2: %s, message2[10]: %s\n", SKYPIAX_P_LOG,
- * message_2, &message_2[10]); */
- memset(tech_pvt->skype_fullname, 0, 512);
- strncpy(tech_pvt->skype_fullname, &message_2[10], 511);
- }
- if (!strcasecmp(message, "#765")) {
- /* DEBUGA_SKYPE("Skype MSG: message_2: %s, message2[10]: %s\n", SKYPIAX_P_LOG,
- * message_2, &message_2[10]); */
- memset(tech_pvt->skype_displayname, 0, 512);
- strncpy(tech_pvt->skype_displayname, &message_2[10], 511);
+ WARNINGA("got is %d, but was expected to be %d\n", SKYPIAX_P_LOG, got,
+ SAMPLES_PER_FRAME * sizeof(short));
+ }
+ } else {
+ if (rt)
+ ERRORA("CLI rt=%d\n", SKYPIAX_P_LOG, rt);
+ skypiax_sleep(10000);
}
- a = 0;
- } //message end
- } //read_from_pipe
+ }
+ DEBUGA_SKYPE("Skype outbound audio GONE\n", SKYPIAX_P_LOG);
+ skypiax_close_socket(fd);
+ break;
+ }
- return 0;
+ DEBUGA_SKYPE("outbound audio server (I am it) GONE\n", SKYPIAX_P_LOG);
+ skypiax_close_socket(s);
+ return NULL;
+}
+
+int skypiax_skypeaudio_read(private_t * tech_pvt)
+{
+ unsigned int samples;
+
+ samples =
+ skypiax_pipe_read(tech_pvt->audiopipe[0], tech_pvt->read_frame.data,
+ SAMPLES_PER_FRAME * sizeof(short));
+
+ if (samples != SAMPLES_PER_FRAME * sizeof(short)) {
+ if (samples)
+ WARNINGA("read samples=%u expected=%u\n", SKYPIAX_P_LOG, samples,
+ SAMPLES_PER_FRAME * sizeof(short));
+ return 0;
+ } else {
+ /* A real frame */
+ tech_pvt->read_frame.datalen = samples;
+ }
+ return 1;
}
int skypiax_skype_senddigit(private_t * tech_pvt, char digit)
@@ -722,9 +663,7 @@
char msg_to_skype[1024];
DEBUGA_SKYPE("DIGIT received: %c\n", SKYPIAX_P_LOG, digit);
-
sprintf(msg_to_skype, "SET CALL %s DTMF %c", tech_pvt->skype_call_id, digit);
-
skypiax_skype_write(tech_pvt, msg_to_skype);
return 0;
@@ -743,7 +682,6 @@
sprintf(msg_to_skype, "CALL %s", rdest);
if (skypiax_skype_write(tech_pvt, msg_to_skype) < 0) {
-
ERRORA("failed to communicate with Skype client, now exit\n", SKYPIAX_P_LOG);
return -1;
}
More information about the Freeswitch-branches
mailing list