Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

wsp_caps.c

Go to the documentation of this file.
00001 /* ==================================================================== 
00002  * The Kannel Software License, Version 1.0 
00003  * 
00004  * Copyright (c) 2001-2008 Kannel Group  
00005  * Copyright (c) 1998-2001 WapIT Ltd.   
00006  * All rights reserved. 
00007  * 
00008  * Redistribution and use in source and binary forms, with or without 
00009  * modification, are permitted provided that the following conditions 
00010  * are met: 
00011  * 
00012  * 1. Redistributions of source code must retain the above copyright 
00013  *    notice, this list of conditions and the following disclaimer. 
00014  * 
00015  * 2. Redistributions in binary form must reproduce the above copyright 
00016  *    notice, this list of conditions and the following disclaimer in 
00017  *    the documentation and/or other materials provided with the 
00018  *    distribution. 
00019  * 
00020  * 3. The end-user documentation included with the redistribution, 
00021  *    if any, must include the following acknowledgment: 
00022  *       "This product includes software developed by the 
00023  *        Kannel Group (http://www.kannel.org/)." 
00024  *    Alternately, this acknowledgment may appear in the software itself, 
00025  *    if and wherever such third-party acknowledgments normally appear. 
00026  * 
00027  * 4. The names "Kannel" and "Kannel Group" must not be used to 
00028  *    endorse or promote products derived from this software without 
00029  *    prior written permission. For written permission, please  
00030  *    contact org@kannel.org. 
00031  * 
00032  * 5. Products derived from this software may not be called "Kannel", 
00033  *    nor may "Kannel" appear in their name, without prior written 
00034  *    permission of the Kannel Group. 
00035  * 
00036  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 
00037  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
00038  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
00039  * DISCLAIMED.  IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS 
00040  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,  
00041  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  
00042  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR  
00043  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
00044  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE  
00045  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  
00046  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
00047  * ==================================================================== 
00048  * 
00049  * This software consists of voluntary contributions made by many 
00050  * individuals on behalf of the Kannel Group.  For more information on  
00051  * the Kannel Group, please see <http://www.kannel.org/>. 
00052  * 
00053  * Portions of this software are based upon software originally written at  
00054  * WapIT Ltd., Helsinki, Finland for the Kannel project.  
00055  */ 
00056 
00057 /* wsp_caps.c - implement interface to WSP capability negotiation
00058  *
00059  * Richard Braakman
00060  */
00061 
00062 #include "gwlib/gwlib.h"
00063 #include "wsp_caps.h"
00064 
00065 
00066 static void wsp_cap_destroy_item(void *cap) {
00067     wsp_cap_destroy(cap);
00068 }
00069 
00070 
00071 Capability *wsp_cap_create(int id, Octstr *name, Octstr *data) {
00072     Capability *new_cap;
00073 
00074     new_cap = gw_malloc(sizeof(*new_cap));
00075     new_cap->id = id;
00076     new_cap->name = name;
00077     new_cap->data = data;
00078     new_cap->accept = 0;
00079 
00080     return new_cap;
00081 }
00082 
00083 void wsp_cap_destroy(Capability *cap) {
00084     if (cap == NULL)
00085         return;
00086 
00087     octstr_destroy(cap->name);
00088     octstr_destroy(cap->data);
00089     gw_free(cap);
00090 }
00091 
00092 void wsp_cap_dump(Capability *cap) {
00093     debug("wsp", 0, "Dumping capability at %p:", cap);
00094     if (cap) {
00095         debug("wsp", 0, " id = %d", cap->id);
00096         debug("wsp", 0, " name:");
00097         octstr_dump(cap->name, 1);
00098         debug("wsp", 0, " data:");
00099         octstr_dump(cap->data, 1);
00100         if (cap->data == NULL)
00101             debug("wsp", 0, " accept: %d", cap->accept);
00102     }
00103     debug("wsp", 0, "Capability dump ends.");
00104 }
00105 
00106 void wsp_cap_dump_list(List *caps_list) {
00107     long i;
00108 
00109     if (caps_list == NULL) {
00110         debug("wsp", 0, "NULL capability list");
00111         return;
00112     }
00113     debug("wsp", 0, "Dumping capability list at %p, length %ld",
00114         caps_list, gwlist_len(caps_list));
00115     for (i = 0; i < gwlist_len(caps_list); i++) {
00116         wsp_cap_dump(gwlist_get(caps_list, i));
00117     }
00118     debug("wsp", 0, "End of capability list dump");
00119 }
00120 
00121 void wsp_cap_destroy_list(List *caps_list) {
00122     gwlist_destroy(caps_list, wsp_cap_destroy_item);
00123 }
00124 
00125 List *wsp_cap_duplicate_list(List *caps_list) {
00126     Capability *cap;
00127     List *new_list;
00128     long i;
00129 
00130     new_list = gwlist_create();
00131 
00132     if (caps_list == NULL)
00133         return new_list;
00134 
00135     for (i = 0; i < gwlist_len(caps_list); i++) {
00136         cap = gwlist_get(caps_list, i);
00137         gwlist_append(new_list, wsp_cap_duplicate(cap));
00138     }
00139     return new_list;
00140 };
00141 
00142 Capability *wsp_cap_duplicate(Capability *cap) {
00143     Capability *new_cap;
00144 
00145     if (!cap)
00146         return NULL;
00147 
00148     new_cap = wsp_cap_create(cap->id,
00149                 octstr_duplicate(cap->name),
00150                 octstr_duplicate(cap->data));
00151     new_cap->accept = cap->accept;
00152     return new_cap;
00153 }
00154 
00155 List *wsp_cap_unpack_list(Octstr *caps) {
00156     List *caps_list;
00157     long pos, capslen;
00158 
00159     caps_list = gwlist_create();
00160     if (caps == NULL)
00161         return caps_list;
00162 
00163     capslen = octstr_len(caps);
00164     pos = 0;
00165     while (pos < capslen) {
00166         unsigned long length;
00167         int id;
00168         Octstr *name;
00169         Octstr *data;
00170 
00171         pos = octstr_extract_uintvar(caps, &length, pos);
00172         if (pos < 0 || length == 0)
00173             goto error;
00174 
00175         id = octstr_get_char(caps, pos);
00176         if (id >= 0x80) {
00177             id &= 0x7f; /* It's encoded as a short-integer */
00178             name = NULL;
00179             data = octstr_copy(caps, pos + 1, length - 1);
00180         } else {
00181             long nullpos;
00182             id = -1;  /* It's encoded as token-text */
00183             nullpos = octstr_search_char(caps, 0, pos);
00184             if (nullpos < 0)
00185                             goto error;
00186                         /* check length
00187                          * FIXME: If it's not allowed that data is empty then change check
00188                          *        to <= .
00189                          */
00190                         if (length < (nullpos + 1 - pos))
00191                             goto error;
00192             name = octstr_copy(caps, pos, nullpos - pos);
00193             data = octstr_copy(caps, nullpos + 1,
00194                 length - (nullpos + 1 - pos));
00195         }
00196         gwlist_append(caps_list, wsp_cap_create(id, name, data));
00197         pos += length;
00198     }
00199 
00200     return caps_list;
00201 
00202 error:
00203     warning(0, "WSP: Error unpacking capabilities");
00204     return caps_list;
00205 }
00206 
00207 Octstr *wsp_cap_pack_list(List *caps_list) {
00208     Octstr *result;
00209     Capability *cap;
00210     long i, len;
00211 
00212     result = octstr_create("");
00213     len = gwlist_len(caps_list);
00214     for (i = 0; i < len; i++) {
00215         long datalen;
00216 
00217         cap = gwlist_get(caps_list, i);
00218 
00219         datalen = 0;
00220         if (cap->data)
00221             datalen = octstr_len(cap->data);
00222 
00223         if (datalen == 0 && cap->accept)
00224             continue;
00225 
00226         if (cap->name) {
00227             if (octstr_get_char(cap->name, 0) >= 0x80 ||
00228                 octstr_search_char(cap->name, 0, 0) >= 0) {
00229                 error(0, "WSP: Bad capability.");
00230                 wsp_cap_dump(cap);
00231                 continue;
00232             }
00233             /* Add length */
00234             octstr_append_uintvar(result,
00235                 octstr_len(cap->name) + 1 + datalen);
00236             /* Add identifier */
00237             octstr_append(result, cap->name);
00238             octstr_append_char(result, 0);
00239         } else {
00240             if (cap->id >= 0x80 || cap->id < 0) {
00241                 error(0, "WSP: Bad capability.");
00242                 wsp_cap_dump(cap);
00243                 continue;
00244             }
00245             /* Add length */
00246             octstr_append_uintvar(result, 1 + datalen);
00247             /* Add identifier */
00248             octstr_append_char(result, 0x80 | cap->id);
00249         }
00250         /* Add payload, if any */
00251         if (cap->data) {
00252             octstr_append(result, cap->data);
00253         }
00254     }
00255 
00256     return result;
00257 }
00258 
00259 static int wsp_cap_get_data(List *caps_list, int id, Octstr *name,
00260             Octstr **data) {
00261     long i, len;
00262     Capability *cap;
00263     int found;
00264 
00265     len = gwlist_len(caps_list);
00266     found = 0;
00267     *data = NULL;
00268     for (i = 0; i < len; i++) {
00269         cap = gwlist_get(caps_list, i);
00270         if ((name && cap->name 
00271              && octstr_compare(name, cap->name) == 0)
00272             || (!name && cap->id == id)) {
00273             if (!found)
00274                 *data = cap->data;
00275             found++;
00276         }
00277     }
00278 
00279     return found;
00280 }
00281         
00282 int wsp_cap_count(List *caps_list, int id, Octstr *name) {
00283     Octstr *data;
00284 
00285     return wsp_cap_get_data(caps_list, id, name, &data);
00286 }
00287 
00288 int wsp_cap_get_client_sdu(List *caps_list, unsigned long *sdu) {
00289     Octstr *data;
00290     int found;
00291 
00292     found = wsp_cap_get_data(caps_list, WSP_CAPS_CLIENT_SDU_SIZE,
00293                     NULL, &data);
00294     if (found > 0 && octstr_extract_uintvar(data, sdu, 0) < 0)
00295         return -1;
00296 
00297     return found;
00298 }
00299 
00300 int wsp_cap_get_server_sdu(List *caps_list, unsigned long *sdu) {
00301     Octstr *data;
00302     int found;
00303 
00304     found = wsp_cap_get_data(caps_list, WSP_CAPS_SERVER_SDU_SIZE,
00305                     NULL, &data);
00306     if (found > 0 && octstr_extract_uintvar(data, sdu, 0) < 0)
00307         return -1;
00308 
00309     return found;
00310 }
00311 
00312 int wsp_cap_get_method_mor(List *caps_list, unsigned long *mor) {
00313     Octstr *data;
00314     int found;
00315     int c;
00316 
00317     found = wsp_cap_get_data(caps_list, WSP_CAPS_METHOD_MOR, NULL, &data);
00318     if (found > 0) {
00319         c = octstr_get_char(data, 0);
00320         if (c < 0)
00321             return -1;
00322         *mor = c;
00323     }
00324     
00325     return found;
00326 }
00327 
00328 int wsp_cap_get_push_mor(List *caps_list, unsigned long *mor) {
00329     Octstr *data;
00330     int found;
00331     int c;
00332 
00333     found = wsp_cap_get_data(caps_list, WSP_CAPS_PUSH_MOR, NULL, &data);
00334     if (found > 0) {
00335         c = octstr_get_char(data, 0);
00336         if (c < 0)
00337             return -1;
00338         *mor = c;
00339     }
00340     
00341     return found;
00342 }
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.