jeffrafter-rubygsm 0.3.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bin/sms +38 -0
- data/lib/rubygsm/core.rb +215 -48
- data/lib/rubygsm/errors.rb +5 -1
- data/lib/rubygsm/log.rb +24 -0
- data/lib/rubygsm/msg/incoming.rb +5 -2
- data/lib/rubygsm/msg/outgoing.rb +7 -0
- data/rubygsm.gemspec +8 -6
- metadata +16 -4
data/bin/sms
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# vim: noet
|
3
|
+
|
4
|
+
dir = File.dirname(__FILE__)
|
5
|
+
require "#{dir}/../lib/rubygsm.rb"
|
6
|
+
|
7
|
+
|
8
|
+
# expand args (TODO: optparser,
|
9
|
+
# which we need so very badly)
|
10
|
+
# or fail with USAGE message
|
11
|
+
if (ARGV.length == 2)
|
12
|
+
recipient, msg = *ARGV
|
13
|
+
port = :auto
|
14
|
+
|
15
|
+
elsif (ARGV.length == 3)
|
16
|
+
port, recipient, msg = *ARGV
|
17
|
+
|
18
|
+
else
|
19
|
+
puts "Usage: sms [PORT] RECIPIENT MESSAGE"
|
20
|
+
puts "(don't forget to quote the message)"
|
21
|
+
puts
|
22
|
+
puts "Examples:"
|
23
|
+
puts ' sms +13474201234 Hello'
|
24
|
+
puts ' sms /dev/ttyS0 +13474201234 "Hello from RubyGSM"'
|
25
|
+
exit
|
26
|
+
end
|
27
|
+
|
28
|
+
# initialize the modem, send the sms, and
|
29
|
+
# terminate. currently, rubygsm does a lot
|
30
|
+
# of things that aren't strictly required
|
31
|
+
# to get this done; maybe refactor
|
32
|
+
begin
|
33
|
+
modem = Gsm::Modem.new(port)
|
34
|
+
modem.send_sms!(recipient, msg)
|
35
|
+
|
36
|
+
rescue Gsm::Error => err
|
37
|
+
puts "Error: #{err.desc}"
|
38
|
+
end
|
data/lib/rubygsm/core.rb
CHANGED
@@ -18,8 +18,7 @@ module Gsm
|
|
18
18
|
class Modem
|
19
19
|
include Timeout
|
20
20
|
|
21
|
-
|
22
|
-
attr_accessor :verbosity, :read_timeout
|
21
|
+
attr_accessor :verbosity, :read_timeout, :keep_inbox_empty
|
23
22
|
attr_reader :device, :port
|
24
23
|
|
25
24
|
# call-seq:
|
@@ -56,16 +55,25 @@ class Modem
|
|
56
55
|
# tried all ports, nothing worked
|
57
56
|
raise AutoDetectError
|
58
57
|
end
|
59
|
-
|
60
|
-
|
58
|
+
|
59
|
+
# if the port was a port number or file
|
60
|
+
# name, initialize a serialport object
|
61
|
+
elsif port.is_a?(String) or port.is_a?(Fixnum)
|
61
62
|
@device = SerialPort.new(port, baud, 8, 1, SerialPort::NONE)
|
62
63
|
@port = port
|
64
|
+
|
65
|
+
# otherwise, we'll assume that the object passed
|
66
|
+
# was an object ready to quack like a serial modem
|
67
|
+
else
|
68
|
+
@device = port
|
69
|
+
@port = nil
|
63
70
|
end
|
64
71
|
|
65
72
|
@cmd_delay = cmd_delay
|
66
73
|
@verbosity = verbosity
|
67
74
|
@read_timeout = 10
|
68
75
|
@locked_to = false
|
76
|
+
@encoding = nil
|
69
77
|
|
70
78
|
# keep track of the depth which each
|
71
79
|
# thread is indented in the log
|
@@ -76,33 +84,35 @@ class Modem
|
|
76
84
|
# the last part is delivered
|
77
85
|
@multipart = {}
|
78
86
|
|
79
|
-
#
|
80
|
-
|
81
|
-
|
82
|
-
# initialization message (yes, it's underlined)
|
83
|
-
msg = "RubyGSM Initialized at: #{Time.now}"
|
84
|
-
log msg + "\n" + ("=" * msg.length), :file
|
87
|
+
# start logging to file
|
88
|
+
log_init
|
85
89
|
|
86
90
|
# to store incoming messages
|
87
91
|
# until they're dealt with by
|
88
92
|
# someone else, like a commander
|
89
93
|
@incoming = []
|
90
94
|
|
91
|
-
# initialize the modem
|
92
|
-
|
93
|
-
#
|
94
|
-
|
95
|
-
|
95
|
+
# initialize the modem; rubygsm is (supposed to be) robust enough to function
|
96
|
+
# without these working (hence the "try_"), but they make different modems more
|
97
|
+
# consistant, and the logs a bit more sane.
|
98
|
+
try_command "ATE0" # echo off
|
99
|
+
try_command "AT+CMEE=1" # useful errors
|
100
|
+
try_command "AT+WIND=0" # no notifications
|
101
|
+
|
102
|
+
# PDU mode isn't supported right now (although
|
103
|
+
# it should be, because it's quite simple), so
|
104
|
+
# switching to text mode (mode 1) is MANDATORY
|
105
|
+
command "AT+CMGF=1"
|
96
106
|
end
|
97
107
|
|
98
108
|
|
99
|
-
|
100
|
-
|
101
109
|
private
|
102
110
|
|
103
111
|
|
104
112
|
INCOMING_FMT = "%y/%m/%d,%H:%M:%S%Z" #:nodoc:
|
105
|
-
|
113
|
+
CMGL_STATUS = "REC UNREAD" #:nodoc:
|
114
|
+
|
115
|
+
|
106
116
|
def parse_incoming_timestamp(ts)
|
107
117
|
# extract the weirdo quarter-hour timezone,
|
108
118
|
# convert it into a regular hourly offset
|
@@ -129,17 +139,17 @@ class Modem
|
|
129
139
|
next
|
130
140
|
end
|
131
141
|
|
132
|
-
# since this line IS a CMT string (an
|
142
|
+
# since this line IS a CMT string (an incoming
|
133
143
|
# SMS), parse it and store it to deal with later
|
134
144
|
unless m = lines[n].match(/^\+CMT: "(.+?)",.*?,"(.+?)".*?$/)
|
135
|
-
err = "Couldn't parse CMT data: #{
|
145
|
+
err = "Couldn't parse CMT data: #{lines[n]}"
|
136
146
|
raise RuntimeError.new(err)
|
137
147
|
end
|
138
148
|
|
139
149
|
# extract the meta-info from the CMT line,
|
140
150
|
# and the message from the FOLLOWING line
|
141
151
|
from, timestamp = *m.captures
|
142
|
-
|
152
|
+
msg_text = lines[n+1].strip
|
143
153
|
|
144
154
|
# notify the network that we accepted
|
145
155
|
# the incoming message (for read receipt)
|
@@ -157,12 +167,13 @@ class Modem
|
|
157
167
|
log "Receipt acknowledgement (CNMA) was rejected"
|
158
168
|
end
|
159
169
|
|
160
|
-
# we might abort if this
|
170
|
+
# we might abort if this part of a
|
171
|
+
# multi-part message, but not the last
|
161
172
|
catch :skip_processing do
|
162
173
|
|
163
174
|
# multi-part messages begin with ASCII char 130
|
164
|
-
if (
|
165
|
-
text =
|
175
|
+
if (msg_text[0] == 130) and (msg_text[1].chr == "@")
|
176
|
+
text = msg_text[7,999]
|
166
177
|
|
167
178
|
# ensure we have a place for the incoming
|
168
179
|
# message part to live as they are delivered
|
@@ -178,24 +189,25 @@ class Modem
|
|
178
189
|
|
179
190
|
# abort if this is not the last part
|
180
191
|
throw :skip_processing\
|
181
|
-
unless (
|
192
|
+
unless (msg_text[5] == 173)
|
182
193
|
|
183
194
|
# last part, so switch out the received
|
184
195
|
# part with the whole message, to be processed
|
185
196
|
# below (the sender and timestamp are the same
|
186
197
|
# for all parts, so no change needed there)
|
187
|
-
|
198
|
+
msg_text = @multipart[from].join("")
|
188
199
|
@multipart.delete(from)
|
189
200
|
end
|
190
201
|
|
191
202
|
# just in case it wasn't already obvious...
|
192
|
-
log "Received message from #{from}: #{
|
203
|
+
log "Received message from #{from}: #{msg_text.inspect}"
|
193
204
|
|
194
205
|
# store the incoming data to be picked up
|
195
206
|
# from the attr_accessor as a tuple (this
|
196
207
|
# is kind of ghetto, and WILL change later)
|
197
208
|
sent = parse_incoming_timestamp(timestamp)
|
198
|
-
|
209
|
+
msg = Gsm::Incoming.new(self, from, sent, msg_text)
|
210
|
+
@incoming.push(msg)
|
199
211
|
end
|
200
212
|
|
201
213
|
# drop the two CMT lines (meta-info and message),
|
@@ -313,7 +325,7 @@ class Modem
|
|
313
325
|
# then automatically re-try the command after
|
314
326
|
# a short delay. for others, propagate
|
315
327
|
rescue Error => err
|
316
|
-
log "Rescued: #{err.desc}"
|
328
|
+
log "Rescued (in #command): #{err.desc}"
|
317
329
|
|
318
330
|
if (err.type == "CMS") and (err.code == 515)
|
319
331
|
sleep 2
|
@@ -326,6 +338,24 @@ class Modem
|
|
326
338
|
end
|
327
339
|
|
328
340
|
|
341
|
+
# proxy a single command to #command, but catch any
|
342
|
+
# Gsm::Error exceptions that are raised, and return
|
343
|
+
# nil. This should be used to issue commands which
|
344
|
+
# aren't vital - of which there are VERY FEW.
|
345
|
+
def try_command(cmd, *args)
|
346
|
+
begin
|
347
|
+
log_incr "Trying Command: #{cmd}"
|
348
|
+
out = command(cmd, *args)
|
349
|
+
log_decr "=#{out}"
|
350
|
+
return out
|
351
|
+
|
352
|
+
rescue Error => err
|
353
|
+
log_then_decr "Rescued (in #try_command): #{err.desc}"
|
354
|
+
return nil
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
|
329
359
|
def query(cmd)
|
330
360
|
log_incr "Query: #{cmd}"
|
331
361
|
out = command cmd
|
@@ -352,7 +382,7 @@ class Modem
|
|
352
382
|
while true do
|
353
383
|
buf = read(term)
|
354
384
|
buffer.push(buf)
|
355
|
-
|
385
|
+
|
356
386
|
# some errors contain useful error codes,
|
357
387
|
# so raise a proper error with a description
|
358
388
|
if m = buf.match(/^\+(CM[ES]) ERROR: (\d+)$/)
|
@@ -646,15 +676,38 @@ class Modem
|
|
646
676
|
# send_sms(message) => true or false
|
647
677
|
# send_sms(recipient, text) => true or false
|
648
678
|
#
|
679
|
+
# Sends an SMS message via _send_sms!_, but traps
|
680
|
+
# any exceptions raised, and returns false instead.
|
681
|
+
# Use this when you don't really care if the message
|
682
|
+
# was sent, which is... never.
|
683
|
+
def send_sms(*args)
|
684
|
+
begin
|
685
|
+
send_sms!(*args)
|
686
|
+
return true
|
687
|
+
|
688
|
+
# something went wrong
|
689
|
+
rescue Gsm::Error
|
690
|
+
return false
|
691
|
+
end
|
692
|
+
end
|
693
|
+
|
694
|
+
|
695
|
+
# call-seq:
|
696
|
+
# send_sms!(message) => true or raises Gsm::Error
|
697
|
+
# send_sms!(receipt, text) => true or raises Gsm::Error
|
698
|
+
#
|
649
699
|
# Sends an SMS message, and returns true if the network
|
650
700
|
# accepted it for delivery. We currently can't handle read
|
651
|
-
# receipts, so have no way of confirming delivery.
|
701
|
+
# receipts, so have no way of confirming delivery. If the
|
702
|
+
# device or network rejects the message, a Gsm::Error is
|
703
|
+
# raised containing (hopefully) information about what went
|
704
|
+
# wrong.
|
652
705
|
#
|
653
706
|
# Note: the recipient is passed directly to the modem, which
|
654
707
|
# in turn passes it straight to the SMSC (sms message center).
|
655
|
-
#
|
708
|
+
# For maximum compatibility, use phone numbers in international
|
656
709
|
# format, including the *plus* and *country code*.
|
657
|
-
def send_sms(*args)
|
710
|
+
def send_sms!(*args)
|
658
711
|
|
659
712
|
# extract values from Outgoing object.
|
660
713
|
# for now, this does not offer anything
|
@@ -699,6 +752,9 @@ class Modem
|
|
699
752
|
# the text prompt or an error message
|
700
753
|
command "AT+CMGS=\"#{to}\"", ["\r\n", "> "]
|
701
754
|
|
755
|
+
# encode the message using the setup encoding or the default
|
756
|
+
msg = encode(msg)
|
757
|
+
|
702
758
|
begin
|
703
759
|
# send the sms, and wait until
|
704
760
|
# it is accepted or rejected
|
@@ -712,26 +768,51 @@ class Modem
|
|
712
768
|
# an escpae, to... escape
|
713
769
|
rescue Exception, Timeout::Error => err
|
714
770
|
log "Rescued #{err.desc}"
|
715
|
-
|
716
|
-
|
717
|
-
#
|
771
|
+
write 27.chr
|
772
|
+
|
773
|
+
# allow the error to propagate,
|
774
|
+
# so the application can catch
|
775
|
+
# it for more useful info
|
776
|
+
raise
|
777
|
+
|
778
|
+
ensure
|
779
|
+
log_decr
|
718
780
|
end
|
719
|
-
|
720
|
-
log_decr
|
721
781
|
end
|
722
782
|
|
723
783
|
# if no error was raised,
|
724
784
|
# then the message was sent
|
725
785
|
return true
|
726
786
|
end
|
727
|
-
|
728
|
-
|
787
|
+
|
788
|
+
# Encodes the message using the set encoding or, if no encoding is specified
|
789
|
+
# returns the msg unchange
|
790
|
+
def encode(msg)
|
791
|
+
if (@encoding == :ascii)
|
792
|
+
# TODO, use lucky sneaks here
|
793
|
+
msg
|
794
|
+
elsif (@encoding == :utf8)
|
795
|
+
# Unpacking and repacking supposedly cleans out bad (non-UTF-8) stuff
|
796
|
+
utf8 = msg.unpack("U*");
|
797
|
+
packed = utf8.pack("U*");
|
798
|
+
packed
|
799
|
+
elsif (@encoding == :ucs2)
|
800
|
+
ucs2 = Iconv.iconv("UCS-2", "UTF-8", msg).first
|
801
|
+
ucs2 = ucs2.unpack("H*").join
|
802
|
+
ucs2
|
803
|
+
else
|
804
|
+
msg
|
805
|
+
end
|
806
|
+
end
|
807
|
+
|
729
808
|
# call-seq:
|
730
809
|
# receive(callback_method, interval=5, join_thread=false)
|
731
810
|
#
|
732
811
|
# Starts a new thread, which polls the device every _interval_
|
733
812
|
# seconds to capture incoming SMS and call _callback_method_
|
734
|
-
# for each
|
813
|
+
# for each, and polls the device's internal storage for incoming
|
814
|
+
# SMS that we weren't notified about (some modems don't support
|
815
|
+
# that).
|
735
816
|
#
|
736
817
|
# class Receiver
|
737
818
|
# def incoming(msg)
|
@@ -760,15 +841,25 @@ class Modem
|
|
760
841
|
# keep on receiving forever
|
761
842
|
while true
|
762
843
|
command "AT"
|
763
|
-
|
764
|
-
|
765
|
-
# enable new message notification mode
|
766
|
-
# every ten intevals, in case the
|
844
|
+
|
845
|
+
# enable new message notification mode every ten intevals, in case the
|
767
846
|
# modem "forgets" (power cycle, etc)
|
768
847
|
if (@polled % 10) == 0
|
769
|
-
|
848
|
+
try_command("AT+CNMI=2,2,0,0,0")
|
770
849
|
end
|
850
|
+
|
851
|
+
# check for messages in the default mailbox (wether read or not)
|
852
|
+
# read them and then delete them
|
853
|
+
if (@keep_inbox_empty)
|
854
|
+
fetch_and_delete_stored_messages
|
855
|
+
end
|
771
856
|
|
857
|
+
# check for new messages lurking in the device's
|
858
|
+
# memory (in case we missed them (yes, it happens))
|
859
|
+
if (@polled % 4) == 0
|
860
|
+
fetch_stored_messages
|
861
|
+
end
|
862
|
+
|
772
863
|
# if there are any new incoming messages,
|
773
864
|
# iterate, and pass each to the receiver
|
774
865
|
# in the same format that they were built
|
@@ -800,7 +891,32 @@ class Modem
|
|
800
891
|
# threaded (like debugging handsets)
|
801
892
|
@thr.join if join_thread
|
802
893
|
end
|
894
|
+
|
803
895
|
|
896
|
+
def encodings?
|
897
|
+
command "AT+CSCS=?"
|
898
|
+
end
|
899
|
+
|
900
|
+
def encoding
|
901
|
+
@encoding
|
902
|
+
end
|
903
|
+
|
904
|
+
def encoding=(enc)
|
905
|
+
@encoding = enc
|
906
|
+
case enc
|
907
|
+
when :ascii
|
908
|
+
command "AT+CSCS=\"ASCII\""
|
909
|
+
when :utf8
|
910
|
+
command "AT+CSCS=\"UTF8\""
|
911
|
+
when :ucs2
|
912
|
+
command "AT+CSCS=\"UCS2\""
|
913
|
+
when :gsm
|
914
|
+
command "AT+CSCS=\"GSM\""
|
915
|
+
when :iso88591
|
916
|
+
command "AT+CSCS=\"8859-1\""
|
917
|
+
end
|
918
|
+
end
|
919
|
+
|
804
920
|
def select_default_mailbox
|
805
921
|
# Eventually we will select the first mailbox as the default
|
806
922
|
result = command("AT+CPMS=?")
|
@@ -813,8 +929,8 @@ class Modem
|
|
813
929
|
nil
|
814
930
|
end
|
815
931
|
|
816
|
-
|
817
|
-
|
932
|
+
def fetch_and_delete_stored_messages
|
933
|
+
# If there is no way to select a default mailbox we can't continue
|
818
934
|
return unless select_default_mailbox
|
819
935
|
|
820
936
|
# Try to read the first message from the box (should this be 0?)
|
@@ -847,5 +963,56 @@ class Modem
|
|
847
963
|
@incoming.push Gsm::Incoming.new(self, from, sent, msg)
|
848
964
|
end
|
849
965
|
|
966
|
+
def fetch_stored_messages
|
967
|
+
|
968
|
+
# fetch all/unread (see constant) messages
|
969
|
+
lines = command('AT+CMGL="%s"' % CMGL_STATUS)
|
970
|
+
n = 0
|
971
|
+
|
972
|
+
# if the last line returned is OK
|
973
|
+
# (and it SHOULD BE), remove it
|
974
|
+
lines.pop if lines[-1] == "OK"
|
975
|
+
|
976
|
+
# keep on iterating the data we received,
|
977
|
+
# until there's none left. if there were no
|
978
|
+
# stored messages waiting, this done nothing!
|
979
|
+
while n < lines.length
|
980
|
+
|
981
|
+
# attempt to parse the CMGL line (we're skipping
|
982
|
+
# two lines at a time in this loop, so we will
|
983
|
+
# always land at a CMGL line here) - they look like:
|
984
|
+
# +CMGL: 0,"REC READ","+13364130840",,"09/03/04,21:59:31-20"
|
985
|
+
unless m = lines[n].match(/^\+CMGL: (\d+),"(.+?)","(.+?)",*?,"(.+?)".*?$/)
|
986
|
+
err = "Couldn't parse CMGL data: #{lines[n]}"
|
987
|
+
raise RuntimeError.new(err)
|
988
|
+
end
|
989
|
+
|
990
|
+
# find the index of the next
|
991
|
+
# CMGL line, or the end
|
992
|
+
nn = n+1
|
993
|
+
nn += 1 until\
|
994
|
+
nn >= lines.length ||\
|
995
|
+
lines[nn][0,6] == "+CMGL:"
|
996
|
+
|
997
|
+
# extract the meta-info from the CMGL line, and the
|
998
|
+
# message text from the lines between _n_ and _nn_
|
999
|
+
index, status, from, timestamp = *m.captures
|
1000
|
+
msg_text = lines[(n+1)..(nn-1)].join("\n").strip
|
1001
|
+
|
1002
|
+
# log the incoming message
|
1003
|
+
log "Fetched stored message from #{from}: #{msg_text.inspect}"
|
1004
|
+
|
1005
|
+
# store the incoming data to be picked up
|
1006
|
+
# from the attr_accessor as a tuple (this
|
1007
|
+
# is kind of ghetto, and WILL change later)
|
1008
|
+
sent = parse_incoming_timestamp(timestamp)
|
1009
|
+
msg = Gsm::Incoming.new(self, from, sent, msg_text)
|
1010
|
+
@incoming.push(msg)
|
1011
|
+
|
1012
|
+
# skip over the messge line(s),
|
1013
|
+
# on to the next CMGL line
|
1014
|
+
n = nn
|
1015
|
+
end
|
1016
|
+
end
|
850
1017
|
end # Modem
|
851
1018
|
end # Gsm
|
data/lib/rubygsm/errors.rb
CHANGED
data/lib/rubygsm/log.rb
CHANGED
@@ -15,7 +15,31 @@ class Modem
|
|
15
15
|
:warn => 2,
|
16
16
|
:error => 1 }
|
17
17
|
|
18
|
+
def log_init
|
19
|
+
fn_port = File.basename(@port)
|
20
|
+
fn_time = Time.now.strftime("%Y-%m-%d.%H-%M-%S")
|
21
|
+
|
22
|
+
# (re-) open the full log file
|
23
|
+
filename = "rubygsm.#{fn_port}.#{fn_time}"
|
24
|
+
@log = File.new filename, "w"
|
25
|
+
|
26
|
+
# dump some useful information
|
27
|
+
# at the top, for debugging
|
28
|
+
log "RUBYGSM"
|
29
|
+
log " port: #{@port}"
|
30
|
+
log " timeout: #{@read_timeout}"
|
31
|
+
log " verbosity: #{@verbosity}"
|
32
|
+
log " started at: #{Time.now}"
|
33
|
+
log "===="
|
34
|
+
end
|
35
|
+
|
18
36
|
def log(msg, level=:debug)
|
37
|
+
|
38
|
+
# abort if logging isn't
|
39
|
+
# enabled yet (or ever?)
|
40
|
+
return false if\
|
41
|
+
@log.nil?
|
42
|
+
|
19
43
|
ind = " " * (@log_indents[Thread.current] or 0)
|
20
44
|
|
21
45
|
# create a
|
data/lib/rubygsm/msg/incoming.rb
CHANGED
@@ -21,8 +21,11 @@ module Gsm
|
|
21
21
|
@received = Time.now
|
22
22
|
end
|
23
23
|
|
24
|
-
|
25
|
-
|
24
|
+
# Returns the sender of this message,
|
25
|
+
# so incoming and outgoing messages
|
26
|
+
# can be logged in the same way.
|
27
|
+
def number
|
28
|
+
sender
|
26
29
|
end
|
27
30
|
end
|
28
31
|
end
|
data/lib/rubygsm/msg/outgoing.rb
CHANGED
data/rubygsm.gemspec
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "rubygsm"
|
3
|
-
s.version = "0.
|
4
|
-
s.date = "2009-
|
3
|
+
s.version = "0.5.0"
|
4
|
+
s.date = "2009-03-12"
|
5
5
|
s.summary = "Send and receive SMS with a GSM modem"
|
6
6
|
s.email = "adam.mckaig@gmail.com"
|
7
7
|
s.homepage = "http://github.com/adammck/rubygsm"
|
8
|
-
s.authors = ["Adam Mckaig"]
|
8
|
+
s.authors = ["Adam Mckaig", "Jeff Rafter"]
|
9
9
|
s.has_rdoc = true
|
10
10
|
|
11
11
|
s.files = [
|
@@ -17,12 +17,14 @@ Gem::Specification.new do |s|
|
|
17
17
|
"lib/rubygsm/log.rb",
|
18
18
|
"lib/rubygsm/msg/incoming.rb",
|
19
19
|
"lib/rubygsm/msg/outgoing.rb",
|
20
|
-
"bin/gsm-modem-band"
|
20
|
+
"bin/gsm-modem-band",
|
21
|
+
"bin/gsm-app-monitor"
|
21
22
|
]
|
22
23
|
|
23
24
|
s.executables = [
|
24
|
-
"gsm-modem-band"
|
25
|
+
"gsm-modem-band",
|
26
|
+
"sms"
|
25
27
|
]
|
26
28
|
|
27
|
-
|
29
|
+
s.add_dependency("toholio-serialport", ["> 0.7.1"])
|
28
30
|
end
|
metadata
CHANGED
@@ -1,22 +1,33 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jeffrafter-rubygsm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Mckaig
|
8
|
+
- Jeff Rafter
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
12
|
|
12
|
-
date: 2009-
|
13
|
+
date: 2009-03-12 00:00:00 -07:00
|
13
14
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: toholio-serialport
|
18
|
+
type: :runtime
|
19
|
+
version_requirement:
|
20
|
+
version_requirements: !ruby/object:Gem::Requirement
|
21
|
+
requirements:
|
22
|
+
- - ">"
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 0.7.1
|
25
|
+
version:
|
16
26
|
description:
|
17
27
|
email: adam.mckaig@gmail.com
|
18
28
|
executables:
|
19
29
|
- gsm-modem-band
|
30
|
+
- sms
|
20
31
|
extensions: []
|
21
32
|
|
22
33
|
extra_rdoc_files: []
|
@@ -31,6 +42,7 @@ files:
|
|
31
42
|
- lib/rubygsm/msg/incoming.rb
|
32
43
|
- lib/rubygsm/msg/outgoing.rb
|
33
44
|
- bin/gsm-modem-band
|
45
|
+
- bin/gsm-app-monitor
|
34
46
|
has_rdoc: true
|
35
47
|
homepage: http://github.com/adammck/rubygsm
|
36
48
|
post_install_message:
|