more code clean-up
authorJeremy McNamara <jj@nufone.net>
Thu, 28 Oct 2004 06:06:58 +0000 (06:06 +0000)
committerJeremy McNamara <jj@nufone.net>
Thu, 28 Oct 2004 06:06:58 +0000 (06:06 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@4116 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_h323.c

index e657409..b207994 100755 (executable)
@@ -105,10 +105,8 @@ static int noSilenceSuppression = 0;
 /* Assume we can native bridge by default */
 static int bridging = 1;
 /* Find user by alias (h.323 id) is default, alternative is the incomming call's source IP address*/
-static int  userbyalias = 1;
-/* Just about everybody seems to support ulaw, so make it a nice default */
+static int userbyalias = 1;
 static int capability = AST_FORMAT_ULAW;
-/* TOS flag */
 static int tos = 0;
 static int dtmfmode = H323_DTMF_RFC2833;
 static char secret[50];
@@ -182,7 +180,6 @@ static int h323_reloading = 0;
 /* This is the thread for the monitor which checks for input on the channels
    which are not currently in use.  */
 static pthread_t monitor_thread = AST_PTHREADT_NULL;
-
 static int restart_monitor(void);
 static int h323_do_reload(void);
 
@@ -233,7 +230,6 @@ static struct oh323_alias *build_alias(char *name, struct ast_variable *v)
        struct oh323_alias *alias;
 
        alias = (struct oh323_alias *)malloc(sizeof(struct oh323_alias));
-
        if (alias) {
                memset(alias, 0, sizeof(struct oh323_alias));
                strncpy(alias->name, name, sizeof(alias->name) - 1);
@@ -267,10 +263,10 @@ static struct oh323_user *build_user(char *name, struct ast_variable *v)
                memset(user, 0, sizeof(struct oh323_user));
                strncpy(user->name, name, sizeof(user->name) - 1);
 
-               /* set the native brigding default */
+               /* set a native brigding default value */
                user->bridge = bridging;
+               /* and default context */
                strncpy(user->context, default_context, sizeof(user->context) - 1);
-
                while(v) {
                        if (!strcasecmp(v->name, "context")) {
                                strncpy(user->context, v->value, sizeof(user->context) - 1);
@@ -425,8 +421,9 @@ static int oh323_digit(struct ast_channel *c, char digit)
                ast_rtp_senddigit(p->rtp, digit);
        }
        /* If in-band DTMF is desired, send that */
-       if (p->dtmfmode & H323_DTMF_INBAND)
+       if (p->dtmfmode & H323_DTMF_INBAND) {
                h323_send_tone(p->cd.call_token, digit);
+       }
        return 0;
 }
 
@@ -459,7 +456,7 @@ static int oh323_call(struct ast_channel *c, char *dest, int timeout)
        }
        /* indicate that this is an outgoing call */
        pvt->outgoing = 1;
-       ast_log(LOG_DEBUG, "Outgoing call to %s:%d\n", called_addr, pvt->options.port);
+       ast_log(LOG_DEBUG, "Placing outgoing call to %s:%d\n", called_addr, pvt->options.port);
        res = h323_make_call(called_addr, &(pvt->cd), pvt->options);
        if (res) {
                ast_log(LOG_NOTICE, "h323_make_call failed(%s)\n", c->name);
@@ -475,9 +472,9 @@ static int oh323_answer(struct ast_channel *c)
 
        res = h323_answering_call(pvt->cd.call_token, 0);
        
-       if (c->_state != AST_STATE_UP)
+       if (c->_state != AST_STATE_UP) {
                ast_setstate(c, AST_STATE_UP);
-
+       }
        return res;
 }
 
@@ -485,8 +482,9 @@ static int oh323_hangup(struct ast_channel *c)
 {
        struct oh323_pvt *pvt = (struct oh323_pvt *) c->pvt->pvt;
        int needcancel = 0;
-       if (h323debug)
+       if (h323debug) {
                ast_log(LOG_DEBUG, "oh323_hangup(%s)\n", c->name);
+       }
        if (!c->pvt->pvt) {
                ast_log(LOG_DEBUG, "Asked to hangup channel not connected\n");
                return 0;
@@ -498,16 +496,15 @@ static int oh323_hangup(struct ast_channel *c)
                ast_mutex_unlock(&pvt->lock);
                return 0;
        }
-       if (!c || (c->_state != AST_STATE_UP))
+       if (!c || (c->_state != AST_STATE_UP)) {
                needcancel = 1;
-       /* Disconnect */
-       pvt = (struct oh323_pvt *) c->pvt->pvt;
+       }
+       pvt = (struct oh323_pvt *)c->pvt->pvt;
        
        /* Free dsp used for in-band DTMF detection */
        if (pvt->vad) {
                ast_dsp_free(pvt->vad);
        }
-
        pvt->owner = NULL;
        c->pvt->pvt = NULL;
 
@@ -527,7 +524,6 @@ static int oh323_hangup(struct ast_channel *c)
        }
        ast_mutex_unlock(&usecnt_lock);
        ast_update_use_count();
-
        ast_mutex_unlock(&pvt->lock);
        return 0;
 }
@@ -538,17 +534,17 @@ static struct ast_frame *oh323_rtp_read(struct oh323_pvt *pvt)
        struct ast_frame *f;
        static struct ast_frame null_frame = { AST_FRAME_NULL, };
 
-      /* Only apply it for the first packet, we just need the correct ip/port */
-      if(pvt->nat)
-      {
-              ast_rtp_setnat(pvt->rtp,pvt->nat);
-              pvt->nat = 0;
-      }
+       /* Only apply it for the first packet, we just need the correct ip/port */
+       if (pvt->nat) {
+               ast_rtp_setnat(pvt->rtp,pvt->nat);
+               pvt->nat = 0;
+       }
 
        f = ast_rtp_read(pvt->rtp);
        /* Don't send RFC2833 if we're not supposed to */
-       if (f && (f->frametype == AST_FRAME_DTMF) && !(pvt->dtmfmode & H323_DTMF_RFC2833))
+       if (f && (f->frametype == AST_FRAME_DTMF) && !(pvt->dtmfmode & H323_DTMF_RFC2833)) {
                return &null_frame;
+       }
        if (pvt->owner) {
                /* We already hold the channel lock */
                if (f->frametype == AST_FRAME_VOICE) {
@@ -557,13 +553,12 @@ static struct ast_frame *oh323_rtp_read(struct oh323_pvt *pvt)
                                pvt->owner->nativeformats = f->subclass;
                                ast_set_read_format(pvt->owner, pvt->owner->readformat);
                                ast_set_write_format(pvt->owner, pvt->owner->writeformat);
-                       }
-               
+                       }       
                        /* Do in-band DTMF detection */
                        if (pvt->dtmfmode & H323_DTMF_INBAND) {
                                f = ast_dsp_process(pvt->owner,pvt->vad,f);
                                if (f->frametype == AST_FRAME_DTMF) {
-                                       ast_log(LOG_DEBUG, "Got in-band digit %c.\n", f->subclass);
+                                       ast_log(LOG_DEBUG, "Received in-band digit %c.\n", f->subclass);
                                }
                        }
                        
@@ -572,11 +567,10 @@ static struct ast_frame *oh323_rtp_read(struct oh323_pvt *pvt)
        return f;
 }
 
-
 static struct ast_frame  *oh323_read(struct ast_channel *c)
 {
        struct ast_frame *fr;
-       struct oh323_pvt *pvt = (struct oh323_pvt *) c->pvt->pvt;
+       struct oh323_pvt *pvt = (struct oh323_pvt *)c->pvt->pvt;
        ast_mutex_lock(&pvt->lock);
        fr = oh323_rtp_read(pvt);
        ast_mutex_unlock(&pvt->lock);
@@ -588,9 +582,9 @@ static int oh323_write(struct ast_channel *c, struct ast_frame *frame)
        struct oh323_pvt *pvt = (struct oh323_pvt *) c->pvt->pvt;
        int res = 0;
        if (frame->frametype != AST_FRAME_VOICE) {
-               if (frame->frametype == AST_FRAME_IMAGE)
+               if (frame->frametype == AST_FRAME_IMAGE) {
                        return 0;
-               else {
+               } else {
                        ast_log(LOG_WARNING, "Can't send %d type frames with H323 write\n", frame->frametype);
                        return 0;
                }
@@ -689,7 +683,6 @@ static struct ast_channel *oh323_new(struct oh323_pvt *pvt, int state, const cha
                fmt = ast_best_codec(ch->nativeformats);
                ch->type = type;
                ch->fds[0] = ast_rtp_fd(pvt->rtp);
-               
                if (state == AST_STATE_RING) {
                        ch->rings = 1;
                }
@@ -697,13 +690,11 @@ static struct ast_channel *oh323_new(struct oh323_pvt *pvt, int state, const cha
                ch->pvt->rawwriteformat = fmt;
                ch->readformat = fmt;
                ch->pvt->rawreadformat = fmt;
-               
                /* Allocate dsp for in-band DTMF support */
                if (pvt->dtmfmode & H323_DTMF_INBAND) {
                        pvt->vad = ast_dsp_new();
                        ast_dsp_set_features(pvt->vad, DSP_FEATURE_DTMF_DETECT);
                }
-
                /* Register channel functions. */
                ch->pvt->pvt = pvt;
                ch->pvt->send_digit = oh323_digit;
@@ -714,8 +705,10 @@ static struct ast_channel *oh323_new(struct oh323_pvt *pvt, int state, const cha
                ch->pvt->write = oh323_write;
                ch->pvt->indicate = oh323_indicate;
                ch->pvt->fixup = oh323_fixup;
-            /* ch->pvt->bridge = ast_rtp_bridge; */
-
+               /* disable, for now */
+#if 0
+               ch->pvt->bridge = ast_rtp_bridge;
+#endif
                /*  Set the owner of this channel */
                pvt->owner = ch;
                
@@ -811,7 +804,7 @@ static struct oh323_pvt *find_call(int call_reference, const char *token)
         while(pvt) {
                 if ((signed int)pvt->cd.call_reference == call_reference) {
                         /* Found the call */             
-                        if ((token != NULL) && (strcmp(pvt->cd.call_token, token) == 0)) {
+                        if ((token != NULL) && (!strcmp(pvt->cd.call_token, token))) {
                                ast_mutex_unlock(&iflock);
                                return pvt;
                         } else if (token == NULL) {
@@ -960,7 +953,6 @@ static struct ast_channel *oh323_request(const char *type, int format, void *dat
        char tmp[256];
        
        ast_log(LOG_DEBUG, "type=%s, format=%d, data=%s.\n", type, format, (char *)data);
-
        pvt = oh323_alloc(0);
        if (!pvt) {
                ast_log(LOG_WARNING, "Unable to build pvt data for '%s'\n", (char *)data);
@@ -994,7 +986,6 @@ static struct ast_channel *oh323_request(const char *type, int format, void *dat
                strncpy(pvt->username, ext, sizeof(pvt->username) - 1);
        }
        ast_log(LOG_DEBUG, "Host: %s\tUsername: %s\n", host, pvt->username);
-
        if (!usingGk) {
                if (create_addr(pvt, host)) {
                        oh323_destroy(pvt);
@@ -1083,7 +1074,7 @@ struct rtp_info *external_rtp_create(unsigned call_reference, const char * token
        }
        /* figure out our local RTP port and tell the H.323 stack about it */
        ast_rtp_get_us(pvt->rtp, &us);
-       /* evil hack, until I (someone?) figures out a better way */
+       /* evil hack, until I (or someone?) figures out a better way */
        info->addr = ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr);
        info->port = ntohs(us.sin_port);
        ast_log(LOG_DEBUG, "Sending RTP 'US' %s:%d\n", info->addr, info->port);
@@ -1107,7 +1098,8 @@ void setup_rtp_connection(unsigned call_reference, const char *remoteIp, int rem
                return;
        }
        them.sin_family = AF_INET;
-       them.sin_addr.s_addr = inet_addr(remoteIp); // only works for IPv4
+       /* only works for IPv4 */
+       them.sin_addr.s_addr = inet_addr(remoteIp); 
        them.sin_port = htons(remotePort);
        ast_rtp_set_peer(pvt->rtp, &them);
        return;
@@ -1183,7 +1175,6 @@ int setup_incoming_call(call_details_t cd)
                        strncpy(pvt->context, default_context, sizeof(pvt->context) - 1); 
                } else {
                        alias = find_alias(cd.call_dest_alias);
-               
                        if (!alias) {
                                ast_log(LOG_ERROR, "Call for %s rejected, alias not found\n", cd.call_dest_alias);
                                return 0;
@@ -1241,7 +1232,6 @@ int setup_incoming_call(call_details_t cd)
                        } 
                } 
        }
-
 exit:
        return 1;
 }
@@ -1258,12 +1248,10 @@ static int answer_call(unsigned call_reference, const char *token)
 
        /* Find the call or allocate a private structure if call not found */
        pvt = find_call(call_reference, token); 
-       
        if (!pvt) {
                ast_log(LOG_ERROR, "Something is wrong: answer_call\n");
                return 0;
        }
-       
        /* allocate a channel and tell asterisk about it */
        c = oh323_new(pvt, AST_STATE_RINGING, pvt->cd.call_token);
        if (!c) {
@@ -1293,11 +1281,9 @@ void chan_ringing(unsigned call_reference, const char *token)
         struct oh323_pvt *pvt = NULL;
 
         pvt = find_call(call_reference, token); 
-
         if (!pvt) {
                 ast_log(LOG_ERROR, "Something is wrong: ringing\n");
        }
-
         if (!pvt->owner) {
                 ast_log(LOG_ERROR, "Channel has no owner\n");
                 return;
@@ -1308,7 +1294,6 @@ void chan_ringing(unsigned call_reference, const char *token)
         return;
 }
 
-
 void cleanup_call_details(call_details_t cd) 
 {
         if (cd.call_token) {
@@ -1506,32 +1491,26 @@ static int h323_gk_cycle(int fd, int argc, char *argv[])
 
 static int h323_ep_hangup(int fd, int argc, char *argv[])
 {
-
         if (argc != 3) {
                 return RESULT_SHOWUSAGE;
        }
-
        if (h323_soft_hangup(argv[2])) {
                ast_verbose(VERBOSE_PREFIX_3 "Hangup succeeded on %s\n", argv[2]);
        } else { 
                ast_verbose(VERBOSE_PREFIX_3 "Hangup failed for %s\n", argv[2]);
        }
-
        return RESULT_SUCCESS;
 }
 
 static int h323_tokens_show(int fd, int argc, char *argv[])
 {
-
         if (argc != 3) {
                 return RESULT_SHOWUSAGE;
        }
        h323_show_tokens();
-
        return RESULT_SUCCESS;
 }
 
-
 static char trace_usage[] = 
 "Usage: h.323 trace <level num>\n"
 "       Enables H.323 stack tracing for debugging purposes\n";
@@ -1542,11 +1521,11 @@ static char no_trace_usage[] =
 
 static char debug_usage[] = 
 "Usage: h.323 debug\n"
-"       Enables chan_h323 debug output\n";
+"       Enables H.323 debug output\n";
 
 static char no_debug_usage[] = 
 "Usage: h.323 no debug\n"
-"       Disables chan_h323 debug output\n";
+"       Disables H.323 debug output\n";
 
 static char show_codec_usage[] = 
 "Usage: h.323 show codec\n"
@@ -1554,7 +1533,7 @@ static char show_codec_usage[] =
 
 static char show_cycle_usage[] = 
 "Usage: h.323 gk cycle\n"
-"       Manually re-register with the Gatekeper\n";
+"       Manually re-register with the Gatekeper (Currently Disabled)\n";
 
 static char show_hangup_usage[] = 
 "Usage: h.323 hangup <token>\n"
@@ -1573,9 +1552,9 @@ static struct ast_cli_entry  cli_trace =
 static struct ast_cli_entry  cli_no_trace =
        { { "h.323", "no", "trace", NULL }, h323_no_trace, "Disable H.323 Stack Tracing", no_trace_usage };
 static struct ast_cli_entry  cli_debug =
-       { { "h.323", "debug", NULL }, h323_do_debug, "Enable chan_h323 debug", debug_usage };
+       { { "h.323", "debug", NULL }, h323_do_debug, "Enable H.323 debug", debug_usage };
 static struct ast_cli_entry  cli_no_debug =
-       { { "h.323", "no", "debug", NULL }, h323_no_debug, "Disable chan_h323 debug", no_debug_usage };
+       { { "h.323", "no", "debug", NULL }, h323_no_debug, "Disable H.323 debug", no_debug_usage };
 static struct ast_cli_entry  cli_show_codecs =
        { { "h.323", "show", "codecs", NULL }, h323_show_codec, "Show enabled codecs", show_codec_usage };
 static struct ast_cli_entry  cli_gk_cycle =
@@ -1609,11 +1588,9 @@ int reload_config(void)
        if (!h323_end_point_exist()) {
               h323_end_point_create();        
        }
-       h323debug=0;
+       h323debug = 0;
        dtmfmode = H323_DTMF_RFC2833;
-
        memset(&bindaddr, 0, sizeof(bindaddr));
-
        v = ast_variable_browse(cfg, "general");
        while(v) {
                /* Create the interface list */
@@ -1638,7 +1615,7 @@ int reload_config(void)
                        else
                                capability &= ~format;
                } else if (!strcasecmp(v->name, "tos")) {
-                       if (sscanf(v->value, "%i", &format) == 1) {
+                       if (sscanf(v->value, "%i", &format)) {
                                tos = format & 0xff;
                        } else if (!strcasecmp(v->value, "lowdelay")) {
                                tos = IPTOS_LOWDELAY;
@@ -1667,18 +1644,18 @@ int reload_config(void)
                                strncpy(gatekeeper, v->value, sizeof(gatekeeper) - 1);
                        }
                } else if (!strcasecmp(v->name, "secret")) {
-                               strncpy(secret, v->value, sizeof(secret) - 1);
+                       strncpy(secret, v->value, sizeof(secret) - 1);
                } else if (!strcasecmp(v->name, "AllowGKRouted")) {
-                               gkroute = ast_true(v->value);
+                       gkroute = ast_true(v->value);
                } else if (!strcasecmp(v->name, "context")) {
                        strncpy(default_context, v->value, sizeof(default_context) - 1);
-                       ast_verbose(VERBOSE_PREFIX_3 "Setting default context to %s\n", default_context);       
+                       ast_verbose(VERBOSE_PREFIX_2 "Setting default context to %s\n", default_context);       
                } else if (!strcasecmp(v->name, "dtmfmode")) {
-                       if (!strcasecmp(v->value, "inband"))
-                               dtmfmode=H323_DTMF_INBAND;
-                       else if (!strcasecmp(v->value, "rfc2833"))
+                       if (!strcasecmp(v->value, "inband")) {
+                               dtmfmode=H323_DTMF_INBAND;
+                       } else if (!strcasecmp(v->value, "rfc2833")) {
                                dtmfmode = H323_DTMF_RFC2833;
-                       else {
+                       } else {
                                ast_log(LOG_WARNING, "Unknown dtmf mode '%s', using rfc2833\n", v->value);
                                dtmfmode = H323_DTMF_RFC2833;
                        }
@@ -1687,9 +1664,9 @@ int reload_config(void)
                 } else if (!strcasecmp(v->name, "bridge")) {
                         bridging = ast_true(v->value);
                 } else if (!strcasecmp(v->name, "noFastStart")) {
-                                noFastStart = ast_true(v->value);
+                        noFastStart = ast_true(v->value);
                 } else if (!strcasecmp(v->name, "noH245Tunneling")) {
-                                noH245Tunneling = ast_true(v->value);
+                        noH245Tunneling = ast_true(v->value);
                }
                v = v->next;    
        }
@@ -1715,7 +1692,7 @@ int reload_config(void)
                                                peerl.peers = peer;
                                                ast_mutex_unlock(&peerl.lock);
                                        }
-                               }  else if (!strcasecmp(utype, "h323")) {                       
+                               }  else if (!strcasecmp(utype, "h323") || !strcasecmp(utype, "alias")) {
                                        alias = build_alias(cat, ast_variable_browse(cfg, cat));
                                        if (alias) {
                                                ast_mutex_lock(&aliasl.lock);
@@ -1726,8 +1703,9 @@ int reload_config(void)
                                } else {
                                        ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config);
                                }
-                       } else
+                       } else {
                                ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
+                       }
                }
                cat = ast_category_browse(cfg, cat);
        }
@@ -1742,9 +1720,9 @@ int reload_config(void)
                alias = alias->next;
        }
 
-       /* Add some capabilities */
+       /* Add our capabilities */
        ast_mutex_lock(&caplock);
-       if(h323_set_capability(capability, dtmfmode)) {
+       if (h323_set_capability(capability, dtmfmode)) {
                ast_log(LOG_ERROR, "Capabilities failure, this is bad.\n");
                ast_mutex_unlock(&caplock);
                return -1;
@@ -1801,13 +1779,15 @@ void prune_peers(void)
                peernext = peer->next;
                if (peer->delme) {
                        free(peer);
-                       if (peerlast)
+                       if (peerlast) {
                                peerlast->next = peernext;
-                       else
+                       } else {
                                peerl.peers = peernext;
-               } else
+                       }
+               } else {
                        peerlast = peer;
-               peer=peernext;
+               }
+               peer = peernext;
        }
        ast_mutex_unlock(&peerl.lock);
 }
@@ -1840,7 +1820,6 @@ int reload(void)
        return h323_reload(0, 0, NULL);
 }
 
-
 static struct ast_cli_entry  cli_h323_reload =
         { { "h.323", "reload", NULL }, h323_reload, "Reload H.323 configuration", h323_reload_usage };
 
@@ -1882,7 +1861,6 @@ static char *convertcap(int cap)
                ast_log(LOG_NOTICE, "Don't know how to deal with mode %d\n", cap);
                return NULL;
        }
-
 }
 
 static int oh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs)
@@ -1894,25 +1872,20 @@ static int oh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, str
        char *mode;
        char iabuf[INET_ADDRSTRLEN];
 
-       mode = convertcap(chan->writeformat); 
-
        if (!rtp) {
                return 0;
        }
 
+       mode = convertcap(chan->writeformat); 
        p = (struct oh323_pvt *) chan->pvt->pvt;
        if (!p) {
                ast_log(LOG_ERROR, "No Private Structure, this is bad\n");
                return -1;
        }
-
        ast_rtp_get_peer(rtp, &them);   
        ast_rtp_get_us(rtp, &us);
-
        h323_native_bridge(p->cd.call_token, ast_inet_ntoa(iabuf, sizeof(iabuf), them.sin_addr), mode);
-       
        return 0;
-       
 }
 
 static struct ast_rtp_protocol oh323_rtp = {
@@ -1935,7 +1908,6 @@ int load_module()
        if (!io) {
                ast_log(LOG_WARNING, "Unable to create I/O context\n");
        }
-               
        res = reload_config();
        if (res) {
                return 0;
@@ -1969,15 +1941,13 @@ int load_module()
                                       connection_made, 
                                       send_digit,
                                       answer_call);
-       
                /* start the h.323 listener */
                if (h323_start_listener(h323_signalling_port, bindaddr)) {
                        ast_log(LOG_ERROR, "Unable to create H323 listener.\n");
                        return -1;
                }
-
                /* Possibly register with a GK */
-               if (gatekeeper_disable == 0) {
+               if (!gatekeeper_disable) {
                        if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) {
                                ast_log(LOG_ERROR, "Gatekeeper registration failed.\n");
                                return 0;
@@ -1989,7 +1959,6 @@ int load_module()
        return res;
 }
 
-
 int unload_module() 
 {
        struct oh323_pvt *p, *pl;
@@ -2024,7 +1993,8 @@ int unload_module()
        }
        if (!ast_mutex_lock(&monlock)) {
                 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP)) {
-                        pthread_cancel(monitor_thread);
+                        /* this causes a seg, anyone know why? */
+                       pthread_cancel(monitor_thread);
                         pthread_kill(monitor_thread, SIGURG);
                         pthread_join(monitor_thread, NULL);
                  }
@@ -2075,7 +2045,3 @@ char *key()
 {
        return ASTERISK_GPL_KEY;
 }
-
-
-
-