static int gsm411_mnsms_est_ind(struct gsm411_smr_inst *inst, struct msgb *msg) { struct gsm48_hdr *gh = (struct gsm48_hdr*)msg->l3h; struct gsm411_rp_hdr *rp_data = (struct gsm411_rp_hdr*)&gh->data; uint8_t msg_type = rp_data->msg_type & 0x07; int rc; /* check direction */ if (inst->network == (msg_type & 1)) { LOGP(DLSMS, LOGL_NOTICE, SMR_LOG_STR "Invalid RP type 0x%02x\n", inst->id, msg_type); gsm411_send_rp_error(inst, rp_data->msg_ref, GSM411_RP_CAUSE_MSG_INCOMP_STATE); new_rp_state(inst, GSM411_RPS_IDLE); gsm411_send_release(inst); return -EINVAL; } switch (msg_type) { case GSM411_MT_RP_DATA_MT: case GSM411_MT_RP_DATA_MO: LOGP(DLSMS, LOGL_DEBUG, SMR_LOG_STR "RX SMS RP-DATA\n", inst->id); /* start TR2N and enter 'wait to send RP-ACK state' */ osmo_timer_schedule(&inst->rp_timer, GSM411_TMR_TR2M); new_rp_state(inst, GSM411_RPS_WAIT_TO_TX_RP_ACK); rc = inst->rl_recv(inst, GSM411_SM_RL_DATA_IND, msg); break; case GSM411_MT_RP_SMMA_MO: LOGP(DLSMS, LOGL_DEBUG, SMR_LOG_STR "RX SMS RP-SMMA\n", inst->id); /* start TR2N and enter 'wait to send RP-ACK state' */ osmo_timer_schedule(&inst->rp_timer, GSM411_TMR_TR2M); new_rp_state(inst, GSM411_RPS_WAIT_TO_TX_RP_ACK); rc = inst->rl_recv(inst, GSM411_SM_RL_DATA_IND, msg); break; default: LOGP(DLSMS, LOGL_NOTICE, SMR_LOG_STR "invalid RP type 0x%02x\n", inst->id, msg_type); gsm411_send_rp_error(inst, rp_data->msg_ref, GSM411_RP_CAUSE_MSGTYPE_NOTEXIST); new_rp_state(inst, GSM411_RPS_IDLE); rc = -EINVAL; break; } return rc; }
/** * Send a GSM08.08 Assignment Request. Right now this does not contain the * audio codec type or the allowed rates for the config. It is assumed that * this is for audio handling only. In case the current channel does not allow * the selected mode a new one will be allocated. * * TODO: Add multirate configuration, make it work for more than audio. */ int gsm0808_assign_req(struct gsm_subscriber_connection *conn, int chan_mode, int full_rate) { struct bsc_api *api; api = conn->bts->network->bsc_api; if (chan_compat_with_mode(conn->lchan, chan_mode, full_rate) != 0) { if (handle_new_assignment(conn, chan_mode, full_rate) != 0) goto error; } else { LOGP(DMSC, LOGL_NOTICE, "Sending ChanModify for speech %d %d\n", chan_mode, full_rate); if (chan_mode == GSM48_CMODE_SPEECH_AMR) handle_mr_config(conn, conn->lchan); gsm48_lchan_modify(conn->lchan, chan_mode); } /* we will now start the timer to complete the assignment */ conn->T10.cb = assignment_t10_timeout; conn->T10.data = conn; osmo_timer_schedule(&conn->T10, GSM0808_T10_VALUE); return 0; error: api->assign_fail(conn, 0, NULL); return -1; }
int main(int argc, char** argv) { printf("Starting... timer\n"); osmo_timer_schedule(&timer_one, 3, 0); osmo_timer_schedule(&timer_two, 5, 0); osmo_timer_schedule(&timer_three, 4, 0); #ifdef HAVE_SYS_SELECT_H while (1) { osmo_select_main(0); } #else printf("Select not supported on this platform!\n"); #endif }
static void start_timer(int sec, int micro) { stop_timer(); timer.cb = timeout_cb; timer.data = ms; osmo_timer_schedule(&timer, sec, micro); }
void bsc_msc_schedule_connect(struct bsc_msc_connection *con) { LOGP(DMSC, LOGL_NOTICE, "Attempting to reconnect to the MSC(%s)\n", con->name); con->reconnect_timer.cb = reconnect_msc; con->reconnect_timer.data = con; osmo_timer_schedule(&con->reconnect_timer, 5, 0); }
static void sgsn_gtp_tmr_start(struct sgsn_instance *sgi) { struct timeval next; /* Retrieve next retransmission as struct timeval */ gtp_retranstimeout(sgi->gsn, &next); /* re-schedule the timer */ osmo_timer_schedule(&sgi->gtp_timer, next.tv_sec, next.tv_usec/1000); }
static int gsm411_rl_data_req(struct gsm411_smr_inst *inst, struct msgb *msg) { LOGP(DLSMS, LOGL_DEBUG, SMR_LOG_STR "TX SMS RP-DATA\n", inst->id); /* start TR1N and enter 'wait for RP-ACK state' */ osmo_timer_schedule(&inst->rp_timer, GSM411_TMR_TR1M); new_rp_state(inst, GSM411_RPS_WAIT_FOR_RP_ACK); return inst->mn_send(inst, GSM411_MNSMS_EST_REQ, msg); }
static void swd_state_reset(struct oc2gbts_mgr_instance *mgr, int outcome) { if (mgr->swd.swd_from_loop) { mgr->swd.swd_timeout.data = mgr; mgr->swd.swd_timeout.cb = swd_loop_run; osmo_timer_schedule(&mgr->swd.swd_timeout, SWD_PERIOD, 0); } mgr->swd.state = SWD_INITIAL; swd_close(mgr); }
static void pcu_tx_txt_retry(void *_priv) { struct gprs_rlcmac_bts *bts = bts_main_data(); struct pcu_sock_state *state = pcu_sock_state; if (bts->active) return; LOGP(DL1IF, LOGL_INFO, "Sending version %s to BTS.\n", PACKAGE_VERSION); pcu_tx_txt_ind(PCU_VERSION, "%s", PACKAGE_VERSION); osmo_timer_schedule(&state->timer, 5, 0); }
static void mtk_timer_cb(void *p) { int rc; if (dnload.mtk_state == MTK_INIT_1) { printf("Sending MTK romloader beacon...\n"); rc = write(dnload.serial_fd.fd, &mtk_init_cmd[0], 1); if (!(rc == 1)) printf("Error sending identification beacon\n"); osmo_timer_schedule(p, 0, dnload.beacon_interval); } }
static void beacon_timer_cb(void *p) { int rc; if (dnload.romload_state == WAITING_IDENTIFICATION) { rc = write(dnload.serial_fd.fd, romload_ident_cmd, sizeof(romload_ident_cmd)); if (!(rc == sizeof(romload_ident_cmd))) printf("Error sending identification beacon\n"); osmo_timer_schedule(p, 0, dnload.beacon_interval); } }
static int __handle_ts1_write(struct osmo_fd *bfd, struct e1inp_line *line) { unsigned int ts_nr = bfd->priv_nr; struct e1inp_ts *e1i_ts = &line->ts[ts_nr-1]; struct e1inp_sign_link *sign_link; struct msgb *msg; int ret; bfd->when &= ~BSC_FD_WRITE; /* get the next msg for this timeslot */ msg = e1inp_tx_ts(e1i_ts, &sign_link); if (!msg) { /* no message after tx delay timer */ return 0; } switch (sign_link->type) { case E1INP_SIGN_OML: #ifdef HSL_SR_1_0 /* HSL uses 0x81 for FOM for some reason */ if (msg->data[0] == ABIS_OM_MDISC_FOM) msg->data[0] = ABIS_OM_MDISC_FOM | 0x01; #endif break; case E1INP_SIGN_RSL: break; default: msgb_free(msg); bfd->when |= BSC_FD_WRITE; /* come back for more msg */ return -EINVAL; } msg->l2h = msg->data; ipaccess_prepend_header(msg, sign_link->tei); DEBUGP(DLMI, "TX %u: %s\n", ts_nr, osmo_hexdump(msg->l2h, msgb_l2len(msg))); ret = send(bfd->fd, msg->data, msg->len, 0); msgb_free(msg); /* set tx delay timer for next event */ e1i_ts->sign.tx_timer.cb = timeout_ts1_write; e1i_ts->sign.tx_timer.data = e1i_ts; /* Reducing this might break the nanoBTS 900 init. */ osmo_timer_schedule(&e1i_ts->sign.tx_timer, 0, e1i_ts->sign.delay); return ret; }
/* osmocom_on_mtk_timer */ static void _osmocom_on_mtk_timer(void * data) { ModemPlugin * modem = data; Osmocom * osmocom = modem; int rc; if(osmocom->dnload.mtk_state == MTK_INIT_1) { printf("Sending MTK romloader beacon...\n"); rc = write(osmocom->dnload.serial_fd.fd, &mtk_init_cmd[0], 1); if(rc != 1) printf("Error sending identification beacon\n"); osmo_timer_schedule(&osmocom->tick_timer, 0, osmocom->dnload.beacon_interval); } }
static void timer_fired(void *_data) { unsigned long data = (unsigned long) _data; printf("Fired timer: %lu\n", data); if (data == 1) { osmo_timer_schedule(&timer_one, 3, 0); osmo_timer_del(&timer_two); } else if (data == 2) { printf("Should not be fired... bug in del_timer\n"); } else if (data == 3) { printf("Timer fired not registering again\n"); } else { printf("wtf... wrong data\n"); } }
static void ussd_start_auth(struct bsc_nat_ussd_con *conn) { struct msgb *msg; conn->auth_timeout.data = conn; conn->auth_timeout.cb = ussd_auth_cb; osmo_timer_schedule(&conn->auth_timeout, conn->nat->auth_timeout, 0); msg = msgb_alloc_headroom(4096, 128, "auth message"); if (!msg) { LOGP(DNAT, LOGL_ERROR, "Failed to allocate auth msg\n"); return; } msgb_v_put(msg, IPAC_MSGT_ID_GET); bsc_do_write(&conn->queue, msg, IPAC_PROTO_IPACCESS); }
/* osmocom_on_beacon_timer */ static void _osmocom_on_beacon_timer(void * data) { ModemPlugin * modem = data; Osmocom * osmocom = modem; int rc; if(osmocom->dnload.romload_state == WAITING_IDENTIFICATION) { printf("Sending Calypso romloader beacon...\n"); rc = write(osmocom->dnload.serial_fd.fd, romload_ident_cmd, sizeof(romload_ident_cmd)); if(rc != sizeof(romload_ident_cmd)) printf("Error sending identification beacon\n"); osmo_timer_schedule(&osmocom->tick_timer, 0, osmocom->dnload.beacon_interval); } }
/* send first ctrl message and start timer */ static void trx_ctrl_send(struct trx_l1h *l1h) { struct trx_ctrl_msg *tcm; /* get first command */ if (llist_empty(&l1h->trx_ctrl_list)) return; tcm = llist_entry(l1h->trx_ctrl_list.next, struct trx_ctrl_msg, list); LOGP(DTRX, LOGL_DEBUG, "Sending control '%s' to %s\n", tcm->cmd, phy_instance_name(l1h->phy_inst)); /* send command */ send(l1h->trx_ofd_ctrl.fd, tcm->cmd, strlen(tcm->cmd)+1, 0); /* start timer */ l1h->trx_ctrl_timer.cb = trx_ctrl_timer_cb; l1h->trx_ctrl_timer.data = l1h; osmo_timer_schedule(&l1h->trx_ctrl_timer, 2, 0); }
static void loader_do_fprogram() { uint32_t rembytes = osmoload.memlen - osmoload.memoff; if(!rembytes) { puts("done."); osmoload.quit = 1; return; } osmo_timer_schedule(&osmoload.timeout, 0, 10000000); uint8_t reqbytes = (rembytes < MEM_MSG_MAX) ? rembytes : MEM_MSG_MAX; osmoload.memcrc = osmo_crc16(0, (uint8_t *) osmoload.binbuf + osmoload.memoff, reqbytes); osmoload.memreq = reqbytes; struct msgb *msg = msgb_alloc(MSGB_MAX, "loader"); msgb_put_u8(msg, LOADER_FLASH_PROGRAM); msgb_put_u8(msg, reqbytes); msgb_put_u16(msg, osmoload.memcrc); msgb_put_u8(msg, 0); // XXX: align data to 16bit msgb_put_u8(msg, osmoload.memchip); msgb_put_u32(msg, osmoload.membase + osmoload.memoff); unsigned char *p = msgb_put(msg, reqbytes); memcpy(p, osmoload.binbuf + osmoload.memoff, reqbytes); #if 0 printf("Sending %u bytes at offset %u to address %x with crc %x\n", reqbytes, osmoload.memoff, osmoload.membase + osmoload.memoff, osmoload.memcrc); #endif loader_send_request(msg); msgb_free(msg); osmoload.memoff += reqbytes; }
/* start to scan for one ARFCN */ static int _cinfo_start_arfcn(unsigned int band_arfcn) { int rc; /* ask L1 to try to tune to new ARFCN */ /* FIXME: decode band */ rc = l1ctl_tx_fbsb_req(fps.ms, band_arfcn, L1CTL_FBSB_F_FB01SB, 100, 0, CCCH_MODE_COMBINED); if (rc < 0) return rc; /* allocate new cell info structure */ fps.cur_cell = cell_info_alloc(); fps.cur_arfcn = band_arfcn; fps.cur_cell->band_arfcn = band_arfcn; /* FIXME: start timer in case we never get a sync */ fps.state = BSCAN_S_WAIT_DATA; osmo_timer_schedule(&fps.timer, 2, 0); return 0; }
/* 'swd_num_events' configures the number of events to be monitored before notifying the systemd service watchdog. It must be in the range of [1,64]. Events are notified through the function 'oc2gbts_swd_event' */ int oc2gbts_swd_init(struct oc2gbts_mgr_instance *mgr, int swd_num_events) { /* Checks for a valid number of events to validate */ if (swd_num_events < 1 || swd_num_events > 64) return(-1); mgr->swd.state = SWD_INITIAL; mgr->swd.swd_timeout.data = mgr; mgr->swd.swd_timeout.cb = swd_loop_run; osmo_timer_schedule(&mgr->swd.swd_timeout, 0, 0); if (swd_num_events == 64){ mgr->swd.swd_eventmasks = 0xffffffffffffffffULL; } else { mgr->swd.swd_eventmasks = ((1ULL << swd_num_events) - 1); } mgr->swd.swd_events = 0; mgr->swd.num_events = swd_num_events; return 0; }
/*! \brief perform a state change of the given FSM instance * * Best invoke via the osmo_fsm_inst_state_chg() macro which logs the source * file where the state change was effected. Alternatively, you may pass \a * file as NULL to use the normal file/line indication instead. * * All changes to the FSM instance state must be made via this * function. It verifies that the existing state actually permits a * transiiton to new_state. * * timeout_secs and T are optional parameters, and only have any effect * if timeout_secs is not 0. If the timeout function is used, then the * new_state is entered, and the FSM instances timer is set to expire * in timeout_secs functions. At that time, the FSM's timer_cb * function will be called for handling of the timeout by the user. * * \param[in] fi FSM instance whose state is to change * \param[in] new_state The new state into which we should change * \param[in] timeout_secs Timeout in seconds (if !=0) * \param[in] T Timer number (if \ref timeout_secs != 0) * \param[in] file Calling source file (from osmo_fsm_inst_state_chg macro) * \param[in] line Calling source line (from osmo_fsm_inst_state_chg macro) * \returns 0 on success; negative on error */ int _osmo_fsm_inst_state_chg(struct osmo_fsm_inst *fi, uint32_t new_state, unsigned long timeout_secs, int T, const char *file, int line) { struct osmo_fsm *fsm = fi->fsm; uint32_t old_state = fi->state; const struct osmo_fsm_state *st = &fsm->states[fi->state]; /* validate if new_state is a valid state */ if (!(st->out_state_mask & (1 << new_state))) { LOGPFSMLSRC(fi, LOGL_ERROR, file, line, "transition to state %s not permitted!\n", osmo_fsm_state_name(fsm, new_state)); return -EPERM; } /* delete the old timer */ osmo_timer_del(&fi->timer); if (st->onleave) st->onleave(fi, new_state); LOGPFSMSRC(fi, file, line, "state_chg to %s\n", osmo_fsm_state_name(fsm, new_state)); fi->state = new_state; st = &fsm->states[new_state]; if (timeout_secs) { fi->T = T; osmo_timer_schedule(&fi->timer, timeout_secs, 0); } /* Call 'onenter' last, user might terminate FSM from there */ if (st->onenter) st->onenter(fi, old_state); return 0; }
static int gsm411_mmsms_send_msg(struct gsm411_smc_inst *inst) { struct msgb *nmsg; LOGP(DLSMS, LOGL_INFO, "Send CP data\n"); /* reset retry counter */ if (inst->cp_state != GSM411_CPS_WAIT_CP_ACK) inst->cp_retx = 0; /* 5.2.3.1.2: enter MO-wait for CP-ACK */ /* 5.2.3.2.3: enter MT-wait for CP-ACK */ new_cp_state(inst, GSM411_CPS_WAIT_CP_ACK); inst->cp_timer.data = inst; inst->cp_timer.cb = cp_timer_expired; /* 5.3.2.1: Set Timer TC1A */ osmo_timer_schedule(&inst->cp_timer, inst->cp_tc1, 0); /* clone cp_msg */ nmsg = gsm411_msgb_alloc(); memcpy(msgb_put(nmsg, inst->cp_msg->len), inst->cp_msg->data, inst->cp_msg->len); /* send MMSMS_DATA_REQ with CP-DATA */ return inst->mm_send(inst, GSM411_MMSMS_DATA_REQ, nmsg, GSM411_MT_CP_DATA); }
static int _l1if_req_compl(struct lc15l1_hdl *fl1h, struct msgb *msg, int is_system_prim, l1if_compl_cb *cb, void *data) { struct wait_l1_conf *wlc; struct osmo_wqueue *wqueue; unsigned int timeout_secs; /* allocate new wsc and store reference to mutex and conf_id */ wlc = talloc_zero(fl1h, struct wait_l1_conf); wlc->cb = cb; wlc->cb_data = data; /* Make sure we actually have received a REQUEST type primitive */ if (is_system_prim == 0) { GsmL1_Prim_t *l1p = msgb_l1prim(msg); LOGP(DL1P, LOGL_INFO, "Tx L1 prim %s\n", get_value_string(lc15bts_l1prim_names, l1p->id)); if (lc15bts_get_l1prim_type(l1p->id) != L1P_T_REQ) { LOGP(DL1C, LOGL_ERROR, "L1 Prim %s is not a Request!\n", get_value_string(lc15bts_l1prim_names, l1p->id)); talloc_free(wlc); return -EINVAL; } wlc->is_sys_prim = 0; wlc->conf_prim_id = lc15bts_get_l1prim_conf(l1p->id); wlc->conf_hLayer3 = l1p_get_hLayer3(l1p); wqueue = &fl1h->write_q[MQ_L1_WRITE]; timeout_secs = 30; } else { Litecell15_Prim_t *sysp = msgb_sysprim(msg); LOGP(DL1C, LOGL_INFO, "Tx SYS prim %s\n", get_value_string(lc15bts_sysprim_names, sysp->id)); if (lc15bts_get_sysprim_type(sysp->id) != L1P_T_REQ) { LOGP(DL1C, LOGL_ERROR, "SYS Prim %s is not a Request!\n", get_value_string(lc15bts_sysprim_names, sysp->id)); talloc_free(wlc); return -EINVAL; } wlc->is_sys_prim = 1; wlc->conf_prim_id = lc15bts_get_sysprim_conf(sysp->id); wqueue = &fl1h->write_q[MQ_SYS_WRITE]; timeout_secs = 30; } /* enqueue the message in the queue and add wsc to list */ if (osmo_wqueue_enqueue(wqueue, msg) != 0) { /* So we will get a timeout but the log message might help */ LOGP(DL1C, LOGL_ERROR, "Write queue for %s full. dropping msg.\n", is_system_prim ? "system primitive" : "gsm"); msgb_free(msg); } llist_add(&wlc->list, &fl1h->wlc_list); /* schedule a timer for timeout_secs seconds. If DSP fails to respond, we terminate */ wlc->timer.data = wlc; wlc->timer.cb = l1if_req_timeout; osmo_timer_schedule(&wlc->timer, timeout_secs, 0); return 0; }
int bsc_msc_connect(struct bsc_msc_connection *con) { struct bsc_msc_dest *dest; struct osmo_fd *fd; struct sockaddr_in sin; int on = 1, ret; if (llist_empty(con->dests)) { LOGP(DMSC, LOGL_ERROR, "No MSC(%s) connections configured.\n", con->name); connection_loss(con); return -1; } /* TODO: Why are we not using the libosmocore soecket * abstraction, or libosmo-netif? */ /* move to the next connection */ dest = (struct bsc_msc_dest *) con->dests->next; llist_del(&dest->list); llist_add_tail(&dest->list, con->dests); LOGP(DMSC, LOGL_NOTICE, "Attempting to connect MSC(%s) at %s:%d\n", con->name, dest->ip, dest->port); con->is_connected = 0; msgb_free(con->pending_msg); con->pending_msg = NULL; fd = &con->write_queue.bfd; fd->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); fd->priv_nr = 1; if (fd->fd < 0) { perror("Creating TCP socket failed"); return fd->fd; } /* make it non blocking */ setnonblocking(fd); /* set the socket priority */ ret = setsockopt(fd->fd, IPPROTO_IP, IP_TOS, &dest->dscp, sizeof(dest->dscp)); if (ret != 0) LOGP(DMSC, LOGL_ERROR, "Failed to set DSCP to %d on MSC(%s). %s\n", dest->dscp, con->name, strerror(errno)); memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(dest->port); inet_aton(dest->ip, &sin.sin_addr); ret = setsockopt(fd->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); if (ret != 0) LOGP(DMSC, LOGL_ERROR, "Failed to set SO_REUSEADDR socket option\n"); ret = connect(fd->fd, (struct sockaddr *) &sin, sizeof(sin)); if (ret == -1 && errno == EINPROGRESS) { LOGP(DMSC, LOGL_ERROR, "MSC(%s) Connection in progress\n", con->name); fd->when = BSC_FD_WRITE; fd->cb = msc_connection_connect; con->timeout_timer.cb = msc_con_timeout; con->timeout_timer.data = con; osmo_timer_schedule(&con->timeout_timer, 20, 0); } else if (ret < 0) { perror("Connection failed"); connection_loss(con); return ret; } else { fd->when = BSC_FD_READ | BSC_FD_EXCEPT; fd->cb = osmo_wqueue_bfd_cb; con->is_connected = 1; if (con->connected) con->connected(con); } ret = osmo_fd_register(fd); if (ret < 0) { perror("Registering the fd failed"); close(fd->fd); return ret; } return ret; }
static void loader_command(char *name, int cmdc, char **cmdv) { if(!cmdc) { usage(name); } char *cmd = cmdv[0]; char buf[MEM_MSG_MAX]; memset(buf, 23, sizeof(buf)); if(!strcmp(cmd, "dump")) { osmoload.state = STATE_DUMPING; } else if(!strcmp(cmd, "ping")) { loader_start_query(LOADER_PING); } else if(!strcmp(cmd, "off")) { loader_start_query(LOADER_POWEROFF); } else if(!strcmp(cmd, "reset")) { loader_start_query(LOADER_RESET); } else if(!strcmp(cmd, "jumprom")) { loader_start_query(LOADER_ENTER_ROM_LOADER); } else if(!strcmp(cmd, "jumpflash")) { loader_start_query(LOADER_ENTER_FLASH_LOADER); } else if(!strcmp(cmd, "finfo")) { puts("Requesting flash layout info"); loader_start_query(LOADER_FLASH_INFO); } else if(!strcmp(cmd, "memput")) { uint32_t address; if(cmdc < 3) { usage(name); } address = strtoul(cmdv[1], NULL, 16); unsigned int i; char *hex = cmdv[2]; if(strlen(hex)&1) { puts("Invalid hex string."); exit(2); } for(i = 0; i <= sizeof(buf) && i < strlen(hex)/2; i++) { if(i >= sizeof(buf)) { puts("Value too long for single message"); exit(2); } unsigned int byte; int count = sscanf(hex + i * 2, "%02x", &byte); if(count != 1) { puts("Invalid hex string."); exit(2); } buf[i] = byte & 0xFF; } loader_start_memput(i & 0xFF, address, buf); } else if(!strcmp(cmd, "memget")) { uint32_t address; uint8_t length; if(cmdc < 3) { usage(name); } address = strtoul(cmdv[1], NULL, 16); length = strtoul(cmdv[2], NULL, 16); if(length > MEM_MSG_MAX) { puts("Too many bytes"); exit(2); } loader_start_memget(length, address); } else if(!strcmp(cmd, "jump")) { uint32_t address; if(cmdc < 2) { usage(name); } address = strtoul(cmdv[1], NULL, 16); loader_start_jump(address); } else if(!strcmp(cmd, "memdump")) { uint32_t address; uint32_t length; if(cmdc < 4) { usage(name); } address = strtoul(cmdv[1], NULL, 16); length = strtoul(cmdv[2], NULL, 16); loader_start_memdump(length, address, cmdv[3]); } else if(!strcmp(cmd, "memload")) { uint32_t address; if(cmdc < 3) { usage(name); } address = strtoul(cmdv[1], NULL, 16); loader_start_memload(address, cmdv[2]); } else if(!strcmp(cmd, "fprogram")) { uint8_t chip; uint32_t address; if(cmdc < 4) { usage(name); } chip = strtoul(cmdv[1], NULL, 10); address = strtoul(cmdv[2], NULL, 16); loader_start_fprogram(chip, address, cmdv[3]); } else if(!strcmp(cmd, "ferase")) { uint32_t address; uint32_t length; if(cmdc < 3) { usage(name); } address = strtoul(cmdv[1], NULL, 16); length = strtoul(cmdv[2], NULL, 16); loader_start_flashrange(LOADER_FLASH_ERASE, address, length); } else if(!strcmp(cmd, "flock")) { uint32_t address; uint32_t length; if(cmdc < 3) { usage(name); } address = strtoul(cmdv[1], NULL, 16); length = strtoul(cmdv[2], NULL, 16); loader_start_flashrange(LOADER_FLASH_LOCK, address, length); } else if(!strcmp(cmd, "flockdown")) { uint32_t address; uint32_t length; if(cmdc < 3) { usage(name); } address = strtoul(cmdv[1], NULL, 16); length = strtoul(cmdv[2], NULL, 16); loader_start_flashrange(LOADER_FLASH_LOCKDOWN, address, length); } else if(!strcmp(cmd, "funlock")) { uint32_t address; uint32_t length; if(cmdc < 3) { usage(name); } address = strtoul(cmdv[1], NULL, 16); length = strtoul(cmdv[2], NULL, 16); loader_start_flashrange(LOADER_FLASH_UNLOCK, address, length); } else if(!strcmp(cmd, "fgetlock")) { uint32_t address; uint32_t length; if(cmdc < 3) { usage(name); } address = strtoul(cmdv[1], NULL, 16); length = strtoul(cmdv[2], NULL, 16); loader_start_flashrange(LOADER_FLASH_GETLOCK, address, length); } else if(!strcmp(cmd, "help")) { usage(name); } else { printf("Unknown command '%s'\n", cmd); usage(name); } if(osmoload.state == STATE_QUERY_PENDING) { osmoload.timeout.cb = &query_timeout; osmo_timer_schedule(&osmoload.timeout, 0, 5000000); } if(osmoload.state == STATE_LOAD_IN_PROGRESS) { osmoload.timeout.cb = &memop_timeout; } }
static void hours_timer_cb(void *unused) { sysmobts_update_hours(no_eeprom_write); osmo_timer_schedule(&hours_timer, HOURS_TIMER_SECS, 0); }
static void check_temp_timer_cb(void *unused) { sysmobts_check_temp(no_eeprom_write); osmo_timer_schedule(&temp_timer, TEMP_TIMER_SECS, 0); }
static int _reset_open(ModemPlugin * modem) { Osmocom * osmocom = modem; ModemPluginHelper * helper = osmocom->helper; char const * device; unsigned int baudrate; int flags; uint32_t tmpaddr = ROMLOAD_ADDRESS; char const * p; if((device = helper->config_get(helper->modem, "device")) == NULL) device = "/dev/modem"; if((p = helper->config_get(helper->modem, "baudrate")) == NULL || (baudrate = strtoul(p, NULL, 10)) == 0) baudrate = 115200; baudrate = _reset_baudrate(modem, baudrate); if((osmocom->fd.fd = osmo_serial_init(device, baudrate)) < 0) { /* XXX report error */ #ifdef DEBUG fprintf(stderr, "DEBUG: %s: %s\n", device, strerror(errno)); #endif return -1; } if(osmo_fd_register(&osmocom->fd) != 0) { #ifdef DEBUG fprintf(stderr, "DEBUG: %s: %s\n", device, strerror(errno)); #endif /* XXX report error */ return -1; } /* Set serial socket to non-blocking mode of operation */ if((flags = fcntl(osmocom->fd.fd, F_GETFL)) != -1) { flags |= O_NONBLOCK; fcntl(osmocom->fd.fd, F_SETFL, flags); } osmocom->dnload.serial_fd.when = BSC_FD_READ; osmocom->dnload.serial_fd.cb = _osmocom_on_serial_read; if(osmocom->dnload.mode == MODE_ROMLOAD) { tmpaddr = ROMLOAD_ADDRESS; osmo_serial_set_baudrate(osmocom->fd.fd, ROMLOAD_INIT_BAUDRATE); osmocom->tick_timer.cb = &_osmocom_on_beacon_timer; osmocom->tick_timer.data = modem; osmo_timer_schedule(&osmocom->tick_timer, 0, osmocom->dnload.beacon_interval); } else { tmpaddr = MTK_ADDRESS; osmo_serial_set_baudrate(osmocom->fd.fd, MTK_INIT_BAUDRATE); osmocom->tick_timer.cb = &_osmocom_on_mtk_timer; osmocom->tick_timer.data = modem; osmo_timer_schedule(&osmocom->tick_timer, 0, osmocom->dnload.beacon_interval); } /* FIXME not endian proof */ osmocom->dnload.load_address[0] = (tmpaddr >> 24) & 0xff; osmocom->dnload.load_address[1] = (tmpaddr >> 16) & 0xff; osmocom->dnload.load_address[2] = (tmpaddr >> 8) & 0xff; osmocom->dnload.load_address[3] = tmpaddr & 0xff; return 0; }
static int handle_ts1_write(struct osmo_fd *bfd) { struct e1inp_line *line = bfd->data; struct misdn_line *mline = line->driver_data; unsigned int ts_nr = bfd->priv_nr; struct e1inp_ts *e1i_ts = &line->ts[ts_nr-1]; struct e1inp_sign_link *sign_link; struct sockaddr_mISDN sa; struct msgb *msg; struct mISDNhead *hh; uint8_t *l2_data; int ret; bfd->when &= ~BSC_FD_WRITE; /* get the next msg for this timeslot */ msg = e1inp_tx_ts(e1i_ts, &sign_link); if (!msg) { /* no message after tx delay timer */ return 0; } if (mline->use_userspace_lapd) { DEBUGP(DLMI, "TX %u/%u/%u: %s\n", line->num, sign_link->tei, sign_link->sapi, osmo_hexdump(msg->data, msg->len)); lapd_transmit(e1i_ts->lapd, sign_link->tei, sign_link->sapi, msg); } else { l2_data = msg->data; /* prepend the mISDNhead */ hh = (struct mISDNhead *) msgb_push(msg, sizeof(*hh)); hh->prim = DL_DATA_REQ; DEBUGP(DLMI, "TX channel(%d) TEI(%d) SAPI(%d): %s\n", sign_link->driver.misdn.channel, sign_link->tei, sign_link->sapi, osmo_hexdump(l2_data, msg->len - MISDN_HEADER_LEN)); /* construct the sockaddr */ sa.family = AF_ISDN; sa.sapi = sign_link->sapi; sa.dev = sign_link->tei; sa.channel = sign_link->driver.misdn.channel; ret = sendto(bfd->fd, msg->data, msg->len, 0, (struct sockaddr *)&sa, sizeof(sa)); if (ret < 0) fprintf(stderr, "%s sendto failed %d\n", __func__, ret); msgb_free(msg); } /* set tx delay timer for next event */ e1i_ts->sign.tx_timer.cb = timeout_ts1_write; e1i_ts->sign.tx_timer.data = e1i_ts; osmo_timer_schedule(&e1i_ts->sign.tx_timer, 0, e1i_ts->sign.delay); return ret; }