Index: pjproject/trunk/pjsip/src/pjsip/sip_msg.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip/sip_msg.c	(revision 2004)
+++ pjproject/trunk/pjsip/src/pjsip/sip_msg.c	(revision 2005)
@@ -1132,4 +1132,6 @@
 
 	if (hdr->q1000) {
+	    unsigned frac;
+
 	    if (buf+19 >= endbuf)
 		return -1;
@@ -1142,7 +1144,12 @@
 	    printed = pj_utoa(hdr->q1000/1000, buf+3);
 	    buf += printed + 3;
-	    *buf++ = '.';
-	    printed = pj_utoa(hdr->q1000 % 1000, buf);
-	    buf += printed;
+	    frac = hdr->q1000 % 1000;
+	    if (frac != 0) {
+		*buf++ = '.';
+		if ((frac % 100)==0) frac /= 100;
+		if ((frac % 10)==0) frac /= 10;
+		printed = pj_utoa(frac, buf);
+		buf += printed;
+	    }
 	}
 
Index: pjproject/trunk/pjsip/src/pjsip/sip_parser.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip/sip_parser.c	(revision 2004)
+++ pjproject/trunk/pjsip/src/pjsip/sip_parser.c	(revision 2005)
@@ -1641,9 +1641,14 @@
 	    char *dot_pos = (char*) pj_memchr(pvalue.ptr, '.', pvalue.slen);
 	    if (!dot_pos) {
-		hdr->q1000 = pj_strtoul(&pvalue);
+		hdr->q1000 = pj_strtoul(&pvalue) * 1000;
 	    } else {
+		pj_str_t tmp = pvalue;
+
+		tmp.slen = dot_pos - pvalue.ptr;
+		hdr->q1000 = pj_strtoul(&tmp) * 1000;
+
 		pvalue.slen = (pvalue.ptr+pvalue.slen) - (dot_pos+1);
 		pvalue.ptr = dot_pos + 1;
-		hdr->q1000 = pj_strtoul_mindigit(&pvalue, 3);
+		hdr->q1000 += pj_strtoul_mindigit(&pvalue, 3);
 	    }    
 	} else if (!parser_stricmp(pname, pconst.pjsip_EXPIRES_STR) && pvalue.slen) {
Index: pjproject/trunk/pjsip/src/test-pjsip/msg_test.c
===================================================================
--- pjproject/trunk/pjsip/src/test-pjsip/msg_test.c	(revision 2004)
+++ pjproject/trunk/pjsip/src/test-pjsip/msg_test.c	(revision 2005)
@@ -790,4 +790,9 @@
 static int hdr_test_contact0(pjsip_hdr *h);
 static int hdr_test_contact1(pjsip_hdr *h);
+static int hdr_test_contact_q0(pjsip_hdr *h);
+static int hdr_test_contact_q1(pjsip_hdr *h);
+static int hdr_test_contact_q2(pjsip_hdr *h);
+static int hdr_test_contact_q3(pjsip_hdr *h);
+static int hdr_test_contact_q4(pjsip_hdr *h);
 static int hdr_test_content_length(pjsip_hdr *h);
 static int hdr_test_content_type(pjsip_hdr *h);
@@ -898,4 +903,41 @@
 
     {
+	/* q=0 parameter in Contact header */
+	"Contact", "m",
+	NAME_ADDR ";q=0",
+	&hdr_test_contact_q0,
+	HDR_FLAG_DONT_PRINT
+    },
+
+    {
+	/* q=0.5 parameter in Contact header */
+	"Contact", "m",
+	NAME_ADDR ";q=0.5",
+	&hdr_test_contact_q1
+    },
+
+    {
+	/* q=1 parameter in Contact header */
+	"Contact", "m",
+	NAME_ADDR ";q=1",
+	&hdr_test_contact_q2
+    },
+
+    {
+	/* q=1.0 parameter in Contact header */
+	"Contact", "m",
+	NAME_ADDR ";q=1.0",
+	&hdr_test_contact_q3,
+	HDR_FLAG_DONT_PRINT
+    },
+
+    {
+	/* q=1.1 parameter in Contact header */
+	"Contact", "m",
+	NAME_ADDR ";q=1.15",
+	&hdr_test_contact_q4
+    },
+
+    {
 	/* Content-Length */
 	"Content-Length", "l",
@@ -1271,4 +1313,109 @@
     if (rc != 0)
 	return rc;
+
+    return 0;
+}
+
+/*
+    NAME_ADDR ";q=0"
+ */
+static int hdr_test_contact_q0(pjsip_hdr *h)
+{
+    pjsip_contact_hdr *hdr = (pjsip_contact_hdr*)h;
+    int rc;
+
+    if (h->type != PJSIP_H_CONTACT)
+	return -1710;
+
+    rc = nameaddr_test(hdr->uri);
+    if (rc != 0)
+	return rc;
+
+    if (hdr->q1000 != 0)
+	return -1711;
+
+    return 0;
+}
+
+/*
+    NAME_ADDR ";q=0.5"
+ */
+static int hdr_test_contact_q1(pjsip_hdr *h)
+{
+    pjsip_contact_hdr *hdr = (pjsip_contact_hdr*)h;
+    int rc;
+
+    if (h->type != PJSIP_H_CONTACT)
+	return -1710;
+
+    rc = nameaddr_test(hdr->uri);
+    if (rc != 0)
+	return rc;
+
+    if (hdr->q1000 != 500)
+	return -1712;
+
+    return 0;
+}
+
+/*
+    NAME_ADDR ";q=1"
+ */
+static int hdr_test_contact_q2(pjsip_hdr *h)
+{
+    pjsip_contact_hdr *hdr = (pjsip_contact_hdr*)h;
+    int rc;
+
+    if (h->type != PJSIP_H_CONTACT)
+	return -1710;
+
+    rc = nameaddr_test(hdr->uri);
+    if (rc != 0)
+	return rc;
+
+    if (hdr->q1000 != 1000)
+	return -1713;
+
+    return 0;
+}
+
+/*
+    NAME_ADDR ";q=1.0"
+ */
+static int hdr_test_contact_q3(pjsip_hdr *h)
+{
+    pjsip_contact_hdr *hdr = (pjsip_contact_hdr*)h;
+    int rc;
+
+    if (h->type != PJSIP_H_CONTACT)
+	return -1710;
+
+    rc = nameaddr_test(hdr->uri);
+    if (rc != 0)
+	return rc;
+
+    if (hdr->q1000 != 1000)
+	return -1714;
+
+    return 0;
+}
+
+/*
+    NAME_ADDR ";q=1.15"
+ */
+static int hdr_test_contact_q4(pjsip_hdr *h)
+{
+    pjsip_contact_hdr *hdr = (pjsip_contact_hdr*)h;
+    int rc;
+
+    if (h->type != PJSIP_H_CONTACT)
+	return -1710;
+
+    rc = nameaddr_test(hdr->uri);
+    if (rc != 0)
+	return rc;
+
+    if (hdr->q1000 != 1150)
+	return -1715;
 
     return 0;
