initial demo program working with libcapi20 + capiconn
doesn't do anything but accept incoming calls and log debug output
This commit is contained in:
parent
8bfbcf6d86
commit
1751d4b827
|
@ -0,0 +1,2 @@
|
|||
*.o
|
||||
capi-test
|
|
@ -0,0 +1,18 @@
|
|||
LIBS = -lasan
|
||||
CFLAGS = -g -Wall
|
||||
|
||||
LIBS += $(shell pkg-config --libs talloc libosmocore capi20)
|
||||
CFLAGS += $(shell pkg-config --cflags talloc libosmocore capi20)
|
||||
|
||||
all: capi-test
|
||||
|
||||
clean:
|
||||
@rm -f *.o capi-test
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -o $@ -c $^
|
||||
|
||||
capi-test: capi.o capiconn.o
|
||||
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
|
|
@ -0,0 +1,261 @@
|
|||
#include <malloc.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <talloc.h>
|
||||
|
||||
#include <osmocom/core/utils.h>
|
||||
#include <osmocom/core/select.h>
|
||||
#include <osmocom/core/logging.h>
|
||||
#include <osmocom/core/application.h>
|
||||
|
||||
#include <capi_debug.h>
|
||||
|
||||
#include "capiconn.h"
|
||||
|
||||
#define CM(x) (1<<(x))
|
||||
#define CIPMASK_ALL 0x1FFF03FF
|
||||
#define CIPMASK_VOICE (CM(1)|CM(4)|CM(5)|CM(16)|CM(26))
|
||||
#define CIPMASK_DATA (CM(2)|CM(3))
|
||||
|
||||
|
||||
enum log_subsys {
|
||||
DLCAPI20,
|
||||
DCAPI,
|
||||
};
|
||||
|
||||
static void *tall_capi_ctx;
|
||||
|
||||
struct capi_inst {
|
||||
unsigned int applid;
|
||||
capiconn_context *cc_ctx;
|
||||
struct osmo_fd ofd;
|
||||
};
|
||||
|
||||
static const char *conninfo(capi_connection *p)
|
||||
{
|
||||
static char buf[1024];
|
||||
capi_conninfo *cp = capiconn_getinfo(p);
|
||||
char *callingnumber = "";
|
||||
char *callednumber = "";
|
||||
|
||||
if (cp->callingnumber && cp->callingnumber[0] > 2)
|
||||
callingnumber = (char *) cp->callingnumber+3;
|
||||
if (cp->callednumber && cp->callednumber[0] > 1)
|
||||
callednumber = (char *) cp->callednumber+2;
|
||||
|
||||
snprintf(buf, sizeof(buf),
|
||||
"\"%s\" -> \"%s\" %s (pcli=0x%x/ncci=0x%x)",
|
||||
callingnumber, callednumber,
|
||||
cp->isincoming ? "incoming" : "outgoing",
|
||||
cp->plci, cp->ncci
|
||||
);
|
||||
buf[sizeof(buf)-1] = 0;
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* capiconn call-backs
|
||||
***********************************************************************/
|
||||
|
||||
static void *cb_malloc(size_t size)
|
||||
{
|
||||
return talloc_size(tall_capi_ctx, size);
|
||||
}
|
||||
|
||||
static void cb_free(void *buf)
|
||||
{
|
||||
talloc_free(buf);
|
||||
}
|
||||
|
||||
static void cb_disconnected(capi_connection *cp, int localdisconnect, unsigned reason, unsigned reason_b3)
|
||||
{
|
||||
LOGP(DCAPI, LOGL_DEBUG, "%s(local=%d, reason=0x%4x, reason_b3=0x%x)\n", __func__, localdisconnect, reason, reason_b3);
|
||||
}
|
||||
|
||||
static void cb_incoming(capi_connection *cp, unsigned contr, unsigned cipvalue, char *called, char *calling)
|
||||
{
|
||||
printf("incoming call: %s (0x%x) %s -> %s\n", conninfo(cp), cipvalue, calling, called);
|
||||
/* we should call capiconn_{accept,ignore,reject} */
|
||||
if (1) {
|
||||
capiconn_accept(cp, 1, 1, 0, 0, 0, 0, 0);
|
||||
} else
|
||||
capiconn_ignore(cp);
|
||||
}
|
||||
|
||||
static void cb_connected(capi_connection *cp, _cstruct NCPI)
|
||||
{
|
||||
printf("connected: %s\n", conninfo(cp));
|
||||
}
|
||||
|
||||
/* user plane data received */
|
||||
static void cb_datareceived(capi_connection *cp, unsigned char *data, unsigned int len)
|
||||
{
|
||||
LOGP(DCAPI, LOGL_DEBUG, "%s(%p, %u)\n", __func__, data, len);
|
||||
}
|
||||
|
||||
/* sent user plane data was confirmed */
|
||||
static void cb_datasent(capi_connection *cp, unsigned char *data)
|
||||
{
|
||||
LOGP(DCAPI, LOGL_DEBUG, "%s(%p)\n", __func__, data);
|
||||
}
|
||||
|
||||
|
||||
/* capiconn wants to issue a CAPI_PUT_MESSAGE */
|
||||
static void cb_put_message(unsigned int appid, unsigned char *msg)
|
||||
{
|
||||
int rc;
|
||||
//LOGP(DCAPI, LOGL_DEBUG, "%s(%u)\n", __func__, appid);
|
||||
rc = capi20_put_message(appid, msg);
|
||||
if (rc)
|
||||
fprintf(stderr, "capi20_put_message: %s\n", capi_info2str(rc));
|
||||
}
|
||||
|
||||
static void cb_debugmsg(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
osmo_vlogp(DCAPI, LOGL_DEBUG, __FILE__, __LINE__, 0, fmt, ap);
|
||||
va_end(ap);
|
||||
LOGPC(DCAPI, LOGL_DEBUG, "\n");
|
||||
}
|
||||
|
||||
static void cb_infomsg(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
osmo_vlogp(DCAPI, LOGL_INFO, __FILE__, __LINE__, 0, fmt, ap);
|
||||
va_end(ap);
|
||||
LOGPC(DCAPI, LOGL_INFO, "\n");
|
||||
}
|
||||
|
||||
static void cb_errmsg(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
osmo_vlogp(DCAPI, LOGL_ERROR, __FILE__, __LINE__, 0, fmt, ap);
|
||||
va_end(ap);
|
||||
LOGPC(DCAPI, LOGL_ERROR, "\n");
|
||||
}
|
||||
|
||||
capiconn_callbacks callbacks = {
|
||||
.malloc = cb_malloc,
|
||||
.free = cb_free,
|
||||
|
||||
.disconnected = cb_disconnected,
|
||||
.incoming = cb_incoming,
|
||||
.connected = cb_connected,
|
||||
.received = cb_datareceived,
|
||||
.datasent = cb_datasent,
|
||||
.chargeinfo = NULL,
|
||||
|
||||
.capi_put_message = cb_put_message,
|
||||
|
||||
.debugmsg = cb_debugmsg,
|
||||
.infomsg = cb_infomsg,
|
||||
.errmsg = cb_errmsg,
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* initialization / integration
|
||||
***********************************************************************/
|
||||
|
||||
/* debug print callback for capi20 to log via libosmocore logging framework */
|
||||
static int cb_capi_dprintf(const char *file, int line, const char *func, const char *fmt, va_list va)
|
||||
{
|
||||
osmo_vlogp(DLCAPI20, LOGL_DEBUG, file, line, 0, fmt, va);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* osmocom select file descriptor call-back for capi20 file descriptor */
|
||||
static int capifd_cb(struct osmo_fd *ofd, unsigned int what)
|
||||
{
|
||||
struct capi_inst *ci = ofd->data;
|
||||
int rc;
|
||||
|
||||
if (what & OSMO_FD_READ) {
|
||||
unsigned char *msg = NULL;
|
||||
rc = capi20_get_message(ci->applid, &msg);
|
||||
if (rc == 0) {
|
||||
const char *str = capi20_cmd2str(CAPIMSG_COMMAND(msg), CAPIMSG_SUBCOMMAND(msg));
|
||||
LOGP(DCAPI, LOGL_DEBUG, "Rx from CAPI: %s\n", str);
|
||||
capiconn_inject(ci->applid, msg);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct capi_inst *capi_init(void *ctx)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* libcapi20 debug log print callback */
|
||||
register_dbg_vprintf(cb_capi_dprintf);
|
||||
|
||||
struct capi_inst *ci = talloc_zero(ctx, struct capi_inst);
|
||||
if (!ci)
|
||||
return NULL;
|
||||
|
||||
rc = capi20_register(1, 8, 128, &ci->applid);
|
||||
if (rc != 0) {
|
||||
fprintf(stderr, "Error in capi_register: %s\n", capi_info2str(rc));
|
||||
talloc_free(ci);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ci->cc_ctx = capiconn_getcontext(ci->applid, &callbacks);
|
||||
if (!ci->cc_ctx) {
|
||||
fprintf(stderr, "get_coontext\n");
|
||||
capi20_release(ci->applid);
|
||||
talloc_free(ci);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
struct capi_contrinfo cinfo = {0, 0, 0};
|
||||
capiconn_addcontr(ci->cc_ctx, 1, &cinfo);
|
||||
rc = capiconn_listen(ci->cc_ctx, 1, CIPMASK_ALL, 0);
|
||||
if (rc) {
|
||||
fprintf(stderr, "Error in capiconn_listen: %s\n", capi_info2str(rc));
|
||||
capi20_release(ci->applid);
|
||||
talloc_free(ci);
|
||||
exit(1);
|
||||
}
|
||||
osmo_fd_setup(&ci->ofd, capi20_fileno(ci->applid), OSMO_FD_READ, capifd_cb, ci, 0);
|
||||
osmo_fd_register(&ci->ofd);
|
||||
|
||||
return ci;
|
||||
}
|
||||
|
||||
static const struct log_info_cat log_info_cat[] = {
|
||||
[DCAPI] = {
|
||||
.name = "DCAPI",
|
||||
.description = "ISDN CAPI Interface",
|
||||
.enabled = 1,
|
||||
.loglevel = LOGL_DEBUG,
|
||||
},
|
||||
[DLCAPI20] = {
|
||||
.name = "DLCAPI02",
|
||||
.description = "ISDN libcapi20",
|
||||
.enabled = 1,
|
||||
.loglevel = LOGL_DEBUG,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct log_info log_info = {
|
||||
.cat = log_info_cat,
|
||||
.num_cat = ARRAY_SIZE(log_info_cat),
|
||||
};
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
void *ctx = talloc_named_const(NULL, 1, "capi-test");
|
||||
|
||||
osmo_init_logging2(ctx, &log_info);
|
||||
capi_init(ctx);
|
||||
|
||||
while (1) {
|
||||
osmo_select_main(0);
|
||||
}
|
||||
}
|
|
@ -27,7 +27,6 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "isdntun.h"
|
||||
#include "capiconn.h"
|
||||
|
||||
/* xxxxxxxxxxxxxxxxxx */
|
||||
|
|
Loading…
Reference in New Issue