libosmo-tcap/src/tcap_test.c

189 lines
4.6 KiB
C

/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
* (C) 2010 by On-Waves
*
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <netinet/in.h>
#include <arpa/inet.h>
//#include <asn1/OBJECT_IDENTIFIER.h>
#include <osmocore/utils.h>
#include <osmocore/talloc.h>
#include "tcap_user.h"
static struct {
struct tcap_transport_entity *tte;
unsigned int begin_rcvd:1;
uint32_t dialg_id;
} test_state;
static int send_continue(uint32_t dialg_id, void *app_ctx, void *user_info)
{
struct tcap_dialg_ind tcdi;
memset(&tcdi, 0, sizeof(tcdi));
tcdi.dialg_id = dialg_id;
tcdi.app_ctx_name = app_ctx;
tcdi.user_info = user_info;
return tcap_user_req_dialg(TCAP_PR_TC_CONTINUE, &tcdi);
}
static void tcap_gen_oper_local(struct OPERATION *op, uint32_t local_value)
{
op->present = OPERATION_PR_localValue;
asn_long2INTEGER(&op->choice.localValue, local_value);
}
/* UpdateGprsLocationArg */
static const int gprsLocationUpdateContext_v3[] = { 0, 4, 0, 0, 1, 0, 32, 3 };
static OBJECT_IDENTIFIER_t gprs_loc_upd_ctx_v3_oid;
static uint8_t gprs_loc_upd_param[] = {
0x30, 0x1d, 0x04, 0x0f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x31, 0x32,
0x33, 0x34, 0x35, 0x04, 0x01, 0x31, 0x04, 0x07, 0x31, 0x2e, 0x32, 0x2e, 0x33, 0x2e, 0x34
};
static int send_invoke(uint32_t dialg_id, int8_t invoke_id, uint8_t *param, uint32_t param_len)
{
struct tcap_component_ind tcci;
memset(&tcci, 0, sizeof(tcci));
tcci.dialg_id = dialg_id;
tcci.invoke_id = invoke_id;
tcci.linked_id = NULL;
tcap_gen_oper_local(&tcci.operation, 1);
tcci.timeout_secs = 10;
tcci.op_class = 1;
tcci.parameter.buf = param;
tcci.parameter.size = param_len;
return tcap_user_req_comp(TCAP_PR_TC_INVOKE, &tcci);
}
static int send_begin(uint32_t dialg_id, OBJECT_IDENTIFIER_t *app_ctx)
{
struct tcap_dialg_ind tcdi;
memset(&tcdi, 0, sizeof(tcdi));
tcdi.dialg_id = dialg_id;
tcdi.app_ctx_name = app_ctx;
tcdi.transp_ent = test_state.tte;
return tcap_user_req_dialg(TCAP_PR_TC_BEGIN, &tcdi);
}
int tcap_user_ind_dialg(enum tcap_primitive prim, struct tcap_dialg_ind *tcdi)
{
printf("-> USER_IND_DIALG(%s): ", tcap_prim_name(prim));
switch (prim) {
case TCAP_PR_TC_BEGIN:
test_state.begin_rcvd = 1;
test_state.dialg_id = tcdi->dialg_id;
printf("dialg_id=0x%08x ", tcdi->dialg_id);
break;
default:
break;
}
printf("\n");
return 0;
}
int tcap_user_ind_comp(enum tcap_primitive prim, struct tcap_component_ind *tcci)
{
printf("-> USER_IND_COMP(%s)\n", tcap_prim_name(prim));
if (!test_state.begin_rcvd)
return -1;
switch (prim) {
case TCAP_PR_TC_INVOKE:
/* actually process the invoke */
send_invoke(test_state.dialg_id, 0, NULL, 0);
if (tcci->last_component)
send_continue(test_state.dialg_id, &gprs_loc_upd_ctx_v3_oid, NULL);
break;
default:
break;
}
return 0;
}
static void initialize(void)
{
OBJECT_IDENTIFIER_set_arcs(&gprs_loc_upd_ctx_v3_oid, &gprsLocationUpdateContext_v3,
sizeof(gprsLocationUpdateContext_v3[0]),
ARRAY_SIZE(gprsLocationUpdateContext_v3));
}
static void signal_handler(int signal)
{
switch (signal) {
case SIGINT:
talloc_report_full(NULL, stderr);
exit(0);
break;
default:
break;
}
}
int main(int argc, char **argv)
{
struct sockaddr_storage ss;
struct sockaddr_in *sin = (struct sockaddr_in *)&ss;
talloc_enable_leak_report_full();
signal(SIGINT, &signal_handler);
initialize();
ss.ss_family = AF_INET;
sin->sin_addr.s_addr = INADDR_ANY;
sin->sin_port = htons(4242);
test_state.tte = tcap_transp_udp_create(&ss);
if (!test_state.tte) {
fprintf(stderr, "Cannot create UDP socket\n");
exit(1);
}
/* make sure we sent messages to ourselves */
inet_aton("127.0.0.1", &sin->sin_addr);
memcpy(&test_state.tte->remote_addr, &ss, sizeof(test_state.tte->remote_addr));
send_invoke(0x1234, 0, gprs_loc_upd_param, sizeof(gprs_loc_upd_param));
send_invoke(0x1234, 1, NULL, 0);
send_invoke(0x1234, -1, NULL, 0);
send_begin(0x1234, &gprs_loc_upd_ctx_v3_oid);
while (1) {
bsc_select_main(0);
}
}