00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "libhpsangoma.h"
00017 #include "libhpsangoma_priv.h"
00018
00019
00020
00021
00022
00023 void (*lib_log)(int level, FILE *fp, char *file, const char *func, int line, char *fmt, ...)=NULL;
00024
00025
00034 static int sangoma_hp_tdm_chan_push(struct sangoma_hptdm_chan *chan, char *data, int len)
00035 {
00036 hp_tmd_chunk_t *tx_chunk;
00037 int free_slots;
00038
00039 if (!chan->init) {
00040 return -2;
00041 }
00042
00043 if (len >= SMG_HP_MAX_CHAN_DATA) {
00044
00045 lib_printf(0,NULL,"chan_push c%i tx chunk len %i too big\n",
00046 chan->span_no+1,chan->chan_no+1,chan->tx_idx_in,len);
00047 return -1;
00048 }
00049
00050
00051 if (chan->tx_idx_in >= chan->tx_idx_out) {
00052 free_slots=SMG_HP_TDM_CHUNK_IDX_SZ-(chan->tx_idx_in-chan->tx_idx_out);
00053 } else {
00054 free_slots=chan->tx_idx_out-chan->tx_idx_in;
00055 }
00056
00057
00058 if (!free_slots) {
00059
00060 lib_printf(0,NULL,"chan_push c%i failed no free slots in %i out %i\n",
00061 chan->span_no+1,chan->chan_no+1, chan->tx_idx_in,chan->tx_idx_out);
00062 return 1;
00063 }
00064
00065 tx_chunk = &chan->tx_idx[chan->tx_idx_in];
00066 if (tx_chunk->init) {
00067
00068 lib_printf(15,NULL,"chan_push s%ic%i tx chunk overrun in %i \n",
00069 chan->span_no+1,chan->chan_no+1,chan->tx_idx_in);
00070 return 1;
00071 }
00072
00073 memset(tx_chunk,0,sizeof(hp_tmd_chunk_t));
00074 memcpy(&tx_chunk->data,data,len);
00075 tx_chunk->len=len;
00076 tx_chunk->init=1;
00077
00078 lib_printf(15,NULL,"chan_push s%ic%i tx chunk in %i \n",
00079 chan->span_no+1,chan->chan_no+1,chan->tx_idx_in);
00080
00081 chan->tx_idx_in++;
00082 if (chan->tx_idx_in >= SMG_HP_TDM_CHUNK_IDX_SZ) {
00083 chan->tx_idx_in=0;
00084 }
00085
00086 return 0;
00087 }
00088
00089
00090
00091
00092
00093
00103 static int sangoma_hp_tdm_open_chan(sangoma_hptdm_span_t *span,
00104 sangoma_hptdm_chan_reg_t *cfg,
00105 unsigned int chan_no,
00106 sangoma_hptdm_chan_t **chan_ptr)
00107 {
00108 sangoma_hptdm_chan_t *chan;
00109
00110 if (!span->init) {
00111 return -1;
00112 }
00113
00114 if (chan_no >= SMG_HP_TDM_MAX_CHANS) {
00115 lib_printf(0,NULL,"open_chan failed chan_no %i >= max chans %i\n",
00116 chan_no, SMG_HP_TDM_MAX_CHANS);
00117 return -1;
00118 }
00119
00120 if (!cfg->rx_data || !cfg->p) {
00121 return -1;
00122 }
00123
00124 if (span->chan_idx[chan_no].chan_no_hw < 0) {
00125 lib_printf(0,NULL,"open_chan failed chan_no s%ic%i is not mapped to hardware\n",
00126 span->span_no+1,chan_no+1);
00127 return -1;
00128 }
00129
00130 chan = &span->chan_idx[chan_no].chan;
00131 if (chan->init) {
00132
00133 lib_printf(0,NULL,"open_chan failed chan_no s%ic%i is busy\n",
00134 span->span_no+1,chan_no+1);
00135 return 1;
00136 }
00137
00138 memset(chan,0,sizeof(sangoma_hptdm_chan_t));
00139
00140 chan->chan_no = chan_no;
00141 chan->span = span;
00142 memcpy(&chan->chan_reg, cfg, sizeof(sangoma_hptdm_chan_reg_t));
00143
00144 chan->push = sangoma_hp_tdm_chan_push;
00145
00146 chan->init=1;
00147 lib_printf(15,NULL,"open_chan chan_no s%ic%i ok\n",
00148 span->span_no+1,chan_no+1);
00149
00150 *chan_ptr = chan;
00151
00152 return 0;
00153
00154 }
00155
00156
00163 static int sangoma_hp_tdm_close_chan(sangoma_hptdm_chan_t *chan)
00164 {
00165 chan->init=0;
00166 chan->chan_reg.p=NULL;
00167 lib_printf(15,NULL,"close_chan chan_no s%ic%i ok\n",
00168 chan->span_no+1,chan->chan_no+1);
00169 return 0;
00170 }
00171
00172
00178 static int sangoma_hp_tdm_is_chan_closed (sangoma_hptdm_chan_t *chan)
00179 {
00180 return (chan->init == 0) ? 1:0;
00181 }
00182
00188 static int sangoma_hp_tdm_close_span(sangoma_hptdm_span_t *span)
00189 {
00190 int i;
00191 sangoma_hptdm_chan_t *chan=NULL;
00192
00193 for (i=0;i<SMG_HP_TDM_MAX_CHANS;i++) {
00194 chan = &span->chan_idx[i].chan;
00195 if (chan->init) {
00196 chan->init=0;
00197 }
00198 }
00199
00200 close(span->sock);
00201 span->sock=-1;
00202
00203 return 0;
00204 }
00205
00211 static int sangoma_hp_tdm_event_ctrl_span(sangoma_hptdm_span_t *span, hp_tdmapi_tx_event_t *event)
00212 {
00213 int err;
00214
00215 if (!span->init || span->sock < 0) {
00216 return -1;
00217 }
00218
00219 err = ioctl(span->sock,SIOC_WANPIPE_API,event);
00220 if (err < 0){
00221 lib_printf(0,NULL,"Error: SPAN %i Failed to execute event!\n",
00222 span->span_no+1);
00223 return -1;
00224 }
00225
00226 return 0;
00227 }
00228
00234 static int sangoma_hp_tdm_event_get_cfg(sangoma_hptdm_span_t *span, wan_if_cfg_t *if_cfg)
00235 {
00236 memcpy(if_cfg,&span->span_cfg,sizeof(if_cfg));
00237 return 0;
00238 }
00239
00245 static int sangoma_hp_tdm_run_span(sangoma_hptdm_span_t *span)
00246 {
00247 int err=0;
00248 fd_set sock_read,sock_write,sock_oob;
00249
00250 if (!span->init) {
00251 lib_printf(0, NULL, "Span %i not initialized %i\n",span->span_no+1);
00252 return -1;
00253 }
00254
00255 lib_printf(15, NULL, "Starting RUN SPAN %i Sock=%i\n",span->span_no+1, span->sock);
00256
00257 if (span->sock < 0) {
00258 err=sangoma_hptdm_span_open(span);
00259 if (err) {
00260 usleep(500000);
00261 err=-2;
00262 goto sangoma_hp_tdm_run_span_exit;
00263 }
00264 }
00265
00266
00267 FD_ZERO(&sock_read);
00268 FD_ZERO(&sock_write);
00269 FD_ZERO(&sock_oob);
00270
00271 FD_SET(span->sock,&sock_oob);
00272 FD_SET(span->sock,&sock_read);
00273 FD_SET(span->sock,&sock_write);
00274
00275 err=select(span->sock + 1,&sock_read, NULL, &sock_oob, NULL);
00276
00277 if (err > 0) {
00278
00279 if (FD_ISSET(span->sock,&sock_oob)){
00280 err=sangoma_hp_tdm_handle_oob_event(span);
00281 if (err) {
00282 lib_printf(0, NULL, "RUN SPAN: %i oob err %i\n",
00283 span->span_no+1, err);
00284 err=-3;
00285 goto sangoma_hp_tdm_run_span_exit;
00286 }
00287 }
00288 if (FD_ISSET(span->sock,&sock_read)){
00289 err=sangoma_hp_tdm_handle_read_event(span);
00290 if (err) {
00291 lib_printf(0, NULL, "RUN SPAN: %i read err %i\n",
00292 span->span_no+1, err);
00293 err=-4;
00294 goto sangoma_hp_tdm_run_span_exit;
00295 }
00296
00297 err=sangoma_hp_tdm_handle_write_event(span);
00298 if (err) {
00299 lib_printf(0, NULL, "RUN SPAN: %i write err %i\n",
00300 span->span_no+1, err);
00301 err=-5;
00302 goto sangoma_hp_tdm_run_span_exit;
00303 }
00304 }
00305
00306 } else if (err==0) {
00307
00308 return 0;
00309
00310 } else {
00311
00312 if (errno == EAGAIN) {
00313 goto sangoma_hp_tdm_run_span_exit;
00314 }
00315
00316 err=-6;
00317 }
00318
00319 sangoma_hp_tdm_run_span_exit:
00320
00321 if (err < 0) {
00322 if (span->sock) {
00323 close(span->sock);
00324 span->sock=-1;
00325 }
00326 }
00327
00328 return err;
00329 }
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349 sangoma_hptdm_span_t * __sangoma_hptdm_api_span_init(int span_no, sangoma_hptdm_span_reg_t *cfg, int version)
00350 {
00351 int err,i,ch=0;
00352 sangoma_hptdm_span_t *span;
00353
00354 span = malloc(sizeof(sangoma_hptdm_span_t));
00355 if (!span) {
00356 return NULL;
00357 }
00358
00359 memset(span,0,sizeof(sangoma_hptdm_span_t));
00360
00361 span->span_no=span_no;
00362 sprintf(span->if_name,"w%ig1",span_no+1);
00363
00364 if (cfg) {
00365 memcpy(&span->span_reg,cfg,sizeof(sangoma_hptdm_span_reg_t));
00366 if (!lib_log) {
00367 lib_log=cfg->log;
00368 }
00369 }
00370
00371 err=sangoma_hptdm_span_open(span);
00372 if (err) {
00373 free(span);
00374 return NULL;
00375 }
00376
00377 if (span->span_cfg.media == WAN_MEDIA_E1) {
00378 span->span_cfg.active_ch = span->span_cfg.active_ch >> 1;
00379 }
00380
00381 lib_printf(0,NULL,"Span %i Configuration\n",span->span_no+1);
00382 lib_printf(0,NULL,"Used By\t:%i\n",span->span_cfg.usedby);
00383 lib_printf(0,NULL,"Media\t:%i\n",span->span_cfg.media);
00384 lib_printf(0,NULL,"Active Ch\t:0x%08X\n",span->span_cfg.active_ch);
00385 lib_printf(0,NULL,"Chunk Sz\t:%i\n",span->span_cfg.chunk_sz);
00386 lib_printf(0,NULL,"HW Coding\t:%i\n",span->span_cfg.hw_coding);
00387 lib_printf(0,NULL,"If Number\t:%i\n",span->span_cfg.interface_number);
00388
00389
00390
00391 for (i=0;i<SMG_HP_TDM_MAX_CHANS;i++) {
00392 span->chan_idx[i].chan_no_hw=-1;
00393 if (span->span_cfg.active_ch & (1<<i)) {
00394 span->chan_idx[i].chan_no_hw=ch;
00395 lib_printf(0,NULL,"Chan %i Mapped to %i",i,ch);
00396 ch++;
00397 span->max_chans++;
00398 } else {
00399 lib_printf(0,NULL,"Chan %i Not Mapped",i);
00400 }
00401 }
00402
00403 lib_printf(0,NULL,"Total Chans\t:%i\n",span->max_chans);
00404
00405
00406 span->chunk_sz=span->span_cfg.chunk_sz;
00407 span->tx_size=span->max_chans*span->chunk_sz;
00408
00409 span->init=1;
00410 span->idle=0xFF;
00411
00412 span->open_chan = sangoma_hp_tdm_open_chan;
00413 span->close_chan = sangoma_hp_tdm_close_chan;
00414 span->is_chan_closed = sangoma_hp_tdm_is_chan_closed;
00415 span->run_span =sangoma_hp_tdm_run_span;
00416 span->close_span = sangoma_hp_tdm_close_span;
00417 span->event_ctrl = sangoma_hp_tdm_event_ctrl_span;
00418 span->get_cfg = sangoma_hp_tdm_event_get_cfg;
00419
00420 lib_printf(5, NULL, "Span %i Initialized\n",span->span_no+1);
00421
00422 return span;
00423 }
00424
00425
00426
00427
00428
00429
00430
00431 int sangoma_hptdm_api_span_free(sangoma_hptdm_span_t *span)
00432 {
00433 if (span->sock >= 0) {
00434 span->close_span(span);
00435 }
00436
00437 free(span);
00438 span=NULL;
00439
00440 return 0;
00441 }
00442