unsigned char data[160];
int i, cmr;
- if (!p_g_fr_decoder)
- return;
-
switch (frame->msg_type) {
case GSM_TCHF_FRAME:
if (p_g_media_type != MEDIA_TYPE_GSM) {
/* send traffic to gsm */
int Pgsm::bridge_rx(unsigned char *data, int len)
{
+ int ret;
+
+ if ((ret = Port::bridge_rx(data, len)))
+ return ret;
+
if (p_tone_name[0])
return -EINVAL;
if (p_tap)
tap(data, len, 1); // from up
- /* encoder init failed */
- if (!p_g_fr_encoder)
- return -EINVAL;
-
/* (currently) not connected, so don't flood tch! */
if (!p_g_tch_connected)
return -EINVAL;
case MEDIA_TYPE_GSM_EFR:
add_trace("speech", "version", "EFR given");
mode->lchan_mode = 0x21; /* GSM V2 */
+ mode->lchan_type = 0x02; /* TCH/F */
break;
case MEDIA_TYPE_AMR:
add_trace("speech", "version", "AMR given");
mode->lchan_mode = 0x41; /* GSM V3 */
+ /* as we don't know the available channels, this type will be set by openbsc automatically */
+ mode->lchan_type = 0x02; /* TCH/F */
break;
+ case MEDIA_TYPE_GSM_HR:
+ add_trace("speech", "version", "Half Rate given");
+ mode->lchan_mode = 0x01; /* GSM V1 */
+ mode->lchan_type = 0x03; /* TCH/H */
default:
- add_trace("speech", "version", "Full/Half Rate given");
+ add_trace("speech", "version", "Full Rate given");
mode->lchan_mode = 0x01; /* GSM V1 */
+ mode->lchan_type = 0x02; /* TCH/F */
}
- mode->lchan_type = 0x02; /* FIXME: unused */
add_trace("mode", NULL, "0x%02x", mode->lchan_mode);
end_trace();
send_and_free_mncc(p_g_lcr_gsm, mode->msg_type, mode);
// printf("if = %d\n", param->notifyinfo.notify);
if (param->notifyinfo.notify>INFO_NOTIFY_NONE) {
notify = param->notifyinfo.notify & 0x7f;
+ /* skip all notifiy ids that are not 0, 1, 2 */
+ if (notify > 2)
+ return;
if (p_state!=PORT_STATE_CONNECT /*&& p_state!=PORT_STATE_IN_PROCEEDING*/ && p_state!=PORT_STATE_IN_ALERTING) {
/* queue notification */
if (p_g_notify_pending)
add_trace("cause", "coding", "%d", mncc->cause.coding);
add_trace("cause", "location", "%d", mncc->cause.location);
add_trace("cause", "value", "%d", mncc->cause.value);
+#ifdef WITH_GSM_MS
+ /* special case for BS mode */
+ if (param->disconnectinfo.transfer.result && (p_type & PORT_CLASS_GSM_MASK) == PORT_CLASS_GSM_BS) {
+ ((class Pgsm_bs *)this)->enc_ie_facility_ect(mncc, ¶m->disconnectinfo.transfer);
+ gsm_trace_facility((unsigned char *)mncc->facility.info, mncc->facility.len);
+ }
+#endif
end_trace();
send_and_free_mncc(p_g_lcr_gsm, mncc->msg_type, mncc);
/* free all the calls that were running through the MNCC interface */
port = port_first;
while(port) {
- if ((port->p_type & PORT_CLASS_mISDN_MASK) == PORT_CLASS_GSM) {
+ if ((port->p_type & PORT_CLASS_MASK) == PORT_CLASS_GSM) {
pgsm = (class Pgsm *)port;
if (pgsm->p_g_lcr_gsm == lcr_gsm) {
message = message_create(pgsm->p_serial, ACTIVE_EPOINT(pgsm->p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
int rc;
static char buf[sizeof(struct gsm_mncc)+1024];
struct gsm_mncc *mncc_prim = (struct gsm_mncc *) buf;
+ struct gsm_mncc_hello *hello = (struct gsm_mncc_hello *) buf;
memset(buf, 0, sizeof(buf));
rc = recv(lfd->fd, buf, sizeof(buf), 0);
if (rc < 0)
return rc;
+ /* TODO: size check? */
+ switch (mncc_prim->msg_type) {
+ case MNCC_SOCKET_HELLO:
+ if (hello->version != MNCC_SOCK_VERSION) {
+ PERROR("MNCC version different. BSC version is %u\n", hello->version);
+ mncc_fd_close(lcr_gsm, lfd);
+ return 0;
+ }
+ if (hello->mncc_size != sizeof(struct gsm_mncc)) {
+ PERROR("MNCC gsm_mncc size differs: %u %u\n",
+ hello->mncc_size, sizeof(struct gsm_mncc));
+ mncc_fd_close(lcr_gsm, lfd);
+ return 0;
+ }
+ if (hello->data_frame_size != sizeof(struct gsm_data_frame)) {
+ PERROR("MNCC gsm_mncc size differs: %u %u\n",
+ hello->data_frame_size, sizeof(struct gsm_data_frame));
+ mncc_fd_close(lcr_gsm, lfd);
+ return 0;
+ }
+
+#define CHECK_OFFSET(hello, field, lcr_gsm, lfd) \
+ if (hello->field ##_offset != __builtin_offsetof(struct gsm_mncc, field)) { \
+ PERROR("MNCC gsm_mncc offset of %s is %u %u\n", \
+ #field, hello->field ##_offset, \
+ __builtin_offsetof(struct gsm_mncc, field)); \
+ mncc_fd_close(lcr_gsm, lfd); \
+ return 0; \
+ }
+
+ CHECK_OFFSET(hello, called, lcr_gsm, lfd);
+ CHECK_OFFSET(hello, signal, lcr_gsm, lfd);
+ CHECK_OFFSET(hello, emergency, lcr_gsm, lfd);
+ CHECK_OFFSET(hello, lchan_type, lcr_gsm, lfd);
+#undef CHECK_OFFSET
+
+ break;
+ }
+
/* Hand the MNCC message into LCR */
switch (lcr_gsm->type) {
#ifdef WITH_GSM_BS