The get_pai function in chan_sip.c didn't recognized a proper callerid name and
authorStefan Schmidt <sst@sil.at>
Wed, 18 Jan 2012 16:02:15 +0000 (16:02 +0000)
committerStefan Schmidt <sst@sil.at>
Wed, 18 Jan 2012 16:02:15 +0000 (16:02 +0000)
 number from a P-Asserted-Identity cause the header parsing logic was wrong.
Changing the parsing functions to the sip header parsing APIs in
reqresp_parser.h solves this problem.

Review: https://reviewboard.asterisk.org/r/1673
Reviewed by: wdoekes2 and Mark Michelson
........

Merged revisions 351396 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........

Merged revisions 351408 from http://svn.asterisk.org/svn/asterisk/branches/10

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@351409 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_sip.c

index b836f24..c9ca7d8 100644 (file)
@@ -15235,10 +15235,12 @@ static int get_pai(struct sip_pvt *p, struct sip_request *req)
 {
        char pai[256];
        char privacy[64];
-       char *cid_num = "";
-       char *cid_name = "";
+       char *cid_num = NULL;
+       char *cid_name = NULL;
+       char emptyname[1] = "";
        int callingpres = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
-       char *start = NULL, *end = NULL, *uri = NULL;
+       char *uri = NULL;
+       int is_anonymous = 0, do_update = 1, no_name = 0;
 
        ast_copy_string(pai, sip_get_header(req, "P-Asserted-Identity"), sizeof(pai));
 
@@ -15246,73 +15248,59 @@ static int get_pai(struct sip_pvt *p, struct sip_request *req)
                return 0;
        }
 
-       start = pai;
-       if (*start == '"') {
-               *start++ = '\0';
-               end = strchr(start, '"');
-               if (!end) {
-                       return 0;
-               }
-               *end++ = '\0';
-               cid_name = start;
-               start = ast_skip_blanks(end);
+       /* use the reqresp_parser function get_name_and_number*/
+       if (get_name_and_number(pai, &cid_name, &cid_num)) {
+               return 0;
        }
 
-       if (*start != '<')
-               return 0;
-       /* At this point, 'start' points to the URI in brackets.
-        * We need a copy so that our comparison to the anonymous
-        * URI is valid.
-        */
-       uri = ast_strdupa(start);
-       *start++ = '\0';
-       end = strchr(start, '@');
-       if (!end) {
-               return 0;
+       if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(cid_num)) {
+               ast_shrink_phone_number(cid_num);
        }
-       *end++ = '\0';
+
+       uri = get_in_brackets(pai);
        if (!strncasecmp(uri, "sip:anonymous@anonymous.invalid", 31)) {
                callingpres = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
                /*XXX Assume no change in cid_num. Perhaps it should be
                 * blanked?
                 */
+               ast_free(cid_num);
+               is_anonymous = 1;
                cid_num = (char *)p->cid_num;
-       } else if (!strncasecmp(start, "sip:", 4)) {
-               cid_num = start + 4;
-               if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(cid_num))
-                       ast_shrink_phone_number(cid_num);
-               start = end;
-
-               end = strchr(start, '>');
-               if (!end) {
-                       return 0;
-               }
-               *end = '\0';
-       } else {
-               return 0;
        }
 
        ast_copy_string(privacy, sip_get_header(req, "Privacy"), sizeof(privacy));
        if (!ast_strlen_zero(privacy) && strncmp(privacy, "id", 2)) {
                callingpres = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
        }
-
+       if (!cid_name) {
+               no_name = 1;
+               cid_name = (char *)emptyname;
+       }       
        /* Only return true if the supplied caller id is different */
        if (!strcasecmp(p->cid_num, cid_num) && !strcasecmp(p->cid_name, cid_name) && p->callingpres == callingpres) {
-               return 0;
-       }
+               do_update = 0;
+       } else {
 
-       ast_string_field_set(p, cid_num, cid_num);
-       ast_string_field_set(p, cid_name, cid_name);
-       p->callingpres = callingpres;
+               ast_string_field_set(p, cid_num, cid_num);
+               ast_string_field_set(p, cid_name, cid_name);
+               p->callingpres = callingpres;
 
-       if (p->owner) {
-               ast_set_callerid(p->owner, cid_num, cid_name, NULL);
-               p->owner->caller.id.name.presentation = callingpres;
-               p->owner->caller.id.number.presentation = callingpres;
+               if (p->owner) {
+                       ast_set_callerid(p->owner, cid_num, cid_name, NULL);
+                       p->owner->caller.id.name.presentation = callingpres;
+                       p->owner->caller.id.number.presentation = callingpres;
+               }
        }
 
-       return 1;
+       /* get_name_and_number allocates memory for cid_num and cid_name so we have to free it */
+       if (!is_anonymous) {
+               ast_free(cid_num);
+       }
+       if (!no_name) {
+               ast_free(cid_name);
+       }
+
+       return do_update;
 }
 
 /*! \brief Get name, number and presentation from remote party id header,