summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuper User2007-07-15 12:03:09 +0200
committerSuper User2007-07-15 12:03:09 +0200
commita54078ccf090907f1ebd9ddc3a02cd613ffecf9c (patch)
tree5fb00c27c281d5d687beaecc77c792e2230d212a
parentbackup (diff)
downloadlcr-a54078ccf090907f1ebd9ddc3a02cd613ffecf9c.tar.gz
lcr-a54078ccf090907f1ebd9ddc3a02cd613ffecf9c.tar.xz
lcr-a54078ccf090907f1ebd9ddc3a02cd613ffecf9c.zip
backup
-rw-r--r--asterisk_client.c197
-rw-r--r--callasterisk.cpp (renamed from callchan.cpp)84
-rw-r--r--callasterisk.h (renamed from callchan.h)12
-rw-r--r--macro.h (renamed from save.h)47
4 files changed, 301 insertions, 39 deletions
diff --git a/asterisk_client.c b/asterisk_client.c
new file mode 100644
index 0000000..386ea40
--- /dev/null
+++ b/asterisk_client.c
@@ -0,0 +1,197 @@
+/*****************************************************************************\
+** **
+** LCR **
+** **
+**---------------------------------------------------------------------------**
+** Copyright: Andreas Eversberg **
+** **
+** Asterisk socket client **
+** **
+\*****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include "macro.h"
+#include "extension.h"
+#include "message.h"
+#include "admin.h"
+
+int sock;
+
+struct admin_list {
+ struct admin_list *next;
+ struct admin_msg msg;
+} *admin_first = NULL;
+
+/*
+ * enque message from asterisk
+ */
+int admin_asterisk(int message_type, union parameter *param)
+{
+ struct admin_list *admin, **adminp;
+
+ adminp = &admin_first;
+ while(*adminp)
+ adminp = &((*adminp)->next);
+ admin = (struct admin_list *)MALLOC(sizeof(struct admin_list));
+ *adminp = admin;
+
+ admin->msg.type = message_type;
+ memcpy(&admin->msg.param, param, sizeof(union parameter));
+
+ return(0);
+}
+
+
+/* asterisk handler
+ * warning! not thread safe
+ * returns -1 for socket error, 0 for no work, 1 for work
+ */
+int handle_socket(void)
+{
+ int work = 0;
+ int len;
+ struct admin_message msg;
+ struct admin_list *admin;
+
+ /* read from socket */
+ len = read(sock, &msg, sizeof(msg));
+ if (len == 0)
+ {
+ printf("Socket closed\n");
+ return(-1); // socket closed
+ }
+ if (len > 0)
+ {
+ if (len != sizeof(msg))
+ {
+ fprintf(stderr, "Socket short read (%d)\n", len);
+ return(-1); // socket error
+ }
+ if (msg.message != ADMIN_MESSAGE)
+ {
+ fprintf(stderr, "Socket received illegal message %d\n", msg.message);
+ return(-1); // socket error
+ }
+ printf("message received %d\n", msg.u.msg.type);
+ work = 1;
+ } else
+ {
+ if (errno != EWOULDBLOCK)
+ {
+ fprintf(stderr, "Socket error %d\n", errno);
+ return(-1);
+ }
+ }
+
+ /* write to socket */
+ if (!admin_first)
+ return(work);
+ admin = admin_first;
+ len = write(sock, &admin->msg, sizeof(msg));
+ if (len == 0)
+ {
+ printf("Socket closed\n");
+ return(-1); // socket closed
+ }
+ if (len > 0)
+ {
+ if (len != sizeof(msg))
+ {
+ fprintf(stderr, "Socket short write (%d)\n", len);
+ return(-1); // socket error
+ }
+ /* free head */
+ admin_first = admin->next;
+ FREE(admin, 0);
+
+ work = 1;
+ } else
+ {
+ if (errno != EWOULDBLOCK)
+ {
+ fprintf(stderr, "Socket error %d\n", errno);
+ return(-1);
+ }
+ }
+
+ return(work);
+}
+
+/*
+ * main function
+ */
+int main(int argc, char *argv[])
+{
+ char *socket_name = SOCKET_NAME;
+ int conn;
+ struct sockaddr_un sock_address;
+ int ret;
+ unsigned long on = 1;
+ union parameter hello_param;
+
+ /* open socket */
+ if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
+ {
+ fprintf(stderr, "Failed to create socket.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* set socket address and name */
+ memset(&sock_address, 0, sizeof(sock_address));
+ sock_address.sun_family = PF_UNIX;
+ UCPY(sock_address.sun_path, socket_name);
+
+ /* connect socket */
+ if ((conn = connect(sock, (struct sockaddr *)&sock_address, SUN_LEN(&sock_address))) < 0)
+ {
+ close(sock);
+ fprintf(stderr, "Failed to connect to socket \"%s\".\nIs LCR running?\n", sock_address.sun_path);
+ exit(EXIT_FAILURE);
+ }
+
+ /* set non-blocking io */
+ if (ioctl(sock, FIONBIO, (unsigned char *)(&on)) < 0)
+ {
+ close(sock);
+ fprintf(stderr, "Failed to set socket into non-blocking IO.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* enque hello message */
+ memset(&hello_param, 0, sizeof(hello_param));
+ admin_asterisk(MESSAGE_HELLO, &hello_param);
+
+ while(42)
+ {
+ ret = handle_socket();
+ if (ret < 0)
+ break;
+ if (!ret)
+ usleep(30000);
+ }
+
+ /* close socket */
+ close(sock);
+ /* now we say good bye */
+ if (ret)
+ {
+ printf("%s\n", ret);
+ exit(EXIT_FAILURE);
+ }
+}
+
+
+
+
+
diff --git a/callchan.cpp b/callasterisk.cpp
index a3c7599..0e7719f 100644
--- a/callchan.cpp
+++ b/callasterisk.cpp
@@ -28,60 +28,82 @@
* constructor for a new call
* the call will have a relation to the calling endpoint
*/
-CallChan::CallChan(class Endpoint *epoint) : Call(epoint)
+CallAsterisk::CallAsterisk(unsigned long serial) : Call()
{
- if (!epoint)
- {
- PERROR("software error, epoint is NULL.\n");
- exit(-1);
- }
-
- PDEBUG(DEBUG_CALL, "creating new call and connecting it to the endpoint.\n");
+ PDEBUG(DEBUG_CALL, "Constructor(new call)");
c_type = CALL_TYPE_ASTERISK;
- c_epoint_id = epoint->ep_serial;
- PDEBUG(DEBUG_CALL, "Constructor(new call)");
+ c_epoint_id = serial;
+ if (c_epoint_id)
+ PDEBUG(DEBUG_CALL, "New call connected to endpoint id %lu\n", c_epoint_id);
}
/*
* call descructor
*/
-CallChan::~CallChan()
+CallAsterisk::~CallAsterisk()
{
}
-/* release call from endpoint
- * if the call has two relations, all relations are freed and the call will be
- * destroyed
- */
-void CallChan::release(unsigned long epoint_id, int hold, int location, int cause)
-{
- if (!epoint_id)
- {
- PERROR("software error, epoint is NULL.\n");
- return;
- }
-
- c_epoint_id = 0;
-
- PDEBUG(DEBUG_CALL, "call_release(): ended.\n");
-}
-
-
/* call process is called from the main loop
* it processes the current calling state.
* returns 0 if call nothing was done
*/
-int CallChan::handler(void)
+int CallAsterisk::handler(void)
{
return(0);
}
-void CallChan::message_epoint(unsigned long epoint_id, int message_type, union parameter *param)
+
+void CallAsterisk::message_epoint(unsigned long epoint_id, int message_type, union parameter *param)
+{
+ /* if endpoint has just been removed, but still a message in the que */
+ if (epoint_id != c_epoint_id)
+ return;
+
+ /* look for asterisk's interface */
+ if (admin_message_from_join(epoint_id, message_type, param)<0)
+ {
+ PERROR("No socket with asterisk found, this shall not happen. Closing socket shall cause release of all asterisk calls\n");
+ return;
+ }
+
+ if (message_type == MESSAGE_RELEASE)
+ {
+ delete this;
+ return;
+ }
+}
+
+void CallAsterisk::message_asterisk(unsigned long callref, int message_type, union parameter *param)
{
+ struct message *message;
+
+ /* create relation if no relation exists */
+ if (!c_epoint_id)
+ {
+ class Endpoint *epoint;
+
+ if (!(epoint = new Endpoint(0, c_serial, callref)))
+ FATAL("No memory for Endpoint instance\n");
+ if (!(epoint->ep_app = new DEFAULT_ENDPOINT_APP(epoint)))
+ FATAL("No memory for Endpoint Application instance\n");
+ }
+
+ message = message_create(c_serial, c_epoint_id, CALL_TO_EPOINT, message_type);
+ memcpy(&message->param, param, sizeof(message->param));
+ message_put(message);
+
+ if (message_type == MESSAGE_RELEASE)
+ {
+ delete this;
+ return;
+ }
}
+
+
diff --git a/callchan.h b/callasterisk.h
index 080bdbe..f0573df 100644
--- a/callchan.h
+++ b/callasterisk.h
@@ -1,22 +1,22 @@
/*****************************************************************************\
** **
-** PBX4Linux **
+** LCR **
** **
**---------------------------------------------------------------------------**
** Copyright: Andreas Eversberg **
** **
-** call header file for channel interface **
+** call header file for Asterisk interface **
** **
\*****************************************************************************/
-class CallChan : public Call
+class CallAsterisk : public Call
{
public:
- CallChan(class Endpoint *epoint);
- ~CallChan();
+ CallAsterisk(unsigned long serial);
+ ~CallAsterisk();
void message_epoint(unsigned long epoint_id, int message, union parameter *param);
+ void message_asterisk(unsigned long callref, int message_type, union parameter *param);
int handler(void);
- void release(unsigned long epoint_id, int hold, int location, int cause);
unsigned long c_epoint_id;
};
diff --git a/save.h b/macro.h
index 9b2d8a9..9bb1f29 100644
--- a/save.h
+++ b/macro.h
@@ -1,11 +1,12 @@
/*****************************************************************************\
** **
-** PBX4Linux **
+** LCR **
** **
**---------------------------------------------------------------------------**
** Copyright: Andreas Eversberg **
** **
-** Macros to do save string operations to avoid buffer overflows. **
+** Macros to do safe string operations to avoid buffer overflows **
+** Macros for memory allocation, feeing and error handling **
** **
\*****************************************************************************/
@@ -62,3 +63,45 @@ extern __inline__ void sprint(char *dst, unsigned int siz, char *fmt, ...)
#define UNPRINT snprintf
#define VUNPRINT vsnprintf
+/* fatal error with error message and exit */
+#define FATAL(fmt, arg...) fatal(__FUNCTION__, __LINE__, fmt, ##arg)
+extern __inline__ void fatal(const char *function, int line, char *fmt, ...)
+{
+ va_list args;
+ char buffer[256];
+
+ va_start(args, fmt);
+ vsnprintf(buffer, sizeof(buffer), fmt, args);
+ va_end(args);
+ buffer[sizeof(buffer)-1] = '\0';
+ fprintf(stderr, "FATAL ERROR in function %s, line %d: %s", function, line, buffer);
+ fprintf(stderr, "This error is not recoverable, must exit here.\n");
+#ifdef DEBUG_FUNC
+ debug(function, line, "FATAL ERROR", buffer);
+ debug(function, line, "FATAL ERROR", "This error is not recoverable, must exit here.\n");
+#endif
+ exit(EXIT_FAILURE);
+}
+
+/* memory allocation with setting to zero */
+#define MALLOC(size) _malloc(size, __FUNCTION__, __LINE__)
+extern __inline__ void *_malloc(unsigned long size, const char *function, int line)
+{
+ void *addr;
+ addr = malloc(size);
+ if (!addr)
+ fatal(function, line, "No memory for %d bytes.\n", size);
+ memset(addr, 0, size);
+ return(addr);
+}
+
+/* memory freeing with clearing memory to prevent using freed memory */
+#define FREE(addr, size) _free(addr, size)
+extern __inline void _free(void *addr, int size)
+{
+ if (size)
+ memset(addr, 0, size);
+ free(addr);
+}
+
+