[Freeswitch-branches] [commit] r10290 - freeswitch/branches/gmaruzz/src/mod/endpoints/mod_skypiax

Freeswitch SVN gmaruzz at freeswitch.org
Fri Nov 7 11:42:50 PST 2008


Author: gmaruzz
Date: Fri Nov  7 10:36:59 2008
New Revision: 10290

Modified:
   freeswitch/branches/gmaruzz/src/mod/endpoints/mod_skypiax/mod_skypiax.c

Log:
skypiax: beginning initialization of Skype audio machinery

Modified: freeswitch/branches/gmaruzz/src/mod/endpoints/mod_skypiax/mod_skypiax.c
==============================================================================
--- freeswitch/branches/gmaruzz/src/mod/endpoints/mod_skypiax/mod_skypiax.c	(original)
+++ freeswitch/branches/gmaruzz/src/mod/endpoints/mod_skypiax/mod_skypiax.c	Fri Nov  7 10:36:59 2008
@@ -101,6 +101,43 @@
 	char type[256];
 	char X11_display[256];
 	struct AsteriskHandles AsteriskHandlesAst;
+
+  int interface_state;          /*!< \brief 'state' of the interface (channel) */
+  char language[80];  /*!< \brief default Asterisk dialplan language for this interface */
+  char exten[80];    /*!< \brief default Asterisk dialplan extension for this interface */
+  int skypiax_sound_rate;       /*!< \brief rate of the sound device, in Hz, eg: 8000 */
+  int skypiax_sound_capt_fd;    /*!< \brief file descriptor for sound capture dev */
+  char callid_name[50];
+  char callid_number[50];
+  double playback_boost;
+  double capture_boost;
+  int stripmsd;
+  pthread_t skype_thread;
+  char skype_call_id[512];
+  int skype_call_ongoing;
+  char skype_friends[4096];
+  char skype_fullname[512];
+  char skype_displayname[512];
+  int skype_callflow;           /*!< \brief 'callflow' of the skype interface (as opposed to phone interface) */
+  int skype;                    /*!< \brief config flag, bool, Skype support on this interface (0 if false, -1 if true) */
+  int control_to_send;
+  int audiopipe[2];
+  int audioskypepipe[2];
+  pthread_t tcp_srv_thread;
+  pthread_t tcp_cli_thread;
+  short audiobuf[160];
+  int audiobuf_is_loaded;
+
+  //int phonebook_listing;
+  //int phonebook_querying;
+  //int phonebook_listing_received_calls;
+
+  //int phonebook_first_entry;
+  //int phonebook_last_entry;
+  //int phonebook_number_lenght;
+  //int phonebook_text_lenght;
+  FILE *phonebook_writing_fp;
+  int skypiax_dir_entry_extension_prefix;
 };
 
 typedef struct skypiax_config skypiax_config_t;
@@ -129,8 +166,302 @@
 static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
 static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig);
 
+int option_debug = 100;
+
+#define SKYPE_AUDIO
+#ifdef SKYPE_AUDIO
+
+#define SAMPLES_PER_FRAME 160
+#define NN 160
+#define GG 160
+static void *SWITCH_THREAD_FUNC skypiax_do_tcp_srv_thread(switch_thread_t *thread, void *obj)
+{
+  struct skypiax_config *p = obj;
+  short in[GG];
+  short out[GG / 2];
+  int s, fd, len, sent;
+  unsigned int sin_size;
+  struct sockaddr_in my_addr;
+  struct sockaddr_in remote_addr;
+  int exit = 0;
+  int a;
+  int i;
+
+  if (option_debug > 10) {
+    DEBUGA_PBX("ENTERING FUNC\n", SKYPIAX_P_LOG);
+  }
+  memset(&my_addr, 0, sizeof(my_addr));
+  my_addr.sin_family = AF_INET;
+  my_addr.sin_addr.s_addr = INADDR_ANY;
+  my_addr.sin_port = htons(5556);
+
+  if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+    ERRORA("socket Error\n", SKYPIAX_P_LOG);
+    if (option_debug > 10) {
+      DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG);
+    }
+    return NULL;
+  }
+
+  if (bind(s, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) < 0) {
+    ERRORA("bind Error\n", SKYPIAX_P_LOG);
+    if (option_debug > 10) {
+      DEBUGA_PBX("EXITING FUNC\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) {
+    while (1) {
+      len = recv(fd, in, sizeof(short) * GG, 0);
+      if (len > 0) {
+        a = 0;
+        for (i = 0; i < len / sizeof(short); i++) {
+          out[a] = in[i];
+          i++;
+          a++;
+        }
+
+        if (!p->audiobuf_is_loaded) {
+          for (i = 0; i < (len / sizeof(short)) / 2; i++) {
+            p->audiobuf[i] = out[i];
+          }
+          p->audiobuf_is_loaded = 1;
+        } else {
+          sent = write(p->audiopipe[1], p->audiobuf, len / 2);
+          sent = write(p->audiopipe[1], out, len / 2);
+          p->audiobuf_is_loaded = 0;
+          //DEBUGA_SOUND("read=====> req=%d recv=%d to sent=%d sent=%d\n", SKYPIAX_P_LOG, sizeof(short)*GG, len, (len*sizeof(short))/2, sent);
+        }
+
+      } else if (len == 0) {
+        DEBUGA_SKYPE("client GONE\n", SKYPIAX_P_LOG);
+        break;
+      } else {
+        ERRORA("len=%d\n", SKYPIAX_P_LOG, len);
+        exit = 1;
+        break;
+      }
+    }
+    DEBUGA_SKYPE("client GONE\n", SKYPIAX_P_LOG);
+    close(fd);
+    if (exit)
+      break;
+  }
+
+  DEBUGA_SKYPE("server (I am it) GONE\n", SKYPIAX_P_LOG);
+  close(s);
+  if (option_debug > 10) {
+    DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG);
+  }
+  return NULL;
+}
+void *skypiax_do_tcp_cli_thread(void *data)
+{
+  struct skypiax_config *p = data;
+  int s, fd, len;
+  short in[NN / 2];
+  short out[NN];
+  unsigned int sin_size;
+  struct sockaddr_in my_addr;
+  struct sockaddr_in remote_addr;
+  int a;
+  int i;
+  int got;
+
+  if (option_debug > 10) {
+    DEBUGA_PBX("ENTERING FUNC\n", SKYPIAX_P_LOG);
+  }
+  memset(&my_addr, 0, sizeof(my_addr));
+  my_addr.sin_family = AF_INET;
+  my_addr.sin_addr.s_addr = INADDR_ANY;
+  my_addr.sin_port = htons(5558);
+
+  if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+    ERRORA("socket Error\n", SKYPIAX_P_LOG);
+    if (option_debug > 10) {
+      DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG);
+    }
+    return NULL;
+  }
+
+  if (bind(s, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) < 0) {
+    ERRORA("bind Error\n", SKYPIAX_P_LOG);
+    if (option_debug > 10) {
+      DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG);
+    }
+    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);
+    //while (1 && p->owner && p->owner->_state == AST_STATE_UP)  FIXME FIXME FIXME
+    while (1) {
+
+      got = read(p->audioskypepipe[0], in, (NN / 2) * sizeof(short));
+
+      if (got > 0) {
+        a = 0;
+        for (i = 0; i < got / sizeof(short); i++) {
+          out[a] = in[i];
+          a++;
+          out[a] = in[i];
+          a++;
+        }
+
+        len = send(fd, out, got * 2, 0);
+
+        if (len == 0) {
+          DEBUGA_SKYPE("client GONE\n", SKYPIAX_P_LOG);
+          break;
+        }
+      } else {
+        usleep(100);
+      }
 
+    }
+    DEBUGA_SKYPE("client GONE\n", SKYPIAX_P_LOG);
+    close(fd);
+  }
 
+  DEBUGA_SKYPE("server (I am it) GONE\n", SKYPIAX_P_LOG);
+  close(s);
+  if (option_debug > 10) {
+    DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG);
+  }
+  return NULL;
+}
+
+
+int skypiax_skypeaudio_init(struct skypiax_config *p)
+{
+  int c;
+/* build the pipe that will be polled on by pbx */
+  c = pipe(p->audiopipe);
+  if (c) {
+    ERRORA("Unable to create audio pipe\n", SKYPIAX_P_LOG);
+    if (option_debug > 10) {
+      DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG);
+    }
+    return -1;
+  }
+
+/* the pipe is our audio fd for pbx to poll on */
+  p->skypiax_sound_capt_fd = p->audiopipe[0];
+
+  /* let's start the serial monitoring thread too, so we can have serial signaling */
+
+if(1)
+{
+    switch_thread_t *thread;
+    switch_threadattr_t *thd_attr = NULL;
+
+    switch_threadattr_create(&thd_attr, module_pool);
+    switch_threadattr_detach_set(thd_attr, 1);
+    switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
+    switch_thread_create(&thread, thd_attr, skypiax_do_tcp_srv_thread, p, module_pool);
+}
+
+/*
+  if (ast_pthread_create(&p->tcp_srv_thread, NULL, skypiax_do_tcp_srv_thread, p) < 0) {
+    ERRORA("Unable to start tcp_srv_thread thread.\n", SKYPIAX_P_LOG);
+    if (option_debug > 10) {
+      DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG);
+    }
+    return -1;
+  }
+*/
+
+  c = pipe(p->audioskypepipe);
+  if (c) {
+    ERRORA("Unable to create audioskypepipe\n", SKYPIAX_P_LOG);
+    if (option_debug > 10) {
+      DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG);
+    }
+    return -1;
+  }
+  fcntl(p->audioskypepipe[0], F_SETFL, O_NONBLOCK);
+  fcntl(p->audioskypepipe[1], F_SETFL, O_NONBLOCK);
+
+  if (option_debug > 10) {
+    DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG);
+  }
+  return 0;
+}
+#ifdef NOTDEF
+struct ast_frame *skypiax_skypeaudio_read(struct skypiax_config *p)
+{
+  static struct ast_frame f;
+  static short __buf[SKYPIAX_FRAME_SIZE + AST_FRIENDLY_OFFSET / 2];
+  short *buf;
+  int samples;
+
+  if (option_debug > 100) {
+    DEBUGA_PBX("ENTERING FUNC\n", SKYPIAX_P_LOG);
+  }
+  memset(__buf, '\0', (SKYPIAX_FRAME_SIZE + AST_FRIENDLY_OFFSET / 2));
+
+  buf = __buf + AST_FRIENDLY_OFFSET / 2;
+
+  f.frametype = AST_FRAME_NULL;
+  f.subclass = 0;
+  f.samples = 0;
+  f.datalen = 0;
+  f.data = NULL;
+  f.offset = 0;
+  f.src = skypiax_type;
+  f.mallocd = 0;
+  f.delivery.tv_sec = 0;
+  f.delivery.tv_usec = 0;
+
+  if ((samples = read(p->audiopipe[0], buf, SAMPLES_PER_FRAME * sizeof(short))) != 320) {
+    DEBUGA_SOUND("read=====> NOT GOOD samples=%d expected=%d\n", SKYPIAX_P_LOG, samples,
+                 SAMPLES_PER_FRAME * sizeof(short));
+    usleep(100);
+    //do nothing
+  } else {
+    //DEBUGA_SOUND("read=====> GOOD samples=%d\n", SKYPIAX_P_LOG, samples);
+    /* A real frame */
+    f.frametype = AST_FRAME_VOICE;
+    f.subclass = AST_FORMAT_SLINEAR;
+    f.samples = SKYPIAX_FRAME_SIZE;
+    f.datalen = SKYPIAX_FRAME_SIZE * 2;
+    f.data = buf;
+    f.offset = AST_FRIENDLY_OFFSET;
+    f.src = skypiax_type;
+    f.mallocd = 0;
+  }
+
+  if (option_debug > 100) {
+    DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG);
+  }
+  return &f;
+}
+int skypiax_skypeaudio_write(struct skypiax_config *p, struct ast_frame *f)
+{
+  int sent;
+
+  if (option_debug > 100) {
+    DEBUGA_PBX("ENTERING FUNC\n", SKYPIAX_P_LOG);
+  }
+  sent = write(p->audioskypepipe[1], (short *) f->data, f->datalen);
+
+  if (option_debug > 100) {
+    DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG);
+  }
+  return 0;
+}
+#endif //NOTDEF
+
+#endif /* SKYPE_AUDIO */
 static void tech_init(private_t *tech_pvt, switch_core_session_t *session)
 {
 	tech_pvt->read_frame.data = tech_pvt->databuf;
@@ -946,6 +1277,11 @@
     switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
     switch_thread_create(&thread, thd_attr, do_skype_thread, &SKYPIAX_CONFIGS[span_id], module_pool);
 }
+
+usleep(1000000);
+
+skypiax_skypeaudio_init(&SKYPIAX_CONFIGS[span_id]);
+
 				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "STARTED span_id=%d\n", span_id);
 
 



More information about the Freeswitch-branches mailing list