Hi again,
here is the doc I wrote. Please note it is a few years ago, probably for 
replicant 4, and mmssms.db format change a lot between android versions.

- Fil Lupin.

On Tuesday, August 31st, 2021 at 4:53 PM, Fil Lupin via Replicant 
<replicant@osuosl.org> wrote:

> Hi Augustine,
>
> I encountered some difficulties converting MMS from iOS to replicant so I 
> wrote a few things on this topic here : 
> https://redmine.replicant.us/boards/9/topics/14315
>
> It's slightly different but perhaps it can give you a few hints for your 
> issue.
>
> I remember writing some docs about DB columns meaning but sadly, I did not 
> found it yet. I'll let you know if I find it again.

The format of file /data/data/com.android.providers.telephony/databases/mmssms.db
is sqlite, it is accessible by root.


# Comparison between initial state and output of smstools

non empty tables :

- canonical_addresses
- threads
- sms



missing table :

- sqlite_sequence



## table addr

| name		| type		| description	|
| ------------- | ------------- | ------------- |
| _id		| INTEGER (primary key) |  ID		|
| msg_id	| INTEGER	| The ID of MM which this Address entry belongs to |
| contact_id	| INTEGER	| The ID of contact entry in Phone Book
| address	| TEXT		| The address text	|
| type		| INTEGER	| Type of address,must be one of PduHeaders.BCC, PduHeaders.CC, PduHeaders.FROM, PduHeaders.TO
| charset	| INTEGER	| Character set of entry |


## table android_metadata

| name          | type  |
| ------------- | ----- |
| locale	| TEXT	|


## table SMS (info about SMS)

This table is used by the SMS dispatcher to hold incomplete partial messages
until all the parts arrive.

| name	| type		| description	|
| _id	| INTEGER (primary key)	| SMS ID |
| thread_id| INTEGER	|The thread ID of the message |
| address| TEXT		| The address of the other party |
| person | INTEGER      | |
| date	| INTEGER	| The date the message was received |
| date_sent | INTEGER	| The date the message was sent |
| protocol | INTEGER	| The protocol identifier code |
| read	| INTEGER	| Has the message been read? (boolean) |
| status | INTEGER	| a TP-Status value or -1 if it status hasn't been received (default) |
|	|		| STATUS_COMPLETE=0 	TP-Status: complete. |
|	|		| STATUS_FAILED=64 	TP-Status: failed. |
|	|		| STATUS_NONE=-1 	TP-Status: no status received. |
|	|		| STATUS_PENDING=32 	TP-Status: pending. |
|	|		| http://www.etsi.org/deliver/etsi_gts/03/0340/05.03.00_60/gsmts_0340v050300p.pdf |
| type	| INTEGER	| The type of message	|
|	|		| unsure sense ?	|
|	|		| 1 if sent,		|
|	|		| 2 if received		|
|	|		| 3 if ?		|
| reply_path_present | INTEGER | 		|
| subject | TEXT	| The subject of the message, if present |
| body	| TEXT | The body of the message |
| service_center | TEXT | The service center (SC) through which to send the message, if present |
| locked | INTEGER | Is the message locked?  (default 0) |
| error_code | INTEGER | Error code associated with sending or receiving this message (default 0) |
| seen | INTEGER | Indicates whether this message has been seen by the user. The "seen" flag will be used to figure out whether we need to throw up a statusbar notification or not (default 0) |


## table sr_pending

This table is used by the SMS dispatcher to hold pending delivery status report
intents.

| name			| type	|
| reference_number	| INTEGER |
| action		| TEXT |
| data			| TEXT |


## table threads

This table maps the subject and an ordered set of recipient
IDs, separated by spaces, to a unique thread ID. The IDs
come from the canonical_addresses table. This works
because messages are considered to be part of the same
thread if they have the same subject (or a null subject)
and the same set of recipients.

| name	| type | description |
| _id	| INTEGER PRIMARY KEY |	autoincremented id |
| date	| INTEGER | The date at which the thread was created (default 0) |
| message_count | INTEGER | The message count of the thread (default 0) |
| recipient_ids | TEXT | A string encoding of the recipient IDs of the recipients of the message, in numerical order and separated by spaces = canonical_addresses._id |
| snippet | TEXT | The snippet of the latest message in the thread |
| snippet_cs | INTEGER | The charset of the snippet (default 0) |
| read | INTEGER | Indicates whether all messages of the thread have been read (default 1) |
| type | INTEGER | Type of the thread, either Threads.COMMON_THREAD=0 or Threads.BROADCAST_THREAD=1 |
| error | INTEGER | Indicates whether there is a transmission error in the thread (default 0) |
| has_attachment | INTEGER | Indicates whether this thread contains any attachments (1), or 0 (default) if pure text |


## table words (FTS3)

- _id				(2<<32)+source_id
- index_text
- source_id
- table_to_use			1 or 2


## table words_content

- docid: INTEGER PRIMARY KEY
- c0_id				(2<<32)+ c2source_id
- c1index_text
- c2source_id
- c3table_to_use			1 or 2


## table words_segments

| name | type |
| blockid | INTEGER PRIMARY KEY |
| block | BLOB |


## table words_segdir

| name	| type 			|
| level | INTEGER PRIMARY KEY	|
| idx	| INTEGER 		|
| start_block	| INTEGER	|
| leaves_end_block | INTEGER	|
| end_block	| INTEGER	|
| root	| BLOB			|


## table attachments

| name | type | description |
| sms_id | INTEGER | ID	|
| content_url | TEXT | URL |
| offset | INTEGER | |


## table canonical_addresses

This table maps the first instance seen of any particular
MMS/SMS address to an ID, which is then used as its
canonical representation. If the same address or an
equivalent address (as determined by our Sqlite
PHONE_NUMBERS_EQUAL extension) is seen later, this same ID
will be used. The _id is created with AUTOINCREMENT so it
will never be reused again if a recipient is deleted.

| name	| type | description |
| _id	| INTEGER PRIMARY KEY | |
| address | TEXT | An address used in MMS or SMS. Email addresses are converted to lower case and are compared by string equality. Other addresses are compared using PHONE_NUMBERS_EQUAL |


## table drm

[ name	| type |
| _id	| INTEGER PRIMARY KEY |
| _data | TEXT |


## table part

| name	| type | description |
| _id	| INTEGER PRIMARY KEY | | 
| mid	| INTEGER | The identifier of the message which this part belongs to part._id = pdu._id |
| seq	| INTEGER | The order of the part |
| ct	| TEXT	|type MIME (cf. https://fr.wikipedia.org/wiki/Type_MIME) text/plain, image/jpeg, image/bmp, image/gif, image/jpg, image/png if text/plain or application/smil, MMS is not pure text and there is some attachment (has_attachment=1 in the thread from threads table) |
| name 	| TEXT | The name of the part | 
| chset	| INTEGER | The charset of the part
| cd	| TEXT	| The content disposition of the part |
| fn	| TEXT	| The file name of the part |
| cid	| TEXT	| The content ID of the part |
| cl	| TEXT	| The content location of the part |
| ctt_s	| INTEGER | The start of content-type of the message |
| ctt_t | TEXT	| The type of content-type of the message |
| _data | TEXT	| The location(on filesystem) of the binary data of the part (empty if text) |
| text	| TEXT	| content if text, empty else |


## table pdu (info sur les MMS)

source :
- http://www.xuebuyuan.com/1068475.html
- https://developer.android.com/reference/android/provider/Telephony.BaseMmsColumns.html1

| name	| type | description |
| _id	| INTEGER PRIMARY KEY | |
| thread_id | INTEGER | thread id |
| date	| INTEGER | The date the message was received (unix format) |
| date_sent | INTEGER | The date the message was sent (default 0) |
| msg_box | INTEGER | The box which the message belong to |
|	  |         | MESSAGE_BOX_ALL = 0 |
|	  |         | MESSAGE_BOX_INBOX = 1 |
|	  |         | MESSAGE_BOX_SENT   = 2 |
|	  |         | MESSAGE_BOX_DRAFTS = 3 |
|	  |         | MESSAGE_BOX_OUTBOX = 4 |
| read	| INTEGER	| Has the message been read? (boolean) |
| m_id	| TEXT	| The Message-ID of the message |
| sub	| TEXT	| The subject of the message, if present |
| sub_cs| INTEGER | The character set of the subject, if present |
| ct_t	| TEXT	| The Content-Type of the message |
| ct_l	| TEXT	| The Content-Location of the message |
| exp	| INTEGER | The expiry time of the message |
| m_cls	| TEXT	| The class of the message |
| m_type| INTEGER | The type of the message defined by MMS spec |
|	|	| 128 if sent |
|	|	| 130 si à renvoyer, |
|	|	| 132 si réenvoyé |
| v	| INTEGER | The version of specification that this message conform |
| m_size| INTEGER | The size of the message |
| pri	| INTEGER | The priority of the message |
| rr	| INTEGER | The read-report of the message |
| rpt_a	| INTEGER | Whether the report is allowed |
| resp_st | INTEGER | The response-status of the message |
| st	| INTEGER | The status of the message | 
| tr_id	| TEXT	| The transaction-id of the message |
| retr_st | INTEGER | The retrieve-status of the message |
| retr_txt | TEXT | The retrieve-text of the message |
| retr_txt_cs | INTEGER | The character set of the retrieve-text |
| read_status | INTEGER | The read-status of the message | 
| ct_cls | INTEGER | The content-class of the message | 
| resp_txt | TEXT | The response-text of the message | 
| d_tm | INTEGER | The delivery-time of the message |
| d_rpt | INTEGER | The delivery-report of the message
| locked | INTEGER | Has the message been locked? |
| seen	| INTEGER | Indicates whether this message has been seen by the user. The "seen" flag will be used to figure out whether we need to throw up a statusbar notification or not (default 0) |


## table pending_msgs

This table stores the queue of messages to be sent/downloaded.

| name	| type | description |
| _id	| INTEGER PRIMARY KEY | ID |
| proto_type | INTEGER | The type of transport protocol(MMS or SMS) |
| msg_id | INTEGER | The ID of the message to be sent or downloaded |
| msg_type | INTEGER | The type of the message to be sent or downloaded |
| err_type | INTEGER | The type of the error code |
| err_code | INTEGER | The error code of sending/retrieving process |
| retry_index | INTEGER | How many times we tried to send or download the message |
| due_time | INTEGER | The time to do next retry |
| last_try | INTEGER | The time we last tried to send or download the message |


## table rate

sent_time: INTEGER		When a message was successfully sent

## table raw

| name	| type | description | 
| _id	| INTEGER PRIMARY KEY | |
| date	| INTEGER | |
| reference_number | INTEGER | one per full message |
| count	| INTEGER | the number of parts |
| sequence | INTEGER | the part number of this message |
| destination_port | INTEGER | | 
| address | TEXT | | 
| pdu | TEXT | the raw PDU for this part | 


sqlite_autoindex_words_segdir_1
typeThreadIdIndex


## sources :

https://stackoverflow.com/questions/3012287/how-to-read-mms-data-in-android
http://minhdanh2002.blogspot.de/2012/02/raw-access-to-sms-database-on-android.html
https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/jb-release/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java
http://www.etsi.org/deliver/etsi_gts/03/0340/05.03.00_60/gsmts_0340v050300p.pdf
SMS type 0 (ping SMS, stealth SMS): https://github.com/SecUpwN/Android-IMSI-Catcher-Detector/issues/69
https://github.com/domi007/silentSMS
http://forum.xda-developers.com/showthread.php?t=1422969
http://rednaxela.net/pdu.php
GSM localisation: http://blog.ptsecurity.com/2014/04/search-and-neutralize-how-to-determine.html
http://events.ccc.de/congress/2008/Fahrplan/attachments/1262_25c3-locating-mobile-phones.pdf
GSM card: http://gsmmap.org/

_______________________________________________
Replicant mailing list
Replicant@osuosl.org
https://lists.osuosl.org/mailman/listinfo/replicant

Reply via email to