return;
switch (frame->msg_type) {
+ case ANALOG_8000HZ:
+ if (p_g_media_type != MEDIA_TYPE_ANALOG) {
+ PERROR("'Analog' frame, but current media type mismatches.\n");
+ return;
+ }
+ for (i = 0; i < 160; i++) {
+ data[i] = audio_s16_to_law[((int16_t *)frame->data)[i] & 0xffff];
+ }
+ break;
case GSM_TCHF_FRAME:
if (p_g_media_type != MEDIA_TYPE_GSM) {
PERROR("FR frame, but current media type mismatches.\n");
/* 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;
p_g_rxpos = 0;
switch (p_g_media_type) {
+ case MEDIA_TYPE_ANALOG:
+ frame_send(p_g_rxdata, 320, ANALOG_8000HZ);
+ break;
case MEDIA_TYPE_GSM:
if (!p_g_fr_encoder) {
PERROR("FR frame, but encoder not created.\n");
/* FIXME: the caller should provide this */
switch (msg_type) {
+ case ANALOG_8000HZ:
+ len = sizeof(struct gsm_data_frame) + 320;
+ break;
case GSM_TCHF_FRAME:
len = sizeof(struct gsm_data_frame) + 33;
break;
/* 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);
- message->param.disconnectinfo.cause = 27; // temp. unavail.
+ message->param.disconnectinfo.cause = 41; // temp. fail.
message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
message_put(message);
pgsm->new_state(PORT_STATE_RELEASE);
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;
}