tport_stub_sigcomp.c 6.68 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
/*
 * This file is part of the Sofia-SIP package
 *
 * Copyright (C) 2006 Nokia Corporation.
 *
 * Contact: Pekka Pessi <pekka.pessi@nokia.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

/**@CFILE tport_stub_sigcomp.c Stub interface for SigComp
 *
 * @author Pekka Pessi <Pekka.Pessi@nokia.com>
 *
 * @date Created: Fri Mar 31 12:31:36 EEST 2006
 */

#include "config.h"

#include "tport_internal.h"

Pekka Pessi's avatar
Pekka Pessi committed
36 37
#include <string.h>

38 39 40 41 42 43 44 45 46 47 48 49
tport_comp_vtable_t const *tport_comp_vtable = NULL;

int tport_plug_in_compress(tport_comp_vtable_t const *vsc)
{
  return -1;
}

char const tport_sigcomp_name[] = "sigcomp";

/** Canonize compression string */
char const *tport_canonize_comp(char const *comp)
{
50
  if (tport_comp_vtable && comp && strcasecmp(comp, tport_sigcomp_name) == 0)
51 52 53 54
    return tport_sigcomp_name;
  return NULL;
}

55 56 57
int tport_init_compressor(tport_t *tp,
			  char const *comp_name,
			  tagi_t const *tags)
58 59
{
  tport_comp_vtable_t const *vsc = tport_comp_vtable;
60 61
  tport_master_t *mr = tp ? tp->tp_master : NULL;
  tport_compressor_t *tcc;
62

63 64 65 66
  if (vsc == NULL)
    return -1;
  if (mr == NULL)
    return -1;
67

68 69 70
  if (tp->tp_comp)
    return 0;

71 72 73 74
  comp_name = tport_canonize_comp(comp_name);
  if (comp_name == NULL)
    return 0;

75 76 77 78 79 80 81 82 83 84 85
  tcc = su_zalloc(tp->tp_home, vsc->vsc_sizeof_context);

  if (tcc == NULL)
    return -1;

  if (vsc->vsc_init_comp(mr->mr_stack, tp, tcc, comp_name, tags) < 0) {
    vsc->vsc_deinit_comp(mr->mr_stack, tp, tcc);
    return -1;
  }

  tp->tp_comp = tcc;
86

87
  return 0;
88 89
}

90
void tport_deinit_compressor(tport_t *tp)
91 92
{
  tport_comp_vtable_t const *vsc = tport_comp_vtable;
93
  tport_master_t *mr = tp ? tp->tp_master : NULL;
94

95 96 97 98
  if (vsc && mr && tp->tp_comp) {
    vsc->vsc_deinit_comp(mr->mr_stack, tp, tp->tp_comp);
    su_free(tp->tp_home, tp->tp_comp), tp->tp_comp = NULL;
  }
99 100
}

101

102 103 104 105 106
char const *tport_comp_name(tport_primary_t *pri,
			    char const *name,
			    tagi_t const *tags)
{
  tport_comp_vtable_t const *vsc = tport_comp_vtable;
107
  tport_compressor_t const *comp = pri->pri_master->mr_master->tp_comp;
108 109 110 111 112 113 114

  if (vsc)
    return vsc->vsc_comp_name(comp, name, tags);

  return NULL;
}

115

116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
/** Check if transport can receive compressed messages */
int tport_can_recv_sigcomp(tport_t const *self)
{
  tport_comp_vtable_t const *vsc = tport_comp_vtable;

  if (vsc)
    return vsc->vsc_can_recv_comp(self->tp_comp);

  return 0;
}

/** Check if transport can send compressed messages */
int tport_can_send_sigcomp(tport_t const *self)
{
  tport_comp_vtable_t const *vsc = tport_comp_vtable;

  if (vsc)
    return vsc->vsc_can_send_comp(self->tp_comp);

  return 0;
}

/** Check if transport supports named compression */
int tport_has_compression(tport_t const *self, char const *comp)
{
  return
    self && comp && 
    self->tp_name->tpn_comp == tport_canonize_comp(comp);
}

int tport_set_compression(tport_t *self, char const *comp)
{
  tport_comp_vtable_t const *vsc = tport_comp_vtable;

  if (vsc)
    return vsc->vsc_set_comp_name(self, self->tp_comp, comp);

  return (self == NULL || comp) ? -1 : 0;
}

/** Set options to SigComp */
int tport_sigcomp_option(tport_t const *self,
			 struct sigcomp_compartment *cc,
			 char const *option)
{
  tport_comp_vtable_t const *vsc = tport_comp_vtable;

  if (vsc)
    return vsc->vsc_sigcomp_option(self, cc, option);

  return -1;
}


/** Assign a SigComp compartment (to a possibly connected tport). 
 *
 * @related tport_s
 */
int tport_sigcomp_assign(tport_t *self, struct sigcomp_compartment *cc)
{
  tport_comp_vtable_t const *vsc = tport_comp_vtable;

178 179 180 181 182
  if (!vsc)
    return 0;

  if (tport_is_connection_oriented(self) && 
      tport_is_secondary(self) &&
183
      self->tp_socket != INVALID_SOCKET) {
184 185
    return vsc->vsc_set_compartment(self, self->tp_comp, cc);
  }
186 187 188 189

  return 0;
}

190 191 192 193 194 195
struct sigcomp_compartment *
tport_sigcomp_assign_if_needed(tport_t *self,
			       struct sigcomp_compartment *cc)
{
  tport_comp_vtable_t const *vsc = tport_comp_vtable;

196 197 198 199 200 201 202 203 204 205 206 207
  if (!vsc)
    return NULL;

  if (!self->tp_name->tpn_comp)
    return NULL;

  if (cc) {
    tport_sigcomp_assign(self, cc);
    return cc;
  }

  return vsc->vsc_get_compartment(self, self->tp_comp);
208 209 210
}			   


211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
/** Test if tport has a SigComp compartment assigned to it. */
int tport_has_sigcomp_assigned(tport_t const *self)
{
  tport_comp_vtable_t const *vsc = tport_comp_vtable;

  if (vsc && self)
    return vsc->vsc_has_sigcomp_assigned(self->tp_comp);
    
  return 0;
}

int 
tport_sigcomp_accept(tport_t *self, 
		     struct sigcomp_compartment *cc, 
		     msg_t *msg)
{
  tport_comp_vtable_t const *vsc = tport_comp_vtable;

  if (self == NULL)
    return su_seterrno(EFAULT);

  if (vsc)
    return vsc->vsc_sigcomp_accept(self, self->tp_comp, cc, msg);

  return 0;
}

/* Internal API */

240 241
/** This function is called when the application message is still incomplete
    but a complete SigComp message could have been received */
242
void tport_sigcomp_accept_incomplete(tport_t *self, msg_t *msg)
243 244 245
{
  tport_comp_vtable_t const *vsc = tport_comp_vtable;

246 247
  if (vsc && self->tp_comp)
    vsc->vsc_accept_incomplete(self, self->tp_comp, msg);
248 249 250 251 252 253 254 255 256 257 258 259 260
}

struct sigcomp_udvm **tport_get_udvm_slot(tport_t *self)
{
  tport_comp_vtable_t const *vsc = tport_comp_vtable;

  if (vsc && self)
    return vsc->vsc_get_udvm_slot(self);

  return NULL;
}

/** Receive data from datagram using SigComp. */
261 262
int tport_recv_comp_dgram(tport_t const *self, 
			  tport_compressor_t *sc,
263 264 265
			  msg_t **in_out_msg,
			  su_sockaddr_t *from,
			  socklen_t fromlen)
266 267 268 269
{
  tport_comp_vtable_t const *vsc = tport_comp_vtable;

  if (vsc)
270
    return vsc->vsc_recv_comp(self, sc, in_out_msg, from, fromlen);
271

272
  msg_destroy(*in_out_msg), *in_out_msg = NULL;
273

274
  return su_seterrno(EBADMSG);     
275 276 277
}


278 279 280 281 282 283
ssize_t tport_send_comp(tport_t const *self,
			msg_t *msg, 
			msg_iovec_t iov[], 
			size_t iovused,
			struct sigcomp_compartment *cc,
			tport_compressor_t *comp)
284 285 286 287 288 289 290 291 292
{
  tport_comp_vtable_t const *vsc = tport_comp_vtable;

  if (vsc)
    vsc->vsc_send_comp(self, msg, iov, iovused, cc, comp);

  msg_addrinfo(msg)->ai_flags &= ~TP_AI_COMPRESSED;
  return self->tp_pri->pri_vtable->vtp_send(self, msg, iov, iovused);
}