root/src/sangoma_pri.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gettimeofday
  2. sangoma_pri_event_str
  3. __pri_sangoma_read
  4. __pri_sangoma_write
  5. sangoma_init_pri
  6. sangoma_one_loop
  7. sangoma_run_pri

   1 /*****************************************************************************
   2  * sangoma_pri.c libpri Sangoma integration
   3  *
   4  * Author(s):   Anthony Minessale II <anthmct@yahoo.com>
   5  *              Nenad Corbic <ncorbic@sangoma.com>
   6  *
   7  * Copyright:   (c) 2005 Anthony Minessale II
   8  *
   9  *              This program is free software; you can redistribute it and/or
  10  *              modify it under the terms of the GNU General Public License
  11  *              as published by the Free Software Foundation; either version
  12  *              2 of the License, or (at your option) any later version.
  13  * ============================================================================
  14  */
  15 
  16 #include "freetdm.h"
  17 #include <sangoma_pri.h>
  18 #ifndef HAVE_GETTIMEOFDAY
  19 
  20 #ifdef WIN32
  21 #include <mmsystem.h>
  22 
  23 static __inline int gettimeofday(struct timeval *tp, void *nothing)
  24 {
  25 #ifdef WITHOUT_MM_LIB
  26         SYSTEMTIME st;
  27         time_t tt;
  28         struct tm tmtm;
  29         /* mktime converts local to UTC */
  30         GetLocalTime (&st);
  31         tmtm.tm_sec = st.wSecond;
  32         tmtm.tm_min = st.wMinute;
  33         tmtm.tm_hour = st.wHour;
  34         tmtm.tm_mday = st.wDay;
  35         tmtm.tm_mon = st.wMonth - 1;
  36         tmtm.tm_year = st.wYear - 1900;  tmtm.tm_isdst = -1;
  37         tt = mktime (&tmtm);
  38         tp->tv_sec = tt;
  39         tp->tv_usec = st.wMilliseconds * 1000;
  40 #else
  41         /**
  42          ** The earlier time calculations using GetLocalTime
  43          ** had a time resolution of 10ms.The timeGetTime, part
  44          ** of multimedia apis offer a better time resolution
  45          ** of 1ms.Need to link against winmm.lib for this
  46          **/
  47         unsigned long Ticks = 0;
  48         unsigned long Sec =0;
  49         unsigned long Usec = 0;
  50         Ticks = timeGetTime();
  51 
  52         Sec = Ticks/1000;
  53         Usec = (Ticks - (Sec*1000))*1000;
  54         tp->tv_sec = Sec;
  55         tp->tv_usec = Usec;
  56 #endif /* WITHOUT_MM_LIB */
  57         (void)nothing;
  58         return 0;
  59 }
  60 #endif /* WIN32 */
  61 #endif /* HAVE_GETTIMEOFDAY */
  62 
  63 static struct sangoma_pri_event_list SANGOMA_PRI_EVENT_LIST[] = {
  64         {0, SANGOMA_PRI_EVENT_ANY, "ANY"},
  65         {1, SANGOMA_PRI_EVENT_DCHAN_UP, "DCHAN_UP"},
  66         {2, SANGOMA_PRI_EVENT_DCHAN_DOWN, "DCHAN_DOWN"},
  67         {3, SANGOMA_PRI_EVENT_RESTART, "RESTART"},
  68         {4, SANGOMA_PRI_EVENT_CONFIG_ERR, "CONFIG_ERR"},
  69         {5, SANGOMA_PRI_EVENT_RING, "RING"},
  70         {6, SANGOMA_PRI_EVENT_HANGUP, "HANGUP"},
  71         {7, SANGOMA_PRI_EVENT_RINGING, "RINGING"},
  72         {8, SANGOMA_PRI_EVENT_ANSWER, "ANSWER"},
  73         {9, SANGOMA_PRI_EVENT_HANGUP_ACK, "HANGUP_ACK"},
  74         {10, SANGOMA_PRI_EVENT_RESTART_ACK, "RESTART_ACK"},
  75         {11, SANGOMA_PRI_EVENT_FACNAME, "FACNAME"},
  76         {12, SANGOMA_PRI_EVENT_INFO_RECEIVED, "INFO_RECEIVED"},
  77         {13, SANGOMA_PRI_EVENT_PROCEEDING, "PROCEEDING"},
  78         {14, SANGOMA_PRI_EVENT_SETUP_ACK, "SETUP_ACK"},
  79         {15, SANGOMA_PRI_EVENT_HANGUP_REQ, "HANGUP_REQ"},
  80         {16, SANGOMA_PRI_EVENT_NOTIFY, "NOTIFY"},
  81         {17, SANGOMA_PRI_EVENT_PROGRESS, "PROGRESS"},
  82         {18, SANGOMA_PRI_EVENT_KEYPAD_DIGIT, "KEYPAD_DIGIT"}
  83 };
  84 
  85 #define LINE "--------------------------------------------------------------------------------"
  86 
  87 char *sangoma_pri_event_str(sangoma_pri_event_t event_id)
  88 { 
  89         return SANGOMA_PRI_EVENT_LIST[event_id].name;
  90 }
  91 
  92 static int __pri_sangoma_read(struct pri *pri, void *buf, int buflen)
  93 {
  94         struct sangoma_pri *spri = (struct sangoma_pri *) pri->userdata;
  95         ftdm_size_t len = buflen;
  96         int res;
  97         char bb[4096] = "";
  98 
  99 
 100         if (ftdm_channel_read(spri->zdchan, buf, &len) != FTDM_SUCCESS) {
 101                 printf("D-READ FAIL! [%s]\n", spri->zdchan->last_error);
 102                 return 0;
 103         }
 104         res = (int)len;
 105         memset(&((unsigned char*)buf)[res],0,2);
 106         res+=2;
 107 
 108         //print_bits(buf, res-2, bb, sizeof(bb), 1, 0);
 109         //ftdm_log(FTDM_LOG_DEBUG, "READ %d\n%s\n%s\n\n", res-2, LINE, bb);
 110 
 111         return res;
 112 }
 113 
 114 static int __pri_sangoma_write(struct pri *pri, void *buf, int buflen)
 115 {
 116         struct sangoma_pri *spri = (struct sangoma_pri *) pri->userdata;
 117         int res;
 118         ftdm_size_t len = buflen -2;
 119         char bb[4096] = "";
 120 
 121         if (ftdm_channel_write(spri->zdchan, buf, buflen, &len) != FTDM_SUCCESS) {
 122                 printf("D-WRITE FAIL! [%s]\n", spri->zdchan->last_error);
 123         return 0;
 124         }
 125         
 126         //print_bits(buf, (int)buflen-2, bb, sizeof(bb), 1, 0);
 127         //ftdm_log(FTDM_LOG_DEBUG, "WRITE %d\n%s\n%s\n\n", (int)buflen-2, LINE, bb);
 128 
 129         return (int) buflen;
 130 }
 131 
 132 int sangoma_init_pri(struct sangoma_pri *spri, int span, int dchan, int swtype, int node, int debug)
 133 {
 134         int ret = -1;
 135         ftdm_socket_t dfd = 0;
 136 
 137         memset(spri, 0, sizeof(struct sangoma_pri));
 138 
 139         if (ftdm_channel_open(span, dchan, &spri->zdchan) != FTDM_SUCCESS) {
 140                 fprintf(stderr, "Unable to open DCHAN %d for span %d (%s)\n", dchan, span, strerror(errno));
 141         } else {
 142                 if ((spri->pri = pri_new_cb(spri->zdchan->sockfd, node, swtype, __pri_sangoma_read, __pri_sangoma_write, spri))){
 143                         spri->span = span;
 144                         pri_set_debug(spri->pri, debug);
 145                         ret = 0;
 146                 } else {
 147                         fprintf(stderr, "Unable to create PRI\n");
 148                 }
 149         }
 150         return ret;
 151 }
 152 
 153 
 154 int sangoma_one_loop(struct sangoma_pri *spri)
 155 {
 156         fd_set rfds, efds;
 157         struct timeval now = {0,0}, *next;
 158         pri_event *event;
 159     int sel;
 160         
 161         if (spri->on_loop) {
 162                 spri->on_loop(spri);
 163         }
 164 
 165         FD_ZERO(&rfds);
 166         FD_ZERO(&efds);
 167 
 168 #ifdef _MSC_VER
 169         //Windows macro for FD_SET includes a warning C4127: conditional expression is constant
 170 #pragma warning(push)
 171 #pragma warning(disable:4127)
 172 #endif
 173 
 174         FD_SET(spri->pri->fd, &rfds);
 175         FD_SET(spri->pri->fd, &efds);
 176 
 177 #ifdef _MSC_VER
 178 #pragma warning(pop)
 179 #endif
 180 
 181         if ((next = pri_schedule_next(spri->pri))) {
 182                 gettimeofday(&now, NULL);
 183                 now.tv_sec = next->tv_sec - now.tv_sec;
 184                 now.tv_usec = next->tv_usec - now.tv_usec;
 185                 if (now.tv_usec < 0) {
 186                         now.tv_usec += 1000000;
 187                         now.tv_sec -= 1;
 188                 }
 189                 if (now.tv_sec < 0) {
 190                         now.tv_sec = 0;
 191                         now.tv_usec = 0;
 192                 }
 193         }
 194 
 195         sel = select(spri->pri->fd + 1, &rfds, NULL, &efds, next ? &now : NULL);
 196         event = NULL;
 197 
 198         if (!sel) {
 199                 event = pri_schedule_run(spri->pri);
 200         } else if (sel > 0) {
 201                 event = pri_check_event(spri->pri);
 202         }
 203 
 204         if (event) {
 205                 event_handler handler;
 206                 /* 0 is catchall event handler */
 207                 if ((handler = spri->eventmap[event->e] ? spri->eventmap[event->e] : spri->eventmap[0] ? spri->eventmap[0] : NULL)) {
 208                         handler(spri, event->e, event);
 209                 } else {
 210                         fprintf(stderr,"No event handler found for event %d.\n", event->e);
 211                 }
 212         }
 213 
 214         return sel;
 215 }
 216 
 217 int sangoma_run_pri(struct sangoma_pri *spri)
 218 {
 219         int ret = 0;
 220 
 221         for (;;){
 222                 ret=sangoma_one_loop(spri);
 223                 if (ret < 0){
 224 
 225 #ifndef WIN32 //This needs to be adressed fror WIN32 still
 226                         if (errno == EINTR){
 227                                 /* Igonore an interrupted system call */
 228                                 continue;
 229                         }
 230 #endif  
 231                         printf("Error = %i\n",ret);
 232                         perror("Sangoma Run Pri: ");
 233                         break;          
 234                 }
 235         }
 236 
 237         return ret;
 238 
 239 }
 240 
 241 /* For Emacs:
 242  * Local Variables:
 243  * mode:c
 244  * indent-tabs-mode:t
 245  * tab-width:4
 246  * c-basic-offset:4
 247  * End:
 248  * For VIM:
 249  * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
 250  */
 251 

/* [<][>][^][v][top][bottom][index][help] */