int main(int argc, char **argv) { int max_flag = AVG_ENERGY, plot_flag = 0; u_int print_depth = 0; double load = 1; char *name, opt; /* parse options */ while ((opt = getopt(argc, argv, "+pmd:l:")) != -1) { switch (opt) { case 'p': plot_flag = 1; break; case 'm': max_flag = MAX_ENERGY; break; case 'd': print_depth = atoi(optarg); break; case 'l': load = atof(optarg); break; } } if (optind >= argc) { fprintf(stderr, "test_router: [-pm] [-d print_depth] [-l load] <router_name>\n"); exit(1); } else { name = argv[optind]; } FUNC(SIM_router_power_init, &GLOB(router_info), &GLOB(router_power)); SIM_router_stat_energy(&GLOB(router_info), &GLOB(router_power), print_depth, name, max_flag, load, plot_flag, PARM(Freq)); //load = SIM_reg_stat_energy(&GLOB(router_info).in_buf_info, &GLOB(router_power).in_buf, 0, 1, 0, NULL, 0); //printf("%g\n", load); exit(0); }
int main(int argc, char **argv) { int max_flag = AVG_ENERGY, plot_flag = 0; u_int print_depth = 0; double load = 1; char *name, opt; /* parse options */ while ((opt = getopt(argc, argv, "+pmd:l:")) != -1) { switch (opt) { case 'p': plot_flag = 1; break; case 'm': max_flag = MAX_ENERGY; break; case 'd': print_depth = atoi(optarg); break; case 'l': load = atof(optarg); break; } } if (optind >= argc) { fprintf(stderr, "orion_router_power: [-pm] [-d print_depth] [-l load] <router_name>\n"); return 1; } else { name = argv[optind]; } SIM_router_init(&GLOB(router_info), &GLOB(router_power), NULL); SIM_router_stat_energy(&GLOB(router_info), &GLOB(router_power), print_depth, name, max_flag, load, plot_flag, PARM(Freq)); return 0; }
/* record row decoder and wordline activity */ inline int FUNC( SIM_reg_power_dec, SIM_power_array_info_t *info, SIM_power_array_t *arr, u_int port, LIB_Type_max_uint row_addr, int rw ) { if (rw) /* write */ return SIM_power_array_dec( info, arr, (SIM_array_port_state_t *)&GLOB(reg_write_port)[port], row_addr, rw ); else /* read */ return SIM_power_array_dec( info, arr, (SIM_array_port_state_t *)&GLOB(reg_read_port)[port], row_addr, rw ); }
boolean_t sccp_netsock_getExternalAddr(struct sockaddr_storage *sockAddrStorage) { //! \todo handle IPv4 / IPV6 family ? if (sccp_netsock_is_any_addr(&GLOB(externip))) { sccp_log(DEBUGCAT_CORE) (VERBOSE_PREFIX_3 "SCCP: No externip set in sccp.conf. In case you are running your PBX on a seperate host behind a NATTED Firewall you need to set externip.\n"); return FALSE; } memcpy(sockAddrStorage, &GLOB(externip), sizeof(struct sockaddr_storage)); return TRUE; }
static void * sccp_pbx_call_autoanswer_thread(void *data) { uint32_t *tmp = data; uint32_t callid = *tmp; sccp_channel_t * c; sleep(GLOB(autoanswer_ring_time)); pthread_testcancel(); c = sccp_channel_find_byid(callid); if (!c || !c->device) return NULL; if (c->state != SCCP_CHANNELSTATE_RINGIN) return NULL; sccp_channel_answer(c); if (GLOB(autoanswer_tone) != SKINNY_TONE_SILENCE && GLOB(autoanswer_tone) != SKINNY_TONE_NOTONE) sccp_dev_starttone(c->device, GLOB(autoanswer_tone), c->line->instance, c->callid, 0); if (c->autoanswer_type == SCCP_AUTOANSWER_1W) sccp_dev_set_microphone(c->device, SKINNY_STATIONMIC_OFF); return NULL; }
/*! * \brief Fire an Event * \param event SCCP Event * \note event will be freed after event is fired * * \warning * - sccp_event_listeners->subscriber is not always locked */ void sccp_event_fire(const sccp_event_t * event) { if (event == NULL || SCCP_REF_RUNNING != sccp_refcount_isRunning() || !sccp_event_running) { if (event) { sccp_event_destroy((sccp_event_t *) event); } return; } AUTO_RELEASE sccp_event_t *e = (sccp_event_t *) sccp_refcount_object_alloc(sizeof(sccp_event_t), SCCP_REF_EVENT, sccp_event_type2str(event->type), sccp_event_destroy); if (!e) { pbx_log(LOG_ERROR, "%p: Memory Allocation Error while creating sccp_event e. Exiting\n", event); sccp_event_destroy((sccp_event_t *) event); return; } // memcpy(e, event, sizeof(sccp_event_t)); e->type = event->type; sccp_log((DEBUGCAT_EVENT)) (VERBOSE_PREFIX_3 "Handling Event %p of Type %s\n", event, sccp_event_type2str(e->type)); /* update refcount */ switch (e->type) { case SCCP_EVENT_DEVICE_REGISTERED: case SCCP_EVENT_DEVICE_UNREGISTERED: case SCCP_EVENT_DEVICE_PREREGISTERED: e->event.deviceRegistered.device = event->event.deviceRegistered.device; break; case SCCP_EVENT_LINE_CREATED: e->event.lineCreated.line = event->event.lineCreated.line; break; case SCCP_EVENT_DEVICE_ATTACHED: case SCCP_EVENT_DEVICE_DETACHED: e->event.deviceAttached.linedevice = event->event.deviceAttached.linedevice; break; case SCCP_EVENT_FEATURE_CHANGED: e->event.featureChanged.device = event->event.featureChanged.device; e->event.featureChanged.optional_linedevice = event->event.featureChanged.optional_linedevice; e->event.featureChanged.featureType = event->event.featureChanged.featureType; break; case SCCP_EVENT_LINESTATUS_CHANGED: e->event.lineStatusChanged.line = event->event.lineStatusChanged.line; e->event.lineStatusChanged.optional_device = event->event.lineStatusChanged.optional_device; e->event.lineStatusChanged.state = event->event.lineStatusChanged.state; break; case SCCP_EVENT_LINE_CHANGED: case SCCP_EVENT_LINE_DELETED: break; case SCCP_EVENT_TYPE_SENTINEL: break; } /* search for position in array */ int i, n; sccp_event_type_t eventType = event->type; for (i = 0, n = 1 << i; i < NUMBER_OF_EVENT_TYPES; i++, n = 1 << i) { if (eventType & n) { break; } } // pthread_attr_t tattr; // pthread_t tid; /* start async thread if nessesary */ if (GLOB(module_running)) { if (subscriptions[i].aSyncSize > 0 && sccp_event_running) { /* create thread for async subscribers */ struct sccp_event_aSyncEventProcessorThreadArg *arg = sccp_malloc(sizeof(struct sccp_event_aSyncEventProcessorThreadArg)); if (!arg) { pbx_log(LOG_ERROR, "%p: Memory Allocation Error while creating sccp_event_aSyncEventProcessorThreadArg. Skipping\n", event); } else { arg->subscribers = &subscriptions[i]; arg->event = sccp_event_retain(e); /* initialized with default attributes */ if (arg->event != NULL) { sccp_log((DEBUGCAT_EVENT)) (VERBOSE_PREFIX_3 "Adding work to threadpool for event: %p, type: %s\n", event, sccp_event_type2str(event->type)); if (!sccp_threadpool_add_work(GLOB(general_threadpool), (void *) sccp_event_processor, (void *) arg)) { pbx_log(LOG_ERROR, "Could not add work to threadpool for event: %p, type: %s for processing\n", event, sccp_event_type2str(event->type)); arg->event = sccp_event_release(arg->event); sccp_free(arg); } } else { pbx_log(LOG_ERROR, "Could not retain e: %p, type: %s for processing\n", e, sccp_event_type2str(event->type)); sccp_free(arg); } } } /* execute sync subscribers */ AUTO_RELEASE sccp_event_t *tmp_e = NULL; if ((tmp_e = sccp_event_retain(e))) { for (n = 0; n < subscriptions[i].syncSize && sccp_event_running; n++) { if (subscriptions[i].sync[n].callback_function != NULL) { subscriptions[i].sync[n].callback_function((const sccp_event_t *) e); } } } else { pbx_log(LOG_ERROR, "Could not retain e: %p, type: %s for processing\n", e, sccp_event_type2str(event->type)); } } else { // we are unloading. switching to synchonous mode for everything sccp_log((DEBUGCAT_EVENT)) (VERBOSE_PREFIX_3 "Handling Event %p of Type %s in Forced Synchronous Mode\n", event, sccp_event_type2str(e->type)); AUTO_RELEASE sccp_event_t *tmp_e = NULL; if ((tmp_e = sccp_event_retain(e))) { for (n = 0; n < subscriptions[i].syncSize && sccp_event_running; n++) { if (subscriptions[i].sync[n].callback_function != NULL) { subscriptions[i].sync[n].callback_function((const sccp_event_t *) e); } } for (n = 0; n < subscriptions[i].aSyncSize && sccp_event_running; n++) { if (subscriptions[i].async[n].callback_function != NULL) { subscriptions[i].async[n].callback_function((const sccp_event_t *) e); } } } else { pbx_log(LOG_ERROR, "Could not retain e: %p, type: %s for processing\n", e, sccp_event_type2str(event->type)); } } }
/* record write data bitline and memory cell activity */ inline int FUNC( SIM_reg_power_data_write, SIM_power_array_info_t *info, SIM_power_array_t *arr, u_int port, LIB_Type_max_uint old_data, LIB_Type_max_uint new_data ) { return SIM_power_array_data_write( info, arr, NULL, sizeof(old_data), (u_char *)&GLOB(reg_write_port)[port].data_line, (u_char *)&old_data, (u_char *)&new_data ); }
void * sccp_pbx_startchannel(void *data) { struct cw_channel * chan = data; sccp_channel_t * c; sccp_line_t * l; sccp_device_t * d; uint8_t res_exten = 0, res_wait = 0, res_timeout = 0; c = CS_CW_CHANNEL_PVT(chan); if ( !c || !(l = c->line) || !(d = c->device) ) { cw_hangup(chan); return NULL; } sccp_log(1)( VERBOSE_PREFIX_3 "%s: New call on line %s\n", d->id, l->name); cw_mutex_lock(&c->lock); c->calltype = SKINNY_CALLTYPE_OUTBOUND; c->hangupok = 0; cw_mutex_unlock(&c->lock); sccp_channel_set_callingparty(c, l->cid_name, l->cid_num); if (!cw_strlen_zero(c->dialedNumber)) { /* we have a number to dial. Let's do it */ sccp_log(10)( VERBOSE_PREFIX_3 "%s: Dialing %s on channel %s-%d\n", l->device->id, c->dialedNumber, l->name, c->callid); sccp_channel_set_calledparty(c, c->dialedNumber, c->dialedNumber); sccp_indicate_lock(c, SCCP_CHANNELSTATE_DIALING); goto dial; } /* we have to collect the number */ /* the phone is on TsOffHook state */ sccp_log(10)( VERBOSE_PREFIX_3 "%s: Waiting for the number to dial on channel %s-%d\n", l->device->id, l->name, c->callid); /* let's use the keypad to collect digits */ cw_mutex_lock(&c->lock); c->digittimeout = time(0)+GLOB(firstdigittimeout); cw_mutex_unlock(&c->lock); res_exten = 1; do { pthread_testcancel(); usleep(100); cw_mutex_lock(&c->lock); if (!cw_strlen_zero(c->dialedNumber)) { res_exten = (c->dialedNumber[0] == '*' || cw_matchmore_extension(chan, chan->context, c->dialedNumber, 1, l->cid_num)); } if (! (res_wait = ( c->state == SCCP_CHANNELSTATE_DOWN || chan->_state == CW_STATE_DOWN || chan->_softhangup || c->calltype == SKINNY_CALLTYPE_INBOUND)) ) { if (CS_CW_CHANNEL_PVT(chan)) { res_timeout = (time(0) < c->digittimeout); } else res_timeout = 0; } cw_mutex_unlock(&c->lock); } while ( (res_wait == 0) && res_exten && res_timeout); if (res_wait != 0) { /* CW_STATE_DOWN or softhangup */ sccp_log(10)(VERBOSE_PREFIX_3 "%s: return from the startchannel for DOWN, HANGUP or PICKUP cause\n", l->device->id); cw_mutex_lock(&c->lock); c->hangupok = 1; cw_mutex_unlock(&c->lock); return NULL; } dial: cw_mutex_lock(&c->lock); cw_copy_string(chan->exten, c->dialedNumber, sizeof(chan->exten)); cw_copy_string(d->lastNumber, c->dialedNumber, sizeof(d->lastNumber)); sccp_channel_set_calledparty(c, c->dialedNumber, c->dialedNumber); /* proceed call state is needed to display the called number. The phone will not display callinfo in offhook state */ sccp_channel_set_callstate(c, SKINNY_CALLSTATE_PROCEED); sccp_channel_send_callinfo(c); sccp_dev_clearprompt(d,c->line->instance, c->callid); sccp_dev_displayprompt(d, c->line->instance, c->callid, SKINNY_DISP_CALL_PROCEED, 0); c->hangupok = 1; cw_mutex_unlock(&c->lock); if ( !cw_strlen_zero(c->dialedNumber) && cw_exists_extension(chan, chan->context, c->dialedNumber, 1, l->cid_num) ) { /* found an extension, let's dial it */ sccp_log(10)(VERBOSE_PREFIX_3 "%s: channel %s-%d is dialing number %s\n", l->device->id, l->name, c->callid, c->dialedNumber); /* Answer dialplan command works only when in RINGING OR RING cw_state */ sccp_cw_setstate(c, CW_STATE_RING); if (cw_pbx_run(chan)) { sccp_indicate_lock(c, SCCP_CHANNELSTATE_INVALIDNUMBER); } } else { /* timeout and no extension match */ sccp_indicate_lock(c, SCCP_CHANNELSTATE_INVALIDNUMBER); } sccp_log(10)(VERBOSE_PREFIX_3 "%s: return from the startchannel on exit\n", l->device->id); return NULL; }
uint8_t sccp_pbx_channel_allocate(sccp_channel_t * c) { sccp_device_t * d = c->device; struct cw_channel * tmp; sccp_line_t * l = c->line; int fmt; if (!l || !d || !d->session) { cw_log(LOG_ERROR, "SCCP: Unable to allocate asterisk channel\n"); return 0; } tmp = cw_channel_alloc(1); if (!tmp) { cw_log(LOG_ERROR, "%s: Unable to allocate callweaver channel on line %s\n", d->id, l->name); return 0; } /* need to reset the exten, otherwise it would be set to s */ memset(&tmp->exten,0,sizeof(tmp->exten)); /* let's connect the CW channel to the sccp channel */ cw_mutex_lock(&c->lock); c->owner = tmp; cw_mutex_unlock(&c->lock); sccp_log(10)(VERBOSE_PREFIX_3 "%s: Global Capabilities: %d\n", d->id, GLOB(global_capability)); cw_mutex_lock(&l->lock); cw_mutex_lock(&d->lock); tmp->nativeformats = (d->capability ? d->capability : GLOB(global_capability)); if (tmp->nativeformats & c->format) { fmt = c->format; } else { fmt = cw_codec_choose(&d->codecs, tmp->nativeformats, 1); c->format = fmt; } cw_mutex_unlock(&l->lock); cw_mutex_unlock(&d->lock); sccp_log(2)(VERBOSE_PREFIX_3 "%s: format request: %d/%d\n", d->id, tmp->nativeformats, c->format); snprintf(tmp->name, sizeof(tmp->name), "SCCP/%s-%08x", l->name, c->callid); if (GLOB(debug) > 2) { const unsigned slen=512; char s1[slen]; char s2[slen]; sccp_log(2)(VERBOSE_PREFIX_3 "%s: Channel %s, capabilities: DEVICE %s NATIVE %s BEST %d (%s)\n", d->id, c->owner->name, cw_getformatname_multiple(s1, slen, d->capability), cw_getformatname_multiple(s2, slen, tmp->nativeformats), fmt, cw_getformatname(fmt)); } tmp->type = "SCCP"; tmp->nativeformats = fmt; tmp->writeformat = fmt; tmp->readformat = fmt; tmp->tech = &sccp_tech; tmp->tech_pvt = c; tmp->adsicpe = CW_ADSI_UNAVAILABLE; // XXX: Bridge? // XXX: Transfer? cw_mutex_lock(&GLOB(usecnt_lock)); GLOB(usecnt)++; cw_mutex_unlock(&GLOB(usecnt_lock)); cw_update_use_count(); if (l->cid_num) tmp->cid.cid_num = strdup(l->cid_num); if (l->cid_name) tmp->cid.cid_name = strdup(l->cid_name); cw_copy_string(tmp->context, l->context, sizeof(tmp->context)); if (!cw_strlen_zero(l->language)) cw_copy_string(tmp->language, l->language, sizeof(tmp->language)); if (!cw_strlen_zero(l->accountcode)) cw_copy_string(tmp->accountcode, l->accountcode, sizeof(tmp->accountcode)); if (!cw_strlen_zero(l->musicclass)) cw_copy_string(tmp->musicclass, l->musicclass, sizeof(tmp->musicclass)); tmp->amaflags = l->amaflags; tmp->callgroup = l->callgroup; #ifdef CS_SCCP_PICKUP tmp->pickupgroup = l->pickupgroup; #endif tmp->priority = 1; sccp_log(10)(VERBOSE_PREFIX_3 "%s: Allocated callweaver channel %s-%d\n", d->id, l->name, c->callid); return 1; }
static int sccp_pbx_hangup(struct cw_channel * ast) { sccp_channel_t * c; sccp_line_t * l; sccp_device_t * d; int res = 0; c = CS_CW_CHANNEL_PVT(ast); cw_mutex_lock(&GLOB(usecnt_lock)); GLOB(usecnt)--; cw_mutex_unlock(&GLOB(usecnt_lock)); cw_update_use_count(); if (!c) { sccp_log(10)(VERBOSE_PREFIX_3 "SCCP: Asked to hangup channel %s. SCCP channel already hangup\n", ast->name); return 0; } cw_mutex_lock(&c->lock); CS_CW_CHANNEL_PVT(ast) = NULL; c->owner = NULL; l = c->line; d = l->device; sccp_log(1)(VERBOSE_PREFIX_3 "SCCP: CallWeaver request to hangup %s channel %s\n", skinny_calltype2str(c->calltype), ast->name); if (c->rtp) { sccp_channel_closereceivechannel(c); sccp_channel_stop_rtp(c); } sccp_log(10)(VERBOSE_PREFIX_3 "%s: Current channel %s-%d state %s(%d)\n", DEV_ID_LOG(d), l ? l->name : "(null)", c->callid, sccp_indicate2str(c->state), c->state); if ( c->state != SCCP_CHANNELSTATE_DOWN) { /* we are in a passive hangup */ if (GLOB(remotehangup_tone) && d->state == SCCP_DEVICESTATE_OFFHOOK && c == sccp_channel_get_active(d)) sccp_dev_starttone(d, GLOB(remotehangup_tone), 0, 0, 10); sccp_indicate_nolock(c, SCCP_CHANNELSTATE_ONHOOK); } if (c->calltype == SKINNY_CALLTYPE_OUTBOUND && !c->hangupok) { cw_mutex_unlock(&c->lock); sccp_log(10)(VERBOSE_PREFIX_3 "%s: Waiting for the dialing thread to go down on channel %s\n", DEV_ID_LOG(d), ast->name); do { usleep(10000); cw_mutex_lock(&c->lock); res = c->hangupok; cw_mutex_unlock(&c->lock); } while (!res); } else { cw_mutex_unlock(&c->lock); } cw_mutex_lock(&GLOB(channels_lock)); sccp_channel_delete(c); cw_mutex_unlock(&GLOB(channels_lock)); if (d && d->session) { cw_mutex_lock(&d->session->lock); d->session->needcheckringback = 1; cw_mutex_unlock(&d->session->lock); } return 0; }