int main(int argc, char **argv) { struct ss_request req; const int size = sizeof(ussd_request); int i; struct msgb *msg; osmo_init_logging(&info); memset(&req, 0, sizeof(req)); gsm0480_decode_ss_request((struct gsm48_hdr *) ussd_request, size, &req); printf("Tested if it still works. Text was: %s\n", req.ussd_text); memset(&req, 0, sizeof(req)); gsm0480_decode_ss_request((struct gsm48_hdr *) interrogate_ss, size, &req); OSMO_ASSERT(strlen((char *) req.ussd_text) == 0); OSMO_ASSERT(req.ss_code == 33); printf("interrogateSS CFU text..'%s' code %d\n", req.ussd_text, req.ss_code); printf("Testing parsing a USSD request and truncated versions\n"); for (i = size; i > sizeof(struct gsm48_hdr); --i) { int rc = parse_ussd(&ussd_request[0], i); printf("Result for %d is %d\n", rc, i); } printf("Mangling the container now\n"); for (i = size; i > sizeof(struct gsm48_hdr) + 2; --i) { int rc = parse_mangle_ussd(&ussd_request[0], i); printf("Result for %d is %d\n", rc, i); } printf("<CR> case test for 7 bit encode\n"); test_7bit_ussd("01234567", "b0986c46abd96e", ""); test_7bit_ussd("0123456", "b0986c46abd91a", ""); test_7bit_ussd("01234567\r", "b0986c46abd96e0d", ""); /* The appended \r is compliant to GSM 03.38 section 6.1.2.3.1: */ test_7bit_ussd("0123456\r", "b0986c46abd91a0d", "\r"); test_7bit_ussd("012345\r", "b0986c46ab351a", ""); printf("Checking GSM 04.80 USSD message generation.\n"); test_7bit_ussd("", "", ""); msg = gsm0480_create_unstructuredSS_Notify (0x00, ""); printf ("Created unstructuredSS_Notify (0x00): %s\n", osmo_hexdump(msgb_data(msg), msgb_length(msg))); msgb_free (msg); test_7bit_ussd("forty-two", "e6b79c9e6fd1ef6f", ""); msg = gsm0480_create_unstructuredSS_Notify (0x42, "forty-two"); printf ("Created unstructuredSS_Notify (0x42): %s\n", osmo_hexdump(msgb_data(msg), msgb_length(msg))); msgb_free (msg); return 0; }
int l1ctl_sock_write_msg(struct l1ctl_sock_client *lsc, struct msgb *msg) { int rc; rc = write(lsc->ofd.fd, msgb_data(msg), msgb_length(msg)); msgb_free(msg); return rc; }
static int smpp_handle_deliver(struct esme *esme, struct msgb *msg) { struct deliver_sm_t deliver; struct deliver_sm_resp_t deliver_r; struct submit_sm_t submit; int rc; memset(&deliver, 0, sizeof(deliver)); SMPP34_UNPACK(rc, DELIVER_SM, &deliver, msgb_data(msg), msgb_length(msg)); if (rc < 0) return rc; INIT_RESP(DELIVER_SM_RESP, &deliver_r, &deliver); PACK_AND_SEND(esme, &deliver_r); memset(&submit, 0, sizeof(submit)); submit.command_id = SUBMIT_SM; submit.command_status = ESME_ROK; submit.sequence_number = esme_inc_seq_nr(esme); submit.dest_addr_ton = deliver.source_addr_ton; submit.dest_addr_npi = deliver.source_addr_npi; memcpy(submit.destination_addr, deliver.source_addr, OSMO_MIN(sizeof(submit.destination_addr), sizeof(deliver.source_addr))); submit.source_addr_ton = deliver.dest_addr_ton; submit.source_addr_npi = deliver.dest_addr_npi; memcpy(submit.source_addr, deliver.destination_addr, OSMO_MIN(sizeof(submit.source_addr), sizeof(deliver.destination_addr))); submit.esm_class = deliver.esm_class; submit.protocol_id = deliver.protocol_id; submit.priority_flag = deliver.priority_flag; memcpy(submit.schedule_delivery_time, deliver.schedule_delivery_time, OSMO_MIN(sizeof(submit.schedule_delivery_time), sizeof(deliver.schedule_delivery_time))); memcpy(submit.validity_period, deliver.validity_period, OSMO_MIN(sizeof(submit.validity_period), sizeof(deliver.validity_period))); submit.registered_delivery = deliver.registered_delivery; submit.replace_if_present_flag = deliver.replace_if_present_flag; submit.data_coding = deliver.data_coding; submit.sm_default_msg_id = deliver.sm_default_msg_id; submit.sm_length = deliver.sm_length; memcpy(submit.short_message, deliver.short_message, OSMO_MIN(sizeof(submit.short_message), sizeof(deliver.short_message))); /* FIXME: TLV? */ return PACK_AND_SEND(esme, &submit); }
static struct xua_msg *m3ua_gen_error_msg(uint32_t err_code, struct msgb *msg) { struct xua_msg *xua = m3ua_gen_error(err_code); unsigned int len_max_40 = msgb_length(msg); if (len_max_40 > 40) len_max_40 = 40; xua_msg_add_data(xua, M3UA_IEI_DIAG_INFO, len_max_40, msgb_data(msg)); return xua; }
int main(void) { struct tcp_client *c; struct tcp_conf conf = { .ipproto = AF_INET, .port = 1234, .client = { .inet_addr = { inet_addr("127.0.0.1") }, }, }; struct nft_sync_hdr *hdr; struct msg_buff *msgb; char buf[1024]; fd_set fds; msgb = msgb_alloc(NFTS_MAX_REQUEST); if (msgb == NULL) { perror("msgb_alloc"); exit(EXIT_FAILURE); } hdr = msgb_put(msgb, sizeof(struct nft_sync_hdr) + strlen("fetch")); hdr->len = htonl(sizeof(struct nft_sync_hdr) + strlen("fetch")); memcpy(hdr->data, "fetch", strlen("fetch")); c = tcp_client_create(&conf); if (c == NULL) { fprintf(stderr, "cannot initialize TCP client\n"); exit(EXIT_FAILURE); } FD_ZERO(&fds); FD_SET(tcp_client_get_fd(c), &fds); /* Wait for connection ... */ select(tcp_client_get_fd(c) + 1, NULL, &fds, NULL, NULL); if (tcp_client_send(c, msgb_data(msgb), msgb_len(msgb)) < 0) { perror("cannot send to socket"); exit(EXIT_FAILURE); } FD_ZERO(&fds); FD_SET(tcp_client_get_fd(c), &fds); /* Wait to receive data after sending request ... */ select(tcp_client_get_fd(c) + 1, &fds, NULL, NULL, NULL); if (tcp_client_recv(c, buf, sizeof(buf)) < 0) { perror("cannot send to socket"); exit(EXIT_FAILURE); } printf("[TEST OK] Received: %s\n", buf + sizeof(struct nft_sync_hdr)); tcp_client_destroy(c); }
/** * @brief L1CTL socket file descriptor callback function. * * @param ofd The osmocom file descriptor. * @param what Indicates if the fd has a read, write or exception request. See select.h. * * Will be called by osmo_select_main() if data on fd is pending. */ static int l1ctl_sock_data_cb(struct osmo_fd *ofd, unsigned int what) { struct l1ctl_sock_client *lsc = ofd->data; struct l1ctl_hdr *l1h; struct msgb *msg; uint16_t len; int rc; /* Check if request is really read request */ if (!(what & BSC_FD_READ)) return 0; msg = msgb_alloc(L1CTL_SOCK_MSGB_SIZE, "L1CTL sock rx"); /* read length of the message first and convert to host byte order */ rc = read(ofd->fd, &len, sizeof(len)); if (rc < sizeof(len)) goto err_close; /* convert to host byte order */ len = ntohs(len); if (len <= 0 || len > L1CTL_SOCK_MSGB_SIZE) goto err_close; rc = read(ofd->fd, msgb_data(msg), len); if (rc == len) { msgb_put(msg, rc); l1h = (void *) msgb_data(msg); msg->l1h = (void *) l1h; lsc->l1ctl_sock->recv_cb(lsc, msg); return 0; } err_close: LOGP(DL1C, LOGL_ERROR, "Failed to receive msg from l2. Connection will be closed.\n"); l1ctl_client_destroy(lsc); return 0; }
static void esme_write_cb(struct osmo_fd *ofd, struct msgb *msg) { struct esme *esme = ofd->data; int rc; rc = write(ofd->fd, msgb_data(msg), msgb_length(msg)); if (rc == 0) { osmo_fd_unregister(&esme->wqueue.bfd); close(esme->wqueue.bfd.fd); esme->wqueue.bfd.fd = -1; exit(99); } else if (rc < msgb_length(msg)) { LOGP(DSMPP, LOGL_ERROR, "[%s] Short write\n", esme->system_id); return; } }
static int pcu_sock_write(struct osmo_fd *bfd) { struct pcu_sock_state *state = (struct pcu_sock_state *)bfd->data; int rc; while (!llist_empty(&state->upqueue)) { struct msgb *msg, *msg2; struct gsm_pcu_if *pcu_prim; /* peek at the beginning of the queue */ msg = llist_entry(state->upqueue.next, struct msgb, list); pcu_prim = (struct gsm_pcu_if *)msg->data; bfd->when &= ~BSC_FD_WRITE; /* bug hunter 8-): maybe someone forgot msgb_put(...) ? */ if (!msgb_length(msg)) { LOGP(DL1IF, LOGL_ERROR, "message type (%d) with ZERO " "bytes!\n", pcu_prim->msg_type); goto dontsend; } /* try to send it over the socket */ rc = write(bfd->fd, msgb_data(msg), msgb_length(msg)); if (rc == 0) goto close; if (rc < 0) { if (errno == EAGAIN) { bfd->when |= BSC_FD_WRITE; break; } goto close; } dontsend: /* _after_ we send it, we can deueue */ msg2 = msgb_dequeue(&state->upqueue); assert(msg == msg2); msgb_free(msg); } return 0; close: pcu_sock_close(state, 1); return -1; }
/*! \brief process M3UA message received from socket * \param[in] asp Application Server Process receiving \ref msg * \param[in] msg received message buffer * \returns 0 on success; negative on error */ int m3ua_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg) { struct xua_msg *xua = NULL, *err = NULL; int rc = 0; OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA); /* caller owns msg memory, we shall neither free it here nor * keep references beyond the executin of this function and its * callees */ xua = xua_from_msg(M3UA_VERSION, msgb_length(msg), msgb_data(msg)); if (!xua) { struct xua_common_hdr *hdr = (struct xua_common_hdr *) msg->data; LOGPASP(asp, DLM3UA, LOGL_ERROR, "Unable to parse incoming " "M3UA message\n"); if (hdr->version != M3UA_VERSION) err = m3ua_gen_error_msg(M3UA_ERR_INVALID_VERSION, msg); else err = m3ua_gen_error_msg(M3UA_ERR_PARAM_FIELD_ERR, msg); goto out; } LOGPASP(asp, DLM3UA, LOGL_DEBUG, "Received M3UA Message (%s)\n", xua_hdr_dump(xua, &xua_dialect_m3ua)); if (!xua_dialect_check_all_mand_ies(&xua_dialect_m3ua, xua)) { err = m3ua_gen_error_msg(M3UA_ERR_MISSING_PARAM, msg); goto out; } /* TODO: check if any AS configured in ASP */ /* TODO: check for valid routing context */ switch (xua->hdr.msg_class) { case M3UA_MSGC_XFER: /* The DATA message MUST NOT be sent on stream 0. */ if (msgb_sctp_stream(msg) == 0) { rc = M3UA_ERR_INVAL_STREAM_ID; break; } rc = m3ua_rx_xfer(asp, xua); break; case M3UA_MSGC_ASPSM: case M3UA_MSGC_ASPTM: rc = m3ua_rx_asp(asp, xua); break; case M3UA_MSGC_MGMT: rc = m3ua_rx_mgmt(asp, xua); break; case M3UA_MSGC_RKM: rc = m3ua_rx_rkm(asp, xua); break; case M3UA_MSGC_SNM: /* FIXME */ LOGPASP(asp, DLM3UA, LOGL_NOTICE, "Received unsupported M3UA " "Message Class %u\n", xua->hdr.msg_class); err = m3ua_gen_error_msg(M3UA_ERR_UNSUPP_MSG_CLASS, msg); break; default: LOGPASP(asp, DLM3UA, LOGL_NOTICE, "Received unknown M3UA " "Message Class %u\n", xua->hdr.msg_class); err = m3ua_gen_error_msg(M3UA_ERR_UNSUPP_MSG_CLASS, msg); break; } if (rc > 0) err = m3ua_gen_error_msg(rc, msg); out: if (err) m3ua_tx_xua_asp(asp, err); xua_msg_free(xua); return rc; }
static void test_bssgp_flow_control_bvc(void) { struct bssgp_bvc_ctx bctx = { .nsei = 0x1234, .bvci = 0x5678, }; const uint8_t tag = 42; const uint32_t bmax = 0x1022 * 100; const uint32_t rate = 0xc040 / 8 * 100; const uint32_t bmax_ms = bmax / 2; const uint32_t rate_ms = rate / 2; uint8_t ratio = 0x78; uint32_t qdelay = 0x1144 * 10; int rc; static uint8_t expected_simple_msg[] = { 0x26, 0x1e, 0x81, 0x2a, /* tag */ 0x05, 0x82, 0x10, 0x22, /* Bmax */ 0x03, 0x82, 0xc0, 0x40, /* R */ 0x01, 0x82, 0x08, 0x11, /* Bmax_MS */ 0x1c, 0x82, 0x60, 0x20, /* R_MS */ }; static uint8_t expected_ext_msg[] = { 0x26, 0x1e, 0x81, 0x2a, /* tag */ 0x05, 0x82, 0x10, 0x22, /* Bmax */ 0x03, 0x82, 0xc0, 0x40, /* R */ 0x01, 0x82, 0x08, 0x11, /* Bmax_MS */ 0x1c, 0x82, 0x60, 0x20, /* R_MS */ 0x3c, 0x81, 0x78, /* ratio */ 0x06, 0x82, 0x11, 0x44, /* Qdelay */ }; printf("----- %s START\n", __func__); rc = bssgp_tx_fc_bvc(&bctx, tag, bmax, rate, bmax_ms, rate_ms, NULL, NULL); OSMO_ASSERT(rc >= 0); OSMO_ASSERT(last_ns_tx_msg != NULL); printf("Got message: %s\n", msgb_hexdump(last_ns_tx_msg)); OSMO_ASSERT(msgb_length(last_ns_tx_msg) == sizeof(expected_simple_msg)); OSMO_ASSERT(0 == memcmp(msgb_data(last_ns_tx_msg), expected_simple_msg, sizeof(expected_simple_msg))); rc = bssgp_tx_fc_bvc(&bctx, tag, bmax, rate, bmax_ms, rate_ms, &ratio, &qdelay); OSMO_ASSERT(rc >= 0); OSMO_ASSERT(last_ns_tx_msg != NULL); printf("Got message: %s\n", msgb_hexdump(last_ns_tx_msg)); OSMO_ASSERT(msgb_length(last_ns_tx_msg) == sizeof(expected_ext_msg)); OSMO_ASSERT(0 == memcmp(msgb_data(last_ns_tx_msg), expected_ext_msg, sizeof(expected_ext_msg))); msgb_free(last_ns_tx_msg); last_ns_tx_msg = NULL; printf("----- %s END\n", __func__); } static struct log_info info = {}; int main(int argc, char **argv) { struct sockaddr_in bss_peer= {0}; osmo_init_logging(&info); log_set_use_color(osmo_stderr_target, 0); log_set_print_filename(osmo_stderr_target, 0); bssgp_nsi = gprs_ns_instantiate(gprs_ns_callback, NULL); bss_peer.sin_family = AF_INET; bss_peer.sin_port = htons(32000); bss_peer.sin_addr.s_addr = htonl(0x7f0000ff); gprs_ns_nsip_connect(bssgp_nsi, &bss_peer, BSS_NSEI, BSS_NSEI+1); printf("===== BSSGP test START\n"); test_bssgp_suspend_resume(); test_bssgp_status(); test_bssgp_bad_reset(); test_bssgp_flow_control_bvc(); printf("===== BSSGP test END\n\n"); exit(EXIT_SUCCESS); }
static int feed_write_cb(struct osmo_fd *ofd, struct msgb *msg) { return write(ofd->fd, msgb_data(msg), msgb_length(msg)); }
static inline uint32_t smpp_msgb_cmdid(struct msgb *msg) { uint8_t *tmp = msgb_data(msg) + 4; return ntohl(*(uint32_t *)tmp); }