View Javadoc

1   /* ***** BEGIN LICENSE BLOCK *****
2    * Version: MPL 1.1
3    *
4    * The contents of this file are subject to the Mozilla Public License Version
5    * 1.1 (the "License"); you may not use this file except in compliance with
6    * the License. You may obtain a copy of the License at
7    * http://www.mozilla.org/MPL/
8    *
9    * Software distributed under the License is distributed on an "AS IS" basis,
10   * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11   * for the specific language governing rights and limitations under the
12   * License.
13   *
14   * The Original Code is "SMS Library for the Java platform".
15   *
16   * The Initial Developer of the Original Code is Markus Eriksson.
17   * Portions created by the Initial Developer are Copyright (C) 2002
18   * the Initial Developer. All Rights Reserved.
19   *
20   * Contributor(s):
21   *
22   * ***** END LICENSE BLOCK ***** */
23  package org.marre.sms.siemens;
24  
25  import java.io.File;
26  import java.io.FileInputStream;
27  import java.io.IOException;
28  import java.util.Random;
29  
30  import org.marre.sms.SmsDcs;
31  import org.marre.sms.SmsMessage;
32  import org.marre.sms.SmsConstants;
33  import org.marre.sms.SmsPdu;
34  import org.marre.util.StringUtil;
35  
36  /***
37   * 
38   * @author Raphael Borg Ellul Vincenti
39   * @version $Id: SiemensOtaMessage.java,v 1.4 2005/05/06 13:55:14 c95men Exp $
40   */
41  public class SiemensOtaMessage implements SmsMessage
42  {
43      protected int myVersion = 1;
44      protected String myName = "";
45      protected String myType = "";
46      protected long myReferenceId;
47      protected int myDataSize;
48      protected int myNumberOfPackets;
49      protected byte[] myContent;
50  
51      /***
52       * Creates an SMS containing a Bitmap or a Ringtone
53       * 
54       * @param theMessage
55       *            The content in bytes
56       */
57      public SiemensOtaMessage(String name, String type, byte[] content)
58      {
59          myName = name;
60          myType = type;
61          myContent = content;
62  
63          init();
64      }
65  
66      /***
67       * Creates an SMS containing a Bitmap or a Ringtone
68       * 
69       * @param theMessage
70       *            The content in bytes
71       */
72      public SiemensOtaMessage(int version, String name, String type, byte[] content)
73      {
74          this.myVersion = version;
75          this.myName = name;
76          this.myType = type;
77          this.myContent = content;
78  
79          init();
80  
81      }
82  
83      /***
84       * 
85       *  
86       */
87      private void init()
88      {
89          this.myReferenceId = (new Random()).nextLong();
90          this.myDataSize = 140 - 22 - myName.length() - myType.length();
91          this.myNumberOfPackets = (int) Math.ceil((float) myContent.length / (float) myDataSize);
92      }
93  
94      /***
95       * Returns the userdata header for an SMS
96       * 
97       * @return
98       */
99      private byte[] getHeader(int actPacketNumber)
100     {
101         byte[] header = new byte[22 + myName.length() + myType.length()];
102 
103         // Identifier: "//SEO"
104         header[0] = (byte) 0x2f;
105         header[1] = (byte) 0x2f;
106         header[2] = (byte) 0x53;
107         header[3] = (byte) 0x45;
108         header[4] = (byte) 0x4f;
109 
110         // Version
111         header[5] = (byte) (myVersion & 0xff);
112 
113         // DataSize
114         header[6] = (byte) (myDataSize & 0xff);
115         header[7] = (byte) ((myDataSize >> 8) & 0xff);
116 
117         // ReferenceId
118         header[8] = (byte) (myReferenceId & 0xff);
119         header[9] = (byte) ((myReferenceId >> 8) & 0xff);
120         header[10] = (byte) ((myReferenceId >> 16) & 0xff);
121         header[11] = (byte) ((myReferenceId >> 24) & 0xff);
122 
123         // ActPacketNumber
124         header[12] = (byte) (actPacketNumber & 0xff);
125         header[13] = (byte) ((actPacketNumber >> 8) & 0xff);
126 
127         // NumberOfPackets
128         header[14] = (byte) (myNumberOfPackets & 0xff);
129         header[15] = (byte) ((myNumberOfPackets >> 8) & 0xff);
130 
131         // ObjectSize
132         header[16] = (byte) (myContent.length & 0xff);
133         header[17] = (byte) ((myContent.length >> 8) & 0xff);
134         header[18] = (byte) ((myContent.length >> 16) & 0xff);
135         header[19] = (byte) ((myContent.length >> 24) & 0xff);
136 
137         // ObjectType (Pascal String)
138         header[20] = (byte) (myType.length() & 0xff);
139         header[21] = (byte) (myType.charAt(0) & 0xff);
140         header[22] = (byte) (myType.charAt(1) & 0xff);
141         header[23] = (byte) (myType.charAt(2) & 0xff);
142 
143         // ObjectName (Pascal String)
144         header[24] = (byte) (myName.length() & 0xff);
145         for (int i = 0; i < myName.length(); i++)
146         {
147             header[25 + i] = (byte) ((myName.charAt(i)) & 0xff);
148         }
149 
150         return header;
151     }
152 
153     /***
154      * Converts this message into SmsPdu:s
155      * <p>
156      * If the message is too long to fit in one SmsPdu the message is divided
157      * into many SmsPdu:s with a different packet number
158      * 
159      * @return Returns the message as SmsPdu:s
160      */
161     public SmsPdu[] getPdus()
162     {
163         SmsPdu[] smsPdus = new SmsPdu[myNumberOfPackets];
164         SmsDcs dcs = SmsDcs.getGeneralDataCodingDcs(SmsDcs.ALPHABET_8BIT, SmsDcs.MSG_CLASS_1);
165         for (int i = 0; i < myNumberOfPackets; i++)
166         {
167 
168             byte[] pdu = new byte[140];
169             byte[] header = getHeader(i + 1);
170 
171             System.arraycopy(header, 0, pdu, 0, header.length);
172             int offset = myDataSize * i;
173 
174             // Handle last SMS
175             if (i == (myNumberOfPackets - 1))
176             {
177                 myDataSize = myContent.length % myDataSize;
178             }
179 
180             System.arraycopy(myContent, offset, pdu, header.length, myDataSize);
181 
182             SmsPdu smsPdu = new SmsPdu(null, pdu, pdu.length, dcs);
183             smsPdus[i] = smsPdu;
184         }
185 
186         return smsPdus;
187     }
188 
189     /*
190      *  
191      */
192     public static byte[] loadFromFile(File file) throws IOException
193     {
194         int n;
195         int nread = 0;
196         int len = (int) file.length();
197 
198         FileInputStream fin = new FileInputStream(file);
199 
200         byte[] content = new byte[len];
201 
202         while (nread < len)
203         {
204 
205             if ((n = fin.read(content, nread, len - nread)) == -1)
206             {
207                 throw new IOException("Error loading Compound from file");
208             }
209             nread += n;
210         }
211 
212         return content;
213     }
214 
215     public static void main(String[] args)
216     {
217         String name = "Operator.bmp";
218         String type = "bmp";
219 
220         byte[] data = null;
221 
222         try
223         {
224             data = loadFromFile(new File(args[0]));
225         }
226         catch (IOException e)
227         {
228             e.printStackTrace();
229         }
230 
231         SiemensOtaMessage message = new SiemensOtaMessage(22518750, name, type, data);
232 
233         SmsPdu[] pdus = message.getPdus();
234 
235         System.out.println("Data   : " + StringUtil.bytesToHexString(data));
236 
237         for (int i = 0; i < pdus.length; i++)
238         {
239             System.out.println("UD     : " + StringUtil.bytesToHexString(pdus[i].getUserData().getData()));
240         }
241     }
242 
243 }