Friday, October 22, 2010

books 4 php

11 Must Read Books to Become a PHP Ninja

Every language has it own practice. PHP is no exception. Mastering PHP isn’t easy unless you study hard.

Learning OOP is hard if you don’t have an experience with enterprise languages like Java or C++. Most of the popular books on OOP are targeted for Java users. PHP is a script language, but it is objective-oriented. I’d like to list several books that I find useful for PHP users who are eager to learn OOP and some other intermediate and advanced concepts.

This book is immensely useful even if you have partial knowledge about OOP. As this book is fully updated for PHP 5.3, you can learn about new features like closures and namespaces. Discussion on design patterns is easy to understand.

Not only that, this book mentions development practices such as version control, package management and continuous integration. The version control can be a different matter, but discussion on continuous integration is hard to find elsewhere.

Larry Ullman, the author of the book, already has published many books on PHP and MySQL. What’s notable about this book is, this book claims the support of PHP 6. PHP 6 hasn’t actually been shipped. And many features in PHP 6 are backported into PHP 5.3.2. This book comes as a few sample applications where you can feel the “real” issues. The author clearly introduces every basic, but important concepts in PHP.

This cookbook discusses many problems and its solutions you encounter everyday. Database connection, XML parsing/building, SOAP, REST, and OOP. As this is a recipe-style book, it doesn’t talk about the problem at full length. But this introduce each problem and solution just enough. If you need to explore each topic such as OOP, you need a different resource for that.

The book is rather advanced. If you already know PHP to some extent, this is a must-have. The author talk about advanced concepts in OOP, design patterns, documentation in details. If you are developing a large scale PHP web applications, this book is helpful for your team. One of the rare books that talk about such advanced concepts in a easy-to-follow manner. As an MVC framework, Zend Framework is briefly discussed.

Most applications need JavaScript. And these days most apps use libraries. Among them, jQuery is one of the most popular libraries. It is used in WordPress, Drupal, Digg, NBC, DELL and many others. PHP programmers need to work with frontend developers to bring the best user experience. This book serves as a good introduction to OOP in PHP and jQuery.

This is not exactly about PHP, but Apache is dead. Learn to use Nginx. Nginx is the future. If I’m correct, this book is the only book dedicated for Nginx. If you are already used to Nginx, this book may be too easy. But for newbies, the author explains basic settings in details. Some chapters are written for switchers from Apache.

If you need thorough and advanced understanding of object oriented design, this is a great book. This book also discusses agile development techniques such as unit testing, refactoring and MVC architecture. It’s hard to find a book like this in the PHP world, so this 552-page book from Manning is worth.

Websites can’t live with web APIs. Neither can PHP developers. Experience with some popular APIs is not a bonus, but one of the core skills you need to have. The book introduces major API’s basic usage. Be warned API specifications may have changed since the publication of the book.

Learning each API doesn’t make you build a successful web application. Rather you need to integrate the API to offer functionalities for users. If you need Web 2.0 type websites with API integration, this book comes handy.

REST, Representational State Transfer, is an architectural pattern for HTTP methods and resource handling. REST provides a simple, yet powerful solution. The author discusses the concepts in REST in theory, and also shows various real examples using WS02, RESTClient and Zend Framework.

Got a kid? If you are already a PHP ninja and have a kid, let your your kid learn programming! Your kids don’t need to know PHP at all to enjoy the book.

Lastly, I didn’t talk about frameworks in details. Learning frameworks is a must-have skill. If you are new to any framework, pick Zend Framework or Symfony. They are popular and have an incredible strong community

Monday, September 13, 2010

php mysql injection

// To protect MySQL injection (more detail about MySQL injection)
$myusername = stripslashes($myusername);
$mypassword = stripslashes($mypassword);
$myusername = mysql_real_escape_string($myusername);
$mypassword = mysql_real_escape_string($mypassword);

pls check for more . it isnt enough.

Sunday, July 18, 2010

Interesting ppt slides about marketing.

http://www.studymarketing.org/category/Presentation_Slides/Powerpoint_Slides.html

Friday, July 2, 2010

10 most popular manager interview questions

Here are ten most popular manager interview questions to help you prepare for your important management interview. There is no substitute for good preparation to handle such interviews so start preparing well. A good place to begin is to be well organized about your personal facts and figures and prepare your answers for commonly asked questions. Given below are some frequently asked manager interview questions for which you can write down your answers. Make the answers positive, responsible, honest and factual. Practice the answers before a mirror or a third person and get some feedback. Here goes.
1. How do you handle non-productive team members?
2. How do you motivate team members who are burned out, or bored?
3. How do you handle team members who come to you with their personal problems?
4. What are your career goals? How do you see this job affecting your goals?
5. Explain how you operate interdepartmentally.
6. Tell me how you would react to a situation where there was more than one way to accomplish the same task, and there were very strong feelings by others on each position.
7. Consider that you are in a diverse environment, out of your comfort zone. How would you rate your situational leadership style?
8. Give me an example of your leadership involvement where teamwork played an important role.
9. Tell me about a situation where your loyalty was challenged. What did you do? Why?
10. In what types of situations is it best to abandon loyalty to your manager?

Saturday, June 26, 2010

telco 2.0

The Telco 2.0 team’s view is that the way forward is to understand and specify an end-to-end commercial framework for telcos within the two-sided ecosystem. The diagram below summarises this at a high level.

eventexecsummary1.png

2-Sided Telecoms Business Model: Schematic Architecture

The analysis and brainstorming sessions in Nice focused on 7 important aspects of building a two-sided platform strategy:

  1. Open APIs –how to open telco networks to reduce access and/or transaction costs for other retailers.
  2. Retail Services 2.0 – how telcos can provide both their own retail services and the B2B platform services that will enable other retailers to sell products and services successfully through their networks.
  3. Devices 2.0 – how telcos need to access more of the intelligence in devices and exploit it for their own retail services and two-sided business model strategies.
  4. Enterprise Services 2.0 – how telcos’ assets can be used to remove or reduce the barriers other service providers face in interacting with end users.
  5. Content (esp. Video) Distribution 2.0 – how telcos are in a position to make money by helping to restore rational behaviour to the market
  6. Technical Architecture 2.0– how telcos need to be able to easily access a key untapped asset - customer data
  7. Piloting 2.0 – how to succeed and learn quickly.

The key issues and action points in each of these areas are described in the Executive Briefing Report, including an analysis of how current industry initiatives (e.g.s GSMA, TMF, NGMN, MMA, OMTP, OMA initiatives) map against the schematic architecture above.

From top-down analysis...


In the 'Two-Sided' Telecoms Market Opportunity strategy report we identified a number of areas in which telco assets could be applied to produce new sources of value. These areas were determined by exploring how Telco assets (grouped into seven 'service capability' categories) could add value to multiple vertical industries (see chart below)

The Seven 'Two-Sided' Service Capabilities Apply Across Multiple Industry Sectors

diagram



In the report, we also produced a detailed top-down model to size the potential market for each service capability in each vertical.
B2B%20VAS%20Waterfall.png

...to bottom-up analysis...


We are now recruiting a small number of partners to help us fund the next stage of the research project, which is to develop a deeper understanding of the two-sided B2B VAS market opportunity:

  • Its overall potential size and, most importantly, the size of specific opportunities within it
  • The potential ecosystem associated with each opportunity area and the roles to be played within it
  • The business model options for operators and other ecoystem players - who to charge, what to charge for?
  • The nature and volume of transactions that will flow through the ecosystem and the distribution of value among ecosystem players

This is important to operators and vendors within TMT (our partners) because it will give them sufficient detail to support business decisions:

  • A detailed business case to justify investment in specific opportunities

Thursday, June 17, 2010

Supervision (Business Skills)

http://www.pearsonhighered.com/educator/course/Supervision/91065247.page

Tuesday, June 15, 2010

How (and Why) to Stop Multitasking

During a conference call with the executive committee of a nonprofit board on which I sit, I decided to send an email to a client.

I know, I know. You'd think I'd have learned.

Last week I wrote about the dangers of using a cell phone while driving. Multitasking is dangerous. And so I proposed a way to stop.

But when I sent that email, I wasn't in a car. I was safe at my desk. What could go wrong?

Well, I sent the client the message. Then I had to send him another one, this time with the attachment I had forgotten to append. Finally, my third email to him explained why that attachment wasn't what he was expecting. When I eventually refocused on the call, I realized I hadn't heard a question the Chair of the Board had asked me.

I swear I wasn't smoking anything. But I might as well have been. A study showed that people distracted by incoming email and phone calls saw a 10-point fall in their IQs. What's the impact of a 10-point drop? The same as losing a night of sleep. More than twice the effect of smoking marijuana.

Doing several things at once is a trick we play on ourselves, thinking we're getting more done. In reality, our productivity goes down by as much as 40%. We don't actually multitask. We switch-task, rapidly shifting from one thing to another, interrupting ourselves unproductively, and losing time in the process.

You might think you're different, that you've done it so much you've become good at it. Practice makes perfect and all that.

But you'd be wrong. Research shows that heavy multitaskers are less competent at doing several things at once than light multitaskers. In other words, in contrast to almost everything else in your life, the more you multitask, the worse you are at it. Practice, in this case, works against you.

I decided to do an experiment. For one week I would do no multitasking and see what happened. What techniques would help? Could I sustain a focus on one thing at a time for that long?

For the most part, I succeeded. If I was on the phone, all I did was talk or listen on the phone. In a meeting I did nothing but focus on the meeting. Any interruptions — email, a knock on the door — I held off until I finished what I was working on.

During the week I discovered six things:

First, it was delightful. I noticed this most dramatically when I was with my children. I shut my cell phone off and found myself much more deeply engaged and present with them. I never realized how significantly a short moment of checking my email disengaged me from the people and things right there in front of me. Don't laugh, but I actually — for the first time in a while — noticed the beauty of leaves blowing in the wind.

Second, I made significant progress on challenging projects, the kind that — like writing or strategizing — require thought and persistence. The kind I usually try to distract myself from. I stayed with each project when it got hard, and experienced a number of breakthroughs.

Third, my stress dropped dramatically. Research shows that multitasking isn't just inefficient, it's stressful. And I found that to be true. It was a relief to do only one thing at a time. I felt liberated from the strain of keeping so many balls in the air at each moment. It felt reassuring to finish one thing before going to the next.

Fourth, I lost all patience for things I felt were not a good use of my time. An hour-long meeting seemed interminably long. A meandering pointless conversation was excruciating. II became laser-focused on getting things done. Since I wasn't doing anything else, I got bored much more quickly. I had no tolerance for wasted time.

Fifth, I had tremendous patience for things I felt were useful and enjoyable. When I listened to my wife Eleanor, I was in no rush. When I was brainstorming about a difficult problem, I stuck with it. Nothing else was competing for my attention so I was able to settle into the one thing I was doing.

Sixth, there was no downside. I lost nothing by not multitasking. No projects were left unfinished. No one became frustrated with me for not answering a call or failing to return an email the second I received it.

That's why it's so surprising that multitasking is so hard to resist. If there's no downside to stopping, why don't we all just stop?

I think it's because our minds move considerably faster than the outside world. You can hear far more words a minute than someone else can speak. We have so much to do, why waste any time? So, while you're on the phone listening to someone, why not use that extra brain power to book a trip to Florence?

What we neglect to realize is that we're already using that brain power to pick up nuance, think about what we're hearing, access our creativity, and stay connected to what's happening around us. It's not really extra brain power. And diverting it has negative consequences.

So how do we resist the temptation?

First, the obvious: the best way to avoid interruptions is to turn them off. Often I write at 6 am when there's nothing to distract me, I disconnect my computer from its wireless connection and turn my phone off. In my car, I leave my phone in the trunk. Drastic? Maybe. But most of us shouldn't trust ourselves.

Second, the less obvious: Use your loss of patience to your advantage. Create unrealistically short deadlines. Cut all meetings in half. Give yourself a third of the time you think you need to accomplish something.

There's nothing like a deadline to keep things moving. And when things are moving fast, we can't help but focus on them. How many people run a race while texting? If you really only have 30 minutes to finish a presentation you thought would take an hour, are you really going to answer an interrupting call?

Interestingly, because multitasking is so stressful, single-tasking to meet a tight deadline will actually reduce your stress. In other words, giving yourself less time to do things could make you more productive and relaxed.

Finally, it's good to remember that we're not perfect. Every once in a while it might be OK to allow for a little multitasking. As I was writing this, Daniel, my two-year-old son, walked into my office, climbed on my lap, and said "Monsters, Inc. movie please."

So, here we are, I'm finishing this piece on the left side of my computer screen while Daniel is on my lap watching a movie on the right side of my computer screen.

Sometimes, it is simply impossible to resist a little multitasking.

(Editor's note: Fellow HBR blogger David Silverman has some different thoughts on multi-tasking in his post, "In Defense of Multitasking")

Cold Call Tactics That Increase Sales

Cold Call Tactics That Increase Sales

Featured Products

As social media and web applications have become the hottest networking tools in business, too many sales managers are burying the cold call as an obsolete business practice. If you fall in this category I've got news for you: the cold call is not only alive, it's kicking. And it should be utilized by every B2B sales force.

I see far too many sales teams focus all their attention toward hosting fancy webinars or creating snazzy web-based marketing channels. Still, cold calling remains the most effective way to set up appointments with the right decision makers at your target accounts. A Fortune 50 wireless telecom company hired our firm to train their sales force in the ways of cold calls, and saw a 10% jump in revenue after implementing the tips below. Other clients have seen similar leaps in meetings or demos scheduled, from 20-100%.

So how can you convert phone tactics into actual results? Here are four cold calling tips that will make the sale:

1. Get the direct line of the person that you are cold calling. This doubles the probability of the person answering the phone.

2. Separate your cold calling into two activities: prospecting to find the right person, and call blitzing to get that person on the phone. I recommend prospecting during normal business hours (starting around 10-11:30 am) when administrative assistants are in the office and call blitzing during "call windows," before 8:30 am and after 5:30 pm when admins are gone. Some other great times to call are five minutes before the top of the hour, catching the executives before their next conference call meetings, and holidays like President's Day, when executives are likely to be in the office and other business may be slow.

3. Know the difference between persistence and annoyance. Follow these rules of thumb to be professional while consistently reaching out to prospects: manage the flow of information (make sure it's a constant flow), personalize each message, vary the medium (use an alternating combination of voicemails and emails), and always add value with each subsequent touch.

4. Utilize online resources. There are so many new tools to help you out, including information sources like LinkedIn, Jigsaw, InsideView, and ZoomInfo. With ConnectAndSell you can even outsource your dialing and block an hour to sit at your desk to only talk to live prospects when they get a "connect."

These techniques have helped us set up thousands of sales appointments with strategic executives at target companies. With a good cold calling effort, you can propel your sales team to higher productivity.

What cold-call tactics would you add to this list?

The 4 Ps of Innovation - hbr

The 4 Ps of Innovation

Featured Products

A few weeks ago, an innovation team was painstakingly working through a meticulously crafted spreadsheet detailing the growth potential of their idea. Executives trying to look smart lobbed in "gotcha" questions about specific assumptions in their calculations. Much discussion ensued.

I was an observer in this meeting. I sat quietly and took some notes. After the meeting the team leader said, "That was a really good review. The executives were really involved and we have deeper buy-in to our plan."

I had a different perspective.

"I don't think a single executive could tell you the essence of the idea, or what makes it compelling," I said. "You survived the meeting, but I don't think you are any closer to convincing executives that they should invest in this idea."

I explained how, based on the pioneering thinking from Rita McGrath and Ian MacMillian, I like to focus these discussions on three simple questions:

  1. "What size matters?" In other words, how big does an opportunity have to be to matter inside a company?
  2. "What is a simple calculation that crosses that bar?"
  3. "What leads you to believe that calculation is plausible?"

Any marketer can quickly rattle off the so-called "4 Ps" of marketing (product, price, place, and promotion). Innovators should also be able to quickly recite the 4 Ps that capture their idea's potential: population, penetration, price, and purchase frequency.

Companies looking at a specific revenue target can simply multiply the addressable population, the penetration of that population, the price per purchase, and the purchase frequency to get to annual revenues. Typically I suggest people try to be quite precise about their target population, give their best estimate based on in-market analogies of the pricing and purchase frequency, then determine what penetration they would need to hit their targets.

This deceptively simple calculation neatly captures many of the elements of an idea's business model. Does the idea target a niche or a mass population? Is it an occasional or frequent purchase? What channel would support the target price point? What kind of support would be necessary given the purchase frequency?

Once you do the 4P calculation (and of course, if you add in a fifth — profit margin — you can look at profits instead of revenue), the focus shifts to finding systematic ways to determine whether the assumptions behind the calculation have any hope of being true.

The deep thinking that goes into creating complicated spreadsheets for ideas can be very useful. But it also can be a way to mistake motion for progress. Make sure you can answer the simple questions before you worry about the complicated ones.

books..

http://govleaders.org/books2.htm

http://www.getabstract.com/summaries/27000000/bestselling/all/paged/en/it-production-and-logistics.html

Questions of Character: Illuminating the Heart of Leadership Through Literature

Thursday, April 15, 2010

duration billsec

Hello list,

I'm having troubles implementing the ${CDR(duration)} & ${CDR(billsec)} variables in this scenario:

PEER CALLS OUT ->
CALL GOES TO PEER'S DEFAULT OUTGOING CONTEXT ->
THE CALL IS SENT TO A MACRO AND GOES IN HANGUP ->
THE CALL RETURNS TO EXTENSION h OF PEER'S DEFAULT OUTGOING CONTEXT (here I'm trying to print the variable)

The problem is I'm always getting '0' from those variables. The incoming calls aren't passing through a macro and they return the correct billsec/duration value.

cdr.conf has this enabled: endbeforehexten=yes

asterisk version: 1.6.0.20

Any ideas, clues, suggestions on how may I get this to work?

Thanks in advance,

Alex

Tuesday, February 16, 2010

HipHop for PHP: Move Fast php BINARIES

http://developers.facebook.com/news.php?blog=1&story=358


Hacking Up HipHop

One night at a Hackathon a few years ago (see Prime Time Hack), I started my first piece of code transforming PHP into C++. The languages are fairly similar syntactically and C++ drastically outperforms PHP when it comes to both CPU and memory usage. Even PHP itself is written in C. We knew that it was impossible to successfully rewrite an entire codebase of this size by hand, but wondered what would happen if we built a system to do it programmatically.

Finding new ways to improve PHP performance isn't a new concept. At run time the Zend Engine turns your PHP source into opcodes which are then run through the Zend Virtual Machine. Open source projects such as APC and eAccelerator cache this output and are used by the majority of PHP powered websites. There's also Zend Server, a commercial product which makes PHP faster via opcode optimization and caching. Instead, we were thinking about transforming PHP source directly into C++ which can then be turned into native machine code. Even compiling PHP isn't a new idea, open source projects like Roadsend and phc compile PHP to C, Quercus compiles PHP to Java, and Phalanger compiles PHP to .Net.

Needless to say, it took longer than that single Hackathon. Eight months later, I had enough code to demonstrate it is indeed possible to run faster with compiled code. We quickly added Iain Proctor and Minghui Yang to the team to speed up the pace of the project. We spent the next ten months finishing up all the coding and the following six months testing on production servers. We are proud to say that at this point, we are serving over 90% of our Web traffic using HipHop, all only six months after deployment.

2010 CWE/SANS Top 25 Most Dangerous Programming Errors

This is a brief listing of the Top 25 items, using the general ranking.

NOTE: 16 other weaknesses were considered for inclusion in the Top 25, but their general scores were not high enough. They are listed in the On the Cusp focus profile.

RankScoreIDName
[1]346CWE-79 Failure to Preserve Web Page Structure ('Cross-site Scripting')
[2]330CWE-89 Improper Sanitization of Special Elements used in an SQL Command ('SQL Injection')
[3]273CWE-120 Buffer Copy without Checking Size of Input ('Classic Buffer Overflow')
[4]261CWE-352 Cross-Site Request Forgery (CSRF)
[5]219CWE-285 Improper Access Control (Authorization)
[6]202CWE-807 Reliance on Untrusted Inputs in a Security Decision
[7]197CWE-22 Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
[8]194CWE-434 Unrestricted Upload of File with Dangerous Type
[9]188CWE-78 Improper Sanitization of Special Elements used in an OS Command ('OS Command Injection')
[10]188CWE-311 Missing Encryption of Sensitive Data
[11]176CWE-798 Use of Hard-coded Credentials
[12]158CWE-805 Buffer Access with Incorrect Length Value
[13]157CWE-98 Improper Control of Filename for Include/Require Statement in PHP Program ('PHP File Inclusion')
[14]156CWE-129 Improper Validation of Array Index
[15]155CWE-754 Improper Check for Unusual or Exceptional Conditions
[16]154CWE-209 Information Exposure Through an Error Message
[17]154CWE-190 Integer Overflow or Wraparound
[18]153CWE-131 Incorrect Calculation of Buffer Size
[19]147CWE-306 Missing Authentication for Critical Function
[20]146CWE-494 Download of Code Without Integrity Check
[21]145CWE-732 Incorrect Permission Assignment for Critical Resource
[22]145CWE-770 Allocation of Resources Without Limits or Throttling
[23]142CWE-601 URL Redirection to Untrusted Site ('Open Redirect')
[24]141CWE-327 Use of a Broken or Risky Cryptographic Algorithm
[25]138CWE-362 Race Condition


http://cwe.mitre.org/top25/

Tuesday, January 12, 2010

Monitoring your servers with sysstat (sar)


There's sometimes things that are so helpfull that you think that everyone is aware of them, but sometimes this is not the case. Here I'll talk about a little package that is so powerful and efficient that you won't change anymore...
Taken from the ubuntu man page:

DESCRIPTION
The sar command writes to standard output the contents of selected cumula-
tive activity counters in the operating system. The accounting system, based
on the values in the count and interval parameters, writes information the
specified number of times spaced at the specified intervals in seconds. If
the interval parameter is set to zero, the sar command displays the average
statistics for the time since the system was started. The default value for
the count parameter is 1. If its value is set to zero, then reports are gen-
erated continuously. The collected data can also be saved in the file spec-
ified by the -o filename flag, in addition to being displayed onto the
screen. If filename is omitted, sar uses the standard system activity daily
data file, the /var/log/sysstat/sadd file, where the dd parameter indicates
the current day. By default all the data available from the kernel are
saved in the data file. Exceptions are interrupts and disks data, for which
the relevant options must be explicitly passed to sar (or to its backend
sadc ) when the data file is created (see options below).


"sar" comes with the sysstat package. Once it's installed you can monitor your server like never before...

Here's the description of the sysstat package from the author
The sysstat utilities are a collection of performance monitoring tools for Linux.
These include sar, sadf, mpstat, iostat, pidstat and sa tools. Go to the Features page to display
a list of sysstat's features, or see the Documentation page to learn some more about them.

For example, you can watch realtime the network usage:

# sar -n DEV 1 0
Linux 2.6.22-15-generic (xXxXx) 07/09/2008

11:26:36 AM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s
11:26:37 AM lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00
11:26:37 AM eth0 5.05 0.00 0.86 0.00 0.00 0.00 0.00

11:26:37 AM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s
11:26:38 AM lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00
11:26:38 AM eth0 4.00 0.00 0.45 0.00 0.00 0.00 0.00
...

Today, I'll introduce the erlang-sar package that's able to retrieve information from the sar command.

The application is composed of a collector "sar_collector", a helper module "sar_values" and the main module "sar".
Here comes a quick sample session:

% Starting the collector
sar_collect:start().

% Retrieving the data
sar:stats(cpu).
[{cpu,idle,<<"98.62">>},
{cpu,steal,<<"0.00">>},
{cpu,iowait,<<"0.00">>},
{cpu,system,<<"0.18">>},
{cpu,nice,<<"0.00">>},
{cpu,user,<<"1.20">>}]

% Retrieving more data
sar:stats([cpu,mem]).
[{swap,swpcad,<<"33236">>},
{swap,usage,<<"64.72">>},
{swap,used,<<"389872">>},
{swap,free,<<"212492">>},
{mem,kbcached,<<"84496">>},
{mem,kbbuffers,<<"63408">>},
{mem,memused,<<"98.78">>},
{mem,kbmemused,<<"508984">>},
{mem,kbmemfree,<<"6308">>},
{cpu,idle,<<"97.83">>},
{cpu,steal,<<"0.00">>},
{cpu,iowait,<<"0.75">>},
{cpu,system,<<"0.20">>},
{cpu,nice,<<"0.00">>},
{cpu,user,<<"1.22">>}]


The module "sar_values" also export an "extractor" function that can be used to build fun()s:

% build a Mem fun()
Mem = sar_values:extractor(mem).

% Calling Mem fun() on sar:stats()
Mem(sar:stats([cpu,mem])).
[{kbcached,<<"84496">>},
{kbbuffers,<<"63480">>},
{memused,<<"98.77">>},
{kbmemused,<<"508976">>},
{kbmemfree,<<"6316">>}]

% Calling it on sar:stats()
Mem(sar:stats()).
[{kbcached,<<"84496">>},
{kbbuffers,<<"63520">>},
{memused,<<"98.80">>},
{kbmemused,<<"509100">>},
{kbmemfree,<<"6192">>}]


With this package you have access to all the data sar can export for you.
Here's the "sar.erl" code:

-module(sar).

-export([systat/0, stats/0, stats/1, option/1]).
-export([extract/1]).
-define(OPTIONS, "-u -r -v -c -q -n DEV").
-define(DATA, "/tmp/last").

systat() ->
Cmd = "sadf " ++ ?DATA ++ " -- " ++ ?OPTIONS,
execute(".", Cmd).

stats() ->
Cmd = "sadf " ++ ?DATA ++ " -- " ++ ?OPTIONS,
{ok, _, Bin} = execute(".", Cmd),
extract(Bin).

stats(List) when is_list(List) ->
Args = lists:foldl(fun(X, Acc) -> case option(X) of
error ->
Acc;
T ->
[ $ , T | Acc ]
end end, [], List),
Cmd = "sadf " ++ ?DATA ++ " -- " ++ lists:reverse(Args),
{ok, _, Bin} = execute(".", lists:flatten(Cmd)),
extract(Bin);

stats(Elem) ->
stats([Elem]).

option(cpu) ->
"-u";
option(disk) ->
"-d";
option(sock) ->
"-n SOCK";
option(eth0) ->
"-n DEV";
option(eth1) ->
"-n DEV";
option(eth2) ->
"-n DEV";
option(proc) ->
"-c";
option(run) ->
"-q";
option(mem) ->
"-r";
option(inode) ->
"-v";
option(switch) ->
"-w";
option(swaping) ->
"-W";
option(_) ->
error.

execute(_Host, Cmd) ->
Port = open_port({spawn, Cmd}, [ exit_status, binary ] ),
wait(Port, []).

wait(Port, Content) ->
receive
{Port, {data, BinData}} ->
%error_logger:info_msg("dump:~n~p~n", [BinData]),
NewContent = [ BinData | Content ],
wait(Port, NewContent);

{Port, {exit_status, Status}} ->
%error_logger:info_msg("exit_code: ~p~n", [Status]),
{ok, Status, Content};

{Port, eof} ->
%error_logger:info_msg("Port closed"),
port_close(Port),
{ok, eof, Content};

{Port, exit} ->
error_logger:info_msg("Received : ~p~n", [Port]),
Content
end.

extract(Bin) ->
sar_values:extract(iolist_to_binary(Bin)).


You can see the "option/1" function that let you convert atoms into command line arguments easily. I use also this function to test if sar is able to handle a specific parameter. For example and with the help of my webservice I can query remote stats easily:
http://monitoring.lan/stats/q/cpu/servername


Here's the "sar_collect" module

-module(sar_collect).

-export([systat/1, sartime/1, start/0, start/1]).
-export([extract/1]).
spawn(?MODULE, systat, []).

start(Seconds) ->
spawn(?MODULE, systat, [Seconds]).

% update the file every second
systat(0) ->
loop(1);

systat(Seconds) ->
loop(Seconds).

%update the file every 59 seconds
systat() ->
loop(59).

loop(Seconds) when Seconds <>
Cmd = lists:flatten([ "sar -o /tmp/last.tmp ", integer_to_list(Seconds), " 1" ]),
execute(".", Cmd),
file:rename("/tmp/last.tmp", "/tmp/last"),
timer:sleep(60 - Seconds),
receive
stop ->
exit(normal);

{interval, NewSeconds} ->
loop(NewSeconds);

_A ->
loop(Seconds)

after 0 ->
loop(Seconds)

end;

%default update 20 seconds (arbitrary chosen)
loop(_Seconds) ->
loop(20).

execute(Host, Cmd) ->
Port = open_port({spawn, Cmd}, [ {cd, Host}, exit_status, binary ] ),
wait(Port, []).

wait(Port, Content) ->
receive
{Port, {data, _BinData}} ->
wait(Port, Content);

{Port, {exit_status, _Status}} ->
ok;

{Port, eof} ->
port_close(Port),
Content;

{Port, exit} ->
error_logger:info_msg("Received : ~p~n", [Port]),
Content
end.


Finally there is the "sar_values" source code:

-module(sar_values).

-export([extract/1, extractor/1, sort/1]).
-export([parse/1, parse_value/2]).

extract(Bin) ->
extract(Bin, []).

extract(Bin, Stats) ->
case parse(Bin) of
{Class, Type, Rest} ->
%io:format("~p.~p", [Class, Type]),
case parse_value(Rest, <<>>) of
{more, Value, More} ->
NewStats = [ {Class, Type, Value} | Stats ],
extract(More, NewStats);

{eof, Value} ->
NewStats = [ {Class, Type, Value} | Stats ],
NewStats
end;

eof ->
Stats
end.

parse(<<"%user", Rest/binary >>) -> {cpu, user, Rest};
parse(<<"%nice", Rest/binary>>) -> {cpu, nice, Rest};
parse(<<"%system", Rest/binary>>) -> {cpu, system, Rest};
parse(<<"%iowait", Rest/binary>>) -> {cpu, iowait, Rest};
parse(<<"%steal", Rest/binary>>) -> {cpu, steal, Rest};
parse(<<"%idle", Rest/binary>>) -> {cpu, idle, Rest};

parse(<<"kbmemfree", Rest/binary>>) -> {mem, kbmemfree, Rest};
parse(<<"kbmemused", Rest/binary>>) -> {mem, kbmemused, Rest};
parse(<<"%memused", Rest/binary>>) -> {mem, memused, Rest};
parse(<<"kbbuffers", Rest/binary>>) -> {mem, kbbuffers, Rest};
parse(<<"kbcached", Rest/binary>>) -> {mem, kbcached, Rest};

parse(<<"kbswpfree", Rest/binary>>) -> {swap, free, Rest};
parse(<<"kbswpused", Rest/binary>>) -> {swap, used, Rest};
parse(<<"%swpused", Rest/binary>>) -> {swap, usage, Rest};
parse(<<"kbswpcad", Rest/binary>>) -> {swap, swpcad, Rest};

parse(<<"dentunusd", Rest/binary>>) -> {inode, dentryunused, Rest};
parse(<<"file-sz", Rest/binary>>) -> {inode, fileopened, Rest};
parse(<<"inode-sz", Rest/binary>>) -> {inode, inodes, Rest};
parse(<<"super-sz", Rest/binary>>) -> {inode, super, Rest};
parse(<<"%super-sz", Rest/binary>>) -> {inode, superusage, Rest};
parse(<<"dquot-sz", Rest/binary>>) -> {inode, dquotsz, Rest};
parse(<<"%dquot-sz", Rest/binary>>) -> {inode, dquotszusage, Rest};
parse(<<"rtsig-sz", Rest/binary>>) -> {rtsig, count , Rest};
parse(<<"%rtsig-sz", Rest/binary>>) -> {rtsig, usage, Rest};

parse(<<"totsck", Rest/binary>>) -> {sock, total, Rest};
parse(<<"tcpsck", Rest/binary>>) -> {sock, tcp, Rest};
parse(<<"udpsck", Rest/binary>>) -> {sock, udp, Rest};
parse(<<"rawsck", Rest/binary>>) -> {sock, raw, Rest};
parse(<<"ip-frag", Rest/binary>>) -> {sock, ipfrag, Rest};

parse(<<"runq-sz", Rest/binary>>) -> {procs, running, Rest};
parse(<<"plist-sz", Rest/binary>>) -> {procs, total, Rest};

parse(<<"ldavg-15", Rest/binary>>) -> {load, min15, Rest};
parse(<<"ldavg-1", Rest/binary>>) -> {load, min1, Rest};
parse(<<"ldavg-5", Rest/binary>>) -> {load, min5, Rest};

parse(<<"pswpin/s", Rest/binary>>) -> {swaping, pswpin, Rest};
parse(<<"pswpout/s", Rest/binary>>) -> {swaping, pswpout, Rest};

parse(<<"l0", Rest/binary>>) -> parsebis(Rest, l0);
parse(<<"eth0", Rest/binary>>) -> parsebis(Rest, eth0);
parse(<<"eth1", Rest/binary>>) -> parsebis(Rest, eth1);
parse(<<"eth2", Rest/binary>>) -> parsebis(Rest, eth2);

parse(<<>>) -> eof;

parse(Bin) ->
{_, Next} = split_binary(Bin, 1),
parse(Next).

parsebis(<<"rxpck/s", Rest/binary>>, Category) -> {Category, rxpck, Rest};
parsebis(<<"txpck/s", Rest/binary>>, Category) -> {Category, txpck, Rest};
parsebis(<<"rxbyt/s", Rest/binary>>, Category) -> {Category, rxbyt, Rest};
parsebis(<<"txbyt/s", Rest/binary>>, Category) -> {Category, txbyt, Rest};
parsebis(<<"rxcmp/s", Rest/binary>>, Category) -> {Category, rxcmp, Rest};
parsebis(<<"txcmp/s", Rest/binary>>, Category) -> {Category, txcmp, Rest};
parsebis(<<"rxmcst/s", Rest/binary>>, Category) -> {Category, rxmcst, Rest};
parsebis(Bin, Category) ->
{_, Next} = split_binary(Bin, 1),
parsebis(Next, Category).

parse_value(<<$\t, Rest/binary>>, _Value) ->
parse_value(Rest, _Value);
parse_value(<<$ , Rest/binary>>, _Value) ->
parse_value(Rest, _Value);

parse_value(<<$\n, _Rest/binary>>, Value) ->
{more, Value, _Rest};

parse_value(<<>>, Value) ->
{eof, Value};

parse_value(Bin, Value) ->
{H, Next} = split_binary(Bin, 1),
parse_value(Next, iolist_to_binary([Value, H])).

extractor(Motif) ->
fun(L) when is_list(L) ->
[ {Y, Z} || {X, Y, Z} <- L, X == Motif]
end.

sort(List) ->
lists:sort( fun({X, _V}, {Y, _W}) when X <>
true;
(_A, _B) -> false
end, List).


Now that Erlang is R12B, I'm not so sure if "binary parsing code" is really as efficient as it can...

Wednesday, January 6, 2010

Technology Management

Nice Curriculum

MANAGE MENT SKILL S
The Management Skills part of the NIT program
consists of lectures and seminars as well
as two four-week full-time Spring Schools. The
first part teaches skills necessary to develop an
initial idea for a ready-to-market product, while
the second part emphasizes on developing a
business idea into a functioning business model.
SYLLABUS
Principles of Economics and Management
• Introduction to International Management and Economics
• Statistics & Decision Making Techniques
• Global Economy
Primary Value Chain Activities
• Supply Chain Management
• Research and Development
• Production and Operations
• Marketing and Sales
Strategy, Organization, Human Resources
Accounting and Finance
• Financial Accounting, Management Accounting
• Finance and Investment, Corporate Finance
Entrepreneurship and Elements of Law
• Business Planning
• Project Management
• International Law
• Intellectual Property Rights
Technology Management
• Quality and Information Management
• Management of IT, IT-Security
• Technology Road-Mapping
• Technology Acquisition and Technology Transfer
The curriculum heavily draws on case studies and group work.
Scholarships from:
MBA /MASTER IN TEC HNOLOG Y MANAGE MENT
LEADER SHIP SKILL S
The Leadership Skills of the NIT program deal
with the human factor, focusing on three different
areas: on key qualifications that make a
difference in modern leadership, on determining
non-economic factors of today’s German
and European thinking, and on basic ethical
issues in a global business.
SYLLABUS
Ethics
• Principles of Philosophy and Ethics
• Corporate Governance
• Corporate Responsibility
Management Communication
• Principles of Communication
• Organizational Behavior
• Conflict Management and Negotiation
• Leadership, Teamwork, Presentation
The curriculum offers a balanced blend of lecture courses,
weekend-workshops and intensive study weeks.

SMPP PHP connector

require_once('smppclass.php');

$smpphost = "203.199.142.41"; // your host address
$smppport = 2345;
$systemid = "idsfds"; // Your system id
$password = "es223"; // Your smpp account password
$system_type = "Rdsd "; // Your userid
$from = "919846341106"; // From number

$smpp = new SMPPClass();
$smpp->SetSender($from);
/* bind to smpp server */
$smpp->Start($smpphost, $smppport, $systemid, $password, $system_type);
/* send enquire link PDU to smpp server */
$smpp->TestLink();
/* send single message; large messages are automatically split */
$smpp->Send("971532663061", "This is a test message. Give me a missed call if you get this. sajith");
/* send unicode message */
//$smpp->Send("31648072766", "صباحالخير", true);
/* send message to multiple recipients at once */
//$smpp->SendMulti("31648072766,31651931985", "This is my PHP message");
/* unbind from smpp server */
$smpp->End();

//Click read more for smppclass.php library

More...

//file smppclass.php

define(CM_BIND_TRANSMITTER, 0x00000002);
define(CM_SUBMIT_SM, 0x00000004);
define(CM_SUBMIT_MULTI, 0x00000021);
define(CM_UNBIND, 0x00000006);
define(CM_ENQUIRELINK, 0x00000015);

class SMPPClass {
// public members:
/*
Constructor.
Parameters:
none.
Example:
$smpp = new SMPPClass();
*/
function SMPPClass()
{
/* seed random generator */
list($usec, $sec) = explode(' ', microtime());
$seed = (float) $sec + ((float) $usec * 100000);
srand($seed);

/* initialize member variables */
$this->_debug = true; /* set this to false if you want to suppress debug output. */
$this->_socket = NULL;
$this->_command_status = 0;
$this->_sequence_number = 1;
$this->_source_address = "";
$this->_message_sequence = rand(1,255);
}

/*
For SMS gateways that support sender-ID branding, the method
can be used to set the originating address.
Parameters:
$from : Originating address
Example:
$smpp->SetSender("31495595392");
*/
function SetSender($from)
{
if (strlen($from) > 20) {
$this->debug("Error: sender id too long.\n");
return;
}
$this->_source_address = $from;
}

/*
This method initiates an SMPP session.
It is to be called BEFORE using the Send() method.
Parameters:
$host : SMPP ip to connect to.
$port : port # to connect to.
$username : SMPP system ID
$password : SMPP passord.
$system_type : SMPP System type
Returns:
true if successful, otherwise false
Example:
$smpp->Start("smpp.chimit.nl", 2345, "chimit", "my_password", "client01");
*/
function Start($host, $port, $username, $password, $system_type)
{
/*
$testarr = stream_get_transports();
$have_tcp = false;
reset($testarr);
while (list(, $transport) = each($testarr)) {
if ($transport == "tcpp") {
$have_tcp = true;
}
}
if (!$have_tcp) {
$this->debug("No TCP support in this version of PHP.\n");
return false;
}
*/
$this->_socket = fsockopen($host, $port, $errno, $errstr, 20);
// todo: sanity check on input parameters
if (!$this->_socket) {
$this->debug("Error opening SMPP session.\n");
$this->debug("Error was: $errstr.\n");
return;
}
socket_set_timeout($this->_socket, 1200);
$status = $this->SendBindTransmitter($username, $password, $system_type);
if ($status != 0) {
$this->debug("Error binding to SMPP server. Invalid credentials?\n");
}
return ($status == 0);
}

/*
This method sends out one SMS message.
Parameters:
$to : destination address.
$text : text of message to send.
$unicode: Optional. Indicates if input string is html encoded unicode.
Returns:
true if messages sent successfull, otherwise false.
Example:
$smpp->Send("31649072766", "This is an SMPP Test message.");
$smpp->Send("31648072766", "صباحالخير", true);
*/
function Send($to, $text, $unicode = false)
{
if (strlen($to) > 20) {
$this->debug("to-address too long.\n");
return;
}
if (!$this->_socket) {
$this->debug("Not connected, while trying to send SUBMIT_SM.\n");
// return;
}
$service_type = "";
//default source TON and NPI for international sender
$source_addr_ton = 1;
$source_addr_npi = 1;
$source_addr = $this->_source_address;
if (preg_match('/\D/', $source_addr)) //alphanumeric sender
{
$source_addr_ton = 5;
$source_addr_npi = 0;
}
elseif (strlen($source_addr) < 11) //national or shortcode sender
{
$source_addr_ton = 2;
$source_addr_npi = 1;
}
$dest_addr_ton = 1;
$dest_addr_npi = 1;
$destination_addr = $to;
$esm_class = 3;
$protocol_id = 0;
$priority_flag = 0;
$schedule_delivery_time = "";
$validity_period = "";
$registered_delivery_flag = 0;
$replace_if_present_flag = 0;
$data_coding = 241;
$sm_default_msg_id = 0;
if ($unicode) {
$text = mb_convert_encoding($text, "UCS-2BE", "HTML-ENTITIES"); /* UCS-2BE */
$data_coding = 8; /* UCS2 */
$multi = $this->split_message_unicode($text);
}
else {
$multi = $this->split_message($text);
}
$multiple = (count($multi) > 1);
if ($multiple) {
$esm_class += 0x00000040;
}
$result = true;
reset($multi);
while (list(, $part) = each($multi)) {
$short_message = $part;
$sm_length = strlen($short_message);
$status = $this->SendSubmitSM($service_type, $source_addr_ton, $source_addr_npi, $source_addr, $dest_addr_ton, $dest_addr_npi, $destination_addr, $esm_class, $protocol_id, $priority_flag, $schedule_delivery_time, $validity_period, $registered_delivery_flag, $replace_if_present_flag, $data_coding, $sm_default_msg_id, $sm_length, $short_message);
if ($status != 0) {
$this->debug("SMPP server returned error $status.\n");
$result = false;
}
}
return $result;
}

/*
This method ends a SMPP session.
Parameters:
none
Returns:
true if successful, otherwise false
Example: $smpp->End();
*/
function End()
{
if (!$this->_socket) {
// not connected
return;
}
$status = $this->SendUnbind();
if ($status != 0) {
$this->debug("SMPP Server returned error $status.\n");
}
fclose($this->_socket);
$this->_socket = NULL;
return ($status == 0);
}

/*
This method sends an enquire_link PDU to the server and waits for a response.
Parameters:
none
Returns:
true if successfull, otherwise false.
Example: $smpp->TestLink()
*/
function TestLink()
{
$pdu = "";
$status = $this->SendPDU(CM_ENQUIRELINK, $pdu);
return ($status == 0);
}

/*
This method sends a single message to a comma separated list of phone numbers.
There is no limit to the number of messages to send.
Parameters:
$tolist : comma seperated list of phone numbers
$text : text of message to send
$unicode: Optional. Indicates if input string is html encoded unicode string.
Returns:
true if messages received by smpp server, otherwise false.
Example:
$smpp->SendMulti("31777110204,31649072766,...,...", "This is an SMPP Test message.");
*/
function SendMulti($tolist, $text, $unicode = false)
{
if (!$this->_socket) {
$this->debug("Not connected, while trying to send SUBMIT_MULTI.\n");
// return;
}
$service_type = "";
$source_addr = $this->_source_address;
//default source TON and NPI for international sender
$source_addr_ton = 1;
$source_addr_npi = 1;
$source_addr = $this->_source_address;
if (preg_match('/\D/', $source_addr)) //alphanumeric sender
{
$source_addr_ton = 5;
$source_addr_npi = 0;
}
elseif (strlen($source_addr) < 11) //national or shortcode sender
{
$source_addr_ton = 2;
$source_addr_npi = 1;
}
$dest_addr_ton = 1;
$dest_addr_npi = 1;
$destination_arr = explode(",", $tolist);
$esm_class = 3;
$protocol_id = 0;
$priority_flag = 0;
$schedule_delivery_time = "";
$validity_period = "";
$registered_delivery_flag = 0;
$replace_if_present_flag = 0;
$data_coding = 241;
$sm_default_msg_id = 0;
if ($unicode) {
$text = mb_convert_encoding($text, "UCS-2BE", "HTML-ENTITIES");
$data_coding = 8; /* UCS2 */
$multi = $this->split_message_unicode($text);
}
else {
$multi = $this->split_message($text);
}
$multiple = (count($multi) > 1);
if ($multiple) {
$esm_class += 0x00000040;
}
$result = true;
reset($multi);
while (list(, $part) = each($multi)) {
$short_message = $part;
$sm_length = strlen($short_message);
$status = $this->SendSubmitMulti($service_type, $source_addr_ton, $source_addr_npi, $source_addr, $dest_addr_ton, $dest_addr_npi, $destination_arr, $esm_class, $protocol_id, $priority_flag, $schedule_delivery_time, $validity_period, $registered_delivery_flag, $replace_if_present_flag, $data_coding, $sm_default_msg_id, $sm_length, $short_message);
if ($status != 0) {
$this->debug("SMPP server returned error $status.\n");
$result = false;
}
}
return $result;
}

// private members (not documented):

function ExpectPDU($our_sequence_number)
{
do {
$this->debug("Trying to read PDU.\n");
if (feof($this->_socket)) {
$this->debug("Socket was closed.!!\n");
}
$elength = fread($this->_socket, 4);
if (empty($elength)) {
$this->debug("Connection lost.\n");
return;
}
extract(unpack("Nlength", $elength));
$this->debug("Reading PDU : $length bytes.\n");
$stream = fread($this->_socket, $length - 4);
$this->debug("Stream len : " . strlen($stream) . "\n");
extract(unpack("Ncommand_id/Ncommand_status/Nsequence_number", $stream));
$command_id &= 0x0fffffff;
$this->debug("Command id : $command_id.\n");
$this->debug("Command status : $command_status.\n");
$this->debug("sequence_number : $sequence_number.\n");
$pdu = substr($stream, 12);
switch ($command_id) {
case CM_BIND_TRANSMITTER:
$this->debug("Got CM_BIND_TRANSMITTER_RESP.\n");
$spec = "asystem_id";
extract($this->unpack2($spec, $pdu));
$this->debug("system id : $system_id.\n");
break;
case CM_UNBIND:
$this->debug("Got CM_UNBIND_RESP.\n");
break;
case CM_SUBMIT_SM:
$this->debug("Got CM_SUBMIT_SM_RESP.\n");
if ($command_status == 0) {
$spec = "amessage_id";
extract($this->unpack2($spec, $pdu));
$this->debug("message id : $message_id.\n");
}
break;
case CM_SUBMIT_MULTI:
$this->debug("Got CM_SUBMIT_MULTI_RESP.\n");
$spec = "amessage_id/cno_unsuccess/";
extract($this->unpack2($spec, $pdu));
$this->debug("message id : $message_id.\n");
$this->debug("no_unsuccess : $no_unsuccess.\n");
break;
case CM_ENQUIRELINK:
$this->debug("GOT CM_ENQUIRELINK_RESP.\n");
break;
default:
$this->debug("Got unknown SMPP pdu.\n");
break;
}
$this->debug("\nReceived PDU: ");
for ($i = 0; $i < strlen($stream); $i++) {
if (ord($stream[$i]) <>debug("(" . ord($stream[$i]) . ")"); else $this->debug($stream[$i]);
}
$this->debug("\n");
} while ($sequence_number != $our_sequence_number);
return $command_status;
}

function SendPDU($command_id, $pdu)
{
$length = strlen($pdu) + 16;
$header = pack("NNNN", $length, $command_id, $this->_command_status, $this->_sequence_number);
$this->debug("Sending PDU, len == $length\n");
$this->debug("Sending PDU, header-len == " . strlen($header) . "\n");
$this->debug("Sending PDU, command_id == " . $command_id . "\n");
fwrite($this->_socket, $header . $pdu, $length);
$status = $this->ExpectPDU($this->_sequence_number);
$this->_sequence_number = $this->_sequence_number + 1;
return $status;
}

function SendBindTransmitter($system_id, $smpppassword, $system_type)
{
$system_id = $system_id . chr(0);
$system_id_len = strlen($system_id);
$smpppassword = $smpppassword . chr(0);
$smpppassword_len = strlen($smpppassword);
$system_type = $system_type . chr(0);
$system_type_len = strlen($system_type);
$pdu = pack("a{$system_id_len}a{$smpppassword_len}a{$system_type_len}CCCa1", $system_id, $smpppassword, $system_type, 0x33, 0, 0, chr(0));
$this->debug("Bind Transmitter PDU: ");
for ($i = 0; $i < strlen($pdu); $i++) {
$this->debug(ord($pdu[$i]) . " ");
}
$this->debug("\n");
$status = $this->SendPDU(CM_BIND_TRANSMITTER, $pdu);
return $status;
}

function SendUnbind()
{
$pdu = "";
$status = $this->SendPDU(CM_UNBIND, $pdu);
return $status;
}

function SendSubmitSM($service_type, $source_addr_ton, $source_addr_npi, $source_addr, $dest_addr_ton, $dest_addr_npi, $destination_addr, $esm_class, $protocol_id, $priority_flag, $schedule_delivery_time, $validity_period, $registered_delivery_flag, $replace_if_present_flag, $data_coding, $sm_default_msg_id, $sm_length, $short_message)
{
$service_type = $service_type . chr(0);
$service_type_len = strlen($service_type);
$source_addr = $source_addr . chr(0);
$source_addr_len = strlen($source_addr);
$destination_addr = $destination_addr . chr(0);
$destination_addr_len = strlen($destination_addr);
$schedule_delivery_time = $schedule_delivery_time . chr(0);
$schedule_delivery_time_len = strlen($schedule_delivery_time);
$validity_period = $validity_period . chr(0);
$validity_period_len = strlen($validity_period);
// $short_message = $short_message . chr(0);
$message_len = $sm_length;
$spec = "a{$service_type_len}cca{$source_addr_len}cca{$destination_addr_len}ccca{$schedule_delivery_time_len}a{$validity_period_len}ccccca{$message_len}";
$this->debug("PDU spec: $spec.\n");

$pdu = pack($spec,
$service_type,
$source_addr_ton,
$source_addr_npi,
$source_addr,
$dest_addr_ton,
$dest_addr_npi,
$destination_addr,
$esm_class,
$protocol_id,
$priority_flag,
$schedule_delivery_time,
$validity_period,
$registered_delivery_flag,
$replace_if_present_flag,
$data_coding,
$sm_default_msg_id,
$sm_length,
$short_message);
$status = $this->SendPDU(CM_SUBMIT_SM, $pdu);
return $status;
}

function SendSubmitMulti($service_type, $source_addr_ton, $source_addr_npi, $source_addr, $dest_addr_ton, $dest_addr_npi, $destination_arr, $esm_class, $protocol_id, $priority_flag, $schedule_delivery_time, $validity_period, $registered_delivery_flag, $replace_if_present_flag, $data_coding, $sm_default_msg_id, $sm_length, $short_message)
{
$service_type = $service_type . chr(0);
$service_type_len = strlen($service_type);
$source_addr = $source_addr . chr(0);
$source_addr_len = strlen($source_addr);
$number_destinations = count($destination_arr);
$dest_flag = 1;
$spec = "a{$service_type_len}cca{$source_addr_len}c";
$pdu = pack($spec,
$service_type,
$source_addr_ton,
$source_addr_npi,
$source_addr,
$number_destinations
);

$dest_flag = 1;
reset($destination_arr);
while (list(, $destination_addr) = each($destination_arr)) {
$destination_addr .= chr(0);
$dest_len = strlen($destination_addr);
$spec = "ccca{$dest_len}";
$pdu .= pack($spec, $dest_flag, $dest_addr_ton, $dest_addr_npi, $destination_addr);
}
$schedule_delivery_time = $schedule_delivery_time . chr(0);
$schedule_delivery_time_len = strlen($schedule_delivery_time);
$validity_period = $validity_period . chr(0);
$validity_period_len = strlen($validity_period);
$message_len = $sm_length;
$spec = "ccca{$schedule_delivery_time_len}a{$validity_period_len}ccccca{$message_len}";

$pdu .= pack($spec,
$esm_class,
$protocol_id,
$priority_flag,
$schedule_delivery_time,
$validity_period,
$registered_delivery_flag,
$replace_if_present_flag,
$data_coding,
$sm_default_msg_id,
$sm_length,
$short_message);

$this->debug("\nMulti PDU: ");
for ($i = 0; $i < strlen($pdu); $i++) {
if (ord($pdu[$i]) <>debug("."); else $this->debug($pdu[$i]);
}
$this->debug("\n");

$status = $this->SendPDU(CM_SUBMIT_MULTI, $pdu);
return $status;
}

function split_message($text)
{
$this->debug("In split_message.\n");
$max_len = 153;
$res = array();
if (strlen($text) <= 160) {
$this->debug("One message: " . strlen($text) . "\n");
$res[] = $text;
return $res;
}
$pos = 0;
$msg_sequence = $this->_message_sequence++;
$num_messages = ceil(strlen($text) / $max_len);
$part_no = 1;
while ($pos < strlen($text)) {
$ttext = substr($text, $pos, $max_len);
$pos += strlen($ttext);
$udh = pack("cccccc", 5, 0, 3, $msg_sequence, $num_messages, $part_no);
$part_no++;
$res[] = $udh . $ttext;
$this->debug("Split: UDH = ");
for ($i = 0; $i < strlen($udh); $i++) {
$this->debug(ord($udh[$i]) . " ");
}
$this->debug("\n");
$this->debug("Split: $ttext.\n");
}
return $res;
}

function split_message_unicode($text)
{
$this->debug("In split_message.\n");
$max_len = 134;
$res = array();
if (mb_strlen($text) <= 140) {
$this->debug("One message: " . mb_strlen($text) . "\n");
$res[] = $text;
return $res;
}
$pos = 0;
$msg_sequence = $this->_message_sequence++;
$num_messages = ceil(mb_strlen($text) / $max_len);
$part_no = 1;
while ($pos < mb_strlen($text)) {
$ttext = mb_substr($text, $pos, $max_len);
$pos += mb_strlen($ttext);
$udh = pack("cccccc", 5, 0, 3, $msg_sequence, $num_messages, $part_no);
$part_no++;
$res[] = $udh . $ttext;
$this->debug("Split: UDH = ");
for ($i = 0; $i < strlen($udh); $i++) {
$this->debug(ord($udh[$i]) . " ");
}
$this->debug("\n");
$this->debug("Split: $ttext.\n");
}
return $res;
}

function unpack2($spec, $data)
{
$res = array();
$specs = explode("/", $spec);
$pos = 0;
reset($specs);
while (list(, $sp) = each($specs)) {
$subject = substr($data, $pos);
$type = substr($sp, 0, 1);
$var = substr($sp, 1);
switch ($type) {
case "N":
$temp = unpack("Ntemp2", $subject);
$res[$var] = $temp["temp2"];
$pos += 4;
break;
case "c":
$temp = unpack("ctemp2", $subject);
$res[$var] = $temp["temp2"];
$pos += 1;
break;
case "a":
$pos2 = strpos($subject, chr(0)) + 1;
$temp = unpack("a{$pos2}temp2", $subject);
$res[$var] = $temp["temp2"];
$pos += $pos2;
break;
}
}
return $res;
}

function debug($str)
{
if ($this->_debug) {
echo $str;
}
}
};