プログラミングインタフェース

第 3 章 セッション記述プロトコル API

セッション記述プロトコル (SDP) は、マルチメディアセッションを記述します。この章で説明する SDP API には、アプリケーションに SDP の機能を追加するために使用できる関数呼び出しが含まれます。

セッション記述 API の概要

SDP API を構成する関数呼び出しは、共有オブジェクト libcommputil.so.1 によって提供されます。この共有オブジェクト内の関数は、SDP 記述を解析し、記述の構文を確認します。

sdp.h ヘッダーファイルは、sdp_session_t 構造体を定義します。この構造体には次のメンバーが含まれます。

typedef    struct sdp_session {
   int             sdp_session_version; /* SDP session verstion */
   int             s_version;           /* SDP version field */
   sdp_origin_t    *s_origin;           /* SDP origin field */
   char            *s_name;             /* SDP name field */
   char            *s_info;             /* SDP info field */
   char            *s_uri;              /* SDP uri field */
   sdp_list_t      *s_email;            /* SDP email field */
   sdp_list_t      *s_phone;            /* SDP phone field */
   sdp_conn_t      *s_conn;             /* SDP connection field */
   sdp_bandwidth_t *s_bw;               /* SDP bandwidth field */
   sdp_time_t      *s_time;             /* SDP time field */
   sdp_zone_t      *s_zone;             /* SDP zone field */
   sdp_key_t       *s_key;              /* SDP key field */
   sdp_attr_t      *s_attr;             /* SDP attribute field */
   sdp_media_t     *s_media;            /* SDP media field */
} sdp_session_t;

sdp_session_version メンバーは、構造体のバージョンを追跡します。sdp_session_version メンバーの初期値は SDP_SESSION_VERSION_1 です。

sdp_origin_t 構造体には次のメンバーが含まれます。

typedef struct sdp_origin {
   char        *o_username;  /* username of the originating host */
   uint64_t    o_id;         /* session id */
   uint64_t    o_version;    /* version number of this session */
                             /* description */
   char        *o_nettype;   /* type of network */
   char        *o_addrtype;  /* type of the address */
   char        *o_address;   /* address of the machine from which */
                             /* session was created */
} sdp_origin_t;

sdp_conn_t 構造体には次のメンバーが含まれます。

typedef struct sdp_conn {
   char    *c_nettype;         /* type of network */
   char    *c_addrtype;        /* type of the address */
   char    *c_address;         /* unicast-address or multicast */
                               /* address */
   int     c_addrcount;        /* number of addresses (case of */
                               /* multicast address with layered */
                               /* encodings */
   struct  sdp_conn *c_next;   /* pointer to next connection */
                               /* structure; there could be several */
                               /* connection fields in SDP description */
   uint8_t c_ttl;              /* TTL value for IPV4 multicast address */
} sdp_conn_t;

sdp_bandwidth_t 構造体には次のメンバーが含まれます。

typedef struct sdp_bandwidth {
   char                  *b_type; /* info needed to interpret b_value */
   uint64_t              b_value; /* bandwidth value */
   struct sdp_bandwidth  *b_next; /* pointer to next bandwidth structure*/
                                  /* (there could be several bandwidth */
                                  /* fields in SDP description */
} sdp_bandwidth_t;

sdp_list_t 構造体は、void ポインタのリンクリストです。この構造体は SDP フィールドを保持します。emailphone などの SDP 構造体フィールドの場合は、void ポインタは文字バッファーを指します。offset フィールドが繰り返される場合のように、要素の数が事前に定義されていない場合は、この構造体を使用して情報を保持します。その場合、void ポインタは整数値を保持します。

sdp_list_t 構造体には次のメンバーが含まれます。

typedef struct sdp_list {
   void            *value; /* string values in case of email, phone and */
                           /* format (in media field) or integer values */
                           /* in case of offset (in repeat field) */
   struct sdp_list *next;  /* pointer to the next node in the list */
} sdp_list_t;

sdp_repeat_t 構造体は、時間構造体 sdp_time_t に必ず含まれます。repeat フィールドが SDP 記述に単独で現れることはなく、常に time フィールドに関連付けられています。

sdp_repeat_t 構造体には次のメンバーが含まれます。

typedef struct sdp_repeat {
   uint64_t          r_interval; /* repeat interval, e.g. 86400 seconds */
                                 /* (1 day) */
   uint64_t          r_duration; /* duration of session, e.g. 3600 */
                                 /* seconds (1 hour) */
   sdp_list_t        *r_offset;  /* linked list of offset values; each */
                                 /* represents offset from start-time */
                                 /* in the SDP time field */
   struct sdp_repeat *r_next;    /* pointer to next repeat structure; */
                                 /* there could be several repeat */
                                 /* fields in the SDP description */

sdp_time_t 構造体には次のメンバーが含まれます。

typedef struct sdp_time {
   uint64_t         t_start;   /* start-time for a session */
   uint64_t         t_stop;    /* end-time for a session */
   sdp_repeat_t     *t_repeat; /* points to the SDP repeat field */
   struct sdp_time  *t_next;   /* pointer to next time field; there */
                               /* could there could be several time */
                               /* fields in SDP description */
} sdp_time_t;

sdp_zone_t 構造体には次のメンバーが含まれます。

typedef struct sdp_zone {
   uint64_t        z_time;    /* base time */
   char            *z_offset; /* offset added to z_time to determine */
                              /* session time; mainly used for daylight */
                              /* saving time conversions */
   struct sdp_zone *z_next;   /* pointer to next zone field; there */
                              /* could be several <adjustment-time> */
                              /* <offset> pairs within a zone field */
} sdp_zone_t;

sdp_key_t 構造体には次のメンバーが含まれます。

typedef struct sdp_key {
   char   *k_method;   /* key type */
   char   *k_enckey;   /* encryption key */
 } sdp_key_t;

sdp_attr_t 構造体には次のメンバーが含まれます。

typedef struct sdp_attr {
   char            *a_name;  /* name of the attribute */
   char            *a_value; /* value of the attribute */
   struct sdp_attr *a_next;  /* pointer to the next attribute */
                             /* structure; there could be several */
                             /* attribute fields within SDP description */
} sdp_attr_t;

sdp_media_t 構造体には次のメンバーが含まれます。

typedef struct sdp_media {
   char              *m_name;     /* name of the media such as "audio", */
                                  /* "video", "message" */
   uint_t            m_port;      /* transport layer port information */
   int               m_portcount; /* number of ports in case of */
                                  /* hierarchically encoded streams */
   char              *m_proto;    /* transport protocol */
   sdp_list_t        *m_format;   /* media format description */
   char              *m_info;     /* media info field */
   sdp_conn_t        *m_conn;     /* media connection field */
   sdp_bandwidth_t   *m_bw;       /* media bandwidth field */
   sdp_key_t         *m_key;      /* media key field */
   sdp_attr_t        *m_attr;     /* media attribute field */
   struct sdp_media  *m_next;     /* pointer to next media structure; */
                                  /* there could be several media */
                                  /* sections in SDP description */
   sdp_session_t     *m_session;  /* pointer to the session structure */
} sdp_media_t;

SDP ライブラリ関数

API ライブラリ関数は次の操作をサポートします。

SDP セッション構造体の作成

新しい SDP セッション構造体を作成するには、最初に sdp_new_session() 関数を呼び出して新しい構造体用のメモリーを割り当てます。この関数は新しいセッション構造体へのポインタを返します。この節に示すほかの関数は、このポインタを使用して新しいセッション構造体を作成します。新しいセッション構造体を作成したら、sdp_session_to_str() 関数を使用してセッション構造体を文字列表現に変換します。

新しい SDP セッション構造体の作成

sdp_session_t *sdp_new_session();

sdp_new_session() 関数は、session パラメータで指定された新しい SDP セッション構造体用のメモリーを割り当て、新しい構造体にバージョン番号を割り当てます。セッション構造体に割り当てられたメモリーは、sdp_free_session() 関数を呼び出すことで解放できます。

戻り値: sdp_new_session() 関数は、関数が正常に完了したときに、新しく割り当てられた SDP セッション構造体を返します。エラー発生時には NULL を返します。

SDP セッション構造体への発信元フィールドの追加

int sdp_add_origin(sdp_session_t *session, const char *name, uint64_t id, uint64_t ver, const char *nettype, const char *addrtype, const char *address);

sdp_add_origin() 関数は、nameidvernettypeaddrtypeaddress の各パラメータを使用して、session パラメータの値で指定されたセッション構造体 (sdp_session_t) に Origin (o=) SDP フィールドを追加します。

戻り値: sdp_add_origin() 関数は、関数が正常に完了したときに 0 を返します。必須のパラメータがなかった場合は、EINVAL を返します。メモリーの割り当てに失敗した場合は、ENOMEM を返します。errno の値は、エラーが発生した場合でも変化しません。

SDP セッション構造体への名前フィールドの追加

int sdp_add_name(sdp_session_t *session, const char *name);

sdp_add_name() 関数は、name パラメータを使用して、session パラメータの値で指定されたセッション構造体 (sdp_session_t) に SessionName (s=) SDP フィールドを追加します。

戻り値: sdp_add_name() 関数は、関数が正常に完了したときに 0 を返します。必須のパラメータがなかった場合は、EINVAL を返します。メモリーの割り当てに失敗した場合は、ENOMEM を返します。errno の値は、エラーが発生した場合でも変化しません。

SDP セッション構造体への情報フィールドの追加

int sdp_add_information(char **information, const char *value);

sdp_add_information() 関数は、value パラメータを使用して、セッション構造体 (sdp_session_t) またはメディア構造体 (sdp_media_t) に Info (i=) SDP フィールドを追加します。このフィールドは、SDP 記述のメディアセクションまたはセッションセクションに格納されます。最初の引数として &session->s_info または &media->m_info を渡すことにより、セクションを指定する必要があります。

戻り値: sdp_add_information() 関数は、関数が正常に完了したときに 0 を返します。必須のパラメータがなかった場合は、EINVAL を返します。メモリーの割り当てに失敗した場合は、ENOMEM を返します。errno の値は、エラーが発生した場合でも変化しません。

SDP セッション構造体への URI フィールドの追加

int sdp_add_uri(sdp_session_t *session, const char *uri);

sdp_add_uri() 関数は、uri パラメータを使用して、session パラメータの値で指定されたセッション構造体 (sdp_session_t) に URI (u=) SDP フィールドを追加します。

戻り値: sdp_add_uri() 関数は、関数が正常に完了したときに 0 を返します。必須のパラメータがなかった場合は、EINVAL を返します。メモリーの割り当てに失敗した場合は、ENOMEM を返します。errno の値は、エラーが発生した場合でも変化しません。

SDP セッション構造体への電子メールフィールドの追加

int sdp_add_email(sdp_session_t *session, const char *email);

sdp_add_email() 関数は、email パラメータを使用して、session パラメータの値で指定されたセッション構造体 (sdp_session_t) に Email (e=) SDP フィールドを追加します。

戻り値: sdp_add_email() 関数は、関数が正常に完了したときに 0 を返します。必須のパラメータがなかった場合は、EINVAL を返します。メモリーの割り当てに失敗した場合は、ENOMEM を返します。errno の値は、エラーが発生した場合でも変化しません。

SDP セッション構造体への電話フィールドの追加

int sdp_add_phone(sdp_session_t *session, const char *email);

sdp_add_phone() 関数は、phone パラメータを使用して、session パラメータの値で指定されたセッション構造体 (sdp_session_t) に Phone (p=) SDP フィールドを追加します。

戻り値: sdp_add_phone() 関数は、関数が正常に完了したときに 0 を返します。必須のパラメータがなかった場合は、EINVAL を返します。メモリーの割り当てに失敗した場合は、ENOMEM を返します。errno の値は、エラーが発生した場合でも変化しません。

SDP セッション構造体への接続フィールドの追加

int sdp_add_connection(sdp_conn_t **conn, const char *nettype, const char *addrtype, const char *address, uint8_t ttl, int addrcount);

sdp_add_connection() 関数は、nettypeaddrtypeaddressttladdrcount の各パラメータを使用して、セッション構造体 (sdp_session_t) またはメディア構造体 (sdp_media_t) に Connection (c=) SDP フィールドを追加します。IPv4 または IPv6 のユニキャストアドレスの場合は、ttl パラメータと addrcount パラメータの値をゼロに設定します。マルチキャストアドレスの場合は、ttl パラメータの値を 0 - 255 の範囲に設定します。マルチキャストアドレスの場合は、addrcount パラメータの値をゼロに設定できません。

このフィールドは、SDP 記述のメディアセクションまたはセッションセクションに格納されます。最初の引数として &session->s_info または &media->m_info を渡すことにより、セクションを指定する必要があります。

戻り値: sdp_add_connection() 関数は、関数が正常に完了したときに 0 を返します。必須のパラメータがなかった場合は、EINVAL を返します。メモリーの割り当てに失敗した場合は、ENOMEM を返します。errno の値は、エラーが発生した場合でも変化しません。

SDP セッション構造体への帯域幅フィールドの追加

int sdp_add_bandwidth(sdp_bandwidth_t **bw, const char *type, uint64_t value);

sdp_add_bandwidth() 関数は、type パラメータと value パラメータを使用して、セッション構造体 (sdp_session_t) またはメディア構造体 (sdp_media_t) に Bandwidth (b=) SDP フィールドを追加します。

このフィールドは、SDP 記述のメディアセクションまたはセッションセクションに格納されます。最初の引数として &session->s_info または &media->m_info を渡すことにより、セクションを指定する必要があります。

戻り値: sdp_add_bandwidth() 関数は、関数が正常に完了したときに 0 を返します。必須のパラメータがなかった場合は、EINVAL を返します。メモリーの割り当てに失敗した場合は、ENOMEM を返します。errno の値は、エラーが発生した場合でも変化しません。

SDP セッション構造体への時間フィールドの追加

int sdp_add_time(sdp_session_t *session, uint64_t starttime, uint64_t stoptime, sdp_time_t **time);

sdp_add_time() 関数は、starttime パラメータと stoptime パラメータの値を使用して、セッション構造体に Time (t=) SDP フィールドを追加します。この関数は、新しい時間構造体を作成し、time パラメータにその構造体へのポインタを返します。

戻り値: sdp_add_time() 関数は、関数が正常に完了したときに 0 を返します。必須のパラメータがなかった場合は、EINVAL を返します。メモリーの割り当てに失敗した場合は、ENOMEM を返します。errno の値は、エラーが発生した場合でも変化しません。

SDP セッション構造体への繰り返しフィールドの追加

int sdp_add_repeat(sdp_time_t *time, uint64_t interval, uint64_t duration, const char *offset);

sdp_add_repeat() 関数は、intervaldurationoffset の各パラメータの値を使用して、セッション構造体に RepeatTime (r=) SDP フィールドを追加します。offset パラメータの値は、1 つ以上のオフセット値を保持する文字列 (6060 1d 3h など) です。time パラメータの値は、sdp_add_time() 関数が作成する時間構造体へのポインタです。

戻り値: sdp_add_repeat() 関数は、関数が正常に完了したときに 0 を返します。必須のパラメータがなかった場合は、EINVAL を返します。メモリーの割り当てに失敗した場合は、ENOMEM を返します。errno の値は、エラーが発生した場合でも変化しません。

SDP セッション構造体へのゾーンフィールドの追加

int sdp_add_zone(sdp_session_t *session, uint64_t time, const char *offset);

sdp_add_zone() 関数は、time パラメータと offset パラメータを使用して、session パラメータの値で指定されたセッション構造体 (sdp_session_t) に TimeZoneAdjustment (z=) SDP フィールドを追加します。1 つのゾーンフィールドに対して複数の時間およびオフセットの値を追加するには、時間/オフセットのペアごとにこの関数を呼び出します。

戻り値: sdp_add_zone() 関数は、関数が正常に完了したときに 0 を返します。必須のパラメータがなかった場合は、EINVAL を返します。メモリーの割り当てに失敗した場合は、ENOMEM を返します。errno の値は、エラーが発生した場合でも変化しません。

SDP セッション構造体へのキーフィールドの追加

int sdp_add_key(sdp_key_t **key, const char *method, const char *enckey);

sdp_add_key() 関数は、method パラメータと enckey パラメータを使用して、セッション構造体 (sdp_session_t) またはメディア構造体 (sdp_media_t) に Key (k=) SDP フィールドを追加します。このフィールドは、SDP 記述のメディアセクションまたはセッションセクションに格納されます。最初の引数として &session->s_info または &media->m_info を渡すことにより、セクションを指定する必要があります。

戻り値: sdp_add_key() 関数は、関数が正常に完了したときに 0 を返します。必須のパラメータがなかった場合は、EINVAL を返します。メモリーの割り当てに失敗した場合は、ENOMEM を返します。errno の値は、エラーが発生した場合でも変化しません。

SDP セッション構造体への属性フィールドの追加

int sdp_add_attribute(sdp_attr_t **attr, const char *name, const char *value);

sdp_add_attribute() 関数は、name パラメータと value パラメータを使用して、セッション構造体 (sdp_session_t) またはメディア構造体 (sdp_media_t) に Attribute (a=) SDP フィールドを追加します。このフィールドは、SDP 記述のメディアセクションまたはセッションセクションに格納されます。最初の引数として &session->s_info または &media->m_info を渡すことにより、セクションを指定する必要があります。

戻り値: sdp_add_attribute() 関数は、関数が正常に完了したときに 0 を返します。必須のパラメータがなかった場合は、EINVAL を返します。メモリーの割り当てに失敗した場合は、ENOMEM を返します。errno の値は、エラーが発生した場合でも変化しません。

SDP セッション構造体へのメディアフィールドの追加

int sdp_add_media(sdp_session_t *session, const char *name, uint_t port, int portcount, const char *protocol, const char *format, sdp_media_t **media);

sdp_add_media() 関数は、nameportportcountprotocolformat の各パラメータの値を使用して、session パラメータの値で指定されたセッション構造体 (sdp_session_t) に Media (m=) SDP フィールドを追加します。format パラメータは、1 つ以上の値を保持する文字列 (0 32 97 など) です。

この関数は、新しいメディア構造体を作成し、media パラメータにその構造体へのポインタを返します。メディア構造体に SDP フィールドを追加する関数は、このポインタを使用します。

戻り値: sdp_add_media() 関数は、関数が正常に完了したときに 0 を返します。必須のパラメータがなかった場合は、EINVAL を返します。メモリーの割り当てに失敗した場合は、ENOMEM を返します。errno の値は、エラーが発生した場合でも変化しません。

コード例: SDP セッション構造体の作成

この例では、この節に示した関数を使用して、新しい SDP セッション構造体を作成し、構造体にフィールドを追加し、完成した構造体を文字列表現に変換します。この例では、最後にプログラムから sdp_free_session() 関数を呼び出して、セッションを解放します。


例 3–1 SDP セッション構造体の作成

/* SDP Message we will be building
"v=0\r\n\
o=Alice 2890844526 2890842807 IN IP4 10.47.16.5\r\n\
s=-\r\n\
i=A Seminar on the session description protocol\r\n\
u=http://www.example.com/seminars/sdp.pdf\r\n\
e=alice@example.com (Alice Smith)\r\n\
p=+1 911-345-1160\r\n\
c=IN IP4 10.47.16.5\r\n\
b=CT:1024\r\n\
t=2854678930 2854679000\r\n\
r=604800 3600 0 90000\r\n\
z=2882844526 -1h 2898848070 0h\r\n\
a=recvonly\r\n\
m=audio 49170 RTP/AVP 0\r\n\
i=audio media\r\n\
b=CT:1000\r\n\
k=prompt\r\n\
m=video 51372 RTP/AVP 99 90\r\n\
i=video media\r\n\
a=rtpmap:99 h232-199/90000\r\n\
a=rtpmap:90 h263-1998/90000\r\n"
*/

#include stdio.h>
#include string.h>
#include errno.h>
#include sdp.h>

int main ()
{
   sdp_session_t  *my_sess;
   sdp_media_t    *my_media;
   sdp_time_t     *my_time;
   char *b_sdp;

   my_sess = sdp_new_session();
   if (my_sess == NULL) {
return (ENOMEM);
   }
   my_sess->version = 0;
   if (sdp_add_name(my_sess, "-") != 0)
goto err_ret;
   if (sdp_add_origin(my_sess, "Alice", 2890844526ULL, 2890842807ULL,
 "IN", "IP4", "10.47.16.5") != 0)
goto err_ret;
   if (sdp_add_information(&my_sess->s_info, "A Seminar on the session"
 "description protocol") != 0)
goto err_ret;
   if (sdp_add_uri (my_sess, "http://www.example.com/seminars/sdp.pdf")
 != 0)
goto err_ret;
   if (sdp_add_email(my_sess, "alice@example.com (Alice smith)") != 0)
goto err_ret;
   if (sdp_add_phone(my_sess, "+1 911-345-1160") != 0)
goto err_ret;
   if (sdp_add_connection(&my_sess->s_conn, "IN", "IP4", "10.47.16.5",
0, 0) != 0)
goto err_ret;
   if (sdp_add_bandwidth(&my_sess->s_bw, "CT", 1024) != 0)
goto err_ret;
   if (sdp_add_time(my_sess, 2854678930ULL, 2854679000ULL, &my_time)
!= 0)
goto err_ret;
   if (sdp_add_repeat(my_time, 604800ULL, 3600ULL, "0 90000") != 0)
goto err_ret;
   if (sdp_add_zone(my_sess, 2882844526ULL, "-1h") != 0)
goto err_ret;
   if (sdp_add_zone(my_sess, 2898848070ULL, "0h") != 0)
goto err_ret;
   if (sdp_add_attribute(&my_sess->s_attr, "sendrecv", NULL) != 0)
goto err_ret;
   if (sdp_add_media(my_sess, "audio", 49170, 1, "RTP/AVP",
"0", &my_media) != 0)
goto err_ret;
   if (sdp_add_information(&my_media->m_info, "audio media") != 0)
goto err_ret;
   if (sdp_add_bandwidth(&my_media->m_bw, "CT", 1000) != 0)
goto err_ret;
   if (sdp_add_key(&my_media->m_key, "prompt", NULL) != 0)
goto err_ret;
   if (sdp_add_media(my_sess, "video", 51732, 1, "RTP/AVP",
 "99 90", &my_media) != 0)
goto err_ret;
   if (sdp_add_information(&my_media->m_info, "video media") != 0)
goto err_ret;
   if (sdp_add_attribute(&my_media->m_attr, "rtpmap",
      "99 h232-199/90000") != 0)
goto err_ret;
   if (sdp_add_attribute(&my_media->m_attr, "rtpmap",
      "90 h263-1998/90000") != 0)
goto err_ret;
   b_sdp = sdp_session_to_str(my_sess, &error);

   /*
    * b_sdp is the string representation of my_sess structure
    */

   free(b_sdp);
   sdp_free_session(my_sess);
   return (0);
err_ret:
   free(b_sdp);
   sdp_free_session(my_sess);
   return (1);
}

SDP セッション構造体の検索

この節に示す関数は、SDP セッション構造体から特定の値を検索し、見つかった値へのポインタを返します。

SDP セッション構造体内の属性の検索

sdp_attr_t *sdp_find_attribute (sdp_attr_t *attr, const char *name);

sdp_find_attribute() 関数は、attr パラメータで指定された属性リストから、name パラメータで指定された属性名を検索します。

戻り値: sdp_find_attribute() 関数は、関数が正常に完了したときに、name パラメータで指定された属性へのポインタ (sdp_attr_t *) を返します。それ以外の場合、sdp_find_attribute() 関数は NULL 値を返します。


例 3–2 sdp_find_attribute() 関数の使用

この例では、不完全な SDP 記述にオーディオセクションが含まれています。

m=audio 49170 RTP/AVP 0 8
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=sendonly
a=ptime:10000
a=maxptime:20000

/*
* Assuming that above description is parsed using sdp_parse and that
* the parsed structure is in "session" sdp_session_t structure.
*/

sdp_attr_t *ptime;
sdp_attr_t *max_ptime;
sdp_media_t *media = session->s_media;

if ((ptime = sdp_find_attribute(media->m_attr, "ptime")) == NULL)
/* ptime attribute not present */
else if((max_ptime = sdp_find_attribute(media->m_attr,
 "maxptime")) == NULL)
/* max_ptime attribute not present */

SDP セッション構造体内のメディアの検索

sdp_media_t *sdp_find_media(sdp_media_t *media, const char *name);

sdp_find_media() 関数は、media パラメータで指定されたメディアリストから、name パラメータで指定されたメディアエントリを検索します。

戻り値: sdp_find_media() 関数は、関数が正常に完了したときに、name パラメータで指定されたメディアリストエントリへのポインタ (sdp_media_t *) を返します。それ以外の場合、sdp_find_media() 関数は NULL 値を返します。


例 3–3 sdp_find_media() 関数の使用

この例では、不完全な SDP 記述に 2 つのセクション (オーディオセクションとビデオセクション) が含まれています。

m=audio 49170 RTP/AVP 0 8
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
m=video 51372 RTP/AVP 31 32
a=rtpmap:31 H261/90000
a=rtpmap:32 MPV/90000

/*
* Assuming that above description is parsed using sdp_parse() and that
* the parsed structure is in "session" sdp_session_t structure.
*/

sdp_media_t     *my_media;
my_media = sdp_find_media(session->s_media, "video");

/*
* my_media now points to the structure containg video media section
* information
*/

SDP セッション構造体内のメディア形式の検索

sdp_attr_t *sdp_find_media_rtpmap (sdp_media_t *media, const char *format);

sdp_find_media_rtpmap() 関数は、media パラメータで指定されたメディア構造体の属性リストから、format パラメータで指定された形式エントリを検索します。

戻り値: sdp_find_media_rtpmap() 関数は、関数が正常に完了したときに、name パラメータで指定された形式エントリへのポインタ (sdp_attr_t *) を返します。それ以外の場合、sdp_find_media() 関数は NULL 値を返します。


例 3–4 sdp_find_media_rtpmap() 関数の使用

この例では、不完全な SDP 記述に 2 つのセクション (オーディオセクションとビデオセクション) が含まれています。

m=audio 49170 RTP/AVP 0 8
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
m=video 51372 RTP/AVP 31 32
a=rtpmap:31 H261/90000
a=rtpmap:32 MPV/90000

/*
* Assuming that above description is parsed using sdp_parse() and that
* the parsed structure is in "session" sdp_session_t structure.
*/

sdp_media_t     *video;
sdp_attr_t      *mpv;

video = sdp_find_media(session->s_media, "video);
mpv = sdp_find_media_rtpmap(video, "32");

/*
* Now the attribute structure sdp_attr_t, mpv will be having
* values from the attribute field "a=rtpmap:32 MPV/90000"
*/

SDP セッション構造体のシャットダウン

この節に示す関数は、次の機能を実行します。

SDP セッション構造体からのフィールドの削除

int sdp_delete_all_field(sdp_session_t *session, const char field);

sdp_delete_all_field() 関数は、field パラメータで指定された SDP フィールドのすべての出現箇所を SDP 構造体から削除します。たとえば、SDP 構造体に 3 つの帯域幅 (b=) フィールドがある場合に、field パラメータに SDP_BANDWIDTH_FIELD という値を指定してこの関数を呼び出すと、セッション構造体から 3 つの 帯域幅フィールドがすべて削除されます。

戻り値: sdp_delete_all_field() 関数は、関数が正常に完了したときに 0 を返します。session 引数が NULL であるか、フィールドタイプが不明の場合は、EINVAL を返します。errno の値は、エラーが発生した場合でも変化しません。

SDP メディア構造体からのフィールドの削除

int sdp_delete_all_media_field(sdp_media_t *media, const char field);

sdp_delete_all_media_field() 関数は、field パラメータで指定された SDP フィールドのすべての出現箇所を SDP メディア構造体から削除します。

戻り値: sdp_delete_all_media_field() 関数は、関数が正常に完了したときに 0 を返します。session 引数が NULL であるか、フィールドタイプが不明の場合は、EINVAL を返します。errno の値は、エラーが発生した場合でも変化しません。

SDP メディア構造体からのメディアの削除

int sdp_delete_media(sdp_media_t **l_media, sdp_media_t *media);

sdp_delete_media() 関数は、media パラメータで指定されたメディアエントリをメディアリストから削除します。この関数は、sdp_find_media() 関数を使用して、指定されたメディアエントリを検索します。この関数は、メディアエントリを削除したあとで、メディア構造体に割り当てられていたメモリーを解放します。

戻り値: sdp_delete_media() 関数は、関数が正常に完了したときに 0 を返します。session 引数が NULL であるか、必須の引数が存在しない場合は、EINVAL を返します。errno の値は、エラーが発生した場合でも変化しません。

SDP メディア構造体からの属性の削除

int sdp_delete_attribute(sdp_attr_t **l_attr, sdp_attr_t *attr);

sdp_delete_attribute() 関数は、attr パラメータで指定された属性をメディアリストから削除します。この関数は、sdp_find_media_rtpmap() 関数または sdp_find_attribute() 関数を呼び出して、指定された属性を検索します。この関数は、属性を削除したあとで、属性構造体に割り当てられていたメモリーを解放します。

戻り値: sdp_delete_attribute() 関数は、関数が正常に完了したときに 0 を返します。session 引数が NULL であるか、必須の引数が存在しない場合は、EINVAL を返します。errno の値は、エラーが発生した場合でも変化しません。

SDP メディア構造体からの属性の削除

void sdp_free_session(sdp_session_t *session);

sdp_free_session() 関数は、session パラメータで指定されたセッションを破棄し、その構造体に関連付けられたリソースを解放します。

SDP API ユーティリティー関数

この節に示す関数は、SDP セッション構造体の解析と生成、既存セッションの複製、および既存セッションの文字列表現への変換を行います。

SDP セッション構造体の解析

int sdp_parse(const char *sdp_info, int len, int flags, sdp_session_t **session, uint_t *p_error);

sdp_parse() 関数は、sdp_info パラメータの SDP 記述を解析し、sdp_session_t 構造体を生成します。len パラメータは、文字バッファー sdp_info の長さを指定します。この関数は、sdp_session_t 構造体に必要なメモリーを割り当てます。このメモリーを解放するには、sdp_free_session() 関数を呼び出します。

flags パラメータの値は、ゼロに設定する必要があります。flags パラメータの値がゼロでない場合、sdp_parse() 関数は失敗し、戻り値として EINVAL を返し、*session の値を NULL に設定します。

p_error パラメータは、解析エラーが発生したフィールドの値を取ります。このパラメータの値が NULL になることはありません。p_error パラメータの取り得る値は、次のリストのとおりです。

SDP_VERSION_ERROR             0x00000001
SDP_ORIGIN_ERROR              0x00000002
SDP_NAME_ERROR                0x00000004
SDP_INFO_ERROR                0x00000008
SDP_URI_ERROR                 0x00000010
SDP_EMAIL_ERROR               0x00000020
SDP_PHONE_ERROR               0x00000040
SDP_CONNECTION_ERROR          0x00000080
SDP_BANDWIDTH_ERROR           0x00000100
SDP_TIME_ERROR                0x00000200
SDP_REPEAT_TIME_ERROR         0x00000400
SDP_ZONE_ERROR                0x00000800
SDP_KEY_ERROR                 0x00001000
SDP_ATTRIBUTE_ERROR           0x00002000
SDP_MEDIA_ERROR               0x00004000
SDP_FIELDS_ORDER_ERROR        0x00008000
SDP_MISSING_FIELDS            0x00010000

SDP 構造体のフィールドの順序が誤っており、RFC 4556 に違反している場合、sdp_parse() 関数は p_error パラメータの値を SDP_FIELDS_ORDER_ERROR に設定します。SDP 構造体に必須のフィールドがなく、RFC 4556 に違反している場合、sdp_parse() 関数は p_error パラメータの値を SDP_MISSING_FIELDS に設定します。

sdp_parse() 関数は、解析エラーがあるフィールドを処理したあとも解析を続行しますが、解析エラーがあったフィールドは、結果として得られる sdp_session_t 構造体に含まれません。

戻り値: sdp_parse() 関数は、関数が正常に完了したときに 0 を返します。session 引数が無効である場合、sdp_parse() 関数は EINVAL を返します。sdp_info の解析中にメモリー割り当てに失敗した場合、sdp_parse() 関数は ENOMEM を返します。errno の値は、エラーが発生した場合でも変化しません。


例 3–5 例: SDP セッション構造体の解析

この例で使用する SDP セッション構造体は次のとおりです。

v=0\r\n
o=jdoe 23423423 234234234 IN IP4 192.168.1.1\r\n
s=SDP seminar\r\n
i=A seminar on the session description protocol\r\n
e=test@host.com
c=IN IP4 156.78.90.1\r\n
t=2873397496 2873404696\r\n

sdp_parse_t() 関数を呼び出したあとで、結果として得られる sdp_session_t 構造体は次のとおりです。

session {
        sdp_session_version = 1
        s_version = 0
        s_origin {
                o_username = "jdoe"
                o_id = 23423423ULL
                o_version = 234234234ULL
                o_nettype = "IN"
                o_addrtype = "IP4"
                o_address = "192.168.1.1"
        }
        s_name = "SDP seminar"
        s_info = "A seminar on the session description protocol"
        s_uri =  (nil)
        s_email {
                value = "test@host.com"
                next = (nil)
        }
        s_phone = (nil)
        s_conn {
                c_nettype = "IN"
                c_addrtype = "IP4"
                c_address = "156.78.90.1"
                c_addrcount = 0
                c_ttl = 0
                c_next = (nil)
        }
        s_bw = (nil)
        s_time {
                t_start = 2873397496ULL
                t_stop = 2873404696ULL
                t_repeat = (nil)
                t_next = (nil)
        }
        s_zone = (nil)
        s_key = (nil)
        s_attr = (nil)
        s_media = (nil)
}

既存の SDP セッション構造体の複製

sdp_session_t sdp_clone_session(const sdp_session_t *session);

sdp_clone_session() 関数は、session パラメータで識別される SDP セッション構造体と同一の新しい SDP セッション構造体を作成します。sdp_clone_session() 関数は、正常完了時に、複製されたセッション構造体を返します。sdp_clone_session() 関数は、失敗時に NULL を返します。

SDP セッション構造体の文字列への変換

char *sdp_session_to_str(const sdp_session_t *session, int *error);

sdp_session_to_str() 関数は、session パラメータで指定された SDP セッション構造体の文字列表現を返します。sdp_session_to_str() 関数は、各 SDP フィールドに文字列を追加する前に、フィールドの最後にキャリッジリターン/改行を追加します。

戻り値: sdp_session_to_str() 関数は、正常完了時に SDP セッション構造体の文字列表現を返します。それ以外の場合、sdp_session_to_str() 関数は NULL を返します。入力が NULL だった場合、sdp_session_to_str() 関数は EINVAL へのエラーポインタを返します。メモリー割り当てエラーが発生した場合、sdp_session_to_str() 関数は ENOMEM へのエラーポインタを返します。errno の値は、エラーが発生した場合でも変化しません。