1 package FS::svc_broadband;
4 use vars qw(@ISA $conf);
5 use FS::Record qw( qsearchs qsearch dbh );
11 @ISA = qw( FS::svc_Common );
13 $FS::UID::callback{'FS::svc_broadband'} = sub {
19 FS::svc_broadband - Object methods for svc_broadband records
23 use FS::svc_broadband;
25 $record = new FS::svc_broadband \%hash;
26 $record = new FS::svc_broadband { 'column' => 'value' };
28 $error = $record->insert;
30 $error = $new_record->replace($old_record);
32 $error = $record->delete;
34 $error = $record->check;
36 $error = $record->suspend;
38 $error = $record->unsuspend;
40 $error = $record->cancel;
44 An FS::svc_broadband object represents a 'broadband' Internet connection, such
45 as a DSL, cable modem, or fixed wireless link. These services are assumed to
46 have the following properties:
48 FS::svc_broadband inherits from FS::svc_Common. The following fields are
53 =item svcnum - primary key
55 =item blocknum - see FS::addr_block
58 speed_up - maximum upload speed, in bits per second. If set to zero, upload
59 speed will be unlimited. Exports that do traffic shaping should handle this
60 correctly, and not blindly set the upload speed to zero and kill the customer's
64 speed_down - maximum download speed, as above
66 =item ip_addr - the customer's IP address. If the customer needs more than one
67 IP address, set this to the address of the customer's router. As a result, the
68 customer's router will have the same address for both its internal and external
69 interfaces thus saving address space. This has been found to work on most NAT
80 Creates a new svc_broadband. To add the record to the database, see
83 Note that this stores the hash reference, not a distinct copy of the hash it
84 points to. You can ask the object for a copy with the I<hash> method.
88 sub table { 'svc_broadband'; }
90 =item insert [ , OPTION => VALUE ... ]
92 Adds this record to the database. If there is an error, returns the error,
93 otherwise returns false.
95 The additional fields pkgnum and svcpart (see FS::cust_svc) should be
96 defined. An FS::cust_svc record will be created and inserted.
98 Currently available options are: I<depend_jobnum>
100 If I<depend_jobnum> is set (to a scalar jobnum or an array reference of
101 jobnums), all provisioning jobs will have a dependancy on the supplied
102 jobnum(s) (they will not run until the specific job(s) complete(s)).
106 # Standard FS::svc_Common::insert
110 Delete this record from the database.
114 # Standard FS::svc_Common::delete
116 =item replace OLD_RECORD
118 Replaces the OLD_RECORD with this one in the database. If there is an error,
119 returns the error, otherwise returns false.
123 # Standard FS::svc_Common::replace
127 Called by the suspend method of FS::cust_pkg (see FS::cust_pkg).
131 Called by the unsuspend method of FS::cust_pkg (see FS::cust_pkg).
135 Called by the cancel method of FS::cust_pkg (see FS::cust_pkg).
139 Checks all fields to make sure this is a valid broadband service. If there is
140 an error, returns the error, otherwise returns false. Called by the insert
147 my $x = $self->setfixed;
149 return $x unless ref($x);
152 $self->ut_numbern('svcnum')
153 || $self->ut_foreign_key('blocknum', 'addr_block', 'blocknum')
154 || $self->ut_number('speed_up')
155 || $self->ut_number('speed_down')
156 || $self->ut_ipn('ip_addr')
157 || $self->ut_hexn('mac_addr')
158 || $self->ut_numbern('vlan')
160 return $error if $error;
162 if($self->speed_up < 0) { return 'speed_up must be positive'; }
163 if($self->speed_down < 0) { return 'speed_down must be positive'; }
165 if($self->vlan < 0 || $self->vlan > 4096) { # apropos?
166 return 'vlan is out of range'; }
168 if($self->latitude < -90 || $self->latitude > 90) {
169 return 'latitude must be between -90 and 90';
171 if($self->longitude < -180 || $self->longitude > 180) {
172 return 'longitude must be between -180 and 180';
175 if (not($self->ip_addr) or $self->ip_addr eq '0.0.0.0') {
176 my $next_addr = $self->addr_block->next_free_addr;
178 $self->ip_addr($next_addr->addr);
180 return "No free addresses in addr_block (blocknum: ".$self->blocknum.")";
184 # This should catch errors in the ip_addr. If it doesn't,
185 # they'll almost certainly not map into the block anyway.
186 my $self_addr = $self->NetAddr; #netmask is /32
187 return ('Cannot parse address: ' . $self->ip_addr) unless $self_addr;
189 my $block_addr = $self->addr_block->NetAddr;
190 unless ($block_addr->contains($self_addr)) {
191 return 'blocknum '.$self->blocknum.' does not contain address '.$self->ip_addr;
194 my $router = $self->addr_block->router
195 or return 'Cannot assign address from unallocated block:'.$self->addr_block->blocknum;
196 if(grep { $_->routernum == $router->routernum} $self->allowed_routers) {
199 return 'Router '.$router->routernum.' cannot provide svcpart '.$self->svcpart;
207 Returns a NetAddr::IP object containing the IP address of this service. The netmask
214 return new NetAddr::IP ($self->ip_addr);
219 Returns the FS::addr_block record (i.e. the address block) for this broadband service.
226 return qsearchs('addr_block', { blocknum => $self->blocknum });
231 =item allowed_routers
233 Returns a list of allowed FS::router objects.
237 sub allowed_routers {
240 return map { $_->router } qsearch('part_svc_router', { svcpart => $self->svcpart });
245 The business with sb_field has been 'fixed', in a manner of speaking.
249 FS::svc_Common, FS::Record, FS::addr_block,
250 FS::part_svc, schema.html from the base documentation.