- if (gsm) {
- /* shutdown network */
- if (gsm->network)
- bsc_shutdown_net((struct gsm_network *)gsm->network);
- /* free network */
-// if (gsm->network) {
-// free((struct gsm_network *)gsm->network); /* TBD */
-// }
- }
-#endif
- return(rc);
-}
-
-extern "C" {
-
-static int mncc_q_enqueue(struct gsm_mncc *mncc, unsigned int len)
-{
- struct mncc_q_entry *qe;
-
- qe = (struct mncc_q_entry *) MALLOC(sizeof(*qe)+sizeof(*mncc)+len);
- if (!qe)
- return -ENOMEM;
-
- qe->next = NULL;
- qe->len = len;
- memcpy(qe->data, mncc, len);
-
- /* in case of empty list ... */
- if (!gsm->mncc_q_hd && !gsm->mncc_q_tail) {
- /* the list head and tail both point to the new qe */
- gsm->mncc_q_hd = gsm->mncc_q_tail = qe;
- } else {
- /* append to tail of list */
- gsm->mncc_q_tail->next = qe;
- gsm->mncc_q_tail = qe;
- }
-
- gsm->mncc_lfd.when |= LCR_FD_WRITE;
-
- return 0;
-}
-
-static struct mncc_q_entry *mncc_q_dequeue(void)
-{
- struct mncc_q_entry *qe = gsm->mncc_q_hd;
- if (!qe)
- return NULL;
-
- /* dequeue the successfully sent message */
- gsm->mncc_q_hd = qe->next;
- if (!qe)
- return NULL;
- if (qe == gsm->mncc_q_tail)
- gsm->mncc_q_tail = NULL;
-
- return qe;
-}
-
-/* routine called by LCR code if it wants to send a message to OpenBSC */
-int mncc_send(struct gsm_network *instance, int msg_type, void *data)
-{
- int len = 0;
-
- /* FIXME: the caller should provide this */
- switch (msg_type) {
- case GSM_TCHF_FRAME:
- len = sizeof(struct gsm_data_frame) + 33;
- break;
- default:
- len = sizeof(struct gsm_mncc);
- break;
- }
-
- return mncc_q_enqueue((struct gsm_mncc *)data, len);
-}
-
-} // extern "C"
-
-/* close MNCC socket */
-static int mncc_fd_close(struct lcr_fd *lfd)
-{
- class Port *port;
- class Pgsm_bs *pgsm_bs = NULL;
- struct lcr_msg *message;
-
- PERROR("Lost MNCC socket, retrying in %u seconds\n", SOCKET_RETRY_TIMER);
- close(lfd->fd);
- unregister_fd(lfd);
- lfd->fd = -1;
-
- /* free all the calls that were running through the MNCC interface */
- port = port_first;
- while(port) {
- if ((port->p_type & PORT_CLASS_GSM_MASK) == PORT_CLASS_GSM_BS) {
- pgsm_bs = (class Pgsm_bs *)port;
- message = message_create(pgsm_bs->p_serial, ACTIVE_EPOINT(pgsm_bs->p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
- message->param.disconnectinfo.cause = 27; // temp. unavail.
- message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
- message_put(message);
- pgsm_bs->new_state(PORT_STATE_RELEASE);
- trigger_work(&pgsm_bs->p_m_g_delete);
- }
- port = port->next;
- }
-
- /* flush the queue */
- while (mncc_q_dequeue())
- ;
-
- /* start the re-connect timer */
- schedule_timer(&gsm->socket_retry, SOCKET_RETRY_TIMER, 0);
-
- generate_dtmf();
-
- return 0;
-}
-
-/* read from OpenBSC via MNCC socket */
-static int mncc_fd_write(struct lcr_fd *lfd, void *inst, int idx)
-{
- struct mncc_q_entry *qe, *qe2;
- int rc;
-
- while (1) {
- qe = gsm->mncc_q_hd;
- if (!qe) {
- lfd->when &= ~LCR_FD_WRITE;
- break;