Logo Search packages:      
Sourcecode: tucnak2 version File versions  Download package

dxc.c

/*
    Tucnak - VHF contest log
    Copyright (C) 2002-2006  Ladislav Vaiz <ok1zia@nagano.cz>

    This program is free software; you can redistribute it and/or                                                        
    modify it under the terms of the GNU General Public License                                                          
    version 2 as published by the Free Software Foundation.

*/

#include <header.h>
void dxc_dump(struct spotdb *spotdb, int bi);

#define MIN_SPOTLEN 74
#define STR_DX_DE "DX de"
#define FROM_OFS 6
#define CALL_OFS 26
#define TEXT_OFS 39
#define ZULU_OFS 70

#define FROM_SEP ' '
#define DXC_EXPIRE_TIMER 5*60*1000

struct spotdb *spotdb=NULL;


struct spotdb *init_spotdb(){
    struct spotdb *spotdb;

    spotdb=g_new0(struct spotdb, 1);
    spotdb->first=g_new0(struct spot *, cfg->bands->len);
    spotdb->cur  =g_new0(struct spot *, cfg->bands->len);
    spotdb->timer_id=install_timer(DXC_EXPIRE_TIMER, dxc_timer, CBA0);
    return spotdb;
}

void free_spotdb(struct spotdb *spotdb){
    struct spot *spot;
    int bi,n;
    
    kill_timer(spotdb->timer_id);
    n=0;
    for (bi=0;bi<cfg->bands->len;bi++){
        for (spot=spotdb->first[bi]; spot; ){
            /*dbg("spot=%s qrg=%3.1f\n", spot->callsign, spot->qrg);*/
            struct spot *tofree;
            
            remove_spot(spotdb, bi, spot);
            tofree=spot;
            if (!spot->next){
                spot=spot->prev; /* removing last, new last will be spot->prev */
                free_spot(tofree);
                n++;
                break;
            }else{
              spot=spot->next;
              free_spot(tofree);
              continue;
            }

            if (!spot->next) break;
            spot=spot->next;
        }
    }
    g_free(spotdb->first);
    g_free(spotdb->cur);
    g_free(spotdb);
}

void dxc_timer(union cba_t cba){
    int n;
    n=dxc_remove_expired();
    /*dbg("dxc_timer expired=%d\n",n);*/
    if (n){
        redraw_later();
    }
    
    spotdb->timer_id=install_timer(DXC_EXPIRE_TIMER, dxc_timer, CBA0);
}


struct spot *dxc_parse_spot(gchar *str){
    double qrg;
    gchar *callsign,*from,*text;
    int zulu;
    struct spot *spot;
    gchar *c,*d;
    time_t now;

    
    if (strlen(str)<MIN_SPOTLEN) return NULL;
    if (strncasecmp(str, STR_DX_DE, strlen(STR_DX_DE))!=0) return NULL;

    callsign=from=text=NULL;
    
    d=str+FROM_OFS;
    c=index(d,FROM_SEP);
    
    if (!c) goto x;
    from=g_strndup(d, c-d);
    g_strdown(from);

    c++;
    qrg=strtod(c, (char **)NULL);

    d=str+CALL_OFS;
    c=index(d,' ');
    if (!c) goto x;
    callsign=g_strndup(d, c-d);
    if (strlen(callsign)<3) goto x;

    d=str+ZULU_OFS;
    d[4]='\0';
    zulu=atoi(d);

    d=str+TEXT_OFS;
    str[ZULU_OFS]='\0';
    c=rindex(d, ' ');
    g_strstrip(d);
    if (!c) c=d+ZULU_OFS-1;
    text=g_strndup(d, c-d);

    now=time(NULL);
    
    spot=g_new0(struct spot, 1); /* LEAK */
    spot->qrg     =qrg;
    spot->callsign=callsign;
    spot->from    =from;
    spot->text    =text;
    spot->zulu    =zulu;
#if 1    
    spot->endbold =now + 15 * 60;
    spot->expire  =now + 60 * 60;
#else    
    spot->endbold =now + 1 * 60;
    spot->expire  =now + 2 * 60;
#endif    

    /*dbg("call='%s' qrg='%3.1f' from='%s' text='%s' zulu='%d'\n",
            callsign, qrg, from, text, zulu);*/
    return spot;    
x:;
    CONDGFREE(callsign);
    CONDGFREE(from);    
    CONDGFREE(text);    
    return NULL;
}  

void free_spot(struct spot *spot){
    /*dbg("free_spot(%p)\n", spot);*/
            
    if (!spot) return;

    g_free(spot->callsign);
    g_free(spot->from);
    g_free(spot->text);
    g_free(spot);
}

/* removes spot from list, don't free it from mem */
void remove_spot(struct spotdb *spotdb, int bi, struct spot *spot){
  /*  dbg("removing spot=%s qrg=%3.1f\n", spot->callsign, spot->qrg);*/
    
    if (spotdb->cur[bi]==spot){
        if (spot->prev) spotdb->cur[bi]=spot->prev;
        else            spotdb->cur[bi]=spot->next;
    }
    if (spot->prev)
        spot->prev->next = spot->next;
    else
        spotdb->first[bi] = spot->next; 
    
    if (spot->next)
        spot->next->prev = spot->prev;
}

int dxc_read_spot(gchar *str){
    struct spot *newspot,*spot,*newpos;
    gchar *s;
    int bi;
    struct config_band *confb;
    time_t now;
    
    /*dbg("dxc_read_spot('%s')\n", str);*/
    s=g_strdup(str);
    newspot=dxc_parse_spot(s);
    g_free(s);
    
    if (!newspot) return -3;
    
    /*dbg(" spot accepted %p\n", str, newspot);*/
    confb=get_config_band_by_qrg(newspot->qrg);
    if (!confb){
        free_spot(newspot);
        /*dbg(" bad qrg\n");*/
        return -1;
    }
    
    bi=lowcase(confb->bandchar)-'a';
    if (bi<0 || bi>=cfg->bands->len){
        free_spot(newspot);
/*        dbg(" bad band\n");   */
        return -2;
    }
    
    now=time(NULL);
    newpos=NULL;
    for (spot=spotdb->first[bi]; spot; ){
        /*dbg("spot=%s qrg=%3.1f\n", spot->callsign, spot->qrg);*/
        if (strcasecmp(spot->callsign, newspot->callsign)==0 ||
            spot->expire < now) {
            struct spot *tofree;
            
            remove_spot(spotdb, bi, spot);
            tofree=spot;
            if (!spot->next){
                spot=spot->prev; /* removing last, new last will be spot->prev */
                free_spot(tofree);
                break;
            }else{
              spot=spot->next;
              free_spot(tofree);
              continue;
            }
        }

        if (!newpos && newspot->qrg < spot->qrg){
            newpos=spot;  
        }
        if (!spot->next) break;
        spot=spot->next;
    }

    /* spot points to last spot in list or is NULL */
    if (!newpos){ /* newspot->freq is  maximal  */
        if (spot){ 
            spot->next = newspot;   /* adding to end */
            newspot->prev = spot;
        }else{
            spotdb->first[bi]=newspot; /* empty list */
            spotdb->cur[bi]  =newspot;
        }    
    }else{ /* adding into list before newpos */                 
        if (newpos->prev) 
            newpos->prev->next = newspot;
        else
            spotdb->first[bi] = newspot;
                
        newspot->prev    = newpos->prev;
        newspot->next    = newpos;
        newpos->prev     = newspot;
    }
    
/*    for (spot=spotdb->first[bi]; spot;spot=spot->next){
        dbg("%s\n", spot->callsign);
    }*/
#if 0    
    if (dump){
        dxc_dump(spotdb, bi);
    }
    if (bi==8){dbg("b: %p\n", spotdb->cur[bi]); }
    dxc_assert(spotdb, bi);
#endif    
    return spot!=NULL;
}

int dxc_remove_expired(void){
    struct spot *spot;
    int bi,n;
    time_t now;
    
    n=0;
    now=time(NULL);
    for (bi=0;bi<cfg->bands->len;bi++){
        for (spot=spotdb->first[bi]; spot; ){
            /*dbg("spot=%s qrg=%3.1f\n", spot->callsign, spot->qrg);*/
            if (spot->expire < now) {
                struct spot *tofree;
                
                remove_spot(spotdb, bi, spot);
                tofree=spot;
                if (!spot->next){
                    spot=spot->prev; /* removing last, new last will be spot->prev */
                    free_spot(tofree);
                    n++;
                    break;
                }else{
                  spot=spot->next;
                  free_spot(tofree);
                  continue;
                }
            }

            if (!spot->next) break;
            spot=spot->next;
        }
    }
    return n;
}

void dxc_seek(struct spotdb *spotdb, int value){
    int bi;
                
    if (!aband) return;
    bi=lowcase(aband->bandchar)-'a';

    if (value<0) {
        for (; 
             spotdb->cur[bi]->prev && value;
             spotdb->cur[bi]=spotdb->cur[bi]->prev, value++);
        return;
    }
    
    if (value>0) {
        for (; 
             spotdb->cur[bi]->next && value;
             spotdb->cur[bi]=spotdb->cur[bi]->next, value--);
        return;
    }

    
    if (value==0) { /* special value, seek to end */
        for (; 
             spotdb->cur[bi]->next;
             spotdb->cur[bi]=spotdb->cur[bi]->next);
        return;
    }
    
}

void dxc_assert_spot(struct spot *spot){
    if (!spot) return;
    g_assert(spot->qrg>=0 && spot->qrg<100000000000.0);
    g_assert(strlen(spot->callsign));
    g_assert(strlen(spot->from));
    g_assert(strlen(spot->text));
    g_assert(spot->zulu>=0 && spot->zulu<2400);
}

void dxc_assert(struct spotdb *spotdb, int bi){
    struct spot *spot;

    if (!spotdb->first[bi]) return;
    for (spot=spotdb->first[bi]; spot; spot=spot->next){
        dxc_assert_spot(spot);
        dxc_assert_spot(spot->prev);
    }
    dxc_assert_spot(spotdb->cur[bi]);
}

void dxc_dump(struct spotdb *spotdb, int bi){
    struct spot *spot;

    dbg("dxc_dump(%p, %d)\n", spotdb, bi);
    if (!spotdb->first[bi]) return;
    spot=spotdb->cur[bi];
/*    dbg("%p: %10s %10s %10.1f prev=%p  next=%p\n", spot, spot->from, spot->callsign, spot->qrg, spot->prev, spot->next);*/
    dbg("\n");
    for (spot=spotdb->first[bi]; spot; spot=spot->next){
        dbg("%p: %10s %10s %10.1f prev=%p  next=%p\n", spot, spot->from, spot->callsign, spot->qrg, spot->prev, spot->next);
    }
}



/*

0     6          17       26           39                             70  
DX de ja8edu:    21285.0  OK2SSD       CQ,CQ DX                       0759Z
DX de JA8EDU:    21285.0  OK2SSD       CQ,CQ DX                       0759Z
DX de HL2IFR:    24900.2  BA4ED        AS-136                         0807Z
DX de HL2IFR:    24900.2  BA4ED        AS-136                      33 0807Z 44
DX de JA9LSZ:    28008.2  8Q7VR        cq                             0815Z
DX de JA9LSZ:    28008.2  8Q7VR        cq                             0815Z
DX de OK1MZM:    144300.0 I4XCC        1116Z 55 JN63GV<---JN69QS
144370.0  SM/DJ8MS     5-Mar-2003 0801Z  cq 357 JO88 dir G            <DJ8MS>
144370.0  SM/DJ8MS     5-Mar-2003 0801Z  cq 357 JO88 dir G             <dj8ms>
 144370.0 SM/DJ8MS     0801  5.3  DJ8MS  cq 357 JO88 dir G
144370.0  SM/DJ8MS     5-Mar-2003 0801Z  cq 357 JO88 dir G            <DJ8MS>
 144370.0 SM/DJ8MS     0801  5.3  DJ8MS  cq 357 JO88 dir G
144370.0  SM/DJ8MS     5-Mar-2003 0801Z  cq 357 JO88 dir G            <DJ8MS>
144300.0 HB9QQ        1821 21.8  ON1AEN JN47 SRI TYPO 

 */

Generated by  Doxygen 1.6.0   Back to index