#linux cブロードキャストストリームメディアファイル(トークンバケツ)


ソース:https://github.com/FzhangSpace/net_radio.git
(一)概要
     ,       ,       ,     200   ,         ,        ,                  ,    mpg123  

(二)モジュール区分
送信側
      :
          ,     ,          ,         

        :
                 

        :
                                   

   :
               ,                            

           

     

(三)実現の詳細
3.0送受信時のパケット構造
./src/include/proto.h
./src/include/site_types.h
#defien CHNNR   200 /*      */

#define LISTCHNID       0   /*         */
#define MINCHNID        1   /*       */
#define MAXCHNID        (MINCHNID+CHNNR-1)  /*       */

#define MSG_CHANNEL_MAX    (65536-20-8) /*          */
typedef uint8_t chnid_t;    /*     */

/*            */
struct msg_channel_st {
    chnid_t     id; /* MUST BETWEEN [MINCHIND, MAXCHIND]     */
    uint8_t     data[1];    /*      ,           */    
} __attribute__((packed));  
/*           ,       ,          */

#define MSG_LIST_MAX    (65536-20-8)    
struct msg_listentry_st {   /*                   */
    chnid_t     id; /* MUST BETWEEN [MINCHIND, MAXCHIND]     */
    uint16_t    len;    /*           ,            */
    uint8_t     desrc[1];   /*     ,           */
} __attribute__((packed));

/*    */
struct msg_list_st {    /*          */
    chnid_t     id; /* MUST BE LISTCHNID      */     
    struct msg_listentry_st entry[1];   /*               ,            */
} __attribute__((packed));

新しく出会った関数や使い方
          ,         ,        ,              
                 ,           ,                 
struct list {
    struct list *next;
    char data[0];
};
 32  ,sizeof(struct list) 4   ,data      ,   0   ,  data       struct list      ,        
struct list *ptr = malloc(sizeof(struct list)+20);
              20    ,    data           ,                     

3.1トークンバケツ
./src/server/mytbf.h     
./src/server/mytbf.c 

           ,      ,                ,             , 
          (burst),          (  )(cps),          (token);
          ,    cps   
/*         */
    struct mytbf_st {
        int cps;    /*        */
        int burst;  /*         */
        int token;  /*           */
        pthread_mutex_t mut; /*  token     */
        pthread_cond_t  cond;   /*      ,         ,            */
    };
tpyedef void mytbf_t;   //        

static struct mytbf_st *tbf[TBFMAX];    /*         */
static pthread_mutex_t mut_tbf = PTHREAD_MUTEX_INITIALIZER;           
static pthread_t tid_timer;
static pthread_once_t init_once = PTHREAD_ONCE_INIT;

mytbf_t *mytbf_init(int cps, int burst); //       ,        cps burst
    static void module_load(void);  //      ,
        static void *thr_timer_func(void *unused);   //                 
        static void *module_unload(void);   //         ,    atexit   ,        
    static int get_free_pos();  //                   
            ,    

int mytbf_fetchtoken(mytbf_t *,int n); //       ,      ,             

int mytbf_returntoken(mytbf_t *, int n); //          ,        

int mytbf_destroy(mytbf_t *); //     
                    ,           ,             ,                  ,    ,    .
  ,                   ,      

新しく出会った関数や使い方
    //    
    struct timespec t;
    t.tv_sec = 1;   //m
    t.tv_nsec = 0;  //ns

    /*            ,               ,      ,     ,  1s     ,     */
    while (nanosleep(&t, &t) != 0) {    
        if (errno != EINTR) {
            syslog(LOG_ERR, "nanosleep(): %s", strerror(errno));
            exit(1);
        }   
    }   

    //              (   void,    )
    int atexit(void (*function)(void));

    //      ,         (   void,    )
    pthread_once_t once_control = PTHREAD_ONCE_INIT;
    int pthread_once(pthread_once_t *once_control,
              void (*init_routine)(void));

3.2メディアリソース処理モジュール
./src/server/medialib.c  
./src/server/medialib.h
           ./tmp/media   ,       ,      .MP3      desc.test  (    ),                       ,      200 
    /*         */
struct mlib_listentry_st {      /*             */
    chnid_t   id;       //  id
    char    *desc;      //     ,   desc.test    
};

struct channel_context_st { /*          */
    chnid_t     id;     //  id
    char        *desc;  //    
    glob_t      mp3glob;    //             ("*.mp3")       
    int         pos;    //         mp3glob        
    off_t       offset;     //           
    int         fd;     //          
    mytbf_t     *tbf;   //           
};
/***************API**********/

static struct channel_context_st channel[MAXCHNID+1];   //              


/*         ,                 */
int mlib_getchnlist(struct mlib_listentry_st **, int *);    
    static struct channel_context_st *path2entry(const char *path)  //                ,                  
        mytbf_t *mytbf_init(int cps, int burst);    //           

//               ,  buf ,         
ssize_t mlib_readchn(chnid_t cid, void* buf, ssize_t len);  
    int mytbf_fetchtoken(mytbf_t *,int n); //       ,          
    static int open_next(chnid_t id);   //  read    0,      ,         
    int mytbf_returntoken(mytbf_t *, int n); //      ,         ,    

int mlib_freechnlist(struct mlib_listentry_st *);   //  channel    
       

`int mlib_getchnlist(struct mlib_listentry_st **result, int *resnum)`
      `snprintf(path, PATHSIZE, "%s/*", server_conf.media_dir)`;      "/var/media/*"        ,`server_conf.media_dir`           ("/var/media")(    )

       `glob(path, 0, NULL, &globres)`                 ,  `globres`  

       `globres.gl_pathc`                        , malloc          

        `globres.gl_pathv[i]`,  `globres.gl_pathc`,            ,
           `res = path2entry(globres.gl_pathv[i]);`         (id,  ,      ),
           path2entry        `mlib_listentry_st`,        
                       .


`ssize_t mlib_readchn(chnid_t cid, void* buf, ssize_t len);`       
    `tbfsize = mytbf_fetchtoken(channel[id].tbf, size);`   ;       
    `len = pread(channel[id].fd, buf, tbfsize, channel[id].offset);`  offset         
    `mytbf_returntoken(channel[id].tbf, tbfsize-len);`         

新しく出会った関数や使い方
#include 
int glob(const char *pattern, int flags,
         int (*errfunc) (const char *epath, int eerrno),
         glob_t *pglob);

typedef struct {
    size_t   gl_pathc;    /*gl_pathv                Count of paths matched so far  */
    char   **gl_pathv;    /*        List of matched pathnames.  */
    size_t   gl_offs;     /* Slots to reserve in `gl_pathv'.  GLOB_DOOFS    */
} glob_t;
/*  glob        pattern    , /*            (       ,             ),
                pglob,  4    ,            ,     ,
               ,          pglob  ,            ,    NULL;
      glob                    
 */


#include 
char *strdup(const char *s);
    strdup   malloc()     s          ,     s              ,
         .           free   

ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset);
     read   ,    offset            ,          

3.3メニュー送信モジュール
./src/server/thr_list.h     
./src/server/thr_list.c 
                          ,    
/*          */
int thr_list_create(struct mlib_listentry_st *listp, int nr_ent)
     listp nr_ent         ,            
            struct mlib_listentry_st      ,              struct msg_list_st
            listp  struct msg_list_st          .  malloc  
                 
                1s

3.4メニュー送信モジュール
                     
int thr_channel_create(struct mlib_listentry_st *ptr)
            
    static void *thr_channel_func(void *ptr)
          len = mlib_readchn(ent->id, sbufp->data, datasize);        ,    

新しく出会った関数や使い方
#include  
int sched_yield(void);
          ,     CPU   ,         

(四)プログラムの主体
       
int serversd;   //socket     ,   
struct sockaddr_in sndaddr; //    

//          ,  server_conf.h  proto.h   ,
struct server_conf_st server_conf = {   
    .rcvport = DEFAULT_RCVPORT, //  
    .mgroup = DEFAULT_MGROUP,   //  ip
    .media_dir = DEFAULT_MEDIADIR,  //    
    .ifname = DEFAULT_IF,   //   'eth0'
    .runmode = run_daemon   //    
};
       

1.          
2.        ,     server_conf  
3.         
4. socket     ,  socket  ,UPD,    ,   ,     ,
5.         ,      , mlib_getchnlist
6.          
7.                
8.      ,              ,        

新しく出会った関数や使い方
              ,                
//           ,                
#include  
void openlog(const char *ident, int option, int facility);  //    ,            ,     
void syslog(int priority, const char *format, ...); //     ,(   ,  )====>printf
void closelog(void); //  


#include 

int getopt(int argc, char * const argv[],
           const char *optstring);
extern char *optarg;

        

(四)総括
               ,       .
           ,         ,         ,         ,           ;          ,
                   ,        ,    ,           ,   BUG     .
               ,         ,               ,
                      ,              .
                       ,               ,               ,
                  ,                   ,        ,     .
         ,           ,                ,     ,            ,
                 .
          ,             ,             ,       ,        
            ,                     static   ,           API      .
        ,  malloc          ,  free,