diff options
author | John Crispin <john@openwrt.org> | 2011-02-07 21:47:54 +0000 |
---|---|---|
committer | John Crispin <john@openwrt.org> | 2011-02-07 21:47:54 +0000 |
commit | e651a9341a241ef5cefc1711d42e3f638aaba9b8 (patch) | |
tree | 6597330d9c4e70a48df28970d1b882986961e618 /package/tapi_sip | |
parent | 0cd254bdee1f2575502e0c4c71e1ca2b7dfc5259 (diff) | |
download | master-31e0f0ae-e651a9341a241ef5cefc1711d42e3f638aaba9b8.tar.gz master-31e0f0ae-e651a9341a241ef5cefc1711d42e3f638aaba9b8.tar.bz2 master-31e0f0ae-e651a9341a241ef5cefc1711d42e3f638aaba9b8.zip |
* drop libtapi and tapi_sip (moved to external git) * add build variants to pjsip * split tapi_dev audio driver out of patch into src/
SVN-Revision: 25412
Diffstat (limited to 'package/tapi_sip')
-rw-r--r-- | package/tapi_sip/Makefile | 41 | ||||
-rw-r--r-- | package/tapi_sip/files/telephony.conf | 28 | ||||
-rwxr-xr-x | package/tapi_sip/files/telephony.init | 50 | ||||
-rw-r--r-- | package/tapi_sip/src/Makefile | 21 | ||||
-rw-r--r-- | package/tapi_sip/src/agent.h | 41 | ||||
-rw-r--r-- | package/tapi_sip/src/contact.c | 162 | ||||
-rw-r--r-- | package/tapi_sip/src/contact.h | 33 | ||||
-rw-r--r-- | package/tapi_sip/src/dialdetector.c | 148 | ||||
-rw-r--r-- | package/tapi_sip/src/dialdetector.h | 49 | ||||
-rw-r--r-- | package/tapi_sip/src/list.h | 601 | ||||
-rw-r--r-- | package/tapi_sip/src/session.c | 84 | ||||
-rw-r--r-- | package/tapi_sip/src/session.h | 14 | ||||
-rw-r--r-- | package/tapi_sip/src/sip_agent.h | 27 | ||||
-rw-r--r-- | package/tapi_sip/src/sip_client.c | 800 | ||||
-rw-r--r-- | package/tapi_sip/src/sip_client.h | 61 | ||||
-rw-r--r-- | package/tapi_sip/src/stun.c | 243 | ||||
-rw-r--r-- | package/tapi_sip/src/stun.h | 12 | ||||
-rw-r--r-- | package/tapi_sip/src/tapi_agent.c | 105 | ||||
-rw-r--r-- | package/tapi_sip/src/tapi_agent.h | 37 | ||||
-rw-r--r-- | package/tapi_sip/src/tapi_sip.c | 179 |
20 files changed, 0 insertions, 2736 deletions
diff --git a/package/tapi_sip/Makefile b/package/tapi_sip/Makefile deleted file mode 100644 index 7a3d6766ac..0000000000 --- a/package/tapi_sip/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk - -PKG_NAME:=tapi_sip -PKG_RELEASE:=1 - -include $(INCLUDE_DIR)/package.mk - -define Package/tapi_sip - SECTION:=utils - CATEGORY:=Utilities - TITLE:=tapi_sip - DEPENDS:=+libuci +libtapi +pjsip +kmod-lqtapi -endef - -define Build/Prepare - mkdir -p $(PKG_BUILD_DIR) - $(CP) ./src/* $(PKG_BUILD_DIR)/ -endef - -define Build/Compile - CFLAGS="$(TARGET_CPPFLAGS) $(TARGET_CFLAGS)" \ - LDFLAGS="$(TARGET_LDFLAGS)" \ - $(MAKE) -C $(PKG_BUILD_DIR) \ - $(TARGET_CONFIGURE_OPTS) -endef - -define Package/tapi_sip/install - $(INSTALL_DIR) $(1)/usr/bin - $(INSTALL_BIN) $(PKG_BUILD_DIR)/tapi-sip $(1)/usr/bin/ - - $(INSTALL_DIR) $(1)/etc/config $(1)/etc/init.d - $(INSTALL_DATA) ./files/telephony.conf $(1)/etc/config/telephony - $(INSTALL_BIN) ./files/telephony.init $(1)/etc/init.d/telephony -endef - -$(eval $(call BuildPackage,tapi_sip)) diff --git a/package/tapi_sip/files/telephony.conf b/package/tapi_sip/files/telephony.conf deleted file mode 100644 index 6d87f45a88..0000000000 --- a/package/tapi_sip/files/telephony.conf +++ /dev/null @@ -1,28 +0,0 @@ -config 'config' 'config' -# option 'fw_url' 'http://192.168.1.100/danube_firmware.bin' - option 'fw_file' 'danube_firmware.bin' - option 'netdev' 'pppoe-wan' - option 'disable' '1' - -config 'account' 'account' - option 'realm' 'example.com' - option 'username' 'user' - option 'password' 'password' - option 'stun_host' 'stun.example.com' - option 'stun_port' '3478' - option 'sip_port' '5600' - -config 'contact' - option 'name' 'sip example' - option 'identifier' 'sip:user@example.net' - option 'number' '123' - -config 'contact' - option 'name' 'local1' - option 'identifier' 'tel:1' - option 'number' '01' - -config 'contact' - option 'name' 'local2' - option 'identifier' 'tel:2' - option 'number' '02' diff --git a/package/tapi_sip/files/telephony.init b/package/tapi_sip/files/telephony.init deleted file mode 100755 index 082024c236..0000000000 --- a/package/tapi_sip/files/telephony.init +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/sh /etc/rc.common -START=80 - -download_fw() -{ - config_load telephony - config_get fw_url config fw_url - config_get fw_file config fw_file - wget $fw_url -O /tmp/$fw_file || { - echo "failed to load $fw_url" - exit 1 - } -} - -load_module() -{ - M=`lsmod | grep vmmc` - [ -z "$M" ] || return - config_load telephony - config_get fw_file config fw_file - [ -z "fw_file" ] && exit 1 - F=/lib/firmware/$fw_file - [ ! -f "$F" -a ! -L "$F" ] && { - echo "missing firmware file" - exit 1 - } - [ -L "$F" -a -f /tmp/$fw_file ] && F=/tmp/$fw_file - insmod vmmc - sleep 3 -} - -stop() -{ - killall tapi-sip 2>/dev/null -} - -start() -{ - stop - config_load telephony - config_get fw_url config fw_url - config_get fw_file config fw_file - config_get netdev config netdev - config_get disable config disable - [ "$disable" != "1" ] && { - [ ! -z "$fw_url" -a ! -f "/tmp/$fw_file" ] && download_fw - load_module - /usr/bin/tapi-sip $netdev & - } -} diff --git a/package/tapi_sip/src/Makefile b/package/tapi_sip/src/Makefile deleted file mode 100644 index 56013700fe..0000000000 --- a/package/tapi_sip/src/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -ifndef CFLAGS -CFLAGS = -O2 -g -I ../src -endif - -CFLAGS += -Werror -Wall -std=gnu99 - -PJ_CFLAGS ?= `pkg-config libpjproject --cflags` -PJ_LDFLAGS ?= `pkg-config libpjproject --libs` - -CFLAGS += $(PJ_CFLAGS) -LDFLAGS += $(PJ_LDFLAGS) - -FPIC=-fPIC - -all: tapi-sip - -%.o: %.c - $(CC) -c -o $@ $^ $(CFLAGS) - -tapi-sip: contact.o session.o tapi_agent.o tapi_sip.o sip_client.o stun.o dialdetector.o - $(CC) -o $@ $^ -ltapi -luci $(LDFLAGS) diff --git a/package/tapi_sip/src/agent.h b/package/tapi_sip/src/agent.h deleted file mode 100644 index 795994178e..0000000000 --- a/package/tapi_sip/src/agent.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef __AGENT_H__ -#define __AGENT_H__ - -#include "agent.h" - -struct session; -struct agent; - -struct agent_ops { - int (*invite)(struct agent *, struct session *); - int (*accept)(struct agent *, struct session *); - int (*hangup)(struct agent *, struct session *); - - int (*get_endpoint)(struct agent *, struct session *); -}; - -struct agent { - const struct agent_ops *ops; -}; - -static inline int agent_invite(struct agent *agent, struct session *session) -{ - return agent->ops->invite(agent, session); -} - -static inline int agent_accept(struct agent *agent, struct session *session) -{ - return agent->ops->accept(agent, session); -} - -static inline int agent_hangup(struct agent *agent, struct session *session) -{ - return agent->ops->hangup(agent, session); -} - -static inline int agent_get_endpoint(struct agent *agent, struct session *session) -{ - return agent->ops->get_endpoint(agent, session); -} - -#endif diff --git a/package/tapi_sip/src/contact.c b/package/tapi_sip/src/contact.c deleted file mode 100644 index eeb38b4181..0000000000 --- a/package/tapi_sip/src/contact.c +++ /dev/null @@ -1,162 +0,0 @@ -#include <malloc.h> -#include <string.h> - -#include <uci.h> -#include <ucimap.h> - -#include "list.h" -#include "contact.h" - -static struct uci_context *ctx; -static struct uci_package *pkg; -static struct list_head contact_list; -static struct list_head account_list; - -static int contact_init(struct uci_map *map, void *section, - struct uci_section *s) -{ - struct contact *p = section; - p->name = strdup(s->e.name); - return 0; -} - -static int contact_add(struct uci_map *map, void *section) -{ - struct contact *c = section; - printf("add contact: %s\n", c->name); - list_add_tail(&c->head, &contact_list); - return 0; -} - -static struct uci_optmap contact_uci_map[] = { - { - UCIMAP_OPTION(struct contact, identifier), - .type = UCIMAP_STRING, - .name = "identifier", - }, - { - UCIMAP_OPTION(struct contact, number), - .type = UCIMAP_STRING, - .name = "number", - }, -}; - -static struct uci_sectionmap contact_sectionmap = { - UCIMAP_SECTION(struct contact, map), - .type = "contact", - .init = contact_init, - .add = contact_add, - .options = contact_uci_map, - .n_options = ARRAY_SIZE(contact_uci_map), - .options_size = sizeof(struct uci_optmap), -}; - -static int account_init(struct uci_map *map, void *section, - struct uci_section *s) -{ - struct account *a = section; - a->name = strdup(s->e.name); - return 0; -} - -static int account_add(struct uci_map *map, void *section) -{ - struct account *a = section; - list_add_tail(&a->head, &account_list); - return 0; -} - -static struct uci_optmap account_uci_map[] = { - { - UCIMAP_OPTION(struct account, realm), - .type = UCIMAP_STRING, - .name = "realm", - }, - { - UCIMAP_OPTION(struct account, username), - .type = UCIMAP_STRING, - .name = "username", - }, - { - UCIMAP_OPTION(struct account, sip_port), - .type = UCIMAP_INT, - .name = "sip_port", - }, - { - UCIMAP_OPTION(struct account, password), - .type = UCIMAP_STRING, - .name = "password", - }, - { - UCIMAP_OPTION(struct account, stun_host), - .type = UCIMAP_STRING, - .name = "stun_host", - }, - { - UCIMAP_OPTION(struct account, stun_port), - .type = UCIMAP_INT, - .name = "stun_port", - }, -}; - -static struct uci_sectionmap account_sectionmap = { - UCIMAP_SECTION(struct account, map), - .type = "account", - .init = account_init, - .add = account_add, - .options = account_uci_map, - .n_options = ARRAY_SIZE(account_uci_map), - .options_size = sizeof(struct uci_optmap), -}; - -static struct uci_sectionmap *network_smap[] = { - &contact_sectionmap, - &account_sectionmap, -}; - -static struct uci_map contact_map = { - .sections = network_smap, - .n_sections = ARRAY_SIZE(network_smap), -}; - -int contacts_init(void) -{ - int ret; - - INIT_LIST_HEAD(&contact_list); - INIT_LIST_HEAD(&account_list); - ctx = uci_alloc_context(); - - ucimap_init(&contact_map); - ret = uci_load(ctx, "telephony", &pkg); - if (ret) - return ret; - - ucimap_parse(&contact_map, pkg); - - return 0; -} - -void contacts_free(void) -{ -} - -struct contact *contact_get(const char *number) -{ - struct contact *contact; - list_for_each_entry(contact, &contact_list, head) - { - if (strcmp(contact->number, number) == 0) - return contact; - } - - return NULL; -} - -struct account *get_account(void) -{ - if (list_empty(&account_list)) - return NULL; - - return list_first_entry(&account_list, struct account, head); -} diff --git a/package/tapi_sip/src/contact.h b/package/tapi_sip/src/contact.h deleted file mode 100644 index 1fb0037bf6..0000000000 --- a/package/tapi_sip/src/contact.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef __CONTACT_H__ -#define __CONTACT_H__ - -#include <ucimap.h> - -struct account { - struct ucimap_section_data map; - const char *name; - char *realm; - char *username; - char *password; - int sip_port; - char *stun_host; - int stun_port; - struct list_head head; -}; - -struct contact { - struct ucimap_section_data map; - const char *name; - const char *identifier; - const char *number; - - struct list_head head; -}; - -int contacts_init(void); -void contacts_free(void); -struct contact *contact_get(const char *number); - -struct account *get_account(void); - -#endif diff --git a/package/tapi_sip/src/dialdetector.c b/package/tapi_sip/src/dialdetector.c deleted file mode 100644 index 277b0296c6..0000000000 --- a/package/tapi_sip/src/dialdetector.c +++ /dev/null @@ -1,148 +0,0 @@ -#include <linux/input.h> -#include <sys/epoll.h> -#include <stdint.h> -#include <stdbool.h> - - -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> - -#include <events.h> -#include "timerfd.h" - -#include "tapi-port.h" -#include "dialdetector.h" - -static const struct itimerspec dialdetector_timeout = { - .it_value.tv_sec = 3, -}; - -static const struct itimerspec dialdetector_impulse_timeout = { - .it_value.tv_nsec = 200000000, -}; - -static void dialdetector_note_digit(struct dialdetector *d, unsigned char digit) -{ - printf("note digit: %d\n", d->num_digits); - - d->digits[d->num_digits] = digit; - ++d->num_digits; - - timerfd_settime(d->timer_fd, 0, &dialdetector_timeout, NULL); - d->dial_state = DIALDETECTOR_DIAL_WAIT_TIMEOUT; -} - -static void dialdetector_reset(struct dialdetector *d) -{ - d->num_digits = 0; - d->impulses = 0; - d->dial_state = DIALDETECTOR_DIAL_WAIT; - d->port_state = DIALDETECTOR_PORT_INACTIVE; -} - -static bool dialdetector_timeout_event(int events, void *data) -{ - char num[20]; - struct dialdetector *dialdetector = data; - int i; - uint64_t tmp; - - read(dialdetector->timer_fd, &tmp, sizeof(tmp)); - - for (i = 0; i < dialdetector->num_digits; ++i) { - num[i] = '0' + dialdetector->digits[i]; - } - num[i] = '\0'; - - dialdetector->dial_callback(dialdetector->port, dialdetector->num_digits, - dialdetector->digits); - - dialdetector_reset(dialdetector); - - return true; -} - -static bool dialdetector_impulse_timeout_cb(int events, void *data) -{ - struct dialdetector *d = data; - uint64_t tmp; - - read(d->impulse_timer_fd, &tmp, sizeof(tmp)); - - if (d->port_state == DIALDETECTOR_PORT_ACTIVE_DOWN) { - d->port_state = DIALDETECTOR_PORT_INACTIVE; - } else { - printf("impulse: %d\n", d->impulses); - if (d->impulses > 0) - dialdetector_note_digit(d, d->impulses < 10 ? d->impulses : 0); - d->impulses = 0; - } - - return true; -} - -static void dialdetector_port_event(struct tapi_port *port, - struct tapi_event *event, void *data) -{ - struct dialdetector *d = data; - - printf("port event: %d %d\n", d->port_state, event->hook.on); - - switch (d->port_state) { - case DIALDETECTOR_PORT_INACTIVE: - if (event->type == TAPI_EVENT_TYPE_HOOK && event->hook.on == false) - d->port_state = DIALDETECTOR_PORT_ACTIVE; - break; - case DIALDETECTOR_PORT_ACTIVE: - switch (event->type) { - case TAPI_EVENT_TYPE_HOOK: - if (event->hook.on == true) { - d->port_state = DIALDETECTOR_PORT_ACTIVE_DOWN; - timerfd_settime(d->impulse_timer_fd, 0, &dialdetector_impulse_timeout, NULL); - } - break; - case TAPI_EVENT_TYPE_DTMF: - dialdetector_note_digit(d, event->dtmf.code); - break; - } - break; - case DIALDETECTOR_PORT_ACTIVE_DOWN: - if (event->type == TAPI_EVENT_TYPE_HOOK && event->hook.on == false) { - timerfd_settime(d->timer_fd, 0, &dialdetector_timeout, NULL); - ++d->impulses; - d->port_state = DIALDETECTOR_PORT_ACTIVE; - } - break; - } -} - -struct dialdetector *dialdetector_alloc(struct tapi_port *port) -{ - struct dialdetector *dialdetector; - dialdetector = malloc(sizeof(*dialdetector)); - - dialdetector->timer_fd = timerfd_create(CLOCK_MONOTONIC, 0); - dialdetector->impulse_timer_fd = timerfd_create(CLOCK_MONOTONIC, 0); - dialdetector->port = port; - dialdetector->num_digits = 0; - dialdetector->impulses = 0; - dialdetector->dial_state = DIALDETECTOR_DIAL_WAIT; - dialdetector->port_state = DIALDETECTOR_PORT_INACTIVE; - - dialdetector->timeout_cb.callback = dialdetector_timeout_event; - dialdetector->timeout_cb.data = dialdetector; - dialdetector->impulse_cb.callback = dialdetector_impulse_timeout_cb; - dialdetector->impulse_cb.data = dialdetector; - - dialdetector->port_listener.callback = dialdetector_port_event; - dialdetector->port_listener.data = dialdetector; - - tapi_port_register_event(port, &dialdetector->port_listener); - - event_register(dialdetector->impulse_timer_fd, EPOLLIN, - &dialdetector->impulse_cb); - event_register(dialdetector->timer_fd, EPOLLIN, &dialdetector->timeout_cb); - - return dialdetector; -} diff --git a/package/tapi_sip/src/dialdetector.h b/package/tapi_sip/src/dialdetector.h deleted file mode 100644 index c3737c36e9..0000000000 --- a/package/tapi_sip/src/dialdetector.h +++ /dev/null @@ -1,49 +0,0 @@ -#include <linux/input.h> -#include <sys/epoll.h> -#include <stdint.h> -#include <stdbool.h> - - -#include <stdlib.h> -#include <stdio.h> - -#include "events.h" -#include "timerfd.h" - -#include "tapi-port.h" - -enum dialdetector_dial_state { - DIALDETECTOR_DIAL_WAIT = 1, - DIALDETECTOR_DIAL_WAIT_TIMEOUT = 2, -}; - -enum dialdetector_port_state { - DIALDETECTOR_PORT_INACTIVE = 0, - DIALDETECTOR_PORT_ACTIVE = 1, - DIALDETECTOR_PORT_ACTIVE_DOWN = 2, -}; - -struct dialdetector { - enum dialdetector_dial_state dial_state; - enum dialdetector_port_state port_state; - - struct tapi_port *port; - int timer_fd; - int impulse_timer_fd; - - struct event_callback timeout_cb; - struct event_callback impulse_cb; - struct tapi_port_event_listener port_listener; - - size_t num_digits; - unsigned char digits[20]; - - unsigned int impulses; - - void (*dial_callback)(struct tapi_port *port, size_t num_digits, const unsigned char *digits); -}; - - -struct tapi_port; - -struct dialdetector *dialdetector_alloc(struct tapi_port *port); diff --git a/package/tapi_sip/src/list.h b/package/tapi_sip/src/list.h deleted file mode 100644 index 2959a061d3..0000000000 --- a/package/tapi_sip/src/list.h +++ /dev/null @@ -1,601 +0,0 @@ -#ifndef _LINUX_LIST_H -#define _LINUX_LIST_H - -#include <stddef.h> -/** - * container_of - cast a member of a structure out to the containing structure - * @ptr: the pointer to the member. - * @type: the type of the container struct this is embedded in. - * @member: the name of the member within the struct. - * - */ -#ifndef container_of -#define container_of(ptr, type, member) ( \ - (type *)( (char *)ptr - offsetof(type,member) )) -#endif - - -/* - * Simple doubly linked list implementation. - * - * Some of the internal functions ("__xxx") are useful when - * manipulating whole lists rather than single entries, as - * sometimes we already know the next/prev entries and we can - * generate better code by using them directly rather than - * using the generic single-entry routines. - */ - -struct list_head { - struct list_head *next, *prev; -}; - -#define LIST_HEAD_INIT(name) { &(name), &(name) } - -#define LIST_HEAD(name) \ - struct list_head name = LIST_HEAD_INIT(name) - -static inline void INIT_LIST_HEAD(struct list_head *list) -{ - list->next = list; - list->prev = list; -} - -/* - * Insert a new entry between two known consecutive entries. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static inline void __list_add(struct list_head *new, - struct list_head *prev, - struct list_head *next) -{ - next->prev = new; - new->next = next; - new->prev = prev; - prev->next = new; -} - -/** - * list_add - add a new entry - * @new: new entry to be added - * @head: list head to add it after - * - * Insert a new entry after the specified head. - * This is good for implementing stacks. - */ -static inline void list_add(struct list_head *new, struct list_head *head) -{ - __list_add(new, head, head->next); -} - - -/** - * list_add_tail - add a new entry - * @new: new entry to be added - * @head: list head to add it before - * - * Insert a new entry before the specified head. - * This is useful for implementing queues. - */ -static inline void list_add_tail(struct list_head *new, struct list_head *head) -{ - __list_add(new, head->prev, head); -} - - -/* - * Delete a list entry by making the prev/next entries - * point to each other. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static inline void __list_del(struct list_head * prev, struct list_head * next) -{ - next->prev = prev; - prev->next = next; -} - -/** - * list_del - deletes entry from list. - * @entry: the element to delete from the list. - * Note: list_empty() on entry does not return true after this, the entry is - * in an undefined state. - */ -static inline void list_del(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - entry->next = NULL; - entry->prev = NULL; -} - -/** - * list_replace - replace old entry by new one - * @old : the element to be replaced - * @new : the new element to insert - * - * If @old was empty, it will be overwritten. - */ -static inline void list_replace(struct list_head *old, - struct list_head *new) -{ - new->next = old->next; - new->next->prev = new; - new->prev = old->prev; - new->prev->next = new; -} - -static inline void list_replace_init(struct list_head *old, - struct list_head *new) -{ - list_replace(old, new); - INIT_LIST_HEAD(old); -} - -/** - * list_del_init - deletes entry from list and reinitialize it. - * @entry: the element to delete from the list. - */ -static inline void list_del_init(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - INIT_LIST_HEAD(entry); -} - -/** - * list_move - delete from one list and add as another's head - * @list: the entry to move - * @head: the head that will precede our entry - */ -static inline void list_move(struct list_head *list, struct list_head *head) -{ - __list_del(list->prev, list->next); - list_add(list, head); -} - -/** - * list_move_tail - delete from one list and add as another's tail - * @list: the entry to move - * @head: the head that will follow our entry - */ -static inline void list_move_tail(struct list_head *list, - struct list_head *head) -{ - __list_del(list->prev, list->next); - list_add_tail(list, head); -} - -/** - * list_is_last - tests whether @list is the last entry in list @head - * @list: the entry to test - * @head: the head of the list - */ -static inline int list_is_last(const struct list_head *list, - const struct list_head *head) -{ - return list->next == head; -} - -/** - * list_empty - tests whether a list is empty - * @head: the list to test. - */ -static inline int list_empty(const struct list_head *head) -{ - return head->next == head; -} - -/** - * list_empty_careful - tests whether a list is empty and not being modified - * @head: the list to test - * - * Description: - * tests whether a list is empty _and_ checks that no other CPU might be - * in the process of modifying either member (next or prev) - * - * NOTE: using list_empty_careful() without synchronization - * can only be safe if the only activity that can happen - * to the list entry is list_del_init(). Eg. it cannot be used - * if another CPU could re-list_add() it. - */ -static inline int list_empty_careful(const struct list_head *head) -{ - struct list_head *next = head->next; - return (next == head) && (next == head->prev); -} - -static inline void __list_splice(struct list_head *list, - struct list_head *head) -{ - struct list_head *first = list->next; - struct list_head *last = list->prev; - struct list_head *at = head->next; - - first->prev = head; - head->next = first; - - last->next = at; - at->prev = last; -} - -/** - * list_splice - join two lists - * @list: the new list to add. - * @head: the place to add it in the first list. - */ -static inline void list_splice(struct list_head *list, struct list_head *head) -{ - if (!list_empty(list)) - __list_splice(list, head); -} - -/** - * list_splice_init - join two lists and reinitialise the emptied list. - * @list: the new list to add. - * @head: the place to add it in the first list. - * - * The list at @list is reinitialised - */ -static inline void list_splice_init(struct list_head *list, - struct list_head *head) -{ - if (!list_empty(list)) { - __list_splice(list, head); - INIT_LIST_HEAD(list); - } -} - -/** - * list_entry - get the struct for this entry - * @ptr: the &struct list_head pointer. - * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. - */ -#define list_entry(ptr, type, member) \ - container_of(ptr, type, member) - -/** - * list_first_entry - get the first element from a list - * @ptr: the list head to take the element from. - * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. - * - * Note, that list is expected to be not empty. - */ -#define list_first_entry(ptr, type, member) \ - list_entry((ptr)->next, type, member) - -/** - * list_for_each - iterate over a list - * @pos: the &struct list_head to use as a loop cursor. - * @head: the head for your list. - */ -#define list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); \ - pos = pos->next) - -/** - * __list_for_each - iterate over a list - * @pos: the &struct list_head to use as a loop cursor. - * @head: the head for your list. - * - * This variant differs from list_for_each() in that it's the - * simplest possible list iteration code, no prefetching is done. - * Use this for code that knows the list to be very short (empty - * or 1 entry) most of the time. - */ -#define __list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); pos = pos->next) - -/** - * list_for_each_prev - iterate over a list backwards - * @pos: the &struct list_head to use as a loop cursor. - * @head: the head for your list. - */ -#define list_for_each_prev(pos, head) \ - for (pos = (head)->prev; pos != (head); \ - pos = pos->prev) - -/** - * list_for_each_safe - iterate over a list safe against removal of list entry - * @pos: the &struct list_head to use as a loop cursor. - * @n: another &struct list_head to use as temporary storage - * @head: the head for your list. - */ -#define list_for_each_safe(pos, n, head) \ - for (pos = (head)->next, n = pos->next; pos != (head); \ - pos = n, n = pos->next) - -/** - * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry - * @pos: the &struct list_head to use as a loop cursor. - * @n: another &struct list_head to use as temporary storage - * @head: the head for your list. - */ -#define list_for_each_prev_safe(pos, n, head) \ - for (pos = (head)->prev, n = pos->prev; \ - pos != (head); \ - pos = n, n = pos->prev) - -/** - * list_for_each_entry - iterate over list of given type - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry(pos, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_entry_reverse - iterate backwards over list of given type. - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_reverse(pos, head, member) \ - for (pos = list_entry((head)->prev, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.prev, typeof(*pos), member)) - -/** - * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue() - * @pos: the type * to use as a start point - * @head: the head of the list - * @member: the name of the list_struct within the struct. - * - * Prepares a pos entry for use as a start point in list_for_each_entry_continue(). - */ -#define list_prepare_entry(pos, head, member) \ - ((pos) ? : list_entry(head, typeof(*pos), member)) - -/** - * list_for_each_entry_continue - continue iteration over list of given type - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Continue to iterate over list of given type, continuing after - * the current position. - */ -#define list_for_each_entry_continue(pos, head, member) \ - for (pos = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_entry_continue_reverse - iterate backwards from the given point - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Start to iterate over list of given type backwards, continuing after - * the current position. - */ -#define list_for_each_entry_continue_reverse(pos, head, member) \ - for (pos = list_entry(pos->member.prev, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.prev, typeof(*pos), member)) - -/** - * list_for_each_entry_from - iterate over list of given type from the current point - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Iterate over list of given type, continuing from current position. - */ -#define list_for_each_entry_from(pos, head, member) \ - for (; &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry - * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_safe(pos, n, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member), \ - n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) - -/** - * list_for_each_entry_safe_continue - * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Iterate over list of given type, continuing after current point, - * safe against removal of list entry. - */ -#define list_for_each_entry_safe_continue(pos, n, head, member) \ - for (pos = list_entry(pos->member.next, typeof(*pos), member), \ - n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) - -/** - * list_for_each_entry_safe_from - * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Iterate over list of given type from current point, safe against - * removal of list entry. - */ -#define list_for_each_entry_safe_from(pos, n, head, member) \ - for (n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) - -/** - * list_for_each_entry_safe_reverse - * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Iterate backwards over list of given type, safe against removal - * of list entry. - */ -#define list_for_each_entry_safe_reverse(pos, n, head, member) \ - for (pos = list_entry((head)->prev, typeof(*pos), member), \ - n = list_entry(pos->member.prev, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.prev, typeof(*n), member)) - -/* - * Double linked lists with a single pointer list head. - * Mostly useful for hash tables where the two pointer list head is - * too wasteful. - * You lose the ability to access the tail in O(1). - */ - -struct hlist_head { - struct hlist_node *first; -}; - -struct hlist_node { - struct hlist_node *next, **pprev; -}; - -#define HLIST_HEAD_INIT { .first = NULL } -#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } -#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) -static inline void INIT_HLIST_NODE(struct hlist_node *h) -{ - h->next = NULL; - h->pprev = NULL; -} - -static inline int hlist_unhashed(const struct hlist_node *h) -{ - return !h->pprev; -} - -static inline int hlist_empty(const struct hlist_head *h) -{ - return !h->first; -} - -static inline void __hlist_del(struct hlist_node *n) -{ - struct hlist_node *next = n->next; - struct hlist_node **pprev = n->pprev; - *pprev = next; - if (next) - next->pprev = pprev; -} - -static inline void hlist_del(struct hlist_node *n) -{ - __hlist_del(n); - n->next = NULL; - n->pprev = NULL; -} - -static inline void hlist_del_init(struct hlist_node *n) -{ - if (!hlist_unhashed(n)) { - __hlist_del(n); - INIT_HLIST_NODE(n); - } -} - - -static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) -{ - struct hlist_node *first = h->first; - n->next = first; - if (first) - first->pprev = &n->next; - h->first = n; - n->pprev = &h->first; -} - - -/* next must be != NULL */ -static inline void hlist_add_before(struct hlist_node *n, - struct hlist_node *next) -{ - n->pprev = next->pprev; - n->next = next; - next->pprev = &n->next; - *(n->pprev) = n; -} - -static inline void hlist_add_after(struct hlist_node *n, - struct hlist_node *next) -{ - next->next = n->next; - n->next = next; - next->pprev = &n->next; - - if(next->next) - next->next->pprev = &next->next; -} - -#define hlist_entry(ptr, type, member) container_of(ptr,type,member) - -#define hlist_for_each(pos, head) \ - for (pos = (head)->first; pos; pos = pos->next) - -#define hlist_for_each_safe(pos, n, head) \ - for (pos = (head)->first; pos; pos = n) - -/** - * hlist_for_each_entry - iterate over list of given type - * @tpos: the type * to use as a loop cursor. - * @pos: the &struct hlist_node to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the hlist_node within the struct. - */ -#define hlist_for_each_entry(tpos, pos, head, member) \ - for (pos = (head)->first; pos && \ - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ - pos = pos->next) - -/** - * hlist_for_each_entry_continue - iterate over a hlist continuing after current point - * @tpos: the type * to use as a loop cursor. - * @pos: the &struct hlist_node to use as a loop cursor. - * @member: the name of the hlist_node within the struct. - */ -#define hlist_for_each_entry_continue(tpos, pos, member) \ - for (pos = (pos)->next; pos && \ - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ - pos = pos->next) - -/** - * hlist_for_each_entry_from - iterate over a hlist continuing from current point - * @tpos: the type * to use as a loop cursor. - * @pos: the &struct hlist_node to use as a loop cursor. - * @member: the name of the hlist_node within the struct. - */ -#define hlist_for_each_entry_from(tpos, pos, member) \ - for (; pos && \ - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ - pos = pos->next) - -/** - * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry - * @tpos: the type * to use as a loop cursor. - * @pos: the &struct hlist_node to use as a loop cursor. - * @n: another &struct hlist_node to use as temporary storage - * @head: the head for your list. - * @member: the name of the hlist_node within the struct. - */ -#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \ - for (pos = (head)->first; \ - pos && ({ n = pos->next; 1; }) && \ - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ - pos = n) - -#endif diff --git a/package/tapi_sip/src/session.c b/package/tapi_sip/src/session.c deleted file mode 100644 index 97f6f06fe1..0000000000 --- a/package/tapi_sip/src/session.c +++ /dev/null @@ -1,84 +0,0 @@ -#include <stdlib.h> -#include <stdio.h> - -#include "agent.h" -#include "session.h" - -#include <tapi-device.h> - - -struct session -{ - struct agent *agents[2]; - - struct tapi_device *tdev; - - void (*release)(struct session *); - - int link; -}; - -struct session *session_alloc(struct tapi_device *dev, struct agent *caller, - struct agent *callee, void (*release)(struct session *)) -{ - struct session *session; - int ret; - - session = malloc(sizeof(*session)); - - session->tdev = dev; - - session->agents[0] = caller; - session->agents[1] = callee; - - ret = agent_invite(callee, session); - if (ret < 0) { - session_hangup(session, callee); - free(session); - return NULL; - } - - session->release = release; - - return session; -} - -void session_accept(struct session *session, struct agent *agent) -{ - int ep[2]; - - printf("session_accept: %p %p\n", session, agent); - printf("session agents: %p %p\n", session->agents[0], session->agents[1]); - printf("session tdev: %p\n", session->tdev); - - agent_accept(session->agents[0], session); - - ep[0] = agent_get_endpoint(session->agents[0], session); - ep[1] = agent_get_endpoint(session->agents[1], session); - session->link = tapi_link_alloc(session->tdev, ep[0], ep[1]); - - printf("eps: %d %d\n", ep[0], ep[1]); - - tapi_link_enable(session->tdev, session->link); - - tapi_sync(session->tdev); -} - -void session_hangup(struct session *session, struct agent *agent) -{ - struct agent *other_agent; - - if (session->agents[0] == agent) - other_agent = session->agents[1]; - else - other_agent = session->agents[0]; - - agent_hangup(other_agent, session); - - tapi_link_disable(session->tdev, session->link); - tapi_link_free(session->tdev, session->link); - tapi_sync(session->tdev); - - if (session->release) - session->release(session); -} diff --git a/package/tapi_sip/src/session.h b/package/tapi_sip/src/session.h deleted file mode 100644 index 7403785f5f..0000000000 --- a/package/tapi_sip/src/session.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __SESSION_H__ -#define __SESSION_H__ - -struct agent; -struct session; -struct tapi_device; - -struct session *session_alloc(struct tapi_device *, struct agent *caller, - struct agent *callee, void (*release)(struct session *)); -void session_hangup(struct session *, struct agent *); -void session_accept(struct session *, struct agent *); -void session_free(struct session *); - -#endif diff --git a/package/tapi_sip/src/sip_agent.h b/package/tapi_sip/src/sip_agent.h deleted file mode 100644 index 7f711da437..0000000000 --- a/package/tapi_sip/src/sip_agent.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef __SIP_AGENT_H__ -#define __SIP_AGENT_H__ - -#include "agent.h" -#include <events.h> - -struct sip_agent { - struct sip_client *client; - const char *identifier; - - struct tapi_stream *stream; - struct session *session; - - struct pjsip_inv_session *inv; - - int rtp_sockfd; - - struct sockaddr_storage remote_addr; - struct sockaddr_storage local_addr; - - struct agent agent; - - struct event_callback rtp_recv_callback; - struct event_callback stream_recv_callback; -}; - -#endif diff --git a/package/tapi_sip/src/sip_client.c b/package/tapi_sip/src/sip_client.c deleted file mode 100644 index 0b1e2ddd8f..0000000000 --- a/package/tapi_sip/src/sip_client.c +++ /dev/null @@ -1,800 +0,0 @@ -#include "sip_client.h" - -#include <stdint.h> -#include <sys/socket.h> -#include <sys/types.h> -#include <netdb.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <errno.h> -#include <sys/epoll.h> -#include <stdbool.h> -#include <unistd.h> -#include <fcntl.h> -#include <net/if.h> -#include <sys/ioctl.h> - -#include "stun.h" -#include "sip_agent.h" -#include "session.h" -#include "list.h" - -static inline struct sip_agent *agent_to_sip_agent(struct agent *agent) -{ - return container_of(agent, struct sip_agent, agent); -} - -static int iface_get_addr(const char *iface, struct sockaddr_storage *addr) -{ - int fd; - int ret; - struct ifreq ifr; - - fd = socket(AF_INET, SOCK_DGRAM, 0); - - ifr.ifr_addr.sa_family = AF_INET; - strncpy(ifr.ifr_name, iface, IFNAMSIZ-1); - ret = ioctl(fd, SIOCGIFADDR, &ifr); - if (ret < 0) - perror("Failed to get interface address"); - - close(fd); - - if (ret == 0) - memcpy(addr, &ifr.ifr_addr, sizeof(ifr.ifr_addr)); - - return ret; -} - -#if 0 -static bool sockaddr_is_local(struct sockaddr_storage *addr) -{ - unsigned long s_addr; - bool is_local = false; - - switch (addr->ss_family) { - case AF_INET: - s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr; - if ((s_addr & 0xff000000) == 0x10000000) - is_local = true; - else if ((s_addr & 0xfff00000) == 0xac100000) - is_local = true; - else if ((s_addr & 0xffff0000) == 0xc0a80000) - is_local = true; - break; - default: - break; - } - - return is_local; -} -#endif - -static uint16_t sockaddr_get_port(struct sockaddr_storage *addr) -{ - uint16_t port; - - switch (addr->ss_family) { - case AF_INET: - port = ((struct sockaddr_in *)addr)->sin_port; - break; - case AF_INET6: - port = ((struct sockaddr_in6 *)addr)->sin6_port; - break; - default: - port = 0; - break; - } - - return port; -} - -static void sockaddr_set_port(struct sockaddr_storage *addr, uint16_t port) -{ - switch (addr->ss_family) { - case AF_INET: - ((struct sockaddr_in *)addr)->sin_port = port; - break; - case AF_INET6: - ((struct sockaddr_in6 *)addr)->sin6_port = port; - break; - default: - break; - } -} - -static void *sockaddr_get_addr(struct sockaddr_storage *addr) -{ - void *a; - switch (addr->ss_family) { - case AF_INET: - a = &((struct sockaddr_in *)addr)->sin_addr.s_addr; - break; - case AF_INET6: - a = ((struct sockaddr_in6 *)addr)->sin6_addr.s6_addr; - break; - default: - a = NULL; - break; - } - - return a; -} - -static int sockaddr_to_string(struct sockaddr_storage *addr, char *s, size_t n) -{ - return inet_ntop(addr->ss_family, sockaddr_get_addr(addr), s, n) == NULL ? -1 : 0; -} - -static pjsip_module mod_siprtp; -static struct sip_client *global_client; - -/* Creates a datagram socket and binds it to a port in the range of - * start_port-end_port */ -static int sip_client_create_socket(struct sip_client *client, - struct sockaddr_storage *sockaddr, uint16_t start_port, - uint16_t end_port) -{ - int sockfd; - int ret; - - sockfd = socket(AF_INET, SOCK_DGRAM, 0); - if (sockfd < 0) - return sockfd; - - memcpy(sockaddr, &client->local_addr, sizeof(client->local_addr)); - do { - sockaddr_set_port(sockaddr, start_port); - ret = bind(sockfd, (struct sockaddr *)sockaddr, sizeof(*sockaddr)); - ++start_port; - } while (ret == -1 && start_port < end_port); - - if (ret == -1) - return -1; - - return sockfd; -} - -static int sip_worker_thread(void *arg) -{ - struct sip_client *client = arg; - - while (1) { - pj_time_val timeout = {0, 10}; - pjsip_endpt_handle_events(client->sip_endpt, &timeout); - } - - return 0; -} - -static bool sip_agent_stream_recv_callback(int events, void *data) -{ - struct sip_agent *agent = data; - char buf[512]; - int len; - int ret; - - len = read(agent->stream->fd, buf, 512); - if (len < 0) - return true; - - ret = sendto(agent->rtp_sockfd, buf, len, 0, - (struct sockaddr *)&agent->remote_addr, sizeof(agent->remote_addr)); - - if (ret < 0) - printf("failed to send rtp data: %d\n", errno); - - return true; -} - - -static bool sip_agent_rtp_recv_callback(int events, void *data) -{ - struct sip_agent *agent = data; - char buf[512]; - int len; - - len = recvfrom(agent->rtp_sockfd, buf, 512, 0, NULL, NULL); - if (agent->stream) - write(agent->stream->fd, buf, len); - - return true; -} - -static pj_status_t sip_client_create_sdp(struct sip_client *client, pj_pool_t *pool, - struct sip_agent *agent, - pjmedia_sdp_session **p_sdp) -{ - pj_time_val tv; - pjmedia_sdp_session *sdp; - pjmedia_sdp_media *m; - pjmedia_sdp_attr *attr; - struct sockaddr_storage rtp_addr; - char addr[INET6_ADDRSTRLEN]; - - PJ_ASSERT_RETURN(pool && p_sdp, PJ_EINVAL); - - agent->rtp_sockfd = sip_client_create_socket(client, &rtp_addr, 4000, 5000); - if (client->stun) - stun_client_resolve(client->stun, agent->rtp_sockfd, - (struct sockaddr *)&rtp_addr); - - agent->rtp_recv_callback.callback = sip_agent_rtp_recv_callback; - agent->rtp_recv_callback.data = agent; - event_register(agent->rtp_sockfd, EPOLLIN, &agent->rtp_recv_callback); - - /* Create and initialize basic SDP session */ - sdp = pj_pool_zalloc (pool, sizeof(pjmedia_sdp_session)); - - pj_gettimeofday(&tv); - sdp->origin.user = pj_str("pjsip-siprtp"); - sdp->origin.version = sdp->origin.id = tv.sec + 2208988800UL; - sdp->origin.net_type = pj_str("IN"); - sdp->origin.addr_type = pj_str("IP4"); - sdp->origin.addr = *pj_gethostname(); - sdp->name = pj_str("pjsip"); - - /* Since we only support one media stream at present, put the - * SDP connection line in the session level. - */ - sdp->conn = pj_pool_zalloc(pool, sizeof(pjmedia_sdp_conn)); - sdp->conn->net_type = pj_str("IN"); - sdp->conn->addr_type = pj_str("IP4"); - sockaddr_to_string(&rtp_addr, addr, sizeof(addr)); - pj_strdup2_with_null(pool, &sdp->conn->addr, addr); - - /* SDP time and attributes. */ - sdp->time.start = sdp->time.stop = 0; - sdp->attr_count = 0; - - /* Create media stream 0: */ - - sdp->media_count = 1; - m = pj_pool_zalloc(pool, sizeof(pjmedia_sdp_media)); - sdp->media[0] = m; - - /* Standard media info: */ - m->desc.media = pj_str("audio"); - m->desc.port = sockaddr_get_port(&rtp_addr); - m->desc.port_count = 1; - m->desc.transport = pj_str("RTP/AVP"); - - /* Add format and rtpmap for each codec. */ - m->desc.fmt_count = 1; - m->attr_count = 0; - - { - pjmedia_sdp_rtpmap rtpmap; - char ptstr[10]; - - sprintf(ptstr, "%d", 0); - pj_strdup2_with_null(pool, &m->desc.fmt[0], ptstr); - rtpmap.pt = m->desc.fmt[0]; - rtpmap.clock_rate = 64000; - rtpmap.enc_name = pj_str("PCMU"); - rtpmap.param.slen = 0; - - } - - /* Add sendrecv attribute. */ - attr = pj_pool_zalloc(pool, sizeof(pjmedia_sdp_attr)); - attr->name = pj_str("sendrecv"); - m->attr[m->attr_count++] = attr; - - /* Done */ - *p_sdp = sdp; - - return PJ_SUCCESS; -} - -static int sip_agent_invite(struct agent *agent, struct session *session) -{ - struct sip_agent *sip_agent = agent_to_sip_agent(agent); - struct sip_client *client = sip_agent->client; - pjsip_dialog *dlg; - pjmedia_sdp_session *sdp; - pjsip_tx_data *tdata; - pj_status_t status; - pj_str_t dst_uri; - - sip_agent->session = session; - - dst_uri = pj_str((char *)sip_agent->identifier); - - /* Create UAC dialog */ - status = pjsip_dlg_create_uac(pjsip_ua_instance(), - &client->local_contact, /* local URI */ - &client->local_contact, /* local Contact */ - &dst_uri, /* remote URI */ - &dst_uri, /* remote target */ - &dlg); /* dialog */ - if (status != PJ_SUCCESS) { - fprintf(stderr, "Failed to create uac dialog\n"); - return -1; - } - - pjsip_auth_clt_set_credentials(&dlg->auth_sess, 1, &client->cred); - - /* Create SDP */ - sip_client_create_sdp(client, dlg->pool, sip_agent, &sdp); - - /* Create the INVITE session. */ - status = pjsip_inv_create_uac(dlg, sdp, 0, &sip_agent->inv); - if (status != PJ_SUCCESS) { - fprintf(stderr, "Failed to create invite session\n"); - pjsip_dlg_terminate(dlg); - return -1; - } - - - /* Attach call data to invite session */ - sip_agent->inv->mod_data[mod_siprtp.id] = sip_agent; - - /* Create initial INVITE request. - * This INVITE request will contain a perfectly good request and - * an SDP body as well. - */ - status = pjsip_inv_invite(sip_agent->inv, &tdata); - PJ_ASSERT_RETURN(status == PJ_SUCCESS, -1); /*TODO*/ - - /* Send initial INVITE request. - * From now on, the invite session's state will be reported to us - * via the invite session callbacks. - */ - status = pjsip_inv_send_msg(sip_agent->inv, tdata); - PJ_ASSERT_RETURN(status == PJ_SUCCESS, -1); /*TODO*/ - - return 0; -} - -static int sip_agent_hangup(struct agent *agent, struct session *session) -{ - struct sip_agent *sip_agent = agent_to_sip_agent(agent); - pjsip_tx_data *tdata; - pj_status_t status; - - printf("hangup %p\n", sip_agent->inv); - - status = pjsip_inv_end_session(sip_agent->inv, 603, NULL, &tdata); - if (status == PJ_SUCCESS && tdata != NULL) - pjsip_inv_send_msg(sip_agent->inv, tdata); - - if (sip_agent->rtp_sockfd) { - event_unregister(sip_agent->rtp_sockfd); - close(sip_agent->rtp_sockfd); - } - if (sip_agent->stream) { - event_unregister(sip_agent->stream->fd); - tapi_stream_free(sip_agent->stream); - } - - sip_agent->inv->mod_data[mod_siprtp.id] = NULL; - free(sip_agent); - - return 0; -} - -static int sip_agent_alloc_stream(struct sip_agent *agent) -{ - int flags; - - if (agent->stream) - printf("BUG!!!! %s:%s[%d]\n", __FILE__, __func__, __LINE__); - - agent->stream = tapi_stream_alloc(agent->client->tdev); - agent->stream_recv_callback.callback = sip_agent_stream_recv_callback; - agent->stream_recv_callback.data = agent; - - flags = fcntl(agent->stream->fd, F_GETFL, 0); - fcntl(agent->stream->fd, F_SETFL, flags | O_NONBLOCK); - - event_register(agent->stream->fd, EPOLLIN, &agent->stream_recv_callback); - - return 0; -} - -static void sip_agent_free_stream(struct sip_agent *agent) -{ - if (!agent->stream) - return; - - event_unregister(agent->stream->fd); - tapi_stream_free(agent->stream); - agent->stream = NULL; -} - -static int sip_agent_accept(struct agent *agent, struct session *session) -{ - struct sip_agent *sip_agent = agent_to_sip_agent(agent); - pj_status_t status; - pjsip_tx_data *tdata; - - /* Create 200 response .*/ - status = pjsip_inv_answer(sip_agent->inv, 200, - NULL, NULL, &tdata); - if (status != PJ_SUCCESS) { - status = pjsip_inv_answer(sip_agent->inv, - PJSIP_SC_NOT_ACCEPTABLE, - NULL, NULL, &tdata); - if (status == PJ_SUCCESS) - pjsip_inv_send_msg(sip_agent->inv, tdata); - else - pjsip_inv_terminate(sip_agent->inv, 500, PJ_FALSE); - return -1; - } - - /* Send the 200 response. */ - status = pjsip_inv_send_msg(sip_agent->inv, tdata); - PJ_ASSERT_ON_FAIL(status == PJ_SUCCESS, return -1); - - sip_agent_alloc_stream(sip_agent); - - return 0; -} - -static int sip_agent_get_endpoint(struct agent *agent, struct session *session) -{ - struct sip_agent *sip_agent = agent_to_sip_agent(agent); - return tapi_stream_get_endpoint(sip_agent->stream); -} - -static const struct agent_ops sip_agent_ops = { - .invite = sip_agent_invite, - .accept = sip_agent_accept, - .hangup = sip_agent_hangup, - .get_endpoint = sip_agent_get_endpoint, -}; - -struct sip_agent *sip_client_alloc_agent(struct sip_client *client, - const char *identifier) -{ - struct sip_agent *agent; - - agent = malloc(sizeof(*agent)); - memset(agent, 0, sizeof(*agent)); - - agent->agent.ops = &sip_agent_ops; - agent->identifier = identifier; - agent->client = client; - - return agent; -} - -/* - * Receive incoming call - */ -static void process_incoming_call(struct sip_client *client, pjsip_rx_data *rdata) -{ - unsigned options; - struct sip_agent *agent; - pjsip_tx_data *tdata; - pj_status_t status; - pjsip_dialog *dlg; - pjmedia_sdp_session *sdp; - - agent = sip_client_alloc_agent(client, "extern"); - - /* Verify that we can handle the request. */ - options = 0; - status = pjsip_inv_verify_request(rdata, &options, NULL, NULL, - client->sip_endpt, &tdata); - if (status != PJ_SUCCESS) { - /* - * No we can't handle the incoming INVITE request. - */ - if (tdata) { - pjsip_response_addr res_addr; - pjsip_get_response_addr(tdata->pool, rdata, &res_addr); - pjsip_endpt_send_response(client->sip_endpt, &res_addr, tdata, - NULL, NULL); - } else { - /* Respond with 500 (Internal Server Error) */ - pjsip_endpt_respond_stateless(client->sip_endpt, rdata, 500, NULL, - NULL, NULL); - } - - return; - } - - /* Create UAS dialog */ - status = pjsip_dlg_create_uas(pjsip_ua_instance(), rdata, - &client->local_contact, &dlg); - if (status != PJ_SUCCESS) { - const pj_str_t reason = pj_str("Unable to create dialog"); - pjsip_endpt_respond_stateless(client->sip_endpt, rdata, - 500, &reason, - NULL, NULL); - return; - } - - /* Create SDP */ - sip_client_create_sdp(client, dlg->pool, agent, &sdp); - - /* Create UAS invite session */ - status = pjsip_inv_create_uas(dlg, rdata, sdp, 0, &agent->inv); - if (status != PJ_SUCCESS) { - pjsip_dlg_create_response(dlg, rdata, 500, NULL, &tdata); - pjsip_dlg_send_response(dlg, pjsip_rdata_get_tsx(rdata), tdata); - return; - } - - /* Attach call data to invite session */ - agent->inv->mod_data[mod_siprtp.id] = agent; - - /* Create 180 response .*/ - status = pjsip_inv_initial_answer(agent->inv, rdata, 180, - NULL, NULL, &tdata); - if (status != PJ_SUCCESS) { - status = pjsip_inv_initial_answer(agent->inv, rdata, - PJSIP_SC_NOT_ACCEPTABLE, - NULL, NULL, &tdata); - if (status == PJ_SUCCESS) - pjsip_inv_send_msg(agent->inv, tdata); - else - pjsip_inv_terminate(agent->inv, 500, PJ_FALSE); - return; - } - - /* Send the 180 response. */ - status = pjsip_inv_send_msg(agent->inv, tdata); - PJ_ASSERT_ON_FAIL(status == PJ_SUCCESS, return); - - if (client->incoming_call_cb) - client->incoming_call_cb(client, agent); -} - -/* Callback to be called to handle incoming requests outside dialogs: */ -static pj_bool_t on_rx_request(pjsip_rx_data *rdata) -{ - struct sip_client *client = global_client; - - /* Ignore strandled ACKs (must not send respone */ - if (rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD) - return PJ_FALSE; - - /* Respond (statelessly) any non-INVITE requests with 500 */ - if (rdata->msg_info.msg->line.req.method.id != PJSIP_INVITE_METHOD) { - pj_str_t reason = pj_str("Unsupported Operation"); - pjsip_endpt_respond_stateless(client->sip_endpt, rdata, - 500, &reason, - NULL, NULL); - return PJ_TRUE; - } - - /* Handle incoming INVITE */ - process_incoming_call(client, rdata); - - /* Done */ - return PJ_TRUE; -} - -static pjsip_module sip_client_mod = { - NULL, NULL, /* prev, next. */ - { "mod-tapisip", 13 }, /* Name. */ - -1, /* Id */ - PJSIP_MOD_PRIORITY_APPLICATION, /* Priority */ - NULL, /* load() */ - NULL, /* start() */ - NULL, /* stop() */ - NULL, /* unload() */ - &on_rx_request, /* on_rx_request() */ - NULL, /* on_rx_response() */ - NULL, /* on_tx_request. */ - NULL, /* on_tx_response() */ - NULL, /* on_tsx_state() */ -}; - -/* Callback to be called when dialog has forked: */ -static void call_on_forked(pjsip_inv_session *inv, pjsip_event *e) -{ - PJ_UNUSED_ARG(inv); - PJ_UNUSED_ARG(e); -} - -/* Callback to be called when invite session's state has changed: */ -static void call_on_state_changed(pjsip_inv_session *inv, pjsip_event *e) -{ - struct sip_agent *agent = inv->mod_data[mod_siprtp.id]; - - printf("state changed: %d\n", inv->state); - - if (!agent) - return; - - switch (inv->state) { - case PJSIP_INV_STATE_DISCONNECTED: - printf("Disconnected\n"); - if (agent->session) - session_hangup(agent->session, &agent->agent); - if (agent->rtp_sockfd) { - event_unregister(agent->rtp_sockfd); - close(agent->rtp_sockfd); - } - sip_agent_free_stream(agent); - free(agent); - inv->mod_data[mod_siprtp.id] = NULL; - break; - case PJSIP_INV_STATE_CONFIRMED: - printf("Connected: %p\n", agent->stream); - if (agent->stream) - break; - sip_agent_alloc_stream(agent); - session_accept(agent->session, &agent->agent); - break; - default: - break; - } -} - -static void call_on_media_update(pjsip_inv_session *inv, pj_status_t status) -{ - struct sip_agent *agent; - pj_pool_t *pool; - const pjmedia_sdp_session *local_sdp, *remote_sdp; - char local[100]; - char remote[100]; - int i; - - printf("media updte\n"); - - agent = inv->mod_data[mod_siprtp.id]; - pool = inv->dlg->pool; - - /* Do nothing if media negotiation has failed */ - if (status != PJ_SUCCESS) - return; - /* Capture stream definition from the SDP */ - pjmedia_sdp_neg_get_active_local(inv->neg, &local_sdp); - pjmedia_sdp_neg_get_active_remote(inv->neg, &remote_sdp); - - strlcpy(local, local_sdp->conn->addr.ptr, local_sdp->conn->addr.slen + 1); - printf("local media count: %d\n", local_sdp->media_count); - printf("local: %s %d\n", local, - ntohs(local_sdp->media[0]->desc.port)); - strlcpy(remote, remote_sdp->conn->addr.ptr, remote_sdp->conn->addr.slen + 1); - printf("remote media count: %d\n", remote_sdp->media_count); - printf("remote: %s %d\n", remote, - ntohs(remote_sdp->media[0]->desc.port)); - - agent->remote_addr.ss_family = AF_INET; - inet_pton(AF_INET, remote, - sockaddr_get_addr(&agent->remote_addr)); - sockaddr_set_port(&agent->remote_addr, remote_sdp->media[0]->desc.port); - - printf("attributes: %d\n", remote_sdp->attr_count); - for (i = 0; i < remote_sdp->attr_count; ++i) - printf("%s: %s\n", remote_sdp->attr[i]->name.ptr, - remote_sdp->attr[i]->value.ptr); - -} - -static int sip_client_init_sip_endpoint(struct sip_client *client) -{ - pj_status_t status; - pjsip_host_port addrname; - pjsip_inv_callback inv_cb; - pjsip_transport *tp; - char public_addr[INET6_ADDRSTRLEN]; - - global_client = client; - - pj_caching_pool_init(&client->cp, &pj_pool_factory_default_policy, 0); - client->pool = pj_pool_create(&client->cp.factory, "tapi sip", 1000, 1000, NULL); - - status = pjsip_endpt_create(&client->cp.factory, NULL, - &client->sip_endpt); - - client->sockfd = sip_client_create_socket(client, &client->public_addr, 5060, 5100); - if (client->stun) - stun_client_resolve(client->stun, client->sockfd, (struct sockaddr *)&client->public_addr); - - sockaddr_to_string(&client->public_addr, public_addr, sizeof(public_addr)); - - addrname.host = pj_str(public_addr); - addrname.port = sockaddr_get_port(&client->public_addr); - - pjsip_udp_transport_attach(client->sip_endpt, client->sockfd, &addrname, 1, &tp); - - status = pjsip_tsx_layer_init_module(client->sip_endpt); - PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); - - status = pjsip_ua_init_module(client->sip_endpt, NULL); - PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); - - status = pjsip_100rel_init_module(client->sip_endpt); - PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); - - pj_bzero(&inv_cb, sizeof(inv_cb)); - inv_cb.on_state_changed = &call_on_state_changed; - inv_cb.on_new_session = &call_on_forked; - inv_cb.on_media_update = &call_on_media_update; - - status = pjsip_inv_usage_init(client->sip_endpt, &inv_cb); - PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1); - - status = pjsip_endpt_register_module(client->sip_endpt, &sip_client_mod); - - pj_thread_create(client->pool, "sip client", &sip_worker_thread, client, - 0, 0, &client->sip_thread); - - return status; -} - -static void sip_client_register_callback(struct pjsip_regc_cbparam *param) -{ - if (param->status != PJ_SUCCESS || param->code / 100 != 2) - printf("Failed to register: %d %d", param->status, param->code); -} - -void sip_client_free(struct sip_client *client) -{ - pjsip_regc_destroy(client->regc); - pjsip_endpt_destroy(client->sip_endpt); -} - -void sip_client_register(struct sip_client *client) -{ - pjsip_tx_data *tdata; - - pjsip_regc_register(client->regc, true, &tdata); - pjsip_regc_send(client->regc, tdata); -} - -void sip_client_set_cred(struct sip_client *client) -{ - char local_contact[100]; - char server_uri[100]; - char s[INET6_ADDRSTRLEN]; - char contact_addr[INET6_ADDRSTRLEN + 10]; - pj_str_t pj_contact_addr; - - sockaddr_to_string(&client->public_addr, s, sizeof(s)); - - snprintf(contact_addr, sizeof(contact_addr), "sip:%s:%d", s, - sockaddr_get_port(&client->public_addr)); - pj_contact_addr = pj_str(contact_addr); - - client->cred.realm = pj_str((char *)client->config->host); - client->cred.scheme = pj_str("digest"); - client->cred.username = pj_str((char *)client->config->username); - client->cred.data_type = PJSIP_CRED_DATA_PLAIN_PASSWD; - client->cred.data = pj_str((char *)client->config->password); - - snprintf(local_contact, sizeof(local_contact), "sip:%s@%s", - client->config->username, client->config->host); - pj_strdup2_with_null(client->pool, &client->local_contact, local_contact); - - snprintf(server_uri, sizeof(server_uri), "sip:%s\n", client->config->host); - pj_strdup2_with_null(client->pool, &client->server_uri, server_uri); - - pjsip_regc_init(client->regc, &client->server_uri, &client->local_contact, - &client->local_contact, 1, &pj_contact_addr, 3600); - pjsip_regc_set_credentials(client->regc, 1, &client->cred); - - sip_client_register(client); -} - -void sip_client_init(struct sip_client *client, struct tapi_device *tdev, - const struct sip_client_config *config) -{ - global_client = client; - client->config = config; - - client->tdev = tdev; - - iface_get_addr(config->iface, &client->local_addr); - - if (config->stun_host && config->stun_port) - client->stun = stun_client_alloc(config->stun_host, config->stun_port); - else - client->stun = NULL; - - sip_client_init_sip_endpoint(client); - - pjsip_regc_create(client->sip_endpt, client, sip_client_register_callback, - &client->regc); - - sip_client_set_cred(client); -} - - diff --git a/package/tapi_sip/src/sip_client.h b/package/tapi_sip/src/sip_client.h deleted file mode 100644 index 1c494b6dc3..0000000000 --- a/package/tapi_sip/src/sip_client.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef __SIP_CLIENT_H__ -#define __SIP_CLIENT_H__ - -#include <tapi-stream.h> -#include <tapi-device.h> - -#include <pjsip.h> -#include <pjsip_ua.h> -#include <pjsip_simple.h> -#include <pjlib-util.h> -#include <pjlib.h> - -#include <stdlib.h> -#include <sys/socket.h> -#include <stdint.h> - -struct stun_client; -struct sip_agent; - -struct sip_client_config { - const char *iface; - - const char *host; - uint16_t port; - const char *username; - const char *password; - - const char *stun_host; - uint16_t stun_port; -}; - -struct sip_client { - const struct sip_client_config *config; - - struct tapi_device *tdev; - struct stun_client *stun; - - struct sockaddr_storage public_addr; - struct sockaddr_storage local_addr; - - int sockfd; - - pj_thread_t *sip_thread; - pj_caching_pool cp; - pj_pool_t *pool; - pjsip_endpoint *sip_endpt; - pjsip_cred_info cred; - pj_str_t local_contact; - pj_str_t server_uri; - - pjsip_regc *regc; - - int (*incoming_call_cb)(struct sip_client *client, struct sip_agent *agent); -}; - -void sip_client_init(struct sip_client *client, struct tapi_device *dev, - const struct sip_client_config *config); - -struct sip_agent *sip_client_alloc_agent(struct sip_client *client, const char *dst_uri); - -#endif diff --git a/package/tapi_sip/src/stun.c b/package/tapi_sip/src/stun.c deleted file mode 100644 index 5c6b240679..0000000000 --- a/package/tapi_sip/src/stun.c +++ /dev/null @@ -1,243 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <netdb.h> - -#include <poll.h> - - -struct stun_client { - struct addrinfo *serverinfo; -}; - -struct stun_response { - struct sockaddr addr; -}; - -struct stun_header { - uint16_t type; - uint16_t length; - uint32_t cookie; - uint32_t id[3]; -} __attribute((packed)); - -struct stun_packet { - struct stun_header header; - uint8_t data[0]; -} __attribute((packed)); - -#define STUN_CLASS(c0, c1) (((c0) << 4) | ((c1) << 8)) - -#define STUN_CLASS_REQUEST STUN_CLASS(0, 0) -#define STUN_CLASS_INDICATION STUN_CLASS(0, 1) -#define STUN_CLASS_SUCCESS STUN_CLASS(1, 0) -#define STUN_CLASS_ERROR STUN_CLASS(1, 1) - -#define STUN_CLASS_MASK STUN_CLASS(1, 1) - -#define STUN_MESSAGE(msg) (((msg & 0xf10) << 2) | ((msg & 0x70) << 1) | (msg & 0xf)) -#define STUN_MESSAGE_BIND STUN_MESSAGE(1) - -#define STUN_COOKIE 0x2112a442 - -enum { - STUN_ATTR_TYPE_MAPPED_ADDRESS = 0x1, - STUN_ATTR_TYPE_XOR_MAPPED_ADDRESS = 0x20, - STUN_ATTR_TYPE_XOR_MAPPED_ADDRESS2 = 0x8020, -}; - -static inline uint16_t get_unaligned_be16(const uint8_t *buf) -{ - return (buf[0] << 8) | buf[1]; -} - -static inline uint16_t get_unaligned_be32(const uint8_t *buf) -{ - return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; -} - -static int stun_parse_xor_mapped_address(struct stun_response *response, - const uint8_t *buf, int length) -{ - uint8_t fam = buf[1]; - uint16_t port = get_unaligned_be16(&buf[2]); - struct sockaddr_in *sin = (struct sockaddr_in *)&response->addr; - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&response->addr; - - - switch (fam) { - case 0x1: - sin->sin_family = AF_INET; - sin->sin_port = htons((port ^ (uint16_t)((STUN_COOKIE & 0xffff0000) >> 16))); - memcpy(&sin->sin_addr.s_addr, buf + 4, 4); - sin->sin_addr.s_addr ^= htonl(STUN_COOKIE); - printf("xor port: %d\n", sin->sin_port); - break; - case 0x2: - sin6->sin6_family = AF_INET6; - sin->sin_port = htons((port ^ (uint16_t)((STUN_COOKIE & 0xffff0000) >> 16))); - memcpy(sin6->sin6_addr.s6_addr, buf + 4, 16); - break; - } - - return 0; -} - -static int stun_parse_mapped_address(struct stun_response *response, - const uint8_t *buf, int length) -{ - uint8_t fam = buf[1]; - uint16_t port = get_unaligned_be16(&buf[2]); - struct sockaddr_in *sin = (struct sockaddr_in *)&response->addr; - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&response->addr; - - printf("port: %d\n", port); - - switch (fam) { - case 0x1: - sin->sin_family = AF_INET; - sin->sin_port = htons(port); - memcpy(&sin->sin_addr.s_addr, buf + 4, 4); - break; - case 0x2: - sin6->sin6_family = AF_INET6; - sin6->sin6_port = htons(port); - memcpy(sin6->sin6_addr.s6_addr, buf + 4, 16); - break; - } - - return 0; -} - -static int stun_parse_response(struct stun_response *response, - const struct stun_packet *packet) -{ - uint16_t attr_type, attr_length; - const uint8_t *buf; - int length = ntohs(packet->header.length); - int ret; - int i = 0; - - if (packet->header.cookie != htonl(STUN_COOKIE)) - return -1; - - if (packet->header.length < 4) - return 0; - - buf = packet->data; - - do { - attr_type = get_unaligned_be16(&buf[i]); - attr_length = get_unaligned_be16(&buf[i + 2]); - i += 4; - - if (i + attr_length > length) - break; - - switch (attr_type) { - case STUN_ATTR_TYPE_MAPPED_ADDRESS: - ret = stun_parse_mapped_address(response, &buf[i], attr_length); - break; - case STUN_ATTR_TYPE_XOR_MAPPED_ADDRESS: - case STUN_ATTR_TYPE_XOR_MAPPED_ADDRESS2: - ret = stun_parse_xor_mapped_address(response, &buf[i], attr_length); - break; - } - - i += attr_length; - - } while (i < length && ret == 0); - - return 0; -} - -static struct stun_packet *stun_packet_alloc(size_t data_size) -{ - return malloc(sizeof(struct stun_packet) + data_size); -} - -int stun_client_resolve(struct stun_client *stun, int sockfd, struct sockaddr *addr) -{ - struct stun_packet *packet = stun_packet_alloc(200); - struct stun_response response; - int ret; - int retries = 4; - int timeout = 500; - struct pollfd pollfd; - - pollfd.events = POLLIN; - pollfd.fd = sockfd; - - packet->header.type = htons(STUN_CLASS_REQUEST | STUN_MESSAGE_BIND); - packet->header.cookie = htonl(STUN_COOKIE); - packet->header.id[0] = 0x12345678; - packet->header.id[1] = 0x12345678; - packet->header.id[2] = 0x12345678; - packet->header.length = 0; - - while (retries--) { - ret = sendto(sockfd, packet, sizeof(struct stun_header) + packet->header.length, - 0, stun->serverinfo->ai_addr, stun->serverinfo->ai_addrlen); - - ret = poll(&pollfd, 1, timeout); - switch (ret) { - case 0: - timeout <<= 1; - case -EINTR: - printf("retry\n"); - continue; - default: - retries = 0; - } - ret = recvfrom(sockfd, packet, 200, 0, NULL, NULL); - } - - if (ret <= 0) - return ret ? ret : -ETIMEDOUT; - - memset(&response, 0, sizeof(response)); - ret = stun_parse_response(&response, packet); - - *addr = response.addr; - - return ret; -} - -struct stun_client *stun_client_alloc(const char *hostname, uint16_t port) -{ - struct addrinfo hints; - struct stun_client *stun; - int ret; - char p[6]; - - - stun = malloc(sizeof(*stun)); - if (!stun) - return NULL; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_DGRAM; - hints.ai_flags = AI_NUMERICSERV; - - snprintf(p, sizeof(p), "%d", port); - if ((ret = getaddrinfo(hostname, p, &hints, &stun->serverinfo)) != 0) { - fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(ret)); - return NULL; - } - - - return stun; -} - -void stun_client_free(struct stun_client *stun) -{ - freeaddrinfo(stun->serverinfo); - free(stun); -} diff --git a/package/tapi_sip/src/stun.h b/package/tapi_sip/src/stun.h deleted file mode 100644 index 2cd61c9f16..0000000000 --- a/package/tapi_sip/src/stun.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __STUN_H__ -#define __STUN_H__ - -#include <stdint.h> - -struct stun_client; - -struct stun_client *stun_client_alloc(const char *hostname, uint16_t port); -void stun_client_free(struct stun_client *); -int stun_client_resolve(struct stun_client *stun, int sockfd, struct sockaddr *addr); - -#endif diff --git a/package/tapi_sip/src/tapi_agent.c b/package/tapi_sip/src/tapi_agent.c deleted file mode 100644 index 93c73c24d8..0000000000 --- a/package/tapi_sip/src/tapi_agent.c +++ /dev/null @@ -1,105 +0,0 @@ - -#include <stdbool.h> -#include <stdio.h> -#include <tapi-port.h> - -#include "session.h" -#include "agent.h" -#include "tapi_agent.h" - -static int tapi_agent_invite(struct agent *agent, struct session *session) -{ - struct tapi_agent *tagent = agent_to_tapi_agent(agent); - - if (tagent->session) - return -1; - - tagent->state = TAPI_AGENT_STATE_RINGING; - tapi_port_set_ring(&tagent->port, true); - - tagent->session = session; - - return 0; -} - -static int tapi_agent_accept(struct agent *agent, struct session *session) -{ - return 0; -} - -static int tapi_agent_hangup(struct agent *agent, struct session *session) -{ - struct tapi_agent *tagent = agent_to_tapi_agent(agent); - - switch (tagent->state) { - case TAPI_AGENT_STATE_RINGING: - tapi_port_set_ring(&tagent->port, false); - break; - default: - break; - } - - tagent->state = TAPI_AGENT_STATE_IDLE; - tagent->session = NULL; - - return 0; -} - -static int tapi_agent_get_endpoint(struct agent *agent, struct session *session) -{ - struct tapi_agent *tagent = agent_to_tapi_agent(agent); - return tapi_port_get_endpoint(&tagent->port); -} - -static const struct agent_ops tapi_agent_ops = { - .invite = tapi_agent_invite, - .accept = tapi_agent_accept, - .hangup = tapi_agent_hangup, - .get_endpoint = tapi_agent_get_endpoint, -}; - -static void tapi_agent_event(struct tapi_port *port, struct tapi_event *event, - void *data) -{ - struct tapi_agent *tagent = data; - - if (event->type != TAPI_EVENT_TYPE_HOOK) - return; - - if (!tagent->session) - return; - - if (event->hook.on) { - session_hangup(tagent->session, &tagent->agent); - tagent->state = TAPI_AGENT_STATE_IDLE; - tagent->session = NULL; - } else { - session_accept(tagent->session, &tagent->agent); - tagent->state = TAPI_AGENT_STATE_ACTIVE; - } -} - -void tapi_agent_init(struct tapi_device *tdev, int port, struct tapi_agent *tagent) -{ - int ret; - - tagent->agent.ops = &tapi_agent_ops; - tagent->state = TAPI_AGENT_STATE_IDLE; - tagent->session = NULL; - - ret = tapi_port_open(tdev, port, &tagent->port); - if (ret) { - printf("Failed to open tapi port %d: %d\n", port, ret); - return; - } - - tagent->event_listener.callback = tapi_agent_event; - tagent->event_listener.data = tagent; - - tapi_port_register_event(&tagent->port, &tagent->event_listener); -} - -void tapi_agent_free(struct tapi_agent *tagent) -{ - tapi_port_unregister_event(&tagent->port, &tagent->event_listener); -} diff --git a/package/tapi_sip/src/tapi_agent.h b/package/tapi_sip/src/tapi_agent.h deleted file mode 100644 index 12e8701215..0000000000 --- a/package/tapi_sip/src/tapi_agent.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef __TAPI_AGENT_H__ -#define __TAPI_AGENT_H__ - -#include "agent.h" -#include <tapi-port.h> - -struct session; - -enum tapi_agent_state { - TAPI_AGENT_STATE_IDLE, - TAPI_AGENT_STATE_RINGING, - TAPI_AGENT_STATE_ACTIVE, -}; - -struct tapi_agent { - struct agent agent; - struct tapi_port port; - struct tapi_port_event_listener event_listener; - - enum tapi_agent_state state; - - struct session *session; -}; - -static inline struct tapi_agent *agent_to_tapi_agent(struct agent *agent) -{ - return container_of(agent, struct tapi_agent, agent); -} - -static inline struct tapi_agent *port_to_tapi_agent(struct tapi_port *port) -{ - return container_of(port, struct tapi_agent, port); -} - -void tapi_agent_init(struct tapi_device *tdev, int port, struct tapi_agent *tagent); - -#endif diff --git a/package/tapi_sip/src/tapi_sip.c b/package/tapi_sip/src/tapi_sip.c deleted file mode 100644 index 518c63c3dd..0000000000 --- a/package/tapi_sip/src/tapi_sip.c +++ /dev/null @@ -1,179 +0,0 @@ - -#include <stdbool.h> -#include <stdlib.h> -#include <stdio.h> -#include <sys/ioctl.h> -#include <fcntl.h> -#include <errno.h> -#include <poll.h> -#include <string.h> - -#include <linux/input.h> -#include "dialdetector.h" - -#include <tapi-ioctl.h> - -#include <tapi-device.h> -#include <tapi-port.h> - -#include "contact.h" -#include "session.h" -#include "sip_client.h" -#include "sip_agent.h" -#include "tapi_agent.h" - -static struct tapi_device dev; -static struct tapi_agent *ports; - -static struct sip_client sip_client; - -static void release_session(struct session *session) -{ - free(session); -} - -static void dial(struct tapi_agent *caller, struct agent *callee) -{ - struct session *session; - - session = session_alloc(&dev, &caller->agent, callee, release_session); - - if (!session) - return; - - caller->session = session; -} - -static void tel_dial(struct tapi_agent *caller, const char *number) -{ - int callee; - - callee = atoi(number) - 1; - - if (callee < 0 || callee > 1) - return; - dial(caller, &ports[callee].agent); -} - -static void sip_dial(struct tapi_agent *caller, const char *identifier) -{ - struct sip_agent *callee; - - callee = sip_client_alloc_agent(&sip_client, identifier); - if (!callee) - return; - - dial(caller, &callee->agent); -} - -static void dial_callback(struct tapi_port *port, size_t num_digits, const unsigned char *digits) -{ - struct tapi_agent *tagent = port_to_tapi_agent(port); - char number[100]; - struct contact *contact; - size_t i; - - if (tagent->state != TAPI_AGENT_STATE_IDLE) - return; - - for (i = 0; i < num_digits; ++i) { - if (digits[0] > 9) - break; - number[i] = digits[i] + '0'; - } - number[i] = '\0'; - - printf("dial callback: %s\n", number); - - contact = contact_get(number); - - if (!contact) - return; - - if (strncmp("tel:", contact->identifier, 4) == 0) { - tel_dial(tagent, contact->identifier + 4); - } else if (strncmp("sip:", contact->identifier, 4) == 0) { - sip_dial(tagent, contact->identifier); - } - tagent->state = TAPI_AGENT_STATE_ACTIVE; -} - -static int incoming_sip_call(struct sip_client *client, - struct sip_agent *caller) -{ - struct tapi_agent *callee = NULL;; - struct session *session; - int i; - - for (i = 0; i < 2; ++i) { - if (ports[i].state == TAPI_AGENT_STATE_IDLE) { - callee = &ports[i]; - break; - } - } - - if (callee == NULL) - return -1; - - session = session_alloc(&dev, &caller->agent, &callee->agent, - release_session); - caller->session = session; - - return 0; -} - -int main(int argc, char *argv[]) -{ - struct dialdetector *dd, *dd2; - struct account *account; - struct sip_client_config config; - const char *interface = "eth0"; - int ret; - int i; - - if (argc > 1) - interface = argv[1]; - - pj_init(); - pjlib_util_init(); - - contacts_init(); - - account = get_account(); - if (!account) { - printf("No account\n"); - return 1; - } - - ret = tapi_device_open(0, &dev); - if (ret) { - printf("Failed to open tapi device: %d\n", ret); - return 1; - } - - ports = calloc(dev.num_ports, sizeof(*ports)); - for (i = 0; i < dev.num_ports; ++i) - tapi_agent_init(&dev, i, &ports[i]); - - dd = dialdetector_alloc(&ports[0].port); - dd->dial_callback = dial_callback; - dd2 = dialdetector_alloc(&ports[1].port); - dd2->dial_callback = dial_callback; - - config.iface = interface; - config.host = account->realm; - config.port = account->sip_port; - config.username = account->username; - config.password = account->password; - - config.stun_host = account->stun_host; - config.stun_port = account->stun_port; - - sip_client_init(&sip_client, &dev, &config); - - sip_client.incoming_call_cb = incoming_sip_call; - - tapi_mainloop(); - - return 0; -} |